Page MenuHomec4science

No OneTemporary

File Metadata

Created
Fri, May 24, 08:54
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/.gitmodules b/.gitmodules
index b371272de..dd3f1da62 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,18 +1,18 @@
[submodule "extra_packages/extra-materials"]
path = extra_packages/extra-materials
url = git@lsmssrv1.epfl.ch:akantu-extra-materials.git
[submodule "extra_packages/igfem"]
path = extra_packages/igfem
url = git@lsmssrv1.epfl.ch:akantu-igfem.git
[submodule "extra_packages/parallel-cohesive-element"]
path = extra_packages/parallel-cohesive-element
url = git@lsmssrv1.epfl.ch:akantu-parallel-cohesive.git
-[submodule "extra_packages/traction-at-split-node-contact"]
- path = extra_packages/traction-at-split-node-contact
- url = git@lsmssrv1.epfl.ch:akantu-traction-at-split-node-contact.git
[submodule "extra_packages/students-extra-package"]
path = extra_packages/students-extra-package
url = git@lsmssrv1.epfl.ch:students-extra-package.git
[submodule "extra_packages/phase-field"]
path = extra_packages/phase-field
url = git@lsmssrv1.epfl.ch:akantu-phase-field.git
+[submodule "extra-packages/contact-alejandro"]
+ path = extra_packages/contact-alejandro
+ url = git@lsmssrv1.epfl.ch:akantu-contact-alejandro.git
diff --git a/AUTHORS b/AUTHORS
index 0ba040dbf..e65a837eb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,48 +1,55 @@
-Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
Akantu is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Akantu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Akantu. If not, see <http://www.gnu.org/licenses/>.
Authors :
- Nicolas Richart <nicolas.richart@epfl.ch>
- Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- - Ramin Aghababaei <ramin.aghababaei@epfl.ch>
+ - Jean-François Molinari <jean-francois.molinari@epfl.ch>
- Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- - Fabian Barras <fabian.barras@epfl.ch>
- - Marion Estelle Chambart <mchambart@stucky.ch>
- - Dana Christen <dana.christen@gmail.com>
+ - Alodie Schneuwly <alodie.schneuwly@epfl.ch>
+ - Aranda Ruiz Josue <josue.arandaruiz@epfl.ch>
- Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- - Lucas Frerot <lucas.frerot@epfl.ch>
- - Sébastien Hartmann <sebastien.hartmann@epfl.ch>
- - Jean-François Jerier <jean-francois.jerier@epfl.ch>
- - Till Junge <till.junge@epfl.ch>
- - David Simon Kammer <david.kammer@epfl.ch>
- - Thomas Menouillard <tmenouillard@stucky.ch>
- - Jean-François Molinari <jean-francois.molinari@epfl.ch>
+ - Benjamin Paccaud <benjamin.paccaud@epfl.ch>
+ - Clement Roux <clement.roux@epfl.ch>
+ - Cyprien Wolff <cyprien.wolff@epfl.ch>
+ - Damien Scantamburlo <damien.scantamburlo@epfl.ch>
+ - Damien Spielmann <damien.spielmann@epfl.ch>
+ - Dana Christen <dana.christen@gmail.com>
- Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ - David Simon Kammer <david.kammer@epfl.ch>
+ - Fabian Barras <fabian.barras@epfl.ch>
+ - Jaehyun Cho <jaehyun.cho@epfl.ch>
+ - Jean-François Jerier <jean-francois.jerier@epfl.ch>
+ - Leonardo Snozzi <leonardo.snozzi@epfl.ch>
+ - Lucas Frerot <lucas.frerot@epfl.ch>
+ - Marco Vocialta <marco.vocialta@epfl.ch>
+ - Marion Estelle Chambart <marion.chambart@epfl.ch>
- Mathilde Radiguet <mathilde.radiguet@epfl.ch>
- - Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
+ - Mauro Corrado <mauro.corrado@epfl.ch>
+ - Nicholas Molyneaux <nicholas.molyneaux@epfl.ch>
+ - Okan Yilmaz <okan.yilmaz@epfl.ch>
- Pedro Romero <pedro.romero@epfl.ch>
- - Alodie Schneuwly <alodie.schneuwly@epfl.ch>
- - Leonardo Snozzi <leonardo.snozzi@epfl.ch>
- - Damien Spielmann <damien.spielmann@epfl.ch>
- Peter Spijker <peter.spijker@epfl.ch>
- - Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
- - Marco Vocialta <marco.vocialta@epfl.ch>
+ - Ramin Aghababaei <ramin.aghababaei@epfl.ch>
- Rui Wang <rui.wang@epfl.ch>
- - Cyprien Wolff <cyprien.wolff@epfl.ch>
+ - Sacha Laffely <sacha.laffely@epfl.ch>
+ - Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
+ - Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
+ - Sébastien Hartmann <sebastien.hartmann@epfl.ch>
+ - Thomas Menouillard <tmenouillard@stucky.ch>
+ - Till Junge <till.junge@epfl.ch>
- Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
- - Okan Yilmaz <okan.yilmaz@epfl.ch>
- - Mauro Corrado <mauro.corrado@epfl.ch>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 109ec76f3..0d66fc747 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,186 +1,194 @@
#===============================================================================
# @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: Fri Jan 22 2016
#
# @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)
+ EXTRA_PACKAGES_FOLDER ${PROJECT_SOURCE_DIR}/extra_packages
+ NO_AUTO_COMPILE_FLAGS)
## meta option \todo better way to do it when multiple package give enable the
## same feature
if(AKANTU_SCOTCH)
set(AKANTU_PARTITIONER ON)
else()
set(AKANTU_PARTITIONER OFF)
endif()
if(AKANTU_MUMPS)
set(AKANTU_SOLVER ON)
else()
set(AKANTU_SOLVER OFF)
endif()
#===============================================================================
# Akantu library
#===============================================================================
add_subdirectory(src)
#===============================================================================
# Documentation
#===============================================================================
if(AKANTU_DOCUMENTATION_DOXYGEN OR AKANTU_DOCUMENTATION_MANUAL)
add_subdirectory(doc)
else()
set(AKANTU_DOC_EXCLUDE_FILES "${PROJECT_SOURCE_DIR}/doc/manual" CACHE INTERNAL "")
endif()
#===============================================================================
# Examples and tests
#===============================================================================
option(AKANTU_EXAMPLES "Activate examples" OFF)
option(AKANTU_TESTS "Activate tests" OFF)
include(AkantuTestsMacros)
-include(AkantuExamplesMacros)
+include(AkantuExampleMacros)
if(AKANTU_EXAMPLES OR AKANTU_TESTS)
- option(AKANTU_BUILD_ALL_EXAMPLES "Build all examples")
- option(AKANTU_BUILD_ALL_TESTS "Build all tests")
+ option(AKANTU_BUILD_ALL_TESTS "Build all tests" ON)
find_package(GMSH REQUIRED)
endif()
if(AKANTU_EXAMPLES)
add_subdirectory(examples)
endif()
-
+# tests
add_test_tree(test)
#===============================================================================
-# Install and Packaging
+# Python interface
#===============================================================================
-include(AkantuInstall)
-
-if(NOT AKANTU_DISABLE_CPACK)
- include(AkantuCPack)
+package_is_activated(python_interface _python_act)
+if(_python_act)
+ if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}")
+ set(AKANTU_PYTHON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
+ else()
+ set(AKANTU_PYTHON_INSTALL_PREFIX "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_PREFIX}")
+ endif()
+ add_subdirectory(python)
endif()
#===============================================================================
# Install and Packaging
#===============================================================================
-package_is_activated(python_interface _python_act)
-if(_python_act)
- add_subdirectory(python)
-# add_subdirectory(akantu4py)
+include(AkantuInstall)
+
+option(AKANTU_DISABLE_CPACK
+ "This option commands the generation of extra info for the \"make package\" target" ON)
+mark_as_advanced(AKANTU_DISABLE_CPACK)
+if(NOT AKANTU_DISABLE_CPACK)
+ include(AkantuCPack)
endif()
diff --git a/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/README b/README
index 1f2cb8f0b..7e9214d8b 100644
--- a/README
+++ b/README
@@ -1,91 +1,84 @@
==================================================
_ _
| | | |
__ _| | ____ _ _ __ | |_ _ _
/ _` | |/ / _` | '_ \| __| | | |
| (_| | < (_| | | | | |_| |_| |
\__,_|_|\_\__,_|_| |_|\__|\__,_|
==================================================
-Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
Akantu is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Akantu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Akantu. If not, see <http://www.gnu.org/licenses/>.
___________
COMPILATION
There are two ways to compile Akantu.
1. You can compile it directly using cmake
> mkdir build
> cd build
> ccmake ..
> make
-2. You can use the make file in Akantu's main directory. This make file
-configure the cmake for you
-
- > make config
-
- Several options can be added to the configure script, they include:
- - cc=[compiler] The C compiler used in cmake tests, default: gcc
- - cxx=[compiler] The C++ compiler to use, default: g++
- - prefix=[path] Installation path, default: /usr/local
- - shared=[bool] Build a shared library, default: true
- - assert=[bool] Enable the assert macro, default: true
- - doc=[bool] Configure to build the documentation, default: true
- - build=[string] Build types: Debug, Release, RelWithDebInfo, MinSizeRel,
- default: None
________
CONTACTS
If you need some help to use Akantu you can contact use akantu@akantu.ch
-
_______
AUTHORS
- Nicolas Richart <nicolas.richart@epfl.ch>
- Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- - Ramin Aghababaei <ramin.aghababaei@epfl.ch>
+ - Jean-François Molinari <jean-francois.molinari@epfl.ch>
- Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- - Fabian Barras <fabian.barras@epfl.ch>
- - Marion Estelle Chambart <mchambart@stucky.ch>
- - Dana Christen <dana.christen@gmail.com>
+ - Alodie Schneuwly <alodie.schneuwly@epfl.ch>
+ - Aranda Ruiz Josue <josue.arandaruiz@epfl.ch>
- Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- - Lucas Frerot <lucas.frerot@epfl.ch>
- - Sébastien Hartmann <sebastien.hartmann@epfl.ch>
- - Jean-François Jerier <jean-francois.jerier@epfl.ch>
- - Till Junge <till.junge@epfl.ch>
- - David Simon Kammer <david.kammer@epfl.ch>
- - Thomas Menouillard <tmenouillard@stucky.ch>
- - Jean-François Molinari <jean-francois.molinari@epfl.ch>
+ - Benjamin Paccaud <benjamin.paccaud@epfl.ch>
+ - Clement Roux <clement.roux@epfl.ch>
+ - Cyprien Wolff <cyprien.wolff@epfl.ch>
+ - Damien Scantamburlo <damien.scantamburlo@epfl.ch>
+ - Damien Spielmann <damien.spielmann@epfl.ch>
+ - Dana Christen <dana.christen@gmail.com>
- Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
+ - David Simon Kammer <david.kammer@epfl.ch>
+ - Fabian Barras <fabian.barras@epfl.ch>
+ - Jaehyun Cho <jaehyun.cho@epfl.ch>
+ - Jean-François Jerier <jean-francois.jerier@epfl.ch>
+ - Leonardo Snozzi <leonardo.snozzi@epfl.ch>
+ - Lucas Frerot <lucas.frerot@epfl.ch>
+ - Marco Vocialta <marco.vocialta@epfl.ch>
+ - Marion Estelle Chambart <marion.chambart@epfl.ch>
- Mathilde Radiguet <mathilde.radiguet@epfl.ch>
- - Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
+ - Mauro Corrado <mauro.corrado@epfl.ch>
+ - Nicholas Molyneaux <nicholas.molyneaux@epfl.ch>
+ - Okan Yilmaz <okan.yilmaz@epfl.ch>
- Pedro Romero <pedro.romero@epfl.ch>
- - Alodie Schneuwly <alodie.schneuwly@epfl.ch>
- - Leonardo Snozzi <leonardo.snozzi@epfl.ch>
- - Damien Spielmann <damien.spielmann@epfl.ch>
- Peter Spijker <peter.spijker@epfl.ch>
- - Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
- - Marco Vocialta <marco.vocialta@epfl.ch>
+ - Ramin Aghababaei <ramin.aghababaei@epfl.ch>
- Rui Wang <rui.wang@epfl.ch>
- - Cyprien Wolff <cyprien.wolff@epfl.ch>
+ - Sacha Laffely <sacha.laffely@epfl.ch>
+ - Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
+ - Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
+ - Sébastien Hartmann <sebastien.hartmann@epfl.ch>
+ - Thomas Menouillard <tmenouillard@stucky.ch>
+ - Till Junge <till.junge@epfl.ch>
- Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
- - Okan Yilmaz <okan.yilmaz@epfl.ch>
diff --git a/VERSION b/VERSION
new file mode 100644
index 000000000..bb576dbde
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+2.3
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..220f915ec 100644
--- a/cmake/AkantuCPack.cmake
+++ b/cmake/AkantuCPack.cmake
@@ -1,121 +1,129 @@
#===============================================================================
# @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: Fri Jan 22 2016
#
# @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")
+set(CPACK_SOURCE_GENERATOR "TGZ;TBZ2")
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
- set(CPACK_GENERATOR "TGZ")
+ set(CPACK_GENERATOR "TGZ;DEB")
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_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
+package_get_all_package_system_dependency(deb _deb_deps)
+package_get_all_package_system_dependency(deb-src _deb_src_deps)
+
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}")
+set(CPACK_DEBIAN_PACKAGE_DEPENDS "${_deb_deps}")
+set(CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDSS "${_deb_src_deps}")
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)
+include(AkantuCPackMacros)
+generate_cpack_ignore_list(CPACK_SOURCE_IGNORE_FILES)
-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})
+# for debug
+# foreach(_file ${CPACK_SOURCE_IGNORE_FILES})
+# message("IGNORE ${_file}")
+# endforeach()
- _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$;\\\\.#;/#;~")
+list(APPEND CPACK_SOURCE_IGNORE_FILES
+ "/.*build.*/" "/CVS/" "/\\\\.svn/" "/\\\\.bzr/" "/\\\\.hg/"
+ "/\\\\.hgignore" "/\\\\.git/" "/\\\\.idea/" "\\\\.swp$"
+ "\\\\.#" "/#" "~")
include(CPack)
diff --git a/cmake/AkantuCPackMacros.cmake b/cmake/AkantuCPackMacros.cmake
new file mode 100644
index 000000000..3c7f3a7fc
--- /dev/null
+++ b/cmake/AkantuCPackMacros.cmake
@@ -0,0 +1,153 @@
+#===============================================================================
+# @file AkantuCPack.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Wed Jan 18 2015
+#
+# @brief macros to help for cpack
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+# ==============================================================================
+# let start the ugly things to list what should not be in the package
+# ==============================================================================
+function(generate_cpack_ignore_list ignore_list)
+ message(STATUS "Generating CPack ignore list...")
+
+ # get a full list of all the files include in the source folder
+ file(GLOB _first_level "${PROJECT_SOURCE_DIR}/*")
+ set(_all_files "${PROJECT_SOURCE_DIR}" ${_first_level})
+ foreach(_path ${_first_level})
+ if(IS_DIRECTORY "${_path}" AND
+ NOT _path MATCHES "build.*" AND
+ NOT _path MATCHES "\\.git.*")
+ file(GLOB_RECURSE _second_level "${_path}/*")
+ file(GLOB _second_extra_level "${_path}/*")
+ list(APPEND _all_files ${_second_level} ${_second_extra_level})
+ endif()
+ endforeach()
+
+ set(_dirs)
+ foreach(_file ${_all_files})
+ get_filename_component(_dir ${_file} DIRECTORY)
+ list(APPEND _dirs ${_dir})
+ endforeach()
+ list(REMOVE_DUPLICATES _dirs)
+ list(APPEND _all_files ${_dirs})
+
+ # getting list of all the files that should be in the source package
+ package_get_files_for_package(_all_package_files)
+ package_get_all_activated_packages(_activated_packages)
+ foreach(_pkg ${_activated_packages})
+ _package_get_filename(${_pkg} _file_name)
+
+ _package_get_source_files(${_pkg} _srcs _pub_hdrs _priv_hdrs)
+ _package_get_variable(TESTS_FILES ${_pkg} _tests_files)
+ # adding the source directory
+ set(_need_source_folder)
+ foreach(_src ${_srcs} ${_pub_hdrs} ${_priv_hdrs} ${_tests_files})
+ list(APPEND _need_source_folder ${PROJECT_SOURCE_DIR}/${_src})
+ endforeach()
+
+ _package_get_documentation_files(${_pkg} _doc_files)
+ # adding the manual directory
+ set(_all_docs)
+ _package_get_manual_folder(${_pkg} _doc_folder)
+ foreach(_file ${_doc_files})
+ list(APPEND _all_docs ${_doc_folder}/${_file})
+ endforeach()
+
+ _package_get_variable(EXAMPLES_FILES ${_pkg} _examples_files)
+ _package_get_variable(EXTRA_FILES ${_pkg} _extra_files)
+
+ # split the set in 2 for debug reasons
+ set(_package_files
+ ${_file_name} ${_need_source_folder}
+ ${_examples_files} ${_extra_files} ${_all_docs}
+ )
+
+ list(APPEND _all_package_files ${_package_files})
+ endforeach()
+
+ # generate ignore list
+ set(_ignore_list)
+ set(_keep_dirs)
+ set(_ignore_dirs)
+ foreach(_file ${_all_files})
+ set(_found FALSE)
+ foreach(_pkg_file ${_all_package_files})
+ if(IS_DIRECTORY "${_file}" AND
+ _pkg_file MATCHES "${_file}/.*")
+ set(_found TRUE)
+ list(APPEND _keep_dirs "${_file}")
+ break()
+ elseif(_pkg_file MATCHES "${_file}")
+ set(_found TRUE)
+ break()
+ endif()
+ endforeach()
+
+ if(NOT _found)
+ list(APPEND _ignore_list "${_file}")
+ if(IS_DIRECTORY "${_file}")
+ list(APPEND _ignore_dirs "${_file}")
+ endif()
+ endif()
+ endforeach()
+
+ # Save CMakeLists.txt in folder that are kept
+ foreach(_dir ${_keep_dirs})
+ if(EXISTS "${_dir}/CMakeLists.txt")
+ list(REMOVE_ITEM _ignore_list "${_dir}/CMakeLists.txt")
+ endif()
+ endforeach()
+
+ set(_tmp_ignore_list ${_ignore_list})
+ set(_ignore_list)
+ # cleaning the ignore
+ foreach(_file ${_tmp_ignore_list})
+ set(_found FALSE)
+ foreach(_dir ${_ignore_dirs})
+ if(_file MATCHES "${_dir}/.*")
+ set(_found TRUE)
+ break()
+ endif()
+ endforeach()
+
+ if(NOT _found)
+ if(IS_DIRECTORY ${_file})
+ list(APPEND _ignore_list "${_file}/")
+ else()
+ list(APPEND _ignore_list "${_file}")
+ endif()
+ endif()
+ endforeach()
+
+ list(SORT _ignore_list)
+ list(REMOVE_DUPLICATES _ignore_list)
+
+ set(${ignore_list} ${_ignore_list} PARENT_SCOPE)
+endfunction()
+# ==============================================================================
+# Let's hope that after all this the list is complete and not to heavy for cpack
+# ==============================================================================
diff --git a/cmake/AkantuConfig.cmake.in b/cmake/AkantuConfig.cmake.in
index 455433c99..b53e58447 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 Jan 18 2016
#
# @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)
+ include(AkantuSimulationMacros)
else()
# In install tree
set(AKANTU_INCLUDE_DIR "${AKANTU_CMAKE_DIR}/../../include/akantu")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${AKANTU_CMAKE_DIR}/cmake")
- include(AkantuExamplesMacros)
+ include(AkantuSimulationMacros)
endif()
include("${AKANTU_CMAKE_DIR}/AkantuLibraryDepends.cmake")
# Dependencies
include("${AKANTU_CMAKE_DIR}/AkantuConfigInclude.cmake")
set(AKANTU_BUILD_TYPE @CMAKE_BUILD_TYPE@)
# find_akantu_dependencies()
set(AKANTU_LIBRARY akantu)
if(AKANTU_HAS_CORE_CXX11)
add_definitions(-std=c++0x)
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/AkantuExampleMacros.cmake b/cmake/AkantuExampleMacros.cmake
new file mode 100644
index 000000000..552a5e70f
--- /dev/null
+++ b/cmake/AkantuExampleMacros.cmake
@@ -0,0 +1,87 @@
+#===============================================================================
+# @file AkantuExampleMacros.cmake
+#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Jan 18 2016
+# @date last modification: Fri Jan 22 2016
+#
+# @brief macros for examples
+#
+# @section LICENSE
+#
+# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+# (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+include(AkantuSimulationMacros)
+
+# ==============================================================================
+function(register_example example_name)
+ _add_akantu_simulation(${example_name} ${ARGN} LIST_FILES _example_files)
+ if(DEFINED _add_examples_pkg)
+ package_add_to_variable(EXAMPLES_FILES ${_add_examples_pkg} ${_example_files})
+ endif()
+endfunction()
+
+# ==============================================================================
+function(add_example et_name desc)
+ string(TOUPPER ${et_name} upper_name)
+
+ if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${et_name})
+ 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()
+ else()
+ message(SEND_ERROR "Examples should be associated to a package")
+ endif()
+
+ if(${_act})
+ if(DEFINED _add_examples_pkg)
+ set(_save_add_examples_pkg ${_add_examples_pkg})
+ endif()
+ list(GET _manage_example_PACKAGE 0 _pkg)
+ set(_add_examples_pkg ${_pkg})
+
+ add_subdirectory(${et_name})
+
+ unset(_add_examples_pkg)
+ if(DEFINED _save_add_examples_pkg)
+ set(_add_examples_pkg ${_save_add_examples_pkg})
+ unset(_save_add_examples_pkg)
+ endif()
+ endif()
+endfunction()
diff --git a/cmake/AkantuExamplesMacros.cmake b/cmake/AkantuExamplesMacros.cmake
deleted file mode 100644
index 940a083ed..000000000
--- a/cmake/AkantuExamplesMacros.cmake
+++ /dev/null
@@ -1,175 +0,0 @@
-#===============================================================================
-# @file AkantuTestAndExamples.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
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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..f745f7cdf 100644
--- a/cmake/AkantuInstall.cmake
+++ b/cmake/AkantuInstall.cmake
@@ -1,137 +1,154 @@
#===============================================================================
# @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: Fri Jan 22 2016
#
# @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)
+ _package_get_compile_flags(${_pkg_name} CXX _compile_flags)
if(_compile_flags)
file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
-set(AKANTU_${_real_pkg_name}_COMPILE_FLAGS ${_compile_flags})
+set(AKANTU_${_real_pkg_name}_COMPILE_CXX_FLAGS ${_compile_flags})
")
endif()
endforeach()
file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
")
+file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
+set(AKANTU_EXTRA_CXX_FLAGS \"${AKANTU_EXTRA_CXX_FLAGS}\")
+")
+
+
# 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)
+configure_file(cmake/akantu_environement.sh.in ${PROJECT_BINARY_DIR}/akantu_environement.sh @ONLY)
+configure_file(cmake/akantu_environement.csh.in ${PROJECT_BINARY_DIR}/akantu_environement.csh @ONLY)
+
+
+configure_file(cmake/akantu_install_environement.sh.in ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/akantu_environement.sh @ONLY)
+configure_file(cmake/akantu_install_environement.csh.in ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/akantu_environement.csh @ONLY)
+
+install(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/akantu_environement.sh
+ ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/akantu_environement.csh
+ DESTINATION share/akantu${AKANTU_VERSION})
# 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
+ ${PROJECT_SOURCE_DIR}/cmake/AkantuSimulationMacros.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..cdbca13c6 100644
--- a/cmake/AkantuMacros.cmake
+++ b/cmake/AkantuMacros.cmake
@@ -1,345 +1,363 @@
#===============================================================================
# @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: Tue Jan 19 2016
#
# @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()
+# ==============================================================================
+function(get_target_list_of_associated_files tgt files)
+ get_target_property(_type ${tgt} TYPE)
+ if(_type STREQUAL "SHARED_LIBRARY"
+ OR _type STREQUAL "STATIC_LIBRARY"
+ OR _type STREQUAL "MODULE_LIBRARY"
+ OR _type STREQUAL "EXECUTABLE")
+ get_target_property(_srcs ${tgt} SOURCES)
+ set(_dep_ressources)
+ foreach(_file ${_srcs})
+ list(APPEND _dep_ressources ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
+ endforeach()
+ else()
+ get_target_property(_dep_ressources ${tgt} RESSOURCES)
+ endif()
+
+ set(${files} ${_dep_ressources} PARENT_SCOPE)
+endfunction()
+
#===============================================================================
# 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)
-
+ check_cxx_compiler_flag (-std=c++11 HAVE_CPP_11)
unset(_cpp_11_flag)
- if(HAVE_CPP_0X)
- set(_cpp_11_flag "-std=c++0x")
+ if(HAVE_CPP_11)
+ set(_cpp_11_flag "-std=c++11")
else()
- check_cxx_compiler_flag (-std=c++11 HAVE_CPP_11)
- if(HAVE_CPP_11)
- set(_cpp_11_flag "-std=c++11")
+ check_cxx_compiler_flag (-std=c++0x HAVE_CPP_0X)
+ if(HAVE_CPP_0X)
+ set(_cpp_11_flag "-std=c++0x")
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..f64074096 100644
--- a/cmake/AkantuPackagesSystem.cmake
+++ b/cmake/AkantuPackagesSystem.cmake
@@ -1,283 +1,364 @@
#===============================================================================
-# @file CMakePackagesSystem.cmake
+# @file AkantuPackagesSystem.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Sat Jul 18 2015
+# @date last modification: Mon Jan 18 2016
+#
# @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()
-#-------------------------------------------------------------------------------
+# ------------------------------------------------------------------------------
+# Extra files to consider in source package generated by CPack
+# ------------------------------------------------------------------------------
+function(package_declare_extra_files_to_package pkg)
+ set(_types SOURCES MANUAL TESTS PROJECT)
+ cmake_parse_arguments(_extra_files
+ ""
+ ""
+ "${_types}"
+ ${ARGN})
+
+ set(_files ${_extra_files_UNPARSED_ARGUMENTS})
+
+ package_get_sources_folder(${pkg} _folder_SOURCES)
+ package_get_manual_folder(${pkg} _folder_MANUAL)
+ package_get_tests_folder(${pkg} _folder_TESTS)
+ set(_folder_PROJECT ${PROJECT_SOURCE_DIR})
+
+ foreach(_type ${_types})
+ if(_extra_files_${_type})
+ foreach(_file ${_extra_files_${_type}})
+ list(APPEND _files ${_folder_${_type}}/${_file})
+ if(NOT EXISTS ${_folder_${_type}}/${_file})
+ message(SEND_ERROR "The package ${pkg} tries to register the file ${_file} (as a ${_type} file).
+This file cannot be found.")
+ endif()
+ endforeach()
+ endif()
+ endforeach()
+
+ package_set_variable(EXTRA_FILES ${pkg} ${_files})
+endfunction()
+
+# ------------------------------------------------------------------------------
+function(package_add_files_to_package)
+ set(_files)
+ foreach(_file ${ARGN})
+ list(APPEND _files ${PROJECT_SOURCE_DIR}/${_file})
+ endforeach()
+ package_add_to_project_variable(EXTRA_FILES ${_files})
+endfunction()
+
+function(package_get_files_for_package files)
+ package_get_project_variable(EXTRA_FILES _tmp)
+ set(${files} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+
+package_add_files_to_package(
+ .clang-format
+ AUTHORS
+ README
+ VERSION
+ COPYING
+ COPYING.lesser
+ CTestConfig.cmake
+ cmake/akantu_environement.sh.in
+ cmake/akantu_environement.csh.in
+ cmake/akantu_install_environement.sh.in
+ cmake/akantu_install_environement.csh.in
+ cmake/Modules/CMakeFlagsHandling.cmake
+ cmake/Modules/CMakePackagesSystem.cmake
+ cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
+ cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
+ cmake/Modules/CMakeVersionGenerator.cmake
+ cmake/Modules/PCHgcc.cmake
+ cmake/AkantuBuildTreeSettings.cmake.in
+ cmake/AkantuConfig.cmake.in
+ cmake/AkantuConfigVersion.cmake.in
+ cmake/AkantuCPack.cmake
+ cmake/AkantuCPackMacros.cmake
+ cmake/AkantuInstall.cmake
+ cmake/AkantuMacros.cmake
+ cmake/AkantuPackagesSystem.cmake
+ cmake/AkantuUse.cmake
+ cmake/AkantuSimulationMacros.cmake
+ cmake/material_lister.cc
+ cmake/Modules/FindGMSH.cmake
+ )
diff --git a/cmake/AkantuSimulationMacros.cmake b/cmake/AkantuSimulationMacros.cmake
new file mode 100644
index 000000000..c072a53e3
--- /dev/null
+++ b/cmake/AkantuSimulationMacros.cmake
@@ -0,0 +1,168 @@
+#===============================================================================
+# @file AkantuSimulationMacros.cmake
+#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Jan 18 2016
+# @date last modification: Wed Jan 20 2016
+#
+# @brief macros for examples
+#
+# @section LICENSE
+#
+# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+# (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+if(__AKANTU_SIMULATION_MACROS)
+ return()
+endif()
+set(__AKANTU_SIMULATION_MACROS TRUE)
+
+
+
+#===============================================================================
+function(add_akantu_simulation simulation_name)
+ _add_akantu_simulation(${simulation_name} ${ARGN})
+endfunction()
+
+#===============================================================================
+function(_add_akantu_simulation simulation_name)
+ set(multi_variables
+ SCRIPT
+ SOURCES
+ FILES_TO_COPY
+ DEPENDS
+ DIRECTORIES_TO_CREATE
+ COMPILE_OPTIONS
+ USE_PACKAGES
+ )
+
+ cmake_parse_arguments(_simulation
+ ""
+ "LIST_FILES"
+ "${multi_variables}"
+ ${ARGN}
+ )
+
+ set(_deps_OK TRUE)
+
+ if(_simulation_USE_PACKAGES)
+ foreach(_pkg ${_simulation_USE_PACKAGES})
+ package_is_activated(${_pkg} _activated)
+ if(_activated)
+ package_get_include_dir(${_pkg} _inc_dir)
+ list(APPEND _simulation_INCLUDE_DIRS ${_inc_dir})
+
+ package_get_libraries(${_pkg} _libraries)
+ list(APPEND _simulation_LIBRARIES ${_libraries})
+
+ package_get_compile_flags(${_pkg} CXX _flags)
+ list(APPEND _simulation_COMPILE_FLAGS "${_flags}")
+ else()
+ message("${simulation_name} use ${_pkg} but Akantu "
+ " has been compiled without this package")
+ set(_deps_OK FALSE)
+ endif()
+ endforeach()
+ endif()
+
+ package_is_activated(CORE_CXX11 _activated)
+ if(_activated)
+ package_get_compile_flags(CORE_CXX11 CXX _flags)
+ list(APPEND _simulation_COMPILE_FLAGS "${_flags}")
+ endif()
+
+ package_get_compile_flags(BOOST CXX _flags)
+ list(APPEND _simulation_COMPILE_FLAGS "${_flags}")
+
+ string(REPLACE ";" " " _tmp_flags "${_simulation_COMPILE_FLAGS}")
+ string(REGEX REPLACE " +" " " _simulation_COMPILE_FLAGS "${_tmp_flags}")
+
+ if(_deps_OK)
+ if(_simulation_UNPARSED_ARGUMENTS OR _simulation_SOURCES)
+ add_executable(${simulation_name}
+ ${_simulation_UNPARSED_ARGUMENTS} ${_simulation_SOURCES})
+
+ target_link_libraries(${simulation_name} akantu ${_simulation_LIBRARIES})
+ target_include_directories(${simulation_name} PRIVATE ${AKANTU_INCLUDE_DIRS} ${_simulation_INCLUDE_DIRS})
+
+ if(_simulation_DEPENDS)
+ foreach(_deps ${_simulation_DEPENDS})
+ get_target_property(_type ${_deps} TYPE)
+ if(_type STREQUAL "SHARED_LIBRARY"
+ OR _type STREQUAL "STATIC_LIBRARY")
+ target_link_libraries(${simulation_name} ${_deps})
+ else()
+ add_dependencies(${simulation_name} ${_deps})
+ endif()
+ endforeach()
+ endif()
+
+ if(_simulation_COMPILE_OPTIONS)
+ set_target_properties(${simulation_name}
+ PROPERTIES COMPILE_DEFINITIONS "${_simulation_COMPILE_OPTIONS}")
+ endif()
+
+ if(_simulation_COMPILE_FLAGS)
+ set_target_properties(${simulation_name}
+ PROPERTIES COMPILE_FLAGS "${_simulation_COMPILE_FLAGS}")
+ endif()
+ endif()
+
+ if(_simulation_SCRIPT)
+ file(COPY ${_simulation_SCRIPT} DESTINATION .)
+ endif()
+
+ # copy the needed files to the build folder
+ if(_simulation_FILES_TO_COPY)
+ file(COPY ${_simulation_FILES_TO_COPY} DESTINATION .)
+ endif()
+
+ # create the needed folders in the build folder
+ if(_simulation_DIRECTORIES_TO_CREATE)
+ foreach(_dir ${_simulation_DIRECTORIES_TO_CREATE})
+ if(IS_ABSOLUTE ${dir})
+ file(MAKE_DIRECTORY ${_dir})
+ else()
+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir})
+ endif()
+ endforeach()
+ endif()
+ endif()
+
+ if(_simulation_LIST_FILES)
+ set(_simulation_files)
+
+ foreach(_file ${_simulation_SCRIPT} ${_simulation_SOURCES}
+ ${_simulation_UNPARSED_ARGUMENTS} ${_simulation_FILES_TO_COPY})
+ list(APPEND _simulation_files ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
+ endforeach()
+
+ foreach(_dep ${_simulation_DEPENDS})
+ get_target_list_of_associated_files(${_dep} _dep_ressources)
+ if(_dep_ressources)
+ list(APPEND _simulation_files "${_dep_ressources}")
+ endif()
+ endforeach()
+
+ set(${_simulation_LIST_FILES} ${_simulation_files} PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/cmake/AkantuTestsMacros.cmake b/cmake/AkantuTestsMacros.cmake
index 0e94790b5..0c15b2c35 100644
--- a/cmake/AkantuTestsMacros.cmake
+++ b/cmake/AkantuTestsMacros.cmake
@@ -1,354 +1,399 @@
#===============================================================================
-# @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 22 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_DIFF_SCRIPT ${AKANTU_CMAKE_DIR}/akantu_diff.sh)
-set(AKANTU_POSTPROCESS_SCRIPT ${AKANTU_CMAKE_DIR}/akantu_apply_post_process.sh)
set(AKANTU_DRIVER_SCRIPT ${AKANTU_CMAKE_DIR}/akantu_test_driver.sh)
# ==============================================================================
macro(add_test_tree dir)
if(AKANTU_TESTS)
enable_testing()
include(CTest)
mark_as_advanced(BUILD_TESTING)
- set(AKANTU_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)
+ if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${dir})
+ return()
+ endif()
+
set(_my_parent_dir ${_akantu_current_parent_test})
# initialize variables
set(_akantu_current_parent_test ${dir} CACHE INTERNAL "Current test folder" FORCE)
set(_akantu_${dir}_tests_count 0 CACHE INTERNAL "" FORCE)
# set the option for this directory
string(TOUPPER ${dir} _u_dir)
option(AKANTU_BUILD_${_u_dir} "${desc}")
mark_as_advanced(AKANTU_BUILD_${_u_dir})
# add the sub-directory
add_subdirectory(${dir})
# if no test can be activated make the option disappear
set(_force_deactivate_count FALSE)
if(${_akantu_${dir}_tests_count} EQUAL 0)
set(_force_deactivate_count TRUE)
endif()
# if parent off make the option disappear
set(_force_deactivate_parent FALSE)
string(TOUPPER ${_my_parent_dir} _u_parent_dir)
if(NOT AKANTU_BUILD_${_u_parent_dir})
set(_force_deactivate_parent TRUE)
endif()
if(_force_deactivate_parent OR _force_deactivate_count OR AKANTU_BUILD_ALL_TESTS)
if(NOT DEFINED _AKANTU_BUILD_${_u_dir}_SAVE)
set(_AKANTU_BUILD_${_u_dir}_SAVE ${AKANTU_BUILD_${_u_dir}} CACHE INTERNAL "" FORCE)
endif()
unset(AKANTU_BUILD_${_u_dir} CACHE)
if(AKANTU_BUILD_ALL_TESTS AND NOT _force_deactivate_count)
set(AKANTU_BUILD_${_u_dir} ON CACHE INTERNAL "${desc}" FORCE)
else()
set(AKANTU_BUILD_${_u_dir} OFF CACHE INTERNAL "${desc}" FORCE)
endif()
else()
if(DEFINED _AKANTU_BUILD_${_u_dir}_SAVE)
unset(AKANTU_BUILD_${_u_dir} CACHE)
set(AKANTU_BUILD_${_u_dir} ${_AKANTU_BUILD_${_u_dir}_SAVE} CACHE BOOL "${desc}")
unset(_AKANTU_BUILD_${_u_dir}_SAVE CACHE)
endif()
endif()
# adding up to the parent count
math(EXPR _tmp_parent_count "${_akantu_${dir}_tests_count} + ${_akantu_${_my_parent_dir}_tests_count}")
set(_akantu_${_my_parent_dir}_tests_count ${_tmp_parent_count} CACHE INTERNAL "" FORCE)
# restoring the parent current dir
set(_akantu_current_parent_test ${_my_parent_dir} CACHE INTERNAL "Current test folder" FORCE)
endfunction()
# ==============================================================================
function(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"
+ "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}")
+ 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()
+
+ set(_compile_source)
+ foreach(_file ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS})
+ if(_file MATCHES "\\.cc$" OR _file MATCHES "\\.hh$")
+ list(APPEND _compile_source ${_file})
+ endif()
+ endforeach()
+
# 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)
- # 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()
- set(_test_all_files)
- # 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(AKANTU_BUILD_${_u_parent} OR AKANTU_BUILD_ALL_TESTS)
+ if(_compile_source)
+ # get the include directories for sources in activated directories
+ package_get_all_include_directories(
+ AKANTU_LIBRARY_INCLUDE_DIRS
+ )
+
+ # get the external packages compilation and linking informations
+ package_get_all_external_informations(
+ AKANTU_EXTERNAL_INCLUDE_DIR
+ AKANTU_EXTERNAL_LIBRARIES
+ )
+
+ # set the proper includes to build most of the tests
+ include_directories(
+ ${PROJECT_BINARY_DIR}/src
+ ${AKANTU_LIBRARY_INCLUDE_DIRS}
+ ${AKANTU_EXTERNAL_INCLUDE_DIR}
+ )
+
+ # Register the executable to compile
+ add_executable(${test_name} ${_compile_source})
+ set_property(TARGET ${test_name} APPEND
+ PROPERTY INCLUDE_DIRECTORIES ${AKANTU_LIBRARY_INCLUDE_DIRS} ${AKANTU_EXTERNAL_INCLUDE_DIR})
+ target_link_libraries(${test_name} akantu)
+
+ if(_register_test_DEPENDS)
+ add_dependencies(${test_name} ${_register_test_DEPENDS})
+ endif()
- if(_dep_in_ressources)
- list(APPEND _test_all_files "${_dep_in_ressources}")
+ # add the extra compilation options
+ if(_register_test_COMPILE_OPTIONS)
+ set_target_properties(${test_name}
+ PROPERTIES COMPILE_DEFINITIONS "${_register_test_COMPILE_OPTIONS}")
endif()
- endforeach()
+ if(AKANTU_EXTRA_CXX_FLAGS)
+ set_target_properties(${test_name}
+ PROPERTIES COMPILE_FLAGS "${AKANTU_EXTRA_CXX_FLAGS}")
+ endif()
+ else()
+ if(_register_test_UNPARSED_ARGUMENTS AND NOT _register_test_SCRIPT)
+ set(_register_test_SCRIPT ${_register_test_UNPARSED_ARGUMENTS})
+ endif()
+ endif()
# copy the needed files to the build folder
if(_register_test_FILES_TO_COPY)
foreach(_file ${_register_test_FILES_TO_COPY})
file(COPY "${_file}" DESTINATION .)
- 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(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh")
+ set(_arguments -n "${test_name}")
+ if(_register_test_SCRIPT)
+ file(COPY ${_register_test_SCRIPT}
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+ DESTINATION .)
+ list(APPEND _arguments -e "${_register_test_SCRIPT}")
+ elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh")
file(COPY ${test_name}.sh DESTINATION .)
- list(APPEND _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_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})
+ # register them test
+ 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})
+ endif()
+ endif()
+ set(_test_all_files)
+ # add the source files in the list of all files
+ foreach(_file ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS}
+ ${_register_test_EXTRA_FILES} ${_register_test_SOURCES} ${_register_test_SCRIPT}
+ ${_register_test_POSTPROCESS} ${_register_test_FILES_TO_COPY})
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
+ list(APPEND _test_all_files "${_file}")
+ else()
+ message("The file \"${_file}\" registred by the test \"${test_name}\" does not exists")
+ endif()
+ endforeach()
- # add_test(${test_name}_run
- # ${AKANTU_REDIRECT_SCRIPT} ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.sh)
- # elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified)
- # list(APPEND _test_all_files ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified)
- # add_test(${test_name}_run
- # ${AKANTU_DIFF_SCRIPT} ${test_name} ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified)
- # else()
- # add_test(${test_name}_run
- # ${CMAKE_CURRENT_BINARY_DIR}/${test_name})
- # endif()
-
-
- # 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 "")
+ # add the different dependencies files (meshes, local libraries, ...)
+ foreach(_dep ${_register_test_DEPENDS})
+ get_target_list_of_associated_files(${_dep} _dep_ressources)
+ if(_dep_ressources)
+ list(APPEND _test_all_files "${_dep_ressources}")
endif()
+ endforeach()
+
+ # add estra files to the list of files referenced by a given test
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh")
+ list(APPEND _test_all_files "${test_name}.sh")
+ endif()
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified")
+ list(APPEND _test_all_files "${test_name}.verified")
endif()
+ if(_register_test_SCRIPT)
+ list(APPEND _test_all_files "${_register_test_SCRIPT}")
+ endif()
+
+ # clean the list of all files for this test and add them in the total list
+ foreach(_file ${_test_all_files})
+ get_filename_component(_full ${_file} ABSOLUTE)
+ file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_full})
+ list(APPEND _tmp "${__file}")
+ endforeach()
+
+ foreach(_pkg ${_register_test_PACKAGE})
+ package_get_name(${_pkg} _pkg_name)
+ _package_add_to_variable(TESTS_FILES ${_pkg_name} ${_tmp})
+ endforeach()
endfunction()
diff --git a/cmake/AkantuUse.cmake b/cmake/AkantuUse.cmake
index 00add8aa1..18bcc0151 100644
--- a/cmake/AkantuUse.cmake
+++ b/cmake/AkantuUse.cmake
@@ -1,49 +1,69 @@
#===============================================================================
# @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)
+function(package_get_compile_flags pkg lang flags)
string(TOUPPER ${pkg} _u_pkg)
- set(flags ${AKANTU_${_u_pkg}_COMPILE_FLAGS} PARENT_SCOPE)
+ set(flags ${AKANTU_${_u_pkg}_COMPILE_${lang}_FLAGS} PARENT_SCOPE)
+endfunction()
+
+
+function(get_target_list_of_associated_files tgt files)
+ get_target_property(_type ${tgt} TYPE)
+ if(_type STREQUAL "SHARED_LIBRARY"
+ OR _type STREQUAL "STATIC_LIBRARY"
+ OR _type STREQUAL "MODULE_LIBRARY"
+ OR _type STREQUAL "EXECUTABLE")
+ get_target_property(_srcs ${tgt} SOURCES)
+ set(_dep_ressources)
+ foreach(_file ${_srcs})
+ list(APPEND _dep_ressources ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
+ endforeach()
+ else()
+ get_target_property(_dep_ressources ${tgt} RESSOURCES)
+ endif()
+
+ set(${files} ${_dep_ressources} PARENT_SCOPE)
endfunction()
diff --git a/cmake/Modules/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..511ebfa74 100644
--- a/cmake/Modules/CMakeDetermineCompiler.cmake
+++ b/cmake/Modules/CMakeDetermineCompiler.cmake
@@ -1,87 +1,103 @@
-# 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
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @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 d5b4afb33..c628e7207 100644
--- a/cmake/Modules/CMakePackagesSystem.cmake
+++ b/cmake/Modules/CMakePackagesSystem.cmake
@@ -1,855 +1,1002 @@
#===============================================================================
# @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 20 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
#
-# It can also declare multiple informations:
-# source files:
-# package_declare_sources(<package real name>
-# <src1> <src2> ... <srcn>)
+# package_list_packages(<regular_package_folder>
+# [ EXTRA_PACKAGE_FOLDER <extra_package_folder> ]
+# [ SOURCE_FOLDER <source_folder>]
+# [ TEST_FOLDER <test_folder> ]
+# [ MANUAL_FOLDER <manual_folder> ]
+# )
#
-# a LaTeX documentation:
-# package_declare_documentation(<package real name>
-# <line1> <line2> ...<linen>)
+# This command will look for packages name like ``<regular_package_folder>/<package>.cmake``
+# OR ``<extra_package_folder>/<package>/package.cmake``
#
-# LaTeX documentation files
-# package_declare_documentation_files(<package real name>
-# <file1> <file2> ... <filen>)
+#A package is a cmake script that should contain at list the declaration of a
+#package
#
-# Different function can also be retrieved from the package system by using the
-# different accessors
+#.. command:: package_declare
+#
+# 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 <lang> <flags>]
+# [SYSTEM <bool> [ <script_to_compile> ]]
+# )
+#
+#.. 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>)
#
-# package_get_compile_flags(<pkg> <retval>)
+#.. command:: package_get_compile_flags
+# package_get_compile_flags(<pkg> <lang> <retval>)
+#.. command:: package_set_compile_flags
+# package_set_compile_flags(<pkg> <lang> <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.
+#.. command:: package_set_package_system_dependency(<pkg> <system> <dep1>
+# <dep2> ... <depn>)
+# package_set_package_system_dependency(<pkg> <system> <dep1>
+# <dep2> ... <depn>)
+#.. command:: package_get_package_system_dependency(<pkg> <var>)
+# package_get_package_system_dependency(<pkg> <var>)
#
-# You 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)
+function(package_get_compile_flags pkg lang ret)
package_get_name(${pkg} _pkg_name)
- _package_get_compile_flags(${_pkg_name} _tmp)
- set(${ret} ${_tmp} PARENT_SCOPE)
+ _package_get_compile_flags(${_pkg_name} ${lang} _tmp)
+ set(${ret} "${_tmp}" PARENT_SCOPE)
+endfunction()
+
+function(package_set_compile_flags pkg lang)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_compile_flags(${_pkg_name} ${lang} ${ARGN})
+endfunction()
+
+function(package_unset_compile_flags pkg lang)
+ package_get_name(${pkg} _pkg_name)
+ _package_unset_compile_flags(${_pkg_name} ${lang})
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)
+function(package_add_to_variable variable pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_add_to_variable(${variable} ${_pkg_name} ${ARGN})
+endfunction()
+
+function(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()
+ if(_value_tmp)
+ set(${value} ${_value_tmp} PARENT_SCOPE)
+ else()
+ unset(${value} PARENT_SCOPE)
+ endif()
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Exteral package system as apt rpm dependencies
+# ------------------------------------------------------------------------------
+function(package_set_package_system_dependency pkg system)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_package_system_dependency(${_pkg_name} ${system} ${ARGN})
+endfunction()
+
+function(package_get_package_system_dependency pkg system var)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_package_system_dependency(${_pkg_name} ${sytem} _tmp)
+ set(${var} ${_tmp} PARENT_SCOPE)
+endfunction()
+# ------------------------------------------------------------------------------
# ==============================================================================
# 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()
+# ------------------------------------------------------------------------------
+# Get compilation flags
+# ------------------------------------------------------------------------------
+function(package_get_all_compilation_flags LANG FLAGS)
+ _package_get_variable_for_activated(COMPILE_${LANG}_FLAGS _tmp_flags)
+ string(REPLACE ";" " " _flags "${_tmp_flags}")
+ set(${FLAGS} ${_flags} 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()
+# ------------------------------------------------------------------------------
+# Get package systems dependencies
+# ------------------------------------------------------------------------------
+function(package_get_all_package_system_dependency system deps)
+ string(TOUPPER ${system} _u_system)
+ _package_get_variable_for_activated(PACKAGE_SYSTEM_${_u_system} _tmp)
+ set(${deps} ${_tmp} 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
- ""
+ "NO_AUTO_COMPILE_FLAGS"
"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()
+ if(_opt_pkg_NO_AUTO_COMPILE_FLAGS)
+ package_set_project_variable(NO_AUTO_COMPILE_FLAGS TRUE)
+ else()
+ package_set_project_variable(NO_AUTO_COMPILE_FLAGS FALSE)
+ 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>]
+# [COMPILE_FLAGS <lang> <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}")
+ _package_variable_unset(SRCS ${_pkg_name})
+ _package_variable_unset(PUBLIC_HEADERS ${_pkg_name})
+ _package_variable_unset(PRIVATE_HEADERS ${_pkg_name})
+
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}")
+ set(_languages C CXX Fortran)
+ cmake_parse_arguments(_compile_flags
+ "" "" "${_languages}"
+ ${_opt_pkg_COMPILE_FLAGS}
+ )
+
+
+ # this is done to maintain backward compatibility
+ if(_compile_flags_UNPARSED_ARGUMENTS)
+ set(_compile_flags_CXX ${_compile_flags_UNPARSED_ARGUMENTS})
+ endif()
+
+ foreach(_lang ${_languages})
+ if(_compile_flags_${_lang})
+ _package_set_compile_flags(${_pkg_name} ${_lang} ${_compile_flags_${_lang}})
+ else()
+ _package_unset_compile_flags(${_pkg_name} ${_lang})
+ endif()
+ endforeach()
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..268bb3999 100644
--- a/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
+++ b/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
@@ -1,98 +1,109 @@
#===============================================================================
-# @file CMakePackagesSystem.cmake
+# @file CMakePackagesSystemGlobalFunctions.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Sat Jul 18 2015
+# @date last modification: Mon Jan 18 2016
+#
# @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_add_to_project_variable variable)
+ package_get_project_variable(${variable} _tmp_list)
+ list(APPEND _tmp_list ${ARGN})
+ if(_tmp_list)
+ list(REMOVE_DUPLICATES _tmp_list)
+ endif()
+ package_set_project_variable(${variable} ${_tmp_list})
+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..028d0b4f3 100644
--- a/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
+++ b/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
@@ -1,875 +1,899 @@
#===============================================================================
-# @file CMakePackagesSystem.cmake
+# @file CMakePackagesSystemPrivateFunctions.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Sat Jul 18 2015
+# @date last modification: Wed Jan 20 2016
+#
# @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})
+function(_package_set_compile_flags pkg_name lang)
+ _package_set_variable(COMPILE_${lang}_FLAGS ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_unset_compile_flags pkg_name lang)
+ _package_variable_unset(COMPILE_${lang}_FLAGS ${pkg_name})
endfunction()
-function(_package_get_compile_flags pkg_name flags)
- _package_get_variable(COMPILE_FLAGS ${pkg_name} _flags)
- set(${flags} ${_flags} PARENT_SCOPE)
+function(_package_get_compile_flags pkg_name lang flags)
+ _package_get_variable(COMPILE_${lang}_FLAGS ${pkg_name} _tmp_flags)
+ string(REPLACE ";" " " _flags "${_tmp_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()
+# ------------------------------------------------------------------------------
+# Exteral package system as apt rpm dependencies
+# ------------------------------------------------------------------------------
+function(_package_set_package_system_dependency pkg system)
+ string(TOUPPER "${_system}" _u_system)
+ _package_set_variable(PACKAGE_SYSTEM_${_u_system} ${_pkg_name} ${ARGN})
+endfunction()
+
+
+function(_package_get_package_system_dependency pkg system var)
+ string(TOUPPER "${_system}" _u_system)
+ _package_get_variable(PACKAGE_SYSTEM_${_u_system} ${_pkg_name} ${_deps})
+ set(${var} ${_deps} PARENT_SCOPE)
+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)
+ _package_get_compile_flags(${pkg_name} CXX _pkg_compile_flags)
+ package_get_project_variable(NO_AUTO_COMPILE_FLAGS _no_auto_compile_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})
+ if(_pkg_compile_flags AND NOT _no_auto_compile_flags)
+ add_flags(cxx ${_pkg_compile_flags})
endif()
else()
#remove the comilation flags if needed
- if(_pkg_comile_flags)
- remove_flags(cxx ${_pkg_comile_flags})
+ if(_pkg_comile_flags AND NOT _no_auto_compile_flags)
+ remove_flags(cxx ${_pkg_compile_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..222d3418b 100644
--- a/cmake/Modules/CMakeVersionGenerator.cmake
+++ b/cmake/Modules/CMakeVersionGenerator.cmake
@@ -1,85 +1,85 @@
#===============================================================================
# @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
+# @date last modification: Mon Jan 18 2016
#
# @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()
+ 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
+endmacro()
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..d04be5459 100644
--- a/cmake/Modules/FindGMSH.cmake
+++ b/cmake/Modules/FindGMSH.cmake
@@ -1,82 +1,84 @@
#===============================================================================
# @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
+# @date last modification: Tue Jan 19 2016
#
# @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}"
- )
+ 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})
+ DEPENDS ${_msh_file})
set_target_properties(${MESH_TARGET} PROPERTIES RESSOURCES ${_geo_file})
- #else(EXISTS ${_geo_file})
- # message("File ${_geo_file} not found")
+ else(EXISTS ${_geo_file})
+ message(WARNING
+ "File ${_geo_file} not found for target ${MESH_TARGET}")
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 e17596ea3..036e58910 100644
--- a/cmake/Modules/FindMumps.cmake
+++ b/cmake/Modules/FindMumps.cmake
@@ -1,130 +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_library(MUMPS_LIBRARY_DMUMPS NAMES dmumps${MUMPS_PREFIX}
- HINTS ${MUMPS_DIR} /usr
- PATH_SUFFIXES lib
- )
+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()
-find_path(MUMPS_INCLUDE_DIR dmumps_c.h
- HINTS ${MUMPS_DIR}
- PATH_SUFFIXES include
- )
-
-mark_as_advanced(MUMPS_LIBRARY_COMMON)
-mark_as_advanced(MUMPS_LIBRARY_DMUMPS)
-mark_as_advanced(MUMPS_LIBRARY_PORD)
-mark_as_advanced(MUMPS_INCLUDE_DIR)
-set(MUMPS_LIBRARIES_ALL ${MUMPS_LIBRARY_DMUMPS} ${MUMPS_LIBRARY_COMMON} ${MUMPS_LIBRARY_PORD})
-
-if("${Mumps_FIND_COMPONENTS}" STREQUAL "parallel")
- find_library(BLACS_LIBRARY_C NAME blacsC
- HINTS ${MUMPS_DIR} PATH_SUFFIXES lib)
- find_library(BLACS_LIBRARY_F77 NAME blacsF77
- HINTS ${MUMPS_DIR} PATH_SUFFIXES lib)
- find_library(BLACS_LIBRARY NAME blacs
- HINTS ${MUMPS_DIR} PATH_SUFFIXES lib)
- find_library(SCALAPACK_LIBRARY NAME scalapack
- HINTS ${MUMPS_DIR} PATH_SUFFIXES lib)
-
- mark_as_advanced(BLACS_LIBRARY_C)
- mark_as_advanced(BLACS_LIBRARY_F77)
- mark_as_advanced(BLACS_LIBRARY)
- mark_as_advanced(SCALAPACK_LIBRARY)
- if(SCALAPACK_LIBRARY)
- set(BLACS_LIBRARIES_ALL ${BLACS_LIBRARIES_ALL} ${SCALAPACK_LIBRARY})
- endif()
- if(BLACS_LIBRARY_F77)
- set(BLACS_LIBRARIES_ALL ${BLACS_LIBRARIES_ALL} ${BLACS_LIBRARY_F77})
- endif()
- if(BLACS_LIBRARY)
- set(BLACS_LIBRARIES_ALL ${BLACS_LIBRARIES_ALL} ${BLACS_LIBRARY})
- endif()
- if(BLACS_LIBRARY_C)
- set(BLACS_LIBRARIES_ALL ${BLACS_LIBRARIES_ALL} ${BLACS_LIBRARY_C})
- endif()
- if(BLACS_LIBRARY_F77)
- set(BLACS_LIBRARIES_ALL ${BLACS_LIBRARIES_ALL} ${BLACS_LIBRARY_F77})
- endif()
-endif()
-
-set(MUMPS_LIBRARIES ${MUMPS_LIBRARIES_ALL} ${BLACS_LIBRARIES_ALL} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES} CACHE INTERNAL "Libraries for MUMPS" FORCE)
-
+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_LIBRARIES MUMPS_INCLUDE_DIR
- VERSION_VAR MUMPS_VERSION)
+ 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/FindPETSc.cmake b/cmake/Modules/FindPETSc.cmake
index 3c96349ab..0ca3a0c1b 100644
--- a/cmake/Modules/FindPETSc.cmake
+++ b/cmake/Modules/FindPETSc.cmake
@@ -1,345 +1,344 @@
# - Try to find PETSc
# Once done this will define
#
# PETSC_FOUND - system has PETSc
# PETSC_INCLUDES - the PETSc include directories
# PETSC_LIBRARIES - Link these to use PETSc
# PETSC_COMPILER - Compiler used by PETSc, helpful to find a compatible MPI
# PETSC_DEFINITIONS - Compiler switches for using PETSc
# PETSC_MPIEXEC - Executable for running MPI programs
# PETSC_VERSION - Version string (MAJOR.MINOR.SUBMINOR)
#
# Usage:
# find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0
# find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler
# find_package(PETSc) - same as above
#
# Setting these changes the behavior of the search
# PETSC_DIR - directory in which PETSc resides
# PETSC_ARCH - build architecture
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
set(PETSC_VALID_COMPONENTS
C
CXX)
if(NOT PETSc_FIND_COMPONENTS)
set(PETSC_LANGUAGE_BINDINGS "C")
else()
# Right now, this is designed for compatability with the --with-clanguage option, so
# only allow one item in the components list.
list(LENGTH ${PETSc_FIND_COMPONENTS} components_length)
if(${components_length} GREATER 1)
message(FATAL_ERROR "Only one component for PETSc is allowed to be specified")
endif()
# This is a stub for allowing multiple components should that time ever come. Perhaps
# to also test Fortran bindings?
foreach(component ${PETSc_FIND_COMPONENTS})
list(FIND PETSC_VALID_COMPONENTS ${component} component_location)
if(${component_location} EQUAL -1)
message(FATAL_ERROR "\"${component}\" is not a valid PETSc component.")
else()
list(APPEND PETSC_LANGUAGE_BINDINGS ${component})
endif()
endforeach()
endif()
function (petsc_get_version)
if (EXISTS "${PETSC_DIR}/include/petscversion.h")
file (STRINGS "${PETSC_DIR}/include/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(RELEASE|MAJOR|MINOR|SUBMINOR|PATCH) ")
foreach (line ${vstrings})
string (REGEX REPLACE " +" ";" fields ${line}) # break line into three fields (the first is always "#define")
list (GET fields 1 var)
list (GET fields 2 val)
set (${var} ${val} PARENT_SCOPE)
set (${var} ${val}) # Also in local scope so we have access below
endforeach ()
if (PETSC_VERSION_RELEASE)
set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}p${PETSC_VERSION_PATCH}" PARENT_SCOPE)
else ()
# make dev version compare higher than any patch level of a released version
set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}.99" PARENT_SCOPE)
endif ()
else ()
message (SEND_ERROR "PETSC_DIR can not be used, ${PETSC_DIR}/include/petscversion.h does not exist")
endif ()
endfunction ()
find_path (PETSC_DIR include/petsc.h
HINTS ENV PETSC_DIR
PATHS
# Debian paths
/usr/lib/petscdir/3.3 /usr/lib/petscdir/3.2 /usr/lib/petscdir/3.1
/usr/lib/petscdir/3.0.0 /usr/lib/petscdir/2.3.3 /usr/lib/petscdir/2.3.2
$ENV{HOME}/petsc
DOC "PETSc Directory")
find_program (MAKE_EXECUTABLE NAMES make gmake)
if (NOT PETSC_ARCH)
if (NOT ENV{PETSC_ARCH})
set(_petsc_arches
linux-gnu-c-debug linux-gnu-c-opt # Debian defaults
x86_64-unknown-linux-gnu i386-unknown-linux-gnu)
else()
set(_petsc_arches $ENV{PETSC_ARCH}) # If set, use environment variable first)
endif()
else()
set (_petsc_arches
${PETSC_ARCH})
endif()
if (NOT PETSC_DIR)
if (NOT ENV{PETSC_DIR})
set(PETSC_DIR /usr/lib/petsc)
else()
set(PETSC_DIR $ENV{PETSC_DIR}) # If set, use environment variable first)
endif()
endif()
foreach (arch ${_petsc_arches})
set (petscconf "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE)
find_path (petscconf petscconf.h
HINTS ${PETSC_DIR}
PATH_SUFFIXES ${arch}/include bmake/${arch}
NO_DEFAULT_PATH)
if(petscconf)
set (PETSC_ARCH "${arch}" CACHE STRING "PETSc build architecture")
set(_petsc_dir ${PETSC_DIR})
set (PETSC_DIR "${_petsc_dir}" CACHE STRING "PETSc build directory")
break()
endif()
endforeach()
set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS
INCLUDE_DIR INCLUDE_CONF)
include (FindPackageMultipass)
#find_package_multipass (PETSc petsc_config_current
# STATES DIR ARCH
# DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC EXECUTABLE_RUNS ${petsc_slaves})
#
# Determine whether the PETSc layout is old-style (through 2.3.3) or
# new-style (>= 3.0.0)
if (EXISTS "${PETSC_DIR}/${PETSC_ARCH}/include/petscconf.h") # > 2.3.3
set (petsc_conf_rules "${PETSC_DIR}/conf/rules")
set (petsc_conf_variables "${PETSC_DIR}/conf/variables")
elseif (EXISTS "${PETSC_DIR}/bmake/${PETSC_ARCH}/petscconf.h") # <= 2.3.3
set (petsc_conf_rules "${PETSC_DIR}/bmake/common/rules")
set (petsc_conf_variables "${PETSC_DIR}/bmake/common/variables")
elseif (PETSC_DIR)
message (SEND_ERROR "The pair PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSc installation")
endif ()
-message(petsc_conf_rules ${petsc_conf_rules})
-message(petsc_conf_variables ${petsc_conf_variables})
-message(petsc_config_current ${petsc_config_current})
-
+#message(petsc_conf_rules ${petsc_conf_rules})
+#message(petsc_conf_variables ${petsc_conf_variables})
+#message(petsc_config_current ${petsc_config_current})
if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current)
petsc_get_version()
# Put variables into environment since they are needed to get
# configuration (petscvariables) in the PETSc makefile
set (ENV{PETSC_DIR} "${PETSC_DIR}")
set (ENV{PETSC_ARCH} "${PETSC_ARCH}")
# A temporary makefile to probe the PETSc configuration
set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc")
file (WRITE "${petsc_config_makefile}"
"## This file was autogenerated by FindPETSc.cmake
# PETSC_DIR = ${PETSC_DIR}
# PETSC_ARCH = ${PETSC_ARCH}
include ${petsc_conf_rules}
include ${petsc_conf_variables}
show :
-@echo -n \${\${VARIABLE}}
")
macro (PETSC_GET_VARIABLE name var)
set (${var} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE)
execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} show VARIABLE=${name}
OUTPUT_VARIABLE ${var}
RESULT_VARIABLE petsc_return)
endmacro (PETSC_GET_VARIABLE)
petsc_get_variable (PETSC_LIB_DIR petsc_lib_dir)
petsc_get_variable (PETSC_EXTERNAL_LIB_BASIC petsc_libs_external)
petsc_get_variable (PETSC_CCPPFLAGS petsc_cpp_line)
petsc_get_variable (PETSC_INCLUDE petsc_include)
petsc_get_variable (PCC petsc_cc)
petsc_get_variable (PCC_FLAGS petsc_cc_flags)
petsc_get_variable (MPIEXEC petsc_mpiexec)
# We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid!
file (REMOVE ${petsc_config_makefile})
include (ResolveCompilerPaths)
# Extract include paths and libraries from compile command line
resolve_includes (petsc_includes_all "${petsc_cpp_line}")
#on windows we need to make sure we're linking against the right
#runtime library
if (WIN32)
if (petsc_cc_flags MATCHES "-MT")
set(using_md False)
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
set(using_md True)
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
if(${using_md} MATCHES "True")
message(WARNING "PETSc was built with /MT, but /MD is currently set.
See http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F")
endif(${using_md} MATCHES "True")
endif (petsc_cc_flags MATCHES "-MT")
endif (WIN32)
include (CorrectWindowsPaths)
convert_cygwin_path(petsc_lib_dir)
message (STATUS "petsc_lib_dir ${petsc_lib_dir}")
macro (PETSC_FIND_LIBRARY suffix name)
set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # Clear any stale value, if we got here, we need to find it again
if (WIN32)
set (libname lib${name}) #windows expects "libfoo", linux expects "foo"
else (WIN32)
set (libname ${name})
endif (WIN32)
find_library (PETSC_LIBRARY_${suffix} NAMES ${libname} HINTS ${petsc_lib_dir} NO_DEFAULT_PATH)
set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}")
mark_as_advanced (PETSC_LIBRARY_${suffix})
endmacro (PETSC_FIND_LIBRARY suffix name)
# Look for petscvec first, if it doesn't exist, we must be using single-library
petsc_find_library (VEC petscvec)
if (PETSC_LIBRARY_VEC)
petsc_find_library (SYS "petscsys;petsc") # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced)
petsc_find_library (MAT petscmat)
petsc_find_library (DM petscdm)
petsc_find_library (KSP petscksp)
petsc_find_library (SNES petscsnes)
petsc_find_library (TS petscts)
macro (PETSC_JOIN libs deps)
list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}})
endmacro (PETSC_JOIN libs deps)
petsc_join (VEC SYS)
petsc_join (MAT VEC)
petsc_join (DM MAT)
petsc_join (KSP DM)
petsc_join (SNES KSP)
petsc_join (TS SNES)
petsc_join (ALL TS)
else ()
petsc_find_library (SINGLE petsc)
foreach (pkg SYS VEC MAT DM KSP SNES TS ALL)
set (PETSC_LIBRARIES_${pkg} "${PETSC_LIBRARY_SINGLE}")
endforeach ()
set (PETSC_LIBRARY_VEC "${PETSC_LIBRARY_SINGLE}" CACHE INTERNAL "Cleared" FORCE) # There is no libpetscvec
endif ()
if (PETSC_LIBRARY_TS)
message (STATUS "Recognized PETSc install with separate libraries for each package")
else ()
message (STATUS "Recognized PETSc install with single library for all packages")
endif ()
include(Check${PETSC_LANGUAGE_BINDINGS}SourceRuns)
macro (PETSC_TEST_RUNS includes libraries runs)
if(${PETSC_LANGUAGE_BINDINGS} STREQUAL "C")
set(_PETSC_ERR_FUNC "CHKERRQ(ierr)")
elseif(${PETSC_LANGUAGE_BINDINGS} STREQUAL "CXX")
set(_PETSC_ERR_FUNC "CHKERRXX(ierr)")
endif()
if (PETSC_VERSION VERSION_GREATER 3.1)
set (_PETSC_TSDestroy "TSDestroy(&ts)")
else ()
set (_PETSC_TSDestroy "TSDestroy(ts)")
endif ()
set(_PETSC_TEST_SOURCE "
static const char help[] = \"PETSc test program.\";
#include <petscts.h>
int main(int argc,char *argv[]) {
PetscErrorCode ierr;
TS ts;
ierr = PetscInitialize(&argc,&argv,0,help);${_PETSC_ERR_FUNC};
ierr = TSCreate(PETSC_COMM_WORLD,&ts);${_PETSC_ERR_FUNC};
ierr = TSSetFromOptions(ts);${_PETSC_ERR_FUNC};
ierr = ${_PETSC_TSDestroy};${_PETSC_ERR_FUNC};
ierr = PetscFinalize();${_PETSC_ERR_FUNC};
return 0;
}
")
multipass_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs} "${PETSC_LANGUAGE_BINDINGS}")
if (${${runs}})
set (PETSC_EXECUTABLE_RUNS "YES" CACHE BOOL
"Can the system successfully run a PETSc executable? This variable can be manually set to \"YES\" to force CMake to accept a given PETSc configuration, but this will almost always result in a broken build. If you change PETSC_DIR, PETSC_ARCH, or PETSC_CURRENT you would have to reset this variable." FORCE)
endif (${${runs}})
endmacro (PETSC_TEST_RUNS)
find_path (PETSC_INCLUDE_DIR petscts.h HINTS "${PETSC_DIR}" PATH_SUFFIXES include NO_DEFAULT_PATH)
find_path (PETSC_INCLUDE_CONF petscconf.h HINTS "${PETSC_DIR}" PATH_SUFFIXES "${PETSC_ARCH}/include" "bmake/${PETSC_ARCH}" NO_DEFAULT_PATH)
mark_as_advanced (PETSC_INCLUDE_DIR PETSC_INCLUDE_CONF)
set (petsc_includes_minimal ${PETSC_INCLUDE_CONF} ${PETSC_INCLUDE_DIR})
petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_minimal)
if (petsc_works_minimal)
message (STATUS "Minimal PETSc includes and libraries work. This probably means we are building with shared libs.")
set (petsc_includes_needed "${petsc_includes_minimal}")
else (petsc_works_minimal) # Minimal includes fail, see if just adding full includes fixes it
petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_allincludes)
if (petsc_works_allincludes) # It does, we just need all the includes (
message (STATUS "PETSc requires extra include paths, but links correctly with only interface libraries. This is an unexpected configuration (but it seems to work fine).")
set (petsc_includes_needed ${petsc_includes_all})
else (petsc_works_allincludes) # We are going to need to link the external libs explicitly
resolve_libraries (petsc_libraries_external "${petsc_libs_external}")
foreach (pkg SYS VEC MAT DM KSP SNES TS ALL)
list (APPEND PETSC_LIBRARIES_${pkg} ${petsc_libraries_external})
endforeach (pkg)
petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_alllibraries)
if (petsc_works_alllibraries)
message (STATUS "PETSc only need minimal includes, but requires explicit linking to all dependencies. This is expected when PETSc is built with static libraries.")
set (petsc_includes_needed ${petsc_includes_minimal})
else (petsc_works_alllibraries)
# It looks like we really need everything, should have listened to Matt
set (petsc_includes_needed ${petsc_includes_all})
petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_all)
if (petsc_works_all) # We fail anyways
message (STATUS "PETSc requires extra include paths and explicit linking to all dependencies. This probably means you have static libraries and something unexpected in PETSc headers.")
else (petsc_works_all) # We fail anyways
message (STATUS "PETSc could not be used, maybe the install is broken.")
endif (petsc_works_all)
endif (petsc_works_alllibraries)
endif (petsc_works_allincludes)
endif (petsc_works_minimal)
# We do an out-of-source build so __FILE__ will be an absolute path, hence __INSDIR__ is superfluous
if (${PETSC_VERSION} VERSION_LESS 3.1)
set (PETSC_DEFINITIONS "-D__SDIR__=\"\"" CACHE STRING "PETSc definitions" FORCE)
else ()
set (PETSC_DEFINITIONS "-D__INSDIR__=" CACHE STRING "PETSc definitions" FORCE)
endif ()
# Sometimes this can be used to assist FindMPI.cmake
set (PETSC_MPIEXEC ${petsc_mpiexec} CACHE FILEPATH "Executable for running PETSc MPI programs" FORCE)
set (PETSC_INCLUDES ${petsc_includes_needed} CACHE STRING "PETSc include path" FORCE)
set (PETSC_LIBRARIES ${PETSC_LIBRARIES_ALL} CACHE STRING "PETSc libraries" FORCE)
set (PETSC_COMPILER ${petsc_cc} CACHE FILEPATH "PETSc compiler" FORCE)
# Note that we have forced values for all these choices. If you
# change these, you are telling the system to trust you that they
# work. It is likely that you will end up with a broken build.
mark_as_advanced (PETSC_INCLUDES PETSC_LIBRARIES PETSC_COMPILER PETSC_DEFINITIONS PETSC_MPIEXEC PETSC_EXECUTABLE_RUNS)
endif ()
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (PETSc
"PETSc could not be found. Be sure to set PETSC_DIR and PETSC_ARCH."
PETSC_INCLUDES PETSC_LIBRARIES PETSC_EXECUTABLE_RUNS)
diff --git a/cmake/Modules/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..d92a77fd8 100644
--- a/cmake/Modules/FindParaDiS.cmake
+++ b/cmake/Modules/FindParaDiS.cmake
@@ -1,45 +1,45 @@
#===============================================================================
# @file FindParaDiS.cmake
#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @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 f4ab77ff6..b2f203f52 100644
--- a/cmake/Modules/FindScaLAPACK.cmake
+++ b/cmake/Modules/FindScaLAPACK.cmake
@@ -1,74 +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(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)
-
find_library(SCALAPACK_LIBRARY NAME scalapack
HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib)
-mark_as_advanced(BLACS_LIBRARY_C)
-mark_as_advanced(BLACS_LIBRARY_F77)
-mark_as_advanced(BLACS_LIBRARY)
mark_as_advanced(SCALAPACK_LIBRARY)
-if(SCALAPACK_LIBRARY)
- list(APPEND SCALAPACK_LIBRARIES_ALL ${SCALAPACK_LIBRARY})
-endif()
-if(BLACS_LIBRARY_F77)
- list(APPEND SCALAPACK_LIBRARIES_ALL ${BLACS_LIBRARY_F77})
-endif()
-if(BLACS_LIBRARY)
- list(APPEND SCALAPACK_LIBRARIES_ALL ${BLACS_LIBRARY})
-endif()
-if(BLACS_LIBRARY_C)
- list(APPEND SCALAPACK_LIBRARIES_ALL ${BLACS_LIBRARY_C})
-endif()
-if(BLACS_LIBRARY_F77)
- list(APPEND SCALAPACK_LIBRARIES_ALL ${BLACS_LIBRARY_F77})
-endif()
-
-set(SCALAPACK_LIBRARIES ${SCALAPACK_LIBRARIES_ALL} CACHE INTERNAL "Libraries for MUMPS" FORCE)
#===============================================================================
-if(NOT MUMPS_FOUND)
+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_LIBRARIES SCALAPACK_INCLUDE_DIR)
\ No newline at end of file
+ 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 3cfc42c67..b73aa3cdd 100644
--- a/cmake/Modules/FindScotch.cmake
+++ b/cmake/Modules/FindScotch.cmake
@@ -1,116 +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/>.
#
#===============================================================================
#===============================================================================
-find_library(SCOTCH_LIBRARY scotch
- HINTS ${SCOTCH_DIR}
- PATH_SUFFIXES src/libscotch lib
- )
-
-find_library(SCOTCH_LIBRARY_ERR scotcherr
- HINTS ${SCOTCH_DIR}
- PATH_SUFFIXES src/libscotch lib
- )
-
-find_library(SCOTCH_LIBRARY_ERREXIT scotcherrexit
- HINTS ${SCOTCH_DIR}
- PATH_SUFFIXES src/libscotch lib
- )
-
-find_library(SCOTCH_LIBRARY_ESMUMPS esmumps
- HINTS ${SCOTCH_DIR}
- PATH_SUFFIXES src/libscotch lib
- )
-
-find_library(SCOTCH_LIBRARY_METIS scotchmetis
- PATHS ${SCOTCH_DIR}
- PATH_SUFFIXES src/libscotch lib
- )
+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_PARMETIS scotchparmetis
- PATHS ${SCOTCH_DIR}
- PATH_SUFFIXES src/libscotch lib
- )
+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
- HINTS ${SCOTCH_DIR}
- PATH_SUFFIXES include scotch src/libscotch include/scotch
+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()
-
-#===============================================================================
-if(NOT SCOTCH_FOUND)
- set(SCOTCH_DIR "" CACHE PATH "Location of Scotch library.")
- mark_as_advanced(SCOTCH_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/akantu_environement.csh.in b/cmake/akantu_environement.csh.in
new file mode 100644
index 000000000..55e6493f4
--- /dev/null
+++ b/cmake/akantu_environement.csh.in
@@ -0,0 +1,2 @@
+setenv PYTHONPATH $PYTHONPATH:@PROJECT_BINARY_DIR@/python
+setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:@PROJECT_BINARY_DIR@/src
diff --git a/cmake/akantu_environement.sh.in b/cmake/akantu_environement.sh.in
new file mode 100644
index 000000000..59ea4b2fc
--- /dev/null
+++ b/cmake/akantu_environement.sh.in
@@ -0,0 +1,2 @@
+export PYTHONPATH=$PYTHONPATH:@PROJECT_BINARY_DIR@/python
+export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:@PROJECT_BINARY_DIR@/src
diff --git a/cmake/akantu_install_environement.csh.in b/cmake/akantu_install_environement.csh.in
new file mode 100644
index 000000000..254b9a6a7
--- /dev/null
+++ b/cmake/akantu_install_environement.csh.in
@@ -0,0 +1,2 @@
+setenv PYTHONPATH $PYTHONPATH:@AKANTU_PYTHON_INSTALL_PREFIX@/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
+setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:@CMAKE_INSTALL_PREFIX@/lib
diff --git a/cmake/akantu_install_environement.sh.in b/cmake/akantu_install_environement.sh.in
new file mode 100644
index 000000000..1dc7ef299
--- /dev/null
+++ b/cmake/akantu_install_environement.sh.in
@@ -0,0 +1,2 @@
+export PYTHONPATH=$PYTHONPATH:@AKANTU_PYTHON_INSTALL_PREFIX@/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
+export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:@CMAKE_INSTALL_PREFIX@/lib
diff --git a/cmake/akantu_test_driver.sh b/cmake/akantu_test_driver.sh
index 939ea448b..0e01c69ba 100755
--- a/cmake/akantu_test_driver.sh
+++ b/cmake/akantu_test_driver.sh
@@ -1,110 +1,120 @@
#!/bin/bash
set -o errexit
+set -o pipefail
show_help() {
cat << EOF
Usage: ${0##*/} -n NAME -e EXECUTABLE [-p MPI_WRAPPER] [-s SCRIPT_FILE]
[-r REFERENCE_FILE] [-w WORKING_DIR]
Execute the test in the good configuration according to the options given
-e EXECUTABLE Main executable of the test
-n NAME Name of the test
-p MPI_WRAPPER Executes the test for multiple parallel configuration
-s SCRIPT_FILE Script to execute after the execution of the test to
postprocess the results
-r REFERENCE_FILE Reference file to compare with if the name of the file
contains a <nb_proc> this will be used for the different
configuration when -p is given
-w WORKING_DIR The directory in which to execute the test
+ -E ENVIRONMENT_FILE File to source before running tests
-h Print this helps
EOF
}
full_redirect() {
local nproc=$1
shift
local name=$1
shift
local sout=".lastout"
local serr=".lasterr"
if [ ${nproc} -ne 0 ]; then
sout="-${nproc}${sout}"
serr="-${nproc}${serr}"
fi
(($* | tee "${name}${sout}") 3>&1 1>&2 2>&3 | tee "${name}${serr}") 3>&1 1>&2 2>&3
lastout="${name}${sout}"
}
name=
executable=
parallel=
postprocess_script=
reference=
working_dir=
+envi=
-while getopts ":n:e:p:s:r:w:h" opt; do
+while getopts ":n:e:E:p:s:r:w:h" opt; do
case "$opt" in
n) name="$OPTARG"
;;
e) executable="$OPTARG"
;;
p) parallel="$OPTARG"
;;
s) postprocess_script="$OPTARG"
;;
r) reference="$OPTARG"
;;
w) working_dir="$OPTARG"
;;
+ E) envi="$OPTARG"
+ echo toto
+ ;;
h)
show_help
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
show_help
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
show_help
exit 1
;;
esac
done
+if [ -n "${envi}" ]; then
+ source ${envi}
+fi
+
if [ -z "${name}" -o -z "${executable}" ]; then
echo "Missing executable or name"
show_help
exit 1
fi
if [ -n "${working_dir}" ]; then
current_directory=$PWD
echo "Entering directory ${working_dir}"
cd "${working_dir}"
fi
if [ -z "${parallel}" ]; then
echo "Executing the test ${name}"
full_redirect 0 ${name} "./${executable}"
else
for i in ${parallel_processes}; do
echo "Executing the test ${name} for ${i} procs"
full_redirect $i ${name}_$i "${parallel_processes} ${i} ./${executable}"
done
fi
if [ -n "${postprocess_script}" ]; then
echo "Executing the test ${name} post-processing"
full_redirect 0 ${name}_pp ./${postprocess_script}
fi
if [ -n "${reference}" ]; then
echo "Comparing last generated output to the reference file"
diff ${lastout} ${reference}
fi
diff --git a/cmake/material_lister.cc b/cmake/material_lister.cc
index 8ee3a2ea3..03cbe26b4 100644
--- a/cmake/material_lister.cc
+++ b/cmake/material_lister.cc
@@ -1,54 +1,53 @@
/**
* @file material_lister.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Mar 21 2014
* @date last modification: Fri Mar 21 2014
*
* @brief Small code that print out the list of materials
*
* @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 "material_list.hh"
#include <boost/preprocessor.hpp>
#include <iostream>
-int main(int argc, char *argv[]) {
-#define PRINT_OUT_OPTIONS(r, data, i, elem) \
+int main(__attribute__((unused)) int argc,
+ __attribute__((unused)) char * argv[]) {
+#define PRINT_OUT_OPTIONS(r, data, i, elem) \
<< ":" << BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 0, elem))
-#define PRINT_OUT(r, data, elem) \
- std::cout << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(0, elem)) << ":" \
- << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(1, elem)) \
- BOOST_PP_IF(BOOST_PP_EQUAL(3, BOOST_PP_ARRAY_SIZE(elem)), \
- BOOST_PP_SEQ_FOR_EACH_I(PRINT_OUT_OPTIONS, \
- _, \
- BOOST_PP_ARRAY_ELEM(2, elem)), \
- ) \
- << std::endl;
+#define PRINT_OUT(r, data, elem) \
+ std::cout << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(0, elem)) << ":" \
+ << BOOST_PP_STRINGIZE(BOOST_PP_ARRAY_ELEM(1, elem)) BOOST_PP_IF( \
+ BOOST_PP_EQUAL(3, BOOST_PP_ARRAY_SIZE(elem)), \
+ BOOST_PP_SEQ_FOR_EACH_I(PRINT_OUT_OPTIONS, _, \
+ BOOST_PP_ARRAY_ELEM(2, elem)), ) \
+ << std::endl;
BOOST_PP_SEQ_FOR_EACH(PRINT_OUT, _, AKANTU_MATERIAL_LIST);
return 0;
}
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..9faa24820 100644
--- a/doc/doxygen/CMakeLists.txt
+++ b/doc/doxygen/CMakeLists.txt
@@ -1,73 +1,70 @@
#===============================================================================
# @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: Mon Jan 18 2016
#
# @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
+ OUTPUT ${DOXYGEN_OUTPUT}
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/doxygen/akantu.dox.in b/doc/doxygen/akantu.dox.in
index dd00b4ae5..ca5cc4d45 100644
--- a/doc/doxygen/akantu.dox.in
+++ b/doc/doxygen/akantu.dox.in
@@ -1,1818 +1,1773 @@
# Doxyfile 1.7.6.1
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# http://www.gnu.org/software/libiconv for the list of possible encodings.
DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or sequence of words) that should
# identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces.
PROJECT_NAME = @CMAKE_PROJECT_NAME@
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = @AKANTU_VERSION@
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
# a quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF =
# With the PROJECT_LOGO tag one can specify an logo or icon that is
# included in the documentation. The maximum height of the logo should not
# exceed 55 pixels and the maximum width should not exceed 200 pixels.
# Doxygen will copy the logo to the output directory.
PROJECT_LOGO =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = .
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
# format and will distribute the generated files over these directories.
# Enabling this option can be useful when feeding doxygen a huge amount of
# source files, where putting all generated files in the same directory would
# otherwise cause performance problems for the file system.
CREATE_SUBDIRS = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
OUTPUT_LANGUAGE = English
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# This tag implements a quasi-intelligent brief description abbreviator
# that is used to form the text in various listings. Each string
# in this list, if found as the leading text of the brief description, will be
# stripped from the text and the result after processing the whole list, is
# used as the annotated text. Otherwise, the brief description is used as-is.
# If left blank, the following values are used ("$name" is automatically
# replaced with the name of the entity): "The $name class" "The $name widget"
# "The $name file" "is" "provides" "specifies" "contains"
# "represents" "a" "an" "the"
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = YES
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user-defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the
# path to strip.
STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
# the path mentioned in the documentation of a class, which tells
# the reader which header file to include in order to use a class.
# If left blank only the name of the header file containing the class
# definition is used. Otherwise one should specify the include paths that
# are normally passed to the compiler using the -I flag.
STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful if your file system
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like regular Qt-style comments
# (thus requiring an explicit @brief command for a brief description.)
JAVADOC_AUTOBRIEF = NO
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
# interpret the first line (until the first dot) of a Qt-style
# comment as the brief description. If set to NO, the comments
# will behave just like regular Qt-style comments (thus requiring
# an explicit \brief command for a brief description.)
QT_AUTOBRIEF = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
# comments) as a brief description. This used to be the default behaviour.
# The new default is to treat a multi-line C++ comment block as a detailed
# description. Set this tag to YES if you prefer the old behaviour instead.
MULTILINE_CPP_IS_BRIEF = NO
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# re-implements.
INHERIT_DOCS = YES
# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
# a new page for each member. If set to NO, the documentation of a member will
# be part of the file/class/namespace that contains it.
SEPARATE_MEMBER_PAGES = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 4
# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user-defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding
# "class=itcl::class" will allow you to use the command class in the
# itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
# For instance, some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = NO
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
# sources only. Doxygen will then generate output that is more tailored for
# Java. For instance, namespaces will be presented as packages, qualified
# scopes will look different, etc.
OPTIMIZE_OUTPUT_JAVA = NO
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources only. Doxygen will then generate output that is more tailored for
# Fortran.
OPTIMIZE_FOR_FORTRAN = NO
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
# sources. Doxygen will then generate output that is tailored for
# VHDL.
OPTIMIZE_OUTPUT_VHDL = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given extension.
# Doxygen has a built-in mapping, but you can override or extend it using this
# tag. The format is ext=language, where ext is a file extension, and language
# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
EXTENSION_MAPPING =
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should
# set this tag to YES in order to let doxygen match functions declarations and
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
# func(std::string) {}). This also makes the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
BUILTIN_STL_SUPPORT = NO
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
CPP_CLI_SUPPORT = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
# Doxygen will parse them like normal C++ but will assume all classes use public
# instead of private inheritance when no explicit protection keyword is present.
SIP_SUPPORT = NO
# For Microsoft's IDL there are propget and propput attributes to indicate getter
# and setter methods for a property. Setting this option to YES (the default)
# will make doxygen replace the get and set methods by a property in the
# documentation. This will only work if the methods are indeed getting or
# setting a simple type. If this is not the case, or you want to show the
# methods anyway, you should set this option to NO.
IDL_PROPERTY_SUPPORT = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
# the same type (for instance a group of public functions) to be put as a
# subgroup of that type (e.g. under the Public Functions section). Set it to
# NO to prevent subgrouping. Alternatively, this can be done per class using
# the \nosubgrouping command.
SUBGROUPING = YES
# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
# unions are shown inside the group in which they are included (e.g. using
# @ingroup) instead of on a separate page (for HTML and Man pages) or
# section (for LaTeX and RTF).
INLINE_GROUPED_CLASSES = NO
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
# unions with only public data fields will be shown inline in the documentation
# of the scope in which they are defined (i.e. file, namespace, or group
# documentation), provided this scope is documented. If set to NO (the default),
# structs, classes, and unions are shown on a separate page (for HTML and Man
# pages) or section (for LaTeX and RTF).
INLINE_SIMPLE_STRUCTS = NO
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
# is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
# with name TypeT. When disabled the typedef will appear as a member of a file,
# namespace, or class. And the struct will be named TypeS. This can typically
# be useful for C code in case the coding convention dictates that all compound
# types are typedef'ed and only the typedef is referenced, never the tag name.
TYPEDEF_HIDES_STRUCT = NO
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
-# determine which symbols to keep in memory and which to flush to disk.
-# When the cache is full, less often used symbols will be written to disk.
-# For small to medium size projects (<1000 input files) the default value is
-# probably good enough. For larger projects a too small cache size can cause
-# doxygen to be busy swapping symbols to and from disk most of the time
-# causing a significant performance penalty.
-# If the system has enough physical memory increasing the cache will improve the
-# performance by keeping more symbols in memory. Note that the value works on
-# a logarithmic scale so increasing the size by one will roughly double the
-# memory usage. The cache size is given by this formula:
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols.
-
-SYMBOL_CACHE_SIZE = 0
-
# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
# their name and scope. Since this can be an expensive process and often the
# same symbol appear multiple times in the code, doxygen keeps a cache of
# pre-resolved symbols. If the cache is too small doxygen will become slower.
# If the cache is too large, memory is wasted. The cache size is given by this
# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
# corresponding to a cache size of 2^16 = 65536 symbols.
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES = YES
# This flag is only useful for Objective-C code. When set to YES local
# methods, which are defined in the implementation section but not in
# the interface are included in the documentation.
# If set to NO (the default) only methods in the interface are included.
EXTRACT_LOCAL_METHODS = NO
# If this flag is set to YES, the members of anonymous namespaces will be
# extracted and appear in the documentation as a namespace called
# 'anonymous_namespace{file}', where file will be replaced with the base
# name of the file that contains the anonymous namespace. By default
# anonymous namespaces are hidden.
EXTRACT_ANON_NSPACES = NO
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these classes will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
# friend (class|struct|union) declarations.
# If set to NO (the default) these declarations will be included in the
# documentation.
HIDE_FRIEND_COMPOUNDS = NO
# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
# documentation blocks found inside the body of a function.
# If set to NO (the default) these blocks will be appended to the
# function's detailed documentation block.
HIDE_IN_BODY_DOCS = NO
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
# file names in lower-case letters. If set to YES upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
CASE_SENSE_NAMES = NO
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put a list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
# will list include files with double quotes in the documentation
# rather than with sharp brackets.
FORCE_LOCAL_INCLUDES = NO
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
# brief documentation of file, namespace and class members alphabetically
# by member name. If set to NO (the default) the members will appear in
# declaration order.
SORT_BRIEF_DOCS = NO
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
# will sort the (brief and detailed) documentation of class members so that
# constructors and destructors are listed first. If set to NO (the default)
# the constructors will appear in the respective orders defined by
# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
SORT_MEMBERS_CTORS_1ST = NO
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
# hierarchy of group names into alphabetical order. If set to NO (the default)
# the group names will appear in their defined order.
SORT_GROUP_NAMES = NO
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
# sorted by fully-qualified names, including namespaces. If set to
# NO (the default), the class list will be sorted only by class name,
# not including the namespace part.
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
# Note: This option applies only to the class list, not to the
# alphabetical list.
SORT_BY_SCOPE_NAME = NO
# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
# do proper type resolution of all parameters of a function it will reject a
# match between the prototype and the implementation of a member function even
# if there is only one candidate or it is obvious which candidate to choose
# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
# will still accept a match between prototype and implementation in such cases.
STRICT_PROTO_MATCHING = NO
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
# The GENERATE_BUGLIST tag can be used to enable (YES) or
# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.
GENERATE_BUGLIST = YES
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
# disable (NO) the deprecated list. This list is created by putting
# \deprecated commands in the documentation.
GENERATE_DEPRECATEDLIST= YES
# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
# the initial value of a variable or macro consists of for it to appear in
# the documentation. If the initializer consists of more lines than specified
# here it will be hidden. Use a value of 0 to hide initializers completely.
# The appearance of the initializer of individual variables and macros in the
# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
MAX_INITIALIZER_LINES = 30
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
SHOW_USED_FILES = YES
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES = NO
-
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
# This will remove the Files entry from the Quick Index and from the
# Folder Tree View (if specified). The default is YES.
SHOW_FILES = YES
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
# Namespaces page. This will remove the Namespaces entry from the Quick Index
# and from the Folder Tree View (if specified). The default is YES.
SHOW_NAMESPACES = YES
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from
# the version control system). Doxygen will invoke the program by executing (via
# popen()) the command <command> <input-file>, where <command> is the value of
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
# provided by doxygen. Whatever the program writes to standard output
# is used as the file version. See the manual for examples.
FILE_VERSION_FILTER =
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
# output files in an output format independent way. The create the layout file
# that represents doxygen's defaults, run doxygen with the -l option.
# You can optionally specify a file name after the option, if omitted
# DoxygenLayout.xml will be used as the name of the layout file.
LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files
# containing the references data. This must be a list of .bib files. The
# .bib extension is automatically appended if omitted. Using this command
# requires the bibtex tool to be installed. See also
# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
# feature you need bibtex and perl available in the search path.
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
-QUIET = NO
+QUIET = YES
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = NO
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = NO
# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some
# parameters in a documented function, or documenting parameters that
# don't exist or using markup commands wrongly.
WARN_IF_DOC_ERROR = NO
# The WARN_NO_PARAMDOC option can be enabled to get warnings for
# functions that are documented, but have no documentation for their parameters
# or return value. If set to NO (the default) doxygen will only warn about
# wrong or incomplete parameter documentation, but not about the absence of
# documentation.
WARN_NO_PARAMDOC = NO
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text. Optionally the format may contain
# $version, which will be replaced by the version of the file (if it could
# be obtained via FILE_VERSION_FILTER)
WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning
# and error messages should be written. If left blank the output is written
# to stderr.
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = @CMAKE_SOURCE_DIR@/src
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
# also the default input encoding. Doxygen uses libiconv (or the iconv built
# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
# the list of possible encodings.
INPUT_ENCODING = UTF-8
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank the following patterns are tested:
# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
# *.f90 *.f *.for *.vhd *.vhdl
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.d \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.idl \
*.odl \
*.cs \
*.php \
*.php3 \
*.inc \
*.m \
*.mm \
*.dox \
*.py \
*.f90 \
*.f \
*.for \
*.vhd \
*.vhdl
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE = @CMAKE_SOURCE_DIR@/src/aka_fwd.hh
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
# from the input.
EXCLUDE_SYMLINKS = NO
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories. Note that the wildcards are matched
# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
EXCLUDE_SYMBOLS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/test
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS = *
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude
# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.
EXAMPLE_RECURSIVE = NO
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output. If FILTER_PATTERNS is specified, this tag will be
# ignored.
INPUT_FILTER =
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis. Doxygen will compare the file name with each pattern and apply the
# filter if there is a match. The filters are a list of the form:
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
# info on how filters are used. If FILTER_PATTERNS is empty or if
# non of the patterns match the file name, INPUT_FILTER is applied.
FILTER_PATTERNS =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse (i.e. when SOURCE_BROWSER is set to YES).
FILTER_SOURCE_FILES = NO
# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
# and it is also possible to disable source filtering for a specific pattern
# using *.ext= (so without naming a filter). This option only has effect when
# FILTER_SOURCE_FILES is enabled.
FILTER_SOURCE_PATTERNS =
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
# Note: To get rid of all source code in the generated output, make sure also
# VERBATIM_HEADERS is set to NO.
SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES
# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = NO
# If the REFERENCES_RELATION tag is set to YES
# then for each documented function all documented entities
# called/used by that function will be listed.
REFERENCES_RELATION = NO
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
# link to the source code. Otherwise they will link to the documentation.
REFERENCES_LINK_SOURCE = YES
# If the USE_HTAGS tag is set to YES then the references to source code
# will point to the HTML generated by the htags(1) tool instead of doxygen
# built-in source browser. The htags tool is part of GNU's global source
# tagging system (see http://www.gnu.org/software/global/global.html). You
# will need version 4.8.6 or higher.
USE_HTAGS = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = YES
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.
HTML_FILE_EXTENSION = .html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header. Note that when using a custom header you are responsible
# for the proper inclusion of any scripts and style sheets that doxygen
# needs, which is dependent on the configuration options used.
# It is advised to generate a default header using "doxygen -w html
# header.html footer.html stylesheet.css YourConfigFile" and then modify
# that header. Note that the header is subject to change so you typically
# have to redo this when upgrading to a newer version of doxygen or when
# changing the value of configuration settings such as GENERATE_TREEVIEW!
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet. Note that doxygen will try to copy
# the style sheet file to the HTML output directory, so don't put your own
# style sheet in the HTML output directory as well, or it will be erased!
HTML_STYLESHEET =
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
# that these files will be copied to the base HTML output directory. Use the
# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
# files. In the HTML_STYLESHEET file, use the file name only. Also note that
# the files will be copied as-is; there are no commands or markers available.
HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
# Doxygen will adjust the colors in the style sheet and background images
# according to this color. Hue is specified as an angle on a colorwheel,
# see http://en.wikipedia.org/wiki/Hue for more information.
# For instance the value 0 represents red, 60 is yellow, 120 is green,
# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
# The allowed range is 0 to 359.
HTML_COLORSTYLE_HUE = 220
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
# the colors in the HTML output. For a value of 0 the output will use
# grayscales only. A value of 255 will produce the most vivid colors.
HTML_COLORSTYLE_SAT = 100
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
# the luminance component of the colors in the HTML output. Values below
# 100 gradually make the output lighter, whereas values above 100 make
# the output darker. The value divided by 100 is the actual gamma applied,
# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
# and 100 does not change the gamma.
HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP = YES
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded. For this to work a browser that supports
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
HTML_DYNAMIC_SECTIONS = NO
# If the GENERATE_DOCSET tag is set to YES, additional index files
# will be generated that can be used as input for Apple's Xcode 3
# integrated development environment, introduced with OSX 10.5 (Leopard).
# To create a documentation set, doxygen will generate a Makefile in the
# HTML output directory. Running make will produce the docset in that
# directory and running "make install" will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
# it at startup.
# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
GENERATE_DOCSET = NO
# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
# feed. A documentation feed provides an umbrella under which multiple
# documentation sets from a single provider (such as a company or product suite)
# can be grouped.
DOCSET_FEEDNAME = "Doxygen generated docs"
# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
# should uniquely identify the documentation set bundle. This should be a
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
# will append .docset to the name.
DOCSET_BUNDLE_ID = org.doxygen.Project
# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
# the documentation publisher. This should be a reverse domain-name style
# string, e.g. com.mycompany.MyDocSet.documentation.
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
# be used to specify the file name of the resulting .chm file. You
# can add a path in front of the file if the result should not be
# written to the html output directory.
CHM_FILE =
# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
# be used to specify the location (absolute path including file name) of
# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
# the HTML help compiler on the generated index.hhp.
HHC_LOCATION =
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
# content.
CHM_INDEX_ENCODING =
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the HTML help documentation and to the tree view.
TOC_EXPAND = NO
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
# that can be used as input for Qt's qhelpgenerator to generate a
# Qt Compressed Help (.qch) of the generated HTML documentation.
GENERATE_QHP = NO
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
# be used to specify the file name of the resulting .qch file.
# The path specified is relative to the HTML output folder.
QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#namespace
QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#virtual-folders
QHP_VIRTUAL_FOLDER = doc
# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
# add. For more information please see
# http://doc.trolltech.com/qthelpproject.html#custom-filters
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see
# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
# Qt Help Project / Custom Filters</a>.
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's
# filter section matches.
# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
# Qt Help Project / Filter Attributes</a>.
QHP_SECT_FILTER_ATTRS =
# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
# be used to specify the location of Qt's qhelpgenerator.
# If non-empty doxygen will try to run qhelpgenerator on the generated
# .qhp file.
QHG_LOCATION =
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
# will be generated, which together with the HTML files, form an Eclipse help
# plugin. To install this plugin and make it available under the help contents
# menu in Eclipse, the contents of the directory containing the HTML and XML
# files needs to be copied into the plugins directory of eclipse. The name of
# the directory within the plugins directory should be the same as
# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
# the help appears.
GENERATE_ECLIPSEHELP = NO
# A unique identifier for the eclipse help plugin. When installing the plugin
# the directory name containing the HTML and XML files should also have
# this name.
ECLIPSE_DOC_ID = org.doxygen.Project
# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
# at top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it. Since the tabs have the same information as the
# navigation tree you can set this option to NO if you already set
# GENERATE_TREEVIEW to YES.
DISABLE_INDEX = NO
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information.
# If the tag value is set to YES, a side panel will be generated
# containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
# Windows users are probably better off using the HTML help feature.
# Since the tree basically has the same information as the tab index you
# could consider to set DISABLE_INDEX to NO when enabling this option.
GENERATE_TREEVIEW = NO
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
# (range [0,1..20]) that doxygen will group on one line in the generated HTML
# documentation. Note that a value of 0 will completely suppress the enum
# values from appearing in the overview section.
ENUM_VALUES_PER_LINE = 4
-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
-# and Class Hierarchy pages using a tree view instead of an ordered list.
-
-USE_INLINE_TREES = NO
-
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH = 250
# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
# links to external symbols imported via tag files in a separate window.
EXT_LINKS_IN_WINDOW = NO
# Use this tag to change the font size of Latex formulas included
# as images in the HTML documentation. The default is 10. Note that
# when you change the font size after a successful doxygen run you need
# to manually remove any form_*.png images from the HTML output directory
# to force them to be regenerated.
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are
# not supported properly for IE 6.0, but are supported on all modern browsers.
# Note that when changing this option you need to delete any form_*.png files
# in the HTML output before the changes have effect.
FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
# (see http://www.mathjax.org) which uses client side Javascript for the
# rendering instead of using prerendered bitmaps. Use this if you do not
# have LaTeX installed or if you want to formulas look prettier in the HTML
# output. When enabled you also need to install MathJax separately and
# configure the path to it using the MATHJAX_RELPATH option.
USE_MATHJAX = NO
# When MathJax is enabled you need to specify the location relative to the
# HTML output directory using the MATHJAX_RELPATH option. The destination
# directory should contain the MathJax.js script. For instance, if the mathjax
# directory is located at the same level as the HTML output directory, then
# MATHJAX_RELPATH should be ../mathjax. The default value points to the
# mathjax.org site, so you can quickly see the result without installing
# MathJax, but it is strongly recommended to install a local copy of MathJax
# before deployment.
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
# names that should be enabled during MathJax rendering.
MATHJAX_EXTENSIONS =
# When the SEARCHENGINE tag is enabled doxygen will generate a search box
# for the HTML output. The underlying search engine uses javascript
# and DHTML and should work on any modern browser. Note that when using
# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
# (GENERATE_DOCSET) there is already a search function so this one should
# typically be disabled. For large projects the javascript based search engine
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a PHP enabled web server instead of at the web client
# using Javascript. Doxygen will generate the search PHP script and index
# file to put on the web server. The advantage of the server
# based approach is that it scales better to large projects and allows
# full text search. The disadvantages are that it is more difficult to setup
# and does not have live searching capabilities.
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked. If left blank `latex' will be used as the default command name.
# Note that when enabling USE_PDFLATEX this option is only used for
# generating bitmaps for formulas in the HTML output, but not in the
# Makefile that is written to the output directory.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.
MAKEINDEX_CMD_NAME = makeindex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
-EXTRA_PACKAGES =
+EXTRA_PACKAGES = amsmath
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
# the generated latex document. The footer should contain everything after
# the last chapter. If it is left blank doxygen will generate a
# standard footer. Notice: only use this tag if you know what you are doing!
LATEX_FOOTER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = YES
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
-LATEX_BATCHMODE = NO
+LATEX_BATCHMODE = YES
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
# include the index chapters (such as File Index, Compound Index, etc.)
# in the output.
LATEX_HIDE_INDICES = NO
# If LATEX_SOURCE_CODE is set to YES then doxygen will include
# source code with syntax highlighting in the LaTeX output.
# Note that which sources are shown also depends on other settings
# such as SOURCE_BROWSER.
LATEX_SOURCE_CODE = YES
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
# http://en.wikipedia.org/wiki/BibTeX for more info.
LATEX_BIB_STYLE = plain
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimized for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using WORD or other
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load style sheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = YES
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
# then it will generate one additional man file for each entity
# documented in the real man page(s). These additional files
# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation.
GENERATE_XML = NO
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `xml' will be used as the default path.
XML_OUTPUT = xml
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
# and cross-referencing information) to the XML output. Note that
# enabling this will significantly increase the size of the XML output.
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
# generate an AutoGen Definitions (see autogen.sf.net) file
# that captures the structure of the code including all
# documentation. Note that this feature is still experimental
# and incomplete at the moment.
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
# If the GENERATE_PERLMOD tag is set to YES Doxygen will
# generate a Perl module file that captures the structure of
# the code including all documentation. Note that this
# feature is still experimental and incomplete at the
# moment.
GENERATE_PERLMOD = NO
# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
# the necessary Makefile rules, Perl scripts and LaTeX code to be able
# to generate PDF and DVI output from the Perl module output.
PERLMOD_LATEX = NO
# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
# nicely formatted so it can be parsed by a human reader. This is useful
# if you want to understand what is going on. On the other hand, if this
# tag is set to NO the size of the Perl module output will be much smaller
# and Perl will parse it just the same.
PERLMOD_PRETTY = YES
# The names of the make variables in the generated doxyrules.make file
# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
# This is useful so different doxyrules.make files included by the same
# Makefile don't overwrite each other's variables.
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_DEFINED tags.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# pointed to by INCLUDE_PATH will be searched when a #include is found.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH = @AKANTU_DOXYGEN_INCLUDE_DIRS@
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS = *.hh
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed. To prevent a macro definition from being
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
PREDEFINED = @AKANTU_DOXYGEN_DEFINTIONS@
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition that
# overrules the definition found in the source code.
EXPAND_AS_DEFINED = __BEGIN_AKANTU__ \
__END_AKANTU__ \
AKANTU_GET_MACRO \
AKANTU_SET_MACRO \
AKANTU_GET_MACRO_NOT_CONST \
AKANTU_GET_MACRO_BY_ELEMENT_TYPE
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all references to function-like macros
# that are alone on a line, have an all uppercase name, and do not end with a
# semicolon, because these will confuse the parser if not removed.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
# The TAGFILES option can be used to specify one or more tagfiles.
# Optionally an initial location of the external documentation
# can be added for each tagfile. The format of a tag file without
# this location is as follows:
# TAGFILES = file1 file2 ...
# Adding location for the tag files is done as follows:
# TAGFILES = file1=loc1 "file2 = loc2" ...
# where "loc1" and "loc2" can be relative or absolute paths or
# URLs. If a location is present for each tag, the installdox tool
# does not have to be run to correct the links.
# Note that each tag file must have a unique name
# (where the name does NOT include the path)
# If a tag file is not located in the directory in which doxygen
# is run, you must also specify the path to the tagfile here.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
# or super classes. Setting the tag to NO turns the diagrams off. Note that
# this option also works with HAVE_DOT disabled, but it is recommended to
# install and use dot, since it yields more powerful graphs.
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
# or is not a class.
HIDE_UNDOC_RELATIONS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = YES
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
# allowed to run in parallel. When set to 0 (the default) doxygen will
# base this on the number of processors available in the system. You can set it
# explicitly to a value larger than 0 to get control over the balance
# between CPU load and processing speed.
DOT_NUM_THREADS = 0
# By default doxygen will use the Helvetica font for all dot files that
# doxygen generates. When you want a differently looking font you can specify
# the font name using DOT_FONTNAME. You need to make sure dot is able to find
# the font, which can be done by putting it in a standard location or by setting
# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
# directory containing the font.
DOT_FONTNAME = Helvetica
# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
# The default size is 10pt.
DOT_FONTSIZE = 10
# By default doxygen will tell dot to use the Helvetica font.
# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
# set the path where dot can find it.
DOT_FONTPATH =
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = NO
# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for groups, showing the direct groups dependencies
GROUP_GRAPHS = YES
# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
# collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language.
UML_LOOK = YES
# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS = NO
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
# tags are set to YES then doxygen will generate a graph for each documented
# file showing the direct and indirect include dependencies of the file with
# other documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
# If the CALL_GRAPH and HAVE_DOT options are set to YES then
# doxygen will generate a call dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable call graphs
# for selected functions only using the \callgraph command.
CALL_GRAPH = YES
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
# doxygen will generate a caller dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable caller
# graphs for selected functions only using the \callergraph command.
CALLER_GRAPH = YES
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will generate a graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
# then doxygen will show the dependencies a directory has on other directories
# in a graphical way. The dependency relations are determined by the #include
# relations between the files in the directories.
DIRECTORY_GRAPH = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are svg, png, jpg, or gif.
# If left blank png will be used. If you choose svg you need to set
# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
# visible in IE 9+ (other browsers do not have this requirement).
DOT_IMAGE_FORMAT = png
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
# enable generation of interactive SVG images that allow zooming and panning.
# Note that this requires a modern browser other than Internet Explorer.
# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
# visible. Older versions of IE do not have SVG support.
INTERACTIVE_SVG = NO
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
DOT_PATH = @DOXYGEN_DOT_PATH@
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).
DOTFILE_DIRS =
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the
# \mscfile command).
MSCFILE_DIRS =
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
# nodes that will be shown in the graph. If the number of nodes in a graph
# becomes larger than this value, doxygen will truncate the graph, which is
# visualized by representing a node as a red box. Note that doxygen if the
# number of direct children of the root node in a graph is already larger than
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
DOT_GRAPH_MAX_NODES = 600
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
# graphs generated by dot. A depth value of 3 means that only nodes reachable
# from the root by following a path via at most 3 edges will be shown. Nodes
# that lay further from the root node will be omitted. Note that setting this
# option to 1 or 2 may greatly reduce the computation time needed for large
# code bases. Also note that the size of a graph can be further restricted by
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
MAX_DOT_GRAPH_DEPTH = 2
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, because dot on Windows does not
# seem to support this out of the box. Warning: Depending on the platform used,
# enabling this option may lead to badly anti-aliased labels on the edges of
# a graph (i.e. they become hard to read).
DOT_TRANSPARENT = NO
# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10)
# support this, this feature is disabled by default.
DOT_MULTI_TARGETS = NO
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
# remove the intermediate dot files that are used to generate
# the various graphs.
DOT_CLEANUP = YES
diff --git a/doc/manual/CMakeLists.txt b/doc/manual/CMakeLists.txt
index 5348490e2..6d54d9781 100644
--- a/doc/manual/CMakeLists.txt
+++ b/doc/manual/CMakeLists.txt
@@ -1,155 +1,163 @@
#===============================================================================
# @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: Tue Jan 19 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")
+ file(APPEND ${FILENAME} "\\AkantuPackageNameWithLabel{${_pkg_tex}}{${_pkg_tex_label}}{${LEVEL}}\\allowbreak\\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")
+set(AKANTU_MANUAL_SOURCE_FOLDER ${CMAKE_CURRENT_BINARY_DIR}/latex)
+
+set(DOC_DEPS_TEX_FILENAME "${AKANTU_MANUAL_SOURCE_FOLDER}/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)
+
+file(MAKE_DIRECTORY ${AKANTU_MANUAL_SOURCE_FOLDER})
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})
+ 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)
+set(MANUAL_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/akantu_ug.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}
+ COMMAND ${RUBBER_EXECUTABLE} -dfq manual
+ COMMAND ${CMAKE_COMMAND} -E copy manual.pdf ${MANUAL_OUTPUT}
+ WORKING_DIRECTORY ${AKANTU_MANUAL_SOURCE_FOLDER}
COMMENT "Compiling the user's manual"
)
+set_directory_properties(latex/$)
+
add_custom_target(manual ALL DEPENDS ${MANUAL_OUTPUT})
-install(FILES ${MANUAL_OUTPUT} DESTINATION share/akantu/doc)
+install(FILES ${MANUAL_OUTPUT} DESTINATION share/akantu-${AKANTU_VERSION}/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
+configure_file(version-definition.tex.in "${AKANTU_MANUAL_SOURCE_FOLDER}/version-definition.tex" @ONLY)
diff --git a/doc/manual/figures/hertz_3D.png b/doc/manual/figures/hertz_3D.png
deleted file mode 100644
index 7b50bcff9..000000000
Binary files a/doc/manual/figures/hertz_3D.png and /dev/null differ
diff --git a/doc/manual/figures/problemDomain.svg b/doc/manual/figures/problemDomain.svg
deleted file mode 100644
index 1741f94b6..000000000
--- a/doc/manual/figures/problemDomain.svg
+++ /dev/null
@@ -1,842 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- id="svg4096"
- version="1.1"
- inkscape:version="0.48.4 r9939"
- width="124.01613"
- height="124.01613"
- xml:space="preserve"
- sodipodi:docname="problemDomain.pdf"><metadata
- id="metadata4102"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
- id="defs4100"><inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 62.008064 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="124.01613 : 62.008064 : 1"
- inkscape:persp3d-origin="62.008064 : 41.33871 : 1"
- id="perspective5753" /><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="Arrow1Sstart"
- style="overflow:visible"><path
- id="path6253"
- d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
- transform="scale(0.2) translate(6,0)" /></marker><marker
- inkscape:stockid="Arrow2Mstart"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="Arrow2Mstart"
- style="overflow:visible"><path
- id="path6265"
- style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
- d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
- transform="scale(0.6) translate(0,0)" /></marker><marker
- inkscape:stockid="Arrow1Mstart"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="Arrow1Mstart"
- style="overflow:visible"><path
- id="path6247"
- d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
- transform="scale(0.4) translate(10,0)" /></marker><marker
- inkscape:stockid="Arrow1Lstart"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="Arrow1Lstart"
- style="overflow:visible"><path
- id="path6241"
- d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
- transform="scale(0.8) translate(12.5,0)" /></marker><pattern
- inkscape:collect="always"
- xlink:href="#pattern4348"
- id="pattern5146"
- patternTransform="matrix(0.16961,0.105984,-0.105984,0.16961,-5675.1519,7677.4221)" /><clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath4238"><path
- d="m 0,99.213 99.213,0 L 99.213,0 0,0 0,99.213 z"
- id="path4240" /></clipPath><pattern
- patternTransform="matrix(0.16961,0.105984,-0.105984,0.16961,-5753.71,7630.57)"
- patternUnits="userSpaceOnUse"
- x="0"
- y="0"
- width="72"
- height="72"
- id="pattern4348"><g
- transform="translate(71.75,6)"
- id="g4350"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4352" /></g><g
- transform="translate(71.75,30)"
- id="g4354"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4356" /></g><g
- transform="translate(71.75,54)"
- id="g4358"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4360" /></g><g
- transform="translate(71.75,18)"
- id="g4362"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4364" /></g><g
- transform="translate(71.75,42)"
- id="g4366"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4368" /></g><g
- transform="translate(71.75,66)"
- id="g4370"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4372" /></g><g
- transform="translate(-0.25,6)"
- id="g4374"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4376" /></g><g
- transform="translate(-0.25,30)"
- id="g4378"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4380" /></g><g
- transform="translate(-0.25,54)"
- id="g4382"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4384" /></g><g
- transform="translate(-0.25,18)"
- id="g4386"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4388" /></g><g
- transform="translate(-0.25,42)"
- id="g4390"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4392" /></g><g
- transform="translate(-0.25,66)"
- id="g4394"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4396" /></g><g
- transform="translate(-72.25,6)"
- id="g4398"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4400" /></g><g
- transform="translate(-72.25,30)"
- id="g4402"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4404" /></g><g
- transform="translate(-72.25,54)"
- id="g4406"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4408" /></g><g
- transform="translate(-72.25,18)"
- id="g4410"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4412" /></g><g
- transform="translate(-72.25,42)"
- id="g4414"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4416" /></g><g
- transform="translate(-72.25,66)"
- id="g4418"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4420" /></g></pattern><clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath6136"><rect
- style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.16;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6138"
- width="86.268951"
- height="40"
- x="9.7310495"
- y="-92"
- transform="scale(1,-1)" /></clipPath><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart-2"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6253-0"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)" /></marker><clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7669"><rect
- style="fill:none;stroke:#000000;stroke-width:0.67873836;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7671"
- width="58.617989"
- height="34.006798"
- x="41.125267"
- y="-40.378319"
- transform="scale(1,-1)" /></clipPath><clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7675"><rect
- style="fill:none;stroke:#000000;stroke-width:0.63999999;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7677"
- width="40.727409"
- height="26.476818"
- x="59.01585"
- y="-40.378323"
- transform="scale(1,-1)" /></clipPath><clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7681"><rect
- style="fill:none;stroke:#000000;stroke-width:0.63999999;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7683"
- width="35.741554"
- height="18.423975"
- x="64.001709"
- y="-36.727619"
- transform="scale(1,-1)" /></clipPath><clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7687"><rect
- style="fill:none;stroke:#000000;stroke-width:0.6322726;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7689"
- width="23.301664"
- height="25.979616"
- x="69.861725"
- y="15.562471"
- transform="matrix(0.81775189,0.57557089,0.62244302,-0.78266512,0,0)" /></clipPath><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart-9"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6253-9"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)" /></marker><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart-7"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6253-7"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)" /></marker><clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7745"><rect
- style="fill:none;stroke:#000000;stroke-width:0.77970266;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7747"
- width="18.38924"
- height="28.034689"
- x="55.113998"
- y="-70.958023"
- transform="matrix(0.91145551,-0.41139865,-0.41139865,-0.91145551,0,0)" /></clipPath><clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7751"><rect
- style="fill:none;stroke:#000000;stroke-width:0.60000002;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7753"
- width="27.339615"
- height="27.22377"
- x="9.2474384"
- y="-97.671455"
- transform="matrix(0.60394184,-0.79702839,-0.79702839,-0.60394184,0,0)" /></clipPath><clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7769"><rect
- style="fill:none;stroke:#000000;stroke-width:0.41750172;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7771"
- width="14.87412"
- height="23.310919"
- x="53.47971"
- y="-70.916389"
- transform="matrix(0.91292817,-0.40812028,-0.4139461,-0.91030139,0,0)" /></clipPath><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart-6"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6253-8"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)" /></marker><pattern
- patternTransform="matrix(0.16961,0.105984,-0.105984,0.16961,-5753.71,7630.57)"
- patternUnits="userSpaceOnUse"
- x="0"
- y="0"
- width="72"
- height="72"
- id="pattern4348-8"><g
- transform="translate(71.75,6)"
- id="g4350-5"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4352-8" /></g><g
- transform="translate(71.75,30)"
- id="g4354-6"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4356-7" /></g><g
- transform="translate(71.75,54)"
- id="g4358-0"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4360-9" /></g><g
- transform="translate(71.75,18)"
- id="g4362-4"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4364-7" /></g><g
- transform="translate(71.75,42)"
- id="g4366-7"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4368-1" /></g><g
- transform="translate(71.75,66)"
- id="g4370-1"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4372-2" /></g><g
- transform="translate(-0.25,6)"
- id="g4374-9"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4376-3" /></g><g
- transform="translate(-0.25,30)"
- id="g4378-6"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4380-9" /></g><g
- transform="translate(-0.25,54)"
- id="g4382-4"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4384-3" /></g><g
- transform="translate(-0.25,18)"
- id="g4386-4"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4388-4" /></g><g
- transform="translate(-0.25,42)"
- id="g4390-3"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4392-2" /></g><g
- transform="translate(-0.25,66)"
- id="g4394-1"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4396-1" /></g><g
- transform="translate(-72.25,6)"
- id="g4398-8"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4400-0" /></g><g
- transform="translate(-72.25,30)"
- id="g4402-4"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4404-3" /></g><g
- transform="translate(-72.25,54)"
- id="g4406-2"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4408-9" /></g><g
- transform="translate(-72.25,18)"
- id="g4410-3"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4412-9" /></g><g
- transform="translate(-72.25,42)"
- id="g4414-7"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4416-9" /></g><g
- transform="translate(-72.25,66)"
- id="g4418-6"><path
- d="M 0,0 72.5,0"
- style="fill:none;stroke:#231f20;stroke-opacity:1;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path4420-0" /></g></pattern><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart-4"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6253-4"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)" /></marker><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart-3"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6253-3"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)" /></marker><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart-63"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6253-02"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)" /></marker><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart-0"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6253-90"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)" /></marker><marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart-23"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6253-01"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)" /></marker><marker
- inkscape:stockid="Arrow1Mstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Mstart-9"
- style="overflow:visible"><path
- inkscape:connector-curvature="0"
- id="path6247-3"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.4,0,0,0.4,4,0)" /></marker></defs><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="1030"
- id="namedview4098"
- showgrid="true"
- inkscape:zoom="7.0567935"
- inkscape:cx="50.368934"
- inkscape:cy="57.843472"
- inkscape:window-x="0"
- inkscape:window-y="0"
- inkscape:window-maximized="1"
- inkscape:current-layer="g4104"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="true"
- inkscape:object-nodes="true"
- inkscape:snap-smooth-nodes="true"
- inkscape:snap-nodes="false"><inkscape:grid
- type="xygrid"
- id="grid5011"
- empspacing="5"
- visible="true"
- enabled="false"
- snapvisiblegridlinesonly="true" /></sodipodi:namedview><g
- id="g4104"
- inkscape:groupmode="layer"
- inkscape:label="domain"
- transform="matrix(1.25,0,0,-1.25,0,124.01613)"><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 24.940506,46.785585 70.712003,18.160686"
- id="path4026"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 26.92441,49.194611 74.396395,19.436053"
- id="path4028"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 21.539528,34.598747 51.864916,15.609952"
- id="path4018"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 21.000361,38.422205 57.391505,15.893367"
- id="path4020"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 21.681235,41.684118 62.351265,16.318489"
- id="path4022"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 23.098309,44.234851 66.268875,17.114755"
- id="path4024"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 29.266375,51.042255 77.797374,20.853127"
- id="path4030"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 31.600755,53.445833 80.914937,22.270201"
- id="path4032"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 33.726366,55.713152 83.46567,24.112397"
- id="path4034"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 35.71027,57.555349 86.016404,26.096301"
- id="path4036"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:#ffffff;stroke:#ffffff;stroke-width:0.16000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1"
- d="m 8,88.000001 20,-20"
- id="path5021"
- inkscape:connector-curvature="0" /><path
- style="fill:#e5e6e6;stroke:#ffffff;stroke-width:0.20000000000000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1"
- d="m 10,64.016129 25,25"
- id="path5029"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#ffffff;stroke-width:0.20000000000000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 10,89.016129 35,114.01613"
- id="path5033"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 27.989078,87.948999 20,-20.000001"
- id="path5021-7"
- inkscape:connector-curvature="0" /><path
- style="fill:#e5e6e6;fill-opacity:1;stroke:#ffffff;stroke-width:0.16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 27.989078,47.948998 20,-20"
- id="path5029-1"
- inkscape:connector-curvature="0" /><path
- style="fill:#e5e6e6;fill-opacity:1;stroke:#ffffff;stroke-width:0.16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 47.989078,67.940246 20,-20"
- id="path5025-6"
- inkscape:connector-curvature="0" /><path
- style="fill:#e5e6e6;fill-opacity:1;stroke:#ffffff;stroke-width:0.16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 47.989078,47.940246 20,-20"
- id="path5029-12"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#ffffff;stroke-width:0.16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 47.989078,27.940246 20,-19.9999984"
- id="path5033-7"
- inkscape:connector-curvature="0" /><path
- style="fill:#e5e6e6;fill-opacity:1;stroke:#ffffff;stroke-width:0.16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 68.08308,47.940246 20,-20"
- id="path5029-12-3"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#ffffff;stroke-width:0.16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 68.08308,27.940246 20,-19.9999984"
- id="path5033-7-9"
- inkscape:connector-curvature="0" /><path
- inkscape:connector-curvature="0"
- id="path4344"
- style="fill:#e5e6e6;stroke:#231f20;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1"
- d="m 77.7026,58.3032 c -1.131,4.555 -2.762,9.217 -4.916,11.813 -6.634,7.99 -10.461,10.387 -20.179,12.672 -7.311,1.719 -14.269,1.567 -21.559,-0.947 -5.941,-2.052 -11.609,-7.801 -11.892,-14.544 -0.165,-3.938 3.525,-7.161 6.105,-9.583 3.043,-2.86 6.562,-5.927 8.51,-9.675 3.389,-6.519 2.145,-13.148 2.639,-20.257 0.248,-3.57 1.424,-6.867 4.494,-8.912 1.722,-1.144 3.146,-1.998 5.351,-2.826 5.206,-1.956 11.606,0.301 15.143,1.844 2.82,1.228 4.199,2.326 6.649,4.462 3.655,3.19 6.139,7.514 7.733,12.213 1.41,4.16 2.334,8.104 2.777,12.289 0.338,3.184 -0.101,7.273 -0.855,11.451" /><path
- style="fill:none;stroke:#000000;stroke-width:0.40000000000000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="m 75.090932,30.428037 6.091709,-2.746113"
- id="path6217"
- inkscape:connector-curvature="0" /><path
- inkscape:connector-curvature="0"
- id="path4344-0"
- style="fill:none;stroke:#231f20;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"
- d="m 88.868768,58.372827 c -1.131,4.555 -2.762,9.217 -4.916,11.813 -6.634,7.990001 -10.461,10.387001 -20.179,12.672001 -7.311,1.719 -14.269,1.567 -21.559,-0.947 -5.941,-2.052 -11.609,-7.801001 -11.892,-14.544001 -0.165,-3.938 3.525,-7.161 6.105,-9.583 3.043,-2.86 6.562,-5.927 8.51,-9.675 3.389,-6.519 2.145,-13.148 2.639,-20.257 0.248,-3.57 1.424,-6.867 4.494,-8.912 1.722,-1.144 3.146,-1.998 5.351,-2.826 5.206,-1.956 11.606,0.301 15.143,1.844 2.82,1.228 4.199,2.326 6.649,4.462 3.655,3.19 6.139,7.514 7.733,12.213 1.41,4.16 2.334,8.104 2.777,12.289 0.338,3.184 -0.101,7.273 -0.855,11.451"
- clip-path="url(#clipPath7769)"
- transform="translate(-4.8,-4.8)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.40000000000000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="m 72.62782,26.351914 5.614968,-3.954477"
- id="path6217-8"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="m 66.603966,19.723186 3.033339,-5.814175"
- id="path6217-8-6"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="m 25.10802,37.007375 11.545161,0.850512"
- id="path6217-8-3"
- inkscape:connector-curvature="0" /><flowRoot
- transform="matrix(0.07578891,0,0,-0.08804781,-8.901115,87.001895)"
- xml:space="preserve"
- id="flowRoot4010-6-8-2"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><flowRegion
- id="flowRegion4012-45-5-8"><rect
- id="rect4014-6-8-8"
- width="455.71997"
- height="75.822876"
- x="492.85715"
- y="513.79077" /></flowRegion><flowPara
- id="flowPara4016-0-4-2">$\boldsymbol{n}$</flowPara></flowRoot><flowRoot
- transform="matrix(0.07578891,0,0,-0.08804781,43.533893,71.177015)"
- xml:space="preserve"
- id="flowRoot4010-6-8-2-5"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><flowRegion
- id="flowRegion4012-45-5-8-1"><rect
- id="rect4014-6-8-8-1"
- width="585.85559"
- height="87.41082"
- x="492.85715"
- y="513.79077" /></flowRegion><flowPara
- id="flowPara4016-0-4-2-8">$\bar{\boldsymbol{t}}$</flowPara></flowRoot><flowRoot
- transform="matrix(0.07578891,0,0,-0.08804781,-2.9465464,120.82132)"
- xml:space="preserve"
- id="flowRoot4010-6-8-2-5-2-6"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><flowRegion
- id="flowRegion4012-45-5-8-1-1-1"><rect
- id="rect4014-6-8-8-1-2-9"
- width="455.71997"
- height="75.822876"
- x="492.85715"
- y="513.79077" /></flowRegion><flowPara
- id="flowPara4016-0-4-2-8-6-1">$\Omega$</flowPara></flowRoot><flowRoot
- transform="matrix(0.07578891,0,0,-0.08804781,22.762397,134.87738)"
- xml:space="preserve"
- id="flowRoot4010-6-8-2-5-2-6-1"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><flowRegion
- id="flowRegion4012-45-5-8-1-1-1-8"><rect
- id="rect4014-6-8-8-1-2-9-2"
- width="455.71997"
- height="75.822876"
- x="492.85715"
- y="513.79077" /></flowRegion><flowPara
- id="flowPara4016-0-4-2-8-6-1-8">$\Gamma_{u}$</flowPara></flowRoot><flowRoot
- transform="matrix(0.07578891,0,0,-0.08804781,1.4297885,59.588014)"
- xml:space="preserve"
- id="flowRoot4010-6-8-2-5-2-6-1-5"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><flowRegion
- id="flowRegion4012-45-5-8-1-1-1-8-6"><rect
- id="rect4014-6-8-8-1-2-9-2-1"
- width="455.71997"
- height="75.822876"
- x="492.85715"
- y="513.79077" /></flowRegion><flowPara
- id="flowPara4016-0-4-2-8-6-1-8-6">$\Gamma_{t}$</flowPara></flowRoot><path
- style="fill:none;stroke:#000000;stroke-width:0.40000000000000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="m 76.886681,35.261082 6.629864,-1.943877"
- id="path6217-3"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#000000;stroke-width:0.40000000000000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="m 69.939454,22.732742 4.464635,-5.103236"
- id="path6217-8-0"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#000000;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="M 7.085313,21.115568 7.136773,8.578829"
- id="path6217-8-3-9"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#000000;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="M 19.43048,8.7957317 6.8936366,8.7930817"
- id="path6217-8-3-9-4"
- inkscape:connector-curvature="0" /><flowRoot
- transform="matrix(0.07578891,0,0,-0.08804781,-16.06147,55.321013)"
- xml:space="preserve"
- id="flowRoot4010-6-8-2-7"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><flowRegion
- id="flowRegion4012-45-5-8-9"><rect
- id="rect4014-6-8-8-4"
- width="455.71997"
- height="75.822876"
- x="492.85715"
- y="513.79077" /></flowRegion><flowPara
- id="flowPara4016-0-4-2-1">$\boldsymbol{e}_2$</flowPara></flowRoot><flowRoot
- transform="matrix(0.07578891,0,0,-0.08804781,-32.53054,71.238855)"
- xml:space="preserve"
- id="flowRoot4010-6-8-2-7-2"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><flowRegion
- id="flowRegion4012-45-5-8-9-4"><rect
- id="rect4014-6-8-8-4-5"
- width="455.71997"
- height="75.822876"
- x="492.85715"
- y="513.79077" /></flowRegion><flowPara
- id="flowPara4016-0-4-2-1-0">$\boldsymbol{e}_3$</flowPara></flowRoot><path
- style="fill:none;stroke:#000000;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="M 58.730035,30.165428 7.0070025,8.9064478"
- id="path6217-8-3-9-2"
- inkscape:connector-curvature="0" /><flowRoot
- transform="matrix(0.07578891,0,0,-0.08804781,-11.363544,68.159915)"
- xml:space="preserve"
- id="flowRoot4010-6-8-2-9"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><flowRegion
- id="flowRegion4012-45-5-8-6"><rect
- id="rect4014-6-8-8-6"
- width="455.71997"
- height="75.822876"
- x="492.85715"
- y="513.79077" /></flowRegion><flowPara
- id="flowPara4016-0-4-2-5">$\boldsymbol{x}$</flowPara></flowRoot><path
- sodipodi:type="arc"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="path4900"
- sodipodi:cx="2.2044501"
- sodipodi:cy="15.797668"
- sodipodi:rx="4.008091"
- sodipodi:ry="3.8076866"
- d="m 6.2125411,15.797668 c 0,2.102928 -1.7944834,3.807687 -4.008091,3.807687 -0.6664436,0 -1.32236916,-0.157871 -1.90841879,-0.459326"
- transform="matrix(0.7573376,0.25775911,0.25775911,-0.7573376,21.708863,66.676429)"
- sodipodi:start="0"
- sodipodi:end="2.0670581"
- sodipodi:open="true" /><path
- sodipodi:type="arc"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="path4900-1"
- sodipodi:cx="2.2044501"
- sodipodi:cy="15.797668"
- sodipodi:rx="4.008091"
- sodipodi:ry="3.8076866"
- d="m 6.2125411,15.797668 c 0,2.102928 -1.7944834,3.807687 -4.008091,3.807687 -0.6664436,0 -1.32236916,-0.157871 -1.90841879,-0.459326"
- transform="matrix(-0.75494083,-0.2646967,-0.2646967,0.75494083,38.259037,40.073546)"
- sodipodi:start="0"
- sodipodi:end="2.0670581"
- sodipodi:open="true" /><g
- id="g4941"
- transform="matrix(0.75103427,-0.66026322,0.66026322,0.75103427,-15.929482,67.530034)"><path
- sodipodi:open="true"
- sodipodi:end="2.0670581"
- sodipodi:start="0"
- transform="matrix(0.7573376,0.25775911,0.25775911,-0.7573376,72.657319,64.324842)"
- d="m 6.2125411,15.797668 c 0,2.102928 -1.7944834,3.807687 -4.008091,3.807687 -0.6664436,0 -1.32236916,-0.157871 -1.90841879,-0.459326"
- sodipodi:ry="3.8076866"
- sodipodi:rx="4.008091"
- sodipodi:cy="15.797668"
- sodipodi:cx="2.2044501"
- id="path4900-8"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- sodipodi:type="arc" /><path
- sodipodi:open="true"
- sodipodi:end="2.0670581"
- sodipodi:start="0"
- transform="matrix(-0.75494083,-0.2646967,-0.2646967,0.75494083,89.207492,37.721962)"
- d="m 6.2125411,15.797668 c 0,2.102928 -1.7944834,3.807687 -4.008091,3.807687 -0.6664436,0 -1.32236916,-0.157871 -1.90841879,-0.459326"
- sodipodi:ry="3.8076866"
- sodipodi:rx="4.008091"
- sodipodi:cy="15.797668"
- sodipodi:cx="2.2044501"
- id="path4900-1-6"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- sodipodi:type="arc" /></g><path
- style="fill:none;stroke:#000000;stroke-width:0.24000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="M 22.786553,80.37645 29.6781,84.4951"
- id="path4014"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 45.488082,16.035075 23.240017,29.922402"
- id="path4016"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 85.572745,30.126594 2.755563,-1.703438"
- id="path4038"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 87.927499,32.230842 2.505057,-1.653337"
- id="path4040"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 89.781241,34.585596 c 0.250505,-0.150304 2.65536,-1.653338 2.65536,-1.653338"
- id="path4044"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 91.735185,36.940349 2.605259,-1.653337"
- id="path4046"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 93.238219,39.445406 95.89358,37.84217"
- id="path4048"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 94.490748,42.200969 2.605259,-1.603237"
- id="path4050"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 95.643074,45.006633 2.505057,-1.553136"
- id="path4052"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.24;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 77.195834,60.802743 2.124289,1.202427"
- id="path4054"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 97.296412,51.118972 c 0.350708,-0.250506 2.755558,-1.703439 2.755558,-1.703439"
- id="path4056"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 97.947726,54.275343 2.705464,-1.803641"
- id="path4058"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="M 98.248333,57.582018 101.0039,55.828479"
- id="path4060"
- inkscape:connector-curvature="0"
- transform="matrix(0.8,0,0,-0.8,0,99.212904)" /><path
- style="fill:none;stroke:#000000;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart)"
- d="m 1.2025837,1.7841934 5.958941,7.1119823"
- id="path6217-8-3-9-4-1"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" /><flowRoot
- transform="matrix(0.07578891,0,0,-0.08804781,-39.407639,46.603971)"
- xml:space="preserve"
- id="flowRoot4010-6-8-2-7-3"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"><flowRegion
- id="flowRegion4012-45-5-8-9-8"><rect
- id="rect4014-6-8-8-4-58"
- width="455.71997"
- height="75.822876"
- x="492.85715"
- y="513.79077" /></flowRegion><flowPara
- id="flowPara4016-0-4-2-1-9">$\boldsymbol{e}_1$</flowPara></flowRoot></g></svg>
\ No newline at end of file
diff --git a/doc/manual/figures/stress_strain_neo.svg b/doc/manual/figures/stress_strain_neo.svg
deleted file mode 100644
index 760e37f23..000000000
--- a/doc/manual/figures/stress_strain_neo.svg
+++ /dev/null
@@ -1,384 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:ns0="http://www.iki.fi/pav/software/textext/"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="511.03537"
- height="505.40811"
- id="svg2"
- version="1.1"
- inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="stress_strain_neo.svg">
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1.28"
- inkscape:cx="255.79195"
- inkscape:cy="248.76907"
- inkscape:document-units="px"
- inkscape:current-layer="layer2"
- showgrid="false"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0"
- inkscape:snap-bbox="true"
- inkscape:bbox-nodes="true"
- inkscape:bbox-paths="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:snap-bbox-midpoints="true"
- inkscape:object-paths="true"
- inkscape:object-nodes="true"
- inkscape:snap-smooth-nodes="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-midpoints="true"
- inkscape:snap-center="true"
- inkscape:snap-object-midpoints="true"
- inkscape:snap-page="true"
- inkscape:snap-grids="false"
- inkscape:snap-to-guides="false"
- inkscape:window-width="1280"
- inkscape:window-height="1000"
- inkscape:window-x="1920"
- inkscape:window-y="24"
- inkscape:window-maximized="1"
- inkscape:snap-global="true" />
- <defs
- id="defs4">
- <marker
- style="overflow:visible"
- id="Arrow2Mend"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow2Mend">
- <path
- transform="scale(-0.6,-0.6)"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
- id="path3878"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- style="overflow:visible"
- id="Arrow2Mstart"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow2Mstart">
- <path
- transform="scale(0.6,0.6)"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
- id="path3875"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- style="overflow:visible"
- id="TriangleInL"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="TriangleInL">
- <path
- transform="scale(-0.8,-0.8)"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
- id="path3984"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Send"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Send"
- style="overflow:visible">
- <path
- id="path3866"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart"
- style="overflow:visible">
- <path
- id="path3863"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- style="overflow:visible"
- id="Arrow1Mend"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1Mend">
- <path
- transform="matrix(-0.4,0,0,-0.4,-4,0)"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- id="path3860"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- style="overflow:visible"
- id="Arrow1Mstart"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1Mstart">
- <path
- transform="matrix(0.4,0,0,0.4,4,0)"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- id="path3857"
- inkscape:connector-curvature="0" />
- </marker>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3019">
- <path
- inkscape:connector-curvature="0"
- d="m 0,425.197 453.543,0 L 453.543,0 0,0 0,425.197 z"
- id="path3021" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath2999">
- <path
- inkscape:connector-curvature="0"
- d="m 0,425.197 453.543,0 L 453.543,0 0,0 0,425.197 z"
- id="path3001" />
- </clipPath>
- <marker
- style="overflow:visible"
- id="Arrow1Mstart6"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1Mstart6">
- <path
- transform="matrix(0.4,0,0,0.4,4,0)"
- style="fill:#ff0000;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- id="path5666"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- style="overflow:visible"
- id="Arrow1MendC"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1MendC">
- <path
- transform="matrix(-0.4,0,0,-0.4,-4,0)"
- style="fill:#ff0000;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- id="path5669"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- inkscape:stockid="Arrow1SstartK"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1SstartK"
- style="overflow:visible">
- <path
- id="path6151"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill:#ff0000;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt"
- transform="matrix(0.2,0,0,0.2,1.2,0)"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Send9"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Send9"
- style="overflow:visible">
- <path
- id="path6154"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill:#ff0000;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt"
- transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- style="overflow:visible"
- id="Arrow2Mstarth"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow2Mstarth">
- <path
- transform="scale(0.6,0.6)"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- style="fill:#ff0000;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round"
- id="path7863"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- style="overflow:visible"
- id="Arrow2Mendq"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow2Mendq">
- <path
- transform="scale(-0.6,-0.6)"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- style="fill:#ff0000;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round"
- id="path7866"
- inkscape:connector-curvature="0" />
- </marker>
- </defs>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- style="display:inline"
- inkscape:label="real"
- id="layer2"
- inkscape:groupmode="layer"
- transform="translate(-0.05470482,-1.4531938)">
- <g
- id="g8598">
- <path
- style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
- d="m 496.99505,478.64585 -466.690474,0 0,-465.68032"
- id="path3077"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#ff0000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow2Mstarth);marker-mid:none;marker-end:url(#Arrow2Mendq);display:inline"
- d="m 228.36222,354.15963 c 29.45984,-5.46913 53.59203,-22.02814 73.31069,-44.48908"
- id="path4661-8-3"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- style="fill:none;stroke:#ff0000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
- d="M 301.67291,309.67055 C 370.86576,230.85506 385.71428,79.36884 385.71428,79.36884"
- id="path4661-8-3-0"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- style="opacity:0.98000004;fill:none;stroke:#ff0000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
- d="m 30.304576,478.64585 c 0,0 70.670994,-100.83728 198.057644,-124.48621"
- id="path4661-8"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <g
- id="g8314"
- transform="matrix(4.2921685,0,0,4.2921685,-466.29358,-72.511697)"
- ns0:preamble=""
- ns0:text="$\\mathbf{\\varepsilon}$">
- <defs
- id="defs8316">
- <g
- id="g8318">
- <symbol
- id="textext-11069e35-0"
- overflow="visible"
- style="overflow:visible">
- <path
- id="path8321"
- d="M 1.40625,-2.265625 C 1.734375,-2.125 2.03125,-2.125 2.265625,-2.125 c 0.25,0 0.8125,0 0.8125,-0.3125 0,-0.234375 -0.359375,-0.265625 -0.734375,-0.265625 -0.203125,0 -0.5625,0.015625 -0.921875,0.1875 C 1.1875,-2.625 1.015625,-2.828125 1.015625,-3.09375 c 0,-0.609375 0.984375,-0.96875 1.875,-0.96875 0.15625,0 0.515625,0 0.921875,0.28125 0.109375,0.078125 0.125,0.109375 0.1875,0.109375 0.140625,0 0.28125,-0.140625 0.28125,-0.28125 0,-0.1875 -0.609375,-0.5625 -1.296875,-0.5625 -1.140625,0 -2.21875,0.671875 -2.21875,1.421875 0,0.4375 0.359375,0.6875 0.40625,0.71875 -0.59375,0.328125 -0.90625,0.875 -0.90625,1.34375 0,0.640625 0.5625,1.25 1.625,1.25 1.3125,0 1.875,-0.875 1.875,-1.03125 0,-0.0625 -0.0625,-0.09375 -0.109375,-0.09375 -0.0625,0 -0.09375,0.03125 -0.109375,0.0625 -0.140625,0.234375 -0.375,0.609375 -1.578125,0.609375 -0.609375,0 -1.453125,-0.15625 -1.453125,-0.859375 0,-0.34375 0.28125,-0.875 0.890625,-1.171875 z m 0.328125,-0.125 c 0.234375,-0.078125 0.4375,-0.09375 0.609375,-0.09375 0.25,0 0.28125,0.015625 0.46875,0.0625 -0.15625,0.0625 -0.171875,0.078125 -0.546875,0.078125 -0.21875,0 -0.34375,0 -0.53125,-0.046875 z m 0,0"
- style="stroke:none"
- inkscape:connector-curvature="0" />
- </symbol>
- </g>
- </defs>
- <g
- id="textext-11069e35-1">
- <g
- id="g8324"
- style="fill:#000000;fill-opacity:1">
- <use
- id="use8326"
- y="134.765"
- x="223.43201"
- xlink:href="#textext-11069e35-0"
- width="513.50208"
- height="507.94028" />
- </g>
- </g>
- </g>
- <g
- ns0:text="$\\mathbf{\\sigma}$"
- ns0:preamble=""
- transform="matrix(4.2921685,0,0,4.2921685,-960.56268,-558.53798)"
- style="display:inline"
- id="g8507">
- <defs
- id="defs8509">
- <g
- id="g8511">
- <symbol
- style="overflow:visible"
- overflow="visible"
- id="textext-3d6fb78a-0">
- <path
- inkscape:connector-curvature="0"
- style="stroke:none"
- d="m 5.15625,-3.71875 c 0.140625,0 0.5,0 0.5,-0.34375 0,-0.234375 -0.21875,-0.234375 -0.390625,-0.234375 l -2.28125,0 c -1.5,0 -2.609375,1.640625 -2.609375,2.828125 0,0.875 0.59375,1.578125 1.5,1.578125 1.171875,0 2.5,-1.203125 2.5,-2.734375 0,-0.171875 0,-0.65625 -0.3125,-1.09375 z M 1.890625,-0.109375 C 1.390625,-0.109375 1,-0.46875 1,-1.1875 c 0,-0.296875 0.109375,-1.109375 0.46875,-1.703125 0.421875,-0.6875 1.015625,-0.828125 1.359375,-0.828125 0.828125,0 0.90625,0.65625 0.90625,0.96875 0,0.46875 -0.203125,1.28125 -0.53125,1.796875 -0.390625,0.578125 -0.9375,0.84375 -1.3125,0.84375 z m 0,0"
- id="path8514" />
- </symbol>
- </g>
- </defs>
- <g
- id="textext-3d6fb78a-1">
- <g
- style="fill:#000000;fill-opacity:1"
- id="g8517">
- <use
- height="507.94028"
- width="513.50208"
- xlink:href="#textext-3d6fb78a-0"
- x="223.43201"
- y="134.765"
- id="use8519" />
- </g>
- </g>
- </g>
- </g>
- <path
- style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.9000001;stroke-opacity:1;stroke-dasharray:3, 6;stroke-dashoffset:0"
- d="M 30.249871,477.19266 218.59533,271.65969"
- id="path8658"
- inkscape:connector-curvature="0"
- transform="translate(0.05470482,1.4531938)"
- sodipodi:nodetypes="cc" />
- </g>
-</svg>
diff --git a/doc/manual/manual-appendix-materials-cohesive.tex b/doc/manual/manual-appendix-materials-cohesive.tex
index 568c0c691..88a7b6c4e 100644
--- a/doc/manual/manual-appendix-materials-cohesive.tex
+++ b/doc/manual/manual-appendix-materials-cohesive.tex
@@ -1,49 +1,70 @@
\section{Cohesive linear}
\begin{MaterialDesc}{cohesive\_linear}{ssect:smm:cl:coh-snozzi}
\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}\\
Either G\_c and kappa or, G\_cI and G\_cII or delta\_c have to be specified
\matparam{G\_c}{Real}{Mode I fracture energy}
\matparam{kappa}{Real}{$\kappa = G\_cI / G\_cII$ parameter (default 1)}
\matparam{G\_cI (G\_cII)}{Real}{Mode I (II) fracture energy}
\matparam{delta\_c}{Real}{Critical displacement $\delta_\mathrm{c}$}
\matparam{beta}{Real}{$\beta$ parameter (default 1)}
-\matparam{penalty}{Real}{penalty coefficient $\alpha$ (optional; default 0)}
+\matparam{penalty}{Real}{penalty coefficient for compression $\alpha$ (optional; default 0)}
\matparam{volume\_s \& m\_s}{Reals}{optional; to adapt statistical distribution following~\cite{Zhou_Molinari_2004}}
+\matparam{contact\_after\_breaking}{bool}{Activation of contact when the elements are fully damaged (default false)}
+\matparam{max\_quad\_stress\_insertion}{bool}{Insertion of cohesive element when stress is high enough just on one quadrature point (default false)}
\end{MaterialDesc}
\section{Cohesive bilinear}
\begin{MaterialDesc}{cohesive\_bilinear}{ssect:smm:cl:coh-snozzi}
\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}
\matparam{delta\_0}{Real}{Elastic limit displacement $\delta_0$}\\
Either G\_c and kappa or, G\_cI and G\_cII or delta\_c have to be specified
\matparam{G\_c}{Real}{Mode I fracture energy}
\matparam{kappa}{Real}{$\kappa = G\_cI / G\_cII$ parameter (default 1)}
\matparam{G\_cI (G\_cII)}{Real}{Mode I (II) fracture energy}
\matparam{delta\_c}{Real}{Critical displacement $\delta_\mathrm{c}$}
\matparam{beta}{Real}{$\beta$ parameter (default 1)}
-\matparam{penalty}{Real}{Penalty coefficient $\alpha$ (optional; default 0)}
+\matparam{penalty}{Real}{Penalty coefficient for compression $\alpha$ (optional; default 0)}
\end{MaterialDesc}
-\section{Cohesive exponential}
+\section{Cohesive linear with friction}
-\begin{MaterialDesc}{cohesive\_exponential}{ssect:smm:cl:coh-exponential}
-\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}
-\matparam{delta\_c}{Real}{Displacement at the peak traction $\delta_\mathrm{c}$}
+\begin{MaterialDesc}{cohesive\_linear\_friction}{ssect:smm:cl:coh-friction}
+\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}\\
+Either G\_c and kappa or, G\_cI and G\_cII or delta\_c have to be specified
+\matparam{G\_c}{Real}{Mode I fracture energy}
+\matparam{kappa}{Real}{$\kappa = G\_cI / G\_cII$ parameter (default 1)}
+\matparam{G\_cI (G\_cII)}{Real}{Mode I (II) fracture energy}
+\matparam{delta\_c}{Real}{Critical displacement $\delta_\mathrm{c}$}
\matparam{beta}{Real}{$\beta$ parameter (default 1)}
-\matparam{exponential\textunderscore penalty}{Bool}{parameter to activate contact penalty following the exponential law (default true)}
-\matparam{contact\textunderscore tangent}{Real}{ratio of the contact tangent over the initial exponential tangent (to be defined if exponential\textunderscore penalty is false; default 1.0)}
+\matparam{penalty}{Real}{Penalty coefficient for compression $\alpha$ (optional; default 0)}
+\matparam{volume\_s \& m\_s}{Reals}{optional; to adapt statistical distribution following~\cite{Zhou_Molinari_2004}}
+\matparam{contact\_after\_breaking}{bool}{Activation of contact when the elements are fully damaged (default false)}
+\matparam{max\_quad\_stress\_insertion}{bool}{Insertion of cohesive element when stress is high enough just on one quadrature point (default false)}
+\matparam{mu}{Real}{Maximum attainable value of the friction coefficient, $\mu$ (default 0)}
+\matparam{penalty\_for\_friction}{Real}{Penalty parameter for the elasto-plastic friction law (default 0)}
\end{MaterialDesc}
+
\section{Cohesive linear fatigue}
\begin{MaterialDesc}{cohesive\_linear\_fatigue}{ssect:smm:cl:coh-fatigue}
\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}
\matparam{delta\_c}{Real}{Critical displacement $\delta_\mathrm{c}$}
\matparam{beta}{Real}{$\beta$ parameter (default 1)}
\matparam{G\_c}{Real}{Mode I fracture energy}
\matparam{kappa}{Real}{$\kappa$ parameter (default 1)}
\matparam{penalty}{Real}{penalty coefficient $\alpha$ (optional, default 0)}
\matparam{delta\_f}{Real}{Characteristic opening displacement $\delta_\mathrm{f}$ (see~\cite{vocialta15})}
\end{MaterialDesc}
+
+\section{Cohesive exponential}
+
+\begin{MaterialDesc}{cohesive\_exponential}{ssect:smm:cl:coh-exponential}
+\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}
+\matparam{delta\_c}{Real}{Displacement at the peak traction $\delta_\mathrm{c}$}
+\matparam{beta}{Real}{$\beta$ parameter (default 1)}
+\matparam{exponential\textunderscore penalty}{Bool}{parameter to activate contact penalty following the exponential law (default true)}
+\matparam{contact\textunderscore tangent}{Real}{ratio of the contact tangent over the initial exponential tangent (to be defined if exponential\textunderscore penalty is false; default 1.0)}
+\end{MaterialDesc}
diff --git a/doc/manual/manual-cohesive_elements_insertion.tex b/doc/manual/manual-cohesive_elements_insertion.tex
index 20e251bab..ea551500f 100644
--- a/doc/manual/manual-cohesive_elements_insertion.tex
+++ b/doc/manual/manual-cohesive_elements_insertion.tex
@@ -1,81 +1,108 @@
-For cohesive material, \akantu has a pre-defined material selector to assign
-the first cohesive material by default to the cohesive elements which is called
+For cohesive material, \akantu has a pre-defined material selector to
+assign the first cohesive material by default to the cohesive elements
+which is called
\code{DefaultMaterialCohesiveSelector} and it inherits its properties from
\code{DefaultMaterialSelector}. Multiple cohesive materials can be assigned
-using mesh data information (for more details, see \ref{intrinsic_insertion}).
+using mesh data information (for more details,
+see \ref{intrinsic_insertion}).
\subsection{Insertion of Cohesive Elements}
-<<<<<<< Updated upstream
Cohesive elements are currently compatible only with static simulation
and dynamic simulation with an explicit time integration scheme (see
-section~\ref{ssect:smm:expl-time-integr}). They do not have to be inserted when the mesh is generated (intrinsic) but can be added during the simulation (extrinsic). At any time during the simulation, it is possible to access the following energies with the relative function:
+section~\ref{ssect:smm:expl-time-integr}). They do not have to be
+inserted when the mesh is generated (intrinsic) but can be added
+during the simulation (extrinsic). At any time during the simulation,
+it is possible to access the following energies with the relative
+function:
\begin{cpp}
Real Ed = model.getEnergy("dissipated");
Real Er = model.getEnergy("reversible");
Real Ec = model.getEnergy("contact");
\end{cpp}
-A new model have to be call in a very similar way that the solid mechanics model:
+A new model have to be call in a very similar way that the solid
+mechanics model:
\begin{cpp}
SolidMechanicsModelCohesive model(mesh);
model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
\end{cpp}
-\subsubsection{Extrinsic approach}
+\subsubsection{Extrinsic approach \label{extrinsic_insertion}}
The dynamic insertion of extrinsic cohesive elements should be initialized
in the following way:
\begin{cpp}
model.updateAutomaticInsertion();
-\end{cpp}
-During the simulation, stress has to be checked along each facet in order to insert cohesive elements where thestress criterion is reached.
-This check is performed by calling the method \code{checkCohesiveStress}, as
-example before each step resolution:
+\end{cpp}
+During the simulation, stress has to be checked along each facet in
+order to insert cohesive elements where the stress criterion is
+reached. This check is performed by calling the
+method \code{checkCohesiveStress}, as example before each step
+resolution:
\begin{cpp}
model.checkCohesiveStress();
model.solveStep();
\end{cpp}
-The area where stresses are checked and cohesive elements inserted can be limited
-using the method \code{limitInsertion} during initialization. As example, to
-limit insertion in the range $[-1.5, 1.5]$ in the $x$ direction:
+
+In case the extrinsic cohesive method is used in the implicit solution
+scheme, the cohesive elements are inserted one by one, starting from
+the highest locally stressed element (more precisely, the most
+stressed element per material type is inserted). When a cohesive
+element is inserted, the new equilibrated solution of the last
+incremental step is sought. Then, the
+method \code{checkCohesiveStress} is called again to check if new
+cohesive elements have to be inserted. When the insertion is
+terminated, the solution of the incremental loading step is stored,
+and the simulation can advance to the next incremental loading step.
+This procedure is managed by the function \code{solveStepCohesive}
+(for more details see \ref{sect:smm:static})
+
+The area where stresses are checked and cohesive elements inserted can
+be limited using the method \code{limitInsertion} during
+initialization. As example, to limit insertion in the range $[-1.5,
+1.5]$ in the $x$ direction:
\begin{cpp}
model.limitInsertion(_x, -1.5, 1.5);
model.updateAutomaticInsertion();
\end{cpp}
Additional restrictions with respect to $y$ and $z$ directions can be added as well.
\subsubsection{Intrinsic approach \label{intrinsic_insertion}}
-Intrinsic cohesive elements are inserted in the mesh with the method
+Intrinsic cohesive elements are inserted in the mesh with the method
\code{insertIntrinsicElements}. Similarly, the range of insertion can me limited
with \code{limitInsertion}. As example with a static simulation,
\begin{cpp}
model.limitInsertion(_x, -1.5, 1.5);
model.insertIntrinsicElements();
\end{cpp}
-Mesh data information becomes vital to the insertion of cohesive elements along
-surface with more sophisticated geometry or when multiple cohesive materials are
-wanted. To do so, cohesive elements can be inserted along a
-specific group of surface elements identified in a GMSH geometry file. This can
-be achieved with the material selector (see section~\ref{sect:smm:materialselector}), in the input file specify the name of these physical groups in the corresponding cohesive materials, and call these material in the \textit{mesh parameters} section. As example, with two physical surfaces named
+Mesh data information becomes vital to the insertion of cohesive
+elements along surface with more sophisticated geometry or when
+multiple cohesive materials are wanted. To do so, cohesive elements
+can be inserted along a specific group of surface elements identified
+in a GMSH geometry file. This can be achieved with the material
+selector (see section~\ref{sect:smm:materialselector}), in the input
+file specify the name of these physical groups in the corresponding
+cohesive materials, and call these material in the \textit{mesh
+parameters} section. As example, with two physical surfaces named
\textit{weak\_interface} and \textit{strong\_interface} defined in the GMSH
geometry file:
\begin{cpp}
...
material %\emph{cohesive\_constitutive\_law}% [
name = weak_interface
sigma_c = $value$
...
]
material %\emph{cohesive\_constitutive\_law}% [
name = strong_interface
sigma_c = $value$
...
]
mesh parameters [
cohesive_surfaces = weak_interface,strong_interface
]
\end{cpp}
In this case, there is no need to call \code{insertIntrinsicElements} anymore
since the insertion of cohesive elements along physical surfaces is performed
automatically during \code{initFull} call.
diff --git a/doc/manual/manual-cohesive_laws.tex b/doc/manual/manual-cohesive_laws.tex
index dc88f7437..b8ff2201e 100644
--- a/doc/manual/manual-cohesive_laws.tex
+++ b/doc/manual/manual-cohesive_laws.tex
@@ -1,205 +1,236 @@
-\subsection{Cohesive laws}
+\section{Cohesive Constitutive laws}
\label{sec:cohesive-laws}
-\subsubsection{Linear Irreversible Law\matlabel{ssect:smm:cl:coh-snozzi}}
+\subsection{Linear Irreversible Law\matlabel{ssect:smm:cl:coh-snozzi}}
\begin{figure}[!hbt]
\centering
\subfloat[Linear]{\includegraphics[width=0.4\textwidth]{figures/linear_cohesive_law}}
\qquad
\subfloat[Bilinear]{\includegraphics[width=0.4\textwidth]{figures/bilinear_cohesive_law}}
\caption{Irreversible cohesive laws for explicit simulations.}
\label{fig:smm:coh:linear_cohesive_law}
\end{figure}
\akantu includes the Snozzi-Molinari~\cite{snozzi_cohesive_2013}
linear irreversible cohesive law (see
Figure~\ref{fig:smm:coh:linear_cohesive_law}). It is an extension to
the Camacho-Ortiz~\cite{camacho_computational_1996} cohesive law in
order to make dissipated fracture energy path-dependent. The concept
of free potential energy is dropped and a new independent parameter
$\kappa$ is introduced:
\begin{equation}
\kappa = \frac{G_\mathrm{c, II}}{G_\mathrm{c, I}}
\end{equation}
where $G_\mathrm{c, I}$ and $G_\mathrm{c, II}$ are the
necessary works of separation per unit area to open completely a
cohesive zone under mode I and mode II, respectively. Their model yields to the
following equation for cohesive tractions $\vec{T}$ in case of crack
opening ${\delta}$:
\begin{equation}
\label{eq:smm:coh:tractions}
\vec{T} = \left( \frac{\beta^2}{\kappa} \Delta_\mathrm{t} \vec{t} +
\Delta_\mathrm{n} \vec{n} \right)
\frac{\sigma_\mathrm{c}}{\delta}
\left( 1- \frac{\delta}{\delta_\mathrm{c}} \right)
= \hat{\vec T}\,
\frac{\sigma_\mathrm{c}}{\delta}
\left( 1- \frac{\delta}{\delta_\mathrm{c}} \right)
\end{equation}
where $\sigma_\mathrm{c}$ is the material strength along the fracture,
$\delta_\mathrm{c}$ the critical effective displacement after which
cohesive tractions are zero (complete decohesion), $\Delta_\mathrm{t}$
and $\Delta_\mathrm{n}$ are the tangential and normal components of
the opening displacement vector $\vec{\Delta}$, respectively. The
parameter $\beta$ is a weight that indicates how big the tangential
opening contribution is. The effective opening displacement is:
\begin{equation}
\delta = \sqrt{\frac{\beta^2}{\kappa^2} \Delta_\mathrm{t}^2 +
\Delta_\mathrm{n}^2}
\end{equation}
In case of unloading or reloading $\delta < \delta_\mathrm{max}$,
tractions are calculated as:
\begin{align}
T_\mathrm{n} &= \Delta_\mathrm{n}\,
\frac{\sigma_\mathrm{c}}{\delta_\mathrm{max}}
\left( 1- \frac{\delta_\mathrm{max}}{\delta_\mathrm{c}} \right) \\
T_\mathrm{t} &= \frac{\beta^2}{\kappa}\, \Delta_\mathrm{t}\,
\frac{\sigma_\mathrm{c}}{\delta_\mathrm{max}}
\left( 1- \frac{\delta_\mathrm{max}}{\delta_\mathrm{c}} \right)
\end{align}
so that they vary linearly between the origin and the maximum attained
tractions. As shown in Figure~\ref{fig:smm:coh:linear_cohesive_law},
in this law, the dissipated and reversible energies are:
\begin{align}
E_\mathrm{diss} &= \frac{1}{2} \sigma_\mathrm{c}\, \delta_\mathrm{max}\\[1ex]
E_\mathrm{rev} &= \frac{1}{2} T\, \delta
\end{align}
Moreover, a damage parameter $D$ can be defined as:
\begin{equation}
D = \min \left(
\frac{\delta_\mathrm{max}}{\delta_\mathrm{c}},1 \right)
\end{equation}
which varies from 0 (undamaged condition) and 1 (fully
damaged condition). This variable can only increase because damage is
an irreversible process. A simple penalty contact model has been incorporated
in the cohesive law so that normal tractions can be returned in
case of compression:
\begin{equation}
T_\mathrm{n} = \alpha \Delta_\mathrm{n} \quad\text{if
$\Delta_\mathrm{n} < 0$}
\end{equation}
where $\alpha$ is a stiffness parameter that defaults to zero. The
relative contact energy is equivalent to reversible energy but in
compression.
The material name of the linear decreasing cohesive law is
\code{material\_cohesive\_linear} and its parameters with their
respective default values are:
\begin{itemize}
\item \code{sigma\_c}: 0
\item \code{delta\_c}: 0
\item \code{beta}: 0
\item \code{G\_c}: 0
\item \code{kappa}: 1
\item \code{penalty}: 0
\end{itemize}
where \code{G\_c} corresponds to $G_\mathrm{c, I}$. A random number
generator can be used to assign a random $\sigma_\mathrm{c}$ to each
facet following a given distribution (see
Section~\ref{sect:smm:CL}). Only one parameter between \code{delta\_c}
and \code{G\_c} has to be specified. For random $\sigma_\mathrm{c}$
distributions, the chosen parameter of these two is kept fixed and the
other one is varied.
The bilinear constitutive law works exactly the same way as the linear
one, except for the additional parameter \code{delta\_0} that by
default is zero. Two examples for the extrinsic and intrinsic cohesive
elements and also an example to assign different properties to
intergranular and transgranular cohesive elements can be found in
the folder \code{\examplesdir/cohesive\_element/}.
-\subsubsection{Linear Cohesive Law with Fatigue\matlabel{ssect:smm:cl:coh-fatigue}}
+
+\subsection{Linear Cohesive Law with Friction\matlabel{ssect:smm:cl:coh-friction}}
+
+This law represents a variation of the linear irreversible cohesive of
+the previous section, which adds friction. The friction behavior is
+approximated with an elasto-plastic law, which relates the friction
+force to the relative sliding between the two faces of the cohesive
+element. The slope of the elastic branch is called
+\emph{penalty\_for\_friction}, and is defined by the user, together
+with the friction coefficient, as a material property. The friction
+contribution evolves with the damage of the cohesive law: it is null
+when the damage is zero, and it becomes maximum when the damage is
+equal to one. This is done by defining a current value of the
+friction coefficient (mu) that increases linearly with the damage, up
+to the value of the friction coefficient defined by the user. The
+yielding plateau of the friction law is given by the product of the
+current friction coefficient and the local compression stress acting
+in the cohesive element. Such an approach is equivalent to a
+node-to-node contact friction. Its accuracy is acceptable only for
+small displacements.
+
+The material name of the linear cohesive law with friction is
+\code{material\_cohesive\_linear\_friction}. Its additional parameters
+with respect to those of the linear cohesive law without friction,
+with the respective default values, are:
+\begin{itemize}
+\item \code{mu}: 0
+\item \code{penalty\_for\_friction}: 0
+\end{itemize}
+
+
+\subsection{Linear Cohesive Law with Fatigue\matlabel{ssect:smm:cl:coh-fatigue}}
This law represents a variation of the linear irreversible cohesive
law of the previous section, that removes the hypothesis of elastic
unloading-reloading cycles. With this law, some energy is dissipated
also during unloading and reloading with hysteresis. The
implementation follows the work of~\cite{nguyen2001}. During the
unloading-reloading cycle, the traction increment is computed as
\begin{equation}
\dot{T} =
\begin{cases}
K^- \, \dot{\delta} & \text{if $\dot{\delta} < 0$} \\
K^+ \, \dot{\delta} & \text{if $\dot{\delta} > 0$} \\
\end{cases}
\end{equation}
where $\dot{\delta}$ and $\dot{T}$ are respectively the effective
opening displacement and the cohesive traction increments with respect
to time, while $K^-$ and $K^+$ are respectively the unloading and
reloading incremental stiffness. The unloading path is linear and
results in an unloading stiffness
\begin{equation}
K^- = \frac{T_\mathrm{max}}{\delta_\mathrm{max}}
\end{equation}
where $T_\mathrm{max}$ and $\delta_\mathrm{max}$ are the maximum
cohesive traction and the effective opening displacement reached
during the precedent loading phase. The unloading stiffness remains
constant during the unloading phase. On the other hand the reloading
stiffness increment $\dot{K}^+$ is calculated as
\begin{equation}
\dot{K}^+ =
\begin{cases}
- K^+ \, \dot{\delta} / \delta_\mathrm{f} & \text{if $\dot{\delta}
> 0$} \\
\left( K^+ - K^- \right) \, \dot{\delta} / \delta_\mathrm{f} &
\text{if $\dot{\delta} < 0$}
\end{cases}
\end{equation}
where $\delta_\mathrm{f}$ is a material parameter (refer
to~\cite{vocialta15} for more details). During unloading the stiffness
$K^+$ tends to $K^-$, while during reloading $K^+$ gets decreased at
every time step. If the cohesive traction during reloading exceeds the
upper limit given by equation~\eqref{eq:smm:coh:tractions}, it is
recomputed following the behavior of the linear decreasing cohesive
law for crack opening.
-\subsubsection{Exponential Cohesive Law\matlabel{ssect:smm:cl:coh-exponential}}
+\subsection{Exponential Cohesive Law\matlabel{ssect:smm:cl:coh-exponential}}
Ortiz and Pandolfi proposed this cohesive law in 1999~\cite{ortiz1999}. The
traction-opening equation for this law is as follows:
\begin{equation}
\label{eq:exponential_law}
T = e \sigma_c \frac{\delta}{\delta_c}e^{-\delta/ \delta_c}
\end{equation}
This equation is plotted in Figure~\ref{fig:smm:CL:ECL}. The term
$\partial{\vec{T}}/ \partial{\delta}$ of
equation~\eqref{eq:cohesive_stiffness} after the necessary derivation
can expressed as
\begin{equation}
\label{eq:tangent_cohesive}
\frac{\partial{\vec{T}}} {\partial{\delta}} = \hat{\vec{T}} \otimes
\frac {\partial{(T/\delta)}}{\partial{\delta}}
\frac{\hat{\vec{T}}}{\delta}+ \frac{T}{\delta} \left[ \beta^2 \mat{I} +
\left(1-\beta^2\right) \left(\vec{n} \otimes \vec{n}\right)\right]
\end{equation}
where
\begin{equation}
\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.
\end{equation}
As regards the behavior in compression, two options are available:
a contact penalty approach with stiffness following the formulation of
the exponential law and a contact penalty approach with constant
stiffness. In the second case, the stiffness is defined as a function
of the tangent of the exponential law at the origin.
\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.6\textwidth,keepaspectratio=true]{figures/cohesive_exponential.pdf}
\caption{Exponential cohesive law}
\label{fig:smm:CL:ECL}
\end{center}
\end{figure}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual-constitutive-laws.tex b/doc/manual/manual-constitutive-laws.tex
index d9e95716c..20ca5dcf8 100644
--- a/doc/manual/manual-constitutive-laws.tex
+++ b/doc/manual/manual-constitutive-laws.tex
@@ -1,528 +1,529 @@
\section{Constitutive Laws \label{sect:smm:CL}}\index{Material}
In order to compute an element's response to deformation, one needs to
use an appropriate constitutive relationship. The constitutive law is
used to compute the element's stresses from the element's strains.
In the finite-element discretization, the constitutive formulation is
applied to every quadrature point of each element. When the implicit
formulation is used, the tangent matrix has to be computed.
The chosen materials for the simulation have to be specified in the
mesh file or, as an alternative, they can be assigned using the
\code{element\_material} vector. For every material assigned to the
problem one has to specify the material characteristics (constitutive
behavior and material properties) using the text input file (see \ref{sect:io:material}).\\
In order to conveniently store values at each quadrature in a material
point \akantu provides a special data structure, the
\code{InternalField}. The internal fields are inheriting from the
\code{ElementTypeMapArray}. Furthermore, it provides several functions for
initialization, auto-resizing and auto removal of quadrature points.
Sometimes it is also desired to generate random distributions of
internal parameters. An example might be the critical stress at which the
material fails. To generate such a field, in the text input file,
a random quantity needs be added to the base value:
\begin{cpp}
sigma_c = $base$
sigma_c = $base$ uniform [$min$, $max$]
sigma_c = $base$ weibull [$\lambda$, $m$]
\end{cpp}
All parameters are real numbers. For the uniform distribution, minimum
and maximum values have to be specified.
Random parameters are defined as a $base$ value to which we add a random number
that follows the chosen distribution.
The
\href{http://en.wikipedia.org/wiki/Uniform\_distribution\_(continuous)}{\emph{Uniform}}
distribution is gives a random values between in $[min, max)$. The
\href{http://en.wikipedia.org/wiki/Weibull\_distribution}{\emph{Weibull}}
distribution is characterized by the following cumulative distribution
function:
\begin{equation}
F(x) = 1- e^{-\left({x/\lambda}\right)^m}
\end{equation}
which depends on $m$ and $\lambda$, which are the shape parameter and
the scale parameter. These random distributions are different each
time the code is executed. In order to obtain always the same one, it
possible to manually set the \emph{seed} that is the number from which
these pseudo-random distributions are created. This can be done by
adding the following line to the input file \emph{outside} the
material parameters environments:
\begin{cpp}
seed = 1.0
\end{cpp}
where the value 1.0 can be substituted with any number. Currently
\akantu can reproduce always the same distribution when the seed is
specified \emph{only} in serial. The value of the \emph{seed} can be
also specified directly in the code (for instance in the main file)
with the command:
\begin{cpp}
RandGenerator:: seed(1.0)
\end{cpp}
The same command, with empty brackets, can be used to check the value
of the \emph{seed} used in the simulation.
The following sections describe the constitutive models implemented in
\akantu. In Appendix~\ref{app:material-parameters} a summary of the
parameters for all materials of \akantu is provided.
\subsection{Elasticity}\index{Material!Elastic}
The elastic law is a commonly used constitutive relationship that can be used
for a wide range of engineering materials (\eg metals, concrete, rock, wood,
glass, rubber, etc.) provided that the strains remain small (\ie small
deformation and stress lower than yield strength).
The elastic laws are often expressed as $\mat{\sigma} =
\mat{C}:\mat{\varepsilon}$ with where $\mat{\sigma}$ is the Cauchy stress tensor,
$\mat{\varepsilon}$ represents the infinitesimal strain tensor and $\mat{C}$ is the
elastic modulus tensor.
\subsubsection{Linear isotropic\matlabel{ssect:smm:linear-elastic-isotropic}}
The linear isotropic elastic behavior is described by Hooke's law, which states
that the stress is linearly proportional to the applied strain (material behaves
like an ideal spring), as illustrated in Figure~\ref{fig:smm:cl:elastic}.
\begin{figure}[!htb]
\begin{center}
\subfloat[]{
\begin{tikzpicture}
\draw[thick,latex-latex] (0,5) node[left] {$\sigma$} |- (5,0) node (x) [right, below] {$\varepsilon$};
\draw[thin] (1.5,1.5) -- (2.5,1.5) -- (2.5,2.5) node [midway, right] {E};
\draw[very thick,color=red] (0,0) -- (4,4);
\draw[very thick,latex-latex,color=red] (1,1) -- (3,3);
\end{tikzpicture}
\label{fig:smm:cl:elastic:stress_strain} }
\hspace{0.05\textwidth} \subfloat[]{
\raisebox{0.125\textwidth}{\includegraphics[width=0.25\textwidth,keepaspectratio=true]{figures/hooke_law.pdf}}
\label{fig:smm:cl:elastic:hooke} }
\caption{(a) Stress-strain curve for elastic material and (b)
schematic representation of Hooke's law, denoted as a spring.}
\label{fig:smm:cl:elastic}
\end{center}
\end{figure}
The equation that relates the strains to the
displacements is: % First the strain is computed (at every gauss
point) from the displacements as follows:
\begin{equation}
\label{eqn:smm:strain_inf}
\mat{\varepsilon} =
\frac{1}{2} \left[ \nabla_0 \vec{u}+\nabla_0 \vec{u}^T \right]
\end{equation}
where $\mat{\varepsilon}$ represents the infinitesimal strain tensor,
$\nabla_{0}\vec{u}$ the displacement gradient
tensor according to the initial configuration. The constitutive equation
for isotropic homogeneous media can be expressed as:
\begin{equation}
\label{eqn:smm:material:constitutive_elastic}
\mat{\sigma } =\lambda\mathrm{tr}(\mat{\varepsilon})\mat{I}+2 \mu\mat{\varepsilon}
\end{equation}
where $\mat{\sigma}$ is the Cauchy stress tensor
($\lambda$ and $\mu$ are the the first and second Lame's
coefficients).
In Voigt notation this correspond to
\begin{align}
\left[\begin{array}{c}
\sigma_{11}\\
\sigma_{22}\\
\sigma_{33}\\
\sigma_{23}\\
\sigma_{13}\\
\sigma_{12}\\
\end{array}\right]
&= \frac{E}{(1+\nu)(1-2\nu)}\left[
\begin{array}{cccccc}
1-\nu & \nu & \nu & 0 & 0 & 0\\
\nu & 1-\nu & \nu & 0 & 0 & 0\\
\nu & \nu & 1-\nu & 0 & 0 & 0\\
0 & 0 & 0 & \frac{1-2\nu}{2} & 0 & 0 \\
0 & 0 & 0 & 0 & \frac{1-2\nu}{2} & 0 \\
0 & 0 & 0 & 0 & 0 & \frac{1-2\nu}{2} \\
\end{array}\right]
\left[\begin{array}{c}
\varepsilon_{11}\\
\varepsilon_{22}\\
\varepsilon_{33}\\
2\varepsilon_{23}\\
2\varepsilon_{13}\\
2\varepsilon_{12}\\
\end{array}\right]
\end{align}
\subsubsection{Linear anisotropic\matlabel{ssect:smm:linear-elastic-anisotropic}}
This formulation is not sufficient to represent all elastic material
behavior. Some materials have characteristic orientation that have to be taken
into account. To represent this anisotropy a more general stress-strain law has
to be used. For this we define the elastic modulus tensor as follow:
\begin{align}
\left[\begin{array}{c}
\sigma_{11}\\
\sigma_{22}\\
\sigma_{33}\\
\sigma_{23}\\
\sigma_{13}\\
\sigma_{12}\\
\end{array}\right]
&= \left[
\begin{array}{cccccc}
c_{11} & c_{12} & c_{13} & c_{14} & c_{15} & c_{16}\\
c_{21} & c_{22} & c_{23} & c_{24} & c_{25} & c_{26}\\
c_{31} & c_{32} & c_{33} & c_{34} & c_{35} & c_{36}\\
c_{41} & c_{42} & c_{43} & c_{44} & c_{45} & c_{46}\\
c_{51} & c_{52} & c_{53} & c_{54} & c_{55} & c_{56}\\
c_{61} & c_{62} & c_{63} & c_{64} & c_{65} & c_{66}\\
\end{array}\right]
\left[\begin{array}{c}
\varepsilon_{11}\\
\varepsilon_{22}\\
\varepsilon_{33}\\
2\varepsilon_{23}\\
2\varepsilon_{13}\\
2\varepsilon_{12}\\
\end{array}\right]
\end{align}
\begin{figure}[h]
\centering
\begin{tikzpicture}
\draw[thick,latex-latex] (90:3) node[left] {$\vec{e_2}$} |- (0:3) node [right, below] {$\vec{e_1}$};
\draw[ultra thick,latex-latex] (150:3) node[left] {$\vec{n_2}$} -- (0,0) -- (20:3) node [right] {$\vec{n_1}$};
\end{tikzpicture}
\caption{Material basis}
\end{figure}
To simplify the writing of input files the \mat{C} tensor is expressed in the
material basis. And this basis as to be given too. This basis $\Omega_{\st{mat}}
= \{\vec{n_1}, \vec{n_2}, \vec{n_3}\}$ is used to define the rotation $R_{ij} =
\vec{n_j} . \vec{e_i}$. And $\mat{C}$ can be rotated in the global basis $\Omega
= \{\vec{e_1}, \vec{e_2}, \vec{e_3}\}$ as follow:
\begin{align}
\mat{C}_{\Omega} &= \mat{R}_1 \mat{C}_{\Omega_{\st{mat}}} \mat{R}_2\\
\mat{R}_1 &= \left[
\begin{array}{cccccc}
R_{11} R_{11} & R_{12} R_{12} & R_{13} R_{13} & R_{12} R_{13} & R_{11} R_{13} & R_{11} R_{12}\\
R_{21} R_{21} & R_{22} R_{22} & R_{23} R_{23} & R_{22} R_{23} & R_{21} R_{23} & R_{21} R_{22}\\
R_{31} R_{31} & R_{32} R_{32} & R_{33} R_{33} & R_{32} R_{33} & R_{31} R_{33} & R_{31} R_{32}\\
R_{21} R_{31} & R_{22} R_{32} & R_{23} R_{33} & R_{22} R_{33} & R_{21} R_{33} & R_{21} R_{32}\\
R_{11} R_{31} & R_{12} R_{32} & R_{13} R_{33} & R_{12} R_{33} & R_{11} R_{33} & R_{11} R_{32}\\
R_{11} R_{21} & R_{12} R_{22} & R_{13} R_{23} & R_{12} R_{23} & R_{11} R_{23} & R_{11} R_{22}\\
\end{array}\right]\\
\mat{R}_2 &= \left[
\begin{array}{cccccc}
R_{11} R_{11} & R_{21} R_{21} & R_{31} R_{31} & R_{21} R_{31} & R_{11} R_{31} & R_{11} R_{21}\\
R_{12} R_{12} & R_{22} R_{22} & R_{32} R_{32} & R_{22} R_{32} & R_{12} R_{32} & R_{12} R_{22}\\
R_{13} R_{13} & R_{23} R_{23} & R_{33} R_{33} & R_{23} R_{33} & R_{13} R_{33} & R_{13} R_{23}\\
R_{12} R_{13} & R_{22} R_{23} & R_{32} R_{33} & R_{22} R_{33} & R_{12} R_{33} & R_{12} R_{23}\\
R_{11} R_{13} & R_{21} R_{23} & R_{31} R_{33} & R_{21} R_{33} & R_{11} R_{33} & R_{11} R_{23}\\
R_{11} R_{12} & R_{21} R_{22} & R_{31} R_{32} & R_{21} R_{32} & R_{11} R_{32} & R_{11} R_{22}\\
\end{array}\right]\\
\end{align}
\subsubsection{Linear orthotropic\matlabel{ssect:smm:linear-elastic-orthotropic}}
A particular case of anisotropy is when the material basis is orthogonal in which case the elastic modulus tensor can be simplified and rewritten in terms of 9 independents material parameters.
\begin{align}
\left[\begin{array}{c}
\sigma_{11}\\
\sigma_{22}\\
\sigma_{33}\\
\sigma_{23}\\
\sigma_{13}\\
\sigma_{12}\\
\end{array}\right]
&= \left[
\begin{array}{cccccc}
c_{11} & c_{12} & c_{13} & 0 & 0 & 0 \\
& c_{22} & c_{23} & 0 & 0 & 0 \\
& & c_{33} & 0 & 0 & 0 \\
& & & c_{44} & 0 & 0 \\
& \multicolumn{2}{l}{\text{sym.}} & & c_{55} & 0 \\
& & & & & c_{66}\\
\end{array}\right]
\left[\begin{array}{c}
\varepsilon_{11}\\
\varepsilon_{22}\\
\varepsilon_{33}\\
2\varepsilon_{23}\\
2\varepsilon_{13}\\
2\varepsilon_{12}\\
\end{array}\right]
\end{align}
\begin{align}
c_{11} &= E_1 (1 - \nu_{23}\nu_{32})\Gamma \qquad c_{22} = E_2 (1 - \nu_{13}\nu_{31})\Gamma \qquad c_{33} = E_3 (1 - \nu_{12}\nu_{21})\Gamma\\
c_{12} &= E_1 (\nu_{21} - \nu_{31}\nu_{23})\Gamma = E_2 (\nu_{12} - \nu_{32}\nu_{13})\Gamma\\
c_{13} &= E_1 (\nu_{31} - \nu_{21}\nu_{32})\Gamma = E_2 (\nu_{13} - \nu_{21}\nu_{23})\Gamma\\
c_{23} &= E_2 (\nu_{32} - \nu_{12}\nu_{31})\Gamma = E_3 (\nu_{23} - \nu_{21}\nu_{13})\Gamma\\
c_{44} &= \mu_{23} \qquad c_{55} = \mu_{13} \qquad c_{66} = \mu_{12} \\
\Gamma &= \frac{1}{1 - \nu_{12} \nu_{21} - \nu_{13} \nu_{31} - \nu_{32} \nu_{23} - 2 \nu_{21} \nu_{32} \nu_{13}}
\end{align}
The Poisson ratios follow the rule $\nu_{ij} = \nu_{ji} E_i / E_j$.
\subsection{Neo-Hookean\matlabel{ssect:smm:cl:neohookean}}\index{Material!Neohookean}
The hyperelastic Neo-Hookean constitutive law results from an
extension of the linear elastic relationship (Hooke's Law) for large
deformation. Thus, the model predicts nonlinear stress-strain behavior
for bodies undergoing large deformations.
\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.4\textwidth,keepaspectratio=true]{figures/stress_strain_neo.pdf}
\caption{Neo-hookean Stress-strain curve.}
\label{fig:smm:cl:neo_hookean}
\end{center}
\end{figure}
As illustrated in Figure~\ref{fig:smm:cl:neo_hookean}, the behavior is initially
linear and the mechanical behavior is very close to the corresponding linear
elastic material. This constitutive relationship, which accounts for compressibility,
is a modified version of the one proposed by Ronald Rivlin \cite{Belytschko:2000}.
The strain energy stored in the material is given by:
\begin{equation}\label{eqn:smm:constitutive:neohookean_potential}
\Psi(\mat{C}) = \frac{1}{2}\lambda_0\left(\ln J\right)^2-\mu_0\ln J+\frac{1}{2}
\mu_0\left(\mathrm{tr}(\mat{C})-3\right)
\end{equation}
\noindent where $\lambda_0$ and $\mu_0$ are, respectively, Lam\'e's first parameter
and the shear modulus at the initial configuration. $J$ is the jacobian of the deformation
gradient ($\mat{F}=\nabla_{\!\!\vec{X}}\vec{x}$): $J=\text{det}(\mat{F})$. Finally $\mat{C}$ is the right Cauchy-Green
deformation tensor.
Since this kind of material is used for large deformation problems, a
finite deformation framework should be used. Therefore, the Cauchy
stress ($\mat{\sigma}$) should be computed through the second
Piola-Kirchhoff stress tensor $\mat{S}$:
\begin{equation}
\mat{\sigma } = \frac{1}{J}\mat{F}\mat{S}\mat{F}^T
\end{equation}
Finally the second Piola-Kirchhoff stress tensor is given by:
\begin{equation}
\mat{S} = 2\frac{\partial\Psi}{\partial\mat{C}} = \lambda_0\ln J
\mat{C}^{-1}+\mu_0\left(\mat{I}-\mat{C}^{-1}\right)
\end{equation}
The parameters to indicate in the material file are the same
as those for the elastic case: \code{E} (Young's modulus), \code{nu} (Poisson's
ratio).
\subsection{Visco-Elasticity\matlabel{ssect:smm:cl:sls}}
% Standard Solid rheological model, see [] J.C. Simo, T.J.R. Hughes,
% "Computational Inelasticity", Springer (1998), see Sections 10.2 and 10.3
Visco-elasticity is characterized by strain rate dependent
behavior. Moreover, when such a material undergoes a deformation it
dissipates energy. This dissipation results in a hysteresis loop in
the stress-strain curve at every loading cycle (see
Figure~\ref{fig:smm:cl:visco-elastic:hyst}). In principle, it can be
applied to many materials, since all materials exhibit a visco-elastic
behavior if subjected to particular conditions (such as high
temperatures).
\begin{figure}[!htb]
\begin{center}
\subfloat[]{
\includegraphics[width=0.4\textwidth,keepaspectratio=true]{figures/stress_strain_visco.pdf}
\label{fig:smm:cl:visco-elastic:hyst}
}
\hspace{0.05\textwidth}
\subfloat[]{
\raisebox{0.025\textwidth}{\includegraphics[width=0.3\textwidth,keepaspectratio=true]{figures/visco_elastic_law.pdf}}
\label{fig:smm:cl:visco-elastic:model}
}
\caption{(a) Characteristic stress-strain behavior of a visco-elastic material with hysteresis loop and (b) schematic representation of the standard rheological linear solid visco-elastic model.}
\label{fig:smm:cl:visco-elastic}
\end{center}
\end{figure}
The standard rheological linear solid model (see Sections 10.2 and 10.3
of~\cite{simo92}) has been implemented in \akantu. This model results from the
combination of a spring mounted in parallel with a spring and a dashpot
connected in series, as illustrated in
Figure~\ref{fig:smm:cl:visco-elastic:model}. The advantage of this model is that
it allows to account for creep or stress relaxation. The equation that relates
the stress to the strain is (in 1D):
\begin{equation}
\frac{d\varepsilon(t)}{dt} = \left ( E + E_V \right ) ^ {-1} \cdot \left [ \frac{d\sigma(t)}{dt} + \frac{E_V}{\eta}\sigma(t) - \frac{EE_V}{\eta}\varepsilon(t) \right ]
\end{equation}
where $\eta$ is the viscosity. The equilibrium condition is unique and
is attained in the limit, as $t \to \infty $. At this stage, the
response is elastic and depends on the Young's modulus $E$. The
mandatory parameters for the material file are the following:
\code{rho} (density), \code{E} (Young's modulus), \code{nu} (Poisson's
ratio), \code{Plane\_Stress} (if set to zero plane strain, otherwise
plane stress), \code{eta} (dashpot viscosity) and \code{Ev} (stiffness
of the viscous element).
Note that the current standard linear solid model is applied only on the deviatoric part of the strain tensor. The spheric part of the strain tensor affects the stress tensor like an linear elastic material.
\subsection{Small-Deformation Plasticity\matlabel{ssect:smm:cl:plastic}}\index{Material!Small-deformation Plasticity}
The small-deformation plasticity is a simple plasticity material
formulation which accounts for the additive decomposition of strain
into elastic and plastic strain components. This formulation is
applicable to infinitesimal deformation where the additive
decomposition of the strain is a valid approximation. In this
formulation, plastic strain is a shearing process where hydrostatic
stress has no contribution to plasticity and consequently plasticity
does not lead to volume change. Figure~\ref{fig:smm:cl:Lin-strain-hard}
shows the linear strain hardening elasto-plastic behavior according to
the additive decomposition of strain into the elastic and plastic
parts in infinitesimal deformation as
\begin{align}
\mat{\varepsilon} &= \mat{\varepsilon}^e +\mat{\varepsilon}^p\\
{\mat{\sigma}} &= 2G(\mat{\varepsilon}^e) + \lambda \mathrm{tr}(\mat{\varepsilon}^e)\mat{I}
\end{align}
\begin{figure}[htp]
\centering
{\includegraphics[scale=0.4, clip]{figures/isotropic_hardening_plasticity.pdf}}
\caption{
Stress-strain curve for the small-deformation plasticity with linear isotropic hardening.
}
\label{fig:smm:cl:Lin-strain-hard}
\end{figure}
\noindent In this class, the von Mises yield criterion is used. In the von Mises yield criterion, the yield is independent of the hydrostatic stress. Other yielding criteria such as Tresca and Gurson can be easily implemented in this class as well.
In the von Mises yield criterion, the hydrostatic stresses have no effect on the plasticity and consequently the yielding occurs when a critical elastic shear energy is achieved.
\begin{equation} \label{eqn:smm:constitutive:von Mises}
f = \sigma_{\st{eff}} - \sigma_y = \left(\frac{3}{2} {\mat{\sigma}}^{\st{tr}} : {\mat{\sigma}}^{\st{tr}}\right)^\frac{1}{2}-\sigma_y (\mat{\varepsilon}^p)
\end{equation}
\begin{equation} \label{eqn:smm:constitutive:yielding}
f < 0 \quad \textrm{Elastic deformation,} \qquad f = 0 \quad \textrm{Plastic deformation}
\end{equation}
where $\sigma_y$ is the yield strength of the material which can be function of plastic strain in case of hardening type of materials and ${\mat{\sigma}}^{\st{tr}}$ is the deviatoric part of stress given by
\begin{equation} \label{eqn:smm:constitutive:deviatoric stress}
{\mat{\sigma}}^{\st{tr}}=\mat{\sigma} - \frac{1}{3} \mathrm{tr}(\mat{\sigma}) \mat {I}
\end{equation}
After yielding $(f = 0)$, the normality hypothesis of plasticity determines the direction of plastic flow which is normal to the tangent to the yielding surface at the load point. Then, the tensorial form of the plastic constitutive equation using the von Mises yielding criterion (see equation 4.34) may be written as
\begin{equation} \label{eqn:smm:constitutive:plastic contitutive equation}
\Delta {\mat{\varepsilon}}^p = \Delta p \frac {\partial{f}}{\partial{\mat \sigma}}=\frac{3}{2} \Delta p \frac{{\mat{\sigma}}^{\st{tr}}}{\sigma_{\st{eff}}}
\end{equation}
In these expressions, the direction of the plastic strain increment (or equivalently, plastic strain rate) is given by $\frac{{\mat{\sigma}}^{\st{tr}}}{\sigma_{\st{eff}}}$ while the magnitude is defined by the plastic multiplier $\Delta p$. This can be obtained using the \emph{consistency condition} which impose the requirement for the load point to remain on the yielding surface in the plastic regime.
Here, we summarize the implementation procedures for the
small-deformation plasticity with linear isotropic hardening:
\begin{enumerate}
\item Compute the trial stress:
\begin{equation}
{\mat{\sigma}}^{\st{tr}} = {\mat{\sigma}}_t + 2G\Delta \mat{\varepsilon} + \lambda \mathrm{tr}(\Delta \mat{\varepsilon})\mat{I}
\end{equation}
\item Check the Yielding criteria:
\begin{equation}
f = (\frac{3}{2} {\mat{\sigma}}^{\st{tr}} : {\mat{\sigma}}^{\st{tr}})^{1/2}-\sigma_y (\mat{\varepsilon}^p)
\end{equation}
\item Compute the Plastic multiplier:
\begin{align}
d \Delta p &= \frac{\sigma^{tr}_{eff} - 3G \Delta P^{(k)}- \sigma_y^{(k)}}{3G + h}\\
\Delta p^{(k+1)} &= \Delta p^{(k)}+ d\Delta p\\
\sigma_y^{(k+1)} &= (\sigma_y)_t+ h\Delta p
\end{align}
\item Compute the plastic strain increment:
\begin{equation}
\Delta {\mat{\varepsilon}}^p = \frac{3}{2} \Delta p \frac{{\mat{\sigma}}^{\st{tr}}}{\sigma_{\st{eff}}}
\end{equation}
\item Compute the stress increment:
\begin{equation}
{\Delta \mat{\sigma}} = 2G(\Delta \mat{\varepsilon}-\Delta \mat{\varepsilon}^p) + \lambda \mathrm{tr}(\Delta \mat{\varepsilon}-\Delta \mat{\varepsilon}^p)\mat{I}
\end{equation}
\item Update the variables:
\begin{align}
{\mat{\varepsilon^p}} &= {\mat{\varepsilon}}^p_t+{\Delta {\mat{\varepsilon}}^p}\\
{\mat{\sigma}} &= {\mat{\sigma}}_t+{\Delta \mat{\sigma}}
\end{align}
\end{enumerate}
We use an implicit integration technique called \emph{the radial
return method} to obtain the plastic multiplier. This method has the
advantage of being unconditionally stable, however, the accuracy
remains dependent on the step size. The plastic parameters to indicate
in the material file are: \code{$\sigma_y$} (Yield stress) and
\code{h} (Hardening modulus). In addition, the elastic parameters need
to be defined as previously mentioned: \code{E} (Young's modulus),
\code{nu} (Poisson's ratio).
\subsection{Damage}
In the simplified case of a linear elastic and brittle material, isotropic
damage can be represented by a scalar variable $d$, which varies from $0$ to $1$
for no damage to fully broken material respectively. The stress-strain
relationship then becomes:
\begin{equation*}
\mat{\sigma} = (1-d)\, \mat{C}:\mat{\varepsilon}
\end{equation*}
where $\mat{\sigma}$, $\mat{\varepsilon}$ are the Cauchy stress and strain
tensors, and $\mat{C}$ is the elastic stiffness tensor. This formulation relies
on the definition of an evolution law for the damage variable. In \akantu, many
possibilities exist and they are listed below.
\subsubsection{Marigo\matlabel{ssect:smm:cl:damage-marigo}}
This damage evolution law is energy based as defined by Marigo \cite{marigo81a,
lemaitre96a}. It is an isotropic damage law.
\begin{align}
Y &= \frac{1}{2}\mat{\varepsilon}:\mat{C}:\mat{\varepsilon}\\
F &= Y - Y_d - S d\\
d &= \left\{
\begin{array}{l l}
\mathrm{min}\left(\frac{Y-Y_d}{S},\;1\right) & \mathrm{if}\; F > 0\\
\mathrm{unchanged} & \mathrm{otherwise}
\end{array}
\right.
\end{align}
In this formulation, $Y$ is the strain energy release rate, $Y_d$ the
rupture criterion and $S$ the damage energy. The non-local version of
this damage evolution law is constructed by averaging the energy $Y$.
\subsubsection{Mazars\matlabel{ssect:smm:cl:damage-mazars}}
This law introduced by Mazars \cite{mazars84a} is a behavioral model to
represent damage evolution in concrete. This model does not rely on the computation of the tangent stiffness, the damage is directly evaluated from the strain.
The governing variable in this damage
law is the equivalent strain $\varepsilon_{\st{eq}} =
\sqrt{<\mat{\varepsilon}>_+:<\mat{\varepsilon}>_+}$, with $<.>_+$ the positive
part of the tensor. This part is defined in the principal coordinates (I, II, III) as $\varepsilon_{\st{eq}} =
\sqrt{<\mat{\varepsilon_I}>_+^2 + <\mat{\varepsilon_{II}}>_+^2 + <\mat{\varepsilon_{III}}>_+^2}$.
The damage is defined as:
\begin{align}
D &= \alpha_t^\beta D_t + (1-\alpha_t)^\beta D_c\\
D_t &= 1 - \frac{\kappa_0 (1- A_t)}{\varepsilon_{\st{eq}}} - A_t \exp^{-B_t(\varepsilon_{\st{eq}}-\kappa_0)}\\
D_c &= 1 - \frac{\kappa_0 (1- A_c)}{\varepsilon_{\st{eq}}} - A_c
\exp^{-B_c(\varepsilon_{\st{eq}}-\kappa_0)}\\
\alpha_t &= \frac{\sum_{i=1}^3<\varepsilon_i>_+\varepsilon_{\st{nd}\;i}}{\varepsilon_{\st{eq}}^2}
\end{align}
With $\kappa_0$ the damage threshold, $A_t$ and $B_t$ the damage parameter in
traction, $A_c$ and $B_c$ the damage parameter in compression, $\beta$ is the
shear parameter. $\alpha_t$ is the coupling parameter between traction and
compression, the $\varepsilon_i$ are the eigenstrain and the
$\varepsilon_{\st{nd}\;i}$ are the eigenvalues of the strain if the material
were undamaged.
The coefficients $A$ and $B$ are the post-peak asymptotic
value and the decay shape parameters.
-\IfFileExists{manual-constitutive-laws-non_local.tex}{\input{manual-constitutive-laws-non_local.tex}}{}
+\IfFileExists{manual-cohesive_laws.tex}{\input{manual-cohesive_laws}}{}
+
+\IfFileExists{manual-constitutive-laws-non_local.tex}{\input{manual-constitutive-laws-non_local}}{}
\IfFileExists{manual-extra_materials.tex}{\input{manual-extra_materials}}{}
-\IfFileExists{manual-cohesive_laws.tex}{\input{manual-cohesive_laws}}{}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual-contact.tex b/doc/manual/manual-contact.tex
deleted file mode 100644
index e0b4d1d23..000000000
--- a/doc/manual/manual-contact.tex
+++ /dev/null
@@ -1,335 +0,0 @@
-
-
-\chapter{Contact}
-
-\section{Implicit Contact Solver}
-
-The contact formulation corresponds to the augmented-Lagrangian method \cite{Laursen:2002}, which seeks to minimize the following energy functional between two bodies with contact interface $ \Gamma_c^{\left( 1 \right)} $:
-\begin{equation} \label{eq:functinal}
- \Pi^{al} \left( \boldsymbol u, \lambda_N \right) := \sum_{i=1}^2 \Pi ^{\left( i \right) } ( \boldsymbol u ^{\left( i \right) } ) + \int_{\Gamma_c^{\left( 1 \right) } } \left[ \frac{1}{2 \epsilon_N } \left< \lambda_N + \epsilon_N g \right>^ 2 - \frac{1}{2 \epsilon_N} \lambda^2_N \right] \, d\Gamma,
-\end{equation}
-where $ \Pi^{\left( i \right) } $ corresponds to the energy functional of the $ i $-th body in contact, which is a function of the displacement field $\boldsymbol u$ and the Lagrangian multiplier $\lambda_N$. In the equation above, $\epsilon_N$ is a penalty parameter, $g$ the contact gap function, and $\left< \cdot \right>$ the Macaulay bracket.
-
-The solution procedure seeks to make the equation above stationary with respect to both $\boldsymbol u$ and $\lambda_N$:
-\begin{equation}
-\begin{aligned}
- 0 &= D_{\boldsymbol u} \Pi^{al} \cdot \boldsymbol w = G^{int,ext} \left( \boldsymbol u, \boldsymbol w \right) + \int_{\Gamma_c^{\left( 1 \right) } } \left< \lambda_N + \epsilon_N g \right> \delta g \, d\Gamma \qquad \forall \boldsymbol w \in \mathcal{V} \\
-0 &= D_{ \lambda} \Pi^{al} \cdot q_N = \frac{1}{\epsilon_N} \int_{\Gamma_c^{\left( 1 \right) } } \left[ \left< \lambda_N + \epsilon_N g \right> - \lambda_N \right] q_N \, d\Gamma \qquad \forall q_N \in \mathcal{M}
-\end{aligned}
-\end{equation}
-
-A solution is then found by using Uzawa's method, for which we solve for $ \boldsymbol u ^ {\left( k \right) }$, with $ \lambda_N^{\left( k \right)}$ fixed:
-\begin{equation}
- G^{int,ext} ( \boldsymbol u ^ {\left( k \right) }, \boldsymbol w ) + \int_{\Gamma_c^{\left( 1 \right) } } \left< \lambda_N^ {\left( k \right) } + \epsilon_N g( \boldsymbol u ^ {\left( k \right) } ) \right> \delta g \, d\Gamma = 0 \qquad \forall \boldsymbol w \in \mathcal{V},
- \end{equation}
-
-followed by an update of the multipliers on $\Gamma_c ^ {\left( 1 \right) }$:
-\begin{equation}
-\lambda _N ^ {\left( k+1 \right) } = \left< \lambda_N ^ {\left( k \right) } + \epsilon_N g ( \boldsymbol u ^ {\left( k \right) } ) \right>.
-\end{equation}
-
-
-It is worth noting that the results of the implicit contact resolution depend largely on the choice of the penalty parameter $ \epsilon_N $. Depending on this parameter, the computational time needed to obtain a converged solution can be increased dramatically, or a convergence solution could not even be obtained at all.
-
-The code provides a flag that allows the user to rely on an automatic value of $ \epsilon_N $ for each slave node. Yet, this value should be used as a reference only, since for some problems it is actually overestimated and convergence cannot be obtained.
-
-
-\subsection{Implementation}
-
-In \akantu, the object that handles the implicit contact can be found in \code{implicit\_contact\_manager.hh}.
-The object that handles the implicit contact resolution stage is the class template
-\begin{cpp}
-template <int dim, class model_type> struct ContactData;
-\end{cpp}
-This object takes the command line parameters during construction, which can be used to set up the behavior during contact resolution. The object can take the following parameters (default values in brackets):
-
-\begin{tabular}{lrl}
- -e & [auto] & Penalty parameter for augmented-Lagrangian formulation \\
- -alpha & [1] & Multiplier for values of the penalty parameter\\
- -utol & [0.001] & Tolerance used for multipliers in the Uzawa method\\
- -ntol &[0.001]& Tolerance used in the Newton-Raphson inner convergence loop\\
- -usteps &[100]& Maximum number of steps allowed in the Uzawa loop\\
- -nsteps & [100]& Maximum number of steps allowed in the Newton-Raphson loop\\
-\end{tabular} \\
-
-
-Also, the following flags can be given to the command line
-
-
-\begin{tabular}{ll}
- -dump& Dumping within Newton iterations \\
- -v& Verbose output
-\end{tabular} \\
-
-
-
-The \code{ContactData} object stores the state of the contact mechanics simulation. The state is contained within the following variables:
-
-\begin{tabular}{ll}
- \code{sm\_} & slave-master map \\
- \code{multipliers\_} & Lagrange multiplier map \\
- \code{areas\_} & slave areas map \\
- \code{penalty\_} & penalty parameter map \\
- \code{gaps\_} & gap function map \\
- \code{model\_} & reference to solid mechanics model \\
- \code{multiplier\_dumper\_} & structures used to dump multipliers \\
- \code{pressure\_dumper\_} & structures used to dump pressure \\
- \code{options\_} & options map \\
- \code{flags\_} & flags map \\
- \code{uiter\_}, \code{niter\_} & Uzawa and Newton iteration counters
-\end{tabular} \\
-
-
-The interface of the \code{ContactData} object contains three methods to solve for each contact step, which is overloaded depending on the parameters passed. Their signatures are as follows
-
-
-\begin{cpp}
-void solveContactStep();
-
-void solveContactStep(search_type *search);
-
-template <class PostAssemblyFunctor>
-void solveContactStep(search_type *search, const PostAssemblyFunctor& fn);
-}
-\end{cpp}
-
-The second method allows the user to provide a pointer to an object that is used to search slave-master pairs. This can be done, for example, when due to the deformed configuration current slave-master pairs are no longer valid.
-The last method in the snippet above allows the user to provide a functor that is called after the assembly of the contact contributions to the stiffness matrix and the force vector. The last takes place within the method \code{computeTangentAndResidual()}.
-
-
-\subsubsection{Hertz Example}
-
-
-Here we outline, step by step, the use of the implicit contact solver to obtain the solution of Hertzian contact. The complete implementation can be found in \code{examples/contact/hertz\_3D.cc}.
-
-The following class is used as the object that will perform the search for new contact elements when a slave node is found to lie outside its master element. The class derives from a \code{SearchBase} class, and implements the virtual method \code{search}.
-
-\begin{cpp}
-struct Assignator : public ContactData<3,SolidMechanicsModel>::SearchBase {
- typedef Point <3> point_type;
- typedef SolidMechanicsModel model_type;
- typedef ModelElement <model_type> master_type;
-
- model_type &model_;
-
- Assignator(model_type& model) : model_(model) {}
-
- virtual int search(const Real *ptr) {
- point_type p(ptr);
-
- ElementGroup &rs = model_.getMesh().getElementGroup("rigid_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) {
- master_type m(model_, _triangle_3, *it);
- if (point_has_projection_to_triangle(p, m.point <3>(0), m.point <3>(1), m.point <3>(2))) {
- return m.element;
- }
- }
- return -1;
- }
-};
-\end{cpp}
-
-
-The first thing we do in the main file is to add some type definitions:
-
-\begin{cpp}
-
-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 ModelElement <model_type> master_type;
- typedef ContactData <dim, model_type> contact_type;
-
- typedef std::chrono::high_resolution_clock clock;
- typedef std::chrono::seconds seconds;
-\end{cpp}
-
-We initialize the library, create a mesh, and set the solid mechanics model up:
-
-\begin{cpp}
-
- 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);
-\end{cpp}
-
-
-Then we create the contact data, which can be used to solve the contact problem. Note that some of the parameters required by the contact object can be coded in the implementation file (these can also be passed as arguments).
-\begin{cpp}
-
- // create data structure that holds contact data
- contact_type cd(argc, argv, model);
-
- // optimal value of penalty multiplier
- cd[Alpha] = 0.05;
- cd[Uzawa_tol] = 1.e-2;
- cd[Newton_tol] = 1.e-2;
-\end{cpp}
-
-
-Next we find the area that corresponds to each slave node. For this we use the fact that if we apply a unit distributed load over the contact surface, the resulting force vector at each slave node has magnitude that is equal to the area.
-\begin{cpp}
-
- // get physical names from Gmsh file
- mesh.createGroupsFromMeshData <std::string>("physical_names");
-
- // 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");
- cout << "- Adding areas to slave nodes. " << endl;
- for (auto nit = eg.node_begin(); nit != eg.node_end(); ++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();
-\end{cpp}
-
-Note that we clear the force vector after the assignment of areas.
-
-In the next step we prescribe the boundary conditions that do not change in time:
-
-\begin{cpp}
-
- // apply boundary conditions for the rigid plane
- model.applyBC(BC::Dirichlet::FixedValue(0., BC::_x), "bottom_body");
- model.applyBC(BC::Dirichlet::FixedValue(0., BC::_y), "bottom_body");
- model.applyBC(BC::Dirichlet::FixedValue(0., BC::_z), "bottom_body");
-
- // block z-disp in extreme points of top surface
- model.getBoundary()(1, 2) = true;
- model.getBoundary()(2, 2) = true;
-
- // block x-disp in extreme points of top surface
- model.getBoundary()(3, 0) = true;
- model.getBoundary()(4, 0) = true;
-
-\end{cpp}
-
-
-Next we add the slave-master pairs for the analysis. We use a bounding box to consider only a fraction of the slave nodes in the model. Those slave nodes that are not within the bounding box are not considered in the analysis:
-\begin{cpp}
-
- // 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);
-
- // search policy for slave-master pairs
- Assignator a(model);
-
-
- // loop over nodes in contact surface to create contact elements
- cout << "- Adding slave-master pairs" << endl;
- for (auto nit = cs.node_begin(); nit != cs.node_end(); ++nit) {
- point_type p(&coords(*nit));
-
- // ignore slave node if it doesn't lie within the bounding box
- if (!(bb & p))
- continue;
-
- int el = a.search(&coords(*nit));
- if (el != -1)
- cd.addPair(*nit, master_type(model, _triangle_3, el));
- }
-\end{cpp}
-
-
-We then start the loop over displacement increments, and at each step we call {{{solveContactStep}}} and save the displacement, resulting force, and maximum pressure, in an array that will be used to print the results at the end of the simulation:
-\begin{cpp}
-
- 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, BC::_y), "top_surface");
-
- // solve contact step, this method also dumps Paraview files
- cd.solveContactStep(&a);
-
- data[0][k] = delta;
- data[1][k] = cd.getForce();
- data[2][k] = cd.getMaxPressure();
- ++k;
- }
-\end{cpp}
-
-
-The last portion of the output of code above is as follows:
-\begin{verbatim}
- Disp. Force Max pressure
- 0 0 0
- 0.001 1.29 6.068e+04
- 0.002 6.702e+06 6.78e+09
- 0.003 1.832e+07 9.453e+09
- 0.004 3.349e+07 1.091e+10
- 0.005 5.2e+07 1.171e+10
- 0.006 7.211e+07 1.298e+10
- 0.007 9.377e+07 1.481e+10
- 0.008 1.183e+08 1.624e+10
- 0.009 1.41e+08 1.616e+10
- 0.01 1.7e+08 1.688e+10
- 0.011 1.963e+08 1.678e+10
- 0.012 2.263e+08 1.758e+10
- 0.013 2.581e+08 1.805e+10
- 0.014 2.907e+08 1.821e+10
- 0.015 3.244e+08 1.877e+10
- 0.016 3.593e+08 1.954e+10
- 0.017 4.051e+08 2.131e+10
- 0.018 4.317e+08 2.115e+10
- 0.019 4.823e+08 2.201e+10
- 0.02 5.237e+08 2.315e+10
- 0.021 5.639e+08 2.379e+10
- 0.022 6.058e+08 2.405e+10
- 0.023 6.483e+08 2.485e+10
- 0.024 6.917e+08 2.536e+10
- 0.025 7.363e+08 2.854e+10
- 0.026 7.681e+08 3.099e+10
- 0.027 8.332e+08 3.291e+10
- 0.028 8.577e+08 3.399e+10
- 0.029 9.281e+08 3.426e+10
-\end{verbatim}
-
-The following figure shows the deformed state of the half-sphere at the end of the simulation, together with the contact pressure distribution:
-
-\begin{figure}[htbp]
-\begin{center}
-\includegraphics[scale=0.3]{figures/hertz_3D.png}
-\caption{State of pressure and deformation at the end of the simulation of the example of Hertz in 3D.}
-\label{fig:hertz_3D}
-\end{center}
-\end{figure}
diff --git a/doc/manual/manual-planning.tex b/doc/manual/manual-planning.tex
deleted file mode 100644
index c903ac992..000000000
--- a/doc/manual/manual-planning.tex
+++ /dev/null
@@ -1,20 +0,0 @@
-\chapter{Planning}
-
-\begin{description}
-\item[03/12/12] Cyprien: Explicit time integration scheme
-\item[03/29/12] Aurelia: Boundary conditions
-\item[04/13/12] Leonardo: Existing constitutive laws
-\item[04/20/12] Mohadeseh: Adding a constitutive law
-\item[04/27/12] Peter: Adding an element
-\item[05/04/12] Till: Structural mechanics model
-\item[05/11/12] Guillaume: Heat transfer model
-\item[05/18/12] Marco: Cohesive elements
-\item[05/25/12] Alejandro: Contact detection
-\item[06/01/12] David: Contact analysis
-\end{description}
-
-\begin{figure}[!htb]
- \centering
- \includegraphics[width=\linewidth]{figures/doc_wheel}
- \caption{Documentation wheel\label{fig:doc_wheel}}
-\end{figure}
diff --git a/doc/manual/manual-python.tex b/doc/manual/manual-python.tex
new file mode 100644
index 000000000..33c5e274e
--- /dev/null
+++ b/doc/manual/manual-python.tex
@@ -0,0 +1,111 @@
+\chapter{Python interface\index{Python}\label{sect:python}}
+
+Akantu as a python interface which allows to implement a finite
+element case entirely in the Python language. The interface is
+currently in \textcolor{red}{beta} version and bugs (including memory
+leaks) can be expected.
+
+The philosophy of the python wrappers is that it should follow, as
+much as possible, the C++ interface. This is made possible thanks to
+the \href{SWIG}{} software which can port C++ interfaces to Python.
+However, the possibilities of the Python language have some
+restrictions which do not allow the concept of template. For this
+reason the templated classes and methods are currently hardly
+supported in the Akantu Python interface (some are, but without any
+warranty that the interface shall not change in a near future).
+
+In order to use the python interface you want to import the
+\code{akantu} module which is possibly located in directory where you
+built or where you installed \akantu. The easiest way is to source
+the file \code{akantu\_environement.sh} in your terminal environment:
+
+\begin{command}
+source AKANTU_BUILD_DIR/akantu_environement.sh
+\end{command}
+
+or for an installed akantu version:
+
+\begin{command}
+source AKANTU_INSTALL_DIR/share/akantuVERSION/akantu_environement.sh
+\end{command}
+
+Then, you can create a Python script, like \code{script.py} which
+starts with:
+
+\begin{python}
+import akantu
+\end{python}
+
+Then, you can write the initialization sequence just like for the C++
+case:
+
+\begin{python}
+akantu.initialize('materials.dat') spatial_dimension = 2
+
+mesh = akantu.Mesh(spatial_dimension) mesh.read('mesh.msh')
+model = akantu.SolidMechanicsModel(mesh)
+model.initFull(akantu.SolidMechanicsModelOptions(akantu._static))
+\end{python}
+Then for the dumpers declaration:
+\begin{python}
+model.setBaseName("example") model.addDumpFieldVector("displacement")
+model.addDumpFieldVector("force") model.addDumpField("boundary")
+model.addDumpField("strain") model.addDumpField("stress")
+model.addDumpField("blocked_dofs")
+\end{python}
+
+The \akantu arrays can be retrieved at all time. For convenience there
+is an automatic trans-typing operator which allows to use \akantu
+Array, Vectors and Matrix as mere \textbf{Numpy}s.
+
+\begin{python}
+displacement = model.getDisplacement()
+\end{python}
+
+There is no copy made and the \textbf{Numpy} vectors are wrapped
+around \akantu's memory pool.
+
+\begin{python}
+displacement[:,:] = 1.
+displacement[0,1] = 10.
+\end{python}
+
+Also to assign an entire vector to another the '[]' operator must be
+used:
+
+\begin{python}
+result = numpy.linspace(0.,1.,100)
+
+# This works
+displacement[:] = result[:]
+# This does not
+displacement = result
+\end{python}
+
+Then you can solve the problem for instance with:
+\begin{python}
+model.solveStaticDisplacement(1e-10,2);
+\end{python}
+And dump to Paraview:
+\begin{python}
+model.dump()
+\end{python}
+
+Do not forget to finalize at the end of the script:
+\begin{python}
+akantu.finalize()
+\end{python}
+
+Finally the python script can be launched with:
+\begin{command}
+python ./script.py
+\end{command}
+
+\vspace{1cm}
+
+\textcolor{red}{Warning!} : We recall once more that the Python
+interface is in \textbf{beta} state and is provided only for its nice
+services: it avoids recompilation of akantu when coding the main function.
+Several preliminary examples are provided
+in the \code{examples} directory where it is described how to specify
+boundary conditions and also constitutive behavior.
diff --git a/doc/manual/manual-solidmechanicsmodel.tex b/doc/manual/manual-solidmechanicsmodel.tex
index 5c3073d47..b06c528ff 100644
--- a/doc/manual/manual-solidmechanicsmodel.tex
+++ b/doc/manual/manual-solidmechanicsmodel.tex
@@ -1,1101 +1,1142 @@
\chapter{Solid Mechanics Model\index{SolidMechanicsModel}\label{sect:smm}}
The solid mechanics model is a specific implementation of the
\code{Model} interface dedicated to handle the equations of motion or
equations of equilibrium. The model is created for a given mesh. It
will create its own \code{FEEngine} object to compute the interpolation,
gradient, integration and assembly operations. A
\code{SolidMechanicsModel} object can simply be created like this:
\begin{cpp}
SolidMechanicsModel model(mesh);
\end{cpp}
where \code{mesh} is the mesh for which the equations are to be
solved. A second parameter called \code{spatial\_dimension} can be
added after \code{mesh} if the spatial dimension of the problem is
different than that of the mesh.
This model contains at least the following six \code{Arrays}:
\begin{description}
\item[blocked\_dofs] contains a Boolean value for each degree of
freedom specifying whether that degree is blocked or not. A
Dirichlet boundary condition can be prescribed by setting the
\textbf{blocked\_dofs} value of a degree of freedom to \code{true}.
A Neumann boundary condition can be applied by setting the
\textbf{blocked\_dofs} value of a degree of freedom to \code{false}.
The \textbf{displacement}, \textbf{velocity} and
\textbf{acceleration} are computed for all degrees of freedom for
which the \textbf{blocked\_dofs} value is set to \code{false}. For
the remaining degrees of freedom, the imposed values (zero by
default after initialization) are kept.
\item[displacement] contains the displacements of all degrees of
freedom. It can be either a computed displacement for free degrees
of freedom or an imposed displacement in case of blocked ones
($\vec{u}$ in the following).
\item[velocity] contains the velocities of all degrees of freedom. As
\textbf{displacement}, it contains computed or imposed velocities
depending on the nature of the degrees of freedom ($\dot{\vec{u}}$
in the following).
\item[acceleration] contains the accelerations of all degrees of
freedom. As \textbf{displacement}, it contains computed or imposed
accelerations depending on the nature of the degrees of freedom
($\ddot{\vec{u}}$ in the following).
\item[force] contains the external forces applied on the nodes
($\vec{f}_{\st{ext}}$ in the following).
\item[residual] contains the difference between external and internal
forces. On blocked degrees of freedom, \textbf{residual} contains
the support reactions. ($\vec{r}$ in the following). It should be
mentioned that at equilibrium \textbf{residual} should be zero on
free degrees of freedom.
\end{description}
Some examples to help to understand how to use this model will be
presented in the next sections.
\section{Model Setup}
\subsection{Setting Initial Conditions \label{sect:smm:initial_condition}}
For a unique solution of the equations of motion, initial
displacements and velocities for all degrees of freedom must be
specified:
\begin{eqnarray}
\vec{u}(t=0) = \vec{u}_0\\
\dot{\vec u}(t=0) =\vec{v}_0
\end{eqnarray} The solid mechanics model can be initialized as
follows:
\begin{cpp}
model.initFull()
\end{cpp}
This function initializes the internal arrays and sets them to
zero. Initial displacements and velocities that are not equal to zero
can be prescribed by running a loop over the total number of
nodes. Here, the initial displacement in $x$-direction and the
initial velocity in $y$-direction for all nodes is set to $0.1$ and $1$,
respectively.
\begin{cpp}
Array<Real> & disp = model.getDisplacement();
Array<Real> & velo = model.getVelocity();
for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
disp(i, 0) = 0.1;
velo(i, 1) = 1.;
}
\end{cpp}
\subsection{Setting Boundary Conditions\label{sect:smm:boundary}}
This section explains how to impose Dirichlet or Neumann boundary
conditions. A Dirichlet boundary condition specifies the values that
the displacement needs to take for every point $x$ at the boundary
($\Gamma_u$) of the problem domain (Fig.~\ref{fig:smm:boundaries}):
\begin{equation}
\vec{u} = \bar{\vec u} \quad \forall \vec{x}\in
\Gamma_{u}
\end{equation}
A Neumann boundary condition imposes the value of the gradient of the
solution at the boundary $\Gamma_t$ of the problem domain
(Fig.~\ref{fig:smm:boundaries}):
\begin{equation}
\vec{t} = \mat{\sigma} \vec{n} = \bar{\vec t} \quad
\forall \vec{x}\in \Gamma_{t}
\end{equation}
\begin{figure} \centering
\def\svgwidth{0.5\columnwidth}
\input{figures/problemDomain.pdf_tex}
\caption{Problem domain $\Omega$ with boundary in three
dimensions. The Dirchelet and the Neumann regions of the boundary
are denoted with $\Gamma_u$ and $\Gamma_t$,
respecitvely.\label{fig:smm:boundaries}}
\label{fig:problemDomain}
\end{figure}
Different ways of imposing these boundary conditions exist. A basic
way is to loop over nodes or elements at the boundary and apply local
values. A more advanced method consists of using the notion of the
boundary of the mesh. In the following both ways are presented.
Starting with the basic approach, as mentioned, the Dirichlet boundary
conditions can be applied by looping over the nodes and assigning the
required values. Figure~\ref{fig:smm:dirichlet_bc} shows a beam with a
fixed support on the left side. On the right end of the beam, a load
is applied. At the fixed support, the displacement has a given
value. For this example, the displacements in both the $x$ and the
$y$-direction are set to zero. Implementing this displacement boundary
condition is similar to the implementation of initial displacement
conditions described above. However, in order to impose a displacement
boundary condition for all time steps, the corresponding nodes need to
be marked as boundary nodes using the function \code{blocked}. While,
in order to impose a load on the right side, the nodes are not marked.
The detail codes are shown as follows:
\begin{cpp}
Array<bool> & blocked = model.getBlockedDOFs();
const Array<Real> & pos = mesh.getNodes();
UInt nb_nodes = mesh.getNbNodes();
for (UInt i = 0; i < nb_nodes; ++i) {
if(Math::are_float_equal(pos(i, 0), 0)) {
blocked(i, 0) = true; //block dof in x-direction
blocked(i, 1) = true; //block dof in y-direction
disp(i, 0) = 0.; //fixed displacement in x-direction
disp(i, 1)= 0.; //fixed displacement in y-direction
} else if (Math::are_float_equal(pos(i, 10), 0)) {
blocked(i, 0) = false; //unblock dof in x-direction
forces(i, 0) = 10.; //force in x-direction
}
}
\end{cpp}
\begin{figure}[!htb]
\centering
\includegraphics[scale=0.4]{figures/dirichlet}
\caption{Beam with fixed support and load.\label{fig:smm:dirichlet_bc}}
\end{figure}
For the more advanced approach, one needs the notion of a boundary in
the mesh. Therefore, the boundary should be created before boundary
condition functors can be applied. Generally the boundary can be
specified from the mesh file or the geometry. For the first case, the
function \code{createGroupsFromMeshData} is called. This function
can read any types of mesh data which are provided in the mesh
file. If the mesh file is created with Gmsh, the function takes one
input strings which is either \code{tag\_0}, \code{tag\_1} or
\code{physical\_names}. The first two tags are assigned by Gmsh to
each element which shows the physical group that they belong to. In
Gmsh, it is also possible to consider strings for different groups of
elements. These elements can be separated by giving a string
\code{physical\_names} to the function
\code{createGroupsFromMeshData}:
\begin{cpp}
mesh.createGroupsFromMeshData<std::string>("physical_names").
\end{cpp}
Boundary conditions support can also be
created from the geometry by calling
\code{createBoundaryGroupFromGeometry}. This function gathers all the
elements on the boundary of the geometry.
To apply the required boundary conditions, the function \code{applyBC}
needs to be called on a \code{SolidMechanicsModel}. This function
gets a Dirichlet or Neumann functor and a string which specifies the
desired boundary on which the boundary conditions is to be
applied. The functors specify the type of conditions to apply. Three
built-in functors for Dirichlet exist: \code{FlagOnly, FixedValue,}
and \code{IncrementValue}. The functor \code{FlagOnly} is used if a
point is fixed in a given direction. Therefore, the input parameter to
this functor is only the fixed direction. The \code{FixedValue}
functor is used when a displacement value is applied in a fixed
direction. The \code{IncrementValue} applies an increment to the
displacement in a given direction. The following code shows the
utilization of three functors for the top, bottom and side surface of
the mesh which were already defined in the Gmsh file:
\begin{cpp}
model.applyBC(BC::Dirichlet::FixedValue(13.0, _y), "Top");
model.applyBC(BC::Dirichlet::FlagOnly(_x), "Bottom");
model.applyBC(BC::Dirichlet::IncrementValue(13.0, _x), "Side");
\end{cpp}
To apply a Neumann boundary condition, the applied traction or stress
should be specified before. In case of specifying the traction on the
surface, the functor \code{FromTraction} of Neumann boundary
conditions is called. Otherwise, the functor \code{FromStress} should
be called which gets the stress tensor as an input parameter.
\begin{cpp}
Array<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::Neumann::FromTraction(surface_traction), "Bottom");
model.applyBC(BC::Neumann::FromStress(surface_stress), "Top");
\end{cpp}
If the boundary conditions need to be removed during the simulation, a
functor is called from the Neumann boundary condition to free those
boundary conditions from the desired boundary.
\begin{cpp}
model.applyBC(BC::Neumann::FreeBoundary(), "Side");
\end{cpp}
User specified functors can also be implemented. A full example for
setting both initial and boundary conditions can be found in
\shellcode{\examplesdir/boundary\_conditions.cc}. The problem solved
in this example is shown in Fig.~\ref{fig:smm:bc_and_ic}. It consists
of a plate that is fixed with movable supports on the left and bottom
side. On the right side, a traction, which increases linearly with the
number of time steps, is applied. The initial displacement and
velocity in $x$-direction at all free nodes is zero and two
respectively.
\begin{figure}[!htb]
\centering
\includegraphics[scale=0.8]{figures/bc_and_ic_example}
\caption{Plate on movable supports.\label{fig:smm:bc_and_ic}}
\end{figure}
As it is mentioned in Section \ref{sect:common:groups}, node and
element groups can be used to assign the boundary conditions. A
generic example is given below with a Dirichlet boundary condition.
\begin{cpp}
// create a node group
NodeGroup & node_group = mesh.createNodeGroup("nodes_fix");
/*
fill the node group with the nodes you want
*/
// create an element group using the existing node group
mesh.createElementGroupFromNodeGroup("el_fix", "nodes_fix", spatial_dimension-1);
// boundary condition can be applied using the element group name
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "el_fix");
\end{cpp}
\subsection{Material Selector\label{sect:smm:materialselector}}
If the user wants to assign different materials to different
finite elements groups in \akantu, a material selector has to be
used. By default, \akantu assigns the first valid material in the
material file to all elements present in the model (regular continuum
materials are assigned to the regular elements and cohesive materials
are assigned to cohesive elements or element facets).
To assign different materials to specific elements, mesh data
information such as tag information or specified physical names can be
used. \code{MeshDataMaterialSelector} class uses this information to
assign different materials. With the proper physical name or tag name
and index, different materials can be assigned as demonstrated in the
examples below.
\begin{cpp}
MeshDataMaterialSelector<std::string> * mat_selector;
mat_selector = new MeshDataMaterialSelector<std::string>("physical_names", model);
model.setMaterialSelector(*mat_selector);
\end{cpp}
In this example the physical names specified in a GMSH geometry file will by
used to match the material names in the input file.
Another example would be to use the first (\code{tag\_0}) or the second
(\code{tag\_1}) tag associated to each elements in the mesh:
\begin{cpp}
MeshDataMaterialSelector<UInt> * mat_selector;
mat_selector = new MeshDataMaterialSelector<UInt>("tag_1", model, first_index);
model.setMaterialSelector(*mat_selector);
\end{cpp}
where \code{first\_index} (default is 1) is the value of \code{tag\_1} that will
be associated to the first material in the material input file. The following
values of the tag will be associated with the following materials.
There are four different material selectors pre-defined in
\akantu. \code{MaterialSelector} and \code{DefaultMaterialSelector} is
used to assign a material to regular elements by default. For the
regular elements, as in the example above,
\code{MeshDataMaterialSelector} can be used to assign different
materials to different elements.
Apart from the \akantu's default material selectors, users can always
develop their own classes in the main code to tackle various
multi-material assignment situations.
% An application of \code{DefaultMaterialCohesiveSelector} and usage in
% a customly generated material selector class can be seen in
% \shellcode{\examplesdir/cohesive\_element/cohesive\_extrinsic\_IG\_TG/cohesive\_extrinsic\_IG\_TG.cc}.
\IfFileExists{manual-cohesive_elements_insertion.tex}{\input{manual-cohesive_elements_insertion}}{}
\section{Static Analysis\label{sect:smm:static}}
The \code{SolidMechanicsModel} class can handle different analysis
methods, the first one being presented is the static case. In this
case, the equation to solve is
\begin{equation}
\label{eqn:smm:static} \mat{K} \vec{u} =
\vec{f}_{\st{ext}}
\end{equation}
where $\mat{K}$ is the global stiffness matrix, $\vec{u}$ the
displacement vector and $\vec{f}_{\st{ext}}$ the vector of external
forces applied to the system.
To solve such a problem, the static solver of the
\code{SolidMechanicsModel}\index{SolidMechanicsModel} object is used.
First, a model has to be created and initialized. To create the
model, a mesh (which can be read from a file) is needed, as explained
in Section~\ref{sect:common:mesh}. Once an instance of a
\code{SolidMechanicsModel} is obtained, the easiest way to initialize
it is to use the \code{initFull}\index{SolidMechanicsModel!initFull}
method by giving the \code{SolidMechanicsModelOptions}. These options
specify the type of analysis to be performed and whether the materials
should be initialized with \code{initMaterials} or not.
\begin{cpp}
SolidMechanicsModel model(mesh);
model.initFull(SolidMechanicsModelOptions(_static, false));
\end{cpp}
Here, a static analysis is chosen by passing the argument
\code{\_static} to the method. By default, the Boolean for no
initialization of the materials is set to false, so that they are
initialized during the \code{initFull}. The method \code{initFull}
also initializes all appropriate vectors to zero. Once the model is
created and initialized, the boundary conditions can be set as
explained in Section~\ref{sect:smm:boundary}. Boundary conditions
will prescribe the external forces for some free degrees of freedom
$\vec{f}_{\st{ext}}$ and displacements for some others. At this point
of the analysis, the function
\code{solveStep}\index{SolidMechanicsModel!solveStep} can be called:
\begin{cpp}
model.solveStep<_scm_newton_raphson_tangent_modified, _scc_residual>(1e-4, 1);
\end{cpp}
This function is templated by the solving method and the convergence
criterion and takes two arguments: the tolerance and the maximum
number of iterations (100 by default), which are $\num{1e-4}$ and $1$ for this example. The
modified Newton-Raphson method is chosen to solve the system. In this
method, the equilibrium equation (\ref{eqn:smm:static}) is modified in
order to apply a Newton-Raphson convergence algorithm:
\begin{align}\label{eqn:smm:static-newton-raphson}
\mat{K}^{i+1}\delta\vec{u}^{i+1} &= \vec{r} \\
&= \vec{f}_{\st{ext}} -\vec{f}_{\st{int}}\\
&= \vec{f}_{\st{ext}} - \mat{K}^{i} \vec{u}^{i}\\
\vec{u}^{i+1} &= \vec{u}^{i} + \delta\vec{u}^{i+1}~,\nonumber
\end{align}
where $\delta\vec{u}$ is the increment of displacement to be added
from one iteration to the other, and $i$ is the Newton-Raphson
iteration counter. By invoking the \code{solveStep} method in the
first step, the global stiffness matrix $\mat{K}$ from
Equation~(\ref{eqn:smm:static}) is automatically assembled. A
Newton-Raphson iteration is subsequently started, $\mat{K}$ is updated
according to the displacement computed at the previous iteration and
one loops until the forces are balanced (\code{\_scc\_residual}), \ie
$||\vec{r}|| < \mbox{\code{\_scc\_residual}}$. One can also iterate
until the increment of displacement is zero (\code{\_scc\_increment})
which also means that the equilibrium is found. For a linear elastic
problem, the solution is obtained in one iteration and therefore the
maximum number of iterations can be set to one. But for a non-linear
case, one needs to iterate as long as the norm of the residual exceeds
the tolerance threshold and therefore the maximum number of iterations
has to be higher, e.g. $100$:
\begin{cpp}
model.solveStep<_scm_newton_raphson_tangent_modified,_scc_residual>(1e-4, 100)
\end{cpp}
At the end of the analysis, the final solution is stored in the
\textbf{displacement} vector. A full example of how to solve a static
problem is presented in the code \code{\examplesdir/static/static.cc}.
This example is composed of a 2D plate of steel, blocked with rollers
on the left and bottom sides as shown in Figure \ref{fig:smm:static}.
The nodes from the right side of the sample are displaced by $0.01\%$
of the length of the plate.
\begin{figure}[!htb]
\centering
\includegraphics[scale=1.05]{figures/static}
\caption{Numerical setup\label{fig:smm:static}}
\end{figure}
The results of this analysis is depicted in
Figure~\ref{fig:smm:implicit:static_solution}.
\begin{figure}[!htb]
\centering
\includegraphics[width=.7\linewidth]{figures/static_analysis}
\caption{Solution of the static analysis. Left: the initial
condition, right: the solution (deformation magnified 50 times)}
\label{fig:smm:implicit:static_solution}
\end{figure}
+
+\subsection{Static implicit analysis with dynamic insertion of cohesive elements}
+In order to solve problems with the extrinsic cohesive method in the
+static implicit solution scheme, the function \code{solveStepCohesive}
+has to be used:
+\begin{cpp}
+model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(1e-13, error, 25, false, 1e5, true);
+\end{cpp}
+
+in which the arguments are: tolerance, error, max\_iteration,
+load\_reduction, tol\_increase\_factor, do\_not\_factorize. This
+function, first applies the Newton-Raphson procedure to solve the
+problem. Then, it calls the method \code{checkCohesiveStress} to
+check if cohesive elements have to be inserted. Since the approach is
+implicit, only one element is added, the most stressed one (see
+Section \ref{extrinsic_insertion}). After insertion, the
+Newton-Raphson procedure is applied again to solve the same
+incremental loading step, with the new inserted cohesive element. The
+procedure loops in this way since no new cohesive elements have to be
+inserted. At that point, the solution is saved, and the simulation
+can advance to the next incremental loading step. In case the
+convergence is not reached, the obtained solution is not saved and the
+simulation return to the main file with the error given by the
+solution saved in the argument of the function \emph{error}. In this
+way, the user can intervene in the simulation in order to find anyhow
+convergence. A possibility is, for instance, to reduce the last
+incremental loading step. The variable \emph{load\_reduction} can be
+used to identify if the load has been already reduced or not. At the
+same time, with the variable \emph{tol\_increase\_factor} it is
+possible to increase the tolerance by a factor defined by the user in
+the main file, in order to accept a solution even with an error bigger
+than the tolerance set at the beginning. It is possible to increase
+the tolerance only in the phase of loading reduction, i.e., when
+load\_reduction = true. A not converged solution is never saved. In
+case the convergence is not reached even after the loading reduction
+procedure, the displacement field is not updated and remains the one
+of the last converged incremental steps. Also, cohesive elements are
+inserted only if convergence is reached. An example of the extrinsic
+cohesive method in the static implicit solution scheme is presented in
+\shellcode{\examplesdir/cohesive\_element/cohesive\_extrinsic\_implicit}.
+
\section{Dynamic Methods} \label{sect:smm:Dynamic_methods}
Different ways to solve the equations of motion are implemented in the
solid mechanics model. The complete equations that should be solved
are:
\begin{equation}
\label{eqn:equation-motion}
\mat{M}\ddot{\vec{u}} +
\mat{C}\dot{\vec{u}} + \mat{K}\vec{u} = \vec{f}_{\st{ext}}~,
\end{equation}
where $\mat{M}$, $\mat{C}$ and $\mat{K}$ are the mass,
damping and stiffness matrices, respectively.
In the previous section, it has already been discussed how to solve this
equation in the static case, where $\ddot{\vec{u}} = \dot{\vec{u}} = 0$. Here
the method to solve this equation in the general case will be presented. For
this purpose, a time discretization has to be specified. The most common
discretization method in solid mechanics is the Newmark-$\beta$ method, which is
also the default in \akantu.
For the Newmark-$\beta$ method, (\ref{eqn:equation-motion}) becomes a
system of three equations (see \cite{curnier92a} \cite{hughes-83a} for
more details):
\begin{align}
\mat{M} \ddot{\vec{u}}_{n+1} + \mat{C}\dot{\vec{u}}_{n+1} + \mat{K} \vec{u}_{n+1} &={\vec{f}_{\st{ext}}}_{\, n+1}
\label{eqn:equation-motion-discret} \\
\vec{u}_{n+1} &=\vec{u}_{n} + \left(1 - \alpha\right) \Delta t \dot{\vec{u}}_{n} +
\alpha \Delta t \dot{\vec{u}}_{n+1} + \left(\frac{1}{2} -
\alpha\right) \Delta t^2
\ddot{\vec{u}}_{n} \label{eqn:finite-difference-1}\\
\dot{\vec{u}}_{n+1} &= \dot{\vec{u}}_{n} + \left(1 - \beta\right)
\Delta t \ddot{\vec{u}}_{n} + \beta \Delta t
\ddot{\vec{u}}_{n+1} \label{eqn:finite-difference-2}
\end{align}
In these new equations, $\ddot{\vec{u}}_{n}$, $\dot{\vec{u}}_{n}$ and
$\vec{u}_{n}$ are the approximations of $\ddot{\vec{u}}(t_n)$,
$\dot{\vec{u}}(t_n)$ and $\vec{u}(t_n)$.
Equation~(\ref{eqn:equation-motion-discret}) is the equation of motion
discretized in space (finite-element discretization), and equations
(\ref{eqn:finite-difference-1}) and (\ref{eqn:finite-difference-2})
are discretized in both space and time (Newmark discretization). The
$\alpha$ and $\beta$ parameters determine the stability and the
accuracy of the algorithm. Classical values for $\alpha$ and $\beta$
are usually $\beta = 1/2$ for no numerical damping and $0 < \alpha <
1/2$.
\begin{center}
\begin{tabular}{cll}
\toprule
$\alpha$ & Method ($\beta = 1/2$) & Type\\
\midrule
$0$ & central difference & explicit\\
$1/6$ & Fox-Goodwin (royal road) &implicit\\
$1/3$ & Linear acceleration &implicit\\
$1/2$ & Average acceleration (trapezoidal rule)& implicit\\
\bottomrule
\end{tabular}
\end{center}
The solution of this system of equations,
(\ref{eqn:equation-motion-discret})-(\ref{eqn:finite-difference-2}) is
split into a predictor and a corrector system of equations. Moreover,
in the case of a non-linear equations, an iterative algorithm such as
the Newton-Raphson method is applied. The system of equations can be
written as:
\begin{enumerate}
\item \textit{Predictor:}
\begin{align}
\vec{u}_{n+1}^{0} &= \vec{u}_{n} + \Delta t
\dot{\vec{u}}_{n} + \frac{\Delta t^2}{2} \ddot{\vec{u}}_{n} \\
\dot{\vec{u}}_{n+1}^{0} &= \dot{\vec{u}}_{n} + \Delta t
\ddot{\vec{u}}_{n} \\
\ddot{\vec{u}}_{n+1}^{0} &= \ddot{\vec{u}}_{n}
\end{align}
\item \textit{Solve:}
\begin{align}
\left(c \mat{M} + d \mat{C} + e \mat{K}_{n+1}^i\right)
\vec{w} = {\vec{f}_{\st{ext}}}_{\,n+1} - {\vec{f}_{\st{int}}}_{\,n+1}^i -
\mat{C} \dot{\vec{u}}_{n+1}^i - \mat{M} \ddot{\vec{u}}_{n+1}^i = \vec{r}_{n+1}^i
\end{align}
\item \textit{Corrector:}
\begin{align}
\ddot{\vec{u}}_{n+1}^{i+1} &= \ddot{\vec{u}}_{n+1}^{i} +c \vec{w} \\
\dot{\vec{u}}_{n+1}^{i+1} &= \dot{\vec{u}}_{n+1}^{i} + d\vec{w} \\
\vec{u}_{n+1}^{i+1} &= \vec{u}_{n+1}^{i} + e \vec{w}
\end{align}
\end{enumerate}
where $i$ is the Newton-Raphson iteration counter and $c$, $d$ and $e$
are parameters depending on the method used to solve the equations
\begin{center}
\begin{tabular}{lcccc}
\toprule
& $\vec{w}$ & $e$ & $d$ & $c$\\
\midrule
in acceleration &$ \delta\ddot{\vec{u}}$ & $\alpha \beta\Delta t^2$ &$\beta \Delta t$ &$1$\\
in velocity & $ \delta\dot{\vec{u}}$& $\frac{1}{\beta} \Delta t$ & $1$ & $\alpha\Delta t$\\
in displacement &$\delta\vec{u}$ & $ 1$ & $\frac{1}{\alpha} \Delta t$ & $\frac{1}{\alpha \beta} \Delta t^2$\\
\bottomrule
\end{tabular}
\end{center}
% \note{If you want to use the implicit solver \akantu should be compiled at
% least with one sparse matrix solver such as Mumps\cite{mumps}.}
\subsection{Implicit Time Integration}
To solve a problem with an implicit time integration scheme, first a
\code{SolidMechanicsModel} object has to be created and initialized.
Then the initial and boundary conditions have to be set. Everything
is similar to the example in the static case
(Section~\ref{sect:smm:static}), however, in this case the implicit
dynamic scheme is selected at the initialization of the model.
\begin{cpp}
SolidMechanicsModel model(mesh);
model.initFull(SolidMechanicsModelOptions(_implicit_dynamic));
/*Boundary conditions see Section~%\ref{sect:smm:boundary}% */
\end{cpp}
Because a dynamic simulation is conducted, an integration time step
$\Delta t$ has to be specified. In the case of implicit simulations,
\akantu implements a trapezoidal rule by default. That is to say
$\alpha = 1/2$ and $\beta = 1/2$ which is unconditionally
stable. Therefore the value of the time step can be chosen arbitrarily
within reason. \index{SolidMechanicsModel!setTimeStep}
\begin{cpp}
model.setTimeStep(time_step);
\end{cpp}
Since the system has to be solved for a given amount of time steps, the
method \code{solveStep()}, (which has already been used in the static
example in Section~\ref{sect:smm:static}), is called inside a time
loop:
\begin{cpp}
/// time loop
Real time = 0.;
for (UInt s = 1; time <max_time; ++s, time += time_step) {
model.solveStep<_scm_newton_raphson_tangent_modified,_scc_increment>(1e-12, 100);
}
\end{cpp}
An example of solid mechanics with an implicit time integration scheme
is presented in
\shellcode{\examplesdir/implicit/implicit\_dynamic.cc}. This example
consists of a 3D beam of
$\SI{10}{\metre}\,\times\,\SI{1}{\metre}\,\times\,\SI{1}{\metre}$
blocked on one side and is on a roller on the other side. A constant
force of \SI{5}{\kilo\newton} is applied in its middle.
Figure~\ref{fig:smm:implicit:dynamic} presents the geometry of this
case. The material used is a fictitious linear elastic material with a
density of \SI{1000}{\kilo\gram\per\cubic\metre}, a Young's Modulus of
\SI{120}{\mega\pascal} and Poisson's ratio of $0.3$. These values
were chosen to simplify the analytical solution.
An approximation of the dynamic response of the middle point of the
beam is given by:
\begin{equation}
\label{eqn:smm:implicit}
u\left(\frac{L}{2}, t\right)
= \frac{1}{\pi^4} \left(1 - cos\left(\pi^2 t\right) +
\frac{1}{81}\left(1 - cos\left(3^2 \pi^2 t\right)\right) +
\frac{1}{625}\left(1 - cos\left(5^2 \pi^2 t\right)\right)\right)
\end{equation}
\begin{figure}[!htb]
\centering
\includegraphics[scale=.6]{figures/implicit_dynamic}
\caption{Numerical setup}
\label{fig:smm:implicit:dynamic}
\end{figure}
Figure \ref{fig:smm:implicit:dynamic_solution} presents the deformed
beam at 3 different times during the simulation: time steps 0, 1000 and
2000.
\begin{figure}[!htb]
\centering
\setlength{\unitlength}{0.1\textwidth}
\begin{tikzpicture}
\node[above right] (img) at (0,0)
{\includegraphics[width=.6\linewidth]{figures/dynamic_analysis}};
\node[left] at (0pt,20pt) {$0$}; \node[left] at (0pt,60pt) {$1000$};
\node[left] at (0pt,100pt) {$2000$};
\end{tikzpicture}
\caption{Deformed beam at 3 different times (displacement are
magnified by a factor 10).}
\label{fig:smm:implicit:dynamic_solution}
\end{figure}
\subsection{Explicit Time Integration}
\label{ssect:smm:expl-time-integr}
The explicit dynamic time integration scheme is based on the
Newmark-$\beta$ scheme with $\alpha=0$ (see equations
\ref{eqn:equation-motion-discret}-\ref{eqn:finite-difference-2}). In
\akantu, $\beta$ is defaults to $\beta=1/2$, see section
\ref{sect:smm:Dynamic_methods}.
The initialization of the simulation is similar to the static and
implicit dynamic version. The model is created from the
\code{SolidMechanicsModel} class. In the initialization, the explicit
scheme is selected using the \code{\_explicit\_lumped\_mass} constant.
\begin{cpp}
SolidMechanicsModel model(mesh);
model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass));
\end{cpp}
\index{SolidMechanicsModel!initFull}
\note{Writing \code{model.initFull()} or \code{model.initFull(SolidMechanicsModelOptions());} is
equivalent to use the \code{\_explicit\_lumped\_mass} keyword, as this
is the default case.}
The explicit time integration scheme implemented in \akantu uses a
lumped mass matrix $\mat{M}$ (reducing the computational cost). This
matrix is assembled by distributing the mass of each element onto its
nodes. The resulting $\mat{M}$ is therefore a diagonal matrix stored
in the \textbf{mass} vector of the model.
The explicit integration scheme is conditionally stable. The time step
has to be smaller than the stable time step which is obtained in
\akantu as follows:
\begin{cpp}
critical_time_step = model.getStableTimeStep();
\end{cpp} \index{SolidMechanicsModel!StableTimeStep}
The stable time step corresponds to the time the fastest wave (the compressive
wave) needs to travel the characteristic length of the mesh:
\begin{equation}
\label{eqn:smm:explicit:stabletime}
\Delta t_{\st{crit}} = \frac{\Delta x}{c}
\end{equation}
where $\Delta x$ is a characteristic length (\eg the inradius in the case of
linear triangle element) and $c$ is the celerity of the fastest wave in the
material. It is generally the compressive wave of celerity
$c = \sqrt{\frac{2 \mu + \lambda}{\rho}}$, $\mu$ and $\lambda$ are the first and
second Lame's coefficients and $\rho$ is the density. However, it is recommended
to impose a time step that is smaller than the stable time step, for instance,
by multiplying the stable time step by a safety factor smaller than one.
\begin{cpp}
const Real safety_time_factor = 0.8;
Real applied_time_step = critical_time_step * safety_time_factor;
model.setTimeStep(applied_time_step);
\end{cpp}
\index{SolidMechanicsModel!setTimeStep} The initial displacement and
velocity fields are, by default, equal to zero if not given
specifically by the user (see \ref{sect:smm:initial_condition}).
Like in implicit dynamics, a time loop is used in which the
displacement, velocity and acceleration fields are updated at each
time step. The values of these fields are obtained from the
Newmark$-\beta$ equations with $\beta=1/2$ and $\alpha=0$. In \akantu
these computations at each time step are invoked by calling the
function \code{solveStep}:
\begin{cpp}
for (UInt s = 1; (s-1)*applied_time_step < total_time; ++s) {
model.solveStep();
}
\end{cpp} \index{SolidMechanicsModel!solveStep}
The method
\code{solveStep} wraps the four following functions:
\begin{itemize}
\item \code{model.explicitPred()} allows to compute the displacement
field at $t+1$ and a part of the velocity field at $t+1$, denoted by
$\vec{\dot{u}^{\st{p}}}_{n+1}$, which will be used later in the method
\code{model.explicitCorr()}. The equations are:
\begin{align}
\vec{u}_{n+1} &= \vec{u}_{n} + \Delta t
\vec{\dot{u}}_{n} + \frac{\Delta t^2}{2} \vec{\ddot{u}}_{n}\\
\vec{\dot{u}^{\st{p}}}_{n+1} &= \vec{\dot{u}}_{n} + \Delta t
\vec{\ddot{u}}_{n}
\label{eqn:smm:explicit:onehalfvelocity}
\end{align}
\item \code{model.updateResidual()} and
\code{model.updateAcceleration()} compute the acceleration increment
$\delta \vec{\ddot{u}}$:
\begin{equation}
\left(\mat{M} + \frac{1}{2} \Delta t \mat{C}\right)
\delta \vec{\ddot{u}} = \vec{f_{\st{ext}}} - \vec{f}_{\st{int}\, n+1}
- \mat{C} \vec{\dot{u}}_{n} - \mat{M} \vec{\ddot{u}}_{n}
\end{equation}
\note{The internal force $\vec{f}_{\st{int}\, n+1}$ is computed from
the displacement $\vec{u}_{n+1}$ based on the constitutive law.}
\item \code{model.explicitCorr()} computes the velocity and
acceleration fields at $t+1$:
\begin{align}
\vec{\dot{u}}_{n+1} &= \vec{\dot{u}^{\st{p}}}_{n+1} + \frac{\Delta t}{2}
\delta \vec{\ddot{u}} \\ \vec{\ddot{u}}_{n+1} &=
\vec{\ddot{u}}_{n} + \delta \vec{\ddot{u}}
\end{align}
\end{itemize}
The use of an explicit time integration scheme is illustrated by the
example:\par
\noindent \shellcode{\examplesdir/explicit/explicit\_dynamic.cc}\par
\noindent This example models the propagation of a wave in a steel beam. The
beam and the applied displacement in the $x$ direction are shown in
Figure~\ref{fig:smm:explicit}.
\begin{figure}[!htb] \centering
\begin{tikzpicture}
\coordinate (c) at (0,2);
\draw[shift={(c)},thick, color=blue] plot [id=x, domain=-5:5, samples=50] ({\x, {(40 * sin(0.1*pi*3*\x) * exp(- (0.1*pi*3*\x)*(0.1*pi*3*\x) / 4))}});
\draw[shift={(c)},-latex] (-6,0) -- (6,0) node[right, below] {$x$};
\draw[shift={(c)},-latex] (0,-0.7) -- (0,1) node[right] {$u$};
\draw[shift={(c)}] (-0.1,0.6) node[left] {$A$}-- (1.5,0.6);
\coordinate (l) at (0,0.6);
\draw[shift={(0,-0.7)}] (-5, 0) -- (5,0) -- (5, 1) -- (-5, 1) -- cycle;
\draw[shift={(l)}, latex-latex] (-5,0)-- (5,0) node [midway, above] {$L$};
\draw[shift={(l)}] (5,0.2)-- (5,-0.2);
\draw[shift={(l)}] (-5,0.2)-- (-5,-0.2);
\coordinate (h) at (5.3,-0.7);
\draw[shift={(h)}, latex-latex] (0,0)-- (0,1) node [midway, right] {$h$};
\draw[shift={(h)}] (-0.2,1)-- (0.2,1);
\draw[shift={(h)}] (-0.2,0)-- (0.2,0);
\end{tikzpicture}
\caption{Numerical setup \label{fig:smm:explicit}}
\end{figure}
The length and height of the beam are $L=\SI{10}{\metre}$ and
$h = \SI{1}{\metre}$, respectively. The material is linear elastic,
homogeneous and isotropic (density:
\SI{7800}{\kilo\gram\per\cubic\metre}, Young's modulus:
\SI{210}{\giga\pascal} and Poisson's ratio: $0.3$). The imposed
displacement follow a Gaussian function with a maximum amplitude of $A = \SI{0.01}{\meter}$. The
potential, kinetic and total energies are computed. The safety factor
is equal to $0.8$.
\input{manual-constitutive-laws}
\section{Adding a New Constitutive Law}\index{Material!create a new
material}
There are several constitutive laws in \akantu as described in the
previous Section~\ref{sect:smm:CL}. It is also possible to use a
user-defined material for the simulation. These materials are referred
to as local materials since they are local to the example of the user
and not part of the \akantu library. To define a new local material,
two files (\code {material\_XXX.hh} and \code{material\_XXX.cc}) have
to be provided where \code{XXX} is the name of the new material. The
header file \code {material\_XXX.hh} defines the interface of your
custom material. Its implementation is provided in the
\code{material\_XXX.cc}. The new law must inherit from the
\code{Material} class or any other existing material class. It is
therefore necessary to include the interface of the parent material
in the header file of your local material and indicate the inheritance
in the declaration of the class:
\begin{cpp}
/* ---------------------------------------------------------------------- */
#include "material.hh"
/* ---------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_XXX_HH__
#define __AKANTU_MATERIAL_XXX_HH__
__BEGIN_AKANTU__
class MaterialXXX : public Material {
/// declare here the interface of your material
};
\end{cpp}
In the header file the user also needs to declare all the members of the new
material. These include the parameters that a read from the
material input file, as well as any other material parameters that will be
computed during the simulation and internal variables.
In the following the example of adding a new damage material will be
presented. In this case the parameters in the material will consist of the
Young's modulus, the Poisson coefficient, the resistance to damage and the
damage threshold. The material will then from these values compute its Lam\'{e}
coefficients and its bulk modulus. Furthermore, the user has to add a new
internal variable \code{damage} in order to store the amount of damage at each
quadrature point in each step of the simulation. For this specific material the
member declaration inside the class will look as follows:
\begin{cpp}
class LocalMaterialDamage : public Material {
/// declare constructors/destructors here
/// declare methods and accessors here
/* -------------------------------------------------------------------- */
/* Class Members */
/* -------------------------------------------------------------------- */
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real);
private:
/// the young modulus
Real E;
/// Poisson coefficient
Real nu;
/// First Lame coefficient
Real lambda;
/// Second Lame coefficient (shear modulus)
Real mu;
/// resistance to damage
Real Yd;
/// damage threshold
Real Sd;
/// Bulk modulus
Real kpa;
/// damage internal variable
InternalField<Real> damage;
};
\end{cpp}
In order to enable to print the material parameters at any point in
the user's example file using the standard output stream by typing:
\begin{cpp}
for (UInt m = 0; m < model.getNbMaterials(); ++m)
std::cout << model.getMaterial(m) << std::endl;
\end{cpp}
the standard output stream operator has to be redefined. This should be done at the end of the header file:
\begin{cpp}
class LocalMaterialDamage : public Material {
/// declare here the interace of your material
}:
/* ---------------------------------------------------------------------- */
/* inline functions */
/* ---------------------------------------------------------------------- */
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const LocalMaterialDamage & _this)
{
_this.printself(stream);
return stream;
}
\end{cpp}
However, the user still needs to register the material parameters that
should be printed out. The registration is done during the call of the
constructor. Like all definitions the implementation of the
constructor has to be written in the \code{material\_XXX.cc}
file. However, the declaration has to be provided in the
\code{material\_XXX.hh} file:
\begin{cpp}
class LocalMaterialDamage : public Material {
/* -------------------------------------------------------------------- */
/* Constructors/Destructors */
/* -------------------------------------------------------------------- */
public:
LocalMaterialDamage(SolidMechanicsModel & model, const ID & id = "");
};
\end{cpp}
The user can now define the implementation of the constructor in the
\code{material\_XXX.cc} file:
\begin{cpp}
/* ---------------------------------------------------------------------- */
#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 Lame coefficient");
this->registerParam("mu", mu, _pat_readable, "Second Lame 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();
}
\end{cpp}
During the intializer list the reference to the model and the material id are
assigned and the constructor of the internal field is called. Inside the scope
of the constructor the internal values have to be initialized and the
parameters, that should be printed out, are registered with the function:
\code{registerParam}\index{Material!registerParam}:
\begin{cpp}
void registerParam(name of the parameter (key in the material file),
member variable,
default value (optional parameter),
access permissions,
description);
\end{cpp}
The available access permissions are as follows:
\begin{itemize}
\item \code{\_pat\_internal}: Parameter can only be output when the material is printed.
\item \code{\_pat\_writable}: User can write into the parameter. The parameter is output when the material is printed.
\item \code{\_pat\_readable}: User can read the parameter. The parameter is output when the material is printed.
\item \code{\_pat\_modifiable}: Parameter is writable and readable.
\item \code{\_pat\_parsable}: Parameter can be parsed, \textit{i.e.} read from the input file.
\item \code{\_pat\_parsmod}: Parameter is modifiable and parsable.
\end{itemize}
In order to implement the new constitutive law the user needs to
specify how the additional material parameters, that are not
defined in the input material file, should be calculated. Furthermore,
it has to be defined how stresses and the stable time step should be
computed for the new local material. In the case of implicit
simulations, in addition, the computation of the tangent stiffness needs
to be defined. Therefore, the user needs to redefine the following
functions of the parent material:
\begin{cpp}
void initMaterial();
// for explicit and implicit simulations void
computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
// for implicit simulations
void computeTangentStiffness(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost);
// for explicit and implicit simulations
Real getStableTimeStep(Real h, const Element & element);
\end{cpp}
In the following a detailed description of these functions is provided:
\begin{itemize}
\item \code{initMaterial}:~ This method is called after the material
file is fully read and the elements corresponding to each material
are assigned. Some of the frequently used constant parameters are
calculated in this method. For example, the Lam\'{e} constants of
elastic materials can be considered as such parameters.
\item \code{computeStress}:~ In this method, the stresses are
computed based on the constitutive law as a function of the strains of the
quadrature points. For example, the stresses for the elastic
material are calculated based on the following formula:
\begin{equation}
\label{eqn:smm:constitutive_elastic}
\mat{\sigma } =\lambda\mathrm{tr}(\mat{\varepsilon})\mat{I}+2 \mu \mat{\varepsilon}
\end{equation}
Therefore, this method contains a loop on all quadrature points
assigned to the material using the two macros:\par
\code{MATERIAL\_STRESS\_QUADRATURE\_POINT\_LOOP\_BEGIN}\par
\code{MATERIAL\_STRESS\_QUADRATURE\_POINT\_LOOP\_END}
\begin{cpp}
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(element_type);
// sigma <- f(grad_u)
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
\end{cpp}
\note{The strain vector in \akantu contains the values of $\nabla
\vec{u}$, i.e. it is really the \emph{displacement gradient},}
\item \code{computeTangentStiffness}:~ This method is called when
the tangent to the stress-strain curve is desired (see Fig \ref
{fig:smm:AL:K}). For example, it is called in the implicit solver
when the stiffness matrix for the regular elements is assembled
based on the following formula:
\begin{equation}
\label{eqn:smm:constitutive_elasc} \mat{K }
=\int{\mat{B^T}\mat{D(\varepsilon)}\mat{B}}
\end{equation}
Therefore, in this method, the \code{tangent} matrix (\mat{D}) is
computed for a given strain.
\note{ The \code{tangent} matrix is a $4^{th}$ order tensor which is
stored as a matrix in Voigt notation.}
\begin{figure}[!htb]
\begin{center}
\includegraphics[width=0.4\textwidth,keepaspectratio=true]{figures/tangent.pdf}
\caption{Tangent to the stress-strain curve.}
\label{fig:smm:AL:K}
\end{center}
\end{figure}
\item \code{getCelerity}:~The stability criterion of the explicit integration scheme depend on the fastest wave celerity~\eqref{eqn:smm:explicit:stabletime}. This celerity depend on the material, and therefore the value of this velocity should be defined in this method for each new material. By default, the fastest wave speed is the compressive wave whose celerity can be defined in~\code{getPushWaveSpeed}.
\end{itemize}
Once the declaration and implementation of the new material has been
completed, this material can be used in the user's example by including the header file:
\begin{cpp}
#include "material_XXX.hh"
\end{cpp}
For existing materials, as mentioned in Section~\ref{sect:smm:CL}, by
default, the materials are initialized inside the method
\code{initFull}. If a local material should be used instead, the
initialization of the material has to be postponed until the local
material is registered in the model. Therefore, the model is
initialized with the boolean for skipping the material initialization
equal to true:
\begin{cpp}
/// model initialization
model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass,true));
\end{cpp}
Once the model has been initialized, the local material needs
to be registered in the model:
\begin{cpp}
model.registerNewCustomMaterials<XXX>("name_of_local_material");
\end{cpp}
Only at this point the material can be initialized:
\begin{cpp}
model.initMaterials();
\end{cpp}
A full example for adding a new damage law can be found in
\shellcode{\examplesdir/new\_material}.
\subsection{Adding a New Non-Local Constitutive Law}\index{Material!create a new non-local material}
In order to add a new non-local material we first have to add the local constitutive law in \akantu (see above). We can then add the non-local version of the constitutive law by adding the two files (\code{material\_XXX\_non\_local.hh} and \code{material\_XXX\_non\_local.cc}) where \code{XXX} is the name of the corresponding local material. The new law must inherit from the two classes, non-local parent class, such as the \code{MaterialNonLocal} class, and from the local version of the constitutive law, \textit{i.e.} \code{MaterialXXX}. It is therefore necessary to include the interface of those classes in the header file of your custom material and indicate the inheritance in the declaration of the class:
\begin{cpp}
/* ---------------------------------------------------------------------- */
#include "material_non_local.hh" // the non-local parent
#include "material_XXX.hh"
/* ---------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_XXX_HH__
#define __AKANTU_MATERIAL_XXX_HH__
__BEGIN_AKANTU__
class MaterialXXXNonLocal : public MaterialXXX,
public MaterialNonLocal {
/// declare here the interface of your material
};
\end{cpp}
As members of the class we only need to add the internal fields to store the non-local quantities, which are obtained from the averaging process:
\begin{cpp}
/* -------------------------------------------------------------------------- */
/* Class members */
/* -------------------------------------------------------------------------- *
protected:
InternalField<Real> grad_u_nl;
\end{cpp}
The following four functions need to be implemented in the non-local material:
\begin{cpp}
/// initialization of the material
void initMaterial();
/// loop over all element and invoke stress computation
virtual void computeNonLocalStresses(GhostType ghost_type);
/// compute stresses after local quantities have been averaged
virtual void computeNonLocalStress(ElementType el_type, GhostType ghost_type)
/// compute all local quantities
void computeStress(ElementType el_type, GhostType ghost_type);
\end{cpp}
In the intialization of the non-local material we need to register the local quantity for the averaging process. In our example the internal field \emph{grad\_u\_nl} is the non-local counterpart of the gradient of the displacement field (\emph{grad\_u\_nl}):
\begin{cpp}
void MaterialXXXNonLocal::initMaterial() {
MaterialXXX::initMaterial();
MaterialNonLocal::initMaterial();
/// register the non-local variable in the manager
this->model->getNonLocalManager().registerNonLocalVariable(this->grad_u.getName(), this->grad_u_nl.getName(), spatial_dimension * spatial_dimension);
}
\end{cpp}
The function to register the non-local variable takes as parameters the name of the local internal field, the name of the non-local counterpart and the number of components of the field we want to average.
In the \emph{computeStress} we now need to compute all the quantities we want to average. We can then write a loop for the stress computation in the function \emph{computeNonLocalStresses} and then provide the constitutive law on each integration point in the function \emph{computeNonLocalStress}.
%%% Local Variables: %%% mode: latex %%% TeX-master: "manual" %%% End:
diff --git a/doc/manual/manual.sty b/doc/manual/manual.sty
index 3e4be3cfd..690c3205b 100644
--- a/doc/manual/manual.sty
+++ b/doc/manual/manual.sty
@@ -1,372 +1,394 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
%% LaTeX STYLE SHEET for AKANTU DOCUMENTATION %%
%% %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Geometry
\usepackage{a4wide}
\usepackage{geometry}
\geometry{
pdftex=true,
twoside=true,
margin=20mm,
bottom=20mm,
top=20mm,
bindingoffset=5.5mm
}
% Font encoding
\usepackage[T1]{fontenc}
\usepackage{palatino}
% Line spacing
\linespread{1.05}\selectfont
% Allow spaces to be added at the end of macro
\usepackage{xspace}
% Mathematics (including correct font encoding, after amsmath)
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{pxfonts}
\setlength\mathindent{2em}
% Some unit stuff
\usepackage{siunitx}
% Easy tables
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{rotating} % For sideways tables
\usepackage{multirow} % For larger cells
% A special environment for element tables
\newcommand\elemline{}%{\noalign{\smallskip}\hline\noalign{\smallskip}}
\newcommand\elemcooroned{\ensuremath{\left(\xi\right)}}
\newcommand\elemcoortwod{\ensuremath{\left(\xi\;,\;\eta\right)}}
\newcommand\elemcoorthreed{\ensuremath{\left(\xi\;,\;\eta\;,\;\zeta\right)}}
\newcommand\elemdshapeoned{\ensuremath{\left(\partial N_i/\partial\xi\right)}}
\newcommand\elemdshapetwod{\ensuremath{\left(\partial N_i/\partial\xi\;,\;\partial N_i/\partial\eta\right)}}
\newcommand\elemdshapethreed{\ensuremath{\left(\partial N_i/\partial\xi\;,\;\partial N_i/\partial\eta\;,\;\partial N_i/\partial\zeta\right)}}
\newcommand\inelemone[1]{\ensuremath{#1}}
%\newcommand\inelemtwo[2]{\ensuremath{\begin{pmatrix} {\; #1} & \!,\! & {#2 \;} \end{pmatrix}}}
%\newcommand\inelemthree[3]{\ensuremath{\begin{pmatrix} {\; #1} & \!,\! & {#2} & \!,\! & {#3 \;} \end{pmatrix}}}
\newcommand\inelemtwo[2]{\ensuremath{\left( {\; #1} \; , \; {#2 \;} \right)}}
\newcommand\inelemthree[3]{\ensuremath{\left( {\; #1} \; , \; {#2} \; , \; {#3 \;} \right)}}
\newcommand\inelemthreecolumn[3]{\ensuremath{\begin{array}{c}( {\; #1} \; ,\\{#2} \; ,\\{#3 \;} )\end{array}}}
\newcommand\inquadone[1]{\ensuremath{#1}}
\newcommand\inquadtwo[2]{\ensuremath{\left(\, #1 \, , \, #2 \,\right)}}
\newcommand\inquadthree[3]{\ensuremath{\left(\, #1 \, , \, #2 \, , \, #3 \,\right)}}
%\newcommand\quada{\tfrac{1}{20}\left(5-\sqrt{5}\right)}
%\newcommand\quadb{\tfrac{1}{20}\left(5+3\sqrt{5}\right)}
\newcommand\quada{\tfrac{\left(5-\sqrt{5}\right)}{20}}
\newcommand\quadb{\tfrac{\left(5+3\sqrt{5}\right)}{20}}
\newenvironment{Element}[1]
{%\begin{table*}[!htbp]
\footnotesize
\ifthenelse{\equal{#1}{1D}}{\renewcommand{\arraystretch}{1.50}}{}
\ifthenelse{\equal{#1}{2D}}{\renewcommand{\arraystretch}{1.60}}{}
\ifthenelse{\equal{#1}{3D}}{\renewcommand{\arraystretch}{1.70}}{}
\textbf{{\normalsize Element properties}}\\%\vspace*{0.5\baselineskip}
\begin{tabular}{cccc}\\[-2ex]
\toprule
% \multicolumn{4}{l}{\textbf{{\normalsize Element properties}}} \\
Node ($i$) & Coord.
\ifthenelse{\equal{#1}{1D}}{\elemcooroned}{}
\ifthenelse{\equal{#1}{2D}}{\elemcoortwod}{}
\ifthenelse{\equal{#1}{3D}}{\elemcoorthreed}{}
& Shape function ($N_{i}$)
& {Derivative
\ifthenelse{\equal{#1}{1D}}{\elemdshapeoned}{}
\ifthenelse{\equal{#1}{2D}}{\elemdshapetwod}{}
\ifthenelse{\equal{#1}{3D}}{\elemdshapethreed}{}
}\\
\midrule
\elemline
}
{\bottomrule
\end{tabular}%\end{table*}
}
\newenvironment{Element_part1}[1]
{%\begin{table*}[!htbp]
\footnotesize
\ifthenelse{\equal{#1}{1D}}{\renewcommand{\arraystretch}{1.50}}{}
\ifthenelse{\equal{#1}{2D}}{\renewcommand{\arraystretch}{1.60}}{}
\ifthenelse{\equal{#1}{3D}}{\renewcommand{\arraystretch}{1.70}}{}
\textbf{{\normalsize Element properties}}\\%\vspace*{0.5\baselineskip}
\begin{tabular}{ccc}\\[-2ex]
\toprule
% \multicolumn{4}{l}{\textbf{{\normalsize Element properties}}} \\
Node ($i$) & Coord.
\ifthenelse{\equal{#1}{1D}}{\elemcooroned}{}
\ifthenelse{\equal{#1}{2D}}{\elemcoortwod}{}
\ifthenelse{\equal{#1}{3D}}{\elemcoorthreed}{}
& Shape function ($N_{i}$)\\
\midrule
\elemline
}
{\bottomrule\end{tabular}}%\end{table*}}
\newenvironment{Element_part2}[1]
{%\begin{table*}[!htbp]
\footnotesize
\ifthenelse{\equal{#1}{1D}}{\renewcommand{\arraystretch}{1.50}}{}
\ifthenelse{\equal{#1}{2D}}{\renewcommand{\arraystretch}{1.60}}{}
\ifthenelse{\equal{#1}{3D}}{\renewcommand{\arraystretch}{1.70}}{}
\textbf{{\normalsize Element properties}}\\%\vspace*{0.5\baselineskip}
\begin{tabular}{cccc}\\[-2ex]
\toprule
% \multicolumn{4}{l}{\textbf{{\normalsize Element properties}}} \\
Node ($i$)
& {Derivative
\ifthenelse{\equal{#1}{1D}}{\elemdshapeoned}{}
\ifthenelse{\equal{#1}{2D}}{\elemdshapetwod}{}
\ifthenelse{\equal{#1}{3D}}{\elemdshapethreed}{}
}\\
\midrule
\elemline
}
{\bottomrule
\end{tabular}%\end{table*}
}
\newenvironment{QuadPoints}[1]
{\vspace*{\baselineskip}
%\begin{table*}[!htbp]
\footnotesize
\renewcommand{\arraystretch}{1.50}
\noindent\textbf{{\normalsize Gaussian quadrature points}}\newline%\vspace*{0.5\baselineskip}
\begin{tabular}{#1}\\[-2ex]
\toprule
}
{\bottomrule\end{tabular}}%\end{table*}}
%\usepackage{xparse}
\newenvironment{MaterialDesc}[2]{
\label{#2-app}
Keyword: \code{#1}\par
\noindent Description here: \ref{#2}\par
\noindent Parameters:\par
\vspace*{-.4cm}
\begin{itemize}
\setlength{\topsep}{0ex}%
\setlength{\parsep}{0cm}%
\setlength{\itemsep}{0cm}%
\setlength{\parskip}{0cm}%
}{\end{itemize}}
\newcommand{\matparam}[3]{\item \code{#1}: (\emph{#2}) #3}
\newcommand{\matinherit}[1]{\usebox{#1}}
\newcommand{\matlabel}[1]{\label{#1}\xspace(\ref{#1-app})}
% Nice coloring
\usepackage[dvipsnames,usenames,table]{xcolor}
\definecolor{RED}{rgb}{1,0,0}
\definecolor{cppbg}{HTML}{EBF2F2}
\definecolor{shellbg}{HTML}{F5EDE4}
\definecolor{cmakebg}{HTML}{F5EDE4}
\definecolor{commentcolor}{HTML}{101280}
% Allow for the use of listings
\usepackage{listings}
% Create an index
\usepackage{makeidx}
% Figure handling
\usepackage{graphics}
\usepackage{epsfig}
\usepackage[lofdepth,lotdepth]{subfig}
\usepackage{tikz}
\usetikzlibrary{decorations}
\usepackage{wrapfig}
\renewcommand{\floatpagefraction}{.6} % default: .5
\renewcommand\topfraction{0.9} % 90% of page top can be a float (Standard 0.7)
\renewcommand\bottomfraction{0.1} % 10% of page bottom can be a float (Standard 0.3)
\renewcommand\textfraction{0.1} % only 10% of page must to be text (Standard 0.2)
% Removes parenthese around subfig number
\renewcommand*{\thesubfigure}{\alph{subfigure}}
% Create new list style for cmake files
\lstdefinelanguage{cmake}{
morekeywords={project, cmake\_minimum\_required, enable\_language, message,
add\_executable, add\_library, target\_link\_libraries, include\_directories,
find\_package, find\_path, find\_library, include, mark\_as\_advanced,
find\_package\_handle\_standard\_args,
package\_declare, package\_declare\_documentation},
morecomment=[l]{\#},
sensitive=false,
morestring=[b]",
}
\lstdefinestyle{lstDefaultStyle} {
basicstyle=\small\ttfamily, % Without beramono, we'd get cmtt, the teletype font.
commentstyle=\color{commentcolor}\itshape,
% fontadjust,
% numbers=left, % where to put the line-numbers
% numberstyle=\tiny, % the size of the fonts that are used for the line-numbers
% stepnumber=2, % the step between two line-numbers. If it's 1, each line will
% be numbered
% numbersep=5pt, % how far the line-numbers are from the code
% showspaces=false, % show spaces adding particular underscores
showstringspaces=false, % underline spaces within strings
% showtabs=false, % show tabs within strings adding particular underscores
% frame=llines, % adds a frame around the code
% frame=tb,
tabsize=2, % sets default tabsize to 2 spaces
captionpos=b, % sets the caption-position to bottom
breaklines=true, % sets automatic line breaking
breakatwhitespace=false, % sets if automatic breaks should only happen at
% whitespace
% title=\lstname, % show the filename of files included with \lstinputlisting;
% also try caption instead of title
% escapeinside={\%*}{*)}, % if you want to add a comment within your code
xleftmargin=1cm,
xrightmargin=1cm,
escapechar=\%,
columns=flexible,
keepspaces=true,
mathescape=false
}
% Create a new list style for C++
\lstdefinestyle{C++}{
language=C++, % the language of the code
style=lstDefaultStyle,
keywordstyle=\color{DarkOrchid}\bfseries,
mathescape=true,
morekeywords={Real, UInt, Int},
backgroundcolor=\color{cppbg}
}
+% Create a new list style for python
+\lstdefinestyle{python}{
+ language=python, % the language of the code
+ basicstyle=\small\ttfamily, % Without beramono, we'd get cmtt, the teletype font.
+ commentstyle=\color{commentcolor}\itshape,
+ keywordstyle=\color{DarkOrchid}\bfseries,
+ showstringspaces=false, % underline spaces within strings
+ tabsize=2, % sets default tabsize to 2 spaces
+ captionpos=b, % sets the caption-position to bottom
+ breaklines=true, % sets automatic line breaking
+ breakatwhitespace=false, % sets if automatic breaks should only happen at
+ xleftmargin=1cm,
+ xrightmargin=1cm,
+ mathescape=true,
+ escapechar=\%,
+ morekeywords={Real, UInt, Int},
+ columns=flexible,
+ keepspaces=true,
+ backgroundcolor=\color{cppbg}
+}
+
% Create new list style for the shell
\lstdefinestyle{shell}{
language=bash, % the language of the code
style=lstDefaultStyle,
morekeywords={mkdir, make, ccmake, cmake},
backgroundcolor=\color{shellbg}
}
\lstdefinestyle{mycmake}{
language=cmake, % the language of the code
style=lstDefaultStyle,
keywordstyle=\color{RoyalBlue}\bfseries,
stringstyle=\color{Bittersweet}, %
backgroundcolor=\color{cmakebg}
}
% Set some derived listing environments
\lstnewenvironment{cpp}{\lstset{style=C++}}{}
+\lstnewenvironment{python}{\lstset{style=python}}{}
\lstnewenvironment{command}{\lstset{style=shell}}{}
\lstnewenvironment{cmake}{\lstset{style=mycmake}}{}
% Make sure outputspace is white
\makeatletter
\def\lst@outputspace{{\ifx\lst@bkgcolor\empty\color{white}\else\lst@bkgcolor\fi\lst@visiblespace}}
\makeatother
% Renow a label in the itemized lists
\renewcommand{\labelitemi}{$\mathbf{\circ}$}
% Don't care so much about overfull h-boxes
\sloppy
% Penalty adjusments
%\widowpenalty=10000 % Single lines/word on beginning of page
%\clubpenalty=10000 % Single lines/word at end of page
%\hyphenpenalty=2000 % Hyphenate words
%\tolerance=250 % To adjust the hyphenation of words, increase the tolerance to discourage hyphenation
% the higher the value, the more ugly the gaps between words
% default \tolerance=200
%\hfuzz=10000pt % threshold when an overfull hbox is reported, default \hfuzz=0.1pt
%\vfuzz=10000pt % threshold to report an overfull vbox, default \vfuzz=0.1pt
%\hbadness=10000 % threshold to report an underfull \hbox
%\vbadness=10000 % threshold to report an underfull \vbox protokolliert wird.
\emergencystretch=0pt % causes a third attempt to fix bad paragraphs and defines a maximum limit to stretch them
% Insert an empty or a blank page
\newcommand{\insertemptypage}{\newpage\hbox{}\newpage}
\newcommand{\insertblankpage}{\newpage\thispagestyle{empty}\hbox{}\newpage}
% No page number on an empty page
\let\origdoublepage\cleardoublepage
\newcommand{\clearemptydoublepage}{%
\clearpage
{\thispagestyle{empty}\origdoublepage}%
}
\let\cleardoublepage\clearemptydoublepage
% A new ruler for in chapters
\newcommand\InChapterRule{\addvspace{\baselineskip}\rule{0.3\linewidth}{0.25pt}}
% New footnote style
%\def\@fnsymbol#1{\ifcase#1\or *\or \dagger\or \ddagger\or \mathchar "278\or \mathchar "27B\or \|\or **\or \dagger\dagger \or \ddagger\ddagger \else\@ctrerr\fi\relax}
\def\@fnsymbol#1{*\xspace\relax}
\renewcommand{\thefootnote}{\fnsymbol{footnote}} % Symbols rather than numbers
\def\footnoterule{\vspace*{0.5\baselineskip}\InChapterRule\vspace*{0.25\baselineskip}}
% Improved look of the Table of Contents
\usepackage[nottoc,notbib]{tocbibind}
\usepackage[dotinlabels]{titletoc}
\titlecontents{chapter}[1.4pc]
{\addvspace{0.6pc}\large\bfseries\filright}
{\contentslabel[\thecontentslabel.]{1.4pc}}
{\hspace{-1.4pc}}
{\hfill\contentspage}
[\addvspace{2pt}]
\titlecontents{section}[3.4pc]
{\filright}
{\contentslabel[\thecontentslabel]{2pc}}
{\hspace{-2pc}}
{\titlerule*[6pt]{.}\contentspage}
[]
\titlecontents{subsection}[5.0pc]
{\filright}
{\contentslabel[\thecontentslabel]{2.4pc}}
{}
{\titlerule*[6pt]{.}\contentspage}
[]
\setcounter{tocdepth}{2}
\newcommand\addspaceintoc{\addtocontents{toc}{\protect\addvspace{20pt}}}
% Change the appearance of the bibliography
\bibliographystyle{manual-bibliographystyle}
\renewcommand\bibname{References}
\usepackage{cite} % To sort citations: [2,10-14]
\let\oldthebibliography=\thebibliography
\let\endoldthebibliography=\endthebibliography
\renewenvironment{thebibliography}[1]
{ \begin{oldthebibliography}{#1}
% \small
\addcontentsline{toc}{chapter}{\bibname}
\setlength{\labelsep}{2mm}
\setlength{\parskip}{0\baselineskip}
\setlength{\itemsep}{0.24\baselineskip}
}
{ \end{oldthebibliography} }
% Hyperref
\usepackage{url}
\usepackage[pdftex,
bookmarks=true,
bookmarksnumbered=true,
% linkbordercolor={1 1 1},
% pdfborder={0 0 0},
pdfpagemode=UseOutlines
]{hyperref}
\hypersetup{
pdfauthor={Computational Solid Mechanics Laboratory - EPFL},
pdftitle={Akantu User's Guide},
pdfsubject={Open Source Finite Element Code - Akantu}
}
\newenvironment{AkantuPackage}[2]{%
\paragraph*{#1}\label{#2}
}{}
\newenvironment{AkantuPackageDependencies}{\emph{Dependencies}: }{}
\newcommand\AkantuPackageNameWithLabel[3]{\textit{\index{Packages!#1}\hyperref[#2]{#1}}\xspace}
-\newcommand\akantuManualAppendix[1]{}
\ No newline at end of file
+\newcommand\akantuManualAppendix[1]{}
diff --git a/doc/manual/manual.tex b/doc/manual/manual.tex
index 956881ab4..efe9cab1e 100644
--- a/doc/manual/manual.tex
+++ b/doc/manual/manual.tex
@@ -1,52 +1,54 @@
\documentclass[openright,a4paper,11pt,fleqn]{manual}
\usepackage{manual}
\usepackage{manual-macros}
\IfFileExists{version-definition.tex}{
\input{version-definition}
}{
\newcommand{\version}{2.2}
}
\graphicspath{ {./figures/} }
%%% For references \todo check the coherency
%% section 3.5 -> Section 3.5
%% figure 3.5 -> Figure 3.5
%% equation 3.5 -> Equation (3.5)
% Title pages and Table of Contents (includes \begin{document})
\input{manual-titlepages}
% Introduction chapter
\input{manual-introduction}
% The planning to write the documentation
%\input{manual-planning}
% The documentation chapter (split in parts)
\input{manual-gettingstarted}
\input{manual-feengine}
%\IfFileExists{manual-lumping.tex}{}{\input{manual-lumping}}
\input{manual-solidmechanicsmodel}
\IfFileExists{manual-structuralmechanicsmodel.tex}{\input{manual-structuralmechanicsmodel}}{}
\IfFileExists{manual-heattransfermodel.tex}{\input{manual-heattransfermodel}}{}
\input{manual-io}
\IfFileExists{manual-parallel.tex}{\input{manual-parallel}}{}
\IfFileExists{manual-contact.tex}{\input{manual-contact}}{}
+\IfFileExists{manual-python.tex}{\input{manual-python}}{}
+
% The appendices
\appendix
\input{manual-appendix-elements}
\input{manual-appendix-materials}
\input{manual-appendix-packages}
% The backmatter material (index/bibliography, included \end{document})
\input{manual-backmatter}
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index b6a1e7ac7..2aa9a3139 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,53 +1,52 @@
#===============================================================================
# @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: Fri Jan 22 2016
#
# @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(parallel "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)
-#===============================================================================
+add_example(python "Example on how to use the python interface" PACKAGE python_interface)
+
+package_add_files_to_package(
+ examples/README.rst
+ cmake/AkantuExampleMacros.cmake
+ )
+
+
diff --git a/examples/README.rst b/examples/README.rst
new file mode 100644
index 000000000..e317e4b13
--- /dev/null
+++ b/examples/README.rst
@@ -0,0 +1,59 @@
+========
+Examples
+========
+
+This examples demonstrate some of the principal features of **Akantu**. Each
+sub-folder contain concentrate on one particular features.
+
+Common features
+---------------
+
+*boundary_conditions*
+ This shows how to impose boundary conditions by using the group of elements
+ defining the boundaries. Boundaries are applied mainly by using functors, some
+ are predefined in akantu asshown in the sub-example 'predefined_bc'. If this
+ is not sufficient the user can define it's one functor, example
+ 'user_defined_bc'
+
+*io*
+ This examples show some advanced features of the dumpers, to dump extra
+ fields than the default ones
+
+*parallel*
+ This example shows how to initialize a parallel computation
+
+*python*
+ This examples show some basic usage of the python interface
+
+Solid Mechanics
+---------------
+
+*explicit*
+ This examples shows a dynamic wave propagation in a beam. It uses a central
+ difference explicit time integration scheme.
+
+*implicit*
+ This example shows how to use the implicit dynamic solver.
+
+*static*
+ This example shows how to do a static computation
+
+*cohesive_element*
+ This examples show some usage of the cohesive element in explicit or implicit
+ and with extrinsic or intrinsic elements
+
+*new_material*
+ This example shows how to write a custom material outside of **Akantu** and
+ how to use it
+
+Heat transfer
+-------------
+
+*heat_transfer*
+ This example shows how to use the HeatTransferModel
+
+Structural mechanics
+--------------------
+
+*structural_mechanics*
+ This example shows how to use the StructuralMechanicsModel
diff --git a/examples/boundary_conditions/CMakeLists.txt b/examples/boundary_conditions/CMakeLists.txt
index 2914073ce..65c03b0af 100644
--- a/examples/boundary_conditions/CMakeLists.txt
+++ b/examples/boundary_conditions/CMakeLists.txt
@@ -1,32 +1,32 @@
#===============================================================================
# @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
+# @date last modification: Mon Jan 18 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(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
+add_example(predefined_bc "Example of predefined boundary condition" PACKAGE core)
+add_example(user_defined_bc "Example of user defined boundary condition" PACKAGE core)
diff --git a/examples/boundary_conditions/predefined_BC/CMakeLists.txt b/examples/boundary_conditions/predefined_bc/CMakeLists.txt
similarity index 70%
rename from examples/boundary_conditions/predefined_BC/CMakeLists.txt
rename to examples/boundary_conditions/predefined_bc/CMakeLists.txt
index aa209f7a6..8d7036691 100644
--- a/examples/boundary_conditions/predefined_BC/CMakeLists.txt
+++ b/examples/boundary_conditions/predefined_bc/CMakeLists.txt
@@ -1,39 +1,37 @@
#===============================================================================
# @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
+# @date last modification: Mon Jan 18 2016
#
# @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)
+add_mesh(predefined_bc_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
+register_example(predefined_bc SOURCES predefined_bc.cc
+ DEPENDS predefined_bc_mesh
+ FILES_TO_COPY material.dat)
diff --git a/examples/boundary_conditions/predefined_BC/material.dat b/examples/boundary_conditions/predefined_bc/material.dat
similarity index 100%
rename from examples/boundary_conditions/predefined_BC/material.dat
rename to examples/boundary_conditions/predefined_bc/material.dat
diff --git a/examples/boundary_conditions/predefined_BC/plate.cc b/examples/boundary_conditions/predefined_bc/predefined_bc.cc
similarity index 57%
rename from examples/boundary_conditions/predefined_BC/plate.cc
rename to examples/boundary_conditions/predefined_bc/predefined_bc.cc
index 9211fc1d4..c59eeb2ef 100644
--- a/examples/boundary_conditions/predefined_BC/plate.cc
+++ b/examples/boundary_conditions/predefined_bc/predefined_bc.cc
@@ -1,97 +1,63 @@
/**
- * @file plate.cc
+ * @file predefined_bc.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
+ * @date last modification: Mon Jan 18 2016
*
* @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 mesh(2);
mesh.read("square.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
+ // model initialization
SolidMechanicsModel model(mesh);
-
- /// model initialization
model.initFull();
- std::cout << model.getMaterial(0) << std::endl;
- model.assembleMassLumped();
-
- /// Dirichlet boundary conditions
+ // 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();
-
+ // output in a paraview file
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/predefined_BC/square.geo b/examples/boundary_conditions/predefined_bc/square.geo
similarity index 100%
rename from examples/boundary_conditions/predefined_BC/square.geo
rename to examples/boundary_conditions/predefined_bc/square.geo
diff --git a/examples/boundary_conditions/user_defined_BC/CMakeLists.txt b/examples/boundary_conditions/user_defined_bc/CMakeLists.txt
similarity index 67%
rename from examples/boundary_conditions/user_defined_BC/CMakeLists.txt
rename to examples/boundary_conditions/user_defined_bc/CMakeLists.txt
index 3bb958d10..920781217 100644
--- a/examples/boundary_conditions/user_defined_BC/CMakeLists.txt
+++ b/examples/boundary_conditions/user_defined_bc/CMakeLists.txt
@@ -1,39 +1,39 @@
#===============================================================================
# @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
+# @date last modification: Mon Jan 18 2016
#
# @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)
+add_mesh(user_defined_bc_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
+register_example(user_defined_bc
+ SOURCES user_defined_bc.cc
+ DEPENDS user_defined_bc_mesh
+ FILES_TO_COPY material.dat
+ )
diff --git a/examples/boundary_conditions/user_defined_BC/fine_mesh.geo b/examples/boundary_conditions/user_defined_bc/fine_mesh.geo
similarity index 100%
rename from examples/boundary_conditions/user_defined_BC/fine_mesh.geo
rename to examples/boundary_conditions/user_defined_bc/fine_mesh.geo
diff --git a/examples/boundary_conditions/user_defined_BC/material.dat b/examples/boundary_conditions/user_defined_bc/material.dat
similarity index 100%
rename from examples/boundary_conditions/user_defined_BC/material.dat
rename to examples/boundary_conditions/user_defined_bc/material.dat
diff --git a/examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc b/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc
similarity index 68%
rename from examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc
rename to examples/boundary_conditions/user_defined_bc/user_defined_bc.cc
index f31c4e3c3..32e1e048d 100644
--- a/examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc
+++ b/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc
@@ -1,97 +1,89 @@
/**
- * @file complex_boundary_condition.cc
+ * @file user_defined_bc.cc
*
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Wed Dec 16 2015
+ * @date last modification: Mon Jan 18 2016
*
* @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>
+#include <cmath>
/* -------------------------------------------------------------------------- */
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 {
+ SineBoundary(Real amp, Real phase, BC::Axis ax = _x) : DirichletFunctor(ax),
+ amplitude(amp),
+ phase(phase) {}
+public:
+ inline void operator()(__attribute__((unused)) 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));
+ primal(axis) = -amplitude * std::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();
+ model.initFull();
/// 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");
-
+ // output a paraview file with the boundary conditions
model.setBaseName("plate");
model.addDumpFieldVector("displacement");
+ model.addDumpFieldVector("force");
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 019d7d074..ea1b3ac32 100644
--- a/examples/cohesive_element/CMakeLists.txt
+++ b/examples/cohesive_element/CMakeLists.txt
@@ -1,33 +1,38 @@
#===============================================================================
# @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: Tue Jan 12 2016
+# @date last modification: Mon Jan 18 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)
\ No newline at end of file
+
+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)
diff --git a/examples/cohesive_element/cohesive_extrinsic/CMakeLists.txt b/examples/cohesive_element/cohesive_extrinsic/CMakeLists.txt
index 163fd45a9..9c563e853 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: Mon Jan 18 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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 .)
+register_example(cohesive_extrinsic
+ SOURCES cohesive_extrinsic.cc
+ DEPENDS cohesive_extrinsic_mesh
+ FILES_TO_COPY material.dat
+ )
diff --git a/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc b/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc
index c7dc095b8..2c4f4e55d 100644
--- a/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc
+++ b/examples/cohesive_element/cohesive_extrinsic/cohesive_extrinsic.cc
@@ -1,141 +1,124 @@
/**
* @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: Mon Jan 18 2016
*
* @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"
-
+/* -------------------------------------------------------------------------- */
+#include <iostream>
/* -------------------------------------------------------------------------- */
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);
+ displacement(n, 1) += disp_update * position(n, 1);
}
model.checkCohesiveStress();
-
- model.explicitPred();
- model.updateResidual();
- model.updateAcceleration();
- model.explicitCorr();
+ model.solveStep();
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/material.dat b/examples/cohesive_element/cohesive_extrinsic_IG_TG/material.dat
deleted file mode 100644
index 04e600686..000000000
--- a/examples/cohesive_element/cohesive_extrinsic_IG_TG/material.dat
+++ /dev/null
@@ -1,20 +0,0 @@
-material elastic [
- name = steel
- rho = 1e3 # density
- E = 1e3 # young's modulus
- nu = 0.0 # poisson's ratio
-]
-
-material cohesive_linear [
- name = TG_cohesive
- beta = 0
- G_cI = 10
- sigma_c = 100
-]
-
-material cohesive_linear [
- name = IG_cohesive
- beta = 0
- G_cI = 10
- sigma_c = 20
-]
diff --git a/examples/cohesive_element/cohesive_extrinsic_IG_TG/CMakeLists.txt b/examples/cohesive_element/cohesive_extrinsic_ig_tg/CMakeLists.txt
similarity index 66%
rename from examples/cohesive_element/cohesive_extrinsic_IG_TG/CMakeLists.txt
rename to examples/cohesive_element/cohesive_extrinsic_ig_tg/CMakeLists.txt
index 3028fbb46..d48b8babb 100644
--- a/examples/cohesive_element/cohesive_extrinsic_IG_TG/CMakeLists.txt
+++ b/examples/cohesive_element/cohesive_extrinsic_ig_tg/CMakeLists.txt
@@ -1,41 +1,38 @@
#===============================================================================
# @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: Mon Jan 18 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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)
+register_example(cohesive_extrinsic_ig_tg
+ SOURCES cohesive_extrinsic_ig_tg.cc
+ FILES_TO_COPY material.dat square.msh
+ )
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
similarity index 57%
rename from examples/cohesive_element/cohesive_extrinsic_IG_TG/cohesive_extrinsic_IG_TG.cc
rename to examples/cohesive_element/cohesive_extrinsic_ig_tg/cohesive_extrinsic_ig_tg.cc
index ded0af86b..ac2246f35 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,197 @@
/**
- * @file cohesive_extrinsic_IG_TG.cc
+ * @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: Mon Jan 18 2016
*
- * @brief Test for considering different cohesive properties for intergranular (IG) and
+ * @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"
-
+/* -------------------------------------------------------------------------- */
+#include <iostream>
/* -------------------------------------------------------------------------- */
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) {
- }
+ 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);
+ 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);
- }
+ 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);
+ // 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[]) {
+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");
+ MultiGrainMaterialSelector material_selector(model,
+ "tg_cohesive",
+ "ig_cohesive");
model.setMaterialSelector(material_selector);
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true, false));
+ model.initFull(
+ SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true, false));
- Real time_step = model.getStableTimeStep()*0.05;
+ 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)
+ 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("velocity");
model.addDumpField("acceleration");
- model.addDumpField("residual" );
+ 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;
+ 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;}
+ 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.solveStep();
- model.dump();
- if(s % 10 == 0) {
+ if (s % 10 == 0) {
+ model.dump();
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_ig_tg/material.dat b/examples/cohesive_element/cohesive_extrinsic_ig_tg/material.dat
new file mode 100644
index 000000000..7dcb6ff29
--- /dev/null
+++ b/examples/cohesive_element/cohesive_extrinsic_ig_tg/material.dat
@@ -0,0 +1,20 @@
+material elastic [
+ name = steel
+ rho = 1e3 # density
+ E = 1e3 # young's modulus
+ nu = 0.0 # poisson's ratio
+]
+
+material cohesive_linear [
+ name = tg_cohesive
+ beta = 0
+ G_cI = 10
+ sigma_c = 100
+]
+
+material cohesive_linear [
+ name = ig_cohesive
+ beta = 0
+ G_cI = 10
+ sigma_c = 20
+]
diff --git a/examples/cohesive_element/cohesive_extrinsic_IG_TG/square.msh b/examples/cohesive_element/cohesive_extrinsic_ig_tg/square.msh
similarity index 100%
rename from examples/cohesive_element/cohesive_extrinsic_IG_TG/square.msh
rename to examples/cohesive_element/cohesive_extrinsic_ig_tg/square.msh
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/CMakeLists.txt b/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt
similarity index 65%
copy from test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/CMakeLists.txt
copy to examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt
index 0bf4aea54..9f1038539 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/CMakeLists.txt
+++ b/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt
@@ -1,37 +1,39 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Mauro Corrado <mauro.corrado@epfl.ch>
#
-# @date Fri May 01 11:56:18 2015
+# @date creation: Tue Jan 12 2016
+# @date last modification: Mon Jan 18 2016
#
-# @brief checking correct assembling of stiffness matrix in case of cohe elems
+# @brief Example for extrinsic cohesive elements in implicit
#
# @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
#
#===============================================================================
+add_mesh(cohesive_extrinsic_implicit_mesh dcb_2d.geo 2 2)
+
+register_example(cohesive_extrinsic_implicit
+ SOURCES cohesive_extrinsic_implicit.cc
+ DEPENDS cohesive_extrinsic_implicit_mesh
+ FILES_TO_COPY material.dat)
-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/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc b/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc
new file mode 100644
index 000000000..47c5f305f
--- /dev/null
+++ b/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc
@@ -0,0 +1,172 @@
+/**
+ * @file cohesive_extrinsic_implicit.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Tue Jan 12 2016
+ * @date last modification: Mon Jan 18 2016
+ *
+ * @brief Example for extrinsic cohesive elements in implicit
+ *
+ * @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_cohesive.hh"
+/* -------------------------------------------------------------------------- */
+#include <iostream>
+/* -------------------------------------------------------------------------- */
+
+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_extrinsic_implicit/dcb_2d.geo b/examples/cohesive_element/cohesive_extrinsic_implicit/dcb_2d.geo
new file mode 100644
index 000000000..3e7c9b5e4
--- /dev/null
+++ b/examples/cohesive_element/cohesive_extrinsic_implicit/dcb_2d.geo
@@ -0,0 +1,26 @@
+dx = 0.005;
+
+Point(1) = {0,0,0,dx};
+Point(2) = {0,0.05,0,dx};
+Point(3) = {0,-0.05,0,dx};
+Point(4) = {0.3,0,0,dx};
+Point(5) = {0.3,0.05,0,dx};
+Point(6) = {0.3,-0.05,0,dx};
+Line(1) = {1, 2};
+Line(2) = {2, 5};
+Line(3) = {5, 4};
+Line(4) = {1, 4};
+Line(5) = {1, 3};
+Line(6) = {6, 4};
+Line(7) = {3, 6};
+Line Loop(8) = {2, 3, -4, 1};
+Plane Surface(9) = {-8};
+Line Loop(10) = {5, 7, 6, -4};
+Plane Surface(11) = {10};
+Physical Surface("bulk") = {9,11};
+Physical Line("coh") = {4};
+
+Transfinite Surface "*";
+Recombine Surface "*";
+
+Mesh.SecondOrderIncomplete = 1;
diff --git a/examples/cohesive_element/cohesive_extrinsic_implicit/material.dat b/examples/cohesive_element/cohesive_extrinsic_implicit/material.dat
new file mode 100644
index 000000000..51c416afc
--- /dev/null
+++ b/examples/cohesive_element/cohesive_extrinsic_implicit/material.dat
@@ -0,0 +1,18 @@
+material elastic [
+ name = bulk
+ rho = 2500 # density
+ E = 70e9 # young's modulus
+ nu = 0.29 # poisson's ratio
+
+]
+
+material cohesive_linear [
+ name = interface
+ beta = 1
+ G_c = 4.5e2
+ kappa = 1
+ penalty = 1.0e7
+ sigma_c = 1.5e6
+ contact_after_breaking = true
+]
+
diff --git a/examples/cohesive_element/cohesive_intrinsic/CMakeLists.txt b/examples/cohesive_element/cohesive_intrinsic/CMakeLists.txt
index 312c8707b..afbdccbd5 100644
--- a/examples/cohesive_element/cohesive_intrinsic/CMakeLists.txt
+++ b/examples/cohesive_element/cohesive_intrinsic/CMakeLists.txt
@@ -1,45 +1,38 @@
#===============================================================================
# @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: Mon Jan 18 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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)
-
+ SOURCES cohesive_intrinsic.cc
+ DEPENDS cohesive_intrinsic_mesh
+ FILES_TO_COPY material.dat)
- #===============================================================================
-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..3ebb7d77c 100644
--- a/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc
+++ b/examples/cohesive_element/cohesive_intrinsic/cohesive_intrinsic.cc
@@ -1,174 +1,157 @@
/**
* @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: Mon Jan 18 2016
*
* @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"
+/* -------------------------------------------------------------------------- */
+#include <iostream>
/* -------------------------------------------------------------------------- */
using namespace akantu;
-static void updateDisplacement(SolidMechanicsModelCohesive &,
- Array<UInt> &,
- ElementType,
- Real);
+static void updateDisplacement(SolidMechanicsModelCohesive &, Array<UInt> &,
+ ElementType, Real);
-int main(int argc, char *argv[]) {
+/* -------------------------------------------------------------------------- */
+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;
+ 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("velocity");
model.addDumpField("acceleration");
- model.addDumpField("residual" );
+ 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);
+ 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) {
+ 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) {
-
+ 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;
+ displacement(node, 0) -= increment;
+ // displacement(node, 1) += increment;
+ update(node) = true;
}
}
}
}
diff --git a/examples/contact/CMakeLists.txt b/examples/contact/CMakeLists.txt
deleted file mode 100644
index 67168b8ad..000000000
--- a/examples/contact/CMakeLists.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-#===============================================================================
-# @file CMakeLists.txt
-#
-# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
-#
-# @date Mon Mar 24 11:30:00 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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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
deleted file mode 100644
index 33776efc4..000000000
--- a/examples/contact/blocks.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * @file blocks.cc
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date Tue Jan 14 09:38:00 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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/blocks.geo b/examples/contact/blocks.geo
deleted file mode 100644
index 1e787733e..000000000
--- a/examples/contact/blocks.geo
+++ /dev/null
@@ -1,30 +0,0 @@
-// Gmsh project created on Wed Nov 27 11:24:05 2013
-h1=0.7;
-h2=0.45;
-s = 2;
-Point(1) = {-2*s, 0, 0, h1};
-Point(2) = {2*s, 0, 0, h1};
-Point(3) = {2*s, 2, 0, h1};
-Point(4) = {-2*s, 2, 0, h1};
-Point(5) = {-1*s, 2, 0, h2};
-Point(6) = {1*s, 2, 0, h2};
-Point(7) = {1*s, 3, 0, h2};
-Point(8) = {-1*s, 3, 0, h2};
-Line(1) = {1, 2};
-Line(2) = {2, 3};
-Line(3) = {3, 4};
-Line(4) = {4, 1};
-Line Loop(7) = {2, 3, 4, 1};
-Plane Surface(8) = {7};
-Line(9) = {5, 6};
-Line(10) = {6, 7};
-Line(11) = {7, 8};
-Line(12) = {8, 5};
-Line Loop(13) = {9, 10, 11, 12};
-Plane Surface(14) = {13};
-Physical Line("bottom") = {1};
-Physical Line("top") = {11};
-Physical Line("interface_bottom") = {3};
-Physical Line("interface_top") = {9};
-Physical Surface("Bottom_body") = {8};
-Physical Surface("Top_body") = {14};
diff --git a/examples/contact/hertz_2D.cc b/examples/contact/hertz_2D.cc
deleted file mode 100644
index 6294abbd4..000000000
--- a/examples/contact/hertz_2D.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * @file hertz_2D.cc
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date Tue Jan 14 09:38:00 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_2D.geo b/examples/contact/hertz_2D.geo
deleted file mode 100644
index 5dfc70800..000000000
--- a/examples/contact/hertz_2D.geo
+++ /dev/null
@@ -1,29 +0,0 @@
-cl1 = 0.01;
-cl2 = 0.1;
-cl3 = 1;
-Dy = 0.1;
-Point(1) = {0, 0.1-Dy, 0, cl1};
-Point(2) = {0.5, 0.6-Dy, 0, cl2};
-Point(3) = {-0.5, 0.6-Dy, 0, cl2};
-Point(4) = {0.5, 0, 0, cl3};
-Point(5) = {-0.5, 0, 0, cl3};
-Point(6) = {-0.5, -0.25, 0, cl3};
-Point(7) = {0.5, -0.25, 0, cl3};
-Point(8) = {0, 0.6-Dy, 0, cl2};
-Circle(1) = {3, 8, 1};
-Circle(2) = {1, 8, 2};
-Line(3) = {2, 8};
-Line(13) = {8, 3};
-Line(4) = {6, 7};
-Line(5) = {7, 4};
-Line(6) = {4, 5};
-Line(7) = {5, 6};
-Line Loop(9) = {2, 3, 13, 1};
-Plane Surface(9) = {9};
-Line Loop(11) = {6, 7, 4, 5};
-Plane Surface(11) = {11};
-Physical Line("rigid") = {6};
-Physical Line("contact_surface") = {1, 2};
-Physical Line("top") = {3, 13};
-Physical Surface("top_body") = {9};
-Physical Surface("bottom_body") = {11};
diff --git a/examples/contact/hertz_3D.cc b/examples/contact/hertz_3D.cc
deleted file mode 100644
index 9e0ff5c9c..000000000
--- a/examples/contact/hertz_3D.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * @file hertz_3D.cc
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date Fri Apr 4 11:30:00 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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/hertz_3D.geo b/examples/contact/hertz_3D.geo
deleted file mode 100644
index c9a78db78..000000000
--- a/examples/contact/hertz_3D.geo
+++ /dev/null
@@ -1,54 +0,0 @@
-cl1 = 0.005;
-cl2 = 0.1;
-cl3 = 0.4;
-Dy = 0.099;
-Dz = 1;
-Point(1) = {0, 0.1-Dy, 0, cl1};
-Point(2) = {0.5, 0.6-Dy, 0, cl2};
-Point(3) = {-0.5, 0.6-Dy, 0, cl2};
-Point(4) = {0, 0.6-Dy, 0, cl2};
-Point(5) = {0, 0.6-Dy, -0.5, cl2};
-Point(6) = {0, 0.6-Dy, 0.5, cl2};
-
-Point(7) = {0, 0, 0, cl3};
-Point(8) = {0.5, 0, 0, cl3};
-Point(9) = {-0.5, 0, 0, cl3};
-Point(10) = {0, 0, -0.5, cl3};
-Point(11) = {0, 0, 0.5, cl3};
-
-Circle(1) = {3, 4, 1};
-Circle(2) = {1, 4, 2};
-Circle(3) = {6, 4, 1};
-Circle(4) = {1, 4, 5};
-Circle(5) = {3, 4, 6};
-Circle(6) = {6, 4, 2};
-Circle(7) = {2, 4, 5};
-Circle(8) = {5, 4, 3};
-Line Loop(1) = {3, 2, -6};
-Ruled Surface(1) = {1};
-Line Loop(2) = {-2, -7, 4};
-Ruled Surface(2) = {2};
-Line Loop(3) = {-4, -8, -1};
-Ruled Surface(3) = {3};
-Line Loop(4) = {1, -3, -5};
-Ruled Surface(4) = {4};
-Line Loop(5) = {6, 7, 8, 5};
-Plane Surface(5) = {5};
-Surface Loop(1) = {3, 2, 1, 4, 5};
-Volume(1) = {1};
-
-Circle(9) = {9, 7, 11};
-Circle(10) = {11, 7, 8};
-Circle(11) = {8, 7, 10};
-Circle(12) = {10, 7, 9};
-Line Loop(6) = {10, 11, 12, 9};
-Plane Surface(6) = {6};
-Extrude {0, -cl3, 0} {
- Surface{6};
-}
-
-Physical Surface("top_surface") = {5};
-Physical Surface("rigid_surface") = {6};
-Physical Volume("top_body") = {1};
-Physical Volume("bottom_body") = {2};
-Physical Surface("contact_surface") = {1, 2, 4, 3};
diff --git a/examples/contact/steel.dat b/examples/contact/steel.dat
deleted file mode 100644
index fae183ada..000000000
--- a/examples/contact/steel.dat
+++ /dev/null
@@ -1,7 +0,0 @@
-material neohookean [
- name = steel
- rho = 7500 # kg/m^3
- E = 2e11 # GPa
- nu = 0.
- finite_deformation = 1
-]
diff --git a/examples/contact/tetrahedra.cc b/examples/contact/tetrahedra.cc
deleted file mode 100644
index 54dc49336..000000000
--- a/examples/contact/tetrahedra.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * @file tetrahedra.cc
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date Tue Jan 14 09:38:00 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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/contact/tetrahedra.geo b/examples/contact/tetrahedra.geo
deleted file mode 100644
index 13859bf02..000000000
--- a/examples/contact/tetrahedra.geo
+++ /dev/null
@@ -1,69 +0,0 @@
-cl1 = 4;
-off = 0.;
-Point(1) = {-0.5, -0.5, -0.5, cl1};
-Point(2) = {-0.5, 0.5, -0.5, cl1};
-Point(3) = {0.5, 0.5, -0.5, cl1};
-Point(4) = {0.5, -0.5, -0.5, cl1};
-Point(5) = {0.25, 1.2, 0 + off, cl1};
-Point(6) = {0.75, 1.9, -0.5 + off, cl1};
-Point(7) = {-0.25, 1.9, -0.5 + off, cl1};
-Point(11) = {-0.5, -0.5, 0.5, cl1};
-Point(12) = {-0.5, 0.5, 0.5, cl1};
-Point(13) = {0.5, 0.5, 0.5, cl1};
-Point(14) = {0.5, -0.5, 0.5, cl1};
-Point(26) = {0.75, 1.9, 0.5 + off, cl1};
-Point(27) = {-0.25, 1.9, 0.5 + off, cl1};
-Line(1) = {1, 4};
-Line(2) = {4, 3};
-Line(3) = {3, 2};
-Line(4) = {2, 1};
-Line(5) = {5, 6};
-Line(6) = {6, 7};
-Line(7) = {7, 5};
-Line(11) = {11, 14};
-Line(12) = {14, 13};
-Line(13) = {13, 12};
-Line(14) = {12, 11};
-Line(15) = {14, 4};
-Line(16) = {13, 3};
-Line(17) = {11, 1};
-Line(18) = {12, 2};
-Line(19) = {27, 26};
-Line(20) = {26, 26};
-Line(21) = {26, 6};
-Line(22) = {27, 7};
-Line(23) = {26, 5};
-Line(24) = {27, 5};
-Line Loop(26) = {12, 16, -2, -15};
-Plane Surface(26) = {26};
-Line Loop(28) = {1, 2, 3, 4};
-Plane Surface(28) = {28};
-Line Loop(30) = {17, -4, -18, 14};
-Plane Surface(30) = {30};
-Line Loop(32) = {11, 12, 13, 14};
-Plane Surface(32) = {32};
-Line Loop(34) = {15, -1, -17, 11};
-Plane Surface(34) = {34};
-Line Loop(36) = {16, 3, -18, -13};
-Plane Surface(36) = {36};
-Line Loop(38) = {5, -21, 23};
-Plane Surface(38) = {38};
-Line Loop(40) = {24, -23, -19};
-Plane Surface(40) = {40};
-Line Loop(42) = {24, -7, -22};
-Plane Surface(42) = {42};
-Line Loop(44) = {5, 6, 7};
-Plane Surface(44) = {44};
-Line Loop(46) = {21, 6, -22, 19};
-Plane Surface(46) = {46};
-Surface Loop(48) = {38, 44, 46, 42, 40};
-Volume(48) = {48};
-Surface Loop(50) = {36, 26, 32, 34, 28, 30};
-Volume(50) = {50};
-Physical Surface("top_surface") = {46};
-Physical Surface("bottom_surface") = {34};
-Physical Surface("bottom_dummy") = {30, 32, 26, 28};
-Physical Surface("top_dummy") = {40, 38, 44, 42};
-Physical Surface("master") = {36};
-Physical Volume("top_body") = {48};
-Physical Volume("bottom_body") = {50};
diff --git a/examples/embedded/CMakeLists.txt b/examples/embedded/CMakeLists.txt
index db215aa62..bf38b4695 100644
--- a/examples/embedded/CMakeLists.txt
+++ b/examples/embedded/CMakeLists.txt
@@ -1,42 +1,40 @@
#===============================================================================
# @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
+# @date last modification: Mon Jan 18 2016
#
# @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 .)
+register_example(embedded embedded.cc
+ DEPENDS concrete_mesh reinforcement_mesh
+ USE_PACKAGES CGAL
+ FILES_TO_COPY material.dat)
diff --git a/examples/embedded/embedded.cc b/examples/embedded/embedded.cc
index 3bf33542b..92aee950a 100644
--- a/examples/embedded/embedded.cc
+++ b/examples/embedded/embedded.cc
@@ -1,108 +1,112 @@
/**
- * @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
+ * @date last modification: Mon Jan 18 2016
*
- * @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) {}
+ } 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" );
+ 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
+ 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);
+ bool converged =
+ model.solveStep<_scm_newton_raphson_tangent_not_computed, _scc_residual>(
+ 1e-6, error, 1);
- if (!converged)
+ 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..847687700 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: Mon Jan 18 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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 .)
+register_example(explicit_dynamic
+ SOURCES explicit_dynamic.cc
+ DEPENDS explicit_dynamic_mesh
+ FILES_TO_COPY material.dat)
diff --git a/examples/explicit/explicit_dynamic.cc b/examples/explicit/explicit_dynamic.cc
index b3865a8bb..4822ce478 100644
--- a/examples/explicit/explicit_dynamic.cc
+++ b/examples/explicit/explicit_dynamic.cc
@@ -1,109 +1,108 @@
/**
* @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: Mon Jan 18 2016
*
* @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;
+using namespace akantu;
-int main(int argc, char *argv[]) {
+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();
+ model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass));
time_step = model.getStableTimeStep();
- std::cout << "Time Step = " << time_step * time_factor << "s ("<< time_step << "s)" << std::endl;
+ 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();
+ 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("velocity");
model.addDumpField("acceleration");
- model.addDumpField("stress" );
+ model.addDumpField("stress");
model.dump();
- for(UInt s = 1; s <= max_steps; ++s) {
+ 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;
+ energy << s << "," << s * time_step << "," << epot << "," << ekin << ","
+ << epot + ekin << "," << std::endl;
- if(s % 10 == 0) std::cout << "passing step " << s << "/" << max_steps << 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..881ecb056 100644
--- a/examples/heat_transfer/CMakeLists.txt
+++ b/examples/heat_transfer/CMakeLists.txt
@@ -1,42 +1,39 @@
#===============================================================================
# @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: Mon Jan 18 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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 .)
+register_example(explicit_heat_transfer
+ SOURCES explicit_heat_transfer.cc
+ DEPENDS explicit_heat_transfer_mesh
+ FILES_TO_COPY material.dat
+ )
-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..b254d9206 100644
--- a/examples/heat_transfer/explicit_heat_transfer.cc
+++ b/examples/heat_transfer/explicit_heat_transfer.cc
@@ -1,113 +1,110 @@
/**
* @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: Mon Jan 18 2016
*
* @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;
+using namespace akantu;
+const UInt spatial_dimension = 2;
+/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[])
-{
- akantu::initialize("material.dat", argc, argv);
+int main(int argc, char * argv[]) {
+ initialize("material.dat", argc, argv);
- //create mesh
- akantu::Mesh mesh(spatial_dimension);
+ // create mesh
+ Mesh mesh(spatial_dimension);
mesh.read("square.msh");
- akantu::HeatTransferModel model(mesh);
- //initialize everything
+ HeatTransferModel model(mesh);
+ // initialize everything
model.initFull();
- //assemble the lumped capacity
+ // 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;
+ // get 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 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) {
+ // boundary conditions
+ const Array<Real> & nodes = model.getFEEngine().getMesh().getNodes();
+ Array<bool> & boundary = model.getBlockedDOFs();
+ Array<Real> & temperature = model.getTemperature();
+ double length = 1.;
+
+ UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
+ for (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;
+ Real dx = nodes(i, 0) - length / 4.;
+ Real dy = 0.0;
+ 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 (spatial_dimension > 1)
+ dy = nodes(i, 1) - length / 4.;
+ if (spatial_dimension == 3)
+ dz = nodes(i, 2) - length / 4.;
+ Real d = sqrt(dx * dx + dy * dy + dz * dz);
// if(dx < 0.0){
- if(d < 0.1){
+ if (d < 0.1) {
boundary(i) = true;
temperature(i) = 300.;
}
}
model.updateResidual();
model.setBaseName("heat_transfer_square2d");
- model.addDumpField("temperature" );
+ model.addDumpField("temperature");
model.addDumpField("temperature_rate");
- model.addDumpField("residual" );
- model.addDumpField("capacity_lumped" );
+ model.addDumpField("residual");
+ model.addDumpField("capacity_lumped");
model.dump();
- //main loop
+ // main loop
int max_steps = 15000;
- for(int i=0; i<max_steps; i++)
- {
- model.explicitPred();
- model.updateResidual();
- model.solveExplicitLumped();
- model.explicitCorr();
+ 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;
+ if (i % 100 == 0)
+ model.dump();
+ if (i % 10 == 0)
+ std::cout << "Step " << i << "/" << max_steps << std::endl;
+ }
+ std::cout << "\n\n Stable Time Step is : " << time_step << "\n \n"
+ << std::endl;
return 0;
}
diff --git a/examples/implicit/CMakeLists.txt b/examples/implicit/CMakeLists.txt
index 27abfc60e..87a7a4fde 100644
--- a/examples/implicit/CMakeLists.txt
+++ b/examples/implicit/CMakeLists.txt
@@ -1,44 +1,40 @@
#===============================================================================
# @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: Mon Jan 18 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
+register_example(implicit_dynamic
+ SOURCES implicit_dynamic.cc
+ DEPENDS implicit_dynamic_mesh
+ FILES_TO_COPY material_dynamic.dat
)
+
diff --git a/examples/implicit/implicit_dynamic.cc b/examples/implicit/implicit_dynamic.cc
index 9fadb07f6..11e9d6936 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)
- * 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 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..8a1b0d675 100644
--- a/examples/io/dumper/CMakeLists.txt
+++ b/examples/io/dumper/CMakeLists.txt
@@ -1,51 +1,58 @@
#===============================================================================
# @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: Wed Jan 20 2016
#
# @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_mesh(swiss_train_mesh swiss_train.geo 2 1)
add_library(locomotive_tools
locomotive_tools.cc
locomotive_tools.hh
)
+target_include_directories(locomotive_tools PRIVATE ${AKANTU_INCLUDE_DIRS})
+
+if(AKANTU_EXTRA_CXX_FLAGS)
+ set_target_properties(locomotive_tools PROPERTIES COMPILE_FLAGS ${AKANTU_EXTRA_CXX_FLAGS})
+endif()
+
register_example(dumper_low_level
- dumper_low_level.cc
- USE IOHelper
- DEPENDS swiss_train locomotive_tools
- DIRECTORIES_TO_CREATE paraview
+ SOURCES dumper_low_level.cc
+ USE_PACKAGES IOHelper
+ DEPENDS swiss_train_mesh locomotive_tools
)
register_example(dumpable_interface
- dumpable_interface.cc
- USE IOHelper
- DEPENDS swiss_train locomotive_tools
- DIRECTORIES_TO_CREATE paraview
+ SOURCES dumpable_interface.cc
+ USE_PACKAGES IOHelper
+ DEPENDS swiss_train_mesh locomotive_tools
)
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..661ae4121 100644
--- a/examples/io/dumper/locomotive_tools.cc
+++ b/examples/io/dumper/locomotive_tools.cc
@@ -1,87 +1,93 @@
/**
* @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
+ * @date last modification: Mon Jan 18 2016
*
* @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 "aka_array.hh"
#include "mesh.hh"
-#include "aka_types.hh"
+/* -------------------------------------------------------------------------- */
+#include "locomotive_tools.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;
+ if (std::abs(radius) < Math::getTolerance())
+ continue;
Real phi_i = std::acos(pos_rel(_x) / radius);
- if (pos_rel(_y) < 0) phi_i *= -1;
+ 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) {
+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..88655648e 100644
--- a/examples/io/parser/CMakeLists.txt
+++ b/examples/io/parser/CMakeLists.txt
@@ -1,44 +1,40 @@
#===============================================================================
# @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 Jan 18 2016
+#
# @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)
+
+add_mesh(swiss_cheese_mesh 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
+ DEPENDS swiss_cheese_mesh
+ FILES_TO_COPY input_file.dat
)
diff --git a/examples/io/parser/example_parser.cc b/examples/io/parser/example_parser.cc
index b431faf80..e0ab62c1e 100644
--- a/examples/io/parser/example_parser.cc
+++ b/examples/io/parser/example_parser.cc
@@ -1,80 +1,84 @@
/**
* @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
+ * @date last modification: Mon Jan 18 2016
*
* @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 "solid_mechanics_model.hh"
/* -------------------------------------------------------------------------- */
-#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[]) {
-
+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.
+ // Get the user ParserSection.
const ParserSection & usersect = getUserParser();
- // getParameterValue() allows to extract data associated to a given parameter name
+ // 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).
+ // 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.
+
+ // 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.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.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..ed959fe8f 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: Mon Jan 18 2016
+# @date last modification: Tue Jan 19 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
+register_example(new_local_material
+ SOURCES
+ local_material_damage.cc
+ local_material_damage.hh
+ local_material_damage_inline_impl.hh
+ new_local_material.cc
+ DEPENDS
+ new_local_material_barre_trou_mesh
+ FILES_TO_COPY
+ material.dat
)
-
-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..08d02f243 100644
--- a/examples/new_material/local_material_damage.cc
+++ b/examples/new_material/local_material_damage.cc
@@ -1,106 +1,108 @@
/**
* @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: Mon Jan 18 2016
*
* @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) {
+ 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);
+ 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;
+ 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) {
+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) {
+void LocalMaterialDamage::computePotentialEnergy(ElementType el_type,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
Material::computePotentialEnergy(el_type, ghost_type);
- if(ghost_type != _not_ghost) return;
+ 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..2f1105b80 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
+ * @date last modification: Mon Jan 18 2016
*
* @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() {};
+ 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);
+ 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) {};
+ 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);
+ 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);
+ 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:
+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"
+#include "local_material_damage_inline_impl.hh"
__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.hh
similarity index 67%
rename from examples/new_material/local_material_damage_inline_impl.cc
rename to examples/new_material/local_material_damage_inline_impl.hh
index 3bddbbd03..cc7b15170 100644
--- a/examples/new_material/local_material_damage_inline_impl.cc
+++ b/examples/new_material/local_material_damage_inline_impl.hh
@@ -1,81 +1,83 @@
/**
* @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
+ * @date last modification: Mon Jan 18 2016
*
* @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) {
+ 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})
+ /// \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));
+ 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 += sigma(i, j) * grad_u(i, j);
}
}
Y *= 0.5;
- Real Fd = Y - Yd - Sd*dam;
+ Real Fd = Y - Yd - Sd * dam;
- if (Fd > 0) dam = (Y - Yd) / Sd;
- dam = std::min(dam,1.);
+ if (Fd > 0)
+ dam = (Y - Yd) / Sd;
+ dam = std::min(dam, 1.);
- sigma *= 1-dam;
+ sigma *= 1 - dam;
}
/* -------------------------------------------------------------------------- */
-inline void LocalMaterialDamage::computePotentialEnergyOnQuad(Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- Real & epot) {
+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 {
+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));
+ 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..f45f937bd 100644
--- a/examples/new_material/new_local_material.cc
+++ b/examples/new_material/new_local_material.cc
@@ -1,109 +1,110 @@
/**
* @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
+ * @date last modification: Mon Jan 18 2016
*
* @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"
-
+/* -------------------------------------------------------------------------- */
+#include <iostream>
+/* -------------------------------------------------------------------------- */
using namespace akantu;
#define bar_length 10.
#define bar_height 4.
akantu::Real eps = 1e-10;
-int main(int argc, char *argv[]) {
+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);
+ 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.);
+ 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);
+ 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("velocity");
model.addDumpField("acceleration");
- model.addDumpField("force" );
- model.addDumpField("residual" );
- model.addDumpField("grad_u" );
- model.addDumpField("stress" );
- model.addDumpField("damage" );
+ 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) {
+ 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)
+ std::cout << s << " " << epot << " " << ekin << " " << epot + ekin
+ << std::endl;
- if(s % 100 == 0) model.dump();
+ if (s % 100 == 0)
+ model.dump();
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/optimization/fn_optimize.cc b/examples/optimization/fn_optimize.cc
deleted file mode 100644
index 3855de530..000000000
--- a/examples/optimization/fn_optimize.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * @file fn_optimize.cc
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date Thu May 22 14:12:00 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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/CMakeLists.txt
similarity index 70%
rename from examples/parallel_2d/CMakeLists.txt
rename to examples/parallel/CMakeLists.txt
index 71460593a..4a597eb76 100644
--- a/examples/parallel_2d/CMakeLists.txt
+++ b/examples/parallel/CMakeLists.txt
@@ -1,43 +1,39 @@
#===============================================================================
# @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: Mon Jan 18 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
+ SOURCES parallel_2d.cc
+ DEPENDS parallel_2d_mesh
+ FILES_TO_COPY material.dat)
diff --git a/examples/parallel_2d/material.dat b/examples/parallel/material.dat
similarity index 100%
rename from examples/parallel_2d/material.dat
rename to examples/parallel/material.dat
diff --git a/examples/parallel_2d/parallel_2d.cc b/examples/parallel/parallel_2d.cc
similarity index 76%
rename from examples/parallel_2d/parallel_2d.cc
rename to examples/parallel/parallel_2d.cc
index 592196195..b9bb12eea 100644
--- a/examples/parallel_2d/parallel_2d.cc
+++ b/examples/parallel/parallel_2d.cc
@@ -1,125 +1,118 @@
/**
* @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: Mon Jan 18 2016
*
* @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[])
-{
+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) {
+ 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;
+ 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 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) {
+ 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) {
+ 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) {
+ for (UInt s = 1; s <= max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
- if(s % 200 == 0) model.dump();
+ if (s % 200 == 0)
+ model.dump();
- if(prank == 0 && s % 100 == 0)
+ if (prank == 0 && s % 100 == 0)
std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/parallel_2d/square_2d.geo b/examples/parallel/square_2d.geo
similarity index 100%
rename from examples/parallel_2d/square_2d.geo
rename to examples/parallel/square_2d.geo
diff --git a/examples/python/CMakeLists.txt b/examples/python/CMakeLists.txt
new file mode 100644
index 000000000..e7439f6f2
--- /dev/null
+++ b/examples/python/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_subdirectory(plate-hole)
+add_subdirectory(custom-material-dynamics)
+
+package_add_files_to_package(
+ examples/python/README.rst
+ )
diff --git a/examples/python/README.rst b/examples/python/README.rst
new file mode 100644
index 000000000..57361e88d
--- /dev/null
+++ b/examples/python/README.rst
@@ -0,0 +1,8 @@
+In order to use the Akantu examples using the python mode, one has to source
+the file ``akantu_environement.sh``:
+
+| > source <AKANTU_BUILD_DIR>/akantu_environement.sh
+
+or for an installed akantu version:
+
+| > source <AKANTU_INSTALL_DIR>/share/akantu<VERSION>/akantu_environement.sh
diff --git a/examples/python/custom-material-dynamics/CMakeLists.txt b/examples/python/custom-material-dynamics/CMakeLists.txt
new file mode 100644
index 000000000..b9e6e0952
--- /dev/null
+++ b/examples/python/custom-material-dynamics/CMakeLists.txt
@@ -0,0 +1,3 @@
+register_example(newmark
+ SCRIPT newmark.py
+ FILES_TO_COPY material.dat bar.geo)
diff --git a/examples/python/custom-material-dynamics/bar.geo b/examples/python/custom-material-dynamics/bar.geo
new file mode 100644
index 000000000..32f173f35
--- /dev/null
+++ b/examples/python/custom-material-dynamics/bar.geo
@@ -0,0 +1,45 @@
+// Mesh size
+h = 0.05;
+
+h1 = h;
+h2 = h;
+
+// Dimensions of the bar
+Lx = 10;
+Ly = 1;
+
+// ------------------------------------------
+// Geometry
+// ------------------------------------------
+
+Point(101) = { 0.0, -Ly/2, 0.0, h1};
+Point(102) = { Lx, -Ly/2, 0.0, h2};
+
+Point(103) = { Lx, 0., 0.0, h2};
+Point(104) = { Lx, Ly/2., 0.0, h2};
+
+Point(105) = { 0.0, Ly/2., 0.0, h1};
+Point(106) = { 0.0, 0., 0.0, h1};
+
+Line(101) = {101,102};
+Line(102) = {102,103};
+Line(103) = {103,104};
+Line(104) = {104,105};
+Line(105) = {105,106};
+Line(106) = {106,101};
+Line(107) = {106,103};
+
+
+Line Loop(108) = {101, 102, -107, 106};
+Plane Surface(109) = {108};
+Line Loop(110) = {103, 104, 105, 107};
+Plane Surface(111) = {110};
+Physical Surface(112) = {109, 111};
+
+Transfinite Surface "*";
+Recombine Surface "*";
+Physical Surface(113) = {111, 109};
+
+Physical Line("XBlocked") = {103, 102};
+Physical Line("ImposedVelocity") = {105, 106};
+Physical Line("YBlocked") = {104, 101};
diff --git a/examples/python/custom-material-dynamics/material.dat b/examples/python/custom-material-dynamics/material.dat
new file mode 100644
index 000000000..cbb2e7b68
--- /dev/null
+++ b/examples/python/custom-material-dynamics/material.dat
@@ -0,0 +1,4 @@
+material local_elastic [
+ name = steel
+ rho = 1 # density
+]
diff --git a/examples/python/custom-material-dynamics/newmark.py b/examples/python/custom-material-dynamics/newmark.py
new file mode 100644
index 000000000..a7efcf261
--- /dev/null
+++ b/examples/python/custom-material-dynamics/newmark.py
@@ -0,0 +1,173 @@
+#!/usr/bin/python
+################################################################
+import akantu
+import numpy as np
+import os,subprocess
+################################################################
+class FixedValue:
+
+ def __init__(self,value,axis):
+ self.value = value
+ if axis == 'x': axis = 0
+ if axis == 'y': axis = 1
+ self.axis = axis
+
+ def operator(self,node,flags,disp,coord):
+ # sets the displacement to the desired value in the desired axis
+ disp[self.axis] = self.value
+ # sets the blocked dofs vector to true in the desired axis
+ flags[self.axis] = True
+
+################################################################
+
+
+class LocalElastic:
+
+ def __init__(self):
+
+ ## young modulus
+ self.E = 1
+ ## Poisson coefficient
+ self.nu = 0.3
+ ## density
+ self.rho = 1
+ ## First Lame coefficient
+ self._lambda = self.nu * self.E / ((1 + self.nu) * (1 - 2*self.nu))
+ ## Second Lame coefficient (shear modulus)
+ self.mu = self.E / (2 * (1 + self.nu));
+
+ ## declares all the internals
+ def registerInternals(self):
+ return []
+
+ ## declares all the parameters that could be parsed
+ def registerParam(self):
+ return []
+
+
+ ## declares all the parameters that are needed
+ def getPushWaveSpeed(self):
+ return np.sqrt((self._lambda + 2*self.mu)/self.rho);
+
+ ## constitutive law for a given quadrature point
+ def computeStress(self,grad_u,sigma,internals):
+ lbda = 1.
+ mu = 1.
+
+ trace = grad_u.trace();
+ sigma[:,:] = lbda*trace*np.eye(2) + mu * (grad_u + grad_u.T)
+
+
+################################################################
+def main():
+
+ spatial_dimension = 2
+ Lbar = 10.
+ akantu.initialize('material.dat')
+
+ mesh_file = 'bar.msh'
+ max_steps = 250
+ time_step = 1e-3
+
+ #if mesh was not created the calls gmsh to generate it
+ if not os.path.isfile(mesh_file):
+ import subprocess
+ ret = subprocess.call('gmsh -2 bar.geo bar.msh',shell=True)
+ if not ret == 0:
+ raise Exception('execution of GMSH failed: do you have it installed ?')
+
+
+ ################################################################
+ ## Initialization
+ ################################################################
+ mesh = akantu.Mesh(spatial_dimension)
+ mesh.read(mesh_file)
+
+ mesh.createGroupsFromStringMeshData("physical_names")
+ model = akantu.SolidMechanicsModel(mesh)
+
+ model.initFull(akantu.SolidMechanicsModelOptions(akantu._explicit_lumped_mass,True))
+ mat = LocalElastic()
+ model.registerNewPythonMaterial(mat,"local_elastic")
+ model.initMaterials()
+
+
+ model.setBaseName("waves")
+ model.addDumpFieldVector("displacement")
+ model.addDumpFieldVector("acceleration")
+ model.addDumpFieldVector("velocity")
+ model.addDumpField("blocked_dofs")
+
+ ################################################################
+ ## Boundary conditions
+ ################################################################
+ residual = model.getResidual()
+ mass = model.getMass()
+
+ displacement = model.getDisplacement()
+ acceleration = model.getAcceleration()
+ velocity = model.getVelocity()
+
+ blocked_dofs = model.getBlockedDOFs()
+
+ ################################################################
+ ## boundary conditions
+ ################################################################
+
+ model.applyDirichletBC(FixedValue(0,'x'), "XBlocked")
+ model.applyDirichletBC(FixedValue(0,'y'), "YBlocked")
+
+ ################################################################
+ ## initial conditions
+ ################################################################
+
+ nb_nodes = mesh.getNbNodes()
+ position = mesh.getNodes()
+
+ pulse_width = 1
+ A = 0.01
+ for i in range(0,nb_nodes):
+ # Sinus * Gaussian
+ x = position[i, 0] - 5.
+ L = pulse_width
+ k = 0.1 * 2 * np.pi * 3 / L
+ displacement[i, 0] = A * np.sin(k * x) * np.exp(-(k * x) * (k * x) / (L * L))
+
+ ################################################################
+ ## timestep value computation
+ ################################################################
+ time_factor = 0.8
+ stable_time_step = model.getStableTimeStep() * time_factor
+
+ print "Stable Time Step = {0}".format(stable_time_step)
+ print "Required Time Step = {0}".format(time_step)
+
+ time_step = stable_time_step * time_factor
+
+ model.setTimeStep(time_step)
+
+ ################################################################
+ ## loop for evolution of motion dynamics
+ ################################################################
+ model.updateResidual()
+
+ epot = model.getEnergy('potential')
+ ekin = model.getEnergy('kinetic')
+
+ print "step,step * time_step,epot,ekin,epot + ekin"
+ for step in range(0,max_steps+1):
+
+ model.dump()
+ ## output energy calculation to screen
+ print "{0},{1},{2},{3},{4}".format(step,step * time_step,
+ epot,ekin,
+ (epot + ekin))
+
+ model.solveStep()
+
+ akantu.finalize()
+ return
+
+################################################################
+if __name__ == "__main__":
+ main()
diff --git a/examples/python/plate-hole/CMakeLists.txt b/examples/python/plate-hole/CMakeLists.txt
new file mode 100644
index 000000000..4a933e0a3
--- /dev/null
+++ b/examples/python/plate-hole/CMakeLists.txt
@@ -0,0 +1,3 @@
+register_example(plate-hole
+ SCRIPT plate.py
+ FILES_TO_COPY material.dat plate.geo)
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_stiffness_proportional.dat b/examples/python/plate-hole/material.dat
similarity index 55%
rename from test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_stiffness_proportional.dat
rename to examples/python/plate-hole/material.dat
index 5eb98494a..8f20aa1e1 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_stiffness_proportional.dat
+++ b/examples/python/plate-hole/material.dat
@@ -1,7 +1,6 @@
-material elastic_caughey [
- name = viscous_steel
+material elastic [
+ name = steel
rho = 7800 # density
E = 2.1e11 # young's modulus
nu = 0.3 # poisson's ratio
- alpha = 1e-6 # viscous ratio
]
diff --git a/examples/python/plate-hole/plate.geo b/examples/python/plate-hole/plate.geo
new file mode 100644
index 000000000..635cd9d48
--- /dev/null
+++ b/examples/python/plate-hole/plate.geo
@@ -0,0 +1,22 @@
+h1 = 0.1;
+h2 = h1;
+Point(1) = {0, 0, 0, h1};
+Point(2) = {4, 0, 0, h2};
+Point(3) = {4, 4, 0, h2};
+Point(4) = {0, 4, 0, h2};
+Point(5) = {1, 0, 0, h1};
+Point(6) = {0, 1, 0, h1};
+Circle(1) = {5, 1, 6};
+Line(2) = {6, 4};
+Line(3) = {4, 3};
+Line(4) = {3, 2};
+Line(5) = {2, 5};
+Line Loop(6) = {-1, -2, -3, -4, -5};
+Plane Surface(7) = {6};
+Physical Surface(8) = {7};
+Physical Line("XBlocked") = {2};
+Physical Line("YBlocked") = {5};
+Physical Line("Traction") = {3};
+
+Physical Point("XBlocked") = {5};
+Physical Point("YBlocked") = {5};
diff --git a/examples/python/plate-hole/plate.py b/examples/python/plate-hole/plate.py
new file mode 100644
index 000000000..d02f6e181
--- /dev/null
+++ b/examples/python/plate-hole/plate.py
@@ -0,0 +1,107 @@
+import akantu
+import numpy as np
+
+################################################################
+## Dirichlet Boudary condition functor: fix the displacement
+################################################################
+class FixedValue:
+
+ def __init__(self,value,axis):
+ self.value = value
+ if axis == 'x': axis = 0
+ if axis == 'y': axis = 1
+ self.axis = axis
+
+ def operator(self,node,flags,disp,coord):
+ # sets the displacement to the desired value in the desired axis
+ disp[self.axis] = self.value
+ # sets the blocked dofs vector to true in the desired axis
+ flags[self.axis] = True
+
+################################################################
+## Neumann Boudary condition functor: impose a traction
+################################################################
+class FromTraction:
+
+ def __init__(self,traction):
+ self.traction = traction
+
+ def operator(self,quad_point,force,coord,normals):
+ # sets the force to the desired value in the desired axis
+ force[:] = self.traction
+
+################################################################
+
+def solve(material_file,mesh_file,traction):
+ akantu.initialize(material_file)
+ spatial_dimension = 2
+
+ ################################################################
+ ##Initialization
+ ################################################################
+ mesh = akantu.Mesh(spatial_dimension)
+ mesh.read(mesh_file)
+ akantu.MeshUtils.purifyMesh(mesh)
+ mesh.createGroupsFromStringMeshData("physical_names")
+
+ model = akantu.SolidMechanicsModel(mesh)
+ model.initFull(akantu.SolidMechanicsModelOptions(akantu._static))
+ model.assembleStiffnessMatrix()
+ model.updateResidual()
+
+ model.setBaseName("plate")
+ model.addDumpFieldVector("displacement")
+ model.addDumpFieldVector("force")
+ model.addDumpField("boundary")
+ model.addDumpField("strain")
+ model.addDumpField("stress")
+ model.addDumpField("blocked_dofs")
+
+ ################################################################
+ ##Boundary conditions
+ ################################################################
+ displacement = model.getDisplacement()
+ blocked_dofs = model.getBlockedDOFs()
+
+ model.applyDirichletBC(FixedValue(0.0, 'x'), "XBlocked")
+ model.applyDirichletBC(FixedValue(0.0, 'y'), "YBlocked")
+
+ trac = np.zeros(spatial_dimension)
+ trac[1] = traction
+
+ print "Solve for traction ",traction
+
+ model.getForce()[:] = 0
+ model.applyNeumannBC(FromTraction(trac), "Traction")
+
+ model.solveStaticDisplacement(1e-10,2);
+
+ model.dump()
+ akantu.finalize()
+
+################################################################
+# main
+################################################################
+
+def main():
+
+ import os
+ mesh_file = 'plate.msh'
+ #if mesh was not created the calls gmsh to generate it
+ if not os.path.isfile(mesh_file):
+ import subprocess
+ ret = subprocess.call('gmsh -2 plate.geo {0}'.format(mesh_file),shell=True)
+ if not ret == 0:
+ raise Exception('execution of GMSH failed: do you have it installed ?')
+
+
+ material_file = 'material.dat'
+ spatial_dimension = 2
+
+ traction = 1.
+ solve(material_file,mesh_file,traction)
+
+################################################################
+if __name__ == "__main__":
+ main()
+
diff --git a/examples/static/CMakeLists.txt b/examples/static/CMakeLists.txt
index 5f1c6bf35..6960f3cf2 100644
--- a/examples/static/CMakeLists.txt
+++ b/examples/static/CMakeLists.txt
@@ -1,44 +1,40 @@
#===============================================================================
# @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: Mon Jan 18 2016
+# @date last modification: Tue Jan 19 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
+register_example(static
+ SOURCES static.cc
+ DEPENDS static_mesh
+ FILES_TO_COPY material.dat
)
-
diff --git a/examples/static/static.cc b/examples/static/static.cc
index 36999592b..4b12630ed 100644
--- a/examples/static/static.cc
+++ b/examples/static/static.cc
@@ -1,80 +1,81 @@
/**
* @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: Mon Jan 18 2016
*
* @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[]) {
+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("force");
model.addDumpField("residual");
- model.addDumpField("grad_u" );
+ 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);
+ bool converged =
+ model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(
+ 1e-4, 2);
- if(!converged)
+ 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..6b33cfb9b 100644
--- a/examples/structural_mechanics/CMakeLists.txt
+++ b/examples/structural_mechanics/CMakeLists.txt
@@ -1,40 +1,37 @@
#===============================================================================
# @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: Mon Jan 18 2016
+# @date last modification: Tue Jan 19 2016
#
# @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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
+ SOURCES bernoulli_beam_2_exemple.cc
+ )
diff --git a/examples/structural_mechanics/bernoulli_beam_2_exemple.cc b/examples/structural_mechanics/bernoulli_beam_2_exemple.cc
index c46275f87..6d0dbd97a 100644
--- a/examples/structural_mechanics/bernoulli_beam_2_exemple.cc
+++ b/examples/structural_mechanics/bernoulli_beam_2_exemple.cc
@@ -1,184 +1,165 @@
/**
* @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: Mon Jan 18 2016
*
* @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"
+/* -------------------------------------------------------------------------- */
+#include <iostream>
/* -------------------------------------------------------------------------- */
#define TYPE _bernoulli_beam_2
using namespace akantu;
-//Linear load function
+// 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;
- }
+ __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[]){
+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;
+ 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));
+ 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; ++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_nodes_1; ++i) {
+ nodes(i, 0) = 10. * i / ((Real)nb_nodes_1);
+ }
+ nodes(nb_nodes_1, 0) = 10;
- for(UInt i=0; i<nb_element; ++i) {
+ for (UInt i = 0; i < nb_nodes_2; ++i) {
+ nodes(nb_nodes_1 + i + 1, 0) = 10 + 8. * (i + 1) / ((Real)nb_nodes_2);
+ }
- connectivity(i,0)=i;
- connectivity(i,1)=i+1;
+ 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;
+ 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;
+ 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);
+ 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;
+ element_material(i + nb_nodes_1) = 1;
}
-
- forces(nb_nodes-1,2) += M;
+ 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;
- 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;
+ 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;
+ 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/extra_packages/contact-alejandro b/extra_packages/contact-alejandro
new file mode 160000
index 000000000..821523eb4
--- /dev/null
+++ b/extra_packages/contact-alejandro
@@ -0,0 +1 @@
+Subproject commit 821523eb4ade034d82de6b581ded46483abbfda1
diff --git a/extra_packages/extra-materials b/extra_packages/extra-materials
index dea972981..413cd3016 160000
--- a/extra_packages/extra-materials
+++ b/extra_packages/extra-materials
@@ -1 +1 @@
-Subproject commit dea9729814e7967a4088ac100749be7f3e0ca6cd
+Subproject commit 413cd301657897dbf57f36e0250da810fd81eb7a
diff --git a/extra_packages/igfem b/extra_packages/igfem
index 078a747c6..fcacdece3 160000
--- a/extra_packages/igfem
+++ b/extra_packages/igfem
@@ -1 +1 @@
-Subproject commit 078a747c6f453ab4e35def4a195d98ec34d7a57b
+Subproject commit fcacdece31fc1c406208b3780b50b623939e8656
diff --git a/extra_packages/traction-at-split-node-contact b/extra_packages/traction-at-split-node-contact
deleted file mode 160000
index 95926b0cf..000000000
--- a/extra_packages/traction-at-split-node-contact
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 95926b0cfda429a6c2adde41924aa2081892a7ad
diff --git a/extra_packages/traction-at-split-node-contact/README.txt b/extra_packages/traction-at-split-node-contact/README.txt
new file mode 100644
index 000000000..42ca5e02e
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/README.txt
@@ -0,0 +1,5 @@
+Short explanation for AkantuSimTools:
+
+Using ccmake for compilation, give the path to the build folder of akantu. By putting build_shared_libs on, the library is dynamic. Give a cmake_install_prefix (e.g., ./install).
+
+When compiling use: make install (don't forget to create the folder in which you install)
diff --git a/extra_packages/traction-at-split-node-contact/package.cmake b/extra_packages/traction-at-split-node-contact/package.cmake
new file mode 100644
index 000000000..681a7c7d4
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/package.cmake
@@ -0,0 +1,96 @@
+#===============================================================================
+# @file package.cmake
+#
+# @author David Simon Kammer <david.kammer@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Tue Dec 02 2014
+# @date last modification: Fri Jan 22 2016
+#
+# @brief package declaration
+#
+# @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/>.
+#
+#===============================================================================
+
+package_declare(traction-at-split-node-contact
+ DESCRIPTION "The super contact of David"
+ DEPENDS iohelper)
+
+package_declare_sources(traction-at-split-node-contact
+ common/synchronized_array.cc
+ common/parameter_reader.cc
+ common/manual_restart.cc
+ functions/boundary_functions.cc
+ ntn_contact/ntn_base_contact.cc
+ ntn_contact/ntn_contact.cc
+ ntn_contact/ntrf_contact.cc
+ ntn_contact/mIIasym_contact.cc
+ ntn_contact/ntn_base_friction.cc
+ ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.cc
+ ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.cc
+ ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.cc
+ ntn_contact/ntn_initiation_function.cc
+
+ tasn_contact.hh
+
+ # headers
+ common/synchronized_array.hh
+ common/parameter_reader.hh
+ common/manual_restart.hh
+
+ functions/boundary_functions.hh
+ functions/node_filter.hh
+
+ boundary_conditions/force_based_dirichlet.hh
+ boundary_conditions/spring_bc.hh
+ boundary_conditions/inclined_flat_dirichlet.hh
+
+ ntn_contact/ntn_base_contact.hh
+ ntn_contact/ntn_contact.hh
+ ntn_contact/ntrf_contact.hh
+ ntn_contact/mIIasym_contact.hh
+ ntn_contact/ntn_base_friction.hh
+
+ ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh
+ ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh
+ ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh
+
+ ntn_contact/friction_laws/ntn_friclaw_coulomb.hh
+ ntn_contact/friction_laws/ntn_friclaw_coulomb_tmpl.hh
+ ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh
+ ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_tmpl.hh
+ ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh
+ ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh
+ ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh
+ ntn_contact/friction_laws/ntn_friclaw_linear_cohesive_tmpl.hh
+
+ ntn_contact/ntn_friction.hh
+ ntn_contact/ntn_friction_tmpl.hh
+ ntn_contact/ntrf_friction.hh
+ ntn_contact/ntrf_friction_tmpl.hh
+
+ ntn_contact/ntn_initiation_function.hh
+
+ # inlines
+ common/synchronized_array_inline_impl.cc
+ ntn_contact/ntn_base_contact_inline_impl.cc
+ )
+
+
diff --git a/extra_packages/traction-at-split-node-contact/src/boundary_conditions/force_based_dirichlet.hh b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/force_based_dirichlet.hh
new file mode 100644
index 000000000..6ebfe4950
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/force_based_dirichlet.hh
@@ -0,0 +1,137 @@
+/**
+ * @file force_based_dirichlet.hh
+ *
+ * @author Dana Christen <dana.christen@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief dirichlet boundary condition that tries
+ * to keep the force at a given value
+ *
+ * @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 __AST_FORCE_BASED_DIRICHLET_HH__
+#define __AST_FORCE_BASED_DIRICHLET_HH__
+
+// akantu
+#include "aka_common.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class ForceBasedDirichlet : public BC::Dirichlet::IncrementValue {
+
+protected:
+ typedef const Array<Real> * RealArrayPtr;
+ typedef const Array<Int> * IntArrayPtr;
+
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+ ForceBasedDirichlet(SolidMechanicsModel & model,
+ BC::Axis ax,
+ Real target_f,
+ Real mass = 0.) :
+ IncrementValue(0., ax),
+ model(model),
+ mass(mass),
+ velocity(0.),
+ target_force(target_f),
+ total_residual(0.)
+ {}
+
+ virtual ~ForceBasedDirichlet() {}
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ void updateTotalResidual() {
+ SubBoundarySet::iterator it = this->subboundaries.begin();
+ SubBoundarySet::iterator end = this->subboundaries.end();
+ this->total_residual = 0.;
+ for (; it != end; ++it) {
+ this->total_residual += integrateResidual(*it, this->model, this->axis);
+ }
+ }
+
+ virtual Real update() {
+ AKANTU_DEBUG_IN();
+
+ this->updateTotalResidual();
+ Real total_force = this->target_force + this->total_residual;
+
+ Real a = total_force / this->mass;
+ Real dt = model.getTimeStep();
+ this->velocity += 0.5*dt*a;
+ this->value = this->velocity*dt + 0.5*dt*dt*a; // increment position dx
+ this->velocity += 0.5*dt*a;
+
+ AKANTU_DEBUG_OUT();
+ return this->total_residual;
+ }
+
+ Real applyYourself() {
+ AKANTU_DEBUG_IN();
+ Real reaction = this->update();
+
+ SubBoundarySet::iterator it = this->subboundaries.begin();
+ SubBoundarySet::iterator end = this->subboundaries.end();
+ for (; it != end; ++it) {
+ this->model.applyBC(*this,*it);
+ }
+
+ AKANTU_DEBUG_OUT();
+ return reaction;
+ }
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+ AKANTU_SET_MACRO(Mass, mass, Real);
+ AKANTU_SET_MACRO(TargetForce, target_force, Real);
+
+ void insertSubBoundary(const std::string & sb_name) {
+ this->subboundaries.insert(sb_name);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+ typedef std::set<std::string> SubBoundarySet;
+protected:
+ SolidMechanicsModel & model;
+ SubBoundarySet subboundaries;
+
+ Real mass;
+ Real velocity;
+ Real target_force;
+ Real total_residual;
+};
+
+__END_AKANTU__
+
+#endif /* __AST_FORCE_BASED_DIRICHLET_HH__ */
diff --git a/src/io/model_io.hh b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh
similarity index 58%
copy from src/io/model_io.hh
copy to extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh
index f95d02142..fe4298a23 100644
--- a/src/io/model_io.hh
+++ b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh
@@ -1,81 +1,89 @@
/**
- * @file model_io.hh
+ * @file inclined_flat_dirichlet.hh
*
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Thu Feb 21 2013
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief
+ * @brief inclined dirichlet
*
* @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_MODEL_IO_HH__
-#define __AKANTU_MODEL_IO_HH__
-
/* -------------------------------------------------------------------------- */
+#ifndef __AST_INCLINED_FLAT_DIRICHLET_HH__
+#define __AST_INCLINED_FLAT_DIRICHLET_HH__
+
+// akantu
#include "aka_common.hh"
-#include "mesh.hh"
-#include "model.hh"
-/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
-
-
-
-
-class ModelIO {
+/* -------------------------------------------------------------------------- */
+class InclinedFlatDirichlet : public BC::Dirichlet::DirichletFunctor {
+
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- ModelIO();
- virtual ~ModelIO();
-
+ InclinedFlatDirichlet(Real val,
+ BC::Axis ax,
+ BC::Axis incl_ax,
+ Real center_coord,
+ Real tang) :
+ DirichletFunctor(ax),
+ value(val),
+ incl_ax(incl_ax),
+ center_coord(center_coord),
+ tang(tang) {};
+
+ virtual ~InclinedFlatDirichlet() {}
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
- /// read a model from file
- virtual void read(const std::string & filename, Model & model) = 0;
+ inline void operator()(UInt node,
+ Vector<bool> & flags,
+ Vector<Real> & primal,
+ const Vector<Real> & coord) const {
+ AKANTU_DEBUG_IN();
- /// write a mesh to a file
- virtual void write(const std::string & filename, const Model & model) = 0;
+ Real dist = coord(incl_ax) - this->center_coord;
+ flags(axis) = true;
+ primal(axis) = this->value + this->tang * dist;
+
+ AKANTU_DEBUG_OUT();
+ }
-
- /* ------------------------------------------------------------------------ */
- /* Accessors */
- /* ------------------------------------------------------------------------ */
-public:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-private:
-
+protected:
+ Real value;
+ BC::Axis incl_ax;
+ Real center_coord;
+ Real tang;
};
__END_AKANTU__
-#endif /* __AKANTU_MODEL_IO_HH__ */
+#endif /* __AST_INCLINED_FLAT_DIRICHLET_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/boundary_conditions/spring_bc.hh b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/spring_bc.hh
new file mode 100644
index 000000000..fe6faf281
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/spring_bc.hh
@@ -0,0 +1,152 @@
+/**
+ * @file spring_bc.hh
+ *
+ * @author Dana Christen <dana.christen@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief spring boundary condition
+ *
+ * @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 __AST_SPRING_BC_HH__
+#define __AST_SPRING_BC_HH__
+
+// simtools
+#include "force_based_dirichlet.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class SpringBC : public ForceBasedDirichlet {
+
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+ SpringBC(SolidMechanicsModel & model,
+ BC::Axis ax,
+ Real stiffness,
+ Real mass = 0.) :
+ ForceBasedDirichlet(model, ax, 0., mass),
+ stiffness(stiffness),
+ elongation(0.)
+ {}
+
+ virtual ~SpringBC() {}
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual Real update() {
+ AKANTU_DEBUG_IN();
+
+ this->target_force = - this->stiffness * this->elongation;
+ Real reaction = ForceBasedDirichlet::update();
+ this->elongation += this->value;
+
+ AKANTU_DEBUG_OUT();
+ return reaction;
+ }
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+ AKANTU_GET_MACRO(Elongation, elongation, Real);
+
+ inline void setToEquilibrium() {
+ AKANTU_DEBUG_IN();
+
+ this->updateTotalResidual();
+
+ this->target_force = - this->total_residual;
+ this->elongation = - this->target_force / this->stiffness;
+
+ AKANTU_DEBUG_OUT();
+ }
+
+ /// change elongation
+ /// dx > 0 -> target_force < 0
+ inline void incrementElongation(Real dx) {
+ AKANTU_DEBUG_IN();
+
+ this->elongation += dx;
+
+ AKANTU_DEBUG_OUT();
+ }
+ //friend std::ostream& operator<<(std::ostream& out, const SpringBC & spring);
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ Real stiffness;
+ Real elongation;
+};
+
+
+
+
+
+
+
+
+
+
+// class SpringBCRestricted : public SpringBC {
+// public:
+// SpringBCRestricted(BC::Axis ax, Real target_force, BC::Axis surface_axis, Real min, Real max)
+// :SpringBC(ax, target_force), surface_axis(surface_axis), min(min), max(max) {}
+
+// virtual ~SpringBCRestricted() {}
+
+// public:
+// inline void operator()(UInt node, Vector<bool> & flags, Vector<Real> & primal, const Vector<Real> & coord) const {
+// if(coord(surface_axis) > min && coord(surface_axis) < max) {
+// SpringBC::operator()(node, flags, primal, coord);
+// }
+// }
+// private:
+// BC::Axis surface_axis;
+// Real min;
+// Real max;
+// };
+
+// std::ostream& operator<<(std::ostream& out, const SpringBC & spring) {
+// out << "Real total_residual: " << *spring.total_residual << std::endl;
+// out << "Real mass: " << spring.mass << std::endl;
+// out << "Real k: " << spring.k << std::endl;
+// out << "Real delta_x: " << spring.delta_x << std::endl;
+// out << "Real dt: " << spring.dt << std::endl;
+// out << "Real v: " << spring.v << std::endl;
+// out << "Real dx: " << spring.dx << std::endl;
+// out << "Real forcing_vel: " << spring.forcing_vel << std::endl;
+// return out;
+// }
+
+
+__END_AKANTU__
+
+#endif /* __AST_SPRING_BC_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/common/manual_restart.cc b/extra_packages/traction-at-split-node-contact/src/common/manual_restart.cc
new file mode 100644
index 000000000..b59325754
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/common/manual_restart.cc
@@ -0,0 +1,142 @@
+/**
+ * @file manual_restart.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 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/>.
+ *
+ */
+
+/**
+ * @file manual_restart.cc
+ * @author Dana Christen <dana.christen@epfl.ch>
+ * @date May 15, 2013
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "manual_restart.hh"
+
+//#include <iostream>
+#include <fstream>
+
+using namespace akantu;
+
+void dumpArray(const Array<Real> & array, const std::string & fname) {
+ std::ofstream outFile;
+ outFile.open(fname.c_str());
+ outFile.precision(9);
+ outFile.setf(std::ios::scientific);
+ UInt size = array.getSize();
+ UInt nb_component = array.getNbComponent();
+ outFile << size << std::endl;
+ outFile << nb_component << std::endl;
+ Array<Real>::const_iterator< Vector<Real> > tit = array.begin(nb_component);
+ Array<Real>::const_iterator< Vector<Real> > tend = array.end(nb_component);
+ for(; tit != tend; ++tit) {
+ for (UInt c=0; c<nb_component; ++c) {
+ if (c != 0)
+ outFile << " ";
+ outFile << (*tit)(c);
+ }
+ outFile << std::endl;
+ }
+ outFile.close();
+}
+
+void loadArray(Array<Real> & array, const std::string & fname) {
+ std::ifstream inFile;
+ inFile.open(fname.c_str());
+ inFile.precision(9);
+ inFile.setf(std::ios::scientific);
+ UInt size(0), nb_comp(0);
+ inFile >> size;
+ inFile >> nb_comp;
+ AKANTU_DEBUG_ASSERT(array.getNbComponent() == nb_comp, "BAD NUM OF COMPONENTS");
+ AKANTU_DEBUG_ASSERT(array.getSize() == size, "loadArray: number of data points in file ("
+ << size << ") does not correspond to array size (" << array.getSize()
+ << ")!!");
+ Array<Real>::iterator< Vector<Real> > tit = array.begin(nb_comp);
+ Array<Real>::iterator< Vector<Real> > tend = array.end(nb_comp);
+ array.resize(size);
+ for(UInt i(0); i < size; ++i, ++tit) {
+ for (UInt c=0; c < nb_comp; ++c) {
+ inFile >> (*tit)(c);
+ }
+ }
+ inFile.close();
+}
+
+/* -------------------------------------------------------------------------- */
+void loadRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname,
+ akantu::UInt prank) {
+
+ const akantu::Mesh & mesh = model.getMesh();
+ const akantu::UInt spatial_dimension = model.getMesh().getSpatialDimension();
+
+ const_cast<DOFSynchronizer &>(model.getDOFSynchronizer()).initScatterGatherCommunicationScheme();
+
+ if(prank == 0) {
+ akantu::Array<akantu::Real> full_reload_array(mesh.getNbGlobalNodes(),
+ spatial_dimension);
+ loadArray(full_reload_array, fname);
+ model.getDOFSynchronizer().scatter(model.getDisplacement(), 0, &full_reload_array);
+ } else {
+ model.getDOFSynchronizer().scatter(model.getDisplacement(), 0);
+ }
+
+
+}
+
+/* -------------------------------------------------------------------------- */
+void loadRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname) {
+ loadArray(model.getDisplacement(), fname);
+}
+
+/* -------------------------------------------------------------------------- */
+void dumpRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname,
+ akantu::UInt prank) {
+
+ const akantu::Mesh & mesh = model.getMesh();
+ const akantu::UInt spatial_dimension = model.getMesh().getSpatialDimension();
+
+ const_cast<DOFSynchronizer &>(model.getDOFSynchronizer()).initScatterGatherCommunicationScheme();
+
+ if(prank == 0) {
+ akantu::Array<akantu::Real> full_array(mesh.getNbGlobalNodes(),
+ spatial_dimension);
+ model.getDOFSynchronizer().gather(model.getDisplacement(), 0, &full_array);
+ dumpArray(full_array, fname);
+ } else {
+ model.getDOFSynchronizer().gather(model.getDisplacement(), 0);
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void dumpRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname) {
+ dumpArray(model.getDisplacement(), fname);
+}
diff --git a/extra_packages/traction-at-split-node-contact/src/common/manual_restart.hh b/extra_packages/traction-at-split-node-contact/src/common/manual_restart.hh
new file mode 100644
index 000000000..ca44437d8
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/common/manual_restart.hh
@@ -0,0 +1,53 @@
+/**
+ * @file manual_restart.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 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/>.
+ *
+ */
+
+/**
+ * @file manual_restart.hh
+ * @author Dana Christen <dana.christen@epfl.ch>
+ * @date May 15, 2013
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "aka_array.hh"
+#include "solid_mechanics_model.hh"
+
+void dumpArray(const akantu::Array<akantu::Real> & array, const std::string & fname);
+
+void loadArray(akantu::Array<akantu::Real> & array, const std::string & fname);
+void loadRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname,
+ akantu::UInt prank);
+void loadRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname);
+void dumpRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname,
+ akantu::UInt prank);
+void dumpRestart(akantu::SolidMechanicsModel & model,
+ const std::string & fname);
diff --git a/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.cc b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.cc
new file mode 100644
index 000000000..09d3dc36a
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.cc
@@ -0,0 +1,462 @@
+/**
+ * @file parameter_reader.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of parameter reader
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// std
+#include <iostream>
+#include <fstream>
+#include <utility>
+#include <algorithm>
+
+// simtools
+#include "parameter_reader.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+ParameterReader::ParameterReader() :
+ data_types(),
+ element_type_data(),
+ string_data(),
+ int_data(),
+ uint_data(),
+ real_data(),
+ bool_data()
+{
+ AKANTU_DEBUG_IN();
+
+ // setup of types of element
+ data_types.insert("elementtype");
+ data_types.insert("string");
+ data_types.insert("uint");
+ data_types.insert("int");
+ data_types.insert("real");
+ data_types.insert("bool");
+ // data_types.insert("surface");
+
+ // define conversion maps
+ _input_to_akantu_element_types["_segment_2"] = akantu::_segment_2;
+ _input_to_akantu_element_types["_segment_3"] = akantu::_segment_3;
+ _input_to_akantu_element_types["_triangle_3"] = akantu::_triangle_3;
+ _input_to_akantu_element_types["_triangle_6"] = akantu::_triangle_6;
+ _input_to_akantu_element_types["_tetrahedron_4"] = akantu::_tetrahedron_4;
+ _input_to_akantu_element_types["_tetrahedron_10"] = akantu::_tetrahedron_10;
+ _input_to_akantu_element_types["_quadrangle_4"] = akantu::_quadrangle_4;
+ _input_to_akantu_element_types["_quadrangle_8"] = akantu::_quadrangle_8;
+ _input_to_akantu_element_types["_hexahedron_8"] = akantu::_hexahedron_8;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void ParameterReader::readInputFile(std::string file_name) {
+ AKANTU_DEBUG_IN();
+
+ char comment_char = '#';
+ char equal_char = '=';
+
+ // open a file called file name
+ std::ifstream infile;
+ infile.open(file_name.c_str());
+
+ if(!infile.good()) {
+ std::cerr << "Cannot open file " << file_name << "!!!" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ std::string line;
+ std::string clean_line;
+ while(infile.good()) {
+ getline(infile, line);
+ clean_line = line;
+
+ // take out comments
+ size_t found_comment;
+ found_comment = line.find_first_of(comment_char);
+ if (found_comment != std::string::npos)
+ clean_line = line.substr(0,found_comment);
+ if (clean_line.empty())
+ continue;
+
+ std::stringstream sstr(clean_line);
+
+ // check if data type exists
+ std::string type;
+ sstr >> type;
+ std::transform(type.begin(),type.end(),type.begin(),::tolower);
+ if (this->data_types.find(type) == this->data_types.end()) {
+ std::cerr << " *** WARNING *** Data type " << type << " does not exist"
+ << " in this input data structure. Ignore line: ";
+ std::cerr << clean_line << std::endl;
+ continue;
+ }
+
+ std::string keyword;
+ std::string equal;
+ std::string value;
+
+ // get keyword
+ sstr >> keyword;
+ size_t equal_p = keyword.find_first_of(equal_char);
+ if (equal_p != std::string::npos) {
+ equal = keyword.substr(equal_p,std::string::npos);
+ keyword = keyword.substr(0,equal_p);
+ }
+
+ // get equal
+ if (equal.empty())
+ sstr >> equal;
+ if (equal.length() != 1) {
+ value = equal.substr(1,std::string::npos);
+ equal = equal[0];
+ }
+ if (equal[0] != equal_char) {
+ std::cerr << " *** WARNING *** Unrespected convention! Ignore line: ";
+ std::cerr << clean_line << std::endl;
+ continue;
+ }
+
+ // get value
+ if (value.empty())
+ sstr >> value;
+
+ // no value
+ if (value.empty()) {
+ std::cerr << " *** WARNING *** No value given! Ignore line: ";
+ std::cerr << clean_line << std::endl;
+ continue;
+ }
+
+ // put value in map
+ std::stringstream convert(value);
+ if (type.compare("elementtype") == 0) {
+ std::map<std::string, akantu::ElementType>::const_iterator it;
+ it = this->_input_to_akantu_element_types.find(value);
+ if (it != this->_input_to_akantu_element_types.end())
+ this->element_type_data.insert(std::make_pair(keyword,it->second));
+ else {
+ std::cerr << " *** WARNING *** ElementType " << value << " does not exist. Ignore line: ";
+ std::cerr << clean_line << std::endl;
+ continue;
+ }
+ }
+ else if (type.compare("string") == 0) {
+ this->string_data.insert(std::make_pair(keyword,value));
+ }
+ /*
+ else if (type.compare("surface") == 0) {
+ //Surface surf;
+ UInt surf;
+ convert >> surf;
+ //this->surface_data.insert(std::make_pair(keyword,surf));
+ this->uint_data.insert(std::make_pair(keyword,surf));
+ }
+ */
+ else if (type.compare("int") == 0) {
+ Int i;
+ convert >> i;
+ this->int_data.insert(std::make_pair(keyword,i));
+ }
+ else if (type.compare("uint") == 0) {
+ UInt i;
+ convert >> i;
+ this->uint_data.insert(std::make_pair(keyword,i));
+ }
+ else if (type.compare("real") == 0) {
+ Real r;
+ convert >> r;
+ this->real_data.insert(std::make_pair(keyword,r));
+ }
+ else if (type.compare("bool") == 0) {
+ std::transform(value.begin(),value.end(),value.begin(),::tolower);
+ bool b;
+ if (value.compare("true") == 0)
+ b = true;
+ else if (value.compare("false") == 0)
+ b = false;
+ else {
+ std::cerr << " *** WARNING *** boolean cannot be " << value << ". Ignore line: ";
+ std::cerr << clean_line << std::endl;
+ continue;
+ }
+ this->bool_data.insert(std::make_pair(keyword,b));
+ }
+ else {
+ std::cerr << " *** ERROR *** Could not add data to InputData for line: ";
+ std::cerr << clean_line << std::endl;
+ continue;
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void ParameterReader::writeInputFile(std::string file_name) const {
+ AKANTU_DEBUG_IN();
+
+ // open file to write input information
+ std::ofstream outfile;
+ outfile.open(file_name.c_str());
+
+ // element type
+ for (std::map<std::string, akantu::ElementType>::const_iterator it = element_type_data.begin();
+ it != element_type_data.end(); ++it) {
+ for (std::map<std::string, ElementType>::const_iterator et = _input_to_akantu_element_types.begin();
+ et != _input_to_akantu_element_types.end(); ++et) {
+ if (it->second == et->second) {
+ outfile << "ElementType " << it->first << " = " << et->first << std::endl;
+ continue;
+ }
+ }
+ }
+
+ // string
+ for (std::map<std::string, std::string>::const_iterator it = string_data.begin();
+ it != string_data.end(); ++it)
+ outfile << "string " << it->first << " = " << it->second << std::endl;
+
+ // Surface
+ /*
+ for (std::map<std::string, akantu::Surface>::const_iterator it = surface_data.begin();
+ it != surface_data.end(); ++it)
+ outfile << "Surface " << it->first << " = " << it->second << std::endl;
+ */
+ // Int
+ for (std::map<std::string, akantu::Int>::const_iterator it = int_data.begin();
+ it != int_data.end(); ++it)
+ outfile << "Int " << it->first << " = " << it->second << std::endl;
+
+ // UInt
+ for (std::map<std::string, akantu::UInt>::const_iterator it = uint_data.begin();
+ it != uint_data.end(); ++it)
+ outfile << "UInt " << it->first << " = " << it->second << std::endl;
+
+ // Real
+ for (std::map<std::string, akantu::Real>::const_iterator it = real_data.begin();
+ it != real_data.end(); ++it)
+ outfile << "Real " << it->first << " = " << it->second << std::endl;
+
+ // Bool
+ for (std::map<std::string, bool>::const_iterator it = bool_data.begin();
+ it != bool_data.end(); ++it) {
+ std::string b = "false";
+ if (it->second)
+ b = "true";
+ outfile << "bool " << it->first << " = " << b << std::endl;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
+akantu::UInt ParameterReader::get<akantu::UInt>(std::string key) const {
+ std::map<std::string,akantu::UInt>::const_iterator it;
+ it = this->uint_data.find(key);
+
+ // if not in map
+ if (it == this->uint_data.end()) {
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
+ std::cerr << "UInt " << key << " = ???" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ else
+ return it->second;
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
+akantu::ElementType ParameterReader::get<akantu::ElementType>(std::string key) const {
+ std::map<std::string,akantu::ElementType>::const_iterator it;
+ it = this->element_type_data.find(key);
+
+ // if not in map
+ if (it == this->element_type_data.end()) {
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
+ std::cerr << "ElementType " << key << " = ???" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ else
+ return it->second;
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
+std::string ParameterReader::get<std::string>(std::string key) const {
+ std::map<std::string,std::string>::const_iterator it;
+ it = this->string_data.find(key);
+
+ // if not in map
+ if (it == this->string_data.end()) {
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
+ std::cerr << "string " << key << " = ???" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ else
+ return it->second;
+}
+
+/* -------------------------------------------------------------------------- */
+/*
+template<>
+akantu::Surface ParameterData::get<akantu::Surface>(std::string key) const {
+ std::map<std::string,akantu::Surface>::const_iterator it;
+ it = this->surface_data.find(key);
+
+ // if not in map
+ if (it == this->surface_data.end()) {
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
+ std::cerr << "Surface " << key << " = ???" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ else
+ return it->second;
+}
+*/
+
+/* -------------------------------------------------------------------------- */
+template<>
+akantu::Int ParameterReader::get<akantu::Int>(std::string key) const {
+ std::map<std::string,akantu::Int>::const_iterator it;
+ it = this->int_data.find(key);
+
+ // if not in map
+ if (it == this->int_data.end()) {
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
+ std::cerr << "Int " << key << " = ???" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ else
+ return it->second;
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
+akantu::Real ParameterReader::get<akantu::Real>(std::string key) const {
+ std::map<std::string,akantu::Real>::const_iterator it;
+ it = this->real_data.find(key);
+
+ // if not in map
+ if (it == this->real_data.end()) {
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
+ std::cerr << "Real " << key << " = ???" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ else
+ return it->second;
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
+bool ParameterReader::get<bool>(std::string key) const {
+ std::map<std::string,bool>::const_iterator it;
+ it = this->bool_data.find(key);
+
+ // if not in map
+ if (it == this->bool_data.end()) {
+ std::cerr << " *** ERROR *** This data was not in input file. "
+ << "You need the following line in your input file: ";
+ std::cerr << "bool " << key << " = ???" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+
+ else
+ return it->second;
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
+bool ParameterReader::has<bool>(std::string key) const {
+ std::map<std::string,bool>::const_iterator it;
+ it = this->bool_data.find(key);
+ return (it != this->bool_data.end());
+}
+template<>
+bool ParameterReader::has<std::string>(std::string key) const {
+ std::map<std::string,std::string>::const_iterator it;
+ it = this->string_data.find(key);
+ return (it != this->string_data.end());
+}
+template<>
+bool ParameterReader::has<akantu::Int>(std::string key) const {
+ std::map<std::string,akantu::Int>::const_iterator it;
+ it = this->int_data.find(key);
+ return (it != this->int_data.end());
+}
+template<>
+bool ParameterReader::has<akantu::UInt>(std::string key) const {
+ std::map<std::string,akantu::UInt>::const_iterator it;
+ it = this->uint_data.find(key);
+ return (it != this->uint_data.end());
+}
+template<>
+bool ParameterReader::has<akantu::Real>(std::string key) const {
+ std::map<std::string,akantu::Real>::const_iterator it;
+ it = this->real_data.find(key);
+ return (it != this->real_data.end());
+}
+
+/* -------------------------------------------------------------------------- */
+void ParameterReader::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "ParameterReader [" << std::endl;
+ /*
+ stream << space << this->element_type_data << std::endl;
+ stream << space << this->string_data << std::endl;
+ stream << space << this->surface_data << std::endl;
+ stream << space << this->int_data << std::endl;
+ stream << space << this->uint_data << std::endl;
+ stream << space << this->real_data << std::endl;
+ stream << space << this->bool_data << std::endl;
+ */
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/src/synchronizer/synchronizer_registry.hh b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh
similarity index 60%
copy from src/synchronizer/synchronizer_registry.hh
copy to extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh
index 5e7e09617..2528756be 100644
--- a/src/synchronizer/synchronizer_registry.hh
+++ b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh
@@ -1,115 +1,114 @@
/**
- * @file synchronizer_registry.hh
+ * @file parameter_reader.hh
*
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief Registry of synchronizers
+ * @brief for simulations to read parameters from an input 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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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__
+#ifndef __AST_PARAMETER_READER_HH__
+#define __AST_PARAMETER_READER_HH__
/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "data_accessor.hh"
-#include "synchronizer.hh"
-/* -------------------------------------------------------------------------- */
+// std
+#include <set>
+#include <map>
+// akantu
+#include "aka_common.hh"
__BEGIN_AKANTU__
-class SynchronizerRegistry {
+/* -------------------------------------------------------------------------- */
+class ParameterReader {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- SynchronizerRegistry(DataAccessor & data_accessor);
- virtual ~SynchronizerRegistry();
-
+
+ ParameterReader();
+ virtual ~ParameterReader() {};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
+ /// read input file
+ void readInputFile(std::string file_name);
- /// 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);
+ /// write input file
+ void writeInputFile(std::string file_name) const;
- /// function to print the containt of the class
+ /// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
+ ///
+ template<typename T>
+ T get(std::string key) const;
+ template<typename T>
+ bool has(std::string key) const;
+
/* ------------------------------------------------------------------------ */
/* 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;
+ /// type of data available
+ std::set<std::string> data_types;
+
+ /// data
+ std::map<std::string,akantu::ElementType> element_type_data;
+ std::map<std::string,std::string> string_data;
+ std::map<std::string,akantu::Int> int_data;
+ std::map<std::string,akantu::UInt> uint_data;
+ std::map<std::string,akantu::Real> real_data;
+ std::map<std::string,bool> bool_data;
+
+ /// convert string to element type
+ std::map<std::string, ElementType> _input_to_akantu_element_types;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-// #include "synchronizer_registry_inline_impl.cc"
+//#include "parameter_reader_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const SynchronizerRegistry & _this)
+inline std::ostream & operator <<(std::ostream & stream, const ParameterReader & _this)
{
_this.printself(stream);
return stream;
}
-
__END_AKANTU__
-
-
-#endif /* __AKANTU_SYNCHRONIZER_REGISTRY_HH__ */
+#endif /* __AST_PARAMETER_READER_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.cc b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.cc
new file mode 100644
index 000000000..63d452e94
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.cc
@@ -0,0 +1,237 @@
+/**
+ * @file synchronized_array.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of synchronized array function
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// std
+#include <iostream>
+#include <fstream>
+
+// simtools
+#include "synchronized_array.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template<class T>
+SynchronizedArray<T>::SynchronizedArray(UInt size,
+ UInt nb_component,
+ SynchronizedArray<T>::const_reference value,
+ const ID & id,
+ SynchronizedArray<T>::const_reference default_value,
+ const std::string restart_name) :
+ SynchronizedArrayBase(),
+ Array<T>(size, nb_component, value, id),
+ default_value(default_value),
+ restart_name(restart_name),
+ deleted_elements(0),
+ nb_added_elements(size),
+ depending_arrays(0) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<class T>
+void SynchronizedArray<T>::syncElements(SyncChoice sync_choice) {
+ AKANTU_DEBUG_IN();
+
+ if (sync_choice == _deleted) {
+ std::vector<SynchronizedArrayBase *>::iterator it;
+ for (it=depending_arrays.begin(); it != depending_arrays.end(); ++it) {
+ UInt vec_size = (*it)->syncDeletedElements(this->deleted_elements);
+ AKANTU_DEBUG_ASSERT(vec_size == this->size,
+ "Synchronized arrays do not have the same length" <<
+ "(may be a double synchronization)");
+ }
+ this->deleted_elements.clear();
+ }
+
+ else if (sync_choice == _added) {
+ std::vector<SynchronizedArrayBase *>::iterator it;
+ for (it=depending_arrays.begin(); it != depending_arrays.end(); ++it) {
+ UInt vec_size = (*it)->syncAddedElements(this->nb_added_elements);
+ AKANTU_DEBUG_ASSERT(vec_size == this->size,
+ "Synchronized arrays do not have the same length" <<
+ "(may be a double synchronization)");
+ }
+ this->nb_added_elements = 0;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<class T>
+UInt SynchronizedArray<T>::syncDeletedElements(std::vector<UInt> & del_elements) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(nb_added_elements == 0 && deleted_elements.size() == 0,
+ "Cannot sync with a SynchronizedArray if it has already been modified");
+
+ std::vector<UInt>::const_iterator it;
+ for (it = del_elements.begin(); it != del_elements.end(); ++it) {
+ erase(*it);
+ }
+ syncElements(_deleted);
+
+ AKANTU_DEBUG_OUT();
+ return this->size;
+}
+
+/* -------------------------------------------------------------------------- */
+template<class T>
+UInt SynchronizedArray<T>::syncAddedElements(UInt nb_add_elements) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(nb_added_elements == 0 && deleted_elements.size() == 0,
+ "Cannot sync with a SynchronizedArray if it has already been modified");
+
+ for (UInt i=0; i<nb_add_elements; ++i) {
+ push_back(this->default_value);
+ }
+ syncElements(_added);
+
+ AKANTU_DEBUG_OUT();
+ return this->size;
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+void SynchronizedArray<T>::registerDependingArray(SynchronizedArrayBase & array) {
+ AKANTU_DEBUG_IN();
+
+ this->depending_arrays.push_back(&array);
+ array.syncAddedElements(this->size);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+void SynchronizedArray<T>::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "SynchronizedArray<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
+ stream << space << " + default_value : " << this->default_value << std::endl;
+ stream << space << " + nb_added_elements : " << this->nb_added_elements << std::endl;
+ stream << space << " + deleted_elements : ";
+ for(std::vector<UInt>::const_iterator it = this->deleted_elements.begin();
+ it != this->deleted_elements.end();
+ ++it)
+ stream << *it << " ";
+ stream << std::endl;
+
+ stream << space << " + depending_arrays : ";
+ for (std::vector<SynchronizedArrayBase *>::const_iterator it = this->depending_arrays.begin();
+ it!=this->depending_arrays.end();
+ ++it)
+ stream << (*it)->getID() << " ";
+ stream << std::endl;
+
+ Array<T>::printself(stream, indent+1);
+
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+void SynchronizedArray<T>::dumpRestartFile(std::string file_name) const {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(nb_added_elements == 0 && deleted_elements.size() == 0,
+ "Restart File for SynchronizedArray " << this->id <<
+ " should not be dumped as it is not synchronized yet");
+
+ std::stringstream name;
+ name << file_name << "-" << this->restart_name << ".rs";
+
+ std::ofstream out_restart;
+ out_restart.open(name.str().c_str());
+
+ out_restart << this->size << " " << this->nb_component << std::endl;
+ Real size_comp = this->size * this->nb_component;
+ for (UInt i=0; i<size_comp; ++i)
+ out_restart << std::setprecision(12) << this->values[i] << " ";
+ // out_restart << std::hex << std::setprecision(12) << this->values[i] << " ";
+ out_restart << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+void SynchronizedArray<T>::readRestartFile(std::string file_name) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(nb_added_elements == 0 && deleted_elements.size() == 0,
+ "Restart File for SynchronizedArray " << this->id <<
+ " should not be read as it is not synchronized yet");
+
+ std::stringstream name;
+ name << file_name << "-" << this->restart_name << ".rs";
+ std::ifstream infile;
+ infile.open(name.str().c_str());
+
+ std::string line;
+
+ // get size and nb_component info
+ AKANTU_DEBUG_ASSERT(infile.good(), "Could not read restart file for " <<
+ "SynchronizedArray " << this->id);
+ getline(infile, line);
+ std::stringstream size_comp(line);
+ size_comp >> this->size;
+ size_comp >> this->nb_component;
+
+ // get elements in array
+ getline(infile, line);
+ std::stringstream data(line);
+ for (UInt i=0; i<this->size * this->nb_component; ++i) {
+ AKANTU_DEBUG_ASSERT(!data.eof(), "Read SynchronizedArray " << this->id <<
+ " got to the end of the file before having read all data!");
+ data >> this->values[i];
+ // data >> std::hex >> this->values[i];
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template class SynchronizedArray<Real>;
+template class SynchronizedArray<UInt>;
+template class SynchronizedArray<Int>;
+template class SynchronizedArray<bool>;
+
+__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.hh b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.hh
new file mode 100644
index 000000000..779005dc0
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array.hh
@@ -0,0 +1,204 @@
+/**
+ * @file synchronized_array.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief synchronized array: a array can be registered to another (hereafter called top) array. If an element is added to or removed from the top array, the registered array removes or adds at the same position an element. The two arrays stay therefore synchronized.
+ *
+ * @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 __AST_SYNCHRONIZED_ARRAY_HH__
+#define __AST_SYNCHRONIZED_ARRAY_HH__
+
+/* -------------------------------------------------------------------------- */
+// std
+#include <vector>
+
+// akantu
+#include "aka_array.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+enum SyncChoice {_added, _deleted};
+
+/* -------------------------------------------------------------------------- */
+class SynchronizedArrayBase {
+public:
+ SynchronizedArrayBase() {};
+ ~SynchronizedArrayBase() {};
+
+ virtual ID getID() const { return "call should be virtual"; };
+
+ virtual UInt syncDeletedElements(std::vector<UInt> & delete_el) = 0;
+ virtual UInt syncAddedElements(UInt nb_added_el) = 0;
+};
+
+/* -------------------------------------------------------------------------- */
+template<class T>
+class SynchronizedArray : public SynchronizedArrayBase, 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;
+
+ SynchronizedArray(UInt size, UInt nb_component,
+ const_reference value, const ID & id,
+ const_reference default_value,
+ const std::string restart_name);
+ virtual ~SynchronizedArray() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// push_back
+ inline void push_back(const_reference value);
+ inline void push_back(const value_type new_element[]);
+
+ /// erase
+ inline void erase(UInt i);
+ //template<typename R>
+ //inline void erase(const iterator<R> & it);
+
+ /// synchronize elements
+ void syncElements(SyncChoice sync_choice);
+
+ /// dump restart file
+ void dumpRestartFile(std::string file_name) const;
+
+ /// read restart file
+ void readRestartFile(std::string file_name);
+
+ /// register depending array
+ void registerDependingArray(SynchronizedArrayBase & array);
+
+ /// function to print the contain of the class
+ virtual void printself(std::ostream & stream, int indent = 0) const;
+
+ /// find position of element
+ Int find(const T & elem) const { return Array<T>::find(elem); };
+
+ /// set values to zero
+ inline void clear() { Array<T>::clear(); };
+ // inline void clear() { memset(values, 0, size*nb_component*sizeof(T)); };
+
+ /// set all entries of the array to the value t
+ /// @param t value to fill the array with
+ inline void set(T t) { Array<T>::set(t); }
+
+ /// set
+ template<template<typename> class C>
+ inline void set(const C<T> & vm) { Array<T>::set(vm); };
+
+ /// set all entries of the array to value t and set default value
+ inline void setAndChangeDefault(T t) {
+ this->set(t);
+ this->default_value = t;
+ }
+
+ /// copy the content of an other array
+ void copy(const SynchronizedArray<T> & vect) { Array<T>::copy(vect); };
+
+ /// give the address of the memory allocated for this array
+ T * storage() const { return Array<T>::storage(); };
+ // T * storage() const { return this->values; };
+
+ // get nb component
+ UInt getNbComponent() const { return Array<T>::getNbComponent(); };
+
+protected:
+ UInt syncDeletedElements(std::vector<UInt> & del_elements);
+ UInt syncAddedElements(UInt nb_add_elements);
+
+ /* ------------------------------------------------------------------------ */
+ /* Operators */
+ /* ------------------------------------------------------------------------ */
+public:
+ inline reference operator()(UInt i, UInt j = 0) {
+ return Array<T>::operator()(i,j);
+ }
+ inline const_reference operator()(UInt i, UInt j = 0) const {
+ return Array<T>::operator()(i,j);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+ AKANTU_SET_MACRO(DefaultValue, default_value, T);
+
+ UInt getSize() const{ return this->size; };
+
+ ID getID() const { return Array<T>::getID(); };
+
+ const Array<T> & getArray() const {
+ const Array<T> & a = *(dynamic_cast<const Array<T> *>(this));
+ return a;
+ };
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+private:
+ /// init value when new elements added
+ T default_value;
+
+ /// restart file_name
+ const std::string restart_name;
+
+ /// elements that have been deleted
+ std::vector<UInt> deleted_elements;
+
+ /// number of elements to add
+ UInt nb_added_elements;
+
+ /// pointers to arrays to be updated
+ std::vector<SynchronizedArrayBase *> depending_arrays;
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+#include "synchronized_array_inline_impl.cc"
+
+/// standard output stream operator
+template <typename T>
+inline std::ostream & operator <<(std::ostream & stream,
+ const SynchronizedArray<T> & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#endif /* __AST_SYNCHRONIZED_ARRAY_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/common/synchronized_array_inline_impl.cc b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array_inline_impl.cc
new file mode 100644
index 000000000..bc870957a
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/common/synchronized_array_inline_impl.cc
@@ -0,0 +1,85 @@
+/**
+ * @file synchronized_array_inline_impl.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief inlined methods for the synchronized array
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+template <typename T> inline void SynchronizedArray<T>::push_back(const_reference value) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(deleted_elements.size() == 0,
+ "Cannot push_back element if SynchronizedArray" <<
+ " is already modified without synchronization");
+
+ Array<T>::push_back(value);
+ this->nb_added_elements++;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T> inline void SynchronizedArray<T>::push_back(const value_type new_elem[]) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(deleted_elements.size() == 0,
+ "Cannot push_back element if SynchronizedArray" <<
+ " is already modified without synchronization");
+
+ Array<T>::push_back(new_elem);
+ this->nb_added_elements++;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T> inline void SynchronizedArray<T>::erase(UInt i) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(nb_added_elements == 0,
+ "Cannot erase element if SynchronizedArray" <<
+ " is already modified without synchronization");
+
+ for (UInt j=0; j<this->nb_component; ++j)
+ this->values[i*this->nb_component+j] = this->values[(this->size-1)*this->nb_component+j];
+ this->size--;
+
+ this->deleted_elements.push_back(i);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/*
+template<typename T>
+template<typename R>
+inline void SynchronizedArray<T>::erase(const iterator<R> & it) {
+ T * curr = it.getCurrentStorage();
+ UInt pos = (curr - values) / nb_component;
+ erase(pos);
+}
+*/
diff --git a/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc
new file mode 100644
index 000000000..d7c916262
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.cc
@@ -0,0 +1,79 @@
+/**
+ * @file boundary_functions.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 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 "boundary_functions.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+Real integrateResidual(const std::string & sub_boundary_name,
+ const SolidMechanicsModel & model,
+ UInt dir) {
+ Real int_res = 0.;
+
+ const Mesh & mesh = model.getMesh();
+ const Array<Real> & residual = model.getResidual();
+
+ // do not need try catch, as all subboundaries should be everywhere.
+ // try {
+ const ElementGroup & boundary = mesh.getElementGroup(sub_boundary_name);
+ ElementGroup::const_node_iterator nit = boundary.node_begin();
+ ElementGroup::const_node_iterator nend = boundary.node_end();
+ for (; nit != nend; ++nit) {
+ bool is_local_node = mesh.isLocalOrMasterNode(*nit);
+ if (is_local_node) {
+ int_res += residual(*nit, dir);
+ }
+ }
+ // } catch(debug::Exception e) {
+ // // AKANTU_DEBUG_ERROR("Error computing integrateResidual. Cannot get SubBoundary: "
+ // // << sub_boundary_name << " [" << e.what() << "]");
+ // }
+
+ StaticCommunicator::getStaticCommunicator().allReduce(&int_res, 1, _so_sum);
+ return int_res;
+}
+
+/* -------------------------------------------------------------------------- */
+void boundaryFix(Mesh & mesh,
+ const std::vector<std::string> & sub_boundary_names) {
+
+ std::vector<std::string>::const_iterator it = sub_boundary_names.begin();
+ std::vector<std::string>::const_iterator end = sub_boundary_names.end();
+
+ for (; it != end; ++it) {
+ if (mesh.element_group_find(*it) == mesh.element_group_end()) {
+ mesh.createElementGroup(*it,mesh.getSpatialDimension()-1); // empty element group
+ }
+ }
+}
+
+
+__END_AKANTU__
diff --git a/src/contact/scheme.hh b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh
similarity index 56%
rename from src/contact/scheme.hh
rename to extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh
index bcae584f1..72d5842f9 100644
--- a/src/contact/scheme.hh
+++ b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh
@@ -1,48 +1,46 @@
/**
- * @file scheme.hh
+ * @file boundary_functions.hh
*
- * @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 Sep 15 2014
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief contact scheme classes
+ * @brief functions for boundaries
*
* @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_SCHEME_HH__
-#define __AKANTU_SCHEME_HH__
-
+// akantu
#include "aka_common.hh"
-#include "contact_common.hh"
-#include "discretization.hh"
-#include "friction.hh"
+#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
+Real integrateResidual(const std::string & sub_boundary_name,
+ const SolidMechanicsModel & model,
+ UInt dir);
-
+/// this is a fix so that all subboundaries exist on all procs
+void boundaryFix(Mesh & mesh,
+ const std::vector<std::string> & sub_boundary_names);
__END_AKANTU__
-
-#endif /* __AKANTU_SCHEME_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/functions/node_filter.hh b/extra_packages/traction-at-split-node-contact/src/functions/node_filter.hh
new file mode 100644
index 000000000..38d65846a
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/functions/node_filter.hh
@@ -0,0 +1,121 @@
+/**
+ * @file node_filter.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief to filter nodes with functors
+ *
+ * @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 __AST_NODE_FILTER_HH__
+#define __AST_NODE_FILTER_HH__
+
+/* -------------------------------------------------------------------------- */
+// akantu
+#include "aka_common.hh"
+#include "mesh_filter.hh"
+
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class GeometryFilter : public NodeFilterFunctor {
+
+public:
+ GeometryFilter(const Mesh & mesh,
+ UInt dir,
+ Real limit) :
+ NodeFilterFunctor(),
+ mesh(mesh), dir(dir), limit(limit) {
+ this->positions = &(mesh.getNodes());
+ };
+ ~GeometryFilter() {};
+
+ bool operator() (UInt node) {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ };
+
+protected:
+ const Mesh & mesh;
+ UInt dir;
+ Real limit;
+ const Array<Real> * positions;
+};
+
+/* -------------------------------------------------------------------------- */
+class FilterPositionsGreaterThan : public GeometryFilter {
+public:
+ FilterPositionsGreaterThan(const Mesh & mesh,
+ UInt dir,
+ Real limit) : GeometryFilter(mesh, dir, limit) {};
+ ~FilterPositionsGreaterThan() {};
+
+ bool operator() (UInt node) {
+ AKANTU_DEBUG_IN();
+ bool to_filter = true;
+ if((*this->positions)(node,this->dir) > this->limit)
+ to_filter = false;
+ AKANTU_DEBUG_OUT();
+ return to_filter;
+ };
+};
+
+/* -------------------------------------------------------------------------- */
+class FilterPositionsLessThan : public GeometryFilter {
+public:
+ FilterPositionsLessThan(const Mesh & mesh,
+ UInt dir,
+ Real limit) : GeometryFilter(mesh, dir, limit) {};
+ ~FilterPositionsLessThan() {};
+
+ bool operator() (UInt node) {
+ AKANTU_DEBUG_IN();
+ bool to_filter = true;
+ if((*this->positions)(node,this->dir) < this->limit)
+ to_filter = false;
+ AKANTU_DEBUG_OUT();
+ return to_filter;
+ };
+};
+
+/* -------------------------------------------------------------------------- */
+// this filter is erase because the convention of filter has changed!!
+// filter == true -> keep node
+
+// template<class FilterType>
+// void applyNodeFilter(Array<UInt> & nodes, FilterType & filter) {
+
+// Array<UInt>::iterator<> it = nodes.begin();
+
+// for (; it != nodes.end(); ++it) {
+// if (filter(*it)) {
+// it = nodes.erase(it);
+// }
+// }
+// };
+
+__END_AKANTU__
+
+#endif /* __AST_NODE_FILTER_HH__ */
diff --git a/src/common/aka_circular_array.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh
similarity index 56%
copy from src/common/aka_circular_array.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh
index 5a94c6c9c..08ad84e41 100644
--- a/src/common/aka_circular_array.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh
@@ -1,139 +1,110 @@
/**
- * @file aka_circular_array.hh
+ * @file ntn_friclaw_coulomb.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Fri Nov 11 2011
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief class of circular array
+ * @brief coulomb friction with \mu_s = \mu_k (constant)
*
* @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_AKA_CIRCULAR_ARRAY_HH__
-#define __AKANTU_AKA_CIRCULAR_ARRAY_HH__
-
-/* -------------------------------------------------------------------------- */
-#include <typeinfo>
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "aka_array.hh"
+#ifndef __AST_NTN_FRICLAW_COULOMB_HH__
+#define __AST_NTN_FRICLAW_COULOMB_HH__
/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_fricreg_no_regularisation.hh"
__BEGIN_AKANTU__
-template<class T>
-class CircularArray : protected Array<T> {
+/* -------------------------------------------------------------------------- */
+template <class Regularisation = NTNFricRegNoRegularisation>
+class NTNFricLawCoulomb : public Regularisation {
/* ------------------------------------------------------------------------ */
/* 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();
- };
-
+
+ NTNFricLawCoulomb(NTNBaseContact * contact,
+ const FrictionID & id = "coulomb",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawCoulomb() {};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- /**
- advance start and end position by one:
- the first element is now at the end of the array
- **/
- inline void makeStep();
+ /// register synchronizedarrays for sync
+ virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
+
+ /// dump restart file
+ virtual void dumpRestart(const std::string & file_name) const;
+
+ /// read restart file
+ virtual void readRestart(const std::string & file_name);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-
-private:
+
+protected:
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength();
/* ------------------------------------------------------------------------ */
- /* Operators */
+ /* Dumpable */
/* ------------------------------------------------------------------------ */
public:
- inline reference operator()(UInt i, UInt j = 0);
- inline const_reference operator()(UInt i, UInt j = 0) const;
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* 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;
+protected:
+ // friction coefficient
+ SynchronizedArray<Real> mu;
};
-
/* -------------------------------------------------------------------------- */
/* 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)
+template <class Regularisation>
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricLawCoulomb<Regularisation> & _this)
{
_this.printself(stream);
return stream;
}
-
-
__END_AKANTU__
+#include "ntn_friclaw_coulomb_tmpl.hh"
-
-#endif /* __AKANTU_AKA_CIRCULAR_ARRAY_HH__ */
-
-
+#endif /* __AST_NTN_FRICLAW_COULOMB_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb_tmpl.hh
new file mode 100644
index 000000000..c27ef6da0
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb_tmpl.hh
@@ -0,0 +1,162 @@
+/**
+ * @file ntn_friclaw_coulomb_tmpl.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of coulomb friction
+ *
+ * @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 "dumper_nodal_field.hh"
+
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+NTNFricLawCoulomb<Regularisation>::NTNFricLawCoulomb(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ Regularisation(contact,id,memory_id),
+ mu(0,1,0.,id+":mu",0.,"mu") {
+ AKANTU_DEBUG_IN();
+
+ Regularisation::registerSynchronizedArray(this->mu);
+
+ this->registerParam("mu", this->mu, _pat_parsmod, "friction coefficient");
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawCoulomb<Regularisation>::computeFrictionalStrength() {
+ AKANTU_DEBUG_IN();
+
+ // get contact arrays
+ const SynchronizedArray<bool> & is_in_contact = this->internalGetIsInContact();
+ const SynchronizedArray<Real> & pressure = this->internalGetContactPressure();
+
+ // array to fill
+ SynchronizedArray<Real> & strength = this->internalGetFrictionalStrength();
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // node pair is NOT in contact
+ if (!is_in_contact(n))
+ strength(n) = 0.;
+
+ // node pair is in contact
+ else {
+ // compute frictional strength
+ strength(n) = this->mu(n) * pressure(n);
+ }
+ }
+
+ Regularisation::computeFrictionalStrength();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawCoulomb<Regularisation>::registerSynchronizedArray(SynchronizedArrayBase & array) {
+ AKANTU_DEBUG_IN();
+
+ this->mu.registerDependingArray(array);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawCoulomb<Regularisation>::dumpRestart(const std::string & file_name) const {
+ AKANTU_DEBUG_IN();
+
+ this->mu.dumpRestartFile(file_name);
+
+ Regularisation::dumpRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawCoulomb<Regularisation>::readRestart(const std::string & file_name) {
+ AKANTU_DEBUG_IN();
+
+ this->mu.readRestartFile(file_name);
+
+ Regularisation::readRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawCoulomb<Regularisation>::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNFricLawCoulomb [" << std::endl;
+ Regularisation::printself(stream, ++indent);
+ stream << space << "]" << std::endl;
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawCoulomb<Regularisation>::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+#ifdef AKANTU_USE_IOHELPER
+ // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
+
+ if(field_id == "mu") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->mu.getArray()));
+ }
+ /*
+ else if (field_id == "frictional_contact_pressure") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new DumperIOHelper::NodalField<Real>(this->frictional_contact_pressure.getArray()));
+ }
+ */
+ else {
+ Regularisation::addDumpFieldToDumper(dumper_name, field_id);
+ }
+
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/src/common/aka_circular_array.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh
similarity index 56%
copy from src/common/aka_circular_array.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh
index 5a94c6c9c..8ba9f8643 100644
--- a/src/common/aka_circular_array.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh
@@ -1,139 +1,116 @@
/**
- * @file aka_circular_array.hh
+ * @file ntn_friclaw_linear_cohesive.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Fri Nov 11 2011
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief class of circular array
+ * @brief linear cohesive 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_AKA_CIRCULAR_ARRAY_HH__
-#define __AKANTU_AKA_CIRCULAR_ARRAY_HH__
-
-/* -------------------------------------------------------------------------- */
-#include <typeinfo>
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "aka_array.hh"
+#ifndef __AST_NTN_FRICLAW_LINEAR_COHESIVE_HH__
+#define __AST_NTN_FRICLAW_LINEAR_COHESIVE_HH__
/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_fricreg_no_regularisation.hh"
__BEGIN_AKANTU__
-template<class T>
-class CircularArray : protected Array<T> {
+/* -------------------------------------------------------------------------- */
+template <class Regularisation = NTNFricRegNoRegularisation>
+class NTNFricLawLinearCohesive : public Regularisation {
/* ------------------------------------------------------------------------ */
/* 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();
- };
-
+
+ NTNFricLawLinearCohesive(NTNBaseContact * contact,
+ const FrictionID & id = "linear_cohesive",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawLinearCohesive() {};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- /**
- advance start and end position by one:
- the first element is now at the end of the array
- **/
- inline void makeStep();
+ /// register synchronizedarrays for sync
+ virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
+
+ /// dump restart file
+ virtual void dumpRestart(const std::string & file_name) const;
+
+ /// read restart file
+ virtual void readRestart(const std::string & file_name);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-
-private:
+
+protected:
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength();
/* ------------------------------------------------------------------------ */
- /* Operators */
+ /* Dumpable */
/* ------------------------------------------------------------------------ */
public:
- inline reference operator()(UInt i, UInt j = 0);
- inline const_reference operator()(UInt i, UInt j = 0) const;
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
-public:
- UInt getSize() const{ return this->size; };
-
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-private:
- /// indice of first element in this circular array
- UInt start_position;
+protected:
+ // fracture energy
+ SynchronizedArray<Real> G_c;
- /// indice of last element in this circular array
- UInt end_position;
-};
+ // peak value of cohesive law
+ SynchronizedArray<Real> tau_c;
+ // residual value of cohesive law (for slip > d_c)
+ SynchronizedArray<Real> tau_r;
+};
/* -------------------------------------------------------------------------- */
/* 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)
+template <class Regularisation>
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricLawLinearCohesive<Regularisation> & _this)
{
_this.printself(stream);
return stream;
}
-
-
__END_AKANTU__
+#include "ntn_friclaw_linear_cohesive_tmpl.hh"
-
-#endif /* __AKANTU_AKA_CIRCULAR_ARRAY_HH__ */
-
-
+#endif /* __AST_NTN_FRICLAW_LINEAR_COHESIVE_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive_tmpl.hh
new file mode 100644
index 000000000..e0b3f693a
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive_tmpl.hh
@@ -0,0 +1,183 @@
+/**
+ * @file ntn_friclaw_linear_cohesive_tmpl.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of linear cohesive law
+ *
+ * @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 "dumper_text.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+NTNFricLawLinearCohesive<Regularisation>::NTNFricLawLinearCohesive(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ Regularisation(contact,id,memory_id),
+ G_c(0,1,0.,id+":G_c",0.,"G_c"),
+ tau_c(0,1,0.,id+":tau_c",0.,"tau_c"),
+ tau_r(0,1,0.,id+":tau_r",0.,"tau_r") {
+ AKANTU_DEBUG_IN();
+
+ Regularisation::registerSynchronizedArray(this->G_c);
+ Regularisation::registerSynchronizedArray(this->tau_c);
+ Regularisation::registerSynchronizedArray(this->tau_r);
+
+ this->registerParam("G_c", this->G_c, _pat_parsmod, "fracture energy");
+ this->registerParam("tau_c", this->tau_c, _pat_parsmod, "peak shear strength");
+ this->registerParam("tau_r", this->tau_r, _pat_parsmod, "residual shear strength");
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearCohesive<Regularisation>::computeFrictionalStrength() {
+ AKANTU_DEBUG_IN();
+
+ // get arrays
+ const SynchronizedArray<bool> & is_in_contact = this->internalGetIsInContact();
+ //const SynchronizedArray<Real> & slip = this->internalGetSlip();
+ const SynchronizedArray<Real> & slip = this->internalGetCumulativeSlip();
+
+ // array to fill
+ SynchronizedArray<Real> & strength = this->internalGetFrictionalStrength();
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // node pair is NOT in contact
+ if (!is_in_contact(n))
+ strength(n) = 0.;
+
+ // node pair is in contact
+ else {
+ if (this->G_c(n) == 0.) {
+ // strength(n) = 0.;
+ strength(n) = this->tau_r(n);
+ }
+ else {
+ Real slope = (this->tau_c(n) - this->tau_r(n)) * (this->tau_c(n) - this->tau_r(n)) / (2*this->G_c(n));
+ // no strength < tau_r
+ strength(n) = std::max(this->tau_c(n) - slope * slip(n), this->tau_r(n));
+ // strength(n) = std::max(this->tau_c(n) - slope * slip(n), 0.); // no negative strength
+ }
+ }
+ }
+
+ Regularisation::computeFrictionalStrength();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearCohesive<Regularisation>::registerSynchronizedArray(SynchronizedArrayBase & array) {
+ AKANTU_DEBUG_IN();
+
+ this->G_c.registerDependingArray(array);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearCohesive<Regularisation>::dumpRestart(const std::string & file_name) const {
+ AKANTU_DEBUG_IN();
+
+ this->G_c.dumpRestartFile(file_name);
+ this->tau_c.dumpRestartFile(file_name);
+ this->tau_r.dumpRestartFile(file_name);
+
+ Regularisation::dumpRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearCohesive<Regularisation>::readRestart(const std::string & file_name) {
+ AKANTU_DEBUG_IN();
+
+ this->G_c.readRestartFile(file_name);
+ this->tau_c.readRestartFile(file_name);
+ this->tau_r.readRestartFile(file_name);
+
+ Regularisation::readRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearCohesive<Regularisation>::printself(std::ostream & stream,
+ int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNFricLawLinearCohesive [" << std::endl;
+ Regularisation::printself(stream, ++indent);
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearCohesive<Regularisation>::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+#ifdef AKANTU_USE_IOHELPER
+ // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
+
+ if(field_id == "G_c") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->G_c.getArray()));
+ }
+ else if(field_id == "tau_c") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->tau_c.getArray()));
+ }
+ else if(field_id == "tau_r") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->tau_r.getArray()));
+ }
+ else {
+ Regularisation::addDumpFieldToDumper(dumper_name, field_id);
+ }
+
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/src/common/aka_circular_array.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh
similarity index 56%
copy from src/common/aka_circular_array.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh
index 5a94c6c9c..4d1931d7b 100644
--- a/src/common/aka_circular_array.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh
@@ -1,139 +1,118 @@
/**
- * @file aka_circular_array.hh
+ * @file ntn_friclaw_linear_slip_weakening.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Fri Nov 11 2011
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief class of circular array
+ * @brief linear slip weakening
*
* @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_AKA_CIRCULAR_ARRAY_HH__
-#define __AKANTU_AKA_CIRCULAR_ARRAY_HH__
-
-/* -------------------------------------------------------------------------- */
-#include <typeinfo>
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "aka_array.hh"
+#ifndef __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_HH__
+#define __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_HH__
/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_friclaw_coulomb.hh"
__BEGIN_AKANTU__
-template<class T>
-class CircularArray : protected Array<T> {
+/* -------------------------------------------------------------------------- */
+template <class Regularisation = NTNFricRegNoRegularisation>
+class NTNFricLawLinearSlipWeakening : public NTNFricLawCoulomb<Regularisation> {
/* ------------------------------------------------------------------------ */
/* 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();
- };
-
+
+ NTNFricLawLinearSlipWeakening(NTNBaseContact * contact,
+ const FrictionID & id = "linear_slip_weakening",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawLinearSlipWeakening() {};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- /**
- advance start and end position by one:
- the first element is now at the end of the array
- **/
- inline void makeStep();
+ /// register synchronizedarrays for sync
+ virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
+
+ /// dump restart file
+ virtual void dumpRestart(const std::string & file_name) const;
+
+ /// read restart file
+ virtual void readRestart(const std::string & file_name);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-
-private:
+
+protected:
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength();
+ /// computes the friction coefficient as a function of slip
+ virtual void computeFrictionCoefficient();
/* ------------------------------------------------------------------------ */
- /* Operators */
+ /* Dumpable */
/* ------------------------------------------------------------------------ */
public:
- inline reference operator()(UInt i, UInt j = 0);
- inline const_reference operator()(UInt i, UInt j = 0) const;
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
-public:
- UInt getSize() const{ return this->size; };
-
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-private:
- /// indice of first element in this circular array
- UInt start_position;
+protected:
+ // static coefficient of friction
+ SynchronizedArray<Real> mu_s;
- /// indice of last element in this circular array
- UInt end_position;
-};
+ // kinetic coefficient of friction
+ SynchronizedArray<Real> mu_k;
+ // Dc the length over which slip weakening happens
+ SynchronizedArray<Real> d_c;
+};
/* -------------------------------------------------------------------------- */
/* 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)
+template <class Regularisation>
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricLawLinearSlipWeakening<Regularisation> & _this)
{
_this.printself(stream);
return stream;
}
-
-
__END_AKANTU__
+#include "ntn_friclaw_linear_slip_weakening_tmpl.hh"
-
-#endif /* __AKANTU_AKA_CIRCULAR_ARRAY_HH__ */
-
-
+#endif /* __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_HH__ */
diff --git a/src/synchronizer/synchronizer_registry.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh
similarity index 58%
copy from src/synchronizer/synchronizer_registry.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh
index 5e7e09617..ce633b0be 100644
--- a/src/synchronizer/synchronizer_registry.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh
@@ -1,115 +1,96 @@
/**
- * @file synchronizer_registry.hh
+ * @file ntn_friclaw_linear_slip_weakening_no_healing.hh
*
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief Registry of synchronizers
+ * @brief linear slip weakening
*
* @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_SYNCHRONIZER_REGISTRY_HH__
-#define __AKANTU_SYNCHRONIZER_REGISTRY_HH__
+#ifndef __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_NO_HEALING_HH__
+#define __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_NO_HEALING_HH__
/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "data_accessor.hh"
-#include "synchronizer.hh"
-/* -------------------------------------------------------------------------- */
-
+#include "ntn_friclaw_linear_slip_weakening.hh"
__BEGIN_AKANTU__
-class SynchronizerRegistry {
+/* -------------------------------------------------------------------------- */
+template <class Regularisation = NTNFricRegNoRegularisation>
+class NTNFricLawLinearSlipWeakeningNoHealing : public NTNFricLawLinearSlipWeakening<Regularisation> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- SynchronizerRegistry(DataAccessor & data_accessor);
- virtual ~SynchronizerRegistry();
-
+
+ NTNFricLawLinearSlipWeakeningNoHealing(NTNBaseContact * contact,
+ const FrictionID & id = "linear_slip_weakening_no_healing",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawLinearSlipWeakeningNoHealing() {};
+
/* ------------------------------------------------------------------------ */
/* 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
+ /// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
+
+protected:
+ /// computes the friction coefficient as a function of slip
+ virtual void computeFrictionCoefficient();
/* ------------------------------------------------------------------------ */
- /* Accessors */
+ /* Dumpable */
/* ------------------------------------------------------------------------ */
-public:
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-private:
+protected:
- // /// 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)
+template <class Regularisation>
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricLawLinearSlipWeakeningNoHealing<Regularisation> & _this)
{
_this.printself(stream);
return stream;
}
-
__END_AKANTU__
+#include "ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh"
-
-#endif /* __AKANTU_SYNCHRONIZER_REGISTRY_HH__ */
+#endif /* __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_NO_HEALING_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh
new file mode 100644
index 000000000..323a7df06
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh
@@ -0,0 +1,84 @@
+/**
+ * @file ntn_friclaw_linear_slip_weakening_no_healing_tmpl.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of linear slip weakening
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+NTNFricLawLinearSlipWeakeningNoHealing<Regularisation>::
+NTNFricLawLinearSlipWeakeningNoHealing(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ NTNFricLawLinearSlipWeakening<Regularisation>(contact,id,memory_id) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearSlipWeakeningNoHealing<Regularisation>::computeFrictionCoefficient() {
+ AKANTU_DEBUG_IN();
+
+ // get arrays
+ const SynchronizedArray<Real> & slip = this->internalGetCumulativeSlip();
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ if (slip(n) >= this->d_c(n)) {
+ this->mu(n) = this->mu_k(n);
+ }
+ else {
+ // mu = mu_k + (1 - slip / Dc) * (mu_s - mu_k)
+ this->mu(n) = this->mu_k(n)
+ + (1 - (slip(n) / this->d_c(n))) * (this->mu_s(n) - this->mu_k(n));
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearSlipWeakeningNoHealing<Regularisation>::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNFricLawLinearSlipWeakeningNoHealing [" << std::endl;
+ NTNFricLawLinearSlipWeakening<Regularisation>::printself(stream, ++indent);
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_tmpl.hh
new file mode 100644
index 000000000..a5ed68884
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_tmpl.hh
@@ -0,0 +1,186 @@
+/**
+ * @file ntn_friclaw_linear_slip_weakening_tmpl.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of linear slip weakening
+ *
+ * @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 "dumper_text.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+NTNFricLawLinearSlipWeakening<Regularisation>::NTNFricLawLinearSlipWeakening(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ NTNFricLawCoulomb<Regularisation>(contact,id,memory_id),
+ mu_s(0,1,0.,id+":mu_s",0.,"mu_s"),
+ mu_k(0,1,0.,id+":mu_k",0.,"mu_k"),
+ d_c(0,1,0.,id+":d_c",0.,"d_c") {
+ AKANTU_DEBUG_IN();
+
+ NTNFricLawCoulomb<Regularisation>::registerSynchronizedArray(this->mu_s);
+ NTNFricLawCoulomb<Regularisation>::registerSynchronizedArray(this->mu_k);
+ NTNFricLawCoulomb<Regularisation>::registerSynchronizedArray(this->d_c);
+
+ this->registerParam("mu_s", this->mu_s, _pat_parsmod, "static friction coefficient");
+ this->registerParam("mu_k", this->mu_k, _pat_parsmod, "kinetic friction coefficient");
+ this->registerParam("d_c", this->d_c, _pat_parsmod, "slip weakening length");
+
+ this->setParamAccessType("mu", _pat_readable);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearSlipWeakening<Regularisation>::computeFrictionalStrength() {
+ AKANTU_DEBUG_IN();
+
+ computeFrictionCoefficient();
+ NTNFricLawCoulomb<Regularisation>::computeFrictionalStrength();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearSlipWeakening<Regularisation>::computeFrictionCoefficient() {
+ AKANTU_DEBUG_IN();
+
+ // get arrays
+ const SynchronizedArray<bool> & stick = this->internalGetIsSticking();
+ const SynchronizedArray<Real> & slip = this->internalGetSlip();
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ if (stick(n)) {
+ this->mu(n) = this->mu_s(n);
+ }
+ else {
+ if (slip(n) >= this->d_c(n)) {
+ this->mu(n) = this->mu_k(n);
+ }
+ else {
+ // mu = mu_k + (1 - slip / Dc) * (mu_s - mu_k)
+ this->mu(n) = this->mu_k(n)
+ + (1 - (slip(n) / this->d_c(n))) * (this->mu_s(n) - this->mu_k(n));
+ }
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearSlipWeakening<Regularisation>::registerSynchronizedArray(SynchronizedArrayBase & array) {
+ AKANTU_DEBUG_IN();
+
+ this->mu_s.registerDependingArray(array);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearSlipWeakening<Regularisation>::dumpRestart(const std::string & file_name) const {
+ AKANTU_DEBUG_IN();
+
+ this->mu_s.dumpRestartFile(file_name);
+ this->mu_k.dumpRestartFile(file_name);
+ this->d_c.dumpRestartFile(file_name);
+
+ NTNFricLawCoulomb<Regularisation>::dumpRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearSlipWeakening<Regularisation>::readRestart(const std::string & file_name) {
+ AKANTU_DEBUG_IN();
+
+ this->mu_s.readRestartFile(file_name);
+ this->mu_k.readRestartFile(file_name);
+ this->d_c.readRestartFile(file_name);
+
+ NTNFricLawCoulomb<Regularisation>::readRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearSlipWeakening<Regularisation>::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNFricLawLinearSlipWeakening [" << std::endl;
+ NTNFricLawCoulomb<Regularisation>::printself(stream, ++indent);
+ stream << space << "]" << std::endl;
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation>
+void NTNFricLawLinearSlipWeakening<Regularisation>::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+#ifdef AKANTU_USE_IOHELPER
+ // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
+
+ if(field_id == "mu_s") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->mu_s.getArray()));
+ }
+ else if(field_id == "mu_k") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->mu_k.getArray()));
+ }
+ else if(field_id == "d_c") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->d_c.getArray()));
+ }
+ else {
+ NTNFricLawCoulomb<Regularisation>::addDumpFieldToDumper(dumper_name, field_id);
+ }
+
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.cc
new file mode 100644
index 000000000..99de1ca79
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.cc
@@ -0,0 +1,162 @@
+/**
+ * @file ntn_fricreg_no_regularisation.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of no regularisation
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_fricreg_no_regularisation.hh"
+#include "dumper_text.hh"
+#include "dumper_nodal_field.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+NTNFricRegNoRegularisation::NTNFricRegNoRegularisation(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ NTNBaseFriction(contact, id, memory_id),
+ frictional_contact_pressure(0,1,0.,id+":frictional_contact_pressure",0.,
+ "frictional_contact_pressure") {
+ AKANTU_DEBUG_IN();
+
+ NTNBaseFriction::registerSynchronizedArray(this->frictional_contact_pressure);
+
+ this->registerParam("frictional_contact_pressure", this->frictional_contact_pressure,
+ _pat_internal , "contact pressure used for friction law");
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+const SynchronizedArray<Real> & NTNFricRegNoRegularisation::internalGetContactPressure() {
+ AKANTU_DEBUG_IN();
+
+ this->computeFrictionalContactPressure();
+
+ AKANTU_DEBUG_OUT();
+ return this->frictional_contact_pressure;
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegNoRegularisation::computeFrictionalContactPressure() {
+ AKANTU_DEBUG_IN();
+
+ SolidMechanicsModel & model = this->contact->getModel();
+ UInt dim = model.getSpatialDimension();
+
+ // get contact arrays
+ const SynchronizedArray<bool> & is_in_contact = this->internalGetIsInContact();
+ const Array<Real> & pressure = this->contact->getContactPressure().getArray();
+ Array<Real>::const_iterator< Vector<Real> > it = pressure.begin(dim);
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // node pair is NOT in contact
+ if (!is_in_contact(n))
+ this->frictional_contact_pressure(n) = 0.;
+
+ // node pair is in contact
+ else {
+ // compute frictional contact pressure
+ const Vector<Real> & pres = it[n];
+ this->frictional_contact_pressure(n) = pres.norm();
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegNoRegularisation::registerSynchronizedArray(SynchronizedArrayBase & array) {
+ AKANTU_DEBUG_IN();
+
+ this->frictional_contact_pressure.registerDependingArray(array);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegNoRegularisation::dumpRestart(const std::string & file_name) const {
+ AKANTU_DEBUG_IN();
+
+ this->frictional_contact_pressure.dumpRestartFile(file_name);
+
+ NTNBaseFriction::dumpRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegNoRegularisation::readRestart(const std::string & file_name) {
+ AKANTU_DEBUG_IN();
+
+ this->frictional_contact_pressure.readRestartFile(file_name);
+
+ NTNBaseFriction::readRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegNoRegularisation::printself(std::ostream & stream,
+ int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNFricRegNoRegularisation [" << std::endl;
+ NTNBaseFriction::printself(stream, ++indent);
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegNoRegularisation::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+#ifdef AKANTU_USE_IOHELPER
+ // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
+
+ if (field_id == "frictional_contact_pressure") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->frictional_contact_pressure.getArray()));
+ }
+ else {
+ NTNBaseFriction::addDumpFieldToDumper(dumper_name, field_id);
+ }
+
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/src/common/aka_circular_array.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh
similarity index 51%
copy from src/common/aka_circular_array.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh
index 5a94c6c9c..001f543f5 100644
--- a/src/common/aka_circular_array.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh
@@ -1,139 +1,140 @@
/**
- * @file aka_circular_array.hh
+ * @file ntn_fricreg_no_regularisation.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Fri Nov 11 2011
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief class of circular array
+ * @brief regularisation that does nothing
*
* @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_AKA_CIRCULAR_ARRAY_HH__
-#define __AKANTU_AKA_CIRCULAR_ARRAY_HH__
-
-/* -------------------------------------------------------------------------- */
-#include <typeinfo>
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "aka_array.hh"
+#ifndef __AST_NTN_FRICREG_NO_REGULARISATION_HH__
+#define __AST_NTN_FRICREG_NO_REGULARISATION_HH__
/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_base_friction.hh"
__BEGIN_AKANTU__
-template<class T>
-class CircularArray : protected Array<T> {
+/* -------------------------------------------------------------------------- */
+class NTNFricRegNoRegularisation : public NTNBaseFriction {
/* ------------------------------------------------------------------------ */
/* 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();
- };
-
+
+ NTNFricRegNoRegularisation(NTNBaseContact * contact,
+ const FrictionID & id = "no_regularisation",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricRegNoRegularisation() {};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- /**
- advance start and end position by one:
- the first element is now at the end of the array
- **/
- inline void makeStep();
+ /// set to steady state for no regularisation -> do nothing
+ virtual void setToSteadyState() {};
+
+ virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
+ virtual void dumpRestart(const std::string & file_name) const;
+ virtual void readRestart(const std::string & file_name);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-private:
+protected:
+ virtual void computeFrictionalContactPressure();
+
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength() {};
/* ------------------------------------------------------------------------ */
- /* Operators */
+ /* Dumpable */
/* ------------------------------------------------------------------------ */
public:
- inline reference operator()(UInt i, UInt j = 0);
- inline const_reference operator()(UInt i, UInt j = 0) const;
-
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
- UInt getSize() const{ return this->size; };
+
+protected:
+ /// get the is_in_contact array
+ virtual const SynchronizedArray<bool> & internalGetIsInContact() {
+ return this->contact->getIsInContact();
+ };
+
+ /// get the contact pressure (the norm: scalar value)
+ virtual const SynchronizedArray<Real> & internalGetContactPressure();
+
+ /// get the frictional strength array
+ virtual SynchronizedArray<Real> & internalGetFrictionalStrength() {
+ return this->frictional_strength;
+ };
+
+ /// get the is_sticking array
+ virtual SynchronizedArray<bool> & internalGetIsSticking() {
+ return this->is_sticking;
+ }
+
+ /// get the slip array
+ virtual SynchronizedArray<Real> & internalGetSlip() {
+ return this->slip;
+ }
+
+ /// get the slip array
+ virtual SynchronizedArray<Real> & internalGetCumulativeSlip() {
+ return this->cumulative_slip;
+ }
/* ------------------------------------------------------------------------ */
/* 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;
+protected:
+ // contact pressure (absolut value) for computation of friction
+ SynchronizedArray<Real> frictional_contact_pressure;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-#if defined (AKANTU_INCLUDE_INLINE_IMPL)
-# include "aka_circular_array_inline_impl.cc"
-#endif
+//#include "ntn_fricreg_no_regularisation_inline_impl.cc"
/// standard output stream operator
-template <typename T>
-inline std::ostream & operator <<(std::ostream & stream, const CircularArray<T> & _this)
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricRegNoRegularisation & _this)
{
_this.printself(stream);
return stream;
}
-
-
__END_AKANTU__
-
-
-#endif /* __AKANTU_AKA_CIRCULAR_ARRAY_HH__ */
-
-
+#endif /* __AST_NTN_FRICREG_NO_REGULARISATION_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.cc
new file mode 100644
index 000000000..ad7fbdb57
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.cc
@@ -0,0 +1,169 @@
+/**
+ * @file ntn_fricreg_rubin_ampuero.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of no regularisation
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_fricreg_rubin_ampuero.hh"
+#include "dumper_text.hh"
+#include "dumper_nodal_field.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+NTNFricRegRubinAmpuero::NTNFricRegRubinAmpuero(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ NTNFricRegNoRegularisation(contact, id, memory_id),
+ t_star(0,1,0.,id+":t_star",0.,"t_star") {
+ AKANTU_DEBUG_IN();
+
+ NTNFricRegNoRegularisation::registerSynchronizedArray(this->t_star);
+
+ this->registerParam("t_star", this->t_star, _pat_parsmod, "time scale of regularization");
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+const SynchronizedArray<Real> & NTNFricRegRubinAmpuero::internalGetContactPressure() {
+ AKANTU_DEBUG_IN();
+
+ SolidMechanicsModel & model = this->contact->getModel();
+ UInt dim = model.getSpatialDimension();
+ Real delta_t = model.getTimeStep();
+
+ // get contact arrays
+ const SynchronizedArray<bool> & is_in_contact = this->internalGetIsInContact();
+ const Array<Real> & pressure = this->contact->getContactPressure().getArray();
+ Array<Real>::const_iterator< Vector<Real> > it = pressure.begin(dim);
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // node pair is NOT in contact
+ if (!is_in_contact(n))
+ this->frictional_contact_pressure(n) = 0.;
+
+ // if t_star is too small compute like Coulomb friction (without regularization)
+ else if (Math::are_float_equal(this->t_star(n), 0.)) {
+ const Vector<Real> & pres = it[n];
+ this->frictional_contact_pressure(n) = pres.norm();
+ }
+
+ else {
+ // compute frictional contact pressure
+ // backward euler method: first order implicit numerical integration method
+ // \reg_pres_n+1 = (\reg_pres_n + \delta_t / \t_star * \cur_pres)
+ // / (1 + \delta_t / \t_star)
+ Real alpha = delta_t / this->t_star(n);
+ const Vector<Real> & pres = it[n];
+ this->frictional_contact_pressure(n) += alpha * pres.norm();
+ this->frictional_contact_pressure(n) /= 1 + alpha;
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+ return this->frictional_contact_pressure;
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegRubinAmpuero::setToSteadyState() {
+ AKANTU_DEBUG_IN();
+ NTNFricRegNoRegularisation::computeFrictionalContactPressure();
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegRubinAmpuero::registerSynchronizedArray(SynchronizedArrayBase & array) {
+ AKANTU_DEBUG_IN();
+
+ this->t_star.registerDependingArray(array);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegRubinAmpuero::dumpRestart(const std::string & file_name) const {
+ AKANTU_DEBUG_IN();
+
+ this->t_star.dumpRestartFile(file_name);
+
+ NTNFricRegNoRegularisation::dumpRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegRubinAmpuero::readRestart(const std::string & file_name) {
+ AKANTU_DEBUG_IN();
+
+ this->t_star.readRestartFile(file_name);
+
+ NTNFricRegNoRegularisation::readRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegRubinAmpuero::printself(std::ostream & stream,
+ int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNFricRegRubinAmpuero [" << std::endl;
+ NTNFricRegNoRegularisation::printself(stream, ++indent);
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegRubinAmpuero::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+#ifdef AKANTU_USE_IOHELPER
+ // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
+
+ if (field_id == "t_star") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->t_star.getArray()));
+ }
+ else {
+ NTNFricRegNoRegularisation::addDumpFieldToDumper(dumper_name, field_id);
+ }
+
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/src/synchronizer/synchronizer_registry.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh
similarity index 57%
copy from src/synchronizer/synchronizer_registry.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh
index 5e7e09617..740ac2a4e 100644
--- a/src/synchronizer/synchronizer_registry.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh
@@ -1,115 +1,106 @@
/**
- * @file synchronizer_registry.hh
+ * @file ntn_fricreg_rubin_ampuero.hh
*
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief Registry of synchronizers
+ * @brief regularisation that regularizes the contact pressure
*
* @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 __AST_NTN_FRICREG_RUBIN_AMPUERO_HH__
+#define __AST_NTN_FRICREG_RUBIN_AMPUERO_HH__
-
-#ifndef __AKANTU_SYNCHRONIZER_REGISTRY_HH__
-#define __AKANTU_SYNCHRONIZER_REGISTRY_HH__
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "data_accessor.hh"
-#include "synchronizer.hh"
/* -------------------------------------------------------------------------- */
-
+// simtools
+#include "ntn_fricreg_no_regularisation.hh"
__BEGIN_AKANTU__
-class SynchronizerRegistry {
+/* -------------------------------------------------------------------------- */
+class NTNFricRegRubinAmpuero : public NTNFricRegNoRegularisation {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- SynchronizerRegistry(DataAccessor & data_accessor);
- virtual ~SynchronizerRegistry();
-
+
+ NTNFricRegRubinAmpuero(NTNBaseContact * contact,
+ const FrictionID & id = "rubin_ampuero",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricRegRubinAmpuero() {};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
+ virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
+ virtual void dumpRestart(const std::string & file_name) const;
+ virtual void readRestart(const std::string & file_name);
- /// synchronize operation
- void synchronize(SynchronizationTag tag);
+ virtual void setToSteadyState();
- /// 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
+ /// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
+protected:
+ /// get the contact pressure (the norm: scalar value)
+ virtual const SynchronizedArray<Real> & internalGetContactPressure();
+
/* ------------------------------------------------------------------------ */
/* 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;
+ SynchronizedArray<Real> t_star;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-// #include "synchronizer_registry_inline_impl.cc"
+//#include "ntn_fricreg_rubin_ampuero_inline_impl.cc"
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const SynchronizerRegistry & _this)
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricRegRubinAmpuero & _this)
{
_this.printself(stream);
return stream;
}
-
__END_AKANTU__
-
-
-#endif /* __AKANTU_SYNCHRONIZER_REGISTRY_HH__ */
+#endif /* __AST_NTN_FRICREG_RUBIN_AMPUERO_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.cc
new file mode 100644
index 000000000..77d34db5f
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.cc
@@ -0,0 +1,159 @@
+/**
+ * @file ntn_fricreg_simplified_prakash_clifton.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of simplified prakash clifton with one parameter
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_fricreg_simplified_prakash_clifton.hh"
+#include "dumper_text.hh"
+#include "dumper_nodal_field.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+NTNFricRegSimplifiedPrakashClifton::NTNFricRegSimplifiedPrakashClifton(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ NTNFricRegNoRegularisation(contact, id, memory_id),
+ t_star(0,1,0.,id+":t_star",0.,"t_star"),
+ spc_internal(0,1,0.,id+":spc_internal",0.,"spc_internal") {
+ AKANTU_DEBUG_IN();
+
+ NTNFricRegNoRegularisation::registerSynchronizedArray(this->t_star);
+ NTNFricRegNoRegularisation::registerSynchronizedArray(this->spc_internal);
+
+ this->registerParam("t_star", this->t_star, _pat_parsmod, "time scale of regularisation");
+ this->registerParam("spc_internal", this->spc_internal, _pat_internal, "");
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegSimplifiedPrakashClifton::computeFrictionalStrength() {
+ AKANTU_DEBUG_IN();
+
+ SolidMechanicsModel & model = this->contact->getModel();
+ Real delta_t = model.getTimeStep();
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ Real alpha = delta_t / this->t_star(n);
+ this->frictional_strength(n) += alpha * this->spc_internal(n);
+ this->frictional_strength(n) /= 1 + alpha;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegSimplifiedPrakashClifton::setToSteadyState() {
+ AKANTU_DEBUG_IN();
+
+ /// fill the spc_internal array
+ computeFrictionalStrength();
+
+ /// set strength without regularisation
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ this->frictional_strength(n) = this->spc_internal(n);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegSimplifiedPrakashClifton::registerSynchronizedArray(SynchronizedArrayBase & array) {
+ AKANTU_DEBUG_IN();
+
+ this->t_star.registerDependingArray(array);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegSimplifiedPrakashClifton::dumpRestart(const std::string & file_name) const {
+ AKANTU_DEBUG_IN();
+
+ this->t_star.dumpRestartFile(file_name);
+ this->spc_internal.dumpRestartFile(file_name);
+
+ NTNFricRegNoRegularisation::dumpRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegSimplifiedPrakashClifton::readRestart(const std::string & file_name) {
+ AKANTU_DEBUG_IN();
+
+ this->t_star.readRestartFile(file_name);
+ this->spc_internal.readRestartFile(file_name);
+
+ NTNFricRegNoRegularisation::readRestart(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegSimplifiedPrakashClifton::printself(std::ostream & stream,
+ int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNFricRegSimplifiedPrakashClifton [" << std::endl;
+ NTNFricRegNoRegularisation::printself(stream, ++indent);
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNFricRegSimplifiedPrakashClifton::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+#ifdef AKANTU_USE_IOHELPER
+ // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
+
+ if (field_id == "t_star") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->t_star.getArray()));
+ }
+ else {
+ NTNFricRegNoRegularisation::addDumpFieldToDumper(dumper_name, field_id);
+ }
+
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/src/common/aka_circular_array.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh
similarity index 57%
copy from src/common/aka_circular_array.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh
index 5a94c6c9c..a08448822 100644
--- a/src/common/aka_circular_array.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh
@@ -1,139 +1,115 @@
/**
- * @file aka_circular_array.hh
+ * @file ntn_fricreg_simplified_prakash_clifton.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Fri Nov 11 2011
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief class of circular array
+ * @brief regularisation that regularizes the frictional strength with one parameter
*
* @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_AKA_CIRCULAR_ARRAY_HH__
-#define __AKANTU_AKA_CIRCULAR_ARRAY_HH__
-
-/* -------------------------------------------------------------------------- */
-#include <typeinfo>
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "aka_array.hh"
+#ifndef __AST_NTN_FRICREG_SIMPLIFIED_PRAKASH_CLIFTON_HH__
+#define __AST_NTN_FRICREG_SIMPLIFIED_PRAKASH_CLIFTON_HH__
/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_fricreg_no_regularisation.hh"
__BEGIN_AKANTU__
-template<class T>
-class CircularArray : protected Array<T> {
+/* -------------------------------------------------------------------------- */
+class NTNFricRegSimplifiedPrakashClifton : public NTNFricRegNoRegularisation {
/* ------------------------------------------------------------------------ */
/* 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();
- };
-
+
+ NTNFricRegSimplifiedPrakashClifton(NTNBaseContact * contact,
+ const FrictionID & id = "simplified_prakash_clifton",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricRegSimplifiedPrakashClifton() {};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- /**
- advance start and end position by one:
- the first element is now at the end of the array
- **/
- inline void makeStep();
+ virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
+ virtual void dumpRestart(const std::string & file_name) const;
+ virtual void readRestart(const std::string & file_name);
+
+ virtual void setToSteadyState();
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-private:
+protected:
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength();
/* ------------------------------------------------------------------------ */
- /* Operators */
+ /* Dumpable */
/* ------------------------------------------------------------------------ */
public:
- inline reference operator()(UInt i, UInt j = 0);
- inline const_reference operator()(UInt i, UInt j = 0) const;
-
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
- UInt getSize() const{ return this->size; };
+
+protected:
+ /// get the frictional strength array
+ virtual SynchronizedArray<Real> & internalGetFrictionalStrength() {
+ return this->spc_internal;
+ };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
- /// indice of first element in this circular array
- UInt start_position;
+ SynchronizedArray<Real> t_star;
- /// indice of last element in this circular array
- UInt end_position;
+ // to get the incremental frictional strength
+ SynchronizedArray<Real> spc_internal;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-#if defined (AKANTU_INCLUDE_INLINE_IMPL)
-# include "aka_circular_array_inline_impl.cc"
-#endif
+//#include "ntn_fricreg_simplified_prakash_clifton_inline_impl.cc"
/// standard output stream operator
-template <typename T>
-inline std::ostream & operator <<(std::ostream & stream, const CircularArray<T> & _this)
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricRegSimplifiedPrakashClifton & _this)
{
_this.printself(stream);
return stream;
}
-
-
__END_AKANTU__
-
-
-#endif /* __AKANTU_AKA_CIRCULAR_ARRAY_HH__ */
-
-
+#endif /* __AST_NTN_FRICREG_SIMPLIFIED_PRAKASH_CLIFTON_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc
new file mode 100644
index 000000000..6576f6d0f
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc
@@ -0,0 +1,123 @@
+/**
+ * @file mIIasym_contact.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "mIIasym_contact.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+MIIASYMContact::MIIASYMContact(SolidMechanicsModel & model,
+ const ContactID & id,
+ const MemoryID & memory_id) :
+ NTRFContact(model,id,memory_id)
+{
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void MIIASYMContact::updateImpedance() {
+ AKANTU_DEBUG_IN();
+
+ NTRFContact::updateImpedance();
+
+ for (UInt i=0; i<this->impedance.getSize(); ++i) {
+ this->impedance(i) *= 0.5;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/// WARNING: this is only valid for the acceleration in equilibrium
+void MIIASYMContact::computeRelativeNormalField(const Array<Real> & field,
+ Array<Real> & rel_normal_field) const {
+ AKANTU_DEBUG_IN();
+
+ NTRFContact::computeRelativeNormalField(field, rel_normal_field);
+
+ for (Array<Real>::iterator<Real> it_rtfield = rel_normal_field.begin();
+ it_rtfield != rel_normal_field.end();
+ ++it_rtfield) {
+
+ // in the anti-symmetric case
+ *it_rtfield *= 2.;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void MIIASYMContact::computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const {
+ AKANTU_DEBUG_IN();
+
+ NTRFContact::computeRelativeTangentialField(field, rel_tang_field);
+
+ UInt dim = this->model.getSpatialDimension();
+
+ for (Array<Real>::iterator< Vector<Real> > it_rtfield = rel_tang_field.begin(dim);
+ it_rtfield != rel_tang_field.end(dim);
+ ++it_rtfield) {
+
+ // in the anti-symmetric case, the tangential fields become twice as large
+ *it_rtfield *= 2.;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void MIIASYMContact::computeContactPressureInEquilibrium() {
+ AKANTU_DEBUG_IN();
+
+ NTRFContact::computeContactPressure();
+
+ AKANTU_DEBUG_OUT();
+}
+
+
+/* -------------------------------------------------------------------------- */
+void MIIASYMContact::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "MIIASYMContact [" << std::endl;
+ NTRFContact::printself(stream,indent);
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.hh
new file mode 100644
index 000000000..f171a1674
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.hh
@@ -0,0 +1,91 @@
+/**
+ * @file mIIasym_contact.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief contact for mode II anti-symmetric simulations
+ *
+ * @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 __AST_MIIASYM_CONTACT_HH__
+#define __AST_MIIASYM_CONTACT_HH__
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntrf_contact.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class MIIASYMContact : public NTRFContact {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ MIIASYMContact(SolidMechanicsModel & model,
+ const ContactID & id = "contact",
+ const MemoryID & memory_id = 0);
+ virtual ~MIIASYMContact() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// update the impedance matrix
+ virtual void updateImpedance();
+
+ /// compute contact pressure -> do nothing because can only compute it in equilibrium
+ virtual void computeContactPressure() {};
+
+ /// compute relative normal field (only value that has to be multiplied with the normal)
+ /// WARNING: this is only valid for the acceleration in equilibrium
+ virtual void computeRelativeNormalField(const Array<Real> & field,
+ Array<Real> & rel_normal_field) const;
+
+ /// compute relative tangential field (complet array)
+ /// relative to master nodes
+ virtual void computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const;
+
+ /// compute contact pressure that is used over the entire time
+ virtual void computeContactPressureInEquilibrium();
+
+ /// function to print the contain of the class
+ virtual void printself(std::ostream & stream, int indent = 0) const;
+
+};
+
+/// standard output stream operator
+inline std::ostream & operator <<(std::ostream & stream, const MIIASYMContact & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#endif /* __AST_MIIASYM_CONTACT_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.cc
new file mode 100644
index 000000000..522bfc8a9
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.cc
@@ -0,0 +1,571 @@
+/**
+ * @file ntn_base_contact.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of ntn base contact
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_base_contact.hh"
+#include "dumpable_inline_impl.hh"
+#include "dumper_text.hh"
+#include "dumper_nodal_field.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+NTNContactSynchElementFilter::NTNContactSynchElementFilter(NTNBaseContact * contact) :
+ contact(contact),
+ connectivity(contact->getModel().getMesh().getConnectivities()) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+bool NTNContactSynchElementFilter::operator()(const Element & e) {
+ AKANTU_DEBUG_IN();
+
+ ElementType type = e.type;
+ UInt element = e.element;
+ GhostType ghost_type = e.ghost_type;
+
+ // loop over all nodes of this element
+ bool need_element = false;
+ UInt nb_nodes = Mesh::getNbNodesPerElement(type);
+ for (UInt n=0; n<nb_nodes; ++n) {
+ UInt nn = this->connectivity(type, ghost_type)(element,n);
+
+ // if one nodes is in this contact, we need this element
+ if (this->contact->getNodeIndex(nn) >= 0) {
+ need_element = true;
+ break;
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+ return need_element;
+}
+
+/* -------------------------------------------------------------------------- */
+NTNBaseContact::NTNBaseContact(SolidMechanicsModel & model,
+ const ContactID & id,
+ const MemoryID & memory_id) :
+ Memory(id,memory_id), Dumpable(), model(model),
+ slaves(0,1,0,id+":slaves",std::numeric_limits<UInt>::quiet_NaN(),"slaves"),
+ normals(0,model.getSpatialDimension(),0,id+":normals",
+ std::numeric_limits<Real>::quiet_NaN(),"normals"),
+ contact_pressure(0,model.getSpatialDimension(),0,id+":contact_pressure",
+ std::numeric_limits<Real>::quiet_NaN(),"contact_pressure"),
+ is_in_contact(0,1,false,id+":is_in_contact",false,"is_in_contact"),
+ lumped_boundary_slaves(0,1,0,id+":lumped_boundary_slaves",
+ std::numeric_limits<Real>::quiet_NaN(),"lumped_boundary_slaves"),
+ impedance(0,1,0,id+":impedance",std::numeric_limits<Real>::quiet_NaN(),"impedance"),
+ contact_surfaces(),
+ slave_elements("slave_elements", id, memory_id),
+ node_to_elements(),
+ synch_registry(NULL)
+{
+ AKANTU_DEBUG_IN();
+
+ FEEngine & boundary_fem = this->model.getFEEngineBoundary();
+ for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ boundary_fem.initShapeFunctions(*gt);
+ }
+
+ Mesh & mesh = this->model.getMesh();
+ UInt spatial_dimension = this->model.getSpatialDimension();
+
+ mesh.initElementTypeMapArray(this->slave_elements,
+ 1,
+ spatial_dimension - 1);
+
+ MeshUtils::buildNode2Elements(mesh,
+ this->node_to_elements,
+ spatial_dimension - 1);
+
+ this->registerDumper<DumperText>("text_all", id, true);
+ this->addDumpFilteredMesh(mesh,
+ slave_elements,
+ slaves.getArray(),
+ spatial_dimension - 1,
+ _not_ghost,
+ _ek_regular);
+
+ // parallelisation
+ this->synch_registry = new SynchronizerRegistry(*this);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+NTNBaseContact::~NTNBaseContact() {
+ AKANTU_DEBUG_IN();
+
+ if(this->synch_registry) delete this->synch_registry;
+
+ if(this->synchronizer) delete this->synchronizer;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::initParallel() {
+ AKANTU_DEBUG_IN();
+
+ NTNContactSynchElementFilter elem_filter(this);
+ this->synchronizer = FilteredSynchronizer::
+ createFilteredSynchronizer(this->model.getSynchronizer(),
+ elem_filter);
+
+ this->synch_registry->registerSynchronizer(*(this->synchronizer), _gst_cf_nodal);
+ this->synch_registry->registerSynchronizer(*(this->synchronizer), _gst_cf_incr);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::findBoundaryElements(const Array<UInt> & interface_nodes,
+ ElementTypeMapArray<UInt> & elements) {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_interface_nodes = interface_nodes.getSize();
+ const ElementTypeMapArray<UInt> & connectivity = this->model.getMesh().getConnectivities();
+
+ // add connected boundary elements that have all nodes on this contact
+ for (UInt i=0; i<nb_interface_nodes; ++i) {
+ UInt node = interface_nodes(i);
+
+ CSR<Element>::iterator it = this->node_to_elements.begin(node);
+ CSR<Element>::iterator it_e = this->node_to_elements.end(node);
+ for (; it != it_e; ++it) { // loop over all elements connected to node
+ ElementType type = it->type;
+ UInt element = it->element;
+ GhostType ghost_type = it->ghost_type;
+
+ UInt nb_nodes = Mesh::getNbNodesPerElement(type);
+ UInt nb_found_nodes = 0;
+ for (UInt n=0; n<nb_nodes; ++n) {
+ UInt nn = connectivity(type,ghost_type)(element,n);
+ if (interface_nodes.find(nn) >= 0)
+ nb_found_nodes++;
+ else
+ break;
+ }
+
+ // this is an element between all contact nodes
+ // and is not already in the elements
+ if ((nb_found_nodes == nb_nodes)
+ && (elements(type,ghost_type).find(element) < 0)) {
+ elements(type, ghost_type).push_back(element);
+ }
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::addSplitNode(UInt node) {
+ AKANTU_DEBUG_IN();
+
+ UInt dim = this->model.getSpatialDimension();
+
+ // add to node arrays
+ this->slaves.push_back(node);
+
+ // set contact as false
+ this->is_in_contact.push_back(false);
+
+ // before initializing
+ // set contact pressure, normal, lumped_boundary to Nan
+ this->contact_pressure.push_back(std::numeric_limits<Real>::quiet_NaN());
+ this->impedance.push_back(std::numeric_limits<Real>::quiet_NaN());
+ this->lumped_boundary_slaves.push_back(std::numeric_limits<Real>::quiet_NaN());
+
+ Real nan_normal[dim];
+ for (UInt d=0; d<dim; ++d)
+ nan_normal[d] = std::numeric_limits<Real>::quiet_NaN();
+ this->normals.push_back(nan_normal);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::registerSynchronizedArray(SynchronizedArrayBase & array) {
+ AKANTU_DEBUG_IN();
+
+ this->slaves.registerDependingArray(array);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::dumpRestart(const std::string & file_name) const {
+ AKANTU_DEBUG_IN();
+
+ this->slaves.dumpRestartFile(file_name);
+ this->normals.dumpRestartFile(file_name);
+ this->is_in_contact.dumpRestartFile(file_name);
+ this->contact_pressure.dumpRestartFile(file_name);
+ this->lumped_boundary_slaves.dumpRestartFile(file_name);
+ this->impedance.dumpRestartFile(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::readRestart(const std::string & file_name) {
+ AKANTU_DEBUG_IN();
+
+ this->slaves.readRestartFile(file_name);
+ this->normals.readRestartFile(file_name);
+ this->is_in_contact.readRestartFile(file_name);
+ this->contact_pressure.readRestartFile(file_name);
+ this->lumped_boundary_slaves.readRestartFile(file_name);
+ this->impedance.readRestartFile(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+UInt NTNBaseContact::getNbNodesInContact() const {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_contact = 0;
+
+ UInt nb_nodes = this->getNbContactNodes();
+ const Mesh & mesh = this->model.getMesh();
+
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ bool is_local_node = mesh.isLocalOrMasterNode(this->slaves(n));
+ bool is_pbc_slave_node = this->model.isPBCSlaveNode(this->slaves(n));
+ if (is_local_node && !is_pbc_slave_node && this->is_in_contact(n)) {
+ nb_contact++;
+ }
+ }
+
+ StaticCommunicator::getStaticCommunicator().allReduce(&nb_contact, 1, _so_sum);
+
+ AKANTU_DEBUG_OUT();
+ return nb_contact;
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::updateInternalData() {
+ AKANTU_DEBUG_IN();
+
+ updateNormals();
+ updateLumpedBoundary();
+ updateImpedance();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::updateLumpedBoundary() {
+ AKANTU_DEBUG_IN();
+
+ this->internalUpdateLumpedBoundary(this->slaves.getArray(),
+ this->slave_elements,
+ this->lumped_boundary_slaves);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::internalUpdateLumpedBoundary(const Array<UInt> & nodes,
+ const ElementTypeMapArray<UInt> & elements,
+ SynchronizedArray<Real> & boundary) {
+ AKANTU_DEBUG_IN();
+
+ // set all values in lumped_boundary to zero
+ boundary.clear();
+
+ UInt dim = this->model.getSpatialDimension();
+ // UInt nb_contact_nodes = getNbContactNodes();
+
+ const FEEngine & boundary_fem = this->model.getFEEngineBoundary();
+
+ const Mesh & mesh = this->model.getMesh();
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ Mesh::type_iterator it = mesh.firstType(dim-1, *gt);
+ Mesh::type_iterator last = mesh.lastType(dim-1, *gt);
+ for (; it != last; ++it) {
+ UInt nb_elements = mesh.getNbElement(*it, *gt);
+ UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
+ const Array<UInt> & connectivity = mesh.getConnectivity(*it, *gt);
+
+ // get shapes and compute integral
+ const Array<Real> & shapes = boundary_fem.getShapes(*it, *gt);
+ Array<Real> area(nb_elements,nb_nodes_per_element);
+ boundary_fem.integrate(shapes,area,nb_nodes_per_element,*it, *gt);
+
+ if (this->contact_surfaces.size() == 0) {
+ AKANTU_DEBUG_WARNING("No surfaces in ntn base contact."
+ << " You have to define the lumped boundary by yourself.");
+ }
+
+ Array<UInt>::const_iterator<UInt> elem_it = (elements)(*it, *gt).begin();
+ Array<UInt>::const_iterator<UInt> elem_it_end = (elements)(*it, *gt).end();
+ // loop over contact nodes
+ for (; elem_it != elem_it_end; ++elem_it) {
+ for (UInt q=0; q<nb_nodes_per_element; ++q) {
+ UInt node = connectivity(*elem_it,q);
+ UInt node_index = nodes.find(node);
+ AKANTU_DEBUG_ASSERT(node_index != UInt(-1),
+ "Could not find node " << node
+ << " in the array!");
+ Real area_to_add = area(*elem_it,q);
+ boundary(node_index) += area_to_add;
+ }
+ }
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::computeContactPressure() {
+ AKANTU_DEBUG_IN();
+
+ UInt dim = this->model.getSpatialDimension();
+ Real delta_t = this->model.getTimeStep();
+ UInt nb_contact_nodes = getNbContactNodes();
+
+ AKANTU_DEBUG_ASSERT(delta_t > 0.,
+ "Cannot compute contact pressure if no time step is set");
+
+ // synchronize data
+ this->synch_registry->synchronize(_gst_cf_nodal);
+
+ // pre-compute the acceleration
+ // (not increment acceleration, because residual is still Kf)
+ Array<Real> acceleration(this->model.getMesh().getNbNodes(), dim, 0.);
+ this->model.solveLumped(acceleration,
+ this->model.getMass(),
+ this->model.getResidual(),
+ this->model.getBlockedDOFs(),
+ this->model.getF_M2A());
+
+ // compute relative normal fields of displacement, velocity and acceleration
+ Array<Real> r_disp(0,1);
+ Array<Real> r_velo(0,1);
+ Array<Real> r_acce(0,1);
+ Array<Real> r_old_acce(0,1);
+ computeNormalGap(r_disp);
+ // computeRelativeNormalField(this->model.getCurrentPosition(), r_disp);
+ computeRelativeNormalField(this->model.getVelocity(), r_velo);
+ computeRelativeNormalField(acceleration, r_acce);
+ computeRelativeNormalField(this->model.getAcceleration(), r_old_acce);
+
+ AKANTU_DEBUG_ASSERT(r_disp.getSize() == nb_contact_nodes,
+ "computeRelativeNormalField does not give back arrays "
+ << "size == nb_contact_nodes. nb_contact_nodes = " << nb_contact_nodes
+ << " | array size = " << r_disp.getSize());
+
+ // compute gap array for all nodes
+ Array<Real> gap(nb_contact_nodes, 1);
+ Real * gap_p = gap.storage();
+ Real * r_disp_p = r_disp.storage();
+ Real * r_velo_p = r_velo.storage();
+ Real * r_acce_p = r_acce.storage();
+ Real * r_old_acce_p = r_old_acce.storage();
+ for (UInt i=0; i<nb_contact_nodes; ++i) {
+ *gap_p = *r_disp_p + delta_t * *r_velo_p + delta_t * delta_t * *r_acce_p - 0.5 * delta_t * delta_t * *r_old_acce_p;
+ // increment pointers
+ gap_p++;
+ r_disp_p++;
+ r_velo_p++;
+ r_acce_p++;
+ r_old_acce_p++;
+ }
+
+ // check if gap is negative -> is in contact
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ if (gap(n) <= 0.) {
+ for (UInt d=0; d<dim; ++d) {
+ this->contact_pressure(n,d) = this->impedance(n) * gap(n) / (2 * delta_t)
+ * this->normals(n,d);
+ }
+ this->is_in_contact(n) = true;
+ }
+ else {
+ for (UInt d=0; d<dim; ++d)
+ this->contact_pressure(n,d) = 0.;
+ this->is_in_contact(n) = false;
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::applyContactPressure() {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_contact_nodes = getNbContactNodes();
+ UInt dim = this->model.getSpatialDimension();
+
+ Array<Real> & residual = this->model.getResidual();
+
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ UInt slave = this->slaves(n);
+
+ for (UInt d=0; d<dim; ++d) {
+ //residual(master,d) += this->lumped_boundary(n,0) * this->contact_pressure(n,d);
+ residual(slave, d) -= this->lumped_boundary_slaves(n) * this->contact_pressure(n,d);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+
+/* -------------------------------------------------------------------------- */
+Int NTNBaseContact::getNodeIndex(UInt node) const {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_OUT();
+ return this->slaves.find(node);
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNBaseContact [" << std::endl;
+ stream << space << " + id : " << id << std::endl;
+ stream << space << " + slaves : " << std::endl;
+ this->slaves.printself(stream, indent + 2);
+ stream << space << " + normals : " << std::endl;
+ this->normals.printself(stream, indent + 2);
+ stream << space << " + contact_pressure : " << std::endl;
+ this->contact_pressure.printself(stream, indent + 2);
+
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::syncArrays(SyncChoice sync_choice) {
+ AKANTU_DEBUG_IN();
+
+ this->slaves.syncElements(sync_choice);
+ this->normals.syncElements(sync_choice);
+ this->is_in_contact.syncElements(sync_choice);
+ this->contact_pressure.syncElements(sync_choice);
+ this->lumped_boundary_slaves.syncElements(sync_choice);
+ this->impedance.syncElements(sync_choice);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseContact::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+#ifdef AKANTU_USE_IOHELPER
+ const Array<UInt> & nodal_filter = this->slaves.getArray();
+
+
+
+
+#define ADD_FIELD(field_id, field, type) \
+ internalAddDumpFieldToDumper(dumper_name, \
+ field_id, \
+ new dumper::NodalField< type, true, \
+ Array<type>, \
+ Array<UInt> >(field, 0, 0, &nodal_filter))
+
+ if(field_id == "displacement") {
+ ADD_FIELD(field_id, this->model.getDisplacement(), Real);
+ }
+ else if(field_id == "mass") {
+ ADD_FIELD(field_id, this->model.getMass(), Real);
+ }
+ else if(field_id == "velocity") {
+ ADD_FIELD(field_id, this->model.getVelocity(), Real);
+ }
+ else if(field_id == "acceleration") {
+ ADD_FIELD(field_id, this->model.getAcceleration(), Real);
+ }
+ else if(field_id == "force") {
+ ADD_FIELD(field_id, this->model.getForce(), Real);
+ }
+ else if(field_id == "residual") {
+ ADD_FIELD(field_id, this->model.getResidual(), Real);
+ }
+ else if(field_id == "blocked_dofs") {
+ ADD_FIELD(field_id, this->model.getBlockedDOFs(), bool);
+ }
+ else if(field_id == "increment") {
+ ADD_FIELD(field_id, this->model.getIncrement(), Real);
+ }
+ else if(field_id == "normal") {
+ internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->normals.getArray()));
+ }
+ else if(field_id == "contact_pressure") {
+ internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->contact_pressure.getArray()));
+ }
+ else if(field_id == "is_in_contact") {
+ internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<bool>(this->is_in_contact.getArray()));
+ }
+ else if(field_id == "lumped_boundary_slave") {
+ internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->lumped_boundary_slaves.getArray()));
+ }
+ else if(field_id == "impedance") {
+ internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->impedance.getArray()));
+ }
+ else {
+ std::cerr << "Could not add field '" << field_id
+ << "' to the dumper. Just ignored it." << std::endl;
+ }
+
+#undef ADD_FIELD
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.hh
new file mode 100644
index 000000000..f82a9d12c
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact.hh
@@ -0,0 +1,244 @@
+/**
+ * @file ntn_base_contact.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief base contact for ntn and ntrf contact
+ *
+ * @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 __AST_NTN_BASE_CONTACT_HH__
+#define __AST_NTN_BASE_CONTACT_HH__
+
+/* -------------------------------------------------------------------------- */
+// akantu
+#include "solid_mechanics_model.hh"
+#include "filtered_synchronizer.hh"
+
+// simtools
+#include "synchronized_array.hh"
+
+__BEGIN_AKANTU__
+
+class NTNBaseContact;
+
+/* -------------------------------------------------------------------------- */
+class NTNContactSynchElementFilter : public SynchElementFilter {
+public:
+ // constructor
+ NTNContactSynchElementFilter(NTNBaseContact * contact);
+
+ // answer to: do we need this element ?
+ virtual bool operator()(const Element & e);
+
+private:
+ const NTNBaseContact * contact;
+ const ElementTypeMapArray<UInt> & connectivity;
+};
+
+
+
+/* -------------------------------------------------------------------------- */
+class NTNBaseContact : protected Memory,
+ public DataAccessor,
+ public Dumpable {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTNBaseContact(SolidMechanicsModel & model,
+ const ContactID & id = "contact",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNBaseContact();
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// initializes ntn contact parallel
+ virtual void initParallel();
+
+ /// add split node
+ virtual void addSplitNode(UInt node);
+
+ /// update normals, lumped boundary, and impedance
+ virtual void updateInternalData();
+
+ /// update (compute the normals)
+ virtual void updateNormals() = 0;
+
+ /// update the lumped boundary B matrix
+ virtual void updateLumpedBoundary();
+
+ /// update the impedance matrix
+ virtual void updateImpedance() = 0;
+
+ /// compute the normal contact force
+ virtual void computeContactPressure();
+
+ /// impose the normal contact force
+ virtual void applyContactPressure();
+
+ /// register synchronizedarrays for sync
+ virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
+
+ /// dump restart file
+ virtual void dumpRestart(const std::string & file_name) const;
+
+ /// read restart file
+ virtual void readRestart(const std::string & file_name);
+
+ /// compute the normal gap
+ virtual void computeNormalGap(Array<Real> & gap) const = 0;
+
+ /// compute relative normal field (only value that has to be multiplied with the normal)
+ /// relative to master nodes
+ virtual void computeRelativeNormalField(const Array<Real> & field,
+ Array<Real> & rel_normal_field) const = 0;
+
+ /// compute relative tangential field (complet array)
+ /// relative to master nodes
+ virtual void computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const = 0;
+
+ /// function to print the contain of the class
+ virtual void printself(std::ostream & stream, int indent = 0) const;
+
+protected:
+ /// updateLumpedBoundary
+ virtual void internalUpdateLumpedBoundary(const Array<UInt> & nodes,
+ const ElementTypeMapArray<UInt> & elements,
+ SynchronizedArray<Real> & boundary);
+
+ // to find the slave_elements or master_elements
+ virtual void findBoundaryElements(const Array<UInt> & interface_nodes,
+ ElementTypeMapArray<UInt> & elements);
+
+ /// synchronize arrays
+ virtual void syncArrays(SyncChoice sync_choice);
+
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+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);
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+ AKANTU_GET_MACRO(Model, model, SolidMechanicsModel &)
+
+ AKANTU_GET_MACRO(Slaves, slaves, const SynchronizedArray<UInt> &)
+ AKANTU_GET_MACRO(Normals, normals, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(ContactPressure, contact_pressure, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(LumpedBoundarySlaves, lumped_boundary_slaves, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(Impedance, impedance, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(IsInContact, is_in_contact, const SynchronizedArray<bool> &)
+
+ AKANTU_GET_MACRO(SlaveElements, slave_elements, const ElementTypeMapArray<UInt> &)
+
+ AKANTU_GET_MACRO(SynchronizerRegistry, synch_registry, SynchronizerRegistry *)
+
+ /// get number of nodes that are in contact (globally, on all procs together)
+ /// is_in_contact = true
+ virtual UInt getNbNodesInContact() const;
+
+ /// get index of node in either slaves or masters array
+ /// if node is in neither of them, return -1
+ virtual Int getNodeIndex(UInt node) const;
+
+ /// get number of contact nodes: nodes in the system locally (on this proc)
+ /// is_in_contact = true and false, because just in the system
+ virtual UInt getNbContactNodes() const { return this->slaves.getSize(); };
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ typedef std::set<const ElementGroup *> SurfacePtrSet;
+
+ SolidMechanicsModel & model;
+
+ /// array of slave nodes
+ SynchronizedArray<UInt> slaves;
+ /// array of normals
+ SynchronizedArray<Real> normals;
+ /// array indicating if nodes are in contact
+ SynchronizedArray<Real> contact_pressure;
+ /// array indicating if nodes are in contact
+ SynchronizedArray<bool> is_in_contact;
+ /// boundary matrix for slave nodes
+ SynchronizedArray<Real> lumped_boundary_slaves;
+ /// impedance matrix
+ SynchronizedArray<Real> impedance;
+
+ /// contact surface
+ SurfacePtrSet contact_surfaces;
+
+ /// element list for dump and lumped_boundary
+ ElementTypeMapArray<UInt> slave_elements;
+ CSR<Element> node_to_elements;
+
+ /// parallelisation
+ SynchronizerRegistry * synch_registry;
+ Synchronizer * synchronizer;
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+#include "ntn_base_contact_inline_impl.cc"
+
+/// standard output stream operator
+inline std::ostream & operator <<(std::ostream & stream, const NTNBaseContact & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#endif /* __AST_NTN_BASE_CONTACT_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact_inline_impl.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact_inline_impl.cc
new file mode 100644
index 000000000..12bf1f294
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_contact_inline_impl.cc
@@ -0,0 +1,136 @@
+/**
+ * @file ntn_base_contact_inline_impl.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief ntn base contact inline functions
+ *
+ * @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 UInt NTNBaseContact::getNbDataForElements(const Array<Element> & elements,
+ SynchronizationTag tag) const {
+ AKANTU_DEBUG_IN();
+
+ UInt size = 0;
+ UInt spatial_dimension = this->model.getSpatialDimension();
+
+ UInt nb_nodes = 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 += Mesh::getNbNodesPerElement(el.type);
+ }
+
+ switch(tag) {
+ case _gst_cf_nodal: {
+ size += nb_nodes * spatial_dimension * sizeof(Real) * 3; // disp, vel and cur_pos
+ break;
+ }
+ case _gst_cf_incr: {
+ size += nb_nodes * spatial_dimension * sizeof(Real) * 1;
+ break;
+ }
+ default: {}
+ }
+
+ AKANTU_DEBUG_OUT();
+ return size;
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NTNBaseContact::packElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag) const {
+ AKANTU_DEBUG_IN();
+
+ switch(tag) {
+
+ case _gst_cf_nodal: {
+ DataAccessor::packNodalDataHelper(this->model.getDisplacement(),
+ buffer,
+ elements,
+ this->model.getMesh());
+ DataAccessor::packNodalDataHelper(this->model.getCurrentPosition(),
+ buffer,
+ elements,
+ this->model.getMesh());
+ DataAccessor::packNodalDataHelper(this->model.getVelocity(),
+ buffer,
+ elements,
+ this->model.getMesh());
+ break;
+ }
+ case _gst_cf_incr: {
+ DataAccessor::packNodalDataHelper(this->model.getIncrement(),
+ buffer,
+ elements,
+ this->model.getMesh());
+ break;
+ }
+ default: {
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NTNBaseContact::unpackElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag) {
+ AKANTU_DEBUG_IN();
+
+ switch(tag) {
+
+ case _gst_cf_nodal: {
+ DataAccessor::unpackNodalDataHelper(this->model.getDisplacement(),
+ buffer,
+ elements,
+ this->model.getMesh());
+ DataAccessor::unpackNodalDataHelper(const_cast<Array<Real> & >(this->model.getCurrentPosition()),
+ buffer,
+ elements,
+ this->model.getMesh());
+ DataAccessor::unpackNodalDataHelper(this->model.getVelocity(),
+ buffer,
+ elements,
+ this->model.getMesh());
+ break;
+ }
+ case _gst_cf_incr: {
+ DataAccessor::unpackNodalDataHelper(this->model.getIncrement(),
+ buffer,
+ elements,
+ this->model.getMesh());
+ break;
+ }
+ default: {
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc
new file mode 100644
index 000000000..82ca4eba7
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc
@@ -0,0 +1,389 @@
+/**
+ * @file ntn_base_friction.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of ntn base friction
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_base_friction.hh"
+#include "dumper_text.hh"
+#include "dumper_nodal_field.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+NTNBaseFriction::NTNBaseFriction(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ Memory(id,memory_id),
+ Parsable(_st_friction, id),
+ Dumpable(),
+ contact(contact),
+ is_sticking(0,1,true,id+":is_sticking",true,"is_sticking"),
+ frictional_strength(0,1,0.,id+":frictional_strength",0.,"frictional_strength"),
+ friction_traction(0,contact->getModel().getSpatialDimension(),
+ 0.,id+":friction_traction",0.,"friction_traction"),
+ slip(0,1,0.,id+":slip",0.,"slip"),
+ cumulative_slip(0,1,0.,id+":cumulative_slip",0.,"cumulative_slip"),
+ slip_velocity(0,contact->getModel().getSpatialDimension(),
+ 0.,id+":slip_velocity",0.,"slip_velocity") {
+ AKANTU_DEBUG_IN();
+
+ this->contact->registerSynchronizedArray(this->is_sticking);
+ this->contact->registerSynchronizedArray(this->frictional_strength);
+ this->contact->registerSynchronizedArray(this->friction_traction);
+ this->contact->registerSynchronizedArray(this->slip);
+ this->contact->registerSynchronizedArray(this->cumulative_slip);
+ this->contact->registerSynchronizedArray(this->slip_velocity);
+
+ contact->getModel().setIncrementFlagOn();
+
+ this->registerExternalDumper(contact->getDumper(),
+ contact->getDefaultDumperName(),
+ true);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::updateSlip() {
+ AKANTU_DEBUG_IN();
+
+ SolidMechanicsModel & model = this->contact->getModel();
+ UInt dim = model.getSpatialDimension();
+
+ // synchronize increment
+ this->contact->getSynchronizerRegistry()->synchronize(_gst_cf_incr);
+
+ Array<Real> rel_tan_incr(0,dim);
+ this->contact->computeRelativeTangentialField(model.getIncrement(),
+ rel_tan_incr);
+ Array<Real>::const_iterator< Vector<Real> > it = rel_tan_incr.begin(dim);
+
+ UInt nb_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_nodes; ++n) {
+ if (this->is_sticking(n)) {
+ this->slip(n) = 0.;
+ }
+ else {
+ const Vector<Real> & rti = it[n];
+ this->slip(n) += rti.norm();
+ this->cumulative_slip(n) += rti.norm();
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::computeFrictionTraction() {
+ AKANTU_DEBUG_IN();
+
+ this->computeStickTraction();
+ this->computeFrictionalStrength();
+
+ SolidMechanicsModel & model = this->contact->getModel();
+ UInt dim = model.getSpatialDimension();
+
+ // get contact arrays
+ const SynchronizedArray<bool> & is_in_contact = this->contact->getIsInContact();
+
+ Array<Real> & traction = const_cast< Array<Real> & >(this->friction_traction.getArray());
+ Array<Real>::iterator< Vector<Real> > it_fric_trac = traction.begin(dim);
+
+ this->is_sticking.clear(); // set to not sticking
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // node pair is in contact
+ if (is_in_contact(n)) {
+ Vector<Real> fric_trac = it_fric_trac[n];
+ // check if it is larger than frictional strength
+ Real abs_fric = fric_trac.norm();
+ if (abs_fric != 0.) {
+ Real alpha = this->frictional_strength(n) / abs_fric;
+
+ // larger -> sliding
+ if (alpha < 1.) {
+ fric_trac *= alpha;
+ }
+ else
+ this->is_sticking(n) = true;
+ }
+ else {
+ // frictional traction is already zero
+ this->is_sticking(n) = true;
+ }
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::computeStickTraction() {
+ AKANTU_DEBUG_IN();
+
+ SolidMechanicsModel & model = this->contact->getModel();
+ UInt dim = model.getSpatialDimension();
+ Real delta_t = model.getTimeStep();
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+
+ // get contact arrays
+ const SynchronizedArray<Real> & impedance = this->contact->getImpedance();
+ const SynchronizedArray<bool> & is_in_contact = this->contact->getIsInContact();
+
+ // pre-compute the acceleration
+ // (not increment acceleration, because residual is still Kf)
+ Array<Real> acceleration(model.getFEEngine().getMesh().getNbNodes(), dim, 0.);
+ model.solveLumped(acceleration,
+ model.getMass(),
+ model.getResidual(),
+ model.getBlockedDOFs(),
+ model.getF_M2A());
+
+ // compute relative normal fields of velocity and acceleration
+ Array<Real> r_velo(0,dim);
+ Array<Real> r_acce(0,dim);
+ Array<Real> r_old_acce(0,dim);
+ this->contact->computeRelativeTangentialField(model.getVelocity(), r_velo);
+ this->contact->computeRelativeTangentialField(acceleration, r_acce);
+ this->contact->computeRelativeTangentialField(model.getAcceleration(), r_old_acce);
+
+ AKANTU_DEBUG_ASSERT(r_velo.getSize() == nb_contact_nodes,
+ "computeRelativeNormalField does not give back arrays "
+ << "size == nb_contact_nodes. nb_contact_nodes = " << nb_contact_nodes
+ << " | array size = " << r_velo.getSize());
+
+ // compute tangential gap_dot array for all nodes
+ Array<Real> gap_dot(nb_contact_nodes, dim);
+ Real * gap_dot_p = gap_dot.storage();
+ Real * r_velo_p = r_velo.storage();
+ Real * r_acce_p = r_acce.storage();
+ Real * r_old_acce_p = r_old_acce.storage();
+ for (UInt i=0; i<nb_contact_nodes*dim; ++i) {
+ *gap_dot_p = *r_velo_p + delta_t * *r_acce_p - 0.5 * delta_t * *r_old_acce_p;
+ // increment pointers
+ gap_dot_p++;
+ r_velo_p++;
+ r_acce_p++;
+ r_old_acce_p++;
+ }
+
+ // compute friction traction to stop sliding
+ Array<Real> & traction = const_cast< Array<Real> & >(this->friction_traction.getArray());
+ Array<Real>::vector_iterator it_fric_trac = traction.begin(dim);
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ Vector<Real> fric_trac = it_fric_trac[n];
+ // node pair is NOT in contact
+ if (!is_in_contact(n)) {
+ fric_trac.clear(); // set to zero
+ }
+
+ // node pair is in contact
+ else {
+ // compute friction traction
+ for (UInt d=0; d<dim; ++d)
+ fric_trac(d) = impedance(n) * gap_dot(n,d) / 2.;
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::applyFrictionTraction() {
+ AKANTU_DEBUG_IN();
+
+ SolidMechanicsModel & model = this->contact->getModel();
+ Array<Real> & residual = model.getResidual();
+ UInt dim = model.getSpatialDimension();
+
+ const SynchronizedArray<UInt> & slaves = this->contact->getSlaves();
+ const SynchronizedArray<Real> & lumped_boundary_slaves = this->contact->getLumpedBoundarySlaves();
+
+ UInt nb_contact_nodes = this->contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ UInt slave = slaves(n);
+
+ for (UInt d=0; d<dim; ++d) {
+ residual(slave, d) -= lumped_boundary_slaves(n) * this->friction_traction(n,d);
+ }
+ }
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::registerSynchronizedArray(SynchronizedArrayBase & array) {
+ AKANTU_DEBUG_IN();
+
+ this->frictional_strength.registerDependingArray(array);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::dumpRestart(const std::string & file_name) const {
+ AKANTU_DEBUG_IN();
+
+ this->is_sticking.dumpRestartFile(file_name);
+ this->frictional_strength.dumpRestartFile(file_name);
+ this->friction_traction.dumpRestartFile(file_name);
+ this->slip.dumpRestartFile(file_name);
+ this->cumulative_slip.dumpRestartFile(file_name);
+ this->slip_velocity.dumpRestartFile(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::readRestart(const std::string & file_name) {
+ AKANTU_DEBUG_IN();
+
+ this->is_sticking.readRestartFile(file_name);
+ this->frictional_strength.readRestartFile(file_name);
+ this->friction_traction.readRestartFile(file_name);
+ this->cumulative_slip.readRestartFile(file_name);
+ this->slip_velocity.readRestartFile(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::setParam(const std::string & name, UInt node, Real value) {
+ AKANTU_DEBUG_IN();
+
+ SynchronizedArray<Real> & array = this->get< SynchronizedArray<Real> >(name);
+ Int index = this->contact->getNodeIndex(node);
+ if (index < 0) {
+ AKANTU_DEBUG_WARNING("Node " << node << " is not a contact node. "
+ << "Therefore, cannot set interface parameter!!");
+ }
+ else {
+ array(index) = value; // put value
+ }
+
+ AKANTU_DEBUG_OUT();
+};
+
+/* -------------------------------------------------------------------------- */
+UInt NTNBaseFriction::getNbStickingNodes() const {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_stick = 0;
+
+ UInt nb_nodes = this->contact->getNbContactNodes();
+ const SynchronizedArray<UInt> & nodes = this->contact->getSlaves();
+ const SynchronizedArray<bool> & is_in_contact = this->contact->getIsInContact();
+
+ const Mesh & mesh = this->contact->getModel().getMesh();
+
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ bool is_local_node = mesh.isLocalOrMasterNode(nodes(n));
+ bool is_pbc_slave_node = this->contact->getModel().isPBCSlaveNode(nodes(n));
+ if (is_local_node
+ && !is_pbc_slave_node
+ && is_in_contact(n)
+ && this->is_sticking(n)) {
+ nb_stick++;
+ }
+ }
+
+ StaticCommunicator::getStaticCommunicator().allReduce(&nb_stick, 1, _so_sum);
+
+ AKANTU_DEBUG_OUT();
+ return nb_stick;
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNBaseFriction [" << std::endl;
+ Parsable::printself(stream, indent);
+ stream << space << "]" << std::endl;
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNBaseFriction::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+#ifdef AKANTU_USE_IOHELPER
+ // const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
+
+ if(field_id == "is_sticking") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<bool>(this->is_sticking.getArray()));
+ }
+ else if(field_id == "frictional_strength") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->frictional_strength.getArray()));
+ }
+ else if(field_id == "friction_traction") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->friction_traction.getArray()));
+ }
+ else if(field_id == "slip") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->slip.getArray()));
+ }
+ else if(field_id == "cumulative_slip") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->cumulative_slip.getArray()));
+ }
+ else if(field_id == "slip_velocity") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->slip_velocity.getArray()));
+ }
+ else {
+ this->contact->addDumpFieldToDumper(dumper_name, field_id);
+ }
+
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+
+
+__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.hh
new file mode 100644
index 000000000..67f14f8e0
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.hh
@@ -0,0 +1,176 @@
+/**
+ * @file ntn_base_friction.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief base class for ntn and ntrf friction
+ *
+ * @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 __AST_NTN_BASE_FRICTION_HH__
+#define __AST_NTN_BASE_FRICTION_HH__
+
+/* -------------------------------------------------------------------------- */
+// akantu
+#include "parsable.hh"
+
+// simtools
+#include "ntn_base_contact.hh"
+
+/* -------------------------------------------------------------------------- */
+__BEGIN_AKANTU__
+
+template<>
+inline void ParsableParamTyped< akantu::SynchronizedArray<Real> >::parseParam(const ParserParameter & in_param) {
+ ParsableParam::parseParam(in_param);
+ Real tmp = in_param;
+ param.setAndChangeDefault(tmp);
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
+template<>
+inline void ParsableParamTyped< akantu::SynchronizedArray<Real> >::setTyped<Real>(const Real & value) {
+ param.setAndChangeDefault(value);
+}
+
+/* -------------------------------------------------------------------------- */
+class NTNBaseFriction : protected Memory, public Parsable, public Dumpable {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTNBaseFriction(NTNBaseContact * contact,
+ const FrictionID & id = "friction",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNBaseFriction() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// compute friction traction
+ virtual void computeFrictionTraction();
+
+ /// compute stick traction (friction traction needed to stick the nodes)
+ virtual void computeStickTraction();
+
+ /// apply the friction force
+ virtual void applyFrictionTraction();
+
+ /// compute slip
+ virtual void updateSlip();
+
+ /// register Syncronizedarrays for sync
+ virtual void registerSynchronizedArray(SynchronizedArrayBase & array);
+
+ /// dump restart file
+ virtual void dumpRestart(const std::string & file_name) const;
+
+ /// read restart file
+ virtual void readRestart(const std::string & file_name);
+
+ /// set to steady state
+ virtual void setToSteadyState() {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ };
+
+ /// get the number of sticking nodes (in parallel)
+ /// a node that is not in contact does not count as sticking
+ virtual UInt getNbStickingNodes() const;
+
+ /// function to print the contain of the class
+ virtual void printself(std::ostream & stream, int indent = 0) const;
+
+protected:
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength() = 0;
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+ AKANTU_GET_MACRO(Contact, contact, const NTNBaseContact *)
+
+ AKANTU_GET_MACRO(IsSticking, is_sticking, const SynchronizedArray<bool> &)
+ AKANTU_GET_MACRO(FrictionalStrength, frictional_strength, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(FrictionTraction, friction_traction, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(Slip, slip, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(CumulativeSlip, cumulative_slip, const SynchronizedArray<Real> &)
+ AKANTU_GET_MACRO(SlipVelocity, slip_velocity, const SynchronizedArray<Real> &)
+
+ /// set parameter of a given node
+ /// (if you need to set to all: used the setMixed function of the Parsable).
+ virtual void setParam(const std::string & name, UInt node, Real value);
+
+ // replaced by the setMixed of the Parsable
+ // virtual void setParam(const std::string & param, Real value) {
+ // AKANTU_DEBUG_ERROR("Friction does not know the following parameter: " << param);
+ // };
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ NTNBaseContact * contact;
+
+ // if node is sticking
+ SynchronizedArray<bool> is_sticking;
+ // frictional strength
+ SynchronizedArray<Real> frictional_strength;
+ // friction force
+ SynchronizedArray<Real> friction_traction;
+ // slip
+ SynchronizedArray<Real> slip;
+ SynchronizedArray<Real> cumulative_slip;
+ // slip velocity (tangential vector)
+ SynchronizedArray<Real> slip_velocity;
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+//#include "ntn_base_friction_inline_impl.cc"
+
+/// standard output stream operator
+inline std::ostream & operator <<(std::ostream & stream, const NTNBaseFriction & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#endif /* __AST_NTN_BASE_FRICTION_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc
new file mode 100644
index 000000000..fed2b76dc
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc
@@ -0,0 +1,579 @@
+/**
+ * @file ntn_contact.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of ntn_contact
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_contact.hh"
+#include "dumper_text.hh"
+#include "dumper_nodal_field.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+NTNContact::NTNContact(SolidMechanicsModel & model,
+ const ContactID & id,
+ const MemoryID & memory_id) :
+ NTNBaseContact(model,id,memory_id),
+ masters(0,1,0,id+":masters",std::numeric_limits<UInt>::quiet_NaN(),"masters"),
+ lumped_boundary_masters(0,1,0,id+":lumped_boundary_masters",
+ std::numeric_limits<Real>::quiet_NaN(),"lumped_boundary_masters"),
+ master_elements("master_elements", id, memory_id)
+{
+ AKANTU_DEBUG_IN();
+
+ const Mesh & mesh = this->model.getMesh();
+ UInt spatial_dimension = this->model.getSpatialDimension();
+
+ mesh.initElementTypeMapArray(this->master_elements,
+ 1,
+ spatial_dimension - 1);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::pairInterfaceNodes(const ElementGroup & slave_boundary,
+ const ElementGroup & master_boundary,
+ UInt surface_normal_dir,
+ const Mesh & mesh,
+ Array<UInt> & pairs) {
+ AKANTU_DEBUG_IN();
+
+ pairs.resize(0);
+ AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2,
+ "Array of node pairs should have nb_component = 2," <<
+ " but has nb_component = " << pairs.getNbComponent());
+
+ UInt dim = mesh.getSpatialDimension();
+ AKANTU_DEBUG_ASSERT(surface_normal_dir < dim, "Mesh is of " << dim << " dimensions"
+ << " and cannot have direction " << surface_normal_dir
+ << " for surface normal");
+
+ // offset for projection computation
+ UInt offset[dim-1];
+ for (UInt i=0, j=0; i<dim; ++i) {
+ if (surface_normal_dir != i) {
+ offset[j] = i;
+ ++j;
+ }
+ }
+
+ // find projected node coordinates
+ const Array<Real> & coordinates = mesh.getNodes();
+
+ // find slave nodes
+ Array<Real> proj_slave_coord(slave_boundary.getNbNodes(),dim-1,0.);
+ Array<UInt> slave_nodes(slave_boundary.getNbNodes());
+ UInt n(0);
+ for(ElementGroup::const_node_iterator nodes_it(slave_boundary.node_begin()); nodes_it!= slave_boundary.node_end(); ++nodes_it) {
+ for (UInt d=0; d<dim-1; ++d) {
+ proj_slave_coord(n,d) = coordinates(*nodes_it,offset[d]);
+ slave_nodes(n)=*nodes_it;
+ }
+ ++n;
+ }
+
+ // find master nodes
+ Array<Real> proj_master_coord(master_boundary.getNbNodes(),dim-1,0.);
+ Array<UInt> master_nodes(master_boundary.getNbNodes());
+ n=0;
+ for(ElementGroup::const_node_iterator nodes_it(master_boundary.node_begin()); nodes_it!= master_boundary.node_end(); ++nodes_it) {
+ for (UInt d=0; d<dim-1; ++d) {
+ proj_master_coord(n,d) = coordinates(*nodes_it,offset[d]);
+ master_nodes(n)=*nodes_it;
+ }
+ ++n;
+ }
+
+ // find minimum distance between slave nodes to define tolerance
+ Real min_dist = std::numeric_limits<Real>::max();
+ for (UInt i=0; i<proj_slave_coord.getSize(); ++i) {
+ for (UInt j=i+1; j<proj_slave_coord.getSize(); ++j) {
+ Real dist = 0.;
+ for (UInt d=0; d<dim-1; ++d) {
+ dist += (proj_slave_coord(i,d) - proj_slave_coord(j,d))
+ * (proj_slave_coord(i,d) - proj_slave_coord(j,d));
+ }
+ if (dist < min_dist) {
+ min_dist = dist;
+ }
+ }
+ }
+ min_dist = std::sqrt(min_dist);
+ Real local_tol = 0.1*min_dist;
+
+ // find master slave node pairs
+ for (UInt i=0; i<proj_slave_coord.getSize(); ++i) {
+ for (UInt j=0; j<proj_master_coord.getSize(); ++j) {
+ Real dist = 0.;
+ for (UInt d=0; d<dim-1; ++d) {
+ dist += (proj_slave_coord(i,d) - proj_master_coord(j,d))
+ * (proj_slave_coord(i,d) - proj_master_coord(j,d));
+ }
+ dist = std::sqrt(dist);
+ if (dist < local_tol) { // it is a pair
+ UInt pair[2];
+ pair[0] = slave_nodes(i);
+ pair[1] = master_nodes(j);
+ pairs.push_back(pair);
+ continue; // found master do not need to search further for this slave
+ }
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::addSurfacePair(const Surface & slave,
+ const Surface & master,
+ UInt surface_normal_dir) {
+ AKANTU_DEBUG_IN();
+
+ const Mesh & mesh = this->model.getMesh();
+
+ const ElementGroup & slave_boundary = mesh.getElementGroup(slave);
+ const ElementGroup & master_boundary = mesh.getElementGroup(master);
+
+ this->contact_surfaces.insert(&slave_boundary);
+ this->contact_surfaces.insert(&master_boundary);
+
+ Array<UInt> pairs(0,2);
+ NTNContact::pairInterfaceNodes(slave_boundary,
+ master_boundary,
+ surface_normal_dir,
+ this->model.getMesh(),
+ pairs);
+
+ // eliminate pairs which contain a pbc slave node
+ Array<UInt> pairs_no_PBC_slaves(0,2);
+ Array<UInt>::const_vector_iterator it = pairs.begin(2);
+ Array<UInt>::const_vector_iterator end = pairs.end(2);
+ for (; it!=end; ++it) {
+ const Vector<UInt> & pair = *it;
+ if (!this->model.isPBCSlaveNode(pair(0)) && !this->model.isPBCSlaveNode(pair(1))) {
+ pairs_no_PBC_slaves.push_back(pair);
+ }
+ }
+
+ this->addNodePairs(pairs_no_PBC_slaves);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::addNodePairs(const Array<UInt> & pairs) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2,
+ "Array of node pairs should have nb_component = 2," <<
+ " but has nb_component = " << pairs.getNbComponent());
+ UInt nb_pairs = pairs.getSize();
+ for (UInt n=0; n<nb_pairs; ++n) {
+ this->addSplitNode(pairs(n,0), pairs(n,1));
+ }
+
+ // synchronize with depending nodes
+ findBoundaryElements(this->slaves.getArray(), this->slave_elements);
+ findBoundaryElements(this->masters.getArray(), this->master_elements);
+ updateInternalData();
+ syncArrays(_added);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::getNodePairs(Array<UInt> & pairs) const {
+ AKANTU_DEBUG_IN();
+
+ pairs.resize(0);
+ AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2,
+ "Array of node pairs should have nb_component = 2," <<
+ " but has nb_component = " << pairs.getNbComponent());
+ UInt nb_pairs = this->getNbContactNodes();
+ for (UInt n=0; n<nb_pairs; ++n) {
+ UInt pair[2];
+ pair[0] = this->slaves(n);
+ pair[1] = this->masters(n);
+ pairs.push_back(pair);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::addSplitNode(UInt slave, UInt master) {
+ AKANTU_DEBUG_IN();
+
+ NTNBaseContact::addSplitNode(slave);
+
+ this->masters.push_back(master);
+ this->lumped_boundary_masters.push_back(std::numeric_limits<Real>::quiet_NaN());
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/*
+ This function only works for surface elements with one quad point. For
+ surface elements with more quad points, it computes still, but the result
+ might not be what you are looking for.
+ */
+void NTNContact::updateNormals() {
+ AKANTU_DEBUG_IN();
+
+ // set normals to zero
+ this->normals.clear();
+
+ // contact information
+ UInt dim = this->model.getSpatialDimension();
+ UInt nb_contact_nodes = this->getNbContactNodes();
+
+ this->synch_registry->synchronize(_gst_cf_nodal); // synchronize current pos
+ const Array<Real> & cur_pos = this->model.getCurrentPosition();
+
+ FEEngine & boundary_fem = this->model.getFEEngineBoundary();
+ const Mesh & mesh = this->model.getMesh();
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end();
+ ++gt) {
+ Mesh::type_iterator it = mesh.firstType(dim-1, *gt);
+ Mesh::type_iterator last = mesh.lastType(dim-1, *gt);
+
+ for (; it != last; ++it) {
+ // compute the normals
+ Array<Real> quad_normals(0,dim);
+ boundary_fem.computeNormalsOnIntegrationPoints(cur_pos, quad_normals, *it, *gt);
+
+ UInt nb_quad_points = boundary_fem.getNbIntegrationPoints(*it, *gt);
+
+ // new version: compute normals only based on master elements (and not all boundary elements)
+ // -------------------------------------------------------------------------------------
+
+ UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
+ const Array<UInt> & connectivity = mesh.getConnectivity(*it, *gt);
+
+ Array<UInt>::const_iterator<UInt> elem_it = (this->master_elements)(*it, *gt).begin();
+ Array<UInt>::const_iterator<UInt> elem_it_end = (this->master_elements)(*it, *gt).end();
+ // loop over contact nodes
+ for (; elem_it != elem_it_end; ++elem_it) {
+ for (UInt q=0; q<nb_nodes_per_element; ++q) {
+ UInt node = connectivity(*elem_it,q);
+ UInt node_index = this->masters.find(node);
+ AKANTU_DEBUG_ASSERT(node_index != UInt(-1),
+ "Could not find node " << node
+ << " in the array!");
+
+ for (UInt q=0; q<nb_quad_points; ++q) {
+ // add quad normal to master normal
+ for (UInt d=0; d<dim; ++d) {
+ this->normals(node_index,d) += quad_normals((*elem_it)*nb_quad_points + q, d);
+ }
+ }
+ }
+ }
+ // -------------------------------------------------------------------------------------
+
+ /*
+ // get elements connected to each node
+ CSR<UInt> node_to_element;
+ MeshUtils::buildNode2ElementsElementTypeMap(mesh, node_to_element, *it, *gt);
+
+ // add up normals to all master nodes
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ UInt master = this->masters(n);
+ CSR<UInt>::iterator elem = node_to_element.begin(master);
+ // loop over all elements connected to this master node
+ for (; elem != node_to_element.end(master); ++elem) {
+ UInt e = *elem;
+ // loop over all quad points of this element
+ for (UInt q=0; q<nb_quad_points; ++q) {
+ // add quad normal to master normal
+ for (UInt d=0; d<dim; ++d) {
+ this->normals(n,d) += quad_normals(e*nb_quad_points + q, d);
+ }
+ }
+ }
+ }
+ */
+ }
+ }
+
+ Real * master_normals = this->normals.storage();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ if (dim==2)
+ Math::normalize2(&(master_normals[n*dim]));
+ else if (dim==3)
+ Math::normalize3(&(master_normals[n*dim]));
+ }
+
+ // // normalize normals
+ // Array<Real>::iterator<Real> nit = this->normals.begin();
+ // Array<Real>::iterator<Real> nend = this->normals.end();
+ // for (; nit != nend; ++nit) {
+ // nit->normalize();
+ // }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::dumpRestart(const std::string & file_name) const {
+ AKANTU_DEBUG_IN();
+
+ NTNBaseContact::dumpRestart(file_name);
+ this->masters.dumpRestartFile(file_name);
+ this->lumped_boundary_masters.dumpRestartFile(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::readRestart(const std::string & file_name) {
+ AKANTU_DEBUG_IN();
+
+ NTNBaseContact::readRestart(file_name);
+ this->masters.readRestartFile(file_name);
+ this->lumped_boundary_masters.readRestartFile(file_name);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::updateImpedance() {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_contact_nodes = getNbContactNodes();
+ Real delta_t = this->model.getTimeStep();
+ AKANTU_DEBUG_ASSERT(delta_t != NAN, "Time step is NAN. Have you set it already?");
+
+ const Array<Real> & mass = this->model.getMass();
+
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ UInt master = this->masters(n);
+ UInt slave = this->slaves(n);
+
+ Real imp = (this->lumped_boundary_masters(n) / mass(master))
+ + (this->lumped_boundary_slaves(n) / mass(slave));
+ imp = 2 / delta_t / imp;
+ this->impedance(n) = imp;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::updateLumpedBoundary() {
+ AKANTU_DEBUG_IN();
+
+ internalUpdateLumpedBoundary(this->slaves.getArray(),
+ this->slave_elements,
+ this->lumped_boundary_slaves);
+
+ internalUpdateLumpedBoundary(this->masters.getArray(),
+ this->master_elements,
+ this->lumped_boundary_masters);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::applyContactPressure() {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_ntn_pairs = getNbContactNodes();
+ UInt dim = this->model.getSpatialDimension();
+
+ Array<Real> & residual = this->model.getResidual();
+
+ for (UInt n=0; n<nb_ntn_pairs; ++n) {
+ UInt master = this->masters(n);
+ UInt slave = this->slaves(n);
+
+ for (UInt d=0; d<dim; ++d) {
+ residual(master,d) += this->lumped_boundary_masters(n) * this->contact_pressure(n,d);
+ residual(slave, d) -= this->lumped_boundary_slaves(n) * this->contact_pressure(n,d);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const {
+ AKANTU_DEBUG_IN();
+
+ // resize arrays to zero
+ rel_tang_field.resize(0);
+
+ UInt dim = this->model.getSpatialDimension();
+
+ Array<Real>::const_vector_iterator it_field = field.begin(dim);
+ Array<Real>::const_vector_iterator it_normal = this->normals.getArray().begin(dim);
+
+ Vector<Real> rfv(dim);
+ Vector<Real> np_rfv(dim);
+
+ UInt nb_contact_nodes = this->slaves.getSize();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // nodes
+ UInt slave = this->slaves(n);
+ UInt master = this->masters(n);
+
+ // relative field vector (slave - master)
+ rfv = Vector<Real>(it_field[slave]);
+ rfv -= Vector<Real>(it_field[master]);
+
+ // normal projection of relative field
+ const Vector<Real> normal_v = it_normal[n];
+ np_rfv = normal_v;
+ np_rfv *= rfv.dot(normal_v);
+
+ // subract normal projection from relative field to get the tangential projection
+ rfv -= np_rfv;
+ rel_tang_field.push_back(rfv);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::computeRelativeNormalField(const Array<Real> & field,
+ Array<Real> & rel_normal_field) const {
+ AKANTU_DEBUG_IN();
+
+ // resize arrays to zero
+ rel_normal_field.resize(0);
+
+ UInt dim = this->model.getSpatialDimension();
+ // Real * field_p = field.storage();
+ // Real * normals_p = this->normals.storage();
+
+ Array<Real>::const_iterator< Vector<Real> > it_field = field.begin(dim);
+ Array<Real>::const_iterator< Vector<Real> > it_normal = this->normals.getArray().begin(dim);
+
+ Vector<Real> rfv(dim);
+
+ UInt nb_contact_nodes = this->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // nodes
+ UInt slave = this->slaves(n);
+ UInt master = this->masters(n);
+
+ // relative field vector (slave - master)
+ rfv = Vector<Real>(it_field[slave]);
+ rfv -= Vector<Real>(it_field[master]);
+
+ // length of normal projection of relative field
+ const Vector<Real> normal_v = it_normal[n];
+ rel_normal_field.push_back(rfv.dot(normal_v));
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+Int NTNContact::getNodeIndex(UInt node) const {
+ AKANTU_DEBUG_IN();
+
+ Int slave_i = NTNBaseContact::getNodeIndex(node);
+ Int master_i = this->masters.find(node);
+
+ AKANTU_DEBUG_OUT();
+ return std::max(slave_i,master_i);
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNContact [" << std::endl;
+ NTNBaseContact::printself(stream, indent);
+ stream << space << " + masters : " << std::endl;
+ this->masters.printself(stream, indent + 2);
+ stream << space << " + lumped_boundary_mastres : " << std::endl;
+ this->lumped_boundary_masters.printself(stream, indent + 2);
+
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::syncArrays(SyncChoice sync_choice) {
+ AKANTU_DEBUG_IN();
+
+ NTNBaseContact::syncArrays(sync_choice);
+
+ this->masters.syncElements(sync_choice);
+ this->lumped_boundary_masters.syncElements(sync_choice);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTNContact::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+ /*
+#ifdef AKANTU_USE_IOHELPER
+ const Array<UInt> & nodal_filter = this->slaves.getArray();
+
+#define ADD_FIELD(field_id, field, type) \
+ internalAddDumpFieldToDumper(dumper_name, \
+ field_id, \
+ new DumperIOHelper::NodalField< type, true, \
+ Array<type>, \
+ Array<UInt> >(field, 0, 0, &nodal_filter))
+ */
+
+ if(field_id == "lumped_boundary_master") {
+ internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new dumper::NodalField<Real>(this->lumped_boundary_masters.getArray()));
+ }
+ else {
+ NTNBaseContact::addDumpFieldToDumper(dumper_name, field_id);
+ }
+
+ /*
+#undef ADD_FIELD
+#endif
+ */
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.hh
new file mode 100644
index 000000000..2a06632da
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.hh
@@ -0,0 +1,168 @@
+/**
+ * @file ntn_contact.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief contact for node to node discretization
+ *
+ * @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 __AST_NTN_CONTACT_HH__
+#define __AST_NTN_CONTACT_HH__
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_base_contact.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class NTNContact : public NTNBaseContact {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTNContact(SolidMechanicsModel & model,
+ const ContactID & id = "contact",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNContact() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// add surface pair and pair nodes according to the surface normal
+ void addSurfacePair(const Surface & slave,
+ const Surface & master,
+ UInt surface_normal_dir);
+
+ /// fills the pairs vector with interface node pairs (*,0)=slaves, (*,1)=masters
+ static void pairInterfaceNodes(const ElementGroup & slave_boundary,
+ const ElementGroup & master_boundary,
+ UInt surface_normal_dir,
+ const Mesh & mesh,
+ Array<UInt> & pairs);
+
+ // add node pairs from a list with pairs(*,0)=slaves and pairs(*,1)=masters
+ void addNodePairs(const Array<UInt> & pairs);
+
+ /// add node pair
+ virtual void addSplitNode(UInt slave, UInt master);
+
+ /// update (compute the normals on the master nodes)
+ virtual void updateNormals();
+
+ /// update the lumped boundary B matrix
+ virtual void updateLumpedBoundary();
+
+ /// update the impedance matrix
+ virtual void updateImpedance();
+
+ /// impose the normal contact force
+ virtual void applyContactPressure();
+
+ /// dump restart file
+ virtual void dumpRestart(const std::string & file_name) const;
+
+ /// read restart file
+ virtual void readRestart(const std::string & file_name);
+
+ /// compute the normal gap
+ virtual void computeNormalGap(Array<Real> & gap) const {
+ this->computeRelativeNormalField(this->model.getCurrentPosition(),
+ gap);
+ };
+
+ /// compute relative normal field (only value that has to be multiplied with the normal)
+ /// relative to master nodes
+ virtual void computeRelativeNormalField(const Array<Real> & field,
+ Array<Real> & rel_normal_field) const;
+
+ /// compute relative tangential field (complet array)
+ /// relative to master nodes
+ virtual void computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const;
+
+ /// function to print the contain of the class
+ virtual void printself(std::ostream & stream, int indent = 0) const;
+
+protected:
+ /// synchronize arrays
+ virtual void syncArrays(SyncChoice sync_choice);
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+ // virtual void addDumpFieldVector(const std::string & field_id);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+ AKANTU_GET_MACRO(Masters, masters, const SynchronizedArray<UInt> &)
+ AKANTU_GET_MACRO(LumpedBoundaryMasters, lumped_boundary_masters, const SynchronizedArray<Real> &)
+
+ /// get interface node pairs (*,0) are slaves, (*,1) are masters
+ void getNodePairs(Array<UInt> & pairs) const;
+
+ /// get index of node in either slaves or masters array
+ /// if node is in neither of them, return -1
+ Int getNodeIndex(UInt node) const;
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+private:
+ /// array of master nodes
+ SynchronizedArray<UInt> masters;
+ /// lumped boundary of master nodes
+ SynchronizedArray<Real> lumped_boundary_masters;
+
+ // element list for dump and lumped_boundary
+ ElementTypeMapArray<UInt> master_elements;
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+//#include "ntn_contact_inline_impl.cc"
+
+/// standard output stream operator
+inline std::ostream & operator <<(std::ostream & stream, const NTNContact & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#endif /* __AST_NTN_CONTACT_HH__ */
diff --git a/src/synchronizer/synchronizer_registry.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh
similarity index 59%
copy from src/synchronizer/synchronizer_registry.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh
index 5e7e09617..c7bc3a3a7 100644
--- a/src/synchronizer/synchronizer_registry.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh
@@ -1,115 +1,106 @@
/**
- * @file synchronizer_registry.hh
+ * @file ntn_friction.hh
*
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Thu Jun 16 2011
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief Registry of synchronizers
+ * @brief implementation of friction for node to node contact
*
* @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 __AST_NTN_FRICTION_HH__
+#define __AST_NTN_FRICTION_HH__
-#ifndef __AKANTU_SYNCHRONIZER_REGISTRY_HH__
-#define __AKANTU_SYNCHRONIZER_REGISTRY_HH__
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "data_accessor.hh"
-#include "synchronizer.hh"
/* -------------------------------------------------------------------------- */
-
+// simtools
+#include "ntn_base_friction.hh"
+#include "ntn_friclaw_coulomb.hh"
__BEGIN_AKANTU__
-class SynchronizerRegistry {
+/* -------------------------------------------------------------------------- */
+template <template<class> class FrictionLaw = NTNFricLawCoulomb,
+ class Regularisation = NTNFricRegNoRegularisation>
+class NTNFriction : public FrictionLaw<Regularisation> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- SynchronizerRegistry(DataAccessor & data_accessor);
- virtual ~SynchronizerRegistry();
-
+ NTNFriction(NTNBaseContact * contact,
+ const FrictionID & id = "friction",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFriction() {};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
+ /// apply the friction force
+ virtual void applyFrictionTraction();
- /// synchronize operation
- void synchronize(SynchronizationTag tag);
-
- /// asynchronous synchronization
- void asynchronousSynchronize(SynchronizationTag tag);
+ /// function to print the contain of the class
+ virtual void printself(std::ostream & stream, int indent = 0) const;
- /// wait end of asynchronous synchronization
- void waitEndSynchronize(SynchronizationTag tag);
+protected:
- /// 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;
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ // virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ // const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-private:
-
- // /// number of tags registered
- // UInt nb_synchronization_tags;
+protected:
- 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)
+template <template<class> class FrictionLaw, class Regularisation>
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFriction<FrictionLaw,
+ Regularisation> & _this)
{
_this.printself(stream);
return stream;
}
-
__END_AKANTU__
+#include "ntn_friction_tmpl.hh"
-
-#endif /* __AKANTU_SYNCHRONIZER_REGISTRY_HH__ */
+#endif /* __AST_NTN_FRICTION_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction_tmpl.hh
new file mode 100644
index 000000000..967d37dfa
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction_tmpl.hh
@@ -0,0 +1,94 @@
+/**
+ * @file ntn_friction_tmpl.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_contact.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <template <class> class FrictionLaw, class Regularisation>
+NTNFriction<FrictionLaw, Regularisation>::NTNFriction(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ FrictionLaw<Regularisation>(contact, id, memory_id) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <template <class> class FrictionLaw, class Regularisation>
+void NTNFriction<FrictionLaw, Regularisation>::applyFrictionTraction() {
+ AKANTU_DEBUG_IN();
+
+ NTNContact * ntn_contact = dynamic_cast<NTNContact * >(this->contact);
+ SolidMechanicsModel & model = ntn_contact->getModel();
+ Array<Real> & residual = model.getResidual();
+ UInt dim = model.getSpatialDimension();
+
+ const SynchronizedArray<UInt> & masters = ntn_contact->getMasters();
+ const SynchronizedArray<UInt> & slaves = ntn_contact->getSlaves();
+ const SynchronizedArray<Real> & l_boundary_slaves = ntn_contact->getLumpedBoundarySlaves();
+ const SynchronizedArray<Real> & l_boundary_masters = ntn_contact->getLumpedBoundaryMasters();
+
+ UInt nb_contact_nodes = ntn_contact->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ UInt master = masters(n);
+ UInt slave = slaves(n);
+
+ for (UInt d=0; d<dim; ++d) {
+ residual(master,d) += l_boundary_masters(n) * this->friction_traction(n,d);
+ residual(slave, d) -= l_boundary_slaves(n) * this->friction_traction(n,d);
+ }
+ }
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <template <class> class FrictionLaw, class Regularisation>
+void NTNFriction<FrictionLaw, Regularisation>::printself(std::ostream & stream,
+ int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTNFriction [" << std::endl;
+ FrictionLaw<Regularisation>::printself(stream, ++indent);
+ stream << space << "]" << std::endl;
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.cc
new file mode 100644
index 000000000..b1d623468
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.cc
@@ -0,0 +1,413 @@
+/**
+ * @file ntn_initiation_function.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of initializing ntn and ntrf friction
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "mIIasym_contact.hh"
+#include "ntn_initiation_function.hh"
+#include "ntn_friction.hh"
+#include "ntrf_friction.hh"
+
+// friction regularisations
+#include "ntn_fricreg_rubin_ampuero.hh"
+#include "ntn_fricreg_simplified_prakash_clifton.hh"
+
+// friction laws
+#include "ntn_friclaw_linear_cohesive.hh"
+#include "ntn_friclaw_linear_slip_weakening.hh"
+#include "ntn_friclaw_linear_slip_weakening_no_healing.hh"
+
+__BEGIN_AKANTU__
+
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
+ ParameterReader & data) {
+ AKANTU_DEBUG_IN();
+
+ const std::string & friction_law = data.get<std::string>("friction_law");
+ const std::string & friction_reg = data.get<std::string>("friction_regularisation");
+
+ NTNBaseFriction * friction;
+
+ bool is_ntn_contact = true;
+ if (dynamic_cast<NTRFContact *>(contact) != NULL ||
+ dynamic_cast<MIIASYMContact *>(contact) != NULL) {
+ is_ntn_contact = false;
+ }
+
+ if (friction_law == "coulomb") {
+ if (friction_reg == "no_regularisation") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawCoulomb,
+ NTNFricRegNoRegularisation>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawCoulomb,
+ NTNFricRegNoRegularisation>(contact);
+ }
+ else if (friction_reg == "rubin_ampuero") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawCoulomb,
+ NTNFricRegRubinAmpuero>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawCoulomb,
+ NTNFricRegRubinAmpuero>(contact);
+
+ friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
+ }
+ else if (friction_reg == "simplified_prakash_clifton") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawCoulomb,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawCoulomb,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+
+ friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
+ }
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+
+ friction->setMixed< SynchronizedArray<Real> >("mu_s", data.get<Real>("mu_s"));
+ }
+
+ // Friction Law: Linear Slip Weakening
+ else if (friction_law == "linear_slip_weakening") {
+ if (friction_reg == "no_regularisation") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegNoRegularisation>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegNoRegularisation>(contact);
+ }
+ else if (friction_reg == "rubin_ampuero") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegRubinAmpuero>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegRubinAmpuero>(contact);
+
+ friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
+ }
+ else if (friction_reg == "simplified_prakash_clifton") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+
+ friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
+ }
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+
+ friction->setMixed< SynchronizedArray<Real> >("mu_s", data.get<Real>("mu_s"));
+ friction->setMixed< SynchronizedArray<Real> >("mu_k", data.get<Real>("mu_k"));
+ friction->setMixed< SynchronizedArray<Real> >("d_c", data.get<Real>("d_c"));
+ }
+
+ // Friction Law: Linear Slip Weakening No Healing
+ else if (friction_law == "linear_slip_weakening_no_healing") {
+ if (friction_reg == "no_regularisation") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegNoRegularisation>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegNoRegularisation>(contact);
+ }
+ else if (friction_reg == "rubin_ampuero") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegRubinAmpuero>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegRubinAmpuero>(contact);
+
+ friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
+ }
+ else if (friction_reg == "simplified_prakash_clifton") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+
+ friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
+ }
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+
+ friction->setMixed< SynchronizedArray<Real> >("mu_s", data.get<Real>("mu_s"));
+ friction->setMixed< SynchronizedArray<Real> >("mu_k", data.get<Real>("mu_k"));
+ friction->setMixed< SynchronizedArray<Real> >("d_c", data.get<Real>("d_c"));
+ }
+
+ // Friction Law: Linear Cohesive
+ else if (friction_law == "linear_cohesive") {
+ if (friction_reg == "no_regularisation") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegNoRegularisation>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegNoRegularisation>(contact);
+ }
+ else if (friction_reg == "rubin_ampuero") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegRubinAmpuero>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegRubinAmpuero>(contact);
+
+ friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
+ }
+ else if (friction_reg == "simplified_prakash_clifton") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+
+ friction->setMixed< SynchronizedArray<Real> >("t_star", data.get<Real>("t_star"));
+ }
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+
+ friction->setMixed< SynchronizedArray<Real> >("G_c", data.get<Real>("G_c"));
+ friction->setMixed< SynchronizedArray<Real> >("tau_c", data.get<Real>("tau_c"));
+ friction->setMixed< SynchronizedArray<Real> >("tau_r", data.get<Real>("tau_r"));
+ }
+
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction law: "
+ << friction_law);
+ }
+
+ AKANTU_DEBUG_OUT();
+ return friction;
+}
+
+/* -------------------------------------------------------------------------- */
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact) {
+ AKANTU_DEBUG_IN();
+ std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
+ sub_sect = getStaticParser().getSubSections(_st_friction);
+
+ Parser::const_section_iterator it = sub_sect.first;
+ const ParserSection & section = *it;
+
+ std::string friction_law = section.getName();
+ std::string friction_reg = section.getOption();
+ if (friction_reg == "") {
+ std::string friction_reg = "no_regularisation";
+ }
+
+ NTNBaseFriction * friction = initializeNTNFriction(contact,
+ friction_law,
+ friction_reg);
+
+ friction->parseSection(section);
+
+ if (++it != sub_sect.second) {
+ AKANTU_DEBUG_WARNING("There were several friction sections in input file. "
+ << "Only first one was used and all others ignored.");
+ }
+
+ AKANTU_DEBUG_OUT();
+ return friction;
+}
+
+
+/* -------------------------------------------------------------------------- */
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
+ const std::string & friction_law,
+ const std::string & friction_reg) {
+ AKANTU_DEBUG_IN();
+
+ NTNBaseFriction * friction;
+
+ // check whether is is node-to-rigid-flat contact or mIIasym (which is also ntrf)
+ bool is_ntn_contact = true;
+ if (dynamic_cast<NTRFContact *>(contact) != NULL ||
+ dynamic_cast<MIIASYMContact *>(contact) != NULL) {
+ is_ntn_contact = false;
+ }
+
+ if (friction_law == "coulomb") {
+ if (friction_reg == "no_regularisation") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawCoulomb,
+ NTNFricRegNoRegularisation>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawCoulomb,
+ NTNFricRegNoRegularisation>(contact);
+ }
+ else if (friction_reg == "rubin_ampuero") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawCoulomb,
+ NTNFricRegRubinAmpuero>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawCoulomb,
+ NTNFricRegRubinAmpuero>(contact);
+ }
+ else if (friction_reg == "simplified_prakash_clifton") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawCoulomb,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawCoulomb,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ }
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+ }
+
+ // Friction Law: Linear Slip Weakening
+ else if (friction_law == "linear_slip_weakening") {
+ if (friction_reg == "no_regularisation") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegNoRegularisation>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegNoRegularisation>(contact);
+ }
+ else if (friction_reg == "rubin_ampuero") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegRubinAmpuero>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegRubinAmpuero>(contact);
+ }
+ else if (friction_reg == "simplified_prakash_clifton") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakening,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ }
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+ }
+
+
+ // Friction Law: Linear Slip Weakening No Healing
+ else if (friction_law == "linear_slip_weakening_no_healing") {
+ if (friction_reg == "no_regularisation") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegNoRegularisation>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegNoRegularisation>(contact);
+ }
+ else if (friction_reg == "rubin_ampuero") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegRubinAmpuero>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegRubinAmpuero>(contact);
+ }
+ else if (friction_reg == "simplified_prakash_clifton") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearSlipWeakeningNoHealing,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ }
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+ }
+
+ // Friction Law: Linear Cohesive
+ else if (friction_law == "linear_cohesive") {
+ if (friction_reg == "no_regularisation") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegNoRegularisation>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegNoRegularisation>(contact);
+ }
+ else if (friction_reg == "rubin_ampuero") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegRubinAmpuero>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegRubinAmpuero>(contact);
+ }
+ else if (friction_reg == "simplified_prakash_clifton") {
+ if (is_ntn_contact)
+ friction = new NTNFriction<NTNFricLawLinearCohesive,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ else
+ friction = new NTRFFriction<NTNFricLawLinearCohesive,
+ NTNFricRegSimplifiedPrakashClifton>(contact);
+ }
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction regularisation: "
+ << friction_reg);
+ }
+ }
+ else {
+ AKANTU_DEBUG_ERROR("Do not know the following friction law: "
+ << friction_law);
+ }
+
+ AKANTU_DEBUG_OUT();
+ return friction;
+}
+
+
+__END_AKANTU__
diff --git a/src/geometry/aabb_primitives/aabb_primitive.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh
similarity index 55%
copy from src/geometry/aabb_primitives/aabb_primitive.cc
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh
index 6d5324f33..c28a1e9cd 100644
--- a/src/geometry/aabb_primitives/aabb_primitive.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh
@@ -1,48 +1,48 @@
/**
- * @file aabb_primitive.cc
+ * @file ntn_initiation_function.hh
*
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Tue Jun 2 2015
- * @date last modification: Tue Jun 2 2015
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief Macro classe (primitive) for AABB CGAL algos
+ * @brief initiation ntn and ntrf friction
*
* @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 "aabb_primitive.hh"
+// simtools
+#include "parameter_reader.hh"
+#include "ntrf_contact.hh"
+#include "ntn_base_friction.hh"
__BEGIN_AKANTU__
-Triangle_primitive::Point Triangle_primitive::reference_point() const {
- return primitive.vertex(0);
-}
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
+ ParameterReader & data);
+
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact);
-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);
-}
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
+ const std::string & friction_law,
+ const std::string & friction_reg);
__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc
new file mode 100644
index 000000000..24cb3fa45
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.cc
@@ -0,0 +1,314 @@
+/**
+ * @file ntrf_contact.cc
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntrf_contact.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+NTRFContact::NTRFContact(SolidMechanicsModel & model,
+ const ContactID & id,
+ const MemoryID & memory_id) :
+ NTNBaseContact(model,id,memory_id),
+ reference_point(model.getSpatialDimension()),
+ normal(model.getSpatialDimension())
+{
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::setReferencePoint(Real x, Real y, Real z) {
+ AKANTU_DEBUG_IN();
+
+ Real coord[3];
+ coord[0] = x;
+ coord[1] = y;
+ coord[2] = z;
+
+ UInt dim = this->model.getSpatialDimension();
+ for (UInt d=0; d<dim; ++d)
+ this->reference_point(d) = coord[d];
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::setNormal(Real x, Real y, Real z) {
+ AKANTU_DEBUG_IN();
+
+ UInt dim = this->model.getSpatialDimension();
+
+ Real coord[3];
+ coord[0] = x;
+ coord[1] = y;
+ coord[2] = z;
+
+ for (UInt d=0; d<dim; ++d)
+ this->normal(d) = coord[d];
+
+ this->normal.normalize();
+
+ this->updateNormals();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::addSurface(const Surface & surf) {
+ AKANTU_DEBUG_IN();
+
+ const Mesh & mesh_ref = this->model.getFEEngine().getMesh();
+
+ try {
+ const ElementGroup & boundary = mesh_ref.getElementGroup(surf);
+ this->contact_surfaces.insert(&boundary);
+
+ // find slave nodes
+ for(ElementGroup::const_node_iterator nodes_it(boundary.node_begin());
+ nodes_it!= boundary.node_end();
+ ++nodes_it) {
+ if (!this->model.isPBCSlaveNode(*nodes_it)) {
+ this->addSplitNode(*nodes_it);
+ }
+ }
+ } catch (debug::Exception e) {
+ AKANTU_DEBUG_INFO("NTRFContact addSurface did not found subboundary " << surf
+ << " and ignored it. Other procs might have it :)");
+ }
+
+ // synchronize with depending nodes
+ findBoundaryElements(this->slaves.getArray(), this->slave_elements);
+ updateInternalData();
+ syncArrays(_added);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::addNodes(Array<UInt> & nodes) {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_nodes = nodes.getSize();
+ UInt nb_compo = nodes.getNbComponent();
+ for (UInt n=0; n<nb_nodes; ++n) {
+ for (UInt c=0; c<nb_compo; ++c) {
+ this->addSplitNode(nodes(n,c));
+ }
+ }
+
+ // synchronize with depending nodes
+ findBoundaryElements(this->slaves.getArray(), this->slave_elements);
+ updateInternalData();
+ syncArrays(_added);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::updateNormals() {
+ AKANTU_DEBUG_IN();
+
+ // normal is the same for all slaves
+ this->normals.set(this->normal);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::updateImpedance() {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_contact_nodes = getNbContactNodes();
+ Real delta_t = this->model.getTimeStep();
+ AKANTU_DEBUG_ASSERT(delta_t != NAN, "Time step is NAN. Have you set it already?");
+
+ const Array<Real> & mass = this->model.getMass();
+
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ UInt slave = this->slaves(n);
+
+ Real imp = this->lumped_boundary_slaves(n) / mass(slave);
+ imp = 2 / delta_t / imp;
+ this->impedance(n) = imp;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const {
+ AKANTU_DEBUG_IN();
+
+ // resize arrays to zero
+ rel_tang_field.resize(0);
+
+ UInt dim = this->model.getSpatialDimension();
+
+ Array<Real>::const_iterator< Vector<Real> > it_field = field.begin(dim);
+ Array<Real>::const_iterator< Vector<Real> > it_normal = this->normals.getArray().begin(dim);
+
+ Vector<Real> rfv(dim);
+ Vector<Real> np_rfv(dim);
+
+ UInt nb_contact_nodes = this->slaves.getSize();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // nodes
+ UInt node = this->slaves(n);
+
+ // relative field vector
+ rfv = it_field[node];;
+
+ // normal projection of relative field
+ const Vector<Real> & normal_v = it_normal[n];
+ np_rfv = normal_v;
+ np_rfv *= rfv.dot(normal_v);
+
+ // subtract normal projection from relative field to get the tangential projection
+ rfv -= np_rfv;
+ rel_tang_field.push_back(rfv);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::computeNormalGap(Array<Real> & gap) const {
+ AKANTU_DEBUG_IN();
+
+ gap.resize(0);
+
+ UInt dim = this->model.getSpatialDimension();
+
+ Array<Real>::const_iterator< Vector<Real> > it_cur_pos = this->model.getCurrentPosition().begin(dim);
+ Array<Real>::const_iterator< Vector<Real> > it_normal = this->normals.getArray().begin(dim);
+
+ Vector<Real> gap_v(dim);
+
+ UInt nb_contact_nodes = this->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // nodes
+ UInt node = this->slaves(n);
+
+ // gap vector
+ gap_v = it_cur_pos[node];
+ gap_v -= this->reference_point;
+
+ // length of normal projection of gap vector
+ const Vector<Real> & normal_v = it_normal[n];
+ gap.push_back(gap_v.dot(normal_v));
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::computeRelativeNormalField(const Array<Real> & field,
+ Array<Real> & rel_normal_field) const {
+ AKANTU_DEBUG_IN();
+
+ // resize arrays to zero
+ rel_normal_field.resize(0);
+
+ UInt dim = this->model.getSpatialDimension();
+
+ Array<Real>::const_iterator< Vector<Real> > it_field = field.begin(dim);
+ Array<Real>::const_iterator< Vector<Real> > it_normal = this->normals.getArray().begin(dim);
+
+ UInt nb_contact_nodes = this->getNbContactNodes();
+ for (UInt n=0; n<nb_contact_nodes; ++n) {
+ // nodes
+ UInt node = this->slaves(n);
+
+ const Vector<Real> & field_v = it_field[node];
+ const Vector<Real> & normal_v = it_normal[n];
+
+ rel_normal_field.push_back(field_v.dot(normal_v));
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::printself(std::ostream & stream, int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTRFContact [" << std::endl;
+ NTNBaseContact::printself(stream,indent);
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NTRFContact::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+ /*
+#ifdef AKANTU_USE_IOHELPER
+ const Array<UInt> & nodal_filter = this->slaves.getArray();
+
+#define ADD_FIELD(field_id, field, type) \
+ internalAddDumpFieldToDumper(dumper_name, \
+ field_id, \
+ new DumperIOHelper::NodalField< type, true, \
+ Array<type>, \
+ Array<UInt> >(field, 0, 0, &nodal_filter))
+ */
+
+ /*
+ if(field_id == "displacement") {
+ ADD_FIELD(field_id, this->model.getDisplacement(), Real);
+ }
+ else if(field_id == "contact_pressure") {
+ internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new DumperIOHelper::NodalField<Real>(this->contact_pressure.getArray()));
+ }
+ else {*/
+ NTNBaseContact::addDumpFieldToDumper(dumper_name, field_id);
+ //}
+
+ /*
+#undef ADD_FIELD
+#endif
+ */
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/src/common/aka_circular_array.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh
similarity index 57%
copy from src/common/aka_circular_array.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh
index 5a94c6c9c..4f534e6e5 100644
--- a/src/common/aka_circular_array.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh
@@ -1,139 +1,128 @@
/**
- * @file aka_circular_array.hh
+ * @file ntrf_contact.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Fri Nov 11 2011
- * @date last modification: Mon Jun 02 2014
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief class of circular array
+ * @brief contact for node to rigid flat 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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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"
+#ifndef __AST_NTRF_CONTACT_HH__
+#define __AST_NTRF_CONTACT_HH__
/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_base_contact.hh"
__BEGIN_AKANTU__
-template<class T>
-class CircularArray : protected Array<T> {
+/* -------------------------------------------------------------------------- */
+class NTRFContact : public NTNBaseContact {
/* ------------------------------------------------------------------------ */
/* 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();
- };
+ NTRFContact(SolidMechanicsModel & model,
+ const ContactID & id = "contact",
+ const MemoryID & memory_id = 0);
+ virtual ~NTRFContact() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- /**
- advance start and end position by one:
- the first element is now at the end of the array
- **/
- inline void makeStep();
+ void setReferencePoint(Real x=0., Real y=0., Real z=0.);
+ void setNormal(Real x=1., Real y=0., Real z=0.);
+
+ /// add surface and nodes according to the surface normal
+ void addSurface(const Surface & surf);
+
+ // add nodes from a list
+ void addNodes(Array<UInt> & nodes);
+
+ /// update (copy the normal to all normals)
+ virtual void updateNormals();
+
+ /// update the impedance matrix
+ virtual void updateImpedance();
+
+ /// compute the normal gap
+ virtual void computeNormalGap(Array<Real> & gap) const;
+
+ /// compute relative normal field (only value that has to be multiplied with the normal)
+ /// relative to master nodes
+ virtual void computeRelativeNormalField(const Array<Real> & field,
+ Array<Real> & rel_normal_field) const;
+
+ /// compute relative tangential field (complet array)
+ /// relative to master nodes
+ virtual void computeRelativeTangentialField(const Array<Real> & field,
+ Array<Real> & rel_tang_field) const;
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
-private:
-
/* ------------------------------------------------------------------------ */
- /* Operators */
+ /* Dumpable */
/* ------------------------------------------------------------------------ */
public:
- inline reference operator()(UInt i, UInt j = 0);
- inline const_reference operator()(UInt i, UInt j = 0) const;
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+ // virtual void addDumpFieldVector(const std::string & field_id);
/* ------------------------------------------------------------------------ */
/* 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;
+ /// reference point for rigid flat surface
+ Vector<Real> reference_point;
+ /// outpointing normal of rigid flat surface
+ Vector<Real> normal;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-#if defined (AKANTU_INCLUDE_INLINE_IMPL)
-# include "aka_circular_array_inline_impl.cc"
-#endif
+//#include "ntrf_contact_inline_impl.cc"
/// standard output stream operator
-template <typename T>
-inline std::ostream & operator <<(std::ostream & stream, const CircularArray<T> & _this)
+inline std::ostream & operator <<(std::ostream & stream, const NTRFContact & _this)
{
_this.printself(stream);
return stream;
}
-
-
__END_AKANTU__
-
-
-#endif /* __AKANTU_AKA_CIRCULAR_ARRAY_HH__ */
-
-
+#endif /* __AST_NTRF_CONTACT_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh
similarity index 59%
copy from src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
copy to extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh
index 5cdaefb9c..31ee29506 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh
@@ -1,98 +1,100 @@
/**
- * @file material_marigo_non_local.hh
+ * @file ntrf_friction.hh
*
- * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
*
- * @date creation: Wed Aug 31 2011
- * @date last modification: Wed Nov 13 2013
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
*
- * @brief Marigo non-local description
+ * @brief friction for node to rigid flat interface
*
* @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 "material_damage_non_local.hh"
-#include "material_marigo.hh"
-/* -------------------------------------------------------------------------- */
-#ifndef __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__
-#define __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__
+#ifndef __AST_NTRF_FRICTION_HH__
+#define __AST_NTRF_FRICTION_HH__
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_friclaw_coulomb.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-
-/**
- * Material Marigo
- *
- * parameters in the material files :
- */
-template<UInt spatial_dimension>
-class MaterialMarigoNonLocal : public MaterialDamageNonLocal<spatial_dimension, MaterialMarigo<spatial_dimension> > {
+template <template<class> class FrictionLaw = NTNFricLawCoulomb,
+ class Regularisation = NTNFricRegNoRegularisation>
+class NTRFFriction : public FrictionLaw<Regularisation> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef MaterialDamageNonLocal<spatial_dimension, MaterialMarigo<spatial_dimension> > MaterialMarigoNonLocalParent;
- MaterialMarigoNonLocal(SolidMechanicsModel & model, const ID & id = "");
-
- virtual ~MaterialMarigoNonLocal() {};
-
+
+ NTRFFriction(NTNBaseContact * contact,
+ const FrictionID & id = "friction",
+ const MemoryID & memory_id = 0);
+ virtual ~NTRFFriction() {};
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
+ /// function to print the contain of the class
+ virtual void printself(std::ostream & stream, int indent = 0) const;
- 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:
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
- AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Y, Y, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-private:
- InternalField<Real> Y;
- InternalField<Real> Ynl;
+protected:
+
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-#include "material_marigo_non_local_inline_impl.cc"
+/// standard output stream operato
+template <template<class> class FrictionLaw, class Regularisation>
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTRFFriction<FrictionLaw,
+ Regularisation> & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
__END_AKANTU__
-#endif /* __AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH__ */
+#include "ntrf_friction_tmpl.hh"
+
+#endif /* __AST_NTRF_FRICTION_HH__ */
+
+
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction_tmpl.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction_tmpl.hh
new file mode 100644
index 000000000..e42cd6a86
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction_tmpl.hh
@@ -0,0 +1,101 @@
+/**
+ * @file ntrf_friction_tmpl.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief implementation of node to rigid flat interface friction
+ *
+ * @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 "ntrf_friction.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <template <class> class FrictionLaw, class Regularisation>
+NTRFFriction<FrictionLaw, Regularisation>::NTRFFriction(NTNBaseContact * contact,
+ const FrictionID & id,
+ const MemoryID & memory_id) :
+ FrictionLaw<Regularisation>(contact,id,memory_id) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <template <class> class FrictionLaw, class Regularisation>
+void NTRFFriction<FrictionLaw, Regularisation>::printself(std::ostream & stream,
+ int indent) const {
+ AKANTU_DEBUG_IN();
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "NTRFFriction [" << std::endl;
+ FrictionLaw<Regularisation>::printself(stream, ++indent);
+ stream << space << "]" << std::endl;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/*
+void NTRFFriction::addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id) {
+ AKANTU_DEBUG_IN();
+
+#ifdef AKANTU_USE_IOHELPER
+ // const SynchronizedArray<UInt> * nodal_filter = &(this->contact.getSlaves());
+
+ if(field_id == "is_sticking") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new DumperIOHelper::NodalField<bool>(this->is_sticking.getArray()));
+ }
+ else if(field_id == "frictional_strength") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new DumperIOHelper::NodalField<Real>(this->frictional_strength.getArray()));
+ }
+ else if(field_id == "friction_traction") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new DumperIOHelper::NodalField<Real>(this->friction_traction.getArray()));
+ }
+ else if(field_id == "slip") {
+ this->internalAddDumpFieldToDumper(dumper_name,
+ field_id,
+ new DumperIOHelper::NodalField<Real>(this->slip.getArray()));
+ }
+ else {
+ this->contact.addDumpFieldToDumper(dumper_name, field_id);
+ }
+
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+*/
+
+__END_AKANTU__
diff --git a/extra_packages/traction-at-split-node-contact/src/tasn_contact.hh b/extra_packages/traction-at-split-node-contact/src/tasn_contact.hh
new file mode 100644
index 000000000..75c332dac
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/tasn_contact.hh
@@ -0,0 +1,68 @@
+/**
+ * @file tasn_contact.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief main include for traction at split node contact
+ *
+ * @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/>.
+ *
+ */
+
+// ast common
+#include "synchronized_array.hh"
+#include "parameter_reader.hh"
+#include "manual_restart.hh"
+
+// functions
+#include "boundary_functions.hh"
+#include "node_filter.hh"
+
+// boundary conditions
+#include "force_based_dirichlet.hh"
+#include "spring_bc.hh"
+#include "inclined_flat_dirichlet.hh"
+
+// ntn/ntrf contact
+#include "ntn_base_contact.hh"
+#include "ntn_contact.hh"
+#include "ntrf_contact.hh"
+#include "mIIasym_contact.hh"
+
+// ntn/ntrf friction
+#include "ntn_base_friction.hh"
+#include "ntn_friction.hh"
+#include "ntrf_friction.hh"
+
+// friction regularisations
+#include "ntn_fricreg_no_regularisation.hh"
+#include "ntn_fricreg_rubin_ampuero.hh"
+#include "ntn_fricreg_simplified_prakash_clifton.hh"
+
+// friction laws
+#include "ntn_friclaw_coulomb.hh"
+#include "ntn_friclaw_linear_slip_weakening.hh"
+#include "ntn_friclaw_linear_slip_weakening_no_healing.hh"
+#include "ntn_friclaw_linear_cohesive.hh"
+
+// initiation of friction
+#include "ntn_initiation_function.hh"
diff --git a/packages/blackdynamite.cmake b/packages/blackdynamite.cmake
index b4ef8ee38..00f5cd853 100644
--- a/packages/blackdynamite.cmake
+++ b/packages/blackdynamite.cmake
@@ -1,41 +1,48 @@
#===============================================================================
# @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 Jan 18 2016
#
# @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")
+
+package_declare_extra_files_to_package(BlackDynamite
+ PROJECT third-party/cmake/blackdynamite.cmake
+ )
diff --git a/packages/blas.cmake b/packages/blas.cmake
index ac1c90bfd..e43d83d33 100644
--- a/packages/blas.cmake
+++ b/packages/blas.cmake
@@ -1,81 +1,91 @@
#===============================================================================
-# @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: Mon Jan 18 2016
#
# @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}"
)
+
+package_set_package_system_dependency(BLAS deb libblas3)
+package_set_package_system_dependency(BLAS deb-src libblas3)
+
+package_declare_extra_files_to_package(BLAS
+ PROJECT
+ third-party/cmake/blas.cmake
+ third-party/blas_3.5.0_make.inc.cmake
+ )
diff --git a/packages/boost.cmake b/packages/boost.cmake
index a2b62ea41..ac61ea588 100644
--- a/packages/boost.cmake
+++ b/packages/boost.cmake
@@ -1,49 +1,68 @@
#===============================================================================
# @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: Wed Jan 20 2016
#
# @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)
+ package_set_compile_flags(Boost CXX -DBOOST_SPIRIT_USE_PHOENIX_V3)
else()
- remove_flags(cxx -DBOOST_SPIRIT_USE_PHOENIX_V3)
+ package_unset_compile_flags(Boost CXX)
endif()
endif()
")
+
+
+package_declare_documentation(Boost
+ "Akantu uses Boost header only for preprocessor and Spirit"
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ "\\begin{command}"
+ " > sudo apt-get install libboost"
+ "\\end{command}"
+ ""
+)
+
+package_set_package_system_dependency(Boost deb-src libboost-dev)
+
+# only build dependency
+# package_set_package_system_dependency(Boost deb libboost)
+# package_set_package_system_dependency(Boost rmp boost)
diff --git a/packages/cgal.cmake b/packages/cgal.cmake
index 0b13d94a6..557f04c91 100644
--- a/packages/cgal.cmake
+++ b/packages/cgal.cmake
@@ -1,72 +1,75 @@
#===============================================================================
# @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: Wed Jan 20 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"
+ COMPILE_FLAGS CXX -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."
)
+
+package_set_package_system_dependency(CGAL deb-src "libcgal-dev >= 4.5")
diff --git a/packages/cohesive_element.cmake b/packages/cohesive_element.cmake
index 14b397cee..334840d1d 100644
--- a/packages/cohesive_element.cmake
+++ b/packages/cohesive_element.cmake
@@ -1,121 +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
deleted file mode 100644
index 6d7bd8ec9..000000000
--- a/packages/contact.cmake
+++ /dev/null
@@ -1,79 +0,0 @@
-#===============================================================================
-# @file 20_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
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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..70e2c03fa 100644
--- a/packages/core.cmake
+++ b/packages/core.cmake
@@ -1,484 +1,492 @@
#===============================================================================
-# @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 18 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()
+
+package_declare_extra_files_to_package(core
+ SOURCES
+ common/aka_element_classes_info.hh.in
+ common/aka_config.hh.in
+ model/solid_mechanics/material_list.hh.in
+ )
diff --git a/packages/core_cxx11.cmake b/packages/core_cxx11.cmake
index 95964b330..9aaa78d18 100644
--- a/packages/core_cxx11.cmake
+++ b/packages/core_cxx11.cmake
@@ -1,67 +1,51 @@
#===============================================================================
-# @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: Fri Jan 22 2016
#
# @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}")
+ COMPILE_FLAGS CXX "${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
deleted file mode 100644
index c5805141a..000000000
--- a/packages/cpparray.cmake
+++ /dev/null
@@ -1,64 +0,0 @@
-#===============================================================================
-# @file cpp_array.cmake
-#
-# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date Mon Nov 21 18:19:15 2011
-#
-# @brief package description for cpp_array project
-#
-# @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/>.
-#
-#===============================================================================
-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..0e5058094 100644
--- a/packages/damage_non_local.cmake
+++ b/packages/damage_non_local.cmake
@@ -1,81 +1,83 @@
#===============================================================================
-# @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: Mon Jan 18 2016
#
# @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..bfe7dcf31 100644
--- a/packages/documentation_doxygen.cmake
+++ b/packages/documentation_doxygen.cmake
@@ -1,47 +1,53 @@
#===============================================================================
-# @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 Jan 18 2016
#
# @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
+ )
+
+package_set_package_system_dependency(documentation_doxygen deb-src doxygen graphviz)
+
+package_declare_extra_files_to_package(documentation_doxygen
+ PROJECT doc/doxygen/akantu.dox.in)
diff --git a/packages/documentation_manual.cmake b/packages/documentation_manual.cmake
index a649049a7..6d9e0f3da 100644
--- a/packages/documentation_manual.cmake
+++ b/packages/documentation_manual.cmake
@@ -1,40 +1,56 @@
#===============================================================================
-# @file 00_documentation_manual.cmake
+# @file documentation_manual.cmake
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Tue Jun 10 2014
-# @date last modification: Thu Jul 03 2014
+# @date last modification: Mon Jan 18 2016
#
# @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
+"\\end{command}")
+
+package_set_package_system_dependency(documentation_manual deb-src
+ rubber
+ texlive-fonts-recommended
+ texlive-science
+ texlive-picture
+ texlive-extra
+ texlive-math-extra
+ texlive-latex-extra
+ texlive-bibtex-extra
+ )
+
+package_declare_extra_files_to_package(documentation_manual
+ MANUAL version-definition.tex.in
+ PROJECT cmake/Modules/FindInkscape.cmake)
diff --git a/packages/embedded.cmake b/packages/embedded.cmake
index 920125ff1..b223dfbb5 100644
--- a/packages/embedded.cmake
+++ b/packages/embedded.cmake
@@ -1,56 +1,60 @@
#===============================================================================
# @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."
)
+
+#add_example(embedded "Example on how to run embedded model simulation" PACKAGE embedded)
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..b7f7afe67 100644
--- a/packages/iohelper.cmake
+++ b/packages/iohelper.cmake
@@ -1,69 +1,76 @@
#===============================================================================
-# @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: Mon Jan 18 2016
#
# @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."
)
+
+package_declare_extra_files_to_package(IOHelper
+ PROJECT
+ third-party/cmake/iohelper.cmake
+ cmake/Modules/FindIOHelper.cmake
+ )
diff --git a/packages/lapack.cmake b/packages/lapack.cmake
index 41e92649b..69b50a87c 100644
--- a/packages/lapack.cmake
+++ b/packages/lapack.cmake
@@ -1,42 +1,47 @@
#===============================================================================
-# @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 Jan 18 2016
#
# @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}"
)
+
+package_set_package_system_dependency(LAPACK deb liblapack3)
+package_set_package_system_dependency(LAPACK deb-src liblapack-dev)
diff --git a/packages/mpi.cmake b/packages/mpi.cmake
index cea4e214e..cf12e775e 100644
--- a/packages/mpi.cmake
+++ b/packages/mpi.cmake
@@ -1,163 +1,169 @@
#===============================================================================
-# @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 20 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")
+ #package_get_source_files(MPI _srcs _pub _priv)
+ #list(APPEND _srcs "common/aka_error.cc")
- set_property(SOURCE ${_srcs} PROPERTY COMPILE_FLAGS "${_flags}")
+ #set_property(SOURCE ${_srcs} PROPERTY COMPILE_FLAGS "${_flags}")
+ package_set_compile_flags(MPI CXX ${_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}"
)
+
+package_set_package_system_dependency(MPI deb mpi-default-bin)
+package_set_package_system_dependency(MPI deb-src mpi-default-dev)
diff --git a/packages/mumps.cmake b/packages/mumps.cmake
index 7c47c5056..fb5f9d401 100644
--- a/packages/mumps.cmake
+++ b/packages/mumps.cmake
@@ -1,82 +1,100 @@
#===============================================================================
-# @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: Mon Jan 18 2016
#
# @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")
+
+ package_set_package_system_dependency(Mumps deb libmumps)
+ package_set_package_system_dependency(Mumps deb-src libmumps-dev)
else()
package_set_find_package_extra_options(Mumps ARGS COMPONENTS "sequential")
package_add_third_party_script_variable(Mumps MUMPS_TYPE "seq")
+
+ package_set_package_system_dependency(Mumps deb libmumps-seq)
+ package_set_package_system_dependency(Mumps deb-src libmumps-seq-dev)
endif()
package_use_system(Mumps _use_system)
if(NOT _use_system)
enable_language(Fortran)
set(AKANTU_USE_MUMPS_VERSION "4.10.0" CACHE STRING "Default Mumps version to compile")
mark_as_advanced(AKANTU_USE_MUMPS_VERSION)
set_property(CACHE AKANTU_USE_MUMPS_VERSION PROPERTY STRINGS "4.9.2" "4.10.0" "5.0.0")
package_get_option_name(MPI _mpi_option)
if(${_mpi_option})
package_add_dependencies(Mumps ScaLAPACK MPI)
endif()
package_add_dependencies(Mumps Scotch BLAS)
endif()
package_declare_documentation(Mumps
"This package enables the \\href{http://mumps.enseeiht.fr/}{MUMPS} parallel direct solver for sparce matrices."
"This is necessary to solve static or implicit problems."
""
"Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
""
"\\begin{command}"
" > sudo apt-get install libmumps-seq-dev # for sequential"
" > sudo apt-get install libmumps-dev # for parallel"
"\\end{command}"
""
"Under Mac OS X the installation requires the following steps:"
"\\begin{command}"
" > sudo port install mumps"
"\\end{command}"
""
"If you activate the advanced option AKANTU\\_USE\\_THIRD\\_PARTY\\_MUMPS the make system of akantu can automatically compile MUMPS. For this you will have to download MUMPS from \\url{http://mumps.enseeiht.fr/} or \\url{http://graal.ens-lyon.fr/MUMPS} and place it in \\shellcode{<akantu source>/third-party}"
)
+
+package_declare_extra_files_to_package(MUMPS
+ PROJECT
+ third-party/MUMPS_4.10.0_make.inc.cmake
+ third-party/MUMPS_5.0.0.patch
+ third-party/MUMPS_4.10.0.patch
+ third-party/MUMPS_4.9.2_make.inc.cmake
+ third-party/cmake/mumps.cmake
+ cmake/Modules/FindMumps.cmake
+ )
diff --git a/packages/nlopt.cmake b/packages/nlopt.cmake
deleted file mode 100644
index bb397f123..000000000
--- a/packages/nlopt.cmake
+++ /dev/null
@@ -1,83 +0,0 @@
-#===============================================================================
-# @file 80_nlopt.cmake
-#
-# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Thu Jun 05 2014
-# @date last modification: Thu Sep 18 2014
-#
-# @brief package for the opitmization library NLopt
-#
-# @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/>.
-#
-#===============================================================================
-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..158ac82cb 100644
--- a/packages/numpy.cmake
+++ b/packages/numpy.cmake
@@ -1,27 +1,48 @@
-# @file pythonlibs.cmake
+#===============================================================================
+# @file numpy.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Tue Nov 29 2011
+# @date last modification: Tue Jan 19 2016
+#
# @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")
+
+package_declare_documentation(Numpy
+ "This package allows to wrap Akantu arrays to numpy arrays"
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ "\\begin{command}"
+ " > sudo apt-get install python-numpy"
+ "\\end{command}"
+ ""
+)
+
+package_set_package_system_dependency(Numpy deb python-numpy)
+package_set_package_system_dependency(Numpy deb-src python-numpy)
+
+package_declare_extra_files_to_package(Numpy
+ PROJECT cmake/Modules/FindNumpy.cmake)
diff --git a/packages/optimization.cmake b/packages/optimization.cmake
deleted file mode 100644
index 1f331dbc1..000000000
--- a/packages/optimization.cmake
+++ /dev/null
@@ -1,46 +0,0 @@
-#===============================================================================
-# @file 40_optimization.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Fri Jan 04 2013
-# @date last modification: Wed Jul 30 2014
-#
-# @brief Optimization external library interface
-#
-# @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/>.
-#
-#===============================================================================
-
-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..07ecc388b 100644
--- a/packages/petsc.cmake
+++ b/packages/petsc.cmake
@@ -1,46 +1,67 @@
#===============================================================================
# @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: Tue Jan 19 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
)
+package_declare_extra_files_to_package(PETSc
+ PROJECT
+ cmake/Modules/FindPETSc.cmake
+ cmake/Modules/FindPackageMultipass.cmake
+ cmake/Modules/ResolveCompilerPaths.cmake
+ cmake/Modules/CorrectWindowsPaths.cmake
+ )
+
+package_declare_documentation(PETSc
+ "This package enables PETSc as a solver in Akantu"
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ "\\begin{command}"
+ " > sudo apt-get install libpetsc3.4.2-dev"
+ "\\end{command}"
+ ""
+)
+
+package_set_package_system_dependency(PETSc deb libpetsc3.4.2)
+package_set_package_system_dependency(PETSc deb-src libpetsc3.4.2-dev)
diff --git a/packages/python_interface.cmake b/packages/python_interface.cmake
index f42968306..bb06880b2 100644
--- a/packages/python_interface.cmake
+++ b/packages/python_interface.cmake
@@ -1,30 +1,62 @@
#===============================================================================
# @file python_interface.cmake
#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
+# @date creation: Tue Nov 29 2011
+# @date last modification: Fri Jan 22 2016
+#
# @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)
+ DEPENDS PythonLibs core_cxx11)
+
+package_declare_sources(python_interface
+ 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
+ )
+
+
+package_set_package_system_dependency(python_interface deb-src swig3.0)
+
+package_declare_documentation(python_interface
+ "This package enables the python interface of Akantu. It relies on swig3.0 to generate the code"
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ "\\begin{command}"
+ " > sudo apt-get install swig3.0"
+ "\\end{command}"
+ ""
+)
+
+package_declare_documentation_files(python_interface
+ manual-python.tex
+ )
diff --git a/packages/pythonlibs.cmake b/packages/pythonlibs.cmake
index 5b9c22444..8ab88defe 100644
--- a/packages/pythonlibs.cmake
+++ b/packages/pythonlibs.cmake
@@ -1,42 +1,51 @@
#===============================================================================
# @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: Fri Jan 22 2016
+#
# @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
- )
+package_set_package_system_dependency(PythonLibs deb libpython2.7)
+package_set_package_system_dependency(PythonLibs deb-src libpython2.7-dev)
+
+package_declare_documentation(PythonLibs
+ "This package is a dependency of the python interface"
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ "\\begin{command}"
+ " > sudo apt-get install libpython2.7-dev"
+ "\\end{command}"
+ ""
+)
diff --git a/packages/qview.cmake b/packages/qview.cmake
index 81a3b4890..313a0ae3f 100644
--- a/packages/qview.cmake
+++ b/packages/qview.cmake
@@ -1,35 +1,41 @@
#===============================================================================
# @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 Jan 18 2016
#
# @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
)
+
+package_declare_extra_files_to_package(QVIEW
+ PROJECT cmake/Modules/FindQVIEW.cmake)
diff --git a/packages/scalapack.cmake b/packages/scalapack.cmake
index db263c4e5..384f24085 100644
--- a/packages/scalapack.cmake
+++ b/packages/scalapack.cmake
@@ -1,42 +1,64 @@
#===============================================================================
# @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: Tue Jan 19 2016
#
# @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")
+
+package_set_package_system_dependency(ScaLAPACK deb-src libscalapack-mpi-dev)
+
+package_declare_extra_files_to_package(ScaLAPACK
+ PROJECT
+ third-party/scalapack_2.0.2.patch
+ third-party/cmake/scalapack.cmake
+ cmake/Modules/FindScaLAPACK.cmake
+ )
+
+
+package_declare_documentation(ScaLAPACK
+ "ScaLAPACK is used to compile mumps as a third-party"
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ "\\begin{command}"
+ " > sudo apt-get install libscalapack-mpi-dev"
+ "\\end{command}"
+ ""
+)
diff --git a/packages/scotch.cmake b/packages/scotch.cmake
index dad1b0ca6..0ec04f04c 100644
--- a/packages/scotch.cmake
+++ b/packages/scotch.cmake
@@ -1,95 +1,108 @@
#===============================================================================
-# @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 Jan 18 2016
#
# @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()
+
+package_set_package_system_dependency(Scotch deb libscotch)
+package_set_package_system_dependency(Scotch deb-src libscotch-dev)
+
+package_declare_extra_files_to_package(Scotch
+ PROJECT
+ third-party/cmake/scotch.cmake
+ third-party/scotch_5.1.12b.patch
+ third-party/scotch_5.1.12b_make.inc.cmake
+ cmake/Modules/FindScotch.cmake
+ )
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 122e8ae1b..04b727722 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -1,237 +1,301 @@
#===============================================================================
# @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: Mon Jan 18 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
#===============================================================================
-find_package(SWIG 3.0)
+
+set(SWIG_REQURIED_VERISON 3.0)
+find_package(SWIG ${SWIG_REQURIED_VERISON})
+find_package(PythonInterp 2.7 REQUIRED)
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(
+set(_swig_include_dirs
${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)
+function(swig_generate_dependencies _module _depedencies _depedencies_out)
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()
+ set(${_depedencies_out} ${_swig_${_module_we}_depends} PARENT_SCOPE)
+
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})
+ cmake_parse_arguments(_swig_opt "" "OUTPUT_DIR;DEPENDENCIES" "EXTRA_FLAGS;INCLUDE_DIRECTORIES" ${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)
+ list(APPEND _include_directories ${_swig_opt_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)
+ swig_generate_dependencies(${_module} _module_dependencies _depends_out)
+ if(_swig_opt_DEPENDENCIES)
+ set(${_swig_opt_DEPENDENCIES} ${_depends_out} PARENT_SCOPE)
+ endif()
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(_wrapper "${_output_dir}/${_module_we}_wrapper.cpp")
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})
+ EXTRA_FLAGS ${AKANTU_SWIG_FLAGS}
+ DEPENDENCIES _deps
+ INCLUDE_DIRECTORIES ${_swig_include_dirs})
if(AKANTU_SWIG_WRAPPERS_CPP)
- add_library(_akantu MODULE ${AKANTU_SWIG_WRAPPERS_CPP})
- target_link_libraries(_akantu akantu)
+ string(REPLACE ";" "', '" _ext_files "${AKANTU_SWIG_WRAPPERS_CPP}")
+ string(REPLACE ";" "', '" _inc_dirs "${_swig_include_dirs}")
+ string(STRIP "${AKANTU_EXTRA_CXX_FLAGS}" _tmp_flags)
+ string(REGEX REPLACE " +" "', '" _flags "${_tmp_flags} -Wno-maybe-uninitialized")
- set_target_properties(_akantu PROPERTIES PREFIX "")
+ if(CMAKE_VERBOSE_MAKEFILE)
+ set(_quiet)
+ else()
+ set(_quiet --quiet)
+ endif()
- list(APPEND AKANTU_EXPORT_LIST _akantu)
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/setup.py "
+from distutils.core import setup
+from distutils.core import setup, Extension
+import os
+
+
+os.environ['CC'] = '${CMAKE_CXX_COMPILER}'
+os.environ['CXX'] = '${CMAKE_CXX_COMPILER}'
+setup(name='akantu',
+ license='LGPLv3',
+ version='${AKANTU_VERSION}',
+ py_modules=['akantu'],
+ ext_modules=[Extension('_akantu', ['${_ext_files}'],
+ include_dirs=['${_inc_dirs}'],
+ language='c++',
+ libraries=['akantu'],
+ library_dirs=['${PROJECT_BINARY_DIR}/src'],
+ extra_compile_args=['${_flags}'])],
+ )
+")
- 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 ...
+ add_custom_target(_akantu ALL
+ COMMAND ${PYTHON_EXECUTABLE} ./setup.py ${_quiet} --no-user-cfg build_ext --inplace
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${AKANTU_SWIG_WRAPPERS_CPP} akantu
+ COMMENT "Building akantu's python interface"
)
- install(FILES ${AKANTU_WRAPPERS_PYTHON}
- DESTINATION lib COMPONENT python
- )
+ set_directory_properties(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/_akantu${CMAKE_SHARED_MODULE_SUFFIX})
-endif()
+ # 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
+ # )
+
+ install(CODE "execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} ./setup.py ${_quiet} install --prefix=${AKANTU_PYTHON_INSTALL_PREFIX}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ )"
+ COMPONENT python)
+
+ package_declare_extra_files_to_package(python_interface ${_deps} ${PROJECT_SOURCE_DIR}/python/${AKANTU_SWIG_MODULES})
+endif()
diff --git a/python/swig/aka_array.i b/python/swig/aka_array.i
index 3f220cb6d..a384fc884 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 wrapper for arrays
+ *
+ * @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 8a98d0748..95984de36 100644
--- a/python/swig/aka_common.i
+++ b/python/swig/aka_common.i
@@ -1,80 +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 wrapper to aka_common.hh
+ *
+ * @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):
- _initializeWithArgv(input_file, argv)
+ 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..7154152aa 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 csr wrapper
+ *
+ * @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..c9c099045 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 heat transfer model wrapper
+ *
+ * @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 d29a38ac3..f86a7c23d 100644
--- a/python/swig/mesh.i
+++ b/python/swig/mesh.i
@@ -1,141 +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 mesh wrapper
+ *
+ * @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));
- std::cout << "Nb_cohesives : " << $self->getNbElement(type) << std::endl;
+ 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());
+ $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::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);
+
+ 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> & getGroupedArray(akantu::Array<akantu::Real, true> & surface_array, akantu::SolidMechanicsModel & model, int type) {
akantu::Array<akantu::Real> * full_array;
- switch (type) {
-
+ 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);
+
+ 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){
+ 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..e5984ff34 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 mesh_utils wrapper
+ *
+ * @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..59ea5a929 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 model wrapper
+ *
+ * @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/solid_mechanics_model.i b/python/swig/solid_mechanics_model.i
index c9ed3632b..1c27b06f6 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 solid mechanics model wrapper
+ *
+ * @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 bc95c9d96..236a756c3 100644
--- a/python/swig/solid_mechanics_model_cohesive.i
+++ b/python/swig/solid_mechanics_model_cohesive.i
@@ -1,25 +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..bb0590580 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 structural mechanics model wrapper
+ *
+ * @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 eec0171ea..d165d6806 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,157 +1,170 @@
#===============================================================================
# @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 creation: Mon Jun 14 2010
+# @date last modification: Wed Jan 20 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
)
+package_get_all_compilation_flags(CXX _cxx_flags)
+set(AKANTU_EXTRA_CXX_FLAGS "${_cxx_flags}" CACHE STRING "Extra flags defined by loaded packages" FORCE)
+mark_as_advanced(AKANTU_EXTRA_CXX_FLAGS)
+
#===========================================================================
# header for blas/lapack (any other fortran libraries)
#===========================================================================
package_is_activated(BLAS _blas_activated)
package_is_activated(LAPACK _lapack_activated)
if(_blas_activated OR _lapack_activated)
if(CMAKE_Fortran_COMPILER)
# ugly hack
set(CMAKE_Fortran_COMPILER_LOADED TRUE)
endif()
include(FortranCInterface)
FortranCInterface_HEADER(
${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh
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})
-target_link_libraries(akantu ${AKANTU_EXTERNAL_LIBRARIES})
+
+# the repetition is ugly but works for static libraries
+target_link_libraries(akantu ${AKANTU_EXTERNAL_LIBRARIES} ${AKANTU_EXTERNAL_LIBRARIES})
+
+set_target_properties(akantu
+ PROPERTIES
+ ${AKANTU_LIBRARY_PROPERTIES} # this contains the version
+ PUBLIC_HEADER "${AKANTU_LIBRARY_PUBLIC_HDRS}"
+ COMPILE_FLAGS "${_cxx_flags}"
+ LINK_INTERFACE_MULTIPLICITY 2)
package_get_all_extra_dependencies(_extra_target_dependencies)
if(_extra_target_dependencies)
# This only adding todo: find a solution for when a dependency was add the is removed...
add_dependencies(akantu ${_extra_target_dependencies})
endif()
-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)
+
+# print out the list of materials
+generate_material_list()
diff --git a/src/common/aka_array.cc b/src/common/aka_array.cc
index 45a8a3211..f8fa5c317 100644
--- a/src/common/aka_array.cc
+++ b/src/common/aka_array.cc
@@ -1,115 +1,121 @@
/**
* @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(const ID & id)
+ : id(id), allocated_size(0), size(0), nb_component(1), size_of_type(0) {}
/* -------------------------------------------------------------------------- */
-ArrayBase::~ArrayBase() {
-}
+ArrayBase::~ArrayBase() {}
/* -------------------------------------------------------------------------- */
void ArrayBase::printself(std::ostream & stream, int indent) const {
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ 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 << " + 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);
+ for (; (i < size) && (fabs(values[i] - elem) <= epsilon); ++i)
+ ;
AKANTU_DEBUG_OUT();
- return (i == size) ? -1 : (Int) i;
+ return (i == size) ? -1 : (Int)i;
}
-
/* -------------------------------------------------------------------------- */
template <>
-Array<ElementType> & Array<ElementType>::operator*=(__attribute__((unused)) const ElementType & alpha) {
+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) {
+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) {
+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) {
+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) {
+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) {
+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..b651ba3c9 100644
--- a/src/common/aka_array.hh
+++ b/src/common/aka_array.hh
@@ -1,368 +1,381 @@
/**
* @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: Fri Jan 22 2016
*
* @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 */
+ /* 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 {
+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 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 = "");
+ 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 = "");
+ 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 = "");
+ 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 = "");
+ 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);
+ /// 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 >
+ 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;
+ 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;
+ 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;
+ 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)
+ /// 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)
+ /// 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)
+ /// 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)
+ /// 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))
+ /// 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))
+ /// 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))
+ /// 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)
+ /// 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)
+ /// 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)
+ /// 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>
+ 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);
+ 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);
+ 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
+ /// 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
+ /// 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;
+ /// @see Array::find(const_reference elem) const
+ template <template <typename> class C> inline Int find(const C<T> & elem);
/// set all entries of the array to 0
- inline void clear() { std::fill_n(values, size*nb_component, T()); }
+ 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); }
+ 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);
+ 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)
-{
+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)
-{
+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..52fbfccf7 100644
--- a/src/common/aka_array_tmpl.hh
+++ b/src/common/aka_array_tmpl.hh
@@ -1,1298 +1,1462 @@
/**
* @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 Jan 22 2016
*
* @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(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];
+ "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(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];
+ "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 << "\"");
+ 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 << "\"");
+ 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
+ * @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);
+ 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 */
+ * @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);
+ 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>
+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 << ").");
+ 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);
+ resizeUnitialized(size + 1);
T * tmp = values + nb_component * pos;
- std::uninitialized_copy(new_elem.storage(), new_elem.storage() + nb_component, tmp);
+ 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) {
+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);
+ 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){
+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 << ")");
-
+ 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)) {
+ if (i != (size - 1)) {
for (UInt j = 0; j < nb_component; ++j) {
- values[i*nb_component + j] = values[(size-1)*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
+ * 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");
+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) {
+ for (UInt i = 0; i < size * nb_component; ++i) {
*a -= *b;
- ++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");
+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) {
+ 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) {
+ 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
+ * @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());
+ 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>
+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) {
+ 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) {
+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) {
+ if (!is_scal) {
T val = T();
- std::uninitialized_fill(values, values + size*nb_component, val);
+ 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) {
+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) {
+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);
+ 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) {
+Array<T, is_scal>::Array(const Array<T, is_scal> & vect, bool deep,
+ const ID & id)
+ : ArrayBase(vect) {
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);
+ 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) {
+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);
+ std::uninitialized_copy(&(vect[0]), &(vect[size - 1]), tmp);
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
-template <class T, bool is_scal>
-Array<T, is_scal>::~Array () {
+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 <<")");
+ AKANTU_DEBUG(dblAccessory,
+ "Freeing " << printMemorySize<T>(allocated_size * nb_component)
+ << " (" << id << ")");
- if(values){
- if(!is_scal)
+ if (values) {
+ if (!is_scal)
for (UInt i = 0; i < size * nb_component; ++i) {
- T * obj = values+i;
- obj->~T();
+ 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) {
+void Array<T, is_scal>::allocate(UInt size, UInt nb_component) {
AKANTU_DEBUG_IN();
- if (size == 0){
+ if (size == 0) {
values = NULL;
} else {
- values = static_cast<T*>(malloc(nb_component * size * sizeof(T)));
+ values = static_cast<T *>(malloc(nb_component * size * sizeof(T)));
AKANTU_DEBUG_ASSERT(values != NULL,
- "Cannot allocate "
- << printMemorySize<T>(size*nb_component)
- << " (" << id <<")");
+ "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 <<")");
+ << 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) {
+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) {
+ if (new_size < size) {
for (UInt i = new_size * nb_component; i < size * nb_component; ++i) {
- T * obj = old_values+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);
+ 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 <<")");
+ 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 << "]");
+ 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));
+ 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_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));
+ 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;
+ 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");
+ 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)));
+ values = static_cast<T *>(
+ realloc(values, nb_component * multiplicator * size * sizeof(T)));
- UInt new_component = nb_component/block_size * multiplicator;
+ UInt new_component = nb_component / block_size * multiplicator;
- for (UInt i = 0,k=size-1; i < size; ++i,--k) {
+ 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];
+ 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);
+ for (; (i < size) && (values[i] != elem); ++i)
+ ;
AKANTU_DEBUG_OUT();
- return (i == size) ? -1 : (Int) i;
+ return (i == size) ? -1 : (Int)i;
}
/* -------------------------------------------------------------------------- */
-template <class T, bool is_scal>
-Int Array<T, is_scal>::find(T elem[]) const {
+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]) {
+ 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;
+ for (; (c < nb_component) && (*cit == elem[c]); ++c, ++cit)
+ ;
+ if (c == nb_component) {
+ AKANTU_DEBUG_OUT();
+ return i;
}
}
it += nb_component;
}
return -1;
}
+/* -------------------------------------------------------------------------- */
+template <class T, bool is_scal>
+template <template <typename> class C>
+inline Int Array<T, is_scal>::find(const C<T> & elem) {
+ return this->find(elem.storage());
+}
/* -------------------------------------------------------------------------- */
/**
* 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) {
+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");
+ 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);
+ std::uninitialized_copy(vect.storage(), vect.storage() + size * nb_component,
+ tmp);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<bool is_scal>
-class ArrayPrintHelper {
+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()) {
+ 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);
+ 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 << "{";
+ 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> {
+template <> class ArrayPrintHelper<false> {
public:
- template<typename T>
+ template <typename T>
static void print_content(__attribute__((unused)) const Array<T> & vect,
- __attribute__((unused)) std::ostream & stream,
- __attribute__((unused)) int indent) { }
+ __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);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
- std::streamsize prec = stream.precision();
- std::ios_base::fmtflags ff = stream.flags();
+ std::streamsize prec = stream.precision();
+ std::ios_base::fmtflags ff = stream.flags();
- stream.setf (std::ios_base::showbase);
+ stream.setf(std::ios_base::showbase);
stream.precision(2);
- stream << space << "Array<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
+ 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 << " + 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())
+ << 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;
+ << 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;
-}
+inline void ArrayBase::empty() { size = 0; }
/* -------------------------------------------------------------------------- */
/* Iterators */
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
-template<class R, class IR, bool is_r_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 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() : _offset(0), initial(NULL), ret(NULL), ret_ptr(NULL){};
- iterator_internal(pointer wrapped) : _offset(wrapped->size()),
- initial(wrapped->storage()),
- ret(const_cast<internal_pointer>(wrapped)),
- ret_ptr(wrapped->storage()) {
+ 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) {
+ 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) {
+ 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);
+ 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); }
+ 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 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+=(const UInt n) {
+ ret_ptr += _offset * n;
+ return *this;
+ }
+ inline iterator_internal & operator-=(const UInt n) {
+ ret_ptr -= _offset * n;
+ return *this;
+ }
- 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 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 difference_type operator-(const iterator_internal & b) { return (this->ret_ptr - b.ret_ptr) / _offset; }
+ 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 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(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; }
+ if (this != &it) {
+ this->ret = it.ret;
+ this->initial = it.initial;
+ }
}
- virtual ~iterator_internal() { };
+ virtual ~iterator_internal(){};
- inline iterator_internal & operator=(const iterator_internal & it)
- { if(this != &it) { this->ret = it.ret; this->initial = it.initial; } return *this; }
+ 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;};
+ 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++() {
+ ++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 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 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 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 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) {
+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<< ")");
+ "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) {
+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));
+ "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 {
+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<< ")");
+ "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 {
+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));
+ "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) {
+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 << ")");
+ "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)
+ * @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 << ")");
+ "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)
+ * @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 {
+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 << ")");
+ "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)
+ * @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 << ")");
+ "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<< ")");
+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<< ")");
+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<< ")");
+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));
+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
+ * @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) {
+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 << ")");
+ "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)
+ * @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 << ")");
+ "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)
+ * @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 {
+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 << ")");
+ "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)
+ * @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 << ")");
+ "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");
+ 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
- */
+/*! 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");
+ 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");
+ 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");
+ 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>
+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::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() {};
+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; }
+ 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 >
+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> {
+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> {
+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::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() : 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; }
+ 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) {
+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
deleted file mode 100644
index 616e0ffd3..000000000
--- a/src/common/aka_ball.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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
deleted file mode 100644
index 049e61b4c..000000000
--- a/src/common/aka_ball.hh
+++ /dev/null
@@ -1,286 +0,0 @@
-/**
- * @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
- *
- * @brief bounding ball classes
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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..e6cece638 100644
--- a/src/common/aka_blas_lapack.hh
+++ b/src/common/aka_blas_lapack.hh
@@ -1,324 +1,321 @@
/**
* @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: Mon Jan 18 2016
*
* @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
+#include "aka_fortran_mangling.hh"
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
+#include "aka_fortran_mangling.hh"
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
deleted file mode 100644
index cc7597f1e..000000000
--- a/src/common/aka_bounding_box.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * @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
- *
- * @brief Implementation of the bounding box class
- *
- * @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 "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
deleted file mode 100644
index 2168215b3..000000000
--- a/src/common/aka_bounding_box.hh
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * @file aka_bounding_box.hh
- *
- * @author David Simon Kammer <david.kammer@epfl.ch>
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date creation: Fri Jan 04 2013
- * @date last modification: Mon Jun 02 2014
- *
- * @brief class for a bounding box
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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 f72e4815f..59851598b 100644
--- a/src/common/aka_common.cc
+++ b/src/common/aka_common.cc
@@ -1,162 +1,153 @@
/**
* @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: Tue Jan 19 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) {
+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) {
+void initialize(const std::string & input_file, int & argc, char **& argv) {
AKANTU_DEBUG_IN();
StaticMemory::getStaticMemory();
- StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator(argc, argv);
+ 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.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;
+ if (infile == "")
+ infile = input_file;
debug::setDebugLevel(dblError);
if ("" != infile) {
- static_parser.parse(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);
+ StaticSolver::getStaticSolver().initialize(argc, argv);
AKANTU_DEBUG_OUT();
-
}
+
/* -------------------------------------------------------------------------- */
-void clear() {
+void finalize() {
AKANTU_DEBUG_IN();
- /// finalize external solvers
- StaticSolver::getStaticSolver().finalize();
-
- if(StaticMemory::isInstantiated()) delete &(StaticMemory::getStaticMemory());
- if(StaticCommunicator::isInstantiated()) {
+ if (StaticCommunicator::isInstantiated()) {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- comm.barrier();
delete &comm;
}
- static_parser.clear();
+ if (StaticMemory::isInstantiated()) {
+ delete &(StaticMemory::getStaticMemory());
+ }
AKANTU_DEBUG_OUT();
}
-/* -------------------------------------------------------------------------- */
-void finalize() {
- AKANTU_DEBUG_IN();
-
- if(StaticCommunicator::isInstantiated()) {
- StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- comm.barrier();
- comm.finalize();
- }
- clear();
-
- 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;
-}
+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 869684cc0..7901be27d 100644
--- a/src/common/aka_common.hh
+++ b/src/common/aka_common.hh
@@ -1,488 +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: Thu Jan 21 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 __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);
/* -------------------------------------------------------------------------- */
-/// Clean akantu memory. Should be used only before a re-initialize of Akantu.
-/// Otherwise finalize() should be used.
-void clear();
/// 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..8a491ef1d 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: Thu Jan 21 2016
*
* @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..e4df6efa4 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: Tue Jan 19 2016
*
* @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)) && \
+#if (defined(READLINK_COMMAND) || defined(ADDR2LINE_COMMAND)) && \
(not defined(_WIN32))
-# include <execinfo.h>
-# include <sys/wait.h>
+#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>
+#include <sys/time.h>
#else
-# include <time.h>
+#include <time.h>
#endif
#ifdef AKANTU_USE_MPI
-# include <mpi.h>
+#include <mpi.h>
#endif
-#define __BEGIN_AKANTU_DEBUG__ namespace akantu { namespace debug {
-#define __END_AKANTU_DEBUG__ } }
+#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) {
+std::string demangle(const char * symbol) {
int status;
std::string result;
- char *demangled_name;
+ char * demangled_name;
- if ((demangled_name = abi::__cxa_demangle(symbol, NULL, 0, &status)) != NULL) {
+ 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))
+#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 "";
+ 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::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;
+ 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;
+ if (me != "")
+ addr_map[me] = 0;
#endif
- /// \todo for windows this part could be coded using CaptureStackBackTrace and SymFromAddr
+ /// \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;
+ 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) {
+ 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);
+ 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());
+ 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;
+ 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);
+ 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;
+ 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;
+ 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();
+ 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)
+ 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
+ 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) {
+ 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 {
+ 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;
+ *(cout) << parallel_context << "{" << (unsigned int)timestamp << "} "
+ << prefix << " " << info << std::endl;
}
}
/* ------------------------------------------------------------------------ */
-void Debugger::setDebugLevel(const DebugLevel & level) {
- this->level = level;
-}
+void Debugger::setDebugLevel(const DebugLevel & level) { this->level = level; }
/* ------------------------------------------------------------------------ */
-const DebugLevel & Debugger::getDebugLevel() const {
- return level;
-}
+const DebugLevel & Debugger::getDebugLevel() const { return level; }
/* ------------------------------------------------------------------------ */
void Debugger::setLogFile(const std::string & filename) {
if (file_open) {
- dynamic_cast <std::ofstream *>(cout)->close();
+ dynamic_cast<std::ofstream *>(cout)->close();
delete cout;
}
- std::ofstream *fileout = new std::ofstream(filename.c_str());
+ std::ofstream * fileout = new std::ofstream(filename.c_str());
file_open = true;
cout = fileout;
}
-std::ostream & Debugger::getOutputStream() {
- return *cout;
-}
+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 << "] ";
+ 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);
-}
+void setDebugLevel(const DebugLevel & level) { debugger.setDebugLevel(level); }
-const DebugLevel & getDebugLevel() {
- return debugger.getDebugLevel();
-}
+const DebugLevel & getDebugLevel() { return debugger.getDebugLevel(); }
/* -------------------------------------------------------------------------- */
-void exit(int status) {
- debugger.exit(status);
-}
+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
deleted file mode 100644
index 84571612e..000000000
--- a/src/common/aka_geometry.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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
deleted file mode 100644
index c95ff0de4..000000000
--- a/src/common/aka_geometry.hh
+++ /dev/null
@@ -1,365 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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
deleted file mode 100644
index 326fba644..000000000
--- a/src/common/aka_optimize.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @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
- *
- * @brief Objects that can be used to carry out optimization
- *
- * @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 "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
deleted file mode 100644
index 2df512f92..000000000
--- a/src/common/aka_optimize.hh
+++ /dev/null
@@ -1,372 +0,0 @@
-/**
- * @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
- *
- * @brief Objects that can be used to carry out optimization
- *
- * @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/>.
- *
- */
-
-#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
deleted file mode 100644
index 31ac59332..000000000
--- a/src/common/aka_plane.hh
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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
deleted file mode 100644
index 3c7669163..000000000
--- a/src/common/aka_point.hh
+++ /dev/null
@@ -1,270 +0,0 @@
-/**
- * @file aka_point.hh
- *
- * @author David Simon Kammer <david.kammer@epfl.ch>
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date creation: Fri Jan 04 2013
- * @date last modification: Tue Jun 17 2014
- *
- * @brief Geometry class representing points
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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
deleted file mode 100644
index 35edfbb5e..000000000
--- a/src/common/aka_polytope.hh
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * @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
- *
- * @brief k-DOP class template
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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..3e38ff859 100644
--- a/src/common/aka_random_generator.hh
+++ b/src/common/aka_random_generator.hh
@@ -1,351 +1,367 @@
/**
* @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
+#define __CONST_EXPR constexpr
#else
-# define __CONST_EXPR
+#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 \
+ ((uniform, UniformDistribution))((weibull, WeibullDistribution))
#define AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_rdt_, elem)
-#define AKANTU_RANDOM_DISTRIBUTION_PREFIX(s, data, 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)),
+ 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 {
+template <typename T> class RandomDistributionBase {
public:
virtual ~RandomDistributionBase() {}
virtual void printself(std::ostream & stream, int indent = 0) const = 0;
};
-
/* -------------------------------------------------------------------------- */
/* Uniform distribution */
/* -------------------------------------------------------------------------- */
-template<typename T>
+template <typename T>
class UniformDistribution : public RandomDistributionBase<T> {
public:
- UniformDistribution(T min = T(0.), T max = T(1.)) : min(min), max(max) { };
+ UniformDistribution(T min = T(0.), T max = T(1.)) : min(min), max(max){};
/* ------------------------------------------------------------------------ */
- template<template<class> class RandomGenerator>
- T operator() (RandomGenerator<T> & generator) {
+ 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 {
+ virtual void printself(std::ostream & stream,
+ __attribute__((unused)) int indent = 0) const {
stream << "Uniform [ min=" << min << ", max=" << max << " ]";
};
/* ------------------------------------------------------------------------ */
private:
T min;
T max;
};
/* -------------------------------------------------------------------------- */
/* Weibull distribution */
/* -------------------------------------------------------------------------- */
-template<typename T>
+template <typename T>
class WeibullDistribution : public RandomDistributionBase<T> {
public:
- WeibullDistribution(T scale, T shape) : m(shape), lambda(scale) { };
+ WeibullDistribution(T scale, T shape) : m(shape), lambda(scale){};
/* ------------------------------------------------------------------------ */
- template<template<class> class RandomGenerator>
+ 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);
+ 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 {
+ virtual void printself(std::ostream & stream,
+ __attribute__((unused)) 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 {
+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 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()() {
+template <> inline double Rand48Generator<double>::operator()() {
return drand48();
}
#endif
/* -------------------------------------------------------------------------- */
-template<typename T>
-class RandGenerator {
+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 {
+ virtual void printself(std::ostream & stream,
+ __attribute__((unused)) int indent = 0) const {
stream << "RandGenerator [seed=" << _seed << "]";
}
/* ------------------------------------------------------------------------ */
public:
- static void seed(long int s) { _seed = s; srand(_seed); }
+ 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; \
+#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;
+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>
+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)) \
- }; \
+#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)
+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 {
+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(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)
+ 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) {
+ 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)
+ if (type == _rdt_not_defined)
+ distribution = NULL;
+ BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_NEW, _,
+ AKANTU_RANDOM_DISTRIBUTION_TYPES)
}
- return *this;
+ 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); \
+/* ------------------------------------------------------------------------ */
+#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>
+ 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;
+ 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)
+ 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 {
+ virtual void printself(std::ostream & stream,
+ __attribute__((unused)) int indent = 0) const {
stream << base_value;
- if(type != _rdt_not_defined) stream << " " << *distribution;
+ if (type != _rdt_not_defined)
+ stream << " " << *distribution;
}
private:
-
- template<template<typename> class Distribution, template<typename> class Generator,
- class iterator>
+ 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);
+ 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) {
+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) {
+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
deleted file mode 100644
index 62f00af39..000000000
--- a/src/common/aka_timer.hh
+++ /dev/null
@@ -1,219 +0,0 @@
-/**
- * @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
- *
- * @brief timer object
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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
deleted file mode 100644
index d3cf8fdc5..000000000
--- a/src/common/aka_tree.hh
+++ /dev/null
@@ -1,2318 +0,0 @@
-/**
- * @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
- *
- * @brief bounding volume hierarchies
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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..bc7a01abb 100644
--- a/src/common/aka_types.hh
+++ b/src/common/aka_types.hh
@@ -1,1118 +1,1152 @@
/**
* @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: Fri Jan 22 2016
*
* @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)
-};
+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 {
+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]) {
+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]) {
+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]) {
+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;
+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 {
+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));
+ AKANTU_DEBUG_ASSERT(i < ndim, "This tensor has only " << ndim
+ << " dimensions, not "
+ << (i + 1));
return n[i];
}
- inline UInt size() const{
+ inline UInt size() const {
UInt _size = 1;
- for (UInt d = 0; d < ndim; ++d) _size *= this->n[d];
+ 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");
+ 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");
+ 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> > {
+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(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];};
+ 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> > {
+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(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>
+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(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 {
+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);
+ 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;
+ 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) { }
+ 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);
+ 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) {
+ template <class TensorType> inline void shallowCopy(const TensorType & src) {
this->copySize(src);
- if(!this->wrapped) delete[] this->values;
+ if (!this->wrapped)
+ delete[] this->values;
this->values = src.storage();
this->wrapped = true;
}
/* ------------------------------------------------------------------------ */
- template<class TensorType>
- inline void deepCopy(const TensorType & src) {
+ template <class TensorType> inline void deepCopy(const TensorType & src) {
this->copySize(src);
- if(!this->wrapped) delete [] this->values;
+ if (!this->wrapped)
+ delete[] this->values;
this->values = new T[this->_size];
- memcpy((void*)this->values, (void*)src.storage(), this->_size * sizeof(T));
+ memcpy((void *)this->values, (void *)src.storage(),
+ this->_size * sizeof(T));
this->wrapped = false;
}
virtual ~TensorStorage() {
- if(!this->wrapped)
- delete [] this->values;
+ if (!this->wrapped)
+ delete[] this->values;
}
/* ------------------------------------------------------------------------ */
inline TensorStorage & operator=(const RetType & src) {
- if(this != &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));
+ // 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);
+ deepCopy(src);
}
}
return *this;
}
/* ------------------------------------------------------------------------ */
- template<class R>
+ 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++);
+ 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>
+ 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++);
+ 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;
+ 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;
+ 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;
+ 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;
+ 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));
+ 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");
+ 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];
+ 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) {
+ 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);
+ 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) {
+ 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);
+ 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) {
+ 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;
+ 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) {
+ 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);
+ 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); }
+ 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) {
+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;
+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) { }
+ 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() { };
+ virtual ~Vector(){};
/* ------------------------------------------------------------------------ */
inline Vector & operator=(const Vector & src) {
parent::operator=(src);
return *this;
}
/* ------------------------------------------------------------------------ */
- inline T& operator()(UInt i) {
+ 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] << ")");
+ "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 {
+ 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] << ")");
+ "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 T & operator[](UInt i) { return this->operator()(i); }
+ inline const T & operator[](UInt i) const { return this->operator()(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++);
+ 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++);
+ 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) {
+ 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");
+ "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");
+ 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);
+ 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>();
- }
+ inline Real norm() const { return parent::template norm<L_2>(); }
- template<NormType nt>
- inline Real norm() const {
+ 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 * 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);
+ 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 {
+ 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;
+ 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 {
+ 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);
+ 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);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << "[";
for (UInt i = 0; i < this->_size; ++i) {
- if(i != 0) stream << ", ";
+ 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 {
+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;
+ 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;
+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) { }
+ 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() { }
+ 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) {
+ 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]);
+ "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]);
+ "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); }
+ 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]);
+ 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]);
+ 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 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) {
+ 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 T & x) { return parent::operator*=(x); }
- inline Matrix & operator*= (const Matrix & B) {
+ inline Matrix & operator*=(const Matrix & B) {
Matrix C(*this);
this->mul<false, false>(C, B);
return *this;
}
/* ---------------------------------------------------------------------- */
- template<bool tr_A, bool tr_B>
+ 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();
+ if (tr_A)
+ k = A.rows();
#ifndef AKANTU_NDEBUG
- if (tr_B){
+ if (tr_B) {
AKANTU_DEBUG_ASSERT(k == B.cols(),
- "matrices to multiply have no fit dimensions");
+ "matrices to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->cols() == B.rows(),
- "matrices to multiply have no fit dimensions");
- }
- else {
+ "matrices to multiply have no fit dimensions");
+ } else {
AKANTU_DEBUG_ASSERT(k == B.rows(),
- "matrices to multiply have no fit dimensions");
+ "matrices to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->cols() == B.cols(),
- "matrices to multiply have no fit dimensions");
+ "matrices to multiply have no fit dimensions");
}
- if (tr_A){
+ if (tr_A) {
AKANTU_DEBUG_ASSERT(this->rows() == A.cols(),
- "matrices to multiply have no fit dimensions");
- }
- else{
+ "matrices to multiply have no fit dimensions");
+ } else {
AKANTU_DEBUG_ASSERT(this->rows() == A.rows(),
- "matrices to multiply have no fit dimensions");
+ "matrices to multiply have no fit dimensions");
}
-#endif //AKANTU_NDEBUG
+#endif // AKANTU_NDEBUG
- Math::matMul<tr_A, tr_B>(this->rows(), this->cols(), k,
- alpha, A.storage(), B.storage(),
- 0., this->storage());
+ 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");
+ 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];
+ this->values[i + j * this->rows()] += A[i] * B[j];
}
}
}
private:
class EigenSorter {
public:
- EigenSorter(const Vector<T> & eigs) : eigs(eigs) { }
+ 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");
+ "eig is not a valid operation on a rectangular matrix");
AKANTU_DEBUG_ASSERT(eigenvalues.size() == this->cols(),
- "eigenvalues should be of size " << this->cols() << ".");
+ "eigenvalues should be of size " << this->cols()
+ << ".");
#ifndef AKANTU_NDEBUG
- if(eigenvectors.storage() != NULL)
+ 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() << ".");
+ (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)
+ 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());
+ 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;
+ for (UInt i = 0; i < perm.size(); ++i)
+ perm(i) = i;
- std::sort(perm.storage(), perm.storage() + perm.size(), EigenSorter(tmp_eigs));
+ 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));
+ 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)
+ 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));
- }
+ 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");
+ "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");
+ 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);
+ 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");
+ "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);
+ "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);
+ "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();
+ 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);
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
stream << "[";
for (UInt i = 0; i < this->n[0]; ++i) {
- if(i != 0) stream << ", ";
+ if (i != 0)
+ stream << ", ";
stream << "[";
for (UInt j = 0; j < this->n[1]; ++j) {
- if(j != 0) stream << ", ";
- stream << operator()(i, 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) {
+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");
+ 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");
+ 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());
+ 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)
-{
+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)
-{
+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;
+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() : parent(){};
- Tensor3(UInt m, UInt n, UInt p, const T & def = T()) : parent(m, n, p, def) { }
+ 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(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) { }
+ 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 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]);
+ "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]);
+ "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]);
+ 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]);
+ 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> 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> 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> 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> 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> 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> 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 4e85e6c08..d01548209 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., 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 8f2ec9e4c..ed4f74245 100644
--- a/src/common/aka_voigthelper.hh
+++ b/src/common/aka_voigthelper.hh
@@ -1,204 +1,207 @@
/**
* @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: Fri Jan 22 2016
*
* @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 {
+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);
+ 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)
+ /// 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);
+ 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);
+ /// 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];
+ 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)];
+ 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) {
+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);
+ 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
+ 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);
+ Bvoigt(2, 1 + n * 2) = B(0, n);
+ Bvoigt(2, 0 + n * 2) = B(1, n);
}
}
-
- if(dim == 3) {
+ 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$ [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}, 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;
+ /// 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>
+template <UInt dim>
inline void VoigtHelper<dim>::transferBMatrixToBNL(const Matrix<Real> & B,
- Matrix<Real> & Bvoigt,
- UInt nb_nodes_per_element) {
+ 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}
+ // 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;
+ // std::cout << B(n, m) << std::endl;
Bvoigt(i * dim + n, m * dim + i) = B(n, m);
}
}
}
- //TODO: Verify the 2D and 1D case
+ // TODO: Verify the 2D and 1D case
}
-
/* -------------------------------------------------------------------------- */
-template<>
+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<>
+template <>
inline void VoigtHelper<3>::transferBMatrixToBL2(const Matrix<Real> & B,
- const Matrix<Real> & grad_u,
- Matrix<Real> & Bvoigt,
- UInt nb_nodes_per_element) {
+ 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 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<>
+template <>
inline void VoigtHelper<2>::transferBMatrixToBL2(const Matrix<Real> & B,
- const Matrix<Real> & grad_u,
- Matrix<Real> & Bvoigt,
- UInt nb_nodes_per_element) {
+ 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
deleted file mode 100644
index 63837977a..000000000
--- a/src/contact/contact_common.hh
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
- * @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
- *
- * @brief Forward declarations for contact classes
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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
deleted file mode 100644
index 96a12b10e..000000000
--- a/src/contact/contact_impl.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file contact_impl.cc
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date creation: Mon Sep 15 2014
- * @date last modification: Mon Sep 15 2014
- *
- * @brief Contat class Interface
- *
- * @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 "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
deleted file mode 100644
index 88711758d..000000000
--- a/src/contact/contact_impl.hh
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @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
- *
- * @brief Contact interface class
- *
- * @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/>.
- *
- */
-
-//
-// 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
deleted file mode 100644
index 5536fdc39..000000000
--- a/src/contact/contact_manager.hh
+++ /dev/null
@@ -1,432 +0,0 @@
-/**
- * @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
- *
- * @brief contact manager
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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
deleted file mode 100644
index 831af325b..000000000
--- a/src/contact/discretization.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * @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
- *
- * @brief
- *
- * @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/>.
- *
- */
-
diff --git a/src/contact/discretization.hh b/src/contact/discretization.hh
deleted file mode 100644
index d8f1da054..000000000
--- a/src/contact/discretization.hh
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * @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
- *
- * @brief contact discretization classes
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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
deleted file mode 100644
index 1c907121b..000000000
--- a/src/contact/element.cc
+++ /dev/null
@@ -1,306 +0,0 @@
-/**
- * @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
- *
- * @brief contact element classes
- *
- * @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 "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
deleted file mode 100644
index 7498e33af..000000000
--- a/src/contact/element.hh
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
- * @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
- *
- * @brief contact element classes
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#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
deleted file mode 100644
index 26e2024d1..000000000
--- a/src/contact/friction.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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
deleted file mode 100644
index 87b705419..000000000
--- a/src/contact/friction.hh
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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
deleted file mode 100644
index c60349fdc..000000000
--- a/src/contact/resolution.hh
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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
deleted file mode 100644
index f2d58e5f4..000000000
--- a/src/contact/resolution/resolution_augmented_lagrangian.cc
+++ /dev/null
@@ -1,1283 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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
deleted file mode 100644
index a00b182b4..000000000
--- a/src/contact/resolution/resolution_augmented_lagrangian.hh
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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
deleted file mode 100644
index 86bd89bf0..000000000
--- a/src/contact/scheme.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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/search.cc b/src/contact/search.cc
deleted file mode 100644
index 5ab8032a6..000000000
--- a/src/contact/search.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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
deleted file mode 100644
index e593ecaa5..000000000
--- a/src/contact/search.hh
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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
deleted file mode 100644
index 7d0fcd04f..000000000
--- a/src/contact/surface.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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
deleted file mode 100644
index dce176e0c..000000000
--- a/src/contact/surface.hh
+++ /dev/null
@@ -1,181 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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
deleted file mode 100644
index e64d0244c..000000000
--- a/src/contact/zone.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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
deleted file mode 100644
index a40f237cd..000000000
--- a/src/contact/zone.hh
+++ /dev/null
@@ -1,436 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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..4910d16e9 100644
--- a/src/fe_engine/element_class.hh
+++ b/src/fe_engine/element_class.hh
@@ -1,370 +1,396 @@
/**
* @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 Jan 21 2016
*
* @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 {
+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; \
+#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 {
+template <GeometricalType geometrical_type> struct GeometricalShape {
static const GeometricalShapeType shape = _gst_point;
};
/// Templated GeometricalShape with function contains
-template<GeometricalShapeType shape>
-struct GeometricalShapeContains {
+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; \
+/// 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 >
+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) {
+ 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 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);
+ 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 {
+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; \
- };
+/// 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>
+/// 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);
+ 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) {
+ 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);
+ Tensor3<Real> & dnds);
/**
- * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of shape functions along with
+ * 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) {
+ 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) {
+ 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);
+ 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);
+ 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);
-
+ 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);
+ 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);
+ 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>
+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>
+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> {
+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 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;
+ 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);
+ 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);
+ 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);
+ const Matrix<Real> & node_coords,
+ Vector<Real> & jacobians);
- /// compute jacobian (or integration variable change factor) for a set of points
+ /// compute jacobian (or integration variable change factor) for a set of
+ /// points
static inline void computeJacobian(const Tensor3<Real> & J,
- Vector<Real> & jacobians);
+ Vector<Real> & jacobians);
/// compute jacobian (or integration variable change factor) for a given point
- static inline void computeJacobian(const Matrix<Real> & J,
- Real & jacobians);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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 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"
+#include "element_class_structural.hh"
#endif
#if defined(AKANTU_IGFEM)
-# include "element_class_igfem.hh"
+#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..555e922f2 100644
--- a/src/fe_engine/element_class_structural.hh
+++ b/src/fe_engine/element_class_structural.hh
@@ -1,243 +1,259 @@
/**
* @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>
+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) {
+ 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);
+ 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) {
+ 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
+ * 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);
+ 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);
+ 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
+/// 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; \
+#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> {
+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;
+ 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) {
+ 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) {
+ 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> 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);
+ 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);
+ 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);
- }
+ 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);
- }
+ 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());
+ 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);
+ Matrix<Real> shape_deriv_p = shape_deriv(p);
- interpolation_element::computeDNDS(natural_coord(p), shape_deriv_p, projected_nodal_coord, n);
+ 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);
+ 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 {
+ } 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);
+ 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) {
+ 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 AKANTU_GET_MACRO_NOT_CONST(FacetType, _not_defined, ElementType);
+ static ElementType getFacetType(__attribute__((unused)) 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..2bf14915c 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,80 @@
/**
* @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
+ 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_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) {
+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) {}
-
+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.;
+inline void InterpolationElement<_itp_lagrange_point_1>::computeSpecialJacobian(
+ __attribute__((unused)) const Matrix<Real> & J, Real & jac) {
+ jac = 0.;
}
-
-
/* -------------------------------------------------------------------------- */
-template<>
+template <>
inline Real
-GeometricalElement<_gt_point>::getInradius(const Matrix<Real> & coord) {
+GeometricalElement<_gt_point>::getInradius(__attribute__((unused))
+ 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 a556b0532..8b6a6f6b7 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, memory_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..2beae284f 100644
--- a/src/fe_engine/fe_engine_template.hh
+++ b/src/fe_engine/fe_engine_template.hh
@@ -1,365 +1,355 @@
/**
* @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 <ElementKind k> struct AssembleLumpedTemplateHelper;
+template <ElementKind k> struct AssembleFieldMatrixHelper;
/* -------------------------------------------------------------------------- */
-template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind = _ek_regular>
+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);
+ 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);
+ 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;
+ 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;
+ 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;
-
+ 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;
+ /// 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
-
+ 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;
+ 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;
+ 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;
-
-
+ 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 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;
-
+ 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;
+ 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;
+ 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;
+ 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;
+ 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 = _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;
+ 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$
+ /// @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;
+ 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;
+ 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;
+ 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)
+ /// 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;
+ UInt nb_degree_of_freedom, SparseMatrix & M,
+ Array<Real> * n,
+ ElementTypeMapArray<Real> & rotation_mat,
+ __attribute__((unused))
+ const GhostType & ghost_type) const;
#endif
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the shape class (probably useless: see getShapeFunction)
- const ShapeFunctions & getShapeFunctionsInterface() const { return shape_functions; };
+ 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"
+#include "fe_engine_template_tmpl_struct.hh"
#endif
/* -------------------------------------------------------------------------- */
/* Shape IGFEM specialization */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_IGFEM)
-# include "fe_engine_template_tmpl_igfem.hh"
+#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 74f2d01f3..a3a2ae3fa 100644
--- a/src/fe_engine/fe_engine_template_tmpl.hh
+++ b/src/fe_engine/fe_engine_template_tmpl.hh
@@ -1,1726 +1,1611 @@
/**
* @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(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() { }
+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 <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,
+ static void call(__attribute__((unused)) const S & shape_functions,
+ __attribute__((unused)) Mesh & mesh,
+ __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) {
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); \
- } \
+#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)
+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 {
+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();
+ 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.");
+ << ") 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);
+ 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) {
+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) {
+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 it = mesh.firstType(element_dimension, ghost_type, kind);
Mesh::type_iterator end = mesh.lastType(element_dimension, ghost_type, kind);
- for(; it != end; ++it) {
+ for (; it != end; ++it) {
ElementType type = *it;
integrator.initIntegrator(nodes, type, ghost_type);
const Matrix<Real> & control_points =
- getIntegrationPoints(type, ghost_type);
+ 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); \
- } \
+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{
+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();
+ if (filter_elements != empty_filter)
+ nb_element = filter_elements.getSize();
#ifndef AKANTU_NDEBUG
- UInt nb_quadrature_points = getNbIntegrationPoints(type);
+ 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.");
+ << ") 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.");
+ "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);
-
+ 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; \
- } \
+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{
+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);
+ // "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();
+ if (filter_elements != empty_filter)
+ nb_element = filter_elements.getSize();
- UInt nb_quadrature_points = getNbIntegrationPoints(type, ghost_type);
+ 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 << ")");
+ "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.");
+ "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);
+ 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; \
- } \
+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{
+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);
+ 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); \
- } \
+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{
+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);
+ 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);
-
+ // "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.");
+ << ") 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.");
+ "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);
+ 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 <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,
+ static void call(__attribute__((unused)) const S & shape_functions,
+ __attribute__((unused)) const Array<Real> & u,
+ __attribute__((unused)) Array<Real> & uq,
+ __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) {
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); \
- } \
+#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)
+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 {
+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_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();
+ 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.");
+ << ") 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.");
+ "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);
+ 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 {
+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);
+ 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 {
+ } 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);
+ 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 {
-
-
+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);
+ 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 {
-
-
+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);
+ 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 {
+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(), getMemoryID());
- 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);
-
+ ElementTypeMapArray<Real> quadrature_points_coordinates(
+ "quadrature_points_coordinates_for_interpolation", getID(), getMemoryID());
+ 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", id, memory_id);
- ElementTypeMapArray<Real> quad_points_coordinates_inv_matrices("quad_points_coordinates_inv_matrices", id, memory_id);
-
- 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,
+ ElementTypeMapArray<Real> & result, const GhostType ghost_type,
+ const ElementTypeMapArray<UInt> * element_filter) const {
+
+ ElementTypeMapArray<Real> interpolation_points_coordinates_matrices(
+ "interpolation_points_coordinates_matrices", id, memory_id);
+ ElementTypeMapArray<Real> quad_points_coordinates_inv_matrices(
+ "quad_points_coordinates_inv_matrices", id, memory_id);
+
+ 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);
+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 <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) {
+ static void call(__attribute__((unused)) const S & shape_functions,
+ __attribute__((unused)) const Vector<Real> & real_coords,
+ __attribute__((unused)) UInt elem,
+ __attribute__((unused)) const Matrix<Real> & nodal_values,
+ __attribute__((unused)) Vector<Real> & interpolated,
+ __attribute__((unused)) const ElementType & type,
+ __attribute__((unused)) 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); \
- } \
+#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_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{
+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);
+ 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) {
+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);
+ 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) {
+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);
+ // 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) {
+ for (; it != end; ++it) {
ElementType type = *it;
UInt size = mesh.getNbElement(type, ghost_type);
- if(normals_on_integration_points.exists(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);
+ 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);
+ // 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,
+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) {
+ static void call(__attribute__((unused))
+ const FEEngineTemplate<I, S, k> & fem,
+ __attribute__((unused)) const Array<Real> & field,
+ __attribute__((unused)) Array<Real> & normal,
+ __attribute__((unused)) const ElementType & type,
+ __attribute__((unused)) 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); \
- } \
+#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)
+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>
+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 {
+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_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>::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);
+ integrator.template getQuadraturePoints<type>(ghost_type);
- Array<Real>::matrix_iterator f_it = f_el.begin(spatial_dimension, nb_nodes_per_element);
+ 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,
+ 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); \
- } \
+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 {
+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,
+ 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); \
- } \
+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 {
+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);
+ 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 <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);
+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$
+ * @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 <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 {
+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> * 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_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) {
+ 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);
+ 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);
+ 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);
+ 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 <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 {
+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();
+ 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_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; \
+#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 == _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;
+ // 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.;
+ nodal_factor(n) = 51. / 2358.;
- Real mid_triangle = 192./2358.;
- Real mid_quadrangle = 300./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(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);
+ 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> * 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);
+ 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);
+ 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$
+ * @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 <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 {
+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 vect_size = field_1.getSize();
UInt shapes_size = ElementClass<type>::getShapeSize();
- UInt lmat_size = nb_degree_of_freedom * shapes_size;
+ 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);
+ 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>::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 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)(s * nb_degree_of_freedom + d, d) = (*shapes_it)(s);
}
}
}
- mshapes_it = modified_shapes->begin(lmat_size, nb_degree_of_freedom);
+ 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) {
+ 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");
+ 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);
+ lmat_size * lmat_size, ghost_type,
+ empty_filter);
delete local_mat;
- assembleMatrix(*int_field_times_shapes, matrix, nb_degree_of_freedom, type, ghost_type);
+ 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 <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) {
+ static void call(__attribute__((unused)) const S & shape_functions,
+ __attribute__((unused)) const Vector<Real> & real_coords,
+ __attribute__((unused)) UInt element,
+ __attribute__((unused)) const ElementType & type,
+ __attribute__((unused)) Vector<Real> & natural_coords,
+ __attribute__((unused)) 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); \
- } \
+#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_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{
+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);
+ 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 <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) {
+ static void call(__attribute__((unused)) const S & shape_functions,
+ __attribute__((unused)) const Vector<Real> & real_coords,
+ __attribute__((unused)) UInt element,
+ __attribute__((unused)) const ElementType & type,
+ __attribute__((unused)) 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; \
- } \
+#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_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);
+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 <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) {
+ static void call(__attribute__((unused)) const S & shape_functions,
+ __attribute__((unused)) const Vector<Real> & real_coords,
+ __attribute__((unused)) UInt element,
+ __attribute__((unused)) const ElementType type,
+ __attribute__((unused)) Vector<Real> & shapes,
+ __attribute__((unused)) const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
-#define COMPUTE_SHAPES(type) \
- shape_functions.template computeShapes<type>(real_coords, \
- element, \
- shapes, \
+#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); \
- } \
+#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_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{
+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);
+ 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 <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) {
+ static void call(__attribute__((unused)) const S & shape_functions,
+ __attribute__((unused)) const Vector<Real> & real_coords,
+ __attribute__((unused)) UInt element,
+ __attribute__((unused)) const ElementType type,
+ __attribute__((unused)) Matrix<Real> & shape_derivatives,
+ __attribute__((unused)) const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
-#define COMPUTE_SHAPE_DERIVATIVES(type) \
+#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); \
- } \
+ 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_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 {
+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);
+ 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; \
- } \
+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);
+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; \
- } \
+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 {
+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) {
+template <ElementKind kind> struct GetShapesDerivativesHelper {
+ template <template <ElementKind> class S, ElementKind k>
+ static const Array<Real> &
+ call(__attribute__((unused)) const S<k> & shape_functions,
+ __attribute__((unused)) const ElementType & type,
+ __attribute__((unused)) const GhostType & ghost_type, UInt id) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
-#define GET_SHAPES_DERIVATIVES(type) \
+#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; \
- } \
+#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, __attribute__((unused)) 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_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);
+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; \
- } \
+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 {
+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 {
+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);
+ 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);
+ 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);
+ 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);
+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);
+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);
+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<>
+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 {
+ 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!");
+ 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_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>::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");
+ 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];
+ 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));
+ if (segment_connectivity(0) == elem) {
+ difference = coords(elem) - coords(segment_connectivity(1));
} else {
- difference = coords(elem)-coords(segment_connectivity(0));
+ difference = coords(elem) - coords(segment_connectivity(0));
}
- normal_value = difference/std::abs(difference);
+ normal_value = difference / std::abs(difference);
}
- for(UInt n(0); n < nb_points; ++n) {
+ 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..0d93a88a0 100644
--- a/src/fe_engine/fe_engine_template_tmpl_struct.hh
+++ b/src/fe_engine/fe_engine_template_tmpl_struct.hh
@@ -1,238 +1,231 @@
/**
* @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
+ * @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 {
-
+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) \
+#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 {
+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) \
+#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 {
+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)
+#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);;
+ 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 {
+template <template <ElementKind> class I, template <ElementKind> class S,
+ ElementKind kind>
+inline void FEEngineTemplate<I, S, kind>::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();
}
/* -------------------------------------------------------------------------- */
-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 {
+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 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;
+ 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);
- 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{
+ 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 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 <>
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 {
+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 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;
+ 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_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);
+ 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_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){
+ 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");
+ 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, 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 <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();
+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..129285851 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: Thu Jan 21 2016
*
* @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_not_defined>::facet_connectivity_vect[] = {0};
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};
+ 1, 2, 0};
template<> UInt GeometricalElement<_gt_triangle_6>::facet_connectivity_vect[] = {0, 1, 2,
- 1, 2, 0,
- 3, 4, 5};
+ 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};
+ 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};
+ 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};
+ 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};
+ 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};
+ 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..eb9677fe0 100644
--- a/src/fe_engine/integration_point.hh
+++ b/src/fe_engine/integration_point.hh
@@ -1,157 +1,157 @@
/**
* @file integration_point.hh
*
- * @author
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @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 b2a135728..16aa27dd4 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, memory_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..e6beca1bc 100644
--- a/src/fe_engine/shape_cohesive.hh
+++ b/src/fe_engine/shape_cohesive.hh
@@ -1,201 +1,201 @@
/**
* @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);
+ 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 {
+template <> class ShapeLagrange<_ek_cohesive> : public ShapeFunctions {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- ShapeLagrange(const Mesh & mesh,
- const ID & id = "shape_cohesive",
- const MemoryID & memory_id = 0);
+ ShapeLagrange(const Mesh & mesh, const ID & id = "shape_cohesive",
+ const MemoryID & memory_id = 0);
- virtual ~ShapeLagrange() { }
+ virtual ~ShapeLagrange() {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline void initShapeFunctions(const Array<Real> & nodes,
- const Matrix<Real> & integration_points,
- const ElementType & type,
- const GhostType & ghost_type);
+ 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;
+ 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
+ /// pre compute all shapes on the element integration points from natural
+ /// coordinates
template <ElementType type>
void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
- GhostType ghost_type);
+ GhostType ghost_type);
- /// pre compute all shape derivatives on the element integration points from natural coordinates
+ /// 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);
+ 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;
+ 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);
+ 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
+ /// 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);
+ 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;
+ 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;
+ 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 {
+ void fieldTimesShapes(__attribute__((unused)) const Array<Real> & field,
+ __attribute__((unused))
+ Array<Real> & fiedl_times_shapes,
+ __attribute__((unused)) 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;
+ 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;
+ 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> > {
+// 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)
-{
+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 c7a63d509..8bd7db5da 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, memory_id),
shapes_derivatives("shapes_derivatives_generic", id, memory_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..23d11c201 100644
--- a/src/fe_engine/shape_linked_inline_impl.cc
+++ b/src/fe_engine/shape_linked_inline_impl.cc
@@ -1,331 +1,317 @@
/**
* @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) {
+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); \
+#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) {
+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 {
+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);
+ "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 {
+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);
+ "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) {
+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 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) {
+ if (ghost_type == _ghost) {
ghost = "ghost_";
}
UInt nb_element = mesh.getNbElement(type, ghost_type);
- UInt nb_shape_functions = ElementClass<type, _ek_structural>::getNbShapeFunctions();
+ UInt nb_shape_functions =
+ ElementClass<type, _ek_structural>::getNbShapeFunctions();
- Array<Real> ** shapes_tmp = new Array<Real> *[nb_shape_functions];
+ 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);
+ 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);
+ 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);
+ 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);
+ 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) {
+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 natural_spatial_dimension =
+ ElementClass<type>::getNaturalSpaceDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
+ 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) {
+ 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);
+ 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];
+ 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();
+ 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);
+ 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);
+ 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;
+ 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{
+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();
+ 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;
+ 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 = 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 {
+void ShapeLinked<kind>::interpolateOnIntegrationPoints(
+ const Array<Real> & in_u, Array<Real> & out_uq,
+ __attribute__((unused)) 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,
+ __attribute__((unused)) 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);
+ 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);
+ extractNodalToElementField<type>(in_u, u_el,
+ num_degre_of_freedom_to_interpolate,
+ ghost_type, filter_elements);
- if(!accumulate) out_uq.clear();
+ if (!accumulate)
+ out_uq.clear();
- UInt nb_points = integration_points(type, ghost_type).cols() * u_el.getSize();
+ 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);
+ 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 {
+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);
+ 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);
+ 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 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);
+ 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);
+ 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);
+ (*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..940a8105a 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@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 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..37fe10631 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@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 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..cc0b5335d 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@epfl.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..fceb2baee 100644
--- a/src/io/dumper/dumpable.cc
+++ b/src/io/dumper/dumpable.cc
@@ -1,310 +1,285 @@
/**
* @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: Thu Jan 21 2016
*
* @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() : default_dumper("") {}
/* -------------------------------------------------------------------------- */
Dumpable::~Dumpable() {
DumperMap::iterator it = dumpers.begin();
DumperMap::iterator end = dumpers.end();
- for (; it != end; ++it){
+ for (; it != end; ++it) {
delete it->second;
}
}
/* -------------------------------------------------------------------------- */
void Dumpable::registerExternalDumper(DumperIOHelper & dumper,
- const std::string & dumper_name,
- const bool is_default) {
+ 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) {
+ const GhostType & ghost_type,
+ const ElementKind & element_kind) {
- this->addDumpMeshToDumper(this->default_dumper,
- mesh,
- spatial_dimension,
- ghost_type,
- 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) {
+ 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,
+ 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) {
+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);
+ 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) {
+void Dumpable::addDumpFieldToDumper(__attribute__((unused))
+ const std::string & dumper_name,
+ __attribute__((unused))
+ const std::string & field_id) {
AKANTU_DEBUG_TO_IMPLEMENT();
-};
+}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldExternal(const std::string & field_id,
- dumper::Field * field) {
+ 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) {
+ 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) {
+ 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) {
+void Dumpable::addDumpFieldVectorToDumper(__attribute__((unused))
+ const std::string & dumper_name,
+ __attribute__((unused))
+ 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) {
+void Dumpable::addDumpFieldTensorToDumper(__attribute__((unused))
+ const std::string & dumper_name,
+ __attribute__((unused))
+ 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) {
+ 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) {
+ 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) {
+ 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() { 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(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) {
+ 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 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.");
+ 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..24e641d36 100644
--- a/src/io/dumper/dumpable_inline_impl.hh
+++ b/src/io/dumper/dumpable_inline_impl.hh
@@ -1,147 +1,134 @@
/**
* @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: Thu Jan 21 2016
*
* @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>
+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()){
+ 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>
+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);
-};
+ 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) {
+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>
+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,
+ 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) {
+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
+ 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);
+ 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>
+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);
+ T & templated_dumper = dynamic_cast<T &>(dumper);
return templated_dumper;
- }
- catch (...) {
+ } catch (...) {
AKANTU_EXCEPTION("Dumper " << dumper_name << " is not of type: "
- << debug::demangle(typeid(T).name()));
+ << 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..b97c989dc 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: Tue Jan 19 2016
*
* @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>
+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;
-
+ 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();
+ 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;
}
- return_type operator*() {
- return func.func(*it,it.getCurrentElement());
- }
+ UInt currentGlobalIndex() { return this->it.currentGlobalIndex(); }
- Element getCurrentElement(){
- return this->it.getCurrentElement();
- }
+ 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;
+ 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)){
+ : sub_field(cont),
+ func(dynamic_cast<ComputeFunctor<sub_return_type, return_type> &>(
+ func)) {
this->checkHomogeneity();
};
+ ~FieldCompute() {
+ delete &(this->sub_field);
+ delete &(this->func);
+ }
+
virtual void registerToDumper(const std::string & id,
- iohelper::Dumper & dumper) {
+ 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); }
+ iterator end() { return iterator(sub_field.end(), func); }
- UInt getDim() {
- return func.getDim();
- }
+ UInt getDim() { return func.getDim(); }
UInt size() {
throw;
// return Functor::size();
return 0;
}
- virtual void checkHomogeneity(){this->homogeneous = true;};
+ virtual void checkHomogeneity() { this->homogeneous = true; };
- iohelper::DataType getDataType() { return iohelper::getDataType<data_type>(); }
+ 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){
+ 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);
-
+ 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);
+ 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);
+ 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;
+ ComputeFunctor<sub_return_type, return_type> & func;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class FieldComputeProxy {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- FieldComputeProxy(ComputeFunctorInterface & func):func(func){};
+ FieldComputeProxy(ComputeFunctorInterface & func) : func(func){};
inline static Field * createFieldCompute(Field * field,
- ComputeFunctorInterface & func){
+ ComputeFunctorInterface & func) {
+ /// that looks fishy an object passed as a ref and destroyed at their end of
+ /// the function
FieldComputeProxy compute_proxy(func);
return field->connect(compute_proxy);
}
- template <typename T>
- Field * connectToField(T * ptr){
- if (dynamic_cast<ComputeFunctorOutput<Vector<Real> > *>(&func)){
+ 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)){
+ } else if (dynamic_cast<ComputeFunctorOutput<Vector<UInt> > *>(&func)) {
return this->connectToFunctor<Vector<UInt> >(ptr);
}
- else if (dynamic_cast<ComputeFunctorOutput<Matrix<UInt> > *>(&func)){
+ else if (dynamic_cast<ComputeFunctorOutput<Matrix<UInt> > *>(&func)) {
return this->connectToFunctor<Matrix<UInt> >(ptr);
}
- else if (dynamic_cast<ComputeFunctorOutput<Matrix<Real> > *>(&func)){
+ else if (dynamic_cast<ComputeFunctorOutput<Matrix<Real> > *>(&func)) {
return this->connectToFunctor<Matrix<Real> >(ptr);
}
- else throw;
+ else
+ throw;
}
- template <typename output, typename T>
- Field * connectToFunctor(T * ptr){
- FieldCompute<T,output> * functor_ptr = new FieldCompute<T,output>(*ptr,func);
+ 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);
+ template <typename output, typename SubFieldCompute, typename return_type1,
+ typename return_type2>
+ Field * connectToFunctor(__attribute__((unused)) 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;
- }
+ template <typename output, typename SubFieldCompute, typename return_type1,
+ typename return_type2, typename return_type3, typename return_type4>
+ Field * connectToFunctor(__attribute__((unused)) 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){
+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..b36fcfae8 100644
--- a/src/io/dumper/dumper_field.hh
+++ b/src/io/dumper/dumper_field.hh
@@ -1,123 +1,137 @@
/**
* @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 Jan 19 2016
*
* @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() {};
+ 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();};
+ virtual void setNbData(__attribute__((unused)) 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();};
+ virtual void setNbDataPerElem(__attribute__((unused))
+ 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();};
+ virtual void setNbDataPerElem(__attribute__((unused)) 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;};
+ virtual ElementTypeMap<UInt>
+ getNbComponents(__attribute__((unused)) UInt dim = _all_dimensions,
+ __attribute__((unused)) GhostType ghost_type = _not_ghost,
+ __attribute__((unused)) ElementKind kind = _ek_not_defined) {
+ throw;
+ };
/// for connection to a FieldCompute
- inline virtual Field * connect(FieldComputeProxy & proxy){throw;};
+ inline virtual Field * connect(__attribute__((unused))
+ FieldComputeProxy & proxy) {
+ throw;
+ };
/// for connection to a FieldCompute
- inline virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy){throw;};
+ inline virtual ComputeFunctorInterface * connect(__attribute__((unused))
+ 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;};
+ std::string getGroupName() { return group_name; };
/// return the id of the field
- std::string getID(){return field_id;};
+ 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..e722fc882 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: Tue Jan 19 2016
*
* @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::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..60584cc8d 100644
--- a/src/io/dumper/dumper_homogenizing_field.hh
+++ b/src/io/dumper/dumper_homogenizing_field.hh
@@ -1,227 +1,217 @@
/**
* @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){
+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) {
-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);
+ 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){
+template <typename type>
+inline Vector<type>
+typeConverter(__attribute__((unused)) const Vector<type> & input,
+ __attribute__((unused)) Vector<type> & res,
+ __attribute__((unused)) UInt nb_data) {
return res;
}
/* -------------------------------------------------------------------------- */
template <typename type>
-class AvgHomogenizingFunctor : public ComputeFunctor<type,type> {
-
+class AvgHomogenizingFunctor : public ComputeFunctor<type, type> {
+
/* ------------------------------------------------------------------------ */
/* Typedefs */
- /* ------------------------------------------------------------------------ */
-
+ /* ------------------------------------------------------------------------ */
+
typedef typename type::value_type value_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
-
+
public:
-
- AvgHomogenizingFunctor(ElementTypeMap<UInt> & nb_datas){
+ 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;
+ for (; tit != end; ++tit)
+ if (nb_data != nb_datas(*tit))
+ throw;
}
-
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
-
- virtual type func(const type & d, Element global_index){
+
+ virtual type func(const type & d,
+ __attribute__((unused)) 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();
+ 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);
+ 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);
+ return typeConverter(d, res, this->nb_data);
};
-
- UInt getDim(){return nb_data;};
- UInt getNbComponent(UInt old_nb_comp){
- throw;
- };
+ UInt getDim() { return nb_data; };
+ UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) { throw; };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-
- /// The size of data: i.e. the size of the vector to be returned
+
+ /// 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){
+ 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 *
+ inline ComputeFunctorInterface *
instantiateHomogenizer(ElementTypeMap<UInt> & nb_components);
-
-
};
/* -------------------------------------------------------------------------- */
template <typename ret_type>
-inline ComputeFunctorInterface * HomogenizerProxy
-::instantiateHomogenizer(ElementTypeMap<UInt> & nb_components){
+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){
+inline ComputeFunctorInterface *
+HomogenizerProxy::instantiateHomogenizer<Vector<iohelper::ElemType> >(
+ __attribute__((unused)) 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){
+inline ComputeFunctorInterface *
+FieldCompute<SubFieldCompute, return_type>::connect(HomogenizerProxy & proxy) {
return proxy.connectToField(this);
}
/* -------------------------------------------------------------------------- */
-inline ComputeFunctorInterface * HomogenizerProxy::createHomogenizer(Field & field){
-
+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..0c75b299e 100644
--- a/src/io/dumper/dumper_iohelper.hh
+++ b/src/io/dumper/dumper_iohelper.hh
@@ -1,156 +1,158 @@
/**
* @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: Tue Jan 19 2016
*
* @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;
+class Dumper;
}
__BEGIN_AKANTU__
UInt getIOHelperType(ElementType type);
namespace dumper {
- class Field;
- class VariableBase;
+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);
+ 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);
+ 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);
+ 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
+ /// request dump: this calls IOHelper dump routine
virtual void dump();
- /// request dump: this first set the current step and then calls IOHelper dump routine
+ /// 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
+ /// 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;
+ 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 f7df7e0cc..4d3995fe3 100644
--- a/src/io/dumper/dumper_material_padders.hh
+++ b/src/io/dumper/dumper_material_padders.hh
@@ -1,291 +1,297 @@
/**
* @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()),
nb_data_per_element("nb_data_per_element", model.getID(), model.getMemoryID()),
spatial_dimension(model.getSpatialDimension()){}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
/// return the material from the global element index
- const Material & getMaterialFromGlobalIndex(Element global_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){
+ 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;
+ /// 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;
+ const ElementTypeMapArray<UInt> nb_data_per_element;
UInt spatial_dimension;
};
/* -------------------------------------------------------------------------- */
-template<class T, class R>
-class MaterialPadder : public MaterialFunctor, public PadderGeneric<Vector<T>, R > {
+template <class T, class R>
+class MaterialPadder : public MaterialFunctor,
+ public PadderGeneric<Vector<T>, R> {
public:
- MaterialPadder(const SolidMechanicsModel & model) :
- MaterialFunctor(model) {}
+ 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);
+ 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){
+ 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);
+ 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);
+ const Material & material =
+ this->getMaterialFromGlobalIndex(global_element_id);
bool plane_strain = true;
- if(spatial_dimension == 2)
+ if (spatial_dimension == 2)
plane_strain = !material.getParam<bool>("Plane_Stress");
- if(plane_strain) {
+ 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));
+ stress(2, 2 + 3 * d) =
+ nu * (stress(0, 0 + 3 * d) + stress(1, 1 + 3 * d));
}
}
return stress;
}
- UInt getDim(){return 9;};
+ UInt getDim() { return 9; };
- UInt getNbComponent(UInt old_nb_comp){
+ UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) {
return this->getDim();
};
};
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-class StrainPadder : public MaterialFunctor, public PadderGeneric< Matrix<Real>, Matrix<Real> > {
+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);
+ StrainPadder(const SolidMechanicsModel & model) : MaterialFunctor(model) {
+ this->setPadding(3, 3);
}
- inline Matrix<Real> func(const Matrix<Real> & in, Element global_element_id){
+ inline Matrix<Real> func(const Matrix<Real> & in, Element global_element_id) {
UInt nrows = spatial_dimension;
- UInt nb_data = in.size() / (nrows*nrows);
+ UInt nb_data = in.size() / (nrows * nrows);
Matrix<Real> strain = this->pad(in, nb_data);
- const Material & material = this->getMaterialFromGlobalIndex(global_element_id);
+ const Material & material =
+ this->getMaterialFromGlobalIndex(global_element_id);
bool plane_stress = material.getParam<bool>("Plane_Stress");
- if(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));
+ 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 getDim() { return 9; };
- UInt getNbComponent(UInt old_nb_comp){
+ UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) {
return this->getDim();
};
-
};
/* -------------------------------------------------------------------------- */
template <bool green_strain>
-class ComputeStrain : public MaterialFunctor, public ComputeFunctor<Vector<Real>, Matrix<Real> > {
+class ComputeStrain : public MaterialFunctor,
+ public ComputeFunctor<Vector<Real>, Matrix<Real> > {
public:
- ComputeStrain(const SolidMechanicsModel & model) : MaterialFunctor(model) { }
+ ComputeStrain(const SolidMechanicsModel & model) : MaterialFunctor(model) {}
- inline Matrix<Real> func(const Vector<Real> & in, Element global_element_id){
+ inline Matrix<Real> func(const Vector<Real> & in,
+ __attribute__((unused)) Element global_element_id) {
UInt nrows = spatial_dimension;
UInt ncols = in.size() / nrows;
- UInt nb_data = in.size() / (nrows*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);
+ 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 getDim() { return spatial_dimension * spatial_dimension; };
- UInt getNbComponent(UInt old_nb_comp){
+ UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) {
return this->getDim();
};
-
};
/* -------------------------------------------------------------------------- */
template <bool green_strain>
-class ComputePrincipalStrain : public MaterialFunctor, public ComputeFunctor<Vector<Real>,
- Matrix<Real> > {
+class ComputePrincipalStrain
+ : public MaterialFunctor,
+ public ComputeFunctor<Vector<Real>, Matrix<Real> > {
public:
- ComputePrincipalStrain(const SolidMechanicsModel & model) : MaterialFunctor(model) { }
+ ComputePrincipalStrain(const SolidMechanicsModel & model)
+ : MaterialFunctor(model) {}
- inline Matrix<Real> func(const Vector<Real> & in, Element global_element_id){
+ inline Matrix<Real> func(const Vector<Real> & in,
+ __attribute__((unused)) Element global_element_id) {
UInt nrows = spatial_dimension;
- UInt nb_data = in.size() / (nrows*nrows);
+ 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);
+ 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){
+ UInt getNbComponent(__attribute__((unused)) UInt old_nb_comp) {
return this->getDim();
};
-
};
/* -------------------------------------------------------------------------- */
-class ComputeVonMisesStress : public MaterialFunctor,
- public ComputeFunctor<Vector<Real>, Vector<Real> > {
+class ComputeVonMisesStress
+ : public MaterialFunctor,
+ public ComputeFunctor<Vector<Real>, Vector<Real> > {
public:
- ComputeVonMisesStress(const SolidMechanicsModel & model) : MaterialFunctor(model) { }
+ ComputeVonMisesStress(const SolidMechanicsModel & model)
+ : MaterialFunctor(model) {}
- inline Vector<Real> func(const Vector<Real> & in, Element global_element_id){
+ inline Vector<Real> func(const Vector<Real> & in,
+ __attribute__((unused)) Element global_element_id) {
UInt nrows = spatial_dimension;
- UInt nb_data = in.size() / (nrows*nrows);
+ 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);
+ 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){
+ UInt getNbComponent(__attribute__((unused)) 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..b4f679e84 100644
--- a/src/io/dumper/dumper_text.cc
+++ b/src/io/dumper/dumper_text.cc
@@ -1,118 +1,113 @@
/**
* @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() {
+ 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) {
+ __attribute__((unused)) UInt spatial_dimension,
+ __attribute__((unused))
+ const GhostType & ghost_type,
+ __attribute__((unused))
+ const ElementKind & element_kind) {
- registerField("position",
- new dumper::NodalField<Real>(mesh.getNodes()));
+ 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()));
+ 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));
+void DumperText::registerFilteredMesh(
+ const Mesh & mesh,
+ __attribute__((unused)) const ElementTypeMapArray<UInt> & elements_filter,
+ const Array<UInt> & nodes_filter,
+ __attribute__((unused)) UInt spatial_dimension,
+ __attribute__((unused)) const GhostType & ghost_type,
+ __attribute__((unused)) 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));
+ 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");
+ 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);
+ 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..0e01e4be9 100644
--- a/src/io/mesh_io/mesh_io_abaqus.cc
+++ b/src/io/mesh_io/mesh_io_abaqus.cc
@@ -1,548 +1,540 @@
/**
* @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() {}
/* -------------------------------------------------------------------------- */
-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 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 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));
- 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);
- }
- };
+ 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);
- 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);
+ 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;
};
- /* ------------------------------------------------------------------------ */
- 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);
- }
+ 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; };
+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,
+ 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() << ".");
+ 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);
- }
- };
+ 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_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; };
+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);
+ 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() << ".");
+ 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);
- }
- };
+ 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();
- }
- };
+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") {
+template <class Iterator> struct AbaqusSkipper : qi::grammar<Iterator> {
+ AbaqusSkipper() : AbaqusSkipper::base_type(skip, "abaqus_skipper") {
+ /* clang-format off */
skip
= (ascii::space - spirit::eol)
| "**" >> *(qi::char_ - spirit::eol) >> spirit::eol
;
+ /* clang-format on */
}
qi::rule<Iterator> skip;
};
/* -------------------------------------------------------------------------- */
-template<class Iterator, typename Skipper = AbaqusSkipper<Iterator> >
-struct AbaqusMeshGrammar : qi::grammar<Iterator, void(),
- Skipper> {
+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;
+ 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;
-
+ 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;
+
+ /* clang-format off */
start
= *(
(qi::char_('*')
> ( (qi::no_case[ qi::lit("node output") ] > any_section)
| (qi::no_case[ qi::lit("element output") ] > any_section)
| (qi::no_case[ qi::lit("node") ] > nodes)
| (qi::no_case[ qi::lit("element") ] > elements)
| (qi::no_case[ qi::lit("heading") ] > header)
| (qi::no_case[ qi::lit("elset") ] > elements_set)
| (qi::no_case[ qi::lit("nset") ] > nodes_set)
| (qi::no_case[ qi::lit("material") ] > material)
| (keyword > any_section)
)
)
| spirit::eol
)
;
header
= spirit::eol
> *any_line
;
nodes
= *(qi::char_(',') >> option)
>> spirit::eol
>> *( (qi::int_
> node_position) [ lazy_node_read(phx::ref(mesh),
lbs::_1,
lbs::_2,
phx::ref(abaqus_nodes_to_akantu)) ]
>> 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");
+
+ /* clang-format on */
}
public:
- AKANTU_GET_MACRO(MaterialNames, material_names, const std::vector<std::string> &);
+ 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, 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::rule<Iterator, std::string(), Skipper> key, value, option, keyword,
+ any_line;
- qi::real_parser< Real, qi::real_policies<Real> > real;
+ 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;
+ 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;
+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()) {
+ if (!infile.good()) {
AKANTU_DEBUG_ERROR("Cannot open file " << filename);
}
- std::string storage; // We will read the contents here.
+ 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::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 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();
+ 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 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();
+ 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);
+ 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 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..42ea07a41 100644
--- a/src/io/mesh_io/mesh_io_diana.cc
+++ b/src/io/mesh_io/mesh_io_diana.cc
@@ -1,580 +1,584 @@
/**
* @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 Jan 21 2016
*
* @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];
+ UInt * local_connect = new UInt[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;
+
+ delete [] local_connect;
}
AKANTU_DEBUG_OUT();
return lline;
}
/* -------------------------------------------------------------------------- */
std::string MeshIODiana::readMaterialElement(std::ifstream & infile,
Mesh & mesh) {
AKANTU_DEBUG_IN();
std::string line;
std::stringstream sstr_tag_name;
sstr_tag_name << "tag_" << 0;
Mesh::type_iterator it = mesh.firstType();
Mesh::type_iterator end = mesh.lastType();
for (; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it);
mesh.getDataPointer<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..5326adf68 100644
--- a/src/io/mesh_io/mesh_io_msh.cc
+++ b/src/io/mesh_io/mesh_io_msh.cc
@@ -1,969 +1,974 @@
/**
* @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: Thu Jan 21 2016
*
* @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];
+ UInt * local_connect = new UInt [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);
+ delete [] 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..62a8eaf24 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: Fri Jan 22 2016
*
- * @brief Mesh Reader specially created for Wood's Tower analysis performed by the Institute I-Barras
+ * @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)){
+ if (!dynamic_cast<StructuralMechanicsModel *>(&mod)) {
AKANTU_DEBUG_ERROR("");
}
- StructuralMechanicsModel & model = static_cast<StructuralMechanicsModel&>(mod);
+ 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()) {
+ 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;
+ const UInt spatial_dimension = 3;
Real coord[spatial_dimension];
- Real * temp_nodes = new Real[nb_nodes*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);
+ 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)
+ 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));
+ 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){
+ 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){
+ 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;
+ 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;
+ connectivity(i, j) = connect_to_akantu[nonodes[j] - 1] - 1;
}
}
- nb_struct_nodes-=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];
+ 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();
-
+ // MeshPartitionScotch partition(*mesh, spatial_dimension);
+ // partition.reorder();
- ///Apply Boundaries
- model.registerFEEngineObject<StructuralMechanicsModel::MyFEEngineType>("StructuralMechanicsModel", *mesh, spatial_dimension);
+ /// 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){
+ 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;
+ blocked_dofs(connect_to_akantu[boundnary_node - 1] - 1, j) = true;
}
- ///Define Materials
+ /// 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){
+ 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];
+ 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));
+ Array<Real> & normals =
+ const_cast<Array<Real> &>(mesh->getNormals(_bernoulli_beam_3));
normals.resize(nb_elements);
- for (UInt i = 0; i < nb_elements; ++i){
+ 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;
+ 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);
+ 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);
+ }
+ 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];
- }
+ 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){
+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()) {
+ 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){
+ 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];
+ no_element[1] = no_element[0];
sstr_set >> no_element[1];
- while (no_element[0]!=0) {
+ while (no_element[0] != 0) {
- for (UInt j = no_element[0]-1 ; j < no_element[1] ; ++j){
- set_ID(j) = i+1;
+ 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];
+ 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..03535edf2 100644
--- a/src/io/model_io/model_io_ibarras.hh
+++ b/src/io/model_io/model_io_ibarras.hh
@@ -1,69 +1,65 @@
/**
* @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);
-
+ 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..24385b554 100644
--- a/src/io/parser/input_file_parser.hh
+++ b/src/io/parser/input_file_parser.hh
@@ -1,287 +1,289 @@
/**
* @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;
-
+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);
- }
+struct error_handler_ {
+ template <typename, typename, typename, typename> struct result {
+ typedef void type;
};
- 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;
+ template <typename Iterator>
+ void operator()(qi::info const & what, Iterator err_pos,
+ __attribute__((unused)) Iterator first,
+ __attribute__((unused)) Iterator last) const {
+ spirit::classic::file_position pos = err_pos.get_position();
+
+ AKANTU_EXCEPTION("Parse error [ "
+ << "Expecting " << what << " instead of \"" << *err_pos
+ << "\" ]"
+ << " in file " << pos.file << " line " << pos.line
+ << " column " << pos.column << std::endl
+ << "'" << err_pos.get_currentline() << "'" << std::endl
+ << std::setw(pos.column) << " "
+ << "^- here");
+ }
+
+private:
+};
+
+struct lazy_create_subsection_ {
+ template <typename, typename, typename, typename> struct result {
+ typedef ParserSection & type;
};
-
- 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);
+ 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;
}
- };
-
- /* ---------------------------------------------------------------------- */
- /* 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);
+ 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;
+
+ /* clang-format off */
+ start
+ = mini_section(parent_section)
+ ;
+
+ mini_section
+ = *(
+ entry (lbs::_r1)
+ | section(lbs::_r1)
+ )
+ ;
+
+ entry
+ = (
+ qi::raw[key]
+ >> '='
+ > value
+ ) [ lbs::_pass = lazy_create_parameter(lbs::_1,
+ lbs::_2,
+ *lbs::_r1) ]
+ ;
+
+ 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)
+ ;
+
+ /* clang-format on */
+
+#define AKANTU_SECTION_TYPE_ADD(r, data, elem) \
+ (BOOST_PP_STRINGIZE(elem), AKANTU_SECTION_TYPES_PREFIX(elem))
+
+ section_type.add BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_ADD, _,
+ AKANTU_SECTION_TYPES);
#undef AKANTU_SECTION_TYPE_ADD
- 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");
+ 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
-
+ 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; };
+ const std::string & getErrorMessage() const { return error_message; };
- typedef typename Skipper<Iterator>::type skipper_type;
- skipper_type skipper;
+ typedef typename Skipper<Iterator>::type skipper_type;
+ skipper_type skipper;
- private:
- std::string error_message;
+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::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;
+ qi::symbols<char, SectionType> section_type;
- ParserSection * parent_section;
- };
+ 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 5838147d6..e166b1b53 100644
--- a/src/io/parser/parser.cc
+++ b/src/io/parser/parser.cc
@@ -1,100 +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() {
-}
+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");
+ 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);
+ 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);
+ return ((sub_sections_by_type.insert(std::pair<SectionType, ParserSection>(
+ section.getType(), section)))->second);
}
/* -------------------------------------------------------------------------- */
-std::string Parser::getLastParsedFile() const {
- return last_parsed_file;
-}
+std::string Parser::getLastParsedFile() const { return last_parsed_file; }
/* -------------------------------------------------------------------------- */
-void ParserSection::printself(std::ostream & stream, unsigned int indent) const {
+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);
+ 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 << "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) {
+ 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()) {
+ 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);
+ 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 c66335a46..a828ef98f 100644
--- a/src/io/parser/parser.hh
+++ b/src/io/parser/parser.hh
@@ -1,448 +1,468 @@
/**
* @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 \
+ (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))
+ 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; \
+#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;
+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
+ _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
+/// @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()
+ : 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) {}
+ 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) {
+ void setDebugInfo(const std::string & filename, UInt line, UInt column) {
dbg_filename = filename;
- dbg_line = line;
+ 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 << ")";
+ void printself(std::ostream & stream,
+ __attribute__((unused)) unsigned int indent = 0) const {
+ stream << name << ": " << value << " (" << dbg_filename << ":" << dbg_line
+ << ":" << dbg_column << ")";
}
+
private:
- void setParent(const ParserSection & sect) {
- parent_section = &sect;
- }
+ 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(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) {
+ 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 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(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) {
+ 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*() 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) {
+ 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()
+ : 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)
+ : 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) {
+ 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) {
+ 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);
- /// Clear ParserSection content
- void clear() {parameters.clear(); sub_sections_by_type.clear();}
+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);
+ 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);
+ 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) {
+ 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);
+ 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());
+ 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());
+ 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 {
+ 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 (search_ctx & _ppsc_current_scope)
+ it = parameters.find(name);
- if(it == parameters.end()) {
- if((search_ctx & _ppsc_parent_scope) && parent_section)
+ 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");
+ 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 {
+ 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 (search_ctx & _ppsc_current_scope)
+ it = parameters.find(name);
- if(it == parameters.end()) {
- if((search_ctx & _ppsc_parent_scope) && parent_section)
+ if (it == parameters.end()) {
+ if ((search_ctx & _ppsc_parent_scope) && parent_section)
return parent_section->hasParameter(name, search_ctx);
else {
- return false;
+ 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 {
+ 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; }
+ const std::string & getName() const { return name; }
/// Get section type
- const SectionType & getType() const { return 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;
- }
+ 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:
+public:
/// Parse real scalar
- static Real parseReal (const std::string & value, const ParserSection & section);
+ static Real parseReal(const std::string & value,
+ const ParserSection & section);
/// Parse real vector
- static Vector<Real> parseVector(const std::string & value, const ParserSection & section);
+ 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);
+ 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);
+ 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) {
+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) {
+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 81e4b8e2f..aaf08d3cd 100644
--- a/src/io/parser/parser_input_files.cc
+++ b/src/io/parser/parser_input_files.cc
@@ -1,96 +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) {
+void Parser::parse(const std::string & filename) {
+ this->clean();
std::ifstream input(filename.c_str());
- if(!input.good()) {
+ 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;
+ 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);
+ bool result = qi::phrase_parse(position_begin, position_end, ag, ag.skipper);
- if(!result || position_begin != position_end) {
+ 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
+ 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");
+ << "'" << 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);
+ 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 8d52cfa45..1bac54224 100644
--- a/src/mesh/element_group.hh
+++ b/src/mesh/element_group.hh
@@ -1,181 +1,181 @@
/**
* @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);
inline void removeNode(UInt node_id);
/// 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 11ec5ee3b..0bdd36441 100644
--- a/src/mesh/element_group_inline_impl.cc
+++ b/src/mesh/element_group_inline_impl.cc
@@ -1,132 +1,132 @@
/**
* @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::removeNode(UInt node_id) {
node_group.remove(node_id);
}
/* -------------------------------------------------------------------------- */
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..02c978670 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 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> >
+ 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);
+ return filter.firstType(dim, ghost_type, 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);
+ return filter.lastType(dim, ghost_type, 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 6dece9845..11286a6bc 100644
--- a/src/mesh/group_manager.cc
+++ b/src/mesh/group_manager.cc
@@ -1,1016 +1,1017 @@
/**
* @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>("element_to_fragment",
id,
memory_id);
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", id, memory_id);
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 de547a9c9..4f340676d 100644
--- a/src/mesh/mesh.cc
+++ b/src/mesh/mesh.cc
@@ -1,507 +1,491 @@
/**
* @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 Jan 22 2016
*
* @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"
+#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 << "]";
+ 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, memory_id),
normals("normals", id, memory_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", memory_id, 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, memory_id),
normals("normals", id, memory_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, memory_id),
normals("normals", id, memory_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 = 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) {
+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.");
+ 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) {
+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);
+ 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 << " + spatial dimension : " << this->spatial_dimension
+ << std::endl;
stream << space << " + nodes [" << std::endl;
- nodes->printself(stream, indent+2);
+ nodes->printself(stream, indent + 2);
stream << space << " + connectivities [" << std::endl;
- connectivities.printself(stream, indent+2);
+ connectivities.printself(stream, indent + 2);
stream << space << " ]" << std::endl;
GroupManager::printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
-void Mesh::computeBoundingBox(){
+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();
+ 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];
+ Matrix<Real> reduce_bounds(spatial_dimension, 2);
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);
+ reduce_bounds(k, 0) = local_lower_bounds(k);
+ reduce_bounds(k, 1) = -local_upper_bounds(k);
}
-
- comm.allReduce(reduce_bounds, 2 * spatial_dimension, _so_min);
+
+ comm.allReduce(reduce_bounds.storage(), reduce_bounds.size(), _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];
+ lower_bounds(k) = reduce_bounds(k, 0);
+ upper_bounds(k) = -reduce_bounds(k, 1);
}
- }
- else {
+ } 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>
+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 {
+ 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;
+ 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);
+ flag_nb_node_per_elem_multiply, element_kind,
+ size_to_nb_element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+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 {
+ 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);
+ 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>
+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 {
+ 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 it = firstType(dim, gt, element_kind);
Mesh::type_iterator end = lastType(dim, gt, element_kind);
- for(; it != end; ++it) {
+ for (; it != end; ++it) {
ElementType type = *it;
UInt nb_comp = nb_component;
- if (flag_nb_node_per_elem_multiply) nb_comp *= Mesh::getNbNodesPerElement(*it);
+ 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);
+ 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);
+ this->initElementTypeMapArray(normals, spatial_dimension, spatial_dimension,
+ false, _ek_not_defined);
}
/* -------------------------------------------------------------------------- */
-void Mesh::getGlobalConnectivity(ElementTypeMapArray<UInt> & global_connectivity,
- UInt dimension,
- GhostType ghost_type) {
+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 it = firstType(dimension, ghost_type);
Mesh::type_iterator end = lastType(dimension, ghost_type);
- for(; it != end; ++it) {
+ 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);
+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;
-
+#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){
+ 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) {
+
+ 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) = 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);
+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 *
+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 (...){
+ } catch (...) {
return NULL;
}
- ElementTypeMap<UInt> nb_data_per_elem =
- this->getNbDataPerElem(*internal,element_kind);
+ 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);
+ field = this->createElementalField<T, dumper::InternalMaterialField>(
+ *internal, group_name, this->spatial_dimension, element_kind,
+ nb_data_per_elem);
return field;
}
-template dumper::Field *
+template dumper::Field *
Mesh::createFieldFromAttachedData<Real>(const std::string & field_id,
- const std::string & group_name,
- const ElementKind & element_kind);
+ const std::string & group_name,
+ const ElementKind & element_kind);
-template dumper::Field *
+template dumper::Field *
Mesh::createFieldFromAttachedData<UInt>(const std::string & field_id,
- const std::string & group_name,
- const ElementKind & element_kind);
+ 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 a34cadb97..0ff233c68 100644
--- a/src/mesh/mesh.hh
+++ b/src/mesh/mesh.hh
@@ -1,577 +1,578 @@
/**
* @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 id of the mesh
AKANTU_GET_MACRO(MemoryID, Memory::memory_id, const MemoryID &);
/// 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..fcd25618d 100644
--- a/src/mesh/mesh_filter.hh
+++ b/src/mesh/mesh_filter.hh
@@ -1,75 +1,75 @@
/**
* @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
- };
+ enum Type { _node_filter_functor, _element_filter_functor };
};
/// class (functor) for the node filter
class NodeFilterFunctor : public FilterFunctor {
public:
- bool operator()(UInt node) {
+ bool operator()(__attribute__((unused)) 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) {
+ bool operator()(__attribute__((unused)) 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 6ebe61f2a..e9a4c5624 100644
--- a/src/mesh/mesh_inline_impl.cc
+++ b/src/mesh/mesh_inline_impl.cc
@@ -1,600 +1,609 @@
/**
* @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: Thu Jan 21 2016
*
* @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"
+#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 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(), mesh.getMemoryID()) {
}
/* -------------------------------------------------------------------------- */
template <>
-inline void Mesh::sendEvent<RemovedElementsEvent>(RemovedElementsEvent & event) {
+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());
+ 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) {
+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)) {
+ if (new_i != UInt(-1)) {
memcpy(tmp.storage() + new_i * nb_component,
- vect.storage() + i * nb_component,
- nb_component * sizeof(T));
+ 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) {
+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.");
+ AKANTU_DEBUG_ASSERT(sizeof...(Args) <= spatial_dimension,
+ "Number of arguments greater than dimension.");
// unpack parameters
- Real s[] = { params... };
+ Real s[] = {params...};
- Array<Real>& nodes = getNodes();
+ 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());
+ 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 {
+inline Element Mesh::linearizedToElement(UInt linearized_element) const {
UInt t;
for (t = _not_defined;
- t != _max_element_type && linearized_element >= types_offsets(t);
- ++t);
+ 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());
+ "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));
+ 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;
+ 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 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 {
+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";
+ 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) {
+ 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) {
+inline Array<UInt> *
+Mesh::getConnectivityPointer(const ElementType & type,
+ const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
Array<UInt> * tmp;
- if(!connectivities.exists(type, ghost_type)) {
+ 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));
+ tmp = &(connectivities.alloc(0, nb_nodes_per_element, type, ghost_type));
- AKANTU_DEBUG_INFO("The connectivity vector for the type "
- << type << " created");
+ 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);
+ 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);
+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);
+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 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 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 {
+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) {
+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);
+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>
+template <typename T>
inline const Array<T> & Mesh::getData(const std::string & data_name,
- const ElementType & el_type,
- const GhostType & ghost_type) const {
+ const ElementType & el_type,
+ const GhostType & ghost_type) const {
return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+template <typename T>
inline Array<T> & Mesh::getData(const std::string & data_name,
- const ElementType & el_type,
+ 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 {
+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>
+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) {
+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 {
+ 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 {
+ const GhostType & ghost_type,
+ const ElementKind & kind) const {
UInt nb_element = 0;
- type_iterator it = firstType(spatial_dimension, ghost_type, kind);
+ 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);
+ 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 {
+ 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];
+ Real * local_coord = new Real[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));
+ nodes->storage() + conn_val[offset + n] * spatial_dimension,
+ spatial_dimension * sizeof(Real));
}
- Math::barycenter(local_coord, nb_nodes_per_element, spatial_dimension, barycenter);
+ Math::barycenter(local_coord, nb_nodes_per_element, spatial_dimension,
+ barycenter);
+
+ delete [] local_coord;
}
/* -------------------------------------------------------------------------- */
-inline void Mesh::getBarycenter(const Element & element, Vector<Real> & barycenter) const {
- getBarycenter(element.element, element.type, barycenter.storage(), element.ghost_type);
+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) \
+#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()
+#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()
+#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) \
+#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) {
+inline UInt Mesh::getNbFacetTypes(const ElementType & type,
+ __attribute__((unused)) UInt t) {
UInt nb = 0;
-#define GET_NB_FACET_TYPE(type) \
- nb = ElementClass<type>::getNbFacetTypes()
+#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)
+#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()); \
+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()
+#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) \
+#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) {
+inline MatrixProxy<UInt>
+Mesh::getFacetLocalConnectivity(const ElementType & type, UInt t) {
AKANTU_DEBUG_IN();
-#define GET_FACET_CON(type) \
- AKANTU_DEBUG_OUT(); \
+#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
+ // also cause a segfault if reached
}
/* -------------------------------------------------------------------------- */
-inline Matrix<UInt> Mesh::getFacetConnectivity(const Element & element, UInt t) const {
+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 {
+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));
+ 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){
+ 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;
+ 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) {
+ 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 9030c7443..c783039e7 100644
--- a/src/mesh/node_group.hh
+++ b/src/mesh/node_group.hh
@@ -1,136 +1,137 @@
/**
* @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 a node
inline void remove(UInt node);
/// 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 fb6001118..e3e0fe046 100644
--- a/src/mesh/node_group_inline_impl.cc
+++ b/src/mesh/node_group_inline_impl.cc
@@ -1,101 +1,102 @@
/**
* @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 void NodeGroup::remove(UInt node) {
Array<UInt>::iterator<> it = this->node_group.begin();
Array<UInt>::iterator<> end = this->node_group.end();
AKANTU_DEBUG_ASSERT(it != end, "The node group is empty!!");
for (; it != node_group.end(); ++it) {
if (*it == node) {
it = node_group.erase(it);
}
}
AKANTU_DEBUG_ASSERT(it != end, "The node was not found!");
}
/* -------------------------------------------------------------------------- */
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..1a8cee47b 100644
--- a/src/mesh_utils/mesh_partition.cc
+++ b/src/mesh_utils/mesh_partition.cc
@@ -1,424 +1,440 @@
/**
* @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: Fri Jan 22 2016
*
* @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) {
+ 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();
}
/* -------------------------------------------------------------------------- */
/**
+ * TODO this function should most probably be rewritten in a more modern way
* 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) {
+ 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];
+ Vector<UInt> nb_nodes_per_element_p1(nb_types);
- UInt magic_number[nb_types];
+ Vector<UInt> magic_number(nb_types);
// UInt * conn_val[nb_types];
- UInt nb_element[nb_types];
+ Vector<UInt> nb_element(nb_types);
- Array<UInt> * conn[nb_types];
+ Array<UInt> ** conn = new Array<UInt> *[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) {
+ for (it = type_list.begin(); it != type_list.end(); ++it) {
ElementType type = *it;
- if(Mesh::getSpatialDimension(type) != mesh.getSpatialDimension()) continue;
+ 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));
+ 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));
+ 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];
+ 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);
+ 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));
+ 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++;
- }
- }
+ 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;
+ 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;
+ /// 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)++;
+ UInt index_adj = dxadj(adjacent_el)++;
+ UInt index_lin = dxadj(linerized_el)++;
- dadjncy(index_lin) = adjacent_el;
- dadjncy(index_adj) = 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);
+ 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);
+ 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 = 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;
}
}
+ delete [] conn;
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void MeshPartition::fillPartitionInformation(const Mesh & mesh,
- const Int * linearized_partitions) {
+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);
+ 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) {
+ 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);
+ 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);
+ 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);
- }
- }
+ 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)++;
+ 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_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);
+ 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);
+ 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(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) {
+ 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);
+ 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);
+ 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 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()) {
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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();
+ 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;
+ 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);
+ 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) {
+ for (; it != end; ++it) {
ElementType type = *it;
- Array<UInt> & conn = const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
+ Array<UInt> & conn =
+ const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
UInt nb_nodes_per_element = conn.getNbComponent();
- UInt nb_element = conn.getSize();
+ UInt nb_element = conn.getSize();
- Array<UInt> & saved_conn = saved_connectivity.alloc(nb_element, nb_nodes_per_element, type, _not_ghost);
+ 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);
- }
+ 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) {
+ 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> & 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..5665b17fa 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,141 @@
/**
* @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,
+MeshPartitionMeshData::MeshPartitionMeshData(const Mesh & mesh,
+ UInt spatial_dimension,
const ID & id,
- const MemoryID & memory_id) :
- MeshPartition(mesh, spatial_dimension, id, memory_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) {
+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,
+ __attribute__((unused))
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);
+ 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) {
+ 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) {
+ 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");
+ 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::reorder() { AKANTU_DEBUG_TO_IMPLEMENT(); }
/* -------------------------------------------------------------------------- */
-void MeshPartitionMeshData::setPartitionMapping(const ElementTypeMapArray<UInt> & mapping) {
- partition_mapping = &mapping;
+void MeshPartitionMeshData::setPartitionMapping(
+ const ElementTypeMapArray<UInt> & mapping) {
+ partition_mapping = &mapping;
}
/* -------------------------------------------------------------------------- */
-void MeshPartitionMeshData::setPartitionMappingFromMeshData(const std::string & data_name) {
+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..10d386bbc 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
+++ b/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
@@ -1,479 +1,468 @@
/**
* @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: Fri Jan 22 2016
*
* @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
+#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
+#include <scotch.h>
+#ifndef AKANTU_SCOTCH_NO_EXTERN
}
-# endif //AKANTU_SCOTCH_NO_EXTERN
-#else //AKANTU_USE_PTSCOTCH
-# include <ptscotch.h>
-#endif //AKANTU_USE_PTSCOTCH
-
+#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) {
+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 it = mesh.firstType(spatial_dimension);
Mesh::type_iterator end = mesh.lastType(spatial_dimension);
- for(; it != end; ++it) {
+ 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) {
+ it = mesh.firstType(spatial_dimension);
+ for (; it != end; ++it) {
ElementType type = *it;
- if(Mesh::getSpatialDimension(type) != spatial_dimension) continue;
+ 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++)]++;
+ 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];
+ 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 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) {
+ 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;
+ edgetab[verttab[*(conn_val++)]++] = linearized_el + velmbas;
}
}
- for (UInt i = nb_nodes; i > 0; --i) verttab[i] = verttab[i-1];
+ 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) {
+ 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;
+ UInt * conn = connectivity.storage() + el * nb_nodes_per_element;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
- *(edgetab_tmp++) = *(conn++) + vnodbas;
+ *(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);
+ 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");
+ "Scotch mesh is not consistent");
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
/// save initial graph
- FILE *fmesh = fopen("ScotchMesh.msh", "w");
+ 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;
+ 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 << *(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_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);
+ SCOTCH_meshData(meshptr, &velmbas, &vnodbas, &velmnbr, &vnodnbr, &verttab,
+ &vendtab, &velotab, &vnlotab, &vlbltab, &edgenbr, &edgetab,
+ &degrptr);
- delete [] verttab;
- delete [] edgetab;
+ 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) {
+ 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.");
+ 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;
+ 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)
+ 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);
+ 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);
+ 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");
+ 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;
+ 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);
+ 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);
+ Array<Real>::const_vector_iterator nodes_it =
+ nodes.begin(spatial_dimension);
UInt out_linerized_el = 0;
- for(; f_it != f_end; ++f_it) {
+ 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] ;
+ Vector<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;;
+ mid.set(0.);
+ for (UInt n = 0; n < nb_nodes_per_element; ++n) {
+ UInt node = connectivity.storage()[nb_nodes_per_element * el + n];
+ mid += Vector<Real>(nodes_it[node]);
+ }
+ mid /= 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");
-
+ "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");
+ "Partitioned graph is not consistent");
#ifndef AKANTU_NDEBUG
if (AKANTU_DEBUG_TEST(dblDump)) {
/// save the partitioned graph
- FILE *fgraph=fopen("GraphFile.grf", "w");
+ 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;
+ 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;
+ 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_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 cblknbr = 0;
SCOTCH_Num * rangtab = NULL;
SCOTCH_Num * treetab = NULL;
/// Initialize the strategy structure
- SCOTCH_stratInit (&scotch_strat);
+ 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);
+ 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_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;
+ for (UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType gt = (GhostType)g;
- Mesh::type_iterator it = mesh.firstType(_all_dimensions, gt);
+ Mesh::type_iterator it = mesh.firstType(_all_dimensions, gt);
Mesh::type_iterator end = mesh.lastType(_all_dimensions, gt);
- for(; it != end; ++it) {
+ 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();
+ UInt * conn = connectivity.storage();
for (UInt el = 0; el < nb_element * nb_nodes_per_element; ++el, ++conn) {
- *conn = permtab[*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));
+ old_coordinates + i * spatial_dimension,
+ spatial_dimension * sizeof(Real));
}
- memcpy(old_coordinates, new_coordinates, nb_nodes * spatial_dimension * sizeof(Real));
- delete [] new_coordinates;
+ memcpy(old_coordinates, new_coordinates,
+ nb_nodes * spatial_dimension * sizeof(Real));
+ delete[] new_coordinates;
- delete [] permtab;
+ 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 c31cc36ac..69a1252a4 100644
--- a/src/mesh_utils/mesh_utils.cc
+++ b/src/mesh_utils/mesh_utils.cc
@@ -1,2204 +1,2243 @@
/**
* @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: Fri Jan 22 2016
*
* @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) {
+ CSR<Element> & node_to_elem,
+ UInt spatial_dimension) {
AKANTU_DEBUG_IN();
- if (spatial_dimension == _all_dimensions) spatial_dimension = mesh.getSpatialDimension();
-
+ 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!");
+ 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 (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));
+ 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));
+ 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);
+ 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));
+ 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);
+ 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) {
+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();
+ 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];
+ Vector<UInt> nb_nodes_per_element(nb_types);
+ UInt ** conn_val = new UInt *[nb_types];
+ Vector<UInt> nb_element(nb_types);
- UInt * conn_val[nb_types];
- UInt nb_element[nb_types];
-
-
- for(it = type_list.begin(); it != type_list.end(); ++it) {
+ for (it = type_list.begin(); it != type_list.end(); ++it) {
ElementType type = *it;
- if(Mesh::getSpatialDimension(type) != spatial_dimension) continue;
+ if (Mesh::getSpatialDimension(type) != spatial_dimension)
+ continue;
- nb_nodes_per_element[nb_good_types] = Mesh::getNbNodesPerElement(type);
+ 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_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!");
+ 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];
+ 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.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];
+ 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.insertInRow(conn_val[t][el_offset + n], linearized_el);
}
node_to_elem.endInsertions();
-
+ delete [] conn_val;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildNode2ElementsElementTypeMap(const Mesh & mesh,
- CSR<UInt> & node_to_elem,
- const ElementType & type,
- const GhostType & ghost_type) {
+ 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;
+ 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;
+ 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){
+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 it = mesh.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh.lastType(spatial_dimension - 1, gt_facet);
- for(; it != end; ++it) {
+ for (; it != end; ++it) {
mesh.getConnectivity(*it, *gt).resize(0);
// \todo inform the mesh event handler
}
}
- buildFacetsDimension(mesh,
- mesh,
- true,
- spatial_dimension);
+ buildFacetsDimension(mesh, mesh, true, spatial_dimension);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void MeshUtils::buildAllFacets(const Mesh & mesh,
- Mesh & mesh_facets,
- UInt to_dimension,
- DistributedSynchronizer * synchronizer) {
+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);
+ 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) {
+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");
+ 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);
+ 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);
+ 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){
+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
+ // 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);
+ 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) {
+ 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);
+ Mesh::type_iterator last = mesh.lastType(dimension, ghost_type);
- for(; first != last; ++first) {
+ 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);
+ 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) {
+ 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);
+ Mesh::type_iterator last = mesh.lastType(dimension, ghost_type);
- for(; first != last; ++first) {
+ 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);
- }
- }
- }
- }
- }
- }
+ 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) {
+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);
+ (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) {
+ 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));
+ 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));
+ 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) {
+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()) {
+ 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;
+ 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) {
+ 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);
+ 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);
+ 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))
+ 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 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);
+ } 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);
+ 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) {
+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);
+ 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);
+ 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) {
+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 it = mesh_facets.firstType(facet_dimension, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(facet_dimension, gt_facet);
- for(; it != end; ++it) {
+ for (; it != end; ++it) {
ElementType type_facet = *it;
- Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
- type_facet,
- gt_facet);
+ 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;
+ if (nb_facet_to_double == 0)
+ continue;
ElementType type_subfacet = Mesh::getFacetType(type_facet);
- const UInt nb_subfacet_per_facet = Mesh::getNbFacetsPerElement(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<Element> & subfacet_to_facet =
+ mesh_facets.getSubelementToElement(type_facet, gt_facet);
- Array<UInt> & conn_facet = mesh_facets.getConnectivity(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);
+ 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);
- }
+ 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);
+ 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) {
+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);
+ 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) {
+ 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<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);
+ 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;
+ if (f_insertion(f) == false)
+ continue;
- ++nb_facets_to_double;
+ ++nb_facets_to_double;
- if (element_to_facet(f)[1].type == _not_defined
+ if (element_to_facet(f)[1].type == _not_defined
#if defined(AKANTU_COHESIVE_ELEMENT)
- || element_to_facet(f)[1].kind == _ek_cohesive
+ || 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_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;
+ 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 it = mesh_facets.firstType(_all_dimensions, gt);
Mesh::type_iterator end = mesh_facets.lastType(_all_dimensions, gt);
- for(; it != end; ++it) {
+ 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> >(
+ "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> >(
+ "elements_to_subfacet_double", type, gt, 1, false);
- mesh_facets.getDataPointer<std::vector<Element> >
- ("subfacets_to_subsubfacet_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;
+ 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);
+ 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) {
+ for (; it != end; ++it) {
ElementType type_facet = *it;
- Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
- type_facet,
- gt_facet);
+ 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;
+ 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);
+ 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<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<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>;
+ subfacet_list = new std::vector<Element>;
/// map to filter subfacets
- Array< std::vector<Element> > * facet_to_subfacet = NULL;
+ 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);
- }
- }
- }
- }
+ 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;
+ delete subfacet_list;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_COHESIVE_ELEMENT)
-void MeshUtils::updateCohesiveData(Mesh & mesh,
- Mesh & mesh_facets,
- Array<Element> & new_elements) {
+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);
+ 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) {
+ for (; it != end; ++it) {
ElementType type_facet = *it;
- Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
- type_facet,
- gt_facet);
+ 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;
+ 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<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);
+ 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);
+ 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 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;
+ /// (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;
+ 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;
+ /// 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);
- }
+ /// 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;
+ /// 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;
+ /// 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) {
+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;
+ 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);
+ 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) {
+ 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);
+ 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);
+ 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;
+ 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;
+ 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;
+ UInt old_node = conn_facet(old_facet);
+ UInt new_node = old_nb_nodes + facet;
- /// update position
- position(new_node) = position(old_node);
+ /// 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();
+ 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;
+ /// 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;
+ 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) {
+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;
+ if (type_facet != _segment_3)
+ return;
- Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
- type_facet,
- gt_facet);
+ 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;
+ 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<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
- Array< std::vector<Element> > & element_to_facet
- = mesh_facets.getElementToSubelement(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;
+ 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);
+ 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);
+ 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;
+ 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));
+ 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) {
+ 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);
+ 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;
+ 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);
+ 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);
+ 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;
+ 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();
+ 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);
+ 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");
+ 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) {
+ 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);
+ 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 =
+ mesh_facets.getElementToSubelement(type_subfacet, gt_subfacet);
- Array< std::vector<Element> > * facet_to_subfacet_double = NULL;
+ 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);
+ 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) {
+void MeshUtils::doubleSubfacet(Mesh & mesh, Mesh & mesh_facets,
+ Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
- if (spatial_dimension == 1) return;
+ 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 it = mesh_facets.firstType(0, gt_subfacet);
Mesh::type_iterator end = mesh_facets.lastType(0, gt_subfacet);
- for(; it != end; ++it) {
+ for (; it != end; ++it) {
ElementType type_subfacet = *it;
- Array<UInt> & sf_to_double = mesh_facets.getData<UInt>("facet_to_double",
- type_subfacet,
- gt_subfacet);
+ 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;
+ if (nb_subfacet_to_double == 0)
+ continue;
- AKANTU_DEBUG_ASSERT(type_subfacet == _point_1,
- "Only _point_1 subfacet doubling is supported at the moment");
+ 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);
+ 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));
+ 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);
+ UInt new_subfacet = old_nb_subfacet + sf;
+ UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
- conn_subfacet(new_subfacet) = new_node;
+ 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);
+ 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);
+ 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);
+ 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));
+ 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);
+ 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) {
+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("global_connectivity_tmp", mesh_facets.getID(), mesh_facets.getMemoryID());
mesh_facets.initElementTypeMapArray(global_connectivity_tmp, 1,
- spatial_dimension - 1, gt_facet,
- true, _ek_regular, true);
+ spatial_dimension - 1, gt_facet, true,
+ _ek_regular, true);
mesh_facets.getGlobalConnectivity(global_connectivity_tmp,
- spatial_dimension - 1, gt_facet);
+ 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);
+ 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) {
+ 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<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);
+ mesh_facets.getElementToSubelement(type_facet, gt_facet);
Array<Element> & subfacet_to_facet =
- mesh_facets.getSubelementToElement(type_facet, gt_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));
+ 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> & global_conn_tmp =
+ global_connectivity_tmp(type_facet, gt_facet);
Array<UInt>::iterator<Vector<UInt> > conn_it =
- connectivity.begin(nb_nodes_per_facet);
+ connectivity.begin(nb_nodes_per_facet);
Array<UInt>::iterator<Vector<UInt> > gconn_tmp_it =
- global_conn_tmp.begin(nb_nodes_per_facet);
+ global_conn_tmp.begin(nb_nodes_per_facet);
Array<UInt>::const_iterator<Vector<UInt> > conn_glob_it =
- g_connectivity.begin(nb_nodes_per_facet);
+ g_connectivity.begin(nb_nodes_per_facet);
Array<Element>::iterator<Vector<Element> > subf_to_f =
- subfacet_to_facet.begin(nb_subfacet_per_facet);
+ 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) {
+ 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> & 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;
+ 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_node = std::find(begin, end, gconn_tmp(n));
+ AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
- UInt new_position = new_node - begin;
+ UInt new_position = new_node - begin;
- conn_local(new_position) = conn_tmp(n);
+ 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;
+ /// 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;
+ 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.");
+ 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.getMemoryID());
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);
+ 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) {
+ 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);
+ 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);
+ mesh.getBarycenter(el, *it, bary->storage(), *gt);
}
}
}
- for(Int sp(spatial_dimension); sp >= 1; --sp) {
- if(mesh.getNbElement(sp) == 0) continue;
+ 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);
+ 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();
+ for (; tit != tend; ++tit) {
+ mesh.getSubelementToElementPointer(*tit, *git)
+ ->resize(mesh.getNbElement(*tit, *git));
+ mesh.getSubelementToElement(*tit, *git).clear();
}
- tit = mesh.firstType(sp - 1, *git);
+ 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();
+ 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);
+ 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;
- }
- }
+ 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) {
+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 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_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);
+ 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);
+ const Element & current_facet =
+ (*facet_to_element)(current_el.element, f);
- if (current_facet == ElementNull) continue;
+ if (current_facet == ElementNull)
+ continue;
if (current_facet_type != current_facet.type ||
- current_facet_ghost_type != current_facet.ghost_type) {
+ current_facet_ghost_type != current_facet.ghost_type) {
- 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);
+ 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);
+ 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;
+ 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;
+ 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];
+ 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];
+ opposing_el = &(*element_to_facet)(current_facet.element)[0];
/// skip null elements since they are on a boundary
- if (*opposing_el == ElementNull) continue;
+ 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;
+ 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);
+ 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);
+ 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");
+ 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) {
+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();
+ 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) {
+ gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
- Mesh::type_iterator it = mesh_facets.firstType(1, ghost_type);
+ Mesh::type_iterator it = mesh_facets.firstType(1, ghost_type);
Mesh::type_iterator end = mesh_facets.lastType(1, ghost_type);
- for(; it != end; ++it) {
+ 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));
+ 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);
+ 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");
+ // 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) {
+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;
+ 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);
+ 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);
+ 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);
+ 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);
+ 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;
+ 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);
+ 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..5354a89b9 100644
--- a/src/model/boundary_condition_functor.hh
+++ b/src/model/boundary_condition_functor.hh
@@ -1,207 +1,194 @@
/**
* @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;
+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()(__attribute__((unused)) UInt node,
+ __attribute__((unused)) Vector<bool> & flags,
+ __attribute__((unused)) Vector<Real> & primal,
+ __attribute__((unused)) 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;
- struct Functor {
- enum Type {
- _dirichlet,
- _neumann
- };
+ 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;
};
- /* ------------------------------------------------------------------------ */
- /* 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
+ /* ---------------------------------------------------------------------- */
+ 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..712363225 100644
--- a/src/model/boundary_condition_functor_inline_impl.cc
+++ b/src/model/boundary_condition_functor_inline_impl.cc
@@ -1,130 +1,139 @@
/**
- * @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!");
+#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;
- }
+namespace Dirichlet {
+ /* ------------------------------------------------------------------------ */
+ inline void FlagOnly::operator()(__attribute__((unused)) UInt node,
+ Vector<bool> & flags, __attribute__((unused))
+ Vector<Real> & primal,
+ __attribute__((unused))
+ const Vector<Real> & coord) const {
- /* ---------------------------------------------------------------------- */
- inline void FreeBoundary::operator()(UInt node,
- Vector<bool> & flags,
- Vector<Real> & primal,
- const Vector<Real> & coord) const {
+ DIRICHLET_SANITY_CHECK;
- DIRICHLET_SANITY_CHECK;
+ flags(this->axis) = true;
+ }
- flags(axis) = false;
- }
+ /* ------------------------------------------------------------------------ */
+ inline void FreeBoundary::
+ operator()(__attribute__((unused)) UInt node, Vector<bool> & flags,
+ __attribute__((unused)) Vector<Real> & primal,
+ __attribute__((unused)) const Vector<Real> & coord) const {
- /* ---------------------------------------------------------------------- */
- 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;
- }
+ DIRICHLET_SANITY_CHECK;
- /* ---------------------------------------------------------------------- */
- 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
+ flags(this->axis) = false;
+ }
/* ------------------------------------------------------------------------ */
- /* Neumann */
+ inline void FixedValue::operator()(__attribute__((unused)) UInt node,
+ Vector<bool> & flags,
+ Vector<Real> & primal,
+ __attribute__((unused))
+ const Vector<Real> & coord) const {
+ DIRICHLET_SANITY_CHECK;
+ flags(this->axis) = true;
+ primal(this->axis) = value;
+ }
+
/* ------------------------------------------------------------------------ */
- 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 IncrementValue::operator()(__attribute__((unused)) UInt node,
+ Vector<bool> & flags,
+ Vector<Real> & primal,
+ __attribute__((unused))
+ const Vector<Real> & coord) const {
+ DIRICHLET_SANITY_CHECK;
+ flags(this->axis) = true;
+ primal(this->axis) += value;
+ }
+} // end namespace Dirichlet
- /* -------------------------------------------------------------------------- */
- 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);
+/* -------------------------------------------------------------------------- */
+/* Neumann */
+/* -------------------------------------------------------------------------- */
+namespace Neumann {
+ /* ------------------------------------------------------------------------ */
+ inline void FreeBoundary::
+ operator()(__attribute__((unused)) const IntegrationPoint & quad_point,
+ Vector<Real> & dual,
+ __attribute__((unused)) const Vector<Real> & coord,
+ __attribute__((unused)) const Vector<Real> & normals) const {
+ for (UInt i(0); i < dual.size(); ++i) {
+ dual(i) = 0.0;
}
+ }
- /* -------------------------------------------------------------------------- */
- inline void FromSameDim::operator()(const IntegrationPoint & quad_point,
+ /* ------------------------------------------------------------------------ */
+ inline void FromHigherDim::operator()(__attribute__((unused))
+ const IntegrationPoint & quad_point,
Vector<Real> & dual,
+ __attribute__((unused))
const Vector<Real> & coord,
const Vector<Real> & normals) const {
- dual = bc_data;
- }
- } // end namespace Neumann
-} // end namespace BC
+ dual.mul<false>(this->bc_data, normals);
+ }
+ /* ------------------------------------------------------------------------ */
+ inline void FromSameDim::
+ operator()(__attribute__((unused)) const IntegrationPoint & quad_point,
+ Vector<Real> & dual,
+ __attribute__((unused)) const Vector<Real> & coord,
+ __attribute__((unused)) const Vector<Real> & normals) const {
+ dual = this->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 add453712..7be491318 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, memory_id),
criterion(criterion_id, id, memory_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 6b95ab489..ae9bf1289 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, memory_id),
volumes("volumes", id, memory_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 e7572726d..299b6204b 100644
--- a/src/model/common/non_local_toolbox/non_local_manager.hh
+++ b/src/model/common/non_local_toolbox/non_local_manager.hh
@@ -1,285 +1,289 @@
/**
* @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,
const MemoryID & memory_id);
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, 0),
non_local(nl_variable_name, id, 0),
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 59be3e0ee..1bb8c95dd 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,248 @@
/**
* @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) {
+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");
+ "The neighborhood " << neighborhood
+ << "has not been created");
neighborhoods[neighborhood]->insertQuad(quad, coords);
-
}
/* -------------------------------------------------------------------------- */
-inline void NonLocalManager::registerNeighborhood(const ID & neighborhood, const ID & weight_func_id) {
-
+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{
+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");
+ "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();
+ std::set<ID>::const_iterator global_neighborhood_it =
+ global_neighborhoods.begin();
NeighborhoodMap::iterator it;
- for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_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);
+ 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) {
+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);
-
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_it =
+ non_local_variables.find(variable_name);
- AKANTU_DEBUG_OUT();
+ 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) {
+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);
+ 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, memory_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();
+
+ 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;
+ 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) {
+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");
+ 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 {
+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);
+ 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");
+ "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 {
+inline void NonLocalManager::packElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ __attribute__((unused))
+ SynchronizationTag tag,
+ const ID & id) const {
- std::map<ID, NonLocalVariable *>::const_iterator it = non_local_variables.find(id);
+ 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");
+ "The non-local variable " << id << " is not registered");
- DataAccessor::packElementalDataHelper<Real>(it->second->local, buffer, elements, true,
- this->model.getFEEngine());
+ 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 {
+inline void NonLocalManager::unpackElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ __attribute__((unused))
+ SynchronizationTag tag,
+ const ID & id) const {
- std::map<ID, NonLocalVariable *>::const_iterator it = non_local_variables.find(id);
+ 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");
+ "The non-local variable " << id << " is not registered");
- DataAccessor::unpackElementalDataHelper<Real>(it->second->local, buffer, elements, true,
- this->model.getFEEngine());
+ 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..c00a8b6a8 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,127 @@
/**
* @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{
+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);
+ 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() {};
+ 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 {};
+ virtual void weightedAverageOnNeighbours(
+ __attribute__((unused)) const ElementTypeMapReal & to_accumulate,
+ __attribute__((unused)) ElementTypeMapReal & accumulated,
+ __attribute__((unused)) UInt nb_degree_of_freedom,
+ __attribute__((unused)) const GhostType & ghost_type2) const {};
/// update the weights for the non-local averaging
- virtual void updateWeights() {};
+ virtual void updateWeights(){};
/// register a new non-local variable in the neighborhood
- virtual void registerNonLocalVariable(const ID & id) {};
+ virtual void registerNonLocalVariable(__attribute__((unused))
+ 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 */
-/* -------------------------------------------------------------------------- */
+ /* --------------------------------------------------------------------------
+ */
+ /* 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 */
-/* -------------------------------------------------------------------------- */
+ 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> & 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(NonLocalVariables, non_local_variables, const std::set<ID> &);
+ 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..0fb2fadd0 100644
--- a/src/model/heat_transfer/heat_transfer_model.cc
+++ b/src/model/heat_transfer/heat_transfer_model.cc
@@ -1,1255 +1,1270 @@
/**
* @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"
+#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);
+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) {
+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);
+ std::stringstream sstr;
+ sstr << id << ":fem";
+ registerFEEngineObject<MyFEEngineType>(sstr.str(), mesh, spatial_dimension);
- this->temperature= NULL;
+ 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);
+ 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) {
+ DataAccessor * data_accessor) {
AKANTU_DEBUG_IN();
- if (data_accessor == NULL) data_accessor = this;
- Synchronizer & synch_parallel = createParallelSynch(partition,data_accessor);
+ 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);
+ 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);
+ changeLocalEquationNumberForPBC(pbc_pair, 1);
- // as long as there are ones on the diagonal of the matrix, we can put boudandary true for slaves
+ // 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;
+ 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));
+ 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(temperature_on_qpoints, 1,
+ spatial_dimension);
- getFEEngine().getMesh().initElementTypeMapArray(conductivity_on_qpoints,
- spatial_dimension*spatial_dimension,
- spatial_dimension);
+ getFEEngine().getMesh().initElementTypeMapArray(
+ temperature_gradient, spatial_dimension, spatial_dimension);
- getFEEngine().getMesh().initElementTypeMapArray(k_gradt_on_qpoints,
- spatial_dimension,
- spatial_dimension);
+ getFEEngine().getMesh().initElementTypeMapArray(
+ conductivity_on_qpoints, spatial_dimension * spatial_dimension,
+ spatial_dimension);
- getFEEngine().getMesh().initElementTypeMapArray(bt_k_gT,
- 1,
- spatial_dimension,
- true);
+ getFEEngine().getMesh().initElementTypeMapArray(
+ k_gradt_on_qpoints, spatial_dimension, spatial_dimension);
- getFEEngine().getMesh().initElementTypeMapArray(int_bt_k_gT,
- 1,
- spatial_dimension,
- true);
+ getFEEngine().getMesh().initElementTypeMapArray(bt_k_gT, 1, spatial_dimension,
+ true);
- getFEEngine().getMesh().initElementTypeMapArray(thermal_energy,
- 1,
- spatial_dimension);
+ 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;
+ for (UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType gt = (GhostType)g;
const Mesh::ConnectivityTypeList & type_list =
- getFEEngine().getMesh().getConnectivityTypeList(gt);
+ getFEEngine().getMesh().getConnectivityTypeList(gt);
- for(it = type_list.begin(); it != type_list.end(); ++it) {
- if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
+ 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;
+ 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 = 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
+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);
+ 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);
+ 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";
+ 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
+#endif // AKANTU_USE_MUMPS
- if(solver)
+ if (solver)
solver->initialize(options);
-#endif //AKANTU_HAS_SOLVER
+#endif // AKANTU_HAS_SOLVER
}
/* -------------------------------------------------------------------------- */
-void HeatTransferModel::initImplicit(bool dynamic, SolverOptions & solver_options) {
+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;
+ if (method == _implicit_dynamic) {
+ if (integrator)
+ delete integrator;
integrator = new TrapezoidalRule1();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-HeatTransferModel::~HeatTransferModel()
-{
+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 ;
+ 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);
+ 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;
+ 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);
+ 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);
+ 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) {
+void HeatTransferModel::updateResidual(
+ __attribute__((unused)) 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
+ // 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();
- }*/
-
+ /* 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;
+ 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) {
+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);
+ 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) {
+ 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);
+ 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);
+ 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");
+ 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>::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);
+ 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);
+ 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");
+ 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);
+ 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) {
+ if (method != _static) {
// f -= Mddot
- if(capacity_matrix) {
+ 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();
+ 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++;
+ 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");
+ "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 {
+ } else {
*increment_val = 0.0;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void HeatTransferModel::computeConductivityOnQuadPoints(const GhostType & ghost_type) {
+void HeatTransferModel::computeConductivityOnQuadPoints(
+ const GhostType & ghost_type) {
const Mesh::ConnectivityTypeList & type_list =
- this->getFEEngine().getMesh().getConnectivityTypeList(ghost_type);
+ 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;
+ 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);
+ 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);
+ // 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);
+ 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);
+ conductivity_on_qpoints(*it, ghost_type)
+ .end(spatial_dimension, spatial_dimension);
- Array<Real>::iterator<Real> T_it = temperature_interpolated.begin();
+ Array<Real>::iterator<Real> T_it = temperature_interpolated.begin();
- for (;C_it != C_end; ++C_it, ++T_it) {
+ 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));
+ 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) {
+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);
+ this->getFEEngine().getMesh().getConnectivityTypeList(ghost_type);
Mesh::ConnectivityTypeList::const_iterator it;
- for(it = type_list.begin(); it != type_list.end(); ++it) {
+ for (it = type_list.begin(); it != type_list.end(); ++it) {
const ElementType & type = *it;
- if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
+ if (Mesh::getSpatialDimension(*it) != spatial_dimension)
+ continue;
Array<Real> & gradient = temperature_gradient(*it, ghost_type);
- this->getFEEngine().gradientOnIntegrationPoints(*temperature,
- gradient,
- 1 ,*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);
+ 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);
+ 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);
+ k_gradt_on_qpoints(type, ghost_type).end(spatial_dimension);
- for (;k_BT_it != k_BT_end; ++k_BT_it, ++BT_it, ++C_it) {
+ 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) {
+void HeatTransferModel::updateResidual(const GhostType & ghost_type,
+ bool compute_conductivity) {
AKANTU_DEBUG_IN();
const Mesh::ConnectivityTypeList & type_list =
- this->getFEEngine().getMesh().getConnectivityTypeList(ghost_type);
+ 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;
+ 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));
+ 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);
+ computeKgradT(ghost_type, compute_conductivity);
Array<Real>::vector_iterator k_BT_it =
- k_gradt_on_qpoints(*it,ghost_type).begin(spatial_dimension);
+ 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);
+ 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);
+ 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);
-
+ 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) {
+ 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().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);
+ 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_nodes = temperature_rate->getSize();
UInt nb_degree_of_freedom = temperature_rate->getNbComponent();
- Real * capacity_val = capacity_lumped->storage();
+ 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();
+ 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;
+ 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();
+ 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)) {
+ 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);
+ 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.;
+ if (*temp < 0.)
+ *temp = 0.;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::explicitCorr() {
AKANTU_DEBUG_IN();
- integrator->integrationSchemeCorrTempRate(time_step,
- *temperature,
- *temperature_rate,
- *blocked_dofs,
- *increment);
+ integrator->integrationSchemeCorrTempRate(
+ time_step, *temperature, *temperature_rate, *blocked_dofs, *increment);
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
-void HeatTransferModel::implicitPred(){
+void HeatTransferModel::implicitPred() {
AKANTU_DEBUG_IN();
- if(method == _implicit_dynamic)
- integrator->integrationSchemePred(time_step,
- *temperature,
- *temperature_rate,
- *blocked_dofs);
+ if (method == _implicit_dynamic)
+ integrator->integrationSchemePred(time_step, *temperature,
+ *temperature_rate, *blocked_dofs);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void HeatTransferModel::implicitCorr(){
+void HeatTransferModel::implicitCorr() {
AKANTU_DEBUG_IN();
- if(method == _implicit_dynamic) {
- integrator->integrationSchemeCorrTemp(time_step,
- *temperature,
- *temperature_rate,
- *blocked_dofs,
- *increment);
+ 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){
+ 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()
-{
+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++)
+ // 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();
+ 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)
+ 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);
+ 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> 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);
+ 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);
+ 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);
+ 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;
+ 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);
+ 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){
+void HeatTransferModel::initFull(const ModelOptions & options) {
Model::initFull(options);
readMaterials();
- const HeatTransferModelOptions & my_options
- = dynamic_cast<const HeatTransferModelOptions &>(options);
+ const HeatTransferModelOptions & my_options =
+ dynamic_cast<const HeatTransferModelOptions &>(options);
method = my_options.analysis_method;
- //initialize the vectors
+ // initialize the vectors
initArrays();
temperature->clear();
temperature_rate->clear();
external_heat_rate->clear();
-
// initialize pbc
- if(pbc_pair.size()!=0)
+ if (pbc_pair.size() != 0)
initPBC();
- if (method == _explicit_lumped_capacity){
+ 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";
+ 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;
+ 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 it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
- for(; it != end; ++it) {
+ 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) {
+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_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){
+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 * 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;
+ 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");
+ 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())
+ if (norm[1] > Math::getTolerance())
error = norm[0] / norm[1];
else
- error = norm[0]; //In case the total displacement is zero!
+ 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)
+ 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());
+ residual->begin(residual->getNbComponent());
Array<Real>::vector_iterator heat_rate_end =
- residual->end(residual->getNbComponent());
-
+ residual->end(residual->getNbComponent());
UInt n = 0;
- for(;heat_rate_it != heat_rate_end; ++heat_rate_it, ++n) {
+ 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;
+ 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;
+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_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) {
+ for (; it != last_type; ++it) {
UInt nb_element = getFEEngine().getMesh().getNbElement(*it, _not_ghost);
- UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(*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_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();
+ if (id == "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) {
+Real HeatTransferModel::getEnergy(const std::string & id,
+ const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
Real energy = 0.;
- if("thermal") energy = getThermalEnergy(type, index);
+ if (id == "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 * HeatTransferModel::createNodalFieldBool(
+ const std::string & field_name, const std::string & group_name,
+ __attribute__((unused)) 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);
+ 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);
-
+dumper::Field * HeatTransferModel::createNodalFieldReal(
+ const std::string & field_name, const std::string & group_name,
+ __attribute__((unused)) 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 * HeatTransferModel::createElementalField(
+ const std::string & field_name, const std::string & group_name,
+ __attribute__((unused)) bool padding_flag,
+ __attribute__((unused)) 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);
+ 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){
-
+dumper::Field * HeatTransferModel::createElementalField(
+ __attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) bool padding_flag,
+ __attribute__((unused)) const ElementKind & element_kind) {
return NULL;
}
/* -------------------------------------------------------------------------- */
-
-dumper::Field * HeatTransferModel::createNodalFieldBool(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag) {
-
+dumper::Field * HeatTransferModel::createNodalFieldBool(
+ __attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) bool padding_flag) {
return NULL;
-
}
-/* -------------------------------------------------------------------------- */
-dumper::Field * HeatTransferModel::createNodalFieldReal(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag) {
-
+/* -------------------------------------------------------------------------- */
+dumper::Field * HeatTransferModel::createNodalFieldReal(
+ __attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) bool padding_flag) {
return NULL;
}
-
-
-#endif
-
+#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..55a99f6e5 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -1,396 +1,388 @@
/**
* @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()) {
+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;
+ if (it->second)
+ delete it->second;
}
for (it = fems_boundary.begin(); it != fems_boundary.end(); ++it) {
- if(it->second) delete it->second;
+ 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::setParser(Parser & parser) { this->parser = &parser; }
/* -------------------------------------------------------------------------- */
-void Model::initFull(const ModelOptions & options) {
+void Model::initFull(__attribute__((unused)) const ModelOptions & options) {
AKANTU_DEBUG_IN();
initModel();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void Model::createSynchronizerRegistry(DataAccessor * data_accessor){
+void Model::createSynchronizerRegistry(DataAccessor * data_accessor) {
synch_registry = new SynchronizerRegistry(*data_accessor);
}
/* -------------------------------------------------------------------------- */
-void Model::setPBC(UInt x, UInt y, UInt z){
+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);
+ 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){
+void Model::setPBC(SurfacePairList & surface_pairs) {
SurfacePairList::iterator s_it;
- for(s_it = surface_pairs.begin(); s_it != surface_pairs.end(); ++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();
+ 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);
+ mesh.getNodes().begin(this->spatial_dimension);
#endif
- while(it != end){
+ 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]) << ")");
+ 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){
+DistributedSynchronizer &
+Model::createParallelSynch(MeshPartition * partition,
+ __attribute__((unused))
+ DataAccessor * data_accessor) {
AKANTU_DEBUG_IN();
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
- StaticCommunicator & comm =
- StaticCommunicator::getStaticCommunicator();
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int prank = comm.whoAmI();
DistributedSynchronizer * synch = NULL;
- if(prank == 0)
- synch =
- DistributedSynchronizer::createDistributedSynchronizerMesh(getFEEngine().getMesh(),
- partition);
+ if (prank == 0)
+ synch = DistributedSynchronizer::createDistributedSynchronizerMesh(
+ getFEEngine().getMesh(), partition);
else
- synch =
- DistributedSynchronizer::createDistributedSynchronizerMesh(getFEEngine().getMesh(),
- NULL);
+ 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);
+ 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 bit = mesh.element_group_begin();
GroupManager::element_group_iterator bend = mesh.element_group_end();
- for(; bit != bend; ++bit) {
+ 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 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);
+ 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);
+ 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);
+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) {
+ dumper::Field * field,
+ DumperIOHelper & dumper) {
#ifdef AKANTU_USE_IOHELPER
- dumper.registerField(field_id,field);
+ dumper.registerField(field_id, field);
#endif
}
-
-
/* -------------------------------------------------------------------------- */
void Model::addDumpField(const std::string & field_id) {
- this->addDumpFieldToDumper(mesh.getDefaultDumperName(),field_id);
+ this->addDumpFieldToDumper(mesh.getDefaultDumperName(), field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldVector(const std::string & field_id) {
- this->addDumpFieldVectorToDumper(mesh.getDefaultDumperName(),field_id);
+ this->addDumpFieldVectorToDumper(mesh.getDefaultDumperName(), field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldTensor(const std::string & field_id) {
- this->addDumpFieldTensorToDumper(mesh.getDefaultDumperName(),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);
+ 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);
+ 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) {
+ const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
- this->addDumpGroupFieldToDumper(group.getDefaultDumperName(),
- field_id,
- group_name,_ek_regular,false);
+ this->addDumpGroupFieldToDumper(group.getDefaultDumperName(), field_id,
+ group_name, _ek_regular, false);
}
/* -------------------------------------------------------------------------- */
void Model::removeDumpGroupField(const std::string & field_id,
- const std::string & group_name) {
+ const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
- this->removeDumpGroupFieldFromDumper(group.getDefaultDumperName(),
- field_id,
+ 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) {
+ 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) {
+ 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) {
+ const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
- this->addDumpGroupFieldVectorToDumper(group.getDefaultDumperName(),
- field_id,
+ 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);
+ 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);
+ 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);
+ 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,
+ 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)
+ 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);
+ DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name, group_name);
+ this->addDumpGroupFieldToDumper(field_id, field, dumper);
}
#endif
}
/* -------------------------------------------------------------------------- */
-void Model::dump() {
- mesh.dump();
-}
+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);
+ const std::string & directory) {
+ mesh.setDirectoryToDumper(dumper_name, directory);
}
/* -------------------------------------------------------------------------- */
-void Model::setTextModeToDumper(){
- mesh.setTextModeToDumper();
-}
+void Model::setTextModeToDumper() { mesh.setTextModeToDumper(); }
/* -------------------------------------------------------------------------- */
-
-
-
__END_AKANTU__
diff --git a/src/model/model.hh b/src/model/model.hh
index 283a95e6a..be209c721 100644
--- a/src/model/model.hh
+++ b/src/model/model.hh
@@ -1,326 +1,334 @@
/**
* @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);
+ 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);
+ DataAccessor * data_accessor);
/// change local equation number so that PBC is assembled properly
- void changeLocalEquationNumberForPBC(std::map<UInt,UInt> & pbc_pair,UInt dimension);
+ 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;
+ virtual void printself(__attribute__((unused)) std::ostream & stream,
+ __attribute__((unused)) int indent = 0) const {};
/// 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);
+ 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);
+ 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);
+ const std::string & group_name);
/// Get the internal dumper of a given group
DumperIOHelper & getGroupDumper(const std::string & group_name);
/* ------------------------------------------------------------------------ */
- /* Accessors */
+ /* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get id of model
AKANTU_GET_MACRO(ID, id, const ID)
/// get the number of surfaces
- AKANTU_GET_MACRO(Mesh, mesh, Mesh&);
+ 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 &)
+ AKANTU_GET_MACRO(SynchronizerRegistry, *synch_registry,
+ SynchronizerRegistry &)
/// synchronize the boundary in case of parallel run
- virtual void synchronizeBoundaries() {};
+ 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);
+ 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;};
+ 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;
+ 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);
+ 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);
+ const std::string & field_id);
virtual void addDumpFieldVectorToDumper(const std::string & dumper_name,
- const std::string & field_id);
+ const std::string & field_id);
virtual void addDumpFieldTensorToDumper(const std::string & dumper_name,
- const std::string & field_id);
+ 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);
-
+ const std::string & basename);
virtual void addDumpGroupField(const std::string & field_id,
- const std::string & group_name);
+ 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);
+ 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);
+ 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);
+ const std::string & group_name);
virtual void removeDumpGroupFieldFromDumper(const std::string & dumper_name,
- const std::string & field_id,
- const std::string & group_name);
+ const std::string & field_id,
+ const std::string & group_name);
virtual void addDumpGroupFieldVector(const std::string & field_id,
- const std::string & group_name);
+ 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;}
-
+ const std::string & field_id,
+ const std::string & group_name);
+
+ virtual dumper::Field *
+ createNodalFieldReal(__attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) bool padding_flag) {
+ return NULL;
+ }
+
+ virtual dumper::Field *
+ createNodalFieldUInt(__attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) bool padding_flag) {
+ return NULL;
+ }
+
+ virtual dumper::Field *
+ createNodalFieldBool(__attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) bool padding_flag) {
+ return NULL;
+ }
+
+ virtual dumper::Field *
+ createElementalField(__attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) bool padding_flag,
+ __attribute__((unused)) const UInt & spatial_dimension,
+ __attribute__((unused)) const ElementKind & kind) {
+ return NULL;
+ }
void setDirectory(const std::string & directory);
void setDirectoryToDumper(const std::string & dumper_name,
- const std::string & directory);
+ 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;
+ 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"
+#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)
-{
+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 5723f1093..6ca4615a5 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 << memory_id;
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 83cb1a028..49710910e 100644
--- a/src/model/solid_mechanics/material.cc
+++ b/src/model/solid_mechanics/material.cc
@@ -1,1566 +1,1675 @@
/**
* @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) {
+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);
-
+ /// 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) {
+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,
+ 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");
+ 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) {
+ if (finite_deformation) {
this->piola_kirchhoff_2.initialize(spatial_dimension * spatial_dimension);
- if(use_previous_stress) this->piola_kirchhoff_2.initializeHistory();
+ 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();
+ 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<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<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();
+ 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();
+ 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){
+ 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) {
+ 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);
+ 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);
+ 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$
+ /// 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");
+ 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");
+ new Array<Real>(0, size_of_shapes_derivatives, "filtered shapesd");
- FEEngine::filterElementalData(mesh, shapes_derivatives, *shapesd_filtered,
- *it, ghost_type, elem_filter);
+ 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);
+ stress_vect.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator B =
- shapesd_filtered->begin(spatial_dimension, nb_nodes_per_element);
+ 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);
+ 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
+ * 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");
+ 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,
+ 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);
+ 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){
+ } 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);
+ 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) {
+ for (; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
- if (elem_filter.getSize() == 0) continue;
+ 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);
+ 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.");
+ AKANTU_DEBUG_ASSERT(finite_deformation, "The Cauchy stress can only be "
+ "computed if you are working in "
+ "finite deformation.");
- //resizeInternalArray(stress);
+ // 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);
+ 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){
+ 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>
+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);
+ this->gradu(el_type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator gradu_end =
- this->gradu(el_type, ghost_type).end(dim, dim);
+ 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);
+ 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);
+ 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;
+ Matrix<Real> & piola = *piola_it;
+ Matrix<Real> & sigma = *stress_it;
- gradUToF<dim > (grad_u, F_tensor);
- this->computeCauchyStressOnQuad<dim >(F_tensor, piola, sigma);
+ 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);
+ // 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);
+ 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) {
+ 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);
+ 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){
+ 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;
- }
+ 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; }
+ 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>
+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);
-
+ 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_element = elem_filter.getSize();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt nb_quadrature_points = fem->getNbIntegrationPoints(type,
- ghost_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);
+ 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");
+ 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");
+ new Array<Real>(0, dim * nb_nodes_per_element, "filtered shapesd");
FEEngine::filterElementalData(fem->getMesh(), shapes_derivatives,
- *shapesd_filtered, type, ghost_type, elem_filter);
-
+ *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");
+ 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);
+ 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 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_it =
+ tangent_stiffness_matrix->begin(tangent_size, tangent_size);
- Array<Real>::matrix_iterator D_end
- = tangent_stiffness_matrix->end (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) {
+ 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);
+ *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");
+ 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,
+ 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>
+template <UInt dim>
void Material::assembleStiffnessMatrixNL(const ElementType & type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
- SparseMatrix & K = const_cast<SparseMatrix &> (model->getStiffnessMatrix());
+ SparseMatrix & K = const_cast<SparseMatrix &>(model->getStiffnessMatrix());
- const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type);
+ 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);
+ // 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);
+ // 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> * 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>::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);
+ 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];
+ 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");
+ 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);
+ 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 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);
+ 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) {
+ 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);
+ 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");
+ 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);
+ 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);
+ fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type,
+ elem_filter);
delete K_e;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
+template <UInt dim>
void Material::assembleStiffnessMatrixL2(const ElementType & type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
- SparseMatrix & K = const_cast<SparseMatrix &> (model->getStiffnessMatrix());
+ SparseMatrix & K = const_cast<SparseMatrix &>(model->getStiffnessMatrix());
- const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type);
+ 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);
+ 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");
+ 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> * 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>::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);
+ 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];
+ 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");
+ 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);
+ 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 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);
+ 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) {
+ 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);
+ // 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);
+ 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");
+ 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);
+ 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);
+ 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){
+template <UInt dim> void Material::assembleResidual(GhostType ghost_type) {
AKANTU_DEBUG_IN();
- Array<Real> & residual = const_cast<Array<Real> &> (model->getResidual());
+ 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);
+ 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;
+ 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");
+ new Array<Real>(0, size_of_shapes_derivatives, "filtered shapesd");
FEEngine::filterElementalData(mesh, shapes_derivatives, *shapesd_filtered,
- *it, ghost_type, elem_filter);
+ *it, ghost_type, elem_filter);
- Array<Real>::matrix_iterator shapes_derivatives_filtered_it = shapesd_filtered->begin(dim,
- nb_nodes_per_element);
+ Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
+ shapesd_filtered->begin(dim, nb_nodes_per_element);
- //Set stress vectors
+ // Set stress vectors
UInt stress_size = getTangentStiffnessVoigtSize(dim);
- //Set matrices B and BNL*
+ // 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> * 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_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 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);
+ 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);
+ 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) {
+ 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);
+ 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);
+ 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");
+ 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);
+ 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);
+ 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; }
+ 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>
+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);
+ 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_element = elem_filter.getSize();
if (nb_element) {
- UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt nb_quadrature_points = fem->getNbIntegrationPoints(type, ghost_type);
-
+ 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);
+ 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");
+ 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");
+ new Array<Real>(0, dim * nb_nodes_per_element, "filtered shapesd");
- FEEngine::filterElementalData(fem->getMesh(), shapes_derivatives, *shapesd_filtered,
- type, ghost_type, elem_filter);
+ 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);
+ Array<Real> filtered_u(nb_element,
+ nb_nodes_per_element * spatial_dimension);
- FEEngine::extractNodalToElementField(fem->getMesh(), disp, filtered_u,
- type, ghost_type, elem_filter);
+ 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);
+ 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);
+ 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);
+ 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) {
+ 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);
+ 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);
+ 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) {
+ for (; it != last_type; ++it) {
computePotentialEnergy(*it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void Material::computePotentialEnergy(ElementType el_type, GhostType ghost_type) {
+void Material::computePotentialEnergy(__attribute__((unused))
+ ElementType el_type,
+ __attribute__((unused))
+ 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) {
+ for (; it != last_type; ++it) {
- epot += fem->integrate(potential_energy(*it, _not_ghost), *it,
- _not_ghost, element_filter(*it, _not_ghost));
+ 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();
+ 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);
+ if (energy_id == "potential")
+ return getPotentialEnergy(type, index);
AKANTU_DEBUG_OUT();
return 0.;
}
/* -------------------------------------------------------------------------- */
-void Material::initElementalFieldInterpolation(const ElementTypeMapArray<Real> & interpolation_points_coordinates) {
+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));
+ 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));
+ 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) {
+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);
-
+ 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;
-
+ 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);
+ 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;
+ 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;
+ 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);
+ 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){
+ 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);
- }
+ 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 {
+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) {
+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 {
+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";
+ 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 << "]");
+ } 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) {
+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";
+ 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 << "]");
+ } 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 {
+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";
+ 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 << "]");
+ } 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) {
+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";
+ 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 << "]");
+ } 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 {
+template <typename T>
+const InternalField<T> & Material::getInternal(__attribute__((unused))
+ const ID & int_id) const {
AKANTU_DEBUG_TO_IMPLEMENT();
return NULL;
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-InternalField<T> & Material::getInternal(const ID & int_id) {
+template <typename T>
+InternalField<T> & Material::getInternal(__attribute__((unused))
+ const ID & int_id) {
AKANTU_DEBUG_TO_IMPLEMENT();
return NULL;
}
/* -------------------------------------------------------------------------- */
-template<>
+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()) {
+ 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) << ")");
+ << ") 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()) {
+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) << ")");
+ << ") does not contain an internal "
+ << int_id << " ("
+ << (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
-template<>
+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()) {
+ 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) << ")");
+ << ") 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()) {
+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) << ")");
+ << ") 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) {
+ 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);
+ 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);
+ 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();
+ Array<Element>::const_iterator<Element> el_end = elements_to_remove.end();
- if(el_begin==el_end)
+ if (el_begin == el_end)
return;
ElementTypeMapArray<UInt> material_local_new_numbering("remove mat filter elem", getID(), getMemoryID());
Element element;
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ 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);
+ 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) {
+ 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);
+ 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);
+ 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;
+ 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) {
+ 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<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<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);
+ 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();
+ 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) {
+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) {
+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(), getMemoryID());
Array<Element>::const_iterator<Element> el_begin = element_list.begin();
- Array<Element>::const_iterator<Element> el_end = element_list.end();
+ 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) {
+ 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);
+ 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()){
+ 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);
+ 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);
+ 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) {
+ 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");
+ 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<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<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);
+ 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) {
+void Material::onBeginningSolveStep(__attribute__((unused))
+ 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) {
+void Material::onEndSolveStep(__attribute__((unused))
+ 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::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);
+ 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) {
+ for (; it != end; ++it) {
this->updateEnergiesAfterDamage(*it, _not_ghost);
}
}
/* -------------------------------------------------------------------------- */
-void Material::onDump(){
- if(this->isFiniteDeformation())
+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);
+ 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) {
+void Material::extrapolateInternal(const ID & id, const Element & element,
+ __attribute__((unused))
+ 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_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);
+ 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 {
+ } 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) {
+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);
+ 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) {
+ 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) {
+ 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..3d310fa49 100644
--- a/src/model/solid_mechanics/material.hh
+++ b/src/model/solid_mechanics/material.hh
@@ -1,633 +1,655 @@
/**
* @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;
+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 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,
+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 = "");
+ 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) {
+ __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) {
+ 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);
+ 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) {
+ 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) { }
+ __attribute__((unused))
+ GhostType ghost_type = _not_ghost) {}
- virtual void updateEnergiesAfterDamage(__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)
+ /// 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) { }
+ __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);
+ 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(); }
+ virtual Real getPushWaveSpeed(__attribute__((unused))
+ 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(); }
+ virtual Real getShearWaveSpeed(__attribute__((unused))
+ 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); }
+ /// 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>
+ template <typename T>
void registerInternal(__attribute__((unused)) InternalField<T> & vect) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
- template<typename T>
+ 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
+ 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,
+ 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);
+ 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);
+ 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);
+ 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>
+ template <UInt dim>
void computeCauchyStress(__attribute__((unused)) ElementType el_type,
- __attribute__((unused)) GhostType ghost_type = _not_ghost);
+ __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,
+ 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>
+ template <UInt dim>
void computeAllStressesFromTangentModuli(const ElementType & type,
GhostType ghost_type);
- template<UInt dim>
- void assembleStiffnessMatrix(const ElementType & type,
- GhostType ghost_type);
+ template <UInt dim>
+ void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type);
/// assembling in finite deformation
- template<UInt dim>
+ template <UInt dim>
void assembleStiffnessMatrixNL(const ElementType & type,
GhostType ghost_type);
- template<UInt dim>
+ 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>
+ /// 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>
+ 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 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>
+ template <UInt dim>
static inline void gradUToEpsilon(const Matrix<Real> & grad_u,
Matrix<Real> & epsilon);
- template<UInt dim>
+ 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;
+ inline IntegrationPoint
+ convertToLocalPoint(const IntegrationPoint & global_point) const;
/// converts local quadrature point to global quadrature point
- inline IntegrationPoint convertToGlobalPoint(const IntegrationPoint & local_point) const;
+ 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>
+ 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>
+ 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 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
+ 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) {};
+ 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 onDamageUpdate();
virtual void onDump();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
- AKANTU_GET_MACRO(Name, name, const std::string &);
+ 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
+ /// 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
+ /// 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_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(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;
+ 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);
+ 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> InternalField<T> & getInternal(const ID & id);
- template<typename T>
+ 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;
+ 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 void setParam(const ID & param, T value);
- template <typename T>
- inline const T & getParam(const ID & param) const;
+ 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);
+ 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)
+ /// 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)
-{
+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 \
- } \
-
+#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 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>; \
+#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..9f55a061f 100644
--- a/src/model/solid_mechanics/material_selector.hh
+++ b/src/model/solid_mechanics/material_selector.hh
@@ -1,146 +1,147 @@
/**
* @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) {
+ virtual UInt operator()(__attribute__((unused)) 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) { }
+ 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);
+ const Array<UInt> & mat_indexes =
+ material_index(element.type, element.ghost_type);
UInt mat = this->fallback_value;
- if(element.element < mat_indexes.getSize())
+ 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>
+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)
- {}
+ 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) {
+ 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>
+template <typename T>
class MeshDataMaterialSelector : public ElementDataMaterialSelector<T> {
public:
- MeshDataMaterialSelector(const std::string & name, const SolidMechanicsModel & model, UInt first_index = 1);
+ 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..85c8c5090 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,94 @@
/**
* @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: Thu Jan 21 2016
*
* @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()) {
+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> CohesiveInternalField<T>::~CohesiveInternalField() {}
-template<typename T>
+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()) {
+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> FacetInternalField<T>::~FacetInternalField() {}
-template<typename T>
+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) {
+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) {
+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..1b6fd6c7f 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) {
+ __attribute__((unused)) 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 9ddf21d73..3900f1823 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,984 +1,716 @@
/**
* @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");
- use_previous_delta_max = true;
+ this->use_previous_delta_max = 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<Real> & res_sliding = residual_sliding(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);
- res_sliding.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];
- res_sliding(old_nb_quad_points + q) = 0.;
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);
+ /// opening_prec is the opening of the previous step in the
+ /// Newton-Raphson loop
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>::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_iterator< Vector<Real> > normal_it =
+ 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>sigma_c_it =
+ Array<Real>::scalar_iterator sigma_c_it =
sigma_c_eff(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>delta_max_it =
+ Array<Real>::scalar_iterator delta_max_it =
delta_max(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>delta_max_prev_it =
+ Array<Real>::scalar_iterator delta_max_prev_it =
delta_max.previous(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>delta_c_it =
+ Array<Real>::scalar_iterator delta_c_it =
delta_c_eff(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>damage_it =
+ 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>::iterator<Real>res_sliding_it =
- residual_sliding(el_type, ghost_type).begin();
-
- Array<Real>::iterator<Real>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>::iterator<bool> reduction_penalty_it =
+ Array<bool>::scalar_iterator reduction_penalty_it =
reduction_penalty(el_type, ghost_type).begin();
- 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);
-
- // Vector<Real> open_prec(spatial_dimension);
- // Vector<Real> open(spatial_dimension);
+ 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,
- ++res_sliding_it, ++res_sliding_prev_it, ++opening_prec_prev_it,
- ++friction_force_it, ++reduction_penalty_it) {
-
- if (!model->isExplicit())
- *delta_max_it = *delta_max_prev_it;
-
- // check if the local displacement increment is too large. If so,
- // reduce arbitrary it in order to prevent problems of
- // instability
-
- Real normal_opening_prec_norm = opening_prec_it->dot(*normal_it);
-
-// open_prec = *opening_prec_it;
-// Real open_prec_norm = open_prec.norm();
-// open = *opening_it;
-// Real open_norm = open.norm();
-// Real delta_open = std::abs(open_norm - open_prec_norm);
-//
-// // if (delta_open > 1.0e-01){
-// // *opening_it = *opening_prec_it + ((*opening_it - *opening_prec_it) / 50.0);
-// // }
-// *opening_prec_it = *opening_it;
-
- /// 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 * beta2_kappa2;
-
- bool penetration = normal_opening_norm < -Math::getTolerance();
- if (contact_after_breaking == false && Math::are_float_equal(*damage_it, 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.
- if (!model->isExplicit() && !recompute)
- if ((normal_opening_prec_norm * normal_opening_norm) < -Math::getTolerance()){
- *reduction_penalty_it = true;
- }
-
- if (penetration) {
- Real current_penalty = 0.;
- if (recompute && *reduction_penalty_it){
- /// the penalty parameter is locally reduced
- current_penalty = penalty / 1000.;
- }
- else
- current_penalty = penalty;
-
- /// use penalty coefficient in case of penetration
- *contact_traction_it = normal_opening;
- *contact_traction_it *= current_penalty;
- *contact_opening_it = normal_opening;
-
- /* ----------------------------------------- */
- /// ADD FRICTION
- if (friction){
- Real damage = std::min(*delta_max_prev_it / *delta_c_it, Real(1.));
- Real mu = mu_max * std::sqrt(damage);
- Real normal_opening_prec_norm = opening_prec_prev_it->dot(*normal_it);
- Vector<Real> normal_opening_prec = (*normal_it);
- normal_opening_prec *= normal_opening_prec_norm;
- Real tau_max = mu * current_penalty * (normal_opening_prec.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);
- }
- /// end add friction
- /* ----------------------------------------- */
-
- /// 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();
- friction_force_it->clear();
- }
-
- delta = std::sqrt(delta);
-
- /// update maximum displacement and damage
- *delta_max_it = std::max(*delta_max_it, delta);
- *damage_it = std::min(*delta_max_it / *delta_c_it, 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_it, 1.))
- traction_it->clear();
- else if (Math::are_float_equal(*damage_it, 0.)) {
- if (penetration)
- traction_it->clear();
- else
- *traction_it = *insertion_stress_it;
- }
- else {
- *traction_it = tangential_opening;
- *traction_it *= beta2_kappa;
- *traction_it += normal_opening;
-
- AKANTU_DEBUG_ASSERT(*delta_max_it != 0.,
- "Division by zero, tolerance might be too low");
-
- *traction_it *= *sigma_c_it / *delta_max_it * (1. - *damage_it);
- }
-
- if (friction)
- *traction_it += *friction_force_it;
-
+ ++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);
}
- delete [] memory_space;
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.
+ /**
+ * 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.
+ /**
+ * 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>::iterator<Real>delta_max_it =
+ Array<Real>::scalar_iterator delta_max_it =
delta_max(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>delta_max_end =
+ Array<Real>::scalar_iterator delta_max_end =
delta_max(el_type, ghost_type).end();
- Array<Real>::iterator<Real>delta_max_prev_it =
+ Array<Real>::scalar_iterator delta_max_prev_it =
delta_max.previous(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>delta_c_it =
+ 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>::vector_iterator opening_prec_it =
+ opening_prec(el_type, ghost_type).begin(spatial_dimension);
- Array<Real>::iterator<Real>res_sliding_it =
- residual_sliding(el_type, ghost_type).begin();
-
- Array<Real>::iterator<Real>res_sliding_prev_it =
- residual_sliding.previous(el_type, ghost_type).begin();
+ Array<Real>::vector_iterator opening_prec_prev_it =
+ opening_prec.previous(el_type, ghost_type).begin(spatial_dimension);
/// 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) {
+ ++opening_prec_it, ++opening_prec_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;
+ *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.
+ /**
+ * 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>::iterator<bool> reduction_penalty_it =
+ Array<bool>::scalar_iterator reduction_penalty_it =
reduction_penalty(el_type, ghost_type).begin();
- Array<bool>::iterator<bool> reduction_penalty_end =
+ 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);
- Array<Real>::vector_iterator opening_prec_it =
- opening_prec.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 =
+ Array<Real>::scalar_iterator delta_max_it =
delta_max.previous(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>sigma_c_it =
+ Array<Real>::scalar_iterator sigma_c_it =
sigma_c_eff(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>delta_c_it =
+ Array<Real>::scalar_iterator delta_c_it =
delta_c_eff(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>damage_it =
+ Array<Real>::scalar_iterator damage_it =
damage(el_type, ghost_type).begin();
- Array<Real>::iterator< Vector<Real> > contact_opening_it =
+ Array<Real>::vector_iterator contact_opening_it =
contact_opening(el_type, ghost_type).begin(spatial_dimension);
- Array<Real>::iterator<Real>res_sliding_prev_it =
- residual_sliding.previous(el_type, ghost_type).begin();
-
- Array<bool>::iterator<bool> reduction_penalty_it =
+ 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, ++opening_prec_it,
+ ++tangent_it, ++normal_it, ++opening_it,
++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
- ++contact_opening_it, ++res_sliding_prev_it, ++reduction_penalty_it) {
-
- /// 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_it += *contact_opening_it;
-
- /// 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();
- bool penetration = normal_opening_norm < -Math::getTolerance();
- if (contact_after_breaking == false && Math::are_float_equal(*damage_it, 1.))
- penetration = false;
-
- Real derivative = 0; // derivative = d(t/delta)/ddelta
- Real t = 0;
-
- Real delta = tangential_opening_norm * tangential_opening_norm * beta2_kappa2;
-
- Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
- n_outer_n.outerProduct(*normal_it, *normal_it);
-
- if (penetration){
- Real current_penalty = 0.;
- if (recompute && *reduction_penalty_it)
- current_penalty = penalty / 1000.;
- else
- current_penalty = penalty;
-
- /// stiffness in compression given by the penalty parameter
- *tangent_it += n_outer_n;
- *tangent_it *= current_penalty;
-
- /* ------------------------------------- */
- /// ADD FRICTION
- if (friction){
- 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_prec_norm = opening_prec_it->dot(*normal_it);
- Vector<Real> normal_opening_prec = (*normal_it);
- normal_opening_prec *= normal_opening_prec_norm;
- Real tau_max = mu * current_penalty * normal_opening_prec.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> nn(n_outer_n);
- I -= nn;
- *tangent_it += I * friction_penalty;
- }
- }
- /// end add friction
- /* ------------------------------------- */
-
- *opening_it = tangential_opening;
- normal_opening_norm = opening_it->dot(*normal_it);
- normal_opening = (*normal_it);
- 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_it)/1000.;
-
- if (delta >= *delta_max_it){
- if (delta <= *delta_c_it){
- derivative = -*sigma_c_it/(delta * delta);
- t = *sigma_c_it * (1 - delta / *delta_c_it);
- } else {
- derivative = 0.;
- t = 0.;
- }
- } else if (delta < *delta_max_it){
- Real tmax = *sigma_c_it * (1 - *delta_max_it / *delta_c_it);
- t = tmax / *delta_max_it * delta;
- }
-
-
- /// computation of the derivative of the constitutive law (dT/ddelta)
- Matrix<Real> I(spatial_dimension, spatial_dimension);
- I.eye(beta2_kappa);
- Matrix<Real> nn(n_outer_n);
- nn *= (1 - beta2_kappa);
- nn += I;
- nn *= t/delta;
- Vector<Real> t_tilde(normal_opening);
- t_tilde *= (1 - beta2_kappa2);
- Vector<Real> mm(*opening_it);
- mm *= beta2_kappa2;
- t_tilde += mm;
- Vector<Real> t_hat(normal_opening);
- t_hat += beta2_kappa * tangential_opening;
- Matrix<Real> prov(spatial_dimension, spatial_dimension);
- prov.outerProduct(t_hat, t_tilde);
- prov *= derivative/delta;
- prov += nn;
- Matrix<Real> tmp(spatial_dimension, spatial_dimension);
- for (UInt i = 0; i < spatial_dimension; ++i) {
- for (UInt j = 0; j < spatial_dimension; ++j) {
- tmp(j,i) = prov(i,j);
- }
- }
- *tangent_it += tmp;
-
- /// 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;
-// }
-// }
-// }
-// }
-// }
+ ++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 fbe80397b..e9bfe93e2 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,208 +1,216 @@
/**
* @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)
- void checkDeltaMax(GhostType ghost_type = _not_ghost);
+ 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
- void computeTangentTraction(const ElementType & el_type,
- Array<Real> & tangent_matrix,
- const Array<Real> & normal,
- GhostType ghost_type);
+ 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
+ /**
+ * 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 */
/* -------------------------------------------------------------------------- */
-#include "material_cohesive_linear_inline_impl.cc"
-
__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 7634f8b39..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;
- Array<Real> * delta_dot_prec_array;
+ 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
new file mode 100644
index 000000000..68853b75c
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.cc
@@ -0,0 +1,398 @@
+/**
+ * @file material_cohesive_linear_friction.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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(__attribute__((unused)) 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);
+
+ /// opening_prec is the opening at the end of the previous step in
+ /// the Newton-Raphson loop
+ Array<Real>::vector_iterator opening_prec_it =
+ this->opening_prec(el_type, ghost_type).begin(spatial_dimension);
+
+ /// opening_prec_prev is the opening (opening + penetration) refer to
+ /// the convergence of the previous incremental step
+ Array<Real>::vector_iterator opening_prec_prev_it =
+ this->opening_prec.previous(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_prec_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) {
+
+ /// the friction coefficient mu increases with the damage. It
+ /// equals the maximum value when damage = 1.
+ Real damage = std::min(*delta_max_prev_it / *delta_c_it, Real(1.));
+ Real mu = mu_max * damage;
+
+ /// the definition of tau_max refers to the opening
+ /// (penetration) of the previous incremental step
+ Real normal_opening_prev_norm = opening_prec_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) < 0.0)
+ 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,
+ __attribute__((unused)) 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_prec_prev_it =
+ this->opening_prec.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_prec_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.));
+ Real mu = mu_max * damage;
+
+ Real normal_opening_prev_norm = opening_prec_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_bilinear.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
similarity index 52%
copy from src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh
copy to src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
index 86b840e75..841913221 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_linear_friction.hh
@@ -1,112 +1,112 @@
/**
- * @file material_cohesive_bilinear.hh
+ * @file material_cohesive_linear_friction.hh
*
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @author Mauro Corrado <mauro.corrado@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 Bilinear cohesive constitutive law
+ * @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_BILINEAR_HH__
-#define __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__
+/* -------------------------------------------------------------------------- */
+#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
+#define __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/**
- * Cohesive material bilinear
+ * Cohesive material linear with friction force
*
* 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
+ * - mu : friction coefficient
+ * - penalty_for_friction : Penalty parameter for the friction behavior
*/
template<UInt spatial_dimension>
-class MaterialCohesiveBilinear : public MaterialCohesiveLinear<spatial_dimension> {
+class MaterialCohesiveLinearFriction : public MaterialCohesiveLinear<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
+ typedef MaterialCohesiveLinear<spatial_dimension> MaterialParent;
public:
- MaterialCohesiveBilinear(SolidMechanicsModel & model, const ID & id = "");
+ MaterialCohesiveLinearFriction(SolidMechanicsModel & model, const ID & id = "");
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
- /// initialize the material computed parameter
+ /// initialize the material parameters
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);
+ virtual 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);
+ /// 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;
- /// elastic limit displacement
- Real delta_0;
-
-};
-
-
-/* -------------------------------------------------------------------------- */
-/* inline functions */
-/* -------------------------------------------------------------------------- */
+ /// penalty parameter for the friction law
+ Real friction_penalty;
-//#include "material_cohesive_elastic_inline_impl.cc"
+ /// history parameter for the friction law
+ CohesiveInternalField<Real> residual_sliding;
+ /// friction force
+ CohesiveInternalField<Real> friction_force;
+};
__END_AKANTU__
-#endif /* __AKANTU_MATERIAL_COHESIVE_BILINEAR_HH__ */
+#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 207729906..a6f47db12 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,58 +1,313 @@
/**
* @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,
+ __attribute__((unused)) 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.
+ */
+
+ 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 *= this->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 b8193bb85..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,622 +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 61c489626..037ed6434 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
@@ -1,264 +1,266 @@
/**
* @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;
+class SolidMechanicsModelCohesive;
}
__BEGIN_AKANTU__
class MaterialCohesive : public Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef FEEngineTemplate<IntegratorGauss,
- ShapeLagrange, _ek_cohesive> MyFEEngineCohesiveType;
-public:
+ typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>
+ MyFEEngineCohesiveType;
- MaterialCohesive(SolidMechanicsModel& model, const ID & id = "");
+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) {
+ virtual void checkInsertion(__attribute__((unused)) 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) {
+ virtual void checkDeltaMax(__attribute__((unused))
+ 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) {
+ virtual void resetVariables(__attribute__((unused))
+ 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) { };
+ __attribute__((unused))
+ Array<Real> & result){};
/// compute the stresses
- virtual void computeAllStresses(__attribute__((unused)) GhostType ghost_type = _not_ghost) { };
+ 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) {
+ 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);
+ 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,
+ 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,
+ 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> &);
+ 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)
+ /// 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 62286a70e..00bfb1433 100644
--- a/src/model/solid_mechanics/materials/material_cohesive_includes.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive_includes.hh
@@ -1,44 +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..496c58e4f 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,148 @@
/**
* @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
+ * @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) {
+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");
-
+ 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>
+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) {
+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 * 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);
+ 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) {
+template <UInt spatial_dimension>
+void MaterialMazarsNonLocal<spatial_dimension>::computeNonLocalStresses(
+ __attribute__((unused)) 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);
+ // 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) {
+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();
+ 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();
+ 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() {
-
-}
+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..d2ec98823 100644
--- a/src/model/solid_mechanics/materials/material_elastic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic.cc
@@ -1,248 +1,251 @@
/**
* @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) {
+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>
+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) {
+ __attribute__((unused)) 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>::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() {
+template <UInt dim> void MaterialElastic<dim>::initMaterial() {
AKANTU_DEBUG_IN();
Parent::initMaterial();
- if (dim == 1) this->nu = 0.;
+ if (dim == 1)
+ this->nu = 0.;
this->updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-void MaterialElastic<dim>::updateInternalParameters() {
+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->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;
+ this->kpa = this->lambda + 2. / 3. * this->mu;
}
/* -------------------------------------------------------------------------- */
-template<>
-void MaterialElastic<2>::updateInternalParameters() {
+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));
+ 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));
+ if (this->plane_stress)
+ this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - this->nu));
- this->kpa = this->lambda + 2./3. * this->mu;
+ this->kpa = this->lambda + 2. / 3. * this->mu;
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialElastic<spatial_dimension>::computeStress(ElementType el_type, GhostType ghost_type) {
+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();
+ 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) {
+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>::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>
+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) {
+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);
+ 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 (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) {
+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);
+ this->gradu(type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator gradu_end =
- this->gradu(type).begin(spatial_dimension,
- spatial_dimension);
+ this->gradu(type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator stress_it =
- this->stress(type).begin(spatial_dimension,
- spatial_dimension);
+ this->stress(type).begin(spatial_dimension, spatial_dimension);
if (this->finite_deformation)
- stress_it = this->piola_kirchhoff_2(type).begin(spatial_dimension,
- spatial_dimension);
+ stress_it = this->piola_kirchhoff_2(type)
+ .begin(spatial_dimension, spatial_dimension);
- UInt nb_quadrature_points = this->model->getFEEngine().getNbIntegrationPoints(type);
+ 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;
+ 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) {
+ 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 6e3e1c91a..ecd5157a6 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
@@ -1,349 +1,349 @@
/**
* @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);
}
}
}
}
#ifndef AKANTU_NDEBUG
Matrix<Real> eig_vectors_before(Dim*Dim, Dim * Dim);
Matrix<Real> eig_vectors_after(Dim*Dim, Dim * Dim);
Vector<Real> eig_val_before(Dim * Dim);
Vector<Real> eig_val_after(Dim*Dim);
Cprime.eig(eig_val_before, eig_vectors_before);
#endif
// 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);
}
}
#ifndef AKANTU_NDEBUG
Cfull.eig(eig_val_after, eig_vectors_after);
AKANTU_DEBUG_ASSERT(eig_val_before.equal(eig_val_after), "The eigenvalues have changed during the rotation");
Vector<Real> eigen_vector(Dim * Dim);
for(UInt i = 0; i < Dim * Dim; ++i) {
eigen_vector = eig_vectors_before(i);
AKANTU_DEBUG_ASSERT(eigen_vector.equal(eig_vectors_after(i)), "The eigenvectors have changed during the rotation");
}
#endif
}
/* -------------------------------------------------------------------------- */
template<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 588584024..06f8561ec 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
@@ -1,121 +1,122 @@
/**
* @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;
AKANTU_GET_MACRO(VoigtStiffness, C, Matrix<Real>);
/* ------------------------------------------------------------------------ */
/* 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 772c80839..5a1158eda 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..a55a8e331 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,292 @@
/**
* @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
+ * @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) {
+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->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>
+template <UInt spatial_dimension>
void MaterialNeohookean<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
PlaneStressToolbox<spatial_dimension>::initMaterial();
- if (spatial_dimension == 1) nu = 0.;
+ if (spatial_dimension == 1)
+ nu = 0.;
this->updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<> void MaterialNeohookean<2>::initMaterial() {
+template <> void MaterialNeohookean<2>::initMaterial() {
AKANTU_DEBUG_IN();
PlaneStressToolbox<2>::initMaterial();
this->updateInternalParameters();
- if(this->plane_stress) this->third_axis_deformation.setDefaultValue(1.);
+ if (this->plane_stress)
+ this->third_axis_deformation.setDefaultValue(1.);
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+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) {
+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) {
+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);
+ this->gradu(el_type, ghost_type).begin(2, 2);
Array<Real>::matrix_iterator gradu_end =
- this->gradu(el_type, ghost_type).end(2, 2);
+ 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);
+ 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);
+ 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();
+ 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;
+ Matrix<Real> & piola = *piola_it;
+ Matrix<Real> & sigma = *stress_it;
- gradUToF<2 > (grad_u, F_tensor);
- computeCauchyStressOnQuad<2 >(F_tensor, piola, sigma, *c33_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) {
+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) {
+template <>
+void MaterialNeohookean<2>::computeStress(ElementType el_type,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
- if(this->plane_stress){
+ 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();
+ 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{
+ } 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) {
+template <UInt dim>
+void MaterialNeohookean<dim>::computeThirdAxisDeformation(
+ __attribute__((unused)) ElementType el_type,
+ __attribute__((unused)) GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<>
-void MaterialNeohookean<2>::computeThirdAxisDeformation(ElementType el_type, GhostType ghost_type) {
+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!!");
+ 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();
+ 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) {
+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();
+ 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) {
+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) {
+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){
+ 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();
+ 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{
+ } 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 {
+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 {
+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..feae8f7a9 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){
-
-
-}
+template <UInt dim>
+inline void MaterialNeohookean<dim>::computeDeltaStressOnQuad(
+ __attribute__((unused)) const Matrix<Real> & grad_u,
+ __attribute__((unused)) const Matrix<Real> & grad_delta_u,
+ __attribute__((unused)) Matrix<Real> & delta_S) {}
//! computes the second piola kirchhoff stress, called S
-template<UInt dim>
+template <UInt dim>
inline void MaterialNeohookean<dim>::computeStressOnQuad(Matrix<Real> & grad_u,
Matrix<Real> & S,
const Real & C33) {
- //Neo hookean book
+ // Neo hookean book
Matrix<Real> F(dim, dim);
- Matrix<Real> C(dim, dim);//Right green
- Matrix<Real> Cminus(dim, dim);//Right green
+ Matrix<Real> C(dim, dim); // Right green
+ Matrix<Real> Cminus(dim, dim); // Right green
- this->template gradUToF<dim > (grad_u, F);
+ 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;
+ 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);
+ 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) {}
+ 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)))) +
+ 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!!!");
+ "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 & 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
+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
+ Matrix<Real> C(dim, dim); // Right green
- this->template gradUToF<dim > (grad_u, F);
+ 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);
+ 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) {
+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})
+ /// \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) {
+ const Matrix<Real> & grad_u, const Matrix<Real> & S, Matrix<Real> & P) {
Matrix<Real> F(dim, dim);
- Matrix<Real> C(dim, dim);//Right green
+ Matrix<Real> C(dim, dim); // Right green
- this->template gradUToF<dim > (grad_u, F);
+ this->template gradUToF<dim>(grad_u, F);
- // first Piola-Kirchhoff is computed as the product of the deformation gracient
+ // first Piola-Kirchhoff is computed as the product of the deformation
+ // gracient
// tensor and the second Piola-Kirchhoff stress tensor
- P = F*S;
+ 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){
+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
+ Matrix<Real> C(dim, dim); // Right green
- this->template gradUToF<dim > (grad_u, F);
+ this->template gradUToF<dim>(grad_u, F);
this->rightCauchy(F, C);
Real J = F.det();
-// std::cout<<"det(F) -> "<<J<<std::endl;
+ // std::cout<<"det(F) -> "<<J<<std::endl;
- epot=0.5*lambda*pow(log(J),2.)+ mu * (-log(J)+0.5*(C.trace()-dim));
+ 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) {
+template <UInt dim>
+inline void MaterialNeohookean<dim>::computeTangentModuliOnQuad(
+ Matrix<Real> & tangent, Matrix<Real> & grad_u, const Real & C33) {
- //Neo hookean book
+ // 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->template gradUToF<dim>(grad_u, F);
this->rightCauchy(F, C);
Real J = F.det() * sqrt(C33);
-// std::cout<<"det(F) -> "<<J<<std::endl;
+ // 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
+ // 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));
-
+ (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..22833e4d8 100644
--- a/src/model/solid_mechanics/materials/material_non_local.cc
+++ b/src/model/solid_mechanics/materials/material_non_local.cc
@@ -1,152 +1,172 @@
/**
* @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>
+template <UInt DIM>
MaterialNonLocal<DIM>::MaterialNonLocal(SolidMechanicsModel & model,
- const ID & id) :
- Material(model, id) {
+ 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>
+MaterialNonLocal<spatial_dimension>::~MaterialNonLocal() {}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+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) {
+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);
+ 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) {
+ 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_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);
-
+ 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;
+ 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) {
+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) {
+ 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) {
+ 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> & 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);
+ 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);
+ 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);
+ 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];
- }
+ 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) {
+template <UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::updateResidual(__attribute__((unused))
+ GhostType ghost_type) {
AKANTU_EXCEPTION("this method has not been implemented");
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
+template <UInt spatial_dimension>
void MaterialNonLocal<spatial_dimension>::registerNeighborhood() {
- this->model->getNonLocalManager().registerNeighborhood(this->name, this->name);
+ 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..e7a9db227 100644
--- a/src/model/solid_mechanics/materials/material_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_non_local.hh
@@ -1,100 +1,98 @@
/**
* @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.
+ * @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 {
+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);
+ 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) {
+ virtual inline void onElementsAdded(__attribute__((unused))
+ const Array<Element> & element_list,
+ __attribute__((unused))
+ 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..06fe1da02 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 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 Ramin Aghababaei <ramin.aghababaei@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..2870135cd 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,313 @@
/**
* @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;
+/// 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;
+ 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
+ // Compute trial stress, sigma_tr
Matrix<Real> sigma_tr(dim, dim);
- MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr, delta_sigma_th);
+ 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);
+ 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);
+ 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);
+ // 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
+ // 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;
+ 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);
+ 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;
-
+/// 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
+
+ // Compute trial stress, sigma_tr
Matrix<Real> sigma_tr(dim, dim);
- MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr, delta_sigma_th);
+ 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);
+ 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(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);
-
+ 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
+ // 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)
+ // 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;
+ // //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);
+ // 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;
+
+ // 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;
-
+ 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);
+ 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
+ // 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);
+
+ // /// 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;
+ 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.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);
+
+ 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 {
+template <UInt dim>
+inline void MaterialLinearIsotropicHardening<dim>::computeTangentModuliOnQuad(
+ Matrix<Real> & tangent, __attribute__((unused)) const Matrix<Real> & grad_u,
+ __attribute__((unused)) const Matrix<Real> & previous_grad_u,
+ __attribute__((unused)) const Matrix<Real> & sigma_tensor,
+ __attribute__((unused)) const Matrix<Real> & previous_sigma_tensor,
+ __attribute__((unused)) 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);
+ // 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
- //}
+ // 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..1150170f1 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,148 @@
/**
* @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/>.
+ *
*/
/* -------------------------------------------------------------------------- */
#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){
+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");
+
+ 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() );
+ 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");
+ 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);
+ 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());
+ 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);
+ 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){
+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){
+ for (auto i : internal_iterators) {
inputs.push_back(*i);
}
- this->callFunctor<void>("computeStress",grad_u,sigma,inputs);
-
+ 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){
+ Array<Real> & tangent_matrix,
+ GhostType ghost_type) {
- this->callFunctor<void>("computeTangentModuli",el_type,tangent_matrix,ghost_type);
+ this->callFunctor<void>("computeTangentModuli", el_type, tangent_matrix,
+ ghost_type);
}
/* -------------------------------------------------------------------------- */
-
-Real MaterialPython::getPushWaveSpeed(const Element & element) const{
+Real MaterialPython::getPushWaveSpeed(__attribute__((unused))
+ 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..852158597 100644
--- a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
+++ b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
@@ -1,98 +1,101 @@
/**
* @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>
+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) {}
+ 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){
+ 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();
+ virtual void computeCauchyStressPlaneStress(__attribute__((unused))
+ ElementType el_type,
+ __attribute__((unused))
+ 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_ERROR("The function \"computeCauchyStressPlaneStress\" can "
+ "only be used in 2D Plane stress problems, which means "
+ "that you made a mistake somewhere!! ");
- AKANTU_DEBUG_OUT();
+ 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) {} \
+#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..6fc33053b 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,174 @@
/**
* @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>
+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 = "");
+ 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);
+ 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");
+ 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){
+ 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) {
+ virtual void computeStress(ElementType el_type, GhostType ghost_type) {
ParentMaterial::computeStress(el_type, ghost_type);
- if(this->plane_stress) computeThirdAxisDeformation(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) {
- }
+ 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){
+ virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost) {
AKANTU_DEBUG_IN();
- if(this->plane_stress){
+ if (this->plane_stress) {
- AKANTU_DEBUG_ASSERT(this->finite_deformation,"The Cauchy stress can only be computed if you are working in finite deformation.");
+ AKANTU_DEBUG_ASSERT(this->finite_deformation,
+ "The Cauchy stress can only be computed if you are "
+ "working in finite deformation.");
- //resizeInternalArray(stress);
+ // 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);
+ 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)
+ for (; it != last_type; ++it)
this->computeCauchyStressPlaneStress(*it, ghost_type);
- }
- else
+ } else
ParentMaterial::computeAllCauchyStresses(ghost_type);
- AKANTU_DEBUG_OUT();
-
+ AKANTU_DEBUG_OUT();
}
- virtual void computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type = _not_ghost){};
+ virtual void
+ computeCauchyStressPlaneStress(__attribute__((unused)) ElementType el_type,
+ __attribute__((unused))
+ 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) {
+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)
+ /// @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) {
+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");
+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..d1fe4c526 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) {
+void StressBasedWeightFunction::updatePrincipalStress(__attribute__((unused)) 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..2990dd1d4 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,191 @@
/**
* @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);
-// }
+inline Real StressBasedWeightFunction::computeRhoSquare(
+ __attribute__((unused)) Real r, __attribute__((unused)) Vector<Real> & eigs,
+ __attribute__((unused)) Matrix<Real> & eigenvects,
+ __attribute__((unused)) 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) {
+inline Real StressBasedWeightFunction::
+operator()(__attribute__((unused)) Real r,
+ __attribute__((unused)) const IntegrationPoint & q1,
+ __attribute__((unused)) 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];
+ // 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 6290f2de5..98df390ad 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model.cc
@@ -1,1836 +1,1922 @@
/**
* @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: Tue Jan 19 2016
*
* @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"
+#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"
+#include "non_local_manager.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
-const SolidMechanicsModelOptions default_solid_mechanics_model_options(_explicit_lumped_mass, false);
+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, memory_id),
material_local_numbering("material local numbering", id, memory_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);
+ registerFEEngineObject<MyFEEngineType>("SolidMechanicsFEEngine", mesh,
+ spatial_dimension);
this->displacement = NULL;
- this->mass = NULL;
- this->velocity = NULL;
+ this->mass = NULL;
+ this->velocity = NULL;
this->acceleration = NULL;
- this->force = NULL;
- this->residual = NULL;
+ this->force = NULL;
+ this->residual = NULL;
this->blocked_dofs = NULL;
- this->increment = 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) {
+ 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)
+ if (stiffness_matrix && stiffness_matrix != jacobian_matrix)
delete stiffness_matrix;
delete jacobian_matrix;
delete synch_parallel;
- if(is_default_material_selector) {
+ if (is_default_material_selector) {
delete material_selector;
material_selector = NULL;
}
+ flatten_internal_map::iterator fl_it = this->registered_internals.begin();
+ flatten_internal_map::iterator fl_end = this->registered_internals.end();
+ for (; fl_it != fl_end; ++fl_it) {
+ delete fl_it->second;
+ }
+
#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);
+ 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)
+ if (this->pbc_pair.size() != 0)
this->initPBC();
// initialize the time integration schemes
- switch(this->method) {
+ 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
std::stringstream nl_manager_name;
nl_manager_name << "NLManager" << this->id;
this->non_local_manager = new NonLocalManager(*this, nl_manager_name.str(), this->memory_id);
#endif
// initialize the materials
- if(this->parser->getLastParsedFile() != "") {
+ if (this->parser->getLastParsedFile() != "") {
this->instantiateMaterials();
}
- if(!smm_options.no_init_materials) {
+ if (!smm_options.no_init_materials) {
this->initMaterials();
}
- if(this->increment_flag)
+ 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) {
+ DataAccessor * data_accessor) {
AKANTU_DEBUG_IN();
- if (data_accessor == NULL) data_accessor = this;
- synch_parallel = &createParallelSynch(partition,data_accessor);
+ 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())
+ // in case of switch from implicit to explicit
+ if (!this->isExplicit())
method = analysis_method;
- if (integrator) delete integrator;
+ 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()));
+ 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) {
+ 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.));
+ 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_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) {
+ 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
+ // 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;
+ while (it != end) {
+ for (UInt i = 0; i < dim; ++i)
+ (*blocked_dofs)((*it).first, i) = true;
++it;
}
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModel::registerPBCSynchronizer(){
+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();
+ 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) {
+ 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));
+ 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()
-{
-
-}
-
+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();
+ 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) {
+ 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) {
+ 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) {
+ 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) {
+ if (method != _static) {
// f -= Ma
- if(mass_matrix) {
+ 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();
+ 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++;
+ 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) {
+ 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) {
+ 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);
+ 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) {
+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);
+ 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);
+ 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 ?");
+ AKANTU_DEBUG_ASSERT(integrator, "itegrator should have been allocated: "
+ << "have called initExplicit ? "
+ << "or initImplicit ?");
- integrator->integrationSchemePred(time_step,
- *displacement,
- *velocity,
- *acceleration,
- *blocked_dofs);
+ integrator->integrationSchemePred(time_step, *displacement, *velocity,
+ *acceleration, *blocked_dofs);
- if(increment_flag) {
+ if (increment_flag) {
Real * inc_val = increment->storage();
Real * dis_val = displacement->storage();
- UInt nb_degree_of_freedom = displacement->getSize() * displacement->getNbComponent();
+ 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);
+ integrator->integrationSchemeCorrAccel(time_step, *displacement, *velocity,
+ *acceleration, *blocked_dofs,
+ *increment_acceleration);
- if(previous_displacement) previous_displacement->copy(*displacement);
+ if (previous_displacement)
+ previous_displacement->copy(*displacement);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::solveStep() {
AKANTU_DEBUG_IN();
- EventManager::sendEvent(SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
+ EventManager::sendEvent(
+ SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
this->explicitPred();
this->updateResidual();
this->updateAcceleration();
this->explicitCorr();
- EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
+ 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
+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";
+ 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);
+ 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 = 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";
+ 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 = 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
+ 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";
+ std::stringstream sstr_solv;
+ sstr_solv << id << ":solver";
#ifdef AKANTU_USE_PETSC
solver = new SolverPETSc(*jacobian_matrix, sstr_solv.str(), memory_id);
#elif defined(AKANTU_USE_MUMPS)
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str(), memory_id);
dof_synchronizer->initScatterGatherCommunicationScheme();
#else
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
-#endif //AKANTU_USE_MUMPS
+#endif // AKANTU_USE_MUMPS
- if(solver)
+ if (solver)
solver->initialize(options);
-#endif //AKANTU_HAS_SOLVER
+#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_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";
+ std::stringstream sstr_solv;
+ sstr_solv << id << ":solver";
delete solver;
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
- if(solver)
+ 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) {
+void SolidMechanicsModel::initImplicit(bool dynamic,
+ SolverOptions & solver_options) {
AKANTU_DEBUG_IN();
method = dynamic ? _implicit_dynamic : _static;
- if (!increment) setIncrementFlagOn();
+ if (!increment)
+ setIncrementFlagOn();
initSolver(solver_options);
- if(method == _implicit_dynamic) {
- if(integrator) delete integrator;
+ 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);
+ 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";
+ 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
+#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) {
+ 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);
+ 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,
StaticCommunicator & comm){
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 * 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;
+ 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++;
}
}
comm.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");
+ 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())
+ if (norm[1] > Math::getTolerance())
error = norm[0] / norm[1];
else
- error = norm[0]; //In case the total displacement is zero!
+ 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, StaticCommunicator & comm) {
+
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) {
+ 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++;
+ if (!(*blocked_dofs_val)) {
+ norm += *residual_val * *residual_val;
+ }
+ blocked_dofs_val++;
+ residual_val++;
}
} else {
blocked_dofs_val += spatial_dimension;
residual_val += spatial_dimension;
}
}
comm.allReduce(&norm, 1, _so_sum);
norm = sqrt(norm);
- AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
+ 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,
StaticCommunicator & comm) {
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) {
+ 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++;
+ 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;
}
}
comm.allReduce(&norm, 1, _so_sum);
norm = sqrt(norm);
- AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
+ AKANTU_DEBUG_ASSERT(!Math::isnan(norm),
+ "Something goes wrong in the solve phase");
AKANTU_DEBUG_OUT();
return (norm < tolerance);
}
/* -------------------------------------------------------------------------- */
-bool SolidMechanicsModel::testConvergenceResidual(Real tolerance){
+bool SolidMechanicsModel::testConvergenceResidual(Real tolerance) {
AKANTU_DEBUG_IN();
- Real error=0;
+ Real error = 0;
bool res = this->testConvergence<_scc_residual>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
-bool SolidMechanicsModel::testConvergenceResidual(Real tolerance, Real & error){
+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){
+bool SolidMechanicsModel::testConvergenceIncrement(Real tolerance) {
AKANTU_DEBUG_IN();
- Real error=0;
+ Real error = 0;
bool res = this->testConvergence<_scc_increment>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
-bool SolidMechanicsModel::testConvergenceIncrement(Real tolerance, Real & error){
+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);
+ 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);
+ 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){
+ 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?");
+ 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)
+ 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?");
+ 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?");
+ 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?");
+ 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) {
+ if (!increment) {
UInt nb_nodes = mesh.getNbNodes();
- std::stringstream sstr_inc; sstr_inc << id << ":increment";
+ 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) {
+ 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);
+ 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<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> 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);
+ X.begin(spatial_dimension, nb_nodes_per_element);
- for (UInt el = 0; el < nb_element; ++el, ++X_el, ++mat_indexes, ++mat_loc_num) {
+ 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_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 * 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;
+ 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) {
+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);
+ 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);
+ 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);
+ return .5 * getFEEngine().integrate(rho_v2, type, index);
}
-
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getExternalWork() {
AKANTU_DEBUG_IN();
Real * incr_or_velo = NULL;
- if(this->method == _static){
+ if (this->method == _static) {
incr_or_velo = this->increment->storage();
- }
- else
- incr_or_velo = this->velocity->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;
+ 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)
+ 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"){
+ } 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) {
+ 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) {
+ 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_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);
+ 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) {
+ 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) {
+ 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);
+ 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);
+ 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> it = element_list.begin();
Array<Element>::const_iterator<Element> end = element_list.end();
ElementTypeMapArray<UInt> filter("new_element_filter", this->getID(), this->getMemoryID());
for (UInt el = 0; it != end; ++it, ++el) {
const Element & elem = *it;
- if(!filter.exists(elem.type, elem.ghost_type))
+ 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) {
+ for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
(*mat_it)->onElementsAdded(element_list, event);
}
- if(method == _explicit_lumped_mass) this->assembleMassLumped();
+ 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) {
+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) {
+ 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) {
+ __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);
+ 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) {
+ 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);
+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 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, this->memory_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(){
+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 * 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);
+ 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")
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
- }
- }
+ // 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);
+ 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) {
+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;
+ 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) {
+dumper::Field * SolidMechanicsModel::createNodalFieldBool(
+ const std::string & field_name, const std::string & group_name,
+ __attribute__((unused)) bool padding_flag) {
- std::map<std::string,Array<bool>* > uint_nodal_fields;
- uint_nodal_fields["blocked_dofs" ] = blocked_dofs;
+ 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);
+ 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){
+dumper::Field * SolidMechanicsModel::createElementalField(
+ __attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) bool padding_flag,
+ __attribute__((unused)) const UInt & spatial_dimension,
+ __attribute__((unused)) const ElementKind & kind) {
return NULL;
}
/* -------------------------------------------------------------------------- */
-dumper::Field * SolidMechanicsModel::createNodalFieldReal(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag) {
+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) {
+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) {
+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) {
+ for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
- if(mat.isFiniteDeformation())
+ if (mat.isFiniteDeformation())
mat.computeAllCauchyStresses(_not_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::saveStressAndStrainBeforeDamage() {
- EventManager::sendEvent(SolidMechanicsModelEvent::BeginningOfDamageIterationEvent());
+ 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);
+ 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 << " + 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);
+ 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);
+ 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) {
+ 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 9b1627f06..ff042689d 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,777 +1,785 @@
/**
* @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: Tue Jan 19 2016
*
* @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;
+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) { }
+ 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> {
+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> &);
+ AKANTU_GET_MACRO_NOT_CONST(MaterialList, material, Array<UInt> &);
+ AKANTU_GET_MACRO(MaterialList, material, const Array<UInt> &);
+
protected:
- Array <UInt> material;
+ Array<UInt> material;
};
- typedef FEEngineTemplate <IntegratorGauss, ShapeLagrange> MyFEEngineType;
+ typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange> MyFEEngineType;
protected:
- typedef EventHandlerManager <SolidMechanicsModelEventHandler> EventManager;
+ typedef EventHandlerManager<SolidMechanicsModelEventHandler> EventManager;
public:
- SolidMechanicsModel(Mesh & mesh,
- UInt spatial_dimension = _all_dimensions,
- const ID & id = "solid_mechanics_model",
- const MemoryID & memory_id = 0);
+ 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);
+ 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);
+ 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;
+ 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
+ /// Update the increment of displacement
void updateIncrement();
- ///Copy the actuel displacement into previous displacement
+ /// Copy the actuel displacement into previous displacement
void updatePreviousDisplacement();
- ///Save stress and strain through EventManager
+ /// Save stress and strain through EventManager
void saveStressAndStrainBeforeDamage();
- ///Update energies through EventManager
+ /// 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);
+ 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)
virtual 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);
+ 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,
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator());
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,
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator());
/// test if the system is converged
template <SolveConvergenceCriteria criteria>
bool testConvergence(Real tolerance, Real & error,
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator());
/// test the convergence (norm of increment)
bool testConvergenceIncrement(Real tolerance) __attribute__((deprecated));
- bool testConvergenceIncrement(Real tolerance, Real & error) __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));
+ 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.,
+ 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);
+ /// 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);
-
+ 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);
+ 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);
+ 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)
+ /// 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 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 packElementData(CommunicationBuffer & buffer,
- const Array <Element> & elements,
- SynchronizationTag tag) const;
-
- inline virtual void unpackElementData(CommunicationBuffer & buffer,
- const Array <Element> & elements,
- SynchronizationTag tag);
+ 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 packData(CommunicationBuffer & buffer, const UInt index,
+ SynchronizationTag tag) const;
- inline virtual void unpackData(CommunicationBuffer & buffer,
- const UInt index,
- SynchronizationTag tag);
+ 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;
+ 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) {};
-
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
-
+ 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);
+ 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> &);
+ AKANTU_GET_MACRO(Displacement, *displacement, Array<Real> &);
/// get the SolidMechanicsModel::previous_displacement vector
- AKANTU_GET_MACRO(PreviousDisplacement, *previous_displacement, Array <Real> &);
+ 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> &);
+ 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> &);
+ AKANTU_GET_MACRO(Increment, *increment, Array<Real> &);
/// get the lumped SolidMechanicsModel::mass vector
- AKANTU_GET_MACRO(Mass, *mass, Array <Real> &);
+ AKANTU_GET_MACRO(Mass, *mass, Array<Real> &);
/// get the SolidMechanicsModel::velocity vector
- AKANTU_GET_MACRO(Velocity, *velocity, Array <Real> &);
+ AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &);
/// get the SolidMechanicsModel::acceleration vector, updated by
/// SolidMechanicsModel::updateAcceleration
- AKANTU_GET_MACRO(Acceleration, *acceleration, Array <Real> &);
+ AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
/// get the SolidMechanicsModel::force vector (boundary forces)
- AKANTU_GET_MACRO(Force, *force, Array <Real> &);
+ AKANTU_GET_MACRO(Force, *force, Array<Real> &);
/// get the SolidMechanicsModel::residual vector, computed by
/// SolidMechanicsModel::updateResidual
- AKANTU_GET_MACRO(Residual, *residual, Array <Real> &);
+ AKANTU_GET_MACRO(Residual, *residual, Array<Real> &);
/// get the SolidMechanicsModel::blocked_dofs vector
- AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array <bool> &);
+ AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &);
/// get the SolidMechnicsModel::incrementAcceleration vector
- AKANTU_GET_MACRO(IncrementAcceleration, *increment_acceleration, Array <Real> &);
+ 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 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);
+ 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 &);
+ 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 &);
+ 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(Synchronizer, *synch_parallel,
+ const DistributedSynchronizer &);
- AKANTU_GET_MACRO(MaterialByElement, material_index, const ElementTypeMapArray<UInt> &);
+ 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);
+ /// 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);
+ 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, 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;
+ Array<Real> * displacement;
/// displacements array at the previous time step (used in finite deformation)
- Array <Real> *previous_displacement;
+ Array<Real> * previous_displacement;
/// lumped mass array
- Array <Real> *mass;
+ Array<Real> * mass;
/// velocities array
- Array <Real> *velocity;
+ Array<Real> * velocity;
/// accelerations array
- Array <Real> *acceleration;
+ Array<Real> * acceleration;
/// accelerations array
- Array <Real> *increment_acceleration;
+ Array<Real> * increment_acceleration;
/// forces array
- Array <Real> *force;
+ Array<Real> * force;
/// residuals array
- Array <Real> *residual;
+ Array<Real> * residual;
/// array specifing if a degree of freedom is blocked or not
- Array <bool> *blocked_dofs;
+ Array<bool> * blocked_dofs;
/// array of current position used during update residual
- Array <Real> *current_position;
+ Array<Real> * current_position;
/// mass matrix
- SparseMatrix *mass_matrix;
+ SparseMatrix * mass_matrix;
/// velocity damping matrix
- SparseMatrix *velocity_damping_matrix;
+ SparseMatrix * velocity_damping_matrix;
/// stiffness matrix
- SparseMatrix *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;
+ 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)
+ /// 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;
+ std::vector<Material *> materials;
/// mapping between material name and material internal id
- std::map <std::string, UInt> materials_names_to_id;
+ std::map<std::string, UInt> materials_names_to_id;
#ifdef SWIGPYTHON
protected:
#endif
/// class defining of to choose a material
- MaterialSelector *material_selector;
+ 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;
+ IntegrationScheme2ndOrder * integrator;
/// increment of displacement
- Array <Real> *increment;
+ Array<Real> * increment;
/// flag defining if the increment must be computed or not
bool increment_flag;
/// solver for implicit
- Solver *solver;
+ Solver * solver;
/// analysis method check the list in akantu::AnalysisMethod
AnalysisMethod method;
/// internal synchronizer for parallel computations
- DistributedSynchronizer *synch_parallel;
+ DistributedSynchronizer * synch_parallel;
/// tells if the material are instantiated
bool are_materials_instantiated;
+ typedef std::map<std::pair<std::string, ElementKind>,
+ ElementTypeMapArray<Real> *> flatten_internal_map;
+
/// map a registered internals to be flattened for dump purposes
- std::map<std::pair<std::string,ElementKind>,ElementTypeMapArray<Real> *> registered_internals;
+ flatten_internal_map registered_internals;
/// pointer to non-local manager: For non-local continuum damage computations
- NonLocalManager * non_local_manager;
+ NonLocalManager * non_local_manager;
/// pointer to the pbc synchronizer
PBCSynchronizer * pbc_synch;
-
};
-
/* -------------------------------------------------------------------------- */
namespace BC {
- namespace Neumann {
- typedef FromHigherDim FromStress;
- typedef FromSameDim FromTraction;
- }
+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"
+#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) {
+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 447b78abf..9420540d4 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,747 +1,767 @@
/**
* @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"
+#include "dumper_paraview.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
-const SolidMechanicsModelCohesiveOptions default_solid_mechanics_model_cohesive_options(_explicit_lumped_mass,
- false,
- false);
+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) {
+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);
+ 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);
+ 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");
+ 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();
+ 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())
+ 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");
+ "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);
+ 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) {
+ 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);
- }
+ 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 {
- try { /// In case of insertion of intrinsic elements along mesh physical surfaces
- const ParserSection & mesh_section = *(this->parser->getSubSections(_st_mesh).first);
- std::string cohesive_surfaces = mesh_section.getParameter("cohesive_surfaces");
- initIntrinsicCohesiveMaterials(cohesive_surfaces);
- }
- catch(...) { /// Default intrinsic insertion
- initIntrinsicCohesiveMaterials(cohesive_index);
+ } 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) {
+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);
+ 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);
+ 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;
+ if (is_default_material_selector)
+ delete material_selector;
material_selector = new MeshDataMaterialCohesiveSelector(*this);
inserter->insertElements();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(UInt cohesive_index) {
+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) {
+ 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);
+ 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 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);
+ 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);
+ 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) {
+ 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) {
+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();
+ const ElementTypeMapArray<UInt> & rank_to_element =
+ synch_parallel->getPrankToElement();
- facet_stress_synchronizer->updateFacetStressSynchronizer(*inserter,
- rank_to_element,
- *data_accessor);
+ facet_stress_synchronizer->updateFacetStressSynchronizer(
+ *inserter, rank_to_element, *data_accessor);
}
#endif
- inserter->getMeshFacets().initElementTypeMapArray(facet_stress,
- 2 * spatial_dimension * spatial_dimension,
- spatial_dimension - 1);
+ 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();
+ 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);
- }
+ 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);
+ mesh_facets.initElementTypeMapArray(quad_facets, spatial_dimension,
+ spatial_dimension - 1);
- getFEEngine("FacetsFEEngine").interpolateOnIntegrationPoints(position, quad_facets);
+ 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);
+ 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 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;
+ 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);
+ 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);
+ 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);
- }
- }
- }
+ 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&) {
+ 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();
+ if (need_initialize)
+ initializeUpdateResidualData();
// f -= fint
std::vector<Material *>::iterator mat_it;
- for(mat_it = materials.begin(); mat_it != materials.end(); ++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) { }
+ } catch (std::bad_cast & bce) {
+ }
}
SolidMechanicsModel::updateResidual(false);
- if (isExplicit()){
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ 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) { }
+ 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);
+ 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_facets.initElementTypeMapArray(tangents, tangent_components,
+ spatial_dimension - 1);
- Mesh::type_iterator it = mesh_facets.firstType(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);
+ 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&) {
+ 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);
+ 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);
+ "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]);
+ 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&) { }
+ } 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) {
+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();
+ if (is_extrinsic)
+ resizeFacetStress();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::onNodesAdded(const Array<UInt> & doubled_nodes,
- __attribute__((unused)) const NewNodesEvent & event) {
+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);
+ (*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);
+ (*current_position)(new_node, dim) = (*current_position)(old_node, dim);
if (increment_acceleration)
- (*increment_acceleration)(new_node, dim)
- = (*increment_acceleration)(old_node, dim);
+ (*increment_acceleration)(new_node, dim) =
+ (*increment_acceleration)(old_node, dim);
if (increment)
- (*increment)(new_node, dim) = (*increment)(old_node, dim);
+ (*increment)(new_node, dim) = (*increment)(old_node, dim);
if (previous_displacement)
- (*previous_displacement)(new_node, dim)
- = (*previous_displacement)(old_node, dim);
+ (*previous_displacement)(new_node, dim) =
+ (*previous_displacement)(old_node, dim);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::onEndSolveStep(const AnalysisMethod & method) {
+void SolidMechanicsModelCohesive::onEndSolveStep(
+ __attribute__((unused)) 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
- ******************************************************************************/
+ /*
+ * 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) {
+ for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
- if(mat.isFiniteDeformation())
+ if (mat.isFiniteDeformation())
mat.computeAllCauchyStresses(_not_ghost);
}
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::printself(std::ostream & stream, int indent) const {
+void SolidMechanicsModelCohesive::printself(std::ostream & stream,
+ int indent) const {
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ 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) {
+ 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) {
+ 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 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) {
+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);
+ SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name, field_id,
+ group_name, spatial_dimension,
+ _element_kind, padding_flag);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::onDump(){
+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..8775a3a89 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,318 @@
/**
* @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.
+ /**
+ * 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).
+ /**
+ * 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));
+ // 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.
+ /**
+ * 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 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.
+ /**
+ * 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.
+ /**
+ * 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
deleted file mode 100644
index 7c7d22ff9..000000000
--- a/src/model/solid_mechanics/solid_mechanics_model_element.hh
+++ /dev/null
@@ -1,547 +0,0 @@
-/**
- * @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
- *
- * @brief elements for solid mechanics models
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-
-#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..4adb04969 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,127 @@
/**
* @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
+/// 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() {} };
+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() {};
+ 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) {
+ /// 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) {
+ /// 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) {
+ /// Send what is before dump to current dump through EventManager
+ inline void
+ sendEvent(__attribute__((unused))
+ 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) {
+ /// Send what is at the beginning of damage iteration to Damage iteration
+ /// through EventManager
+ inline void sendEvent(
+ __attribute__((unused))
+ const SolidMechanicsModelEvent::BeginningOfDamageIterationEvent & event) {
onDamageIteration();
- }
- ///Send what is after damage for the damage update through EventManager
- inline void sendEvent(const SolidMechanicsModelEvent::AfterDamageEvent & event) {
+ }
+ /// Send what is after damage for the damage update through EventManager
+ inline void
+ sendEvent(__attribute__((unused))
+ const SolidMechanicsModelEvent::AfterDamageEvent & event) {
onDamageUpdate();
}
- template<class EventHandler>
- friend class EventHandlerManager;
+ template <class EventHandler> friend class EventHandlerManager;
/* ------------------------------------------------------------------------ */
/* Interface */
/* ------------------------------------------------------------------------ */
public:
/// function to implement to react on akantu::BeforeSolveStepEvent
- virtual void onBeginningSolveStep(__attribute__((unused)) const AnalysisMethod & method) {}
+ virtual void onBeginningSolveStep(__attribute__((unused))
+ const AnalysisMethod & method) {}
/// function to implement to react on akantu::AfterSolveStepEvent
- virtual void onEndSolveStep(__attribute__((unused)) const AnalysisMethod & method) {}
+ 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 0cd4994ee..69de68a87 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
@@ -1,659 +1,660 @@
/**
* @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,
StaticCommunicator & comm) {
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, comm);
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,
StaticCommunicator & comm) {
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, comm);
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, comm);
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..531b7bdce 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model.cc
@@ -1,1148 +1,1225 @@
/**
* @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"
+#include "dumper_paraview.hh"
+#include "dumper_elemental_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
-const StructuralMechanicsModelOptions default_structural_mechanics_model_options(_static);
+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) {
+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);
+ 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->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)
+ 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);
+ 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();
-
+ 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);
+ 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) {
+ switch (method) {
case _implicit_dynamic:
initImplicit();
break;
case _static:
initSolver();
break;
default:
- AKANTU_EXCEPTION("analysis method not recognised by StructuralMechanicsModel");
- break;
+ 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);
+ 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);
+ 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);
+ stress.alloc(nb_element * nb_quadrature_points, size, *it, _not_ghost);
}
- dof_synchronizer = new DOFSynchronizer(getFEEngine().getMesh(), nb_degree_of_freedom);
+ 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) {
+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
+#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);
+ 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);
+ 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";
+ 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
+#endif // AKANTU_USE_MUMPS
solver->initialize(options);
-#endif //AKANTU_HAS_SOLVER
+#endif // AKANTU_HAS_SOLVER
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
- void StructuralMechanicsModel::initImplicit(bool dynamic, SolverOptions & solver_options) {
- AKANTU_DEBUG_IN();
-
- if (!increment) setIncrementFlagOn();
+void StructuralMechanicsModel::initImplicit(
+ __attribute__((unused)) bool dynamic, SolverOptions & solver_options) {
+ AKANTU_DEBUG_IN();
- initSolver(solver_options);
+ if (!increment)
+ setIncrementFlagOn();
- if(integrator) delete integrator;
- integrator = new TrapezoidalRule2();
+ initSolver(solver_options);
- AKANTU_DEBUG_OUT();
- }
+ if (integrator)
+ delete integrator;
+ integrator = new TrapezoidalRule2();
+
+ AKANTU_DEBUG_OUT();
+}
/* -------------------------------------------------------------------------- */
-UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize(const ElementType & type) {
+UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize(
+ const ElementType & type) {
UInt size;
-#define GET_TANGENT_STIFFNESS_VOIGT_SIZE(type) \
+#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);
+ 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>();
+#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){
+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);
+ 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.;
+ 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){
+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);
+ 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> 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);
+ rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
- for (UInt e=0 ; e < nb_element; ++e, ++n_it, ++connec_it, ++R_it) {
+ 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(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);
+ 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);
+ 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){
+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);
+
+ 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) {
-
+ 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_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);
+
+ 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();
-
+ 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);
+ 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)) {
+ 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);
+ 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);
+ Array<Real> rotations(nb_element,
+ nb_degree_of_freedom * nb_degree_of_freedom);
rotations.clear();
-#define COMPUTE_ROTATION_MATRIX(type) \
- computeRotationMatrix<type>(rotations);
+#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 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);
+ 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 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);
+ 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);
+ 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>();
+#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;
+ AKANTU_DEBUG_IN();
+ residual->copy(*force_momentum);
- this->updateResidualInternal();
+ Array<Real> ku(*displacement_rotation, true);
+ ku *= *stiffness_matrix;
+ *residual -= ku;
- AKANTU_DEBUG_OUT();
+ this->updateResidualInternal();
+ AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::implicitPred() {
AKANTU_DEBUG_IN();
- if(previous_displacement) previous_displacement->copy(*displacement_rotation);
+ if (previous_displacement)
+ previous_displacement->copy(*displacement_rotation);
- if(method == _implicit_dynamic)
- integrator->integrationSchemePred(time_step,
- *displacement_rotation,
- *velocity,
- *acceleration,
- *blocked_dofs);
+ 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);
+
+ 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);
+ 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){
+ 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) {
+ if (method != _static) {
// f -= Ma
- if(mass_matrix) {
+ 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();
+ 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;
+ 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) {
+ 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) {
+ if (!increment) {
UInt nb_nodes = mesh.getNbNodes();
- std::stringstream sstr_inc; sstr_inc << id << ":increment";
+ 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();
+ 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)) {
+ if (!(*blocked_dofs_val)) {
*displacement_val += *increment_val;
- }
- else {
+ } 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){
+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 * 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)) {
+ 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_ASSERT(!Math::isnan(norm[0]),
+ "Something went wrong in the solve phase");
AKANTU_DEBUG_OUT();
- if(norm[1] > Math::getTolerance())
+ if (norm[1] > Math::getTolerance())
error = norm[0] / norm[1];
else
- error = norm[0]; //In case the total displacement is zero!
+ error = norm[0]; // In case the total displacement is zero!
return (error < tolerance);
}
/* -------------------------------------------------------------------------- */
-template<>
-bool StructuralMechanicsModel::testConvergence<_scc_residual>(Real tolerance, Real & norm) {
+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) {
+ if (is_local_node) {
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
- if(!(*blocked_dofs_val)) {
+ 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_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) {
+bool StructuralMechanicsModel::testConvergenceIncrement(Real tolerance,
+ Real & error) {
AKANTU_DEBUG_IN();
- Mesh & mesh= getFEEngine().getMesh();
+ 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();
+ 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;
+ 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_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);
+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<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;
+ 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);
+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);
+ 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;
+ 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);
+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);
+ 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));
-
+ 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;
+ 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);
+template <>
+void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix<
+ _bernoulli_beam_2>(Array<Real> & b, __attribute__((unused)) 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);
+ 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;
+ 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> & 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(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(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) {
+template <>
+void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix<
+ _bernoulli_beam_3>(Array<Real> & b, __attribute__((unused)) 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 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;
+ 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;
+ Matrix<Real> & B = *B_it;
- const Vector<Real> & Np = *shape_Np;
+ 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(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(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(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(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) {
+template <>
+void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix<
+ _kirchhoff_shell>(Array<Real> & b, __attribute__((unused)) 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 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;
+ 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;
+ 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> & 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(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_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 *
+StructuralMechanicsModel::createNodalFieldBool(const std::string & field_name,
+ const std::string & group_name,
+ __attribute__((unused)) 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);
+ 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) {
+dumper::Field *
+StructuralMechanicsModel::createNodalFieldReal(const std::string & field_name,
+ const std::string & group_name,
+ bool padding_flag) {
UInt n;
- if(spatial_dimension == 2) {
+ if (spatial_dimension == 2) {
n = 2;
- } else n = 3;
+ } 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 == "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 == "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 == "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 == "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);
+ 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 * StructuralMechanicsModel::createElementalField(
+ const std::string & field_name, const std::string & group_name,
+ __attribute__((unused)) bool padding_flag, const ElementKind & kind,
+ __attribute__((unused)) 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);
+ 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..87a3f298b 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.hh
+++ b/src/model/structural_mechanics/structural_mechanics_model.hh
@@ -1,401 +1,392 @@
/**
* @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: Thu Jan 21 2016
*
- * @brief Particular implementation of the structural elements in the StructuralMechanicsModel
+ * @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;
+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;
+ StructuralMechanicsModelOptions(AnalysisMethod analysis_method = _static)
+ : analysis_method(analysis_method) {}
+ AnalysisMethod analysis_method;
};
-extern const StructuralMechanicsModelOptions default_structural_mechanics_model_options;
+extern const StructuralMechanicsModelOptions
+ default_structural_mechanics_model_options;
class StructuralMechanicsModel : public Model {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
- typedef FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural> MyFEEngineType;
+ 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);
+ 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);
+ 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);
-
+ 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) {};
+ template <const ElementType type>
+ void computeRotationMatrix(__attribute__((unused)) 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.);
+ template <NewmarkBeta::IntegrationSchemeCorrectorType type>
+ void solve(Array<Real> & increment,
+ __attribute__((unused)) Real block_val = 1.);
- /* ------------------------------------------------------------------------ */
- /* Mass (structural_mechanics_model_mass.cc) */
- /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------ */
+ /* 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);
+ 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> inline UInt getTangentStiffnessVoigtSize();
- template <ElementType type>
- void assembleStiffnessMatrix();
+ template <ElementType type> void assembleStiffnessMatrix();
- template <ElementType type>
- void assembleMass();
+ template <ElementType type> void assembleMass();
- template<ElementType type>
- void computeStressOnQuad();
+ 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);
+ 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);
-
+ 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 = "");
+ 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> &);
+ AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &);
- /// get the StructuralMechanicsModel::acceleration vector, updated by
+ /// get the StructuralMechanicsModel::acceleration vector, updated
+ /// by
/// StructuralMechanicsModel::updateAcceleration
- AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
+ AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
/// get the StructuralMechanicsModel::force vector (boundary forces)
- AKANTU_GET_MACRO(Force, *force_momentum, Array<Real> &);
+ 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::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(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); }
+ void addMaterial(StructuralMaterial & material) {
+ materials.push_back(material);
+ }
/**
- * @brief set the StructuralMechanicsModel::increment_flag to on, the activate the
+ * @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);
+ 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>
+ 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)
-{
+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..c4a8268ed 100644
--- a/src/python/python_functor_inline_impl.cc
+++ b/src/python/python_functor_inline_impl.cc
@@ -1,244 +1,281 @@
+/**
+ * @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__
-/* -------------------------------------------------------------------------- */
+__BEGIN_AKANTU__
+/* -------------------------------------------------------------------------- */
-template <typename T>
-inline int PythonFunctor::getPythonDataTypeCode() const{
+template <typename T> inline int PythonFunctor::getPythonDataTypeCode() const {
AKANTU_EXCEPTION("undefined type");
}
/* -------------------------------------------------------------------------- */
-
-template <>
-inline int PythonFunctor::getPythonDataTypeCode<bool>() const{
+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;
+ 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{
+/* -------------------------------------------------------------------------- */
+template <> inline int PythonFunctor::getPythonDataTypeCode<double>() const {
return NPY_DOUBLE;
}
/* -------------------------------------------------------------------------- */
-
template <typename T>
-PyObject *PythonFunctor::convertToPython(const T & akantu_object) const{
+PyObject * PythonFunctor::convertToPython(__attribute__((unused))
+ const T & akantu_object) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
-/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
template <>
-inline PyObject *PythonFunctor::convertToPython<double>(const double & akantu_object) const{
+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{
+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{
+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 >();
+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;
+ 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 >();
+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;
+ 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;
+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());
+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{
+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 * 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);
+ 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{
+/* -------------------------------------------------------------------------- */
+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");
+
+ // 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 {}
/* -------------------------------------------------------------------------- */
+inline void
+PythonFunctor::packArguments(__attribute__((unused))
+ std::vector<PyObject *> & p_args) 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));
+/* -------------------------------------------------------------------------- */
+template <typename T, typename... Args>
+inline void PythonFunctor::packArguments(std::vector<PyObject *> & p_args,
+ T & p, Args &... params) const {
+ p_args.push_back(this->convertToPython(p));
if (sizeof...(params) != 0)
- this->packArguments(pArgs,params...);
+ this->packArguments(p_args, params...);
}
/* -------------------------------------------------------------------------- */
-
-
template <typename return_type, typename... Params>
return_type PythonFunctor::callFunctor(const std::string & functor_name,
- Params&... parameters) const{
-
-
+ Params &... parameters) const {
_import_array();
-
- std::vector<PyObject*> arg_vector;
- this->packArguments(arg_vector,parameters...);
+
+ 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]);
+ PyTuple_SetItem(pArgs, i, arg_vector[i]);
}
-
+
PyObject * kwargs = PyDict_New();
PyObject * pFunctor = getPythonFunction(functor_name);
- PyObject * res = this->callFunctor(pFunctor,pArgs,kwargs);
+ 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{
+inline return_type PythonFunctor::convertToAkantu(PyObject * python_obj) const {
- if (PyList_Check(python_obj)){
- return this->convertListToAkantu<typename return_type::value_type>(python_obj);
+ 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");
+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");
+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");
+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{
-
+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);
+ 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_matrix_inline_impl.cc b/src/solver/petsc_matrix_inline_impl.cc
deleted file mode 100644
index b3fe55d54..000000000
--- a/src/solver/petsc_matrix_inline_impl.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file petsc_matrix_inline_impl.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Mon Jul 21 21:42:12 2014
- *
- * @brief Implementation of PetscMatrix 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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 PetscMatrix::addToProfile(UInt i, UInt j) {
-
-// // initialize new value
-// MatSetValuesLocal(this->mat,1,i,1,j,0,INSERT_VALUES);
-
-// nb_non_zero++;
-
-// return nb_non_zero - 1;
-// }
-
-// /* -------------------------------------------------------------------------- */
-// inline void PetscMatrix::clearProfile() {
-// //retain matrix but reinitialize its content
-// MatZeroEntries(this->mat);
-// nb_non_zero = 0;
-// }
-
-// /* -------------------------------------------------------------------------- */
-// inline void PetscMatrix::clear() {
-// memset(a.storage(), 0, nb_non_zero*sizeof(Real));
-// }
-
-// /* -------------------------------------------------------------------------- */
-// inline void PetscMatrix::addToMatrix(UInt i, UInt j, Real value) {
-// MatSetValue(this->mat,1,i,1,j,value,ADD_VALUES);
-// }
-
-// /* -------------------------------------------------------------------------- */
-// inline Real PetscMatrix::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 this->mat(i,j).
-// }
-
-// /* -------------------------------------------------------------------------- */
-// inline Real & PetscMatrix::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];
-// }
-
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 34176023d..8a3a0fd60 100644
--- a/src/solver/solver.cc
+++ b/src/solver/solver.cc
@@ -1,89 +1,92 @@
/**
* @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: Tue Jan 19 2016
*
* @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,
StaticCommunicator & comm) :
Memory(id, memory_id), StaticSolverEventHandler(),
matrix(&matrix),
is_matrix_allocated(false),
mesh(NULL),
communicator(comm),
solution(NULL),
synch_registry(NULL) {
AKANTU_DEBUG_IN();
StaticSolver::getStaticSolver().registerEventHandler(*this);
- //createSynchronizerRegistry();
+ // createSynchronizerRegistry();
this->synch_registry = new SynchronizerRegistry(*this);
- synch_registry->registerSynchronizer(this->matrix->getDOFSynchronizer(), _gst_solver_solution);
+ 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{
+ try {
this->destroyInternalData();
- } catch(...) {}
+ } catch (...) {
+ }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Solver::createSynchronizerRegistry() {
- //this->synch_registry = new SynchronizerRegistry(this);
+ // this->synch_registry = new SynchronizerRegistry(this);
}
-
__END_AKANTU__
diff --git a/src/solver/solver.hh b/src/solver/solver.hh
index 468fb14ee..ab071e6de 100644
--- a/src/solver/solver.hh
+++ b/src/solver/solver.hh
@@ -1,168 +1,164 @@
/**
* @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 Jan 19 2016
*
* @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)
- { }
+ SolverOptions(
+ __attribute__((unused)) bool no_option = false) // : no_option(no_option)
+ {}
virtual ~SolverOptions() {}
private:
- //bool no_option;
+ // bool no_option;
};
extern SolverOptions _solver_no_options;
class Solver : protected Memory,
- public StaticSolverEventHandler,
- public DataAccessor {
+ public StaticSolverEventHandler,
+ public DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
Solver(SparseMatrix & matrix,
const ID & id = "solver",
const MemoryID & memory_id = 0,
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator());
virtual ~Solver();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// initialize the solver
virtual void initialize(SolverOptions & options = _solver_no_options) = 0;
- virtual void setOperators() {};
- virtual void analysis() {};
+ virtual void setOperators(){};
+ virtual void analysis(){};
- virtual void factorize() {};
+ 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() {};
+ 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 UInt getNbDataForDOFs(const Array<UInt> & dofs,
+ SynchronizationTag tag) const;
inline virtual void packDOFData(CommunicationBuffer & buffer,
- const Array<UInt> & dofs,
- SynchronizationTag tag) const;
+ const Array<UInt> & dofs,
+ SynchronizationTag tag) const;
inline virtual void unpackDOFData(CommunicationBuffer & buffer,
- const Array<UInt> & dofs,
- SynchronizationTag tag);
+ 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 22739ecd1..55026b1e5 100644
--- a/src/solver/solver_mumps.cc
+++ b/src/solver/solver_mumps.cc
@@ -1,390 +1,401 @@
/**
* @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: Tue Jan 19 2016
*
* @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"
+#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) {
+// 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,
StaticCommunicator & comm) :
Solver(matrix, id, memory_id, comm), 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
+#else // AKANTU_USE_MPI
parallel_method = SolverMumpsOptions::_not_parallel;
-#endif //AKANTU_USE_MPI
+#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) {
+ 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
+ icntl(28) = 0; // automatic choice for analysis analysis
- switch(this->parallel_method) {
+ switch (this->parallel_method) {
case SolverMumpsOptions::_fully_distributed:
- icntl(18) = 3; //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;
+ 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
+ icntl(18) = 0; // centralized
- if(prank == 0) {
- this->mumps_data.nz = matrix->getNbNonZero();
+ 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.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)) {
+ 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;
+ 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());
+ 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
+ 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";
+ 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;
+ this->mumps_data.n = size;
/* ------------------------------------------------------------------------ */
// Output setup
- if(AKANTU_DEBUG_TEST(dblTrace)) {
+ 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)) {
+ if (AKANTU_DEBUG_TEST(dblDump)) {
strcpy(this->mumps_data.write_problem, "mumps_matrix.mtx");
}
this->analysis();
-// icntl(14) = 80;
+ // icntl(14) = 80;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::setRHS(Array<Real> & rhs) {
- if(prank == 0) {
+ if (prank == 0) {
- //std::copy(rhs.storage(), rhs.storage() + this->rhs->getSize(), this->rhs->storage());
+ // 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
+ 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();
+ 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.a = this->matrix->getA().storage();
}
- if(prank == 0) {
+ 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) {
+ 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) {
+ if (prank == 0) {
matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
-// std::copy(this->rhs->storage(), this->rhs->storage() + this->rhs->getSize(), solution.storage());
+ // 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[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: {
+ 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();
+ 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;
+ 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) = "
+ 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]);
+ 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 09ca3c1f1..1c18272e4 100644
--- a/src/solver/solver_mumps.hh
+++ b/src/solver/solver_mumps.hh
@@ -1,155 +1,148 @@
/**
* @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: Tue Jan 19 2016
*
* @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) { }
+ 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,
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator());
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];
- }
+ 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];
- }
+ 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..8cce152c8 100644
--- a/src/solver/solver_petsc.cc
+++ b/src/solver/solver_petsc.cc
@@ -1,1109 +1,1170 @@
/**
* @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: Tue Jan 19 2016
*
* @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(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) {
+ 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);
+ 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) {
+void SolverPETSc::initialize(__attribute__((unused)) 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();
+ 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;
+ this->petsc_solver_wrapper->communicator = PETSC_COMM_SELF;
#endif
PetscErrorCode ierr;
- PETScMatrix * petsc_matrix = static_cast<PETScMatrix*>(this->matrix);
+ 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);
-
+ 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 = 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);
+ 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);
+ 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;
+ 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);
+ 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);
+ 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);
-
-
+ 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);
+ 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);
+ 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);
+ // 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);
-
+ 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);
+ /// 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);
+#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);
+ 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);
+ /// 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;
+// 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) {
+// 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);
-
+// 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) {
-
+
+// 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);
+// 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);
+// // 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);
-
-
+// // 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);
-
-
+// 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) {
+// 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;
+// // 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) {
-
+// 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;
+// 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);
+
+// 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
-
+
+// 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) {
-
+
+// 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);
+// 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) {
-
+
+// 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);
+// 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) {
+// 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);
-
-
+// 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) {
-
-// 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;
+// 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) {
+// 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) {
+// 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) {
+
+// 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) {
+// 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) {
-
+// 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 = 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) {
+// 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) {
-// 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) {
+// 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;
-
-// }
+// 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) {
+// //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()))
+// // 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) {
+// ///*
+// -------------------------------------------------------------------------- */
+// //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) {
+// //
+// // 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());
+// // 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) ="
+// // "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 a9b34e624..4ff978959 100644
--- a/src/solver/sparse_matrix.cc
+++ b/src/solver/sparse_matrix.cc
@@ -1,631 +1,632 @@
/**
* @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,
UInt nb_proc_input) :
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();
if (nb_proc_input == 0) {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
nb_proc = comm.getNbProc();
} else {
nb_proc = nb_proc_input;
}
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(nb_proc == 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 c5fbbab67..2f164979a 100644
--- a/src/solver/sparse_matrix.hh
+++ b/src/solver/sparse_matrix.hh
@@ -1,240 +1,241 @@
/**
* @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,
UInt nb_proc_input = 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..630f04215 100644
--- a/src/solver/static_solver.cc
+++ b/src/solver/static_solver.cc
@@ -1,112 +1,125 @@
/**
* @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: Tue Jan 19 2016
*
* @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) {
+StaticSolver::StaticSolver()
+ : CommunicatorEventHandler(), is_initialized(false) {
StaticCommunicator::getStaticCommunicator().registerEventHandler(*this);
}
-
/* -------------------------------------------------------------------------- */
StaticSolver::~StaticSolver() {
--this->nb_references;
- if(this->nb_references == 0) {
+ if (this->nb_references == 0) {
StaticCommunicator::getStaticCommunicator().unregisterEventHandler(*this);
delete this->static_solver;
}
}
/* -------------------------------------------------------------------------- */
StaticSolver & StaticSolver::getStaticSolver() {
- if(nb_references == 0)
+ 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,
+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 << "\"");
+ 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 << "\"");
+static PetscErrorCode
+PETScErrorHandler(MPI_Comm, int line, __attribute__((unused)) const char * func,
+ __attribute__((unused)) const char * dir, const char * file,
+ PetscErrorCode number,
+ __attribute__((unused)) 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");
+void StaticSolver::initialize(__attribute__((unused)) int & argc,
+ __attribute__((unused)) 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);
+ 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;
- }
+ this->is_initialized = true;
+}
/* -------------------------------------------------------------------------- */
void StaticSolver::finalize() {
- ParentEventHandler::sendEvent(StaticSolverEvent::BeforeStaticSolverDestroyEvent());
-
+ ParentEventHandler::sendEvent(
+ StaticSolverEvent::BeforeStaticSolverDestroyEvent());
- AKANTU_DEBUG_ASSERT(this->is_initialized == true, "The static solver has not been initialized");
+ 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..10accb651 100644
--- a/src/solver/static_solver.hh
+++ b/src/solver/static_solver.hh
@@ -1,108 +1,111 @@
/**
* @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() {}
- };
+struct BeforeStaticSolverDestroyEvent {
+ BeforeStaticSolverDestroyEvent() {}
+};
}
class StaticSolverEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- virtual ~StaticSolverEventHandler() {};
+ virtual ~StaticSolverEventHandler(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
- inline void sendEvent(const StaticSolverEvent::BeforeStaticSolverDestroyEvent & event) {
+ inline void
+ sendEvent(__attribute__((unused))
+ const StaticSolverEvent::BeforeStaticSolverDestroyEvent & event) {
this->beforeStaticSolverDestroy();
}
- template<class EventHandler> friend class EventHandlerManager;
+ 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);
+ 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 c38b70aa6..7d66c313f 100644
--- a/src/synchronizer/distributed_synchronizer.cc
+++ b/src/synchronizer/distributed_synchronizer.cc
@@ -1,1722 +1,1790 @@
/**
* @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: Fri Jan 22 2016
*
- * @brief implementation of a communicator using a static_communicator for real
+ * @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"
+#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, memory_id)
{
+
AKANTU_DEBUG_IN();
nb_proc = static_communicator->getNbProc();
- rank = static_communicator->whoAmI();
+ 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());
- }
+ 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);
+ 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;
+ delete[] send_element;
+ delete[] recv_element;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-DistributedSynchronizer * DistributedSynchronizer::
-createDistributedSynchronizerMesh(Mesh & mesh,
- const MeshPartition * partition,
- UInt root,
- SynchronizerID id,
- MemoryID memory_id) {
+/// TODO check what it would imply to rewrite this creation as a distributed
+/// process
+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));
+ DistributedSynchronizer & communicator =
+ *(new DistributedSynchronizer(mesh, id, memory_id));
- if(nb_proc == 1) return &communicator;
+ 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);
+ 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);
+ 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) {
+ 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));
+ Vector<UInt> nb_local_element(nb_proc, 0);
+ Vector<UInt> nb_ghost_element(nb_proc, 0);
+ Vector<UInt> nb_element_to_send(nb_proc, 0);
/// \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;
+ 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);
+ 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;
+ 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];
+ UInt ** buffers = new UInt *[nb_proc];
+ UInt ** buffers_tmp = new UInt *[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];
+ 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;
+ 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;
- }
+ 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];
- }
+ 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);
+ 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];
+ 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];
+ 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));
+ Vector<UInt> count_by_proc(nb_proc, 0);
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;
- }
+ *(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);
- }
+ 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 (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);
+ 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];
+ delete[] buffers[p];
}
+ delete [] buffers;
+ delete [] buffers_tmp;
/* -------------------------------------------------------------------- */
/// 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]);
-
+ 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);
+ 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));
+ 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;
+ 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];
+ Vector<UInt> nb_nodes_per_proc(nb_proc);
+ UInt ** nodes_per_proc = new UInt *[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));
+ 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();
+ 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;
+ 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;
+ 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;
+ 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;
+ memcpy(nodes->storage(), local_nodes,
+ nb_nodes * spatial_dimension * sizeof(Real));
+ delete[] local_nodes;
- Array<Int> * nodes_type_per_proc[nb_proc];
+ Array<Int> ** nodes_type_per_proc = new Array<Int> *[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));
+ 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());
+ 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)));
+ 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;
+ 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;
+ 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;
+ 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)));
+ 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]);
+ 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];
+ if (p != root)
+ delete[] nodes_per_proc[p];
delete nodes_type_per_proc[p];
}
-
+ delete [] nodes_per_proc;
+ delete [] nodes_type_per_proc;
/* -------->>>>-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 };
+ 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);
+ 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);
+ } 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));
+ 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));
+ 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));
+ 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));
+ 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; \
- } \
+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;
+ 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
+#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;
+ const UInt GHOST_SET = 2;
bool * already_seen = new bool[nb_nodes];
- for(UInt g = _not_ghost; g <= _ghost; ++g) {
- GhostType gt = (GhostType) g;
+ for (UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType gt = (GhostType)g;
UInt set = NORMAL_SET;
- if (gt == _ghost) set = GHOST_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) {
+ 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);
+ 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;
- }
- }
+ 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;
+ 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;
+ 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;
+ delete[] nodes_set;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::fillCommunicationScheme(const UInt * partition,
- UInt nb_local_element,
- UInt nb_ghost_element,
- ElementType type) {
+ 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++;
+ 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++;
+ UInt proc = *part;
+ part++;
- AKANTU_DEBUG(dblAccessory, "Must send : " << element << " to proc " << proc);
+ 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++;
+ UInt proc = *part;
+ part++;
element.element = gel;
element.ghost_type = _ghost;
- AKANTU_DEBUG(dblAccessory, "Must recv : " << element << " from proc " << proc);
+ 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) {
+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);
+ 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()) {
+ 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;
+ 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)");
+ 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> 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);
+ 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)));
+ "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");
+ "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;
+ 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_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) {
+ SynchronizationTag tag) {
AKANTU_DEBUG_IN();
- AKANTU_DEBUG_ASSERT(communications.find(tag) != communications.end(), "No communication with the tag \""
- << tag <<"\" started");
+ 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);
+ 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) {
+ 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];
+ 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);
+ 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 << " ]");
- }
- }
+ 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);
+ 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);
+ 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);
+ 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) {
+ 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)) {
+ 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) {
+ SynchronizationTag tag) {
AKANTU_DEBUG_IN();
communications[tag].resize(nb_proc);
for (UInt p = 0; p < nb_proc; ++p) {
- UInt ssend = 0;
+ 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
+ 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);
+ 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);
+ 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
+ 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);
+ 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);
+ 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_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();
+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 {
+void DistributedSynchronizer::printself(std::ostream & stream,
+ int indent) const {
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ 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;
+ stream << "[" << prank << "/" << psize << "]" << space
+ << "DistributedSynchronizer [" << std::endl;
for (UInt p = 0; p < nb_proc; ++p) {
- if (p == UInt(prank)) continue;
+ if (p == UInt(prank))
+ continue;
stream << "[" << prank << "/" << psize << "]" << space
- << " + Communication to proc " << p << " [" << std::endl;
- if(AKANTU_DEBUG_TEST(dblDump)) {
+ << " + Communication to proc " << p << " [" << std::endl;
+ if (AKANTU_DEBUG_TEST(dblDump)) {
stream << "[" << prank << "/" << psize << "]" << space
- << " - Element to send to proc " << p << " [" << std::endl;
+ << " - Element to send to proc " << p << " [" << std::endl;
- Array<Element>::iterator<Element> it_el = send_element[p].begin();
+ 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;
+ 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;
+ << " - Element to recv from proc " << p << " [" << std::endl;
- it_el = recv_element[p].begin();
+ 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;
+ 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 << " ]"
+ << std::endl;
}
- std::map< SynchronizationTag, Communication>::const_iterator it = communications.begin();
- std::map< SynchronizationTag, Communication>::const_iterator end = communications.end();
+ 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 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;
+ 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) {
+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();
+ 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;
+ 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;
+ 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;
+ 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) {
+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");
+ 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) {
+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.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 it =
+ mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
- Mesh::type_iterator end = mesh.lastType(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) {
+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);
+ newsy_send_element[p].push_back(element);
else
- new_send_element[p].push_back(element);
+ 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);
+ newsy_recv_element[p].push_back(element);
else
- new_recv_element[p].push_back(element);
+ new_recv_element[p].push_back(element);
}
}
/// deleting and reassigning old pointers
- delete [] send_element;
- delete [] recv_element;
+ 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) {
+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) {
+ 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_it = tag_names.begin();
std::vector<std::string>::const_iterator names_end = tag_names.end();
- for(;names_it != names_end; ++names_it) {
+ 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 << ")." );
+ 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();
+ 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) {
+ 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);
+ 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)));
+ 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();
+ names_it = tag_names.begin();
// Loop over each tag for the current type
- for(;names_it != names_end; ++names_it) {
+ 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);
+ 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;
+ 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) {
+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) {
+ 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.");
+ 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) {
+ 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);
+ 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) {
+ 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_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);
+ << 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) << ")");
+ 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));
+ 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);
+ 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) {
+template <class CommunicationBuffer>
+void DistributedSynchronizer::fillElementGroupsFromBuffer(
+ __attribute__((unused)) 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) {
+ 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);
+ 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 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);
+ 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) {
+void DistributedSynchronizer::synchronizeElementGroups(
+ DistributedSynchronizer & communicator, __attribute__((unused)) 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];
+ DynamicCommunicationBuffer * buffers =
+ new DynamicCommunicationBuffer[nb_proc];
- typedef std::vector< std::vector<std::string> > ElementToGroup;
+ 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);
+ 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)
+ 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_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 it = ghost_partition.begin(el);
CSR<UInt>::const_iterator end = ghost_partition.end(el);
- for (;it != end; ++it) {
+ 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)));
+ 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;
-
+ delete[] buffers;
+
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
-void DistributedSynchronizer::synchronizeElementGroups(DistributedSynchronizer & communicator,
- UInt root,
- Mesh & mesh,
- const ElementType & type) {
+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) <<")");
+ 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));
+ 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) {
+template <class CommunicationBuffer>
+void DistributedSynchronizer::fillNodeGroupsFromBuffer(
+ __attribute__((unused)) DistributedSynchronizer & communicator, Mesh & mesh,
+ CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
- std::vector< std::vector<std::string> > node_to_group;
+ 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");
+ "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();
+ 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();
+ 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) {
+void DistributedSynchronizer::synchronizeNodeGroupsMaster(
+ DistributedSynchronizer & communicator, __attribute__((unused)) 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;
+ 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 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)
+ 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)));
+ 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) {
+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) <<")");
+ 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));
+ 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) {
+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;
+ if (p == rank)
+ continue;
Array<Element> & recv = recv_element[p];
- if(recv.getSize() == 0) continue;
+ if (recv.getSize() == 0)
+ continue;
Array<Element>::iterator<Element> recv_begin = recv.begin();
- Array<Element>::iterator<Element> recv_end = recv.end();
+ 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_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);
+ 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())
+ if (list.getSize() == recv.getSize())
list.push_back(UInt(0));
- else list.push_back(UInt(-1));
+ 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)));
+ 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;
+ 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.");
+ 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;
+ if (p == rank)
+ continue;
Array<Element> & send = send_element[p];
- if(send.getSize() == 0) continue;
+ if (send.getSize() == 0)
+ continue;
CommunicationStatus status;
- AKANTU_DEBUG_INFO("Getting number of elements of proc " << p << " not needed anymore TAG("<< this->genTagFromID(0) <<")");
+ 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));
+ 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;
+ if (list.getSize() == 1 && list(0) == 0)
+ continue;
list.erase(list.getSize() - 1);
- if (list.getSize() == send.getSize()) continue;
+ 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.");
+ 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;
+ delete[] list_of_el;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void DistributedSynchronizer::renumberElements(const ElementTypeMapArray<UInt> & new_numbering) {
+void DistributedSynchronizer::renumberElements(
+ const ElementTypeMapArray<UInt> & new_numbering) {
// Handling ghost elements
for (UInt p = 0; p < nb_proc; ++p) {
- if (p == rank) continue;
+ 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..40620ad0d 100644
--- a/src/synchronizer/distributed_synchronizer.hh
+++ b/src/synchronizer/distributed_synchronizer.hh
@@ -1,300 +1,286 @@
/**
* @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);
+ 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);
+ 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);
+ void asynchronousSynchronize(DataAccessor & data_accessor,
+ SynchronizationTag tag);
/// wait end of asynchronous synchronization of ghosts
- void waitEndSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
+ 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);
+ 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);
+ 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) {};
+ virtual void onNodesAdded(__attribute__((unused))
+ const Array<UInt> & nodes_list,
+ __attribute__((unused))
+ const NewNodesEvent & event){};
/// mesh event handler onRemovedNodes
- virtual void onNodesRemoved(const Array<UInt> & nodes_list,
- const Array<UInt> & new_numbering,
- const RemovedNodesEvent & event) {};
+ virtual void
+ onNodesRemoved(__attribute__((unused)) const Array<UInt> & nodes_list,
+ __attribute__((unused)) const Array<UInt> & new_numbering,
+ __attribute__((unused)) const RemovedNodesEvent & event){};
/// mesh event handler onElementsAdded
- virtual void onElementsAdded (const Array<Element> & elements_list,
- const NewElementsEvent & event) {};
+ virtual void onElementsAdded(__attribute__((unused))
+ const Array<Element> & elements_list,
+ __attribute__((unused))
+ const NewElementsEvent & event){};
/// filter elements of a certain kind and copy them into a new synchronizer
void filterElementsByKind(DistributedSynchronizer * new_synchronizer,
- ElementKind kind);
+ 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 std::string & tag_name, const ElementType & el_type,
const Array<UInt> & partition_num);
- template<typename T>
+ 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 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,
+ 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);
+ 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,
+ 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);
+ 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);
+ /// 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);
+ 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);
+ 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);
-
+ 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);
+ UInt root, Mesh & mesh,
+ const ElementType & type);
- template<class CommunicationBuffer>
- static void fillElementGroupsFromBuffer(DistributedSynchronizer & communicator,
- Mesh & mesh,
- const ElementType & type,
- CommunicationBuffer & buffer);
+ 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);
-
+ 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);
+ static void
+ synchronizeNodeGroupsSlaves(DistributedSynchronizer & communicator, UInt root,
+ Mesh & mesh);
- template<class CommunicationBuffer>
+ template <class CommunicationBuffer>
static void fillNodeGroupsFromBuffer(DistributedSynchronizer & communicator,
- Mesh & mesh,
- CommunicationBuffer & buffer);
+ Mesh & mesh,
+ CommunicationBuffer & buffer);
/// substitute elements in the send and recv arrays
- void substituteElements(const std::map<Element, Element> & old_to_new_elements);
+ void
+ substituteElements(const std::map<Element, Element> & old_to_new_elements);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
- AKANTU_GET_MACRO(PrankToElement, prank_to_element, const ElementTypeMapArray<UInt> &);
+ AKANTU_GET_MACRO(PrankToElement, prank_to_element,
+ const ElementTypeMapArray<UInt> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
enum CommTags {
- TAG_SIZES = 0,
+ 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_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 4dc069d8b..6e6218ed0 100644
--- a/src/synchronizer/dof_synchronizer.cc
+++ b/src/synchronizer/dof_synchronizer.cc
@@ -1,503 +1,504 @@
/**
* @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,
StaticCommunicator & comm) :
Synchronizer("synchronizer", 0, comm),
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 49ea9b2c1..a2ff6bcd8 100644
--- a/src/synchronizer/dof_synchronizer.hh
+++ b/src/synchronizer/dof_synchronizer.hh
@@ -1,245 +1,246 @@
/**
* @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,
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator());
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 0177779b8..bd4dc9fe5 100644
--- a/src/synchronizer/grid_synchronizer.cc
+++ b/src/synchronizer/grid_synchronizer.cc
@@ -1,549 +1,593 @@
/**
* @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: Fri Jan 22 2016
*
* @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,
+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) {
+ 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) {
+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;
+ 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[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.");
+ 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;
+ 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;
+ 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;
+ 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 = 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);
+ 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]);
+ 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]);
+ 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) {
+ 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];
+ 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) {
+ 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];
+ 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) {
+ 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];
+ end = proc_bounding_box[s + spatial_dimension];
- AKANTU_DEBUG_INFO("Intersection scheme 3 in direction " << s << " with processor " << p << " [" << start << ", " << end <<"]");
+ 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];
+ end = my_bounding_box[s + spatial_dimension];
- AKANTU_DEBUG_INFO("Intersection scheme 4 in direction " << s << " with processor " << p << " [" << start << ", " << end <<"]");
+ 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);
+ last_cell_p[s] = grid.getCellID(end, s);
}
}
-
- //create the list of cells in the overlapping
+ // 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]) {
+ 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) {
+ if (spatial_dimension == 1) {
cell_ids->push_back(cell_id);
- }
- else {
- for (Int sd = first_cell_p[1]; sd <= last_cell_p[1] ; ++sd) {
+ } else {
+ for (Int sd = first_cell_p[1]; sd <= last_cell_p[1]; ++sd) {
cell_id.setID(1, sd);
- if(spatial_dimension == 2) {
+ if (spatial_dimension == 2) {
cell_ids->push_back(cell_id);
} else {
- for (Int ld = first_cell_p[2]; ld <= last_cell_p[2] ; ++ld) {
+ 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);
+ 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);
+ 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, memory_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))
+ // /!\ 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;
+ Vector<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);
+ 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;
+ 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]) {
+ 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);
+ 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[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) << ")");
+ 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)));
+ 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[0] = (UInt)_not_defined;
info[1] = 0;
- isend_requests.push_back(comm.asyncSend(info, 2, p, Tag::genTag(my_rank, count, SIZE_TAG)));
+ 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());
+ 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];
+ Vector<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;
+ 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]) {
+ if (intersects_proc[p]) {
ElementType type = _not_defined;
do {
- UInt info[2] = { 0 };
+ 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);;
+ 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) << ")");
+ 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));
+ 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];
+ Vector<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);
+ AKANTU_DEBUG_ASSERT(gn < mesh.getNbGlobalNodes(),
+ "This global node seems not correct "
+ << gn << " from element " << el
+ << " node " << n);
- if(ln == UInt(-1)) {
+ if (ln == UInt(-1)) {
global_nodes_ids.push_back(gn);
- nodes_type.push_back(-3); // pure ghost node
+ nodes_type.push_back(-3); // pure ghost node
ln = nb_current_nodes;
- new_nodes.getList().push_back(ln);
+ 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
+ // all the nodes are already known locally, the element should
+ // already exists
UInt c = UInt(-1);
- if(nb_node_to_ask_for_elem == 0) {
+ if (nb_node_to_ask_for_elem == 0) {
c = ghost_connectivity.find(conn);
- element.element = c;
+ element.element = c;
}
- if(c == UInt(-1)) {
+ if (c == UInt(-1)) {
element.element = nb_ghost_element;
++nb_ghost_element;
ghost_connectivity.push_back(conn);
- new_elements.getList().push_back(element);
+ new_elements.getList().push_back(element);
}
communicator.recv_element[p].push_back(element);
}
}
count++;
- } while(type != _not_defined);
+ } 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) << ")");
+ 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];
+ 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];
+ if (element_per_proc[p])
+ delete element_per_proc[p];
}
- delete [] element_per_proc;
+ 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;
+ 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) << ")");
+ 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) << ")");
+ << " 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) << ")");
+ 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));
+ 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!");
+ 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) << ")");
+ 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)));
+ 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)
+#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;
+ 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) << ")");
+ 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];
+ 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)
+#if not defined(AKANTU_NDEBUG)
else {
- if(p != my_rank) {
- AKANTU_DEBUG_INFO("No nodes to receive from processor " << p);
+ 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;
+ delete[] nodes_to_send_per_proc;
// Register the tags if any
- if(synchronizer_registry) {
- std::set<SynchronizationTag>::const_iterator it = tags_to_register.begin();
+ 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;
+ 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);
+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 f950fead4..d703386e4 100644
--- a/src/synchronizer/real_static_communicator.hh
+++ b/src/synchronizer/real_static_communicator.hh
@@ -1,109 +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() { };
- /// Finalize communication process
- virtual void finalize() {};
+
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 26424c971..476e968e2 100644
--- a/src/synchronizer/static_communicator.cc
+++ b/src/synchronizer/static_communicator.cc
@@ -1,128 +1,133 @@
/**
* @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: Tue Jan 19 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"
+#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) {
+CommunicationRequest::CommunicationRequest(UInt source, UInt dest)
+ : source(source), destination(dest) {
this->id = counter++;
}
/* -------------------------------------------------------------------------- */
-CommunicationRequest::~CommunicationRequest() {
-
-}
+CommunicationRequest::~CommunicationRequest() {}
/* -------------------------------------------------------------------------- */
void CommunicationRequest::printself(std::ostream & stream, int indent) const {
std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+ 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) {
+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 {
+ if (type == _communicator_mpi) {
+ real_static_communicator = new StaticCommunicatorMPI(argc, argv);
+ } else {
#endif
- real_static_communicator = new StaticCommunicatorDummy(argc, argv);
+ real_static_communicator = new StaticCommunicatorDummy(argc, argv);
#ifdef AKANTU_USE_MPI
- }
+ }
#endif
}
/* -------------------------------------------------------------------------- */
-void StaticCommunicator::finalize() {
-
- real_static_communicator->finalize();
+StaticCommunicator::~StaticCommunicator() {
+ FinalizeCommunicatorEvent * event = new FinalizeCommunicatorEvent(*this);
+ this->sendEvent(*event);
+
+ this->barrier();
+ delete event;
+ delete real_static_communicator;
+ is_instantiated = false;
+ StaticCommunicator::static_communicator = NULL;
}
+
/* -------------------------------------------------------------------------- */
-StaticCommunicator & StaticCommunicator::getStaticCommunicator(CommunicatorType type) {
+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;
}
- is_instantiated = true;
AKANTU_DEBUG_OUT();
return *static_communicator;
}
/* -------------------------------------------------------------------------- */
-StaticCommunicator & StaticCommunicator::getStaticCommunicator(int & argc,
- char ** & argv,
- CommunicatorType type) {
+StaticCommunicator &
+StaticCommunicator::getStaticCommunicator(int & argc, char **& argv,
+ CommunicatorType type) {
if (!static_communicator)
static_communicator = new StaticCommunicator(argc, argv, type);
return getStaticCommunicator(type);
}
/* -------------------------------------------------------------------------- */
StaticCommunicator * StaticCommunicator::getStaticCommunicatorDummy() {
int nb_args = 0;
char ** null;
return new StaticCommunicator(nb_args, null, _communicator_dummy);
}
__END_AKANTU__
diff --git a/src/synchronizer/static_communicator.hh b/src/synchronizer/static_communicator.hh
index d4e283e0a..b8f49c059 100644
--- a/src/synchronizer/static_communicator.hh
+++ b/src/synchronizer/static_communicator.hh
@@ -1,220 +1,218 @@
/**
* @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: Tue Jan 19 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)))
+#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)))
+#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
+#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) {}
+ FinalizeCommunicatorEvent(const StaticCommunicator & comm)
+ : communicator(comm) {}
const StaticCommunicator & communicator;
};
class CommunicatorEventHandler {
public:
virtual ~CommunicatorEventHandler() {}
- virtual void onCommunicatorFinalize(__attribute__((unused)) const StaticCommunicator & communicator) { }
+ virtual void onCommunicatorFinalize(__attribute__((unused))
+ const StaticCommunicator & communicator) {
+ }
+
private:
inline void sendEvent(const FinalizeCommunicatorEvent & event) {
onCommunicatorFinalize(event.communicator);
}
- template<class EventHandler>
- friend class EventHandlerManager;
+ template <class EventHandler> friend class EventHandlerManager;
};
-class StaticCommunicator : public EventHandlerManager<CommunicatorEventHandler>{
+class StaticCommunicator
+ : public EventHandlerManager<CommunicatorEventHandler> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
protected:
- StaticCommunicator(int & argc, char ** & argv,
+ 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;
-
- };
+ virtual ~StaticCommunicator();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
- /// Finalize the real_static_communicator
- void finalize();
-
/* ------------------------------------------------------------------------ */
/* 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);
+ 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);
+ 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);
+ 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 &);
+ 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); }
+ template <class Comm> Comm & getRealStaticCommunicator() {
+ return dynamic_cast<Comm &>(*real_static_communicator);
+ }
- static StaticCommunicator & getStaticCommunicator(CommunicatorType type = _communicator_mpi);
+ static StaticCommunicator &
+ getStaticCommunicator(CommunicatorType type = _communicator_mpi);
- static StaticCommunicator & getStaticCommunicator(int & argc, char ** & argv,
- CommunicatorType type = _communicator_mpi);
+ static StaticCommunicator &
+ getStaticCommunicator(int & argc, char **& argv,
+ CommunicatorType type = _communicator_mpi);
static StaticCommunicator * getStaticCommunicatorDummy();
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)
-{
+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 59114ab25..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; }
- void finalize() {}
+
/* ------------------------------------------------------------------------ */
/* 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 47ed3732b..2c2d6cbaa 100644
--- a/src/synchronizer/static_communicator_mpi.cc
+++ b/src/synchronizer/static_communicator_mpi.cc
@@ -1,498 +1,502 @@
/**
* @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: Thu Jan 21 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
-};
-
+ 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) {
+CommunicationRequestMPI::CommunicationRequestMPI(UInt source, UInt dest)
+ : CommunicationRequest(source, dest) {
request = new MPI_Request;
}
/* -------------------------------------------------------------------------- */
-CommunicationRequestMPI::~CommunicationRequestMPI() {
- delete request;
-}
+CommunicationRequestMPI::~CommunicationRequestMPI() { delete request; }
/* -------------------------------------------------------------------------- */
-StaticCommunicatorMPI::StaticCommunicatorMPI(int & argc, char ** & argv) :
- RealStaticCommunicator(argc, argv) {
+StaticCommunicatorMPI::StaticCommunicatorMPI(int & argc, char **& argv)
+ : RealStaticCommunicator(argc, argv) {
int is_initialized = false;
MPI_Initialized(&is_initialized);
- if (!is_initialized)
+ if (!is_initialized) {
MPI_Init(&argc, &argv);
+ }
+
+ this->is_externaly_initialized = is_initialized;
mpi_data = new MPITypeWrapper(*this);
mpi_data->setMPICommunicator(MPI_COMM_WORLD);
}
/* -------------------------------------------------------------------------- */
StaticCommunicatorMPI::~StaticCommunicatorMPI() {
-
-}
-
-/* -------------------------------------------------------------------------- */
-void StaticCommunicatorMPI::finalize() {
- MPI_Finalize();
+ if (!this->is_externaly_initialized) {
+ MPI_Finalize();
+ }
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-void StaticCommunicatorMPI::send(T * buffer, Int size,
- Int receiver, Int tag) {
+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);
+ 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) {
+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);
+ MPI_Recv(buffer, size, type, sender, tag, communicator, &status);
AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Recv.");
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+template <typename T>
CommunicationRequest * StaticCommunicatorMPI::asyncSend(T * buffer, Int size,
- Int receiver, Int tag) {
+ Int receiver, Int tag) {
MPI_Comm communicator = mpi_data->getMPICommunicator();
- CommunicationRequestMPI * request = new CommunicationRequestMPI(prank, receiver);
+ 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());
+ 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) {
+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);
+ 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());
+ 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>
+template <typename T>
void StaticCommunicatorMPI::probe(Int sender, Int tag,
- CommunicationStatus & status) {
+ 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);
+ 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);
+ 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);
+ 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);
+ CommunicationRequestMPI * req_mpi =
+ static_cast<CommunicationRequestMPI *>(request);
MPI_Request * req = req_mpi->getMPIRequest();
#if !defined(AKANTU_NDEBUG)
int ret =
#endif
- MPI_Wait(req, &status);
+ MPI_Wait(req, &status);
AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Wait.");
}
/* -------------------------------------------------------------------------- */
-void StaticCommunicatorMPI::waitAll(std::vector<CommunicationRequest *> & requests) {
+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();
+ 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);
+ 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>
+template <typename T>
void StaticCommunicatorMPI::reduce(T * values, int nb_values,
- const SynchronizerOperation & op,
- int root) {
+ 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);
+ 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>
+template <typename T>
void StaticCommunicatorMPI::allReduce(T * values, int nb_values,
- const SynchronizerOperation & op) {
+ 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);
+ 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>
+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);
+ 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>
+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];
+ 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);
+ 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;
+ delete[] displs;
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+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;
+ 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);
+ 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>
+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) {
+ 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];
+ 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;
+ if (prank == root) {
+ send_buf = (T *)MPI_IN_PLACE;
recv_buf = values;
- } else send_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);
+ 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;
+ if (prank == root) {
+ delete[] displs;
}
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+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);
+ MPI_Bcast(values, nb_values, type, root, communicator);
AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Gather.");
}
/* -------------------------------------------------------------------------- */
-int StaticCommunicatorMPI::getMaxTag() {
- return MPI_TAG_UB;
-}
+int StaticCommunicatorMPI::getMaxTag() { return MPI_TAG_UB; }
/* -------------------------------------------------------------------------- */
-int StaticCommunicatorMPI::getMinTag() {
- return 0;
-}
+int StaticCommunicatorMPI::getMinTag() { return 0; }
/* -------------------------------------------------------------------------- */
-
-
// template<typename T>
// MPI_Datatype StaticCommunicatorMPI::getMPIDatatype() {
// return MPI_DATATYPE_NULL;
// }
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<char>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<char>() {
return MPI_CHAR;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<float>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<float>() {
return MPI_FLOAT;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<double>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<double>() {
return MPI_DOUBLE;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<long double>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<long double>() {
return MPI_LONG_DOUBLE;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<signed int>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<signed int>() {
return MPI_INT;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned int>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned int>() {
return MPI_UNSIGNED;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<signed long int>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<signed long int>() {
return MPI_LONG;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned long int>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned long int>() {
return MPI_UNSIGNED_LONG;
}
-template<>
+template <>
MPI_Datatype MPITypeWrapper::getMPIDatatype<signed long long int>() {
return MPI_LONG_LONG;
}
-template<>
+template <>
MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned long long int>() {
return MPI_UNSIGNED_LONG_LONG;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype< SCMinMaxLoc<double, int> >() {
+template <>
+MPI_Datatype MPITypeWrapper::getMPIDatatype<SCMinMaxLoc<double, int> >() {
return MPI_DOUBLE_INT;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype< SCMinMaxLoc<float, 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);
-
+#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);
-
+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 16df1f879..27a863f55 100644
--- a/src/synchronizer/static_communicator_mpi.hh
+++ b/src/synchronizer/static_communicator_mpi.hh
@@ -1,130 +1,128 @@
/**
* @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: Tue Jan 19 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);
+ 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> 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>
+ 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 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 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 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);
+ template <typename T> void broadcast(T * values, int nb_values, int root);
bool testRequest(CommunicationRequest * request);
- void wait (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);
+ 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();
- /// Finalize MPI
- void finalize();
private:
void setRank(int prank) { this->prank = prank; }
void setSize(int psize) { this->psize = psize; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
friend class MPITypeWrapper;
MPITypeWrapper * mpi_data;
+ bool is_externaly_initialized;
};
-
/* -------------------------------------------------------------------------- */
/* 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 c931d018f..d4797c3ed 100644
--- a/src/synchronizer/synchronizer.cc
+++ b/src/synchronizer/synchronizer.cc
@@ -1,58 +1,59 @@
/**
* @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,
StaticCommunicator & comm) :
Memory(id, memory_id),
static_communicator(&comm) {
}
/* -------------------------------------------------------------------------- */
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 d74808f2a..b73174bcb 100644
--- a/src/synchronizer/synchronizer.hh
+++ b/src/synchronizer/synchronizer.hh
@@ -1,174 +1,175 @@
/**
* @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,
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator());
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..8f0da7ceb 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,85 +1,61 @@
#===============================================================================
# @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: Fri Jan 22 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()
+package_add_files_to_package(
+ cmake/akantu_test_driver.sh
+ cmake/AkantuTestsMacros.cmake
+ )
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..7a4d13232 100644
--- a/test/test_common/test_csr.cc
+++ b/test/test_common/test_csr.cc
@@ -1,122 +1,117 @@
/**
* @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[]) {
+int main() {
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.)));
+ 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) {
+ if (csr.getNbRows() != N) {
AKANTU_DEBUG_ERROR("The number of rows does not correspond: "
- << csr.getNbRows()
- << " != "
- << N);
+ << 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);
+ 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) {
+ if (nb_cols != 0) {
AKANTU_DEBUG_ERROR("Not enough columns in the row " << i << ": "
- << nb_cols);
+ << 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);
+ 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);
+ 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..de8a8bed5 100644
--- a/test/test_common/test_math.cc
+++ b/test/test_common/test_math.cc
@@ -1,71 +1,75 @@
/**
* @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 * diff = new Real[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 norm = Math::norm(n, diff) / Math::norm(n, xref);
Real tol = 1e-12;
- AKANTU_DEBUG_ASSERT(norm < tol, "x differs form xref");
+ if (norm > tol) {
+ std::cout << "differs form xref of " << std::scientific << norm << std::endl;
+ exit(-1);
+ }
+
+ delete [] diff;
}
/* -------------------------------------------------------------------------- */
-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, };
+int main() {
+ 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 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 };
+ 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 };
+ 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..79d1f3530 100644
--- a/test/test_common/test_types.cc
+++ b/test/test_common/test_types.cc
@@ -1,348 +1,348 @@
/**
* @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[]) {
+int main() {
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..79e39009f 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[]) {
+int main() {
#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..e58f636f3 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 main() {
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;
+ 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..7aca9f005 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[]) {
+int main() {
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
deleted file mode 100644
index 050465450..000000000
--- a/test/test_contact/CMakeLists.txt
+++ /dev/null
@@ -1,124 +0,0 @@
-#===============================================================================
-# @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
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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
deleted file mode 100644
index ef41acd80..000000000
--- a/test/test_contact/acurnier_2D_1.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @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
- *
- * @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)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_1.geo b/test/test_contact/acurnier_2D_1.geo
deleted file mode 100644
index a54b9d18b..000000000
--- a/test/test_contact/acurnier_2D_1.geo
+++ /dev/null
@@ -1,27 +0,0 @@
-cl1 = 2;
-cl2 = -0.15;
-cl3 = -0.5;
-Point(1) = {-1, cl3, 0, cl1};
-Point(2) = {-1, 0.5, 0, cl1};
-Point(3) = {1, 0.5, 0, cl1};
-Point(4) = {1, cl3, 0, cl1};
-Point(5) = {0, 0.7+cl2, 0, cl1};
-Point(6) = {0.7, 1.4+cl2, 0, cl1};
-Point(7) = {0, 1.4+cl2, 0, cl1};
-Line(1) = {1, 4};
-Line(2) = {4, 3};
-Line(3) = {3, 2};
-Line(4) = {2, 1};
-Line(5) = {5, 6};
-Line(6) = {6, 7};
-Line(7) = {7, 5};
-Line Loop(9) = {1, 2, 3, 4};
-Plane Surface(9) = {9};
-Line Loop(11) = {5, 6, 7};
-Plane Surface(11) = {11};
-Physical Line("Bottom") = {1};
-Physical Line("Top") = {6};
-Physical Line("Contact") = {3};
-Physical Line("Dummy") = {2, 4, 5, 7};
-Physical Surface("Top_body") = {11};
-Physical Surface("Bottom_body") = {9};
diff --git a/test/test_contact/acurnier_2D_2.cc b/test/test_contact/acurnier_2D_2.cc
deleted file mode 100644
index 76b80abf1..000000000
--- a/test/test_contact/acurnier_2D_2.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * @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
- *
- * @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)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_2.geo b/test/test_contact/acurnier_2D_2.geo
deleted file mode 100644
index 60dbd8b77..000000000
--- a/test/test_contact/acurnier_2D_2.geo
+++ /dev/null
@@ -1,31 +0,0 @@
-cl1 = 2;
-cl2 = -0.15;
-cl3 = -0.5;
-Point(1) = {-1, cl3, 0, cl1};
-Point(2) = {-1, 0.5, 0, cl1};
-Point(3) = {1, 0.5, 0, cl1};
-Point(4) = {1, cl3, 0, cl1};
-Point(5) = {0.35, 0.7+cl2, 0, cl1};
-Point(6) = {0.35, 1.4+cl2, 0, cl1};
-Point(7) = {-0.35, 1.4+cl2, 0, cl1};
-Point(8) = {-0.35, 0.7+cl2, 0, cl1};
-Line(1) = {1, 4};
-Line(2) = {4, 3};
-Line(3) = {3, 2};
-Line(4) = {2, 1};
-Line(5) = {8, 5};
-Line(6) = {5, 6};
-Line(7) = {6, 8};
-Line(8) = {7, 8};
-Line(9) = {6, 7};
-Line Loop(10) = {5, 6, 7};
-Plane Surface(11) = {10};
-Line Loop(12) = {-7, 9, 8};
-Plane Surface(13) = {12};
-Line Loop(14) = {1, 2, 3, 4};
-Plane Surface(15) = {14};
-Physical Line("Contact") = {3};
-Physical Line("Top") = {9};
-Physical Line("Bottom") = {1};
-Physical Surface("Top_body") = {11, 13};
-Physical Surface("Bottom_body") = {15};
diff --git a/test/test_contact/acurnier_2D_3.cc b/test/test_contact/acurnier_2D_3.cc
deleted file mode 100644
index e0c25fb59..000000000
--- a/test/test_contact/acurnier_2D_3.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * @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
- *
- * @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)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_2D_3.geo b/test/test_contact/acurnier_2D_3.geo
deleted file mode 100644
index e10ef71ed..000000000
--- a/test/test_contact/acurnier_2D_3.geo
+++ /dev/null
@@ -1,42 +0,0 @@
-cl1 = 2;
-cl2 = -0.15;
-cl3 = -0.5;
-Point(1) = {-1., cl3, 0, cl1};
-Point(2) = {-1., 0.5, 0, cl1};
-Point(3) = {1., 0.5, 0, cl1};
-Point(4) = {1., cl3, 0, cl1};
-Point(5) = {0.7, 0.7+cl2, 0, cl1};
-Point(6) = {0.7, 1.4+cl2, 0, cl1};
-Point(7) = {0, 1.4+cl2, 0, cl1};
-Point(8) = {0, 0.7+cl2, 0, cl1};
-Point(9) = {-0.7, 1.4+cl2, 0, cl1};
-Point(10) = {-0.7, 0.7+cl2, 0, cl1};
-Line(1) = {1, 4};
-Line(2) = {4, 3};
-Line(3) = {3, 2};
-Line(4) = {2, 1};
-Line(5) = {8, 5};
-Line(6) = {5, 6};
-Line(7) = {6, 8};
-Line(8) = {7, 8};
-Line(9) = {6, 7};
-Line(10) = {10, 8};
-Line(11) = {8, 9};
-Line(12) = {7, 9};
-Line(13) = {9, 10};
-Line Loop(10) = {5, 6, 7};
-Plane Surface(11) = {10};
-Line Loop(12) = {-7, 9, 8};
-Plane Surface(13) = {12};
-Line Loop(14) = {1, 2, 3, 4};
-Plane Surface(15) = {14};
-Line Loop(16) = {10, 11, 13};
-Plane Surface(17) = {16};
-Line Loop(18) = {-8, 12, -11};
-Plane Surface(19) = {18};
-Physical Line("Contact") = {3};
-Physical Line("Top") = {9, 12};
-Physical Line("Bottom") = {1};
-Physical Surface("Top_body") = {11, 13, 17, 19};
-Physical Surface("Bottom_body") = {15};
-
diff --git a/test/test_contact/acurnier_2D_3.verified b/test/test_contact/acurnier_2D_3.verified
deleted file mode 100644
index 1966e2109..000000000
--- a/test/test_contact/acurnier_2D_3.verified
+++ /dev/null
@@ -1,51 +0,0 @@
-*** INFO *** Obtaining penalty parameters automatically. Average value: 9452.4
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 4
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Force: 3.11354
diff --git a/test/test_contact/acurnier_3D_1.cc b/test/test_contact/acurnier_3D_1.cc
deleted file mode 100644
index 53b7edafa..000000000
--- a/test/test_contact/acurnier_3D_1.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * @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
- *
- * @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)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_1.geo b/test/test_contact/acurnier_3D_1.geo
deleted file mode 100644
index 0960d8da8..000000000
--- a/test/test_contact/acurnier_3D_1.geo
+++ /dev/null
@@ -1,64 +0,0 @@
-cl1 = 4;
-off = 0.;
-h = -0.6;
-Point(1) = {-0.5, -0.5, -0.5, cl1};
-Point(2) = {-0.5, 0.5, -0.5, cl1};
-Point(3) = {0.5, 0.5, -0.5, cl1};
-Point(4) = {0.5, -0.5, -0.5, cl1};
-Point(5) = {0.25, 1.2+h, 0 + off, cl1};
-Point(6) = {0.75, 1.9+h, -0.5 + off, cl1};
-Point(7) = {-0.25, 1.9+h, -0.5 + off, cl1};
-Point(11) = {-0.5, -0.5, 0.5, cl1};
-Point(12) = {-0.5, 0.5, 0.5, cl1};
-Point(13) = {0.5, 0.5, 0.5, cl1};
-Point(14) = {0.5, -0.5, 0.5, cl1};
-Point(26) = {0.75, 1.9+h, 0.5 + off, cl1};
-Line(1) = {1, 4};
-Line(2) = {4, 3};
-Line(3) = {3, 2};
-Line(4) = {2, 1};
-Line(5) = {5, 6};
-Line(6) = {6, 7};
-Line(7) = {7, 5};
-Line(11) = {11, 14};
-Line(12) = {14, 13};
-Line(13) = {13, 12};
-Line(14) = {12, 11};
-Line(15) = {14, 4};
-Line(16) = {13, 3};
-Line(17) = {11, 1};
-Line(18) = {12, 2};
-Line(19) = {7, 26};
-Line(21) = {26, 6};
-Line(23) = {26, 5};
-
-Line Loop(26) = {-12, 15, 2, -16};
-Plane Surface(26) = {26};
-Line Loop(28) = {-1, -4, -3, -2};
-Plane Surface(28) = {28};
-Line Loop(30) = {-17, -14, 18, 4};
-Plane Surface(30) = {30};
-Line Loop(32) = {11, 12, 13, 14};
-Plane Surface(32) = {32};
-Line Loop(34) = {-15,1, 17, -11};
-Plane Surface(34) = {34};
-Line Loop(36) = {16, 3, -18, -13};
-Plane Surface(36) = {36};
-
-Line Loop(38) = {5, -21, 23};
-Plane Surface(38) = {38};
-Line Loop(44) = {-7, -5, -6};
-Plane Surface(44) = {44};
-Line Loop(45) = {-23, 7, -19};
-Plane Surface(45) = {45};
-Line Loop(46) = {21, 6, 19};
-Plane Surface(46) = {46};
-Surface Loop(48) = {38, 44, 45, 46};
-Volume(48) = {48};
-Surface Loop(50) = {36, 26, 32, 34, 28, 30};
-Volume(50) = {50};
-Physical Surface("Top") = {46};
-Physical Surface("Bottom") = {34};
-Physical Surface("Contact") = {36};
-Physical Volume("Top_body") = {48};
-Physical Volume("Bottom_body") = {50};
diff --git a/test/test_contact/acurnier_3D_2.cc b/test/test_contact/acurnier_3D_2.cc
deleted file mode 100644
index 1a421ba56..000000000
--- a/test/test_contact/acurnier_3D_2.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * @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
- *
- * @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)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_2.geo b/test/test_contact/acurnier_3D_2.geo
deleted file mode 100644
index b15267076..000000000
--- a/test/test_contact/acurnier_3D_2.geo
+++ /dev/null
@@ -1,94 +0,0 @@
-cl1 = 4;
-off = 0.25;
-h = -1.3;
-Point(1) = {-0.5, -0.5, -0.5, cl1};
-Point(2) = {-0.5, 0.5, -0.5, cl1};
-Point(3) = {1, 0.5, -0.5, cl1};
-Point(4) = {1, -0.5, -0.5, cl1};
-Point(5) = {0.75, 2.8+h, -0.5 + off, cl1};
-Point(6) = {0.75, 1.9+h, -0.5 + off, cl1};
-Point(7) = {-0.25, 1.9+h, -0.5 + off, cl1};
-Point(11) = {-0.5, -0.5, 1, cl1};
-Point(12) = {-0.5, 0.5, 1, cl1};
-Point(13) = {1, 0.5, 1, cl1};
-Point(14) = {1, -0.5, 1, cl1};
-Point(26) = {0.75, 1.9+h, 0.5 + off, cl1};
-Point(30) = {-0.25, 2.8+h, -0.5 + off, cl1};
-Point(31) = {0.75, 2.8+h, 0.5 + off, cl1};
-Line(1) = {1, 4};
-Line(2) = {4, 3};
-Line(3) = {3, 2};
-Line(4) = {2, 1};
-Line(5) = {5, 6};
-Line(6) = {6, 7};
-Line(7) = {7, 5};
-Line(11) = {11, 14};
-Line(12) = {14, 13};
-Line(13) = {13, 12};
-Line(14) = {12, 11};
-Line(15) = {14, 4};
-Line(16) = {13, 3};
-Line(17) = {11, 1};
-Line(18) = {12, 2};
-Line(19) = {7, 26};
-Line(21) = {26, 6};
-Line(23) = {26, 5};
-
-Line Loop(26) = {-12, 15, 2, -16};
-Plane Surface(26) = {26};
-Line Loop(28) = {-1, -4, -3, -2};
-Plane Surface(28) = {28};
-Line Loop(30) = {-17, -14, 18, 4};
-Plane Surface(30) = {30};
-Line Loop(32) = {11, 12, 13, 14};
-Plane Surface(32) = {32};
-Line Loop(34) = {-15,1, 17, -11};
-Plane Surface(34) = {34};
-Line Loop(36) = {16, 3, -18, -13};
-Plane Surface(36) = {36};
-
-Line Loop(38) = {-5, -23, 21};
-Plane Surface(38) = {38};
-Line Loop(44) = {7, 6, 5};
-Plane Surface(44) = {44};
-Line Loop(45) = {23, 19, -7};
-Plane Surface(45) = {45};
-Line Loop(46) = {-21, -19, -6};
-Plane Surface(46) = {46};
-
-Line(51) = {31, 5};
-Line(52) = {5, 30};
-Line(53) = {30, 31};
-Line(54) = {31, 26};
-Line(55) = {30, 7};
-Line(67) = {30, 26};
-
-Line Loop(56) = {51, 52, 53};
-Plane Surface(57) = {56};
-Line Loop(58) = {54, 23, -51};
-Plane Surface(59) = {58};
-
-
-Line Loop(62) = {-7, -55, -52};
-Plane Surface(63) = {62};
-
-Line Loop(68) = {-54, -53, 67};
-Plane Surface(69) = {68};
-Line Loop(70) = {-67, 55, 19};
-Plane Surface(71) = {70};
-Line Loop(72) = {52, 67, 23};
-Plane Surface(73) = {72};
-
-
-Surface Loop(50) = {36, 26, 32, 34, 28, 30};
-Volume(50) = {50};
-
-Surface Loop(79) = {38, 44, 46, 63, 71, 69, 59, 57};
-Volume(80) = {79};
-
-Physical Surface("Top") = {57};
-Physical Surface("Bottom") = {34};
-Physical Surface("Contact") = {36};
-Physical Volume("Top_body") = {80};
-Physical Volume("Bottom_body") = {50};
-
diff --git a/test/test_contact/acurnier_3D_3.cc b/test/test_contact/acurnier_3D_3.cc
deleted file mode 100644
index 3737b4418..000000000
--- a/test/test_contact/acurnier_3D_3.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * @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
- *
- * @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)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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/acurnier_3D_3.geo b/test/test_contact/acurnier_3D_3.geo
deleted file mode 100644
index c621016d6..000000000
--- a/test/test_contact/acurnier_3D_3.geo
+++ /dev/null
@@ -1,62 +0,0 @@
-cl1 = 4;
-cl2 = 1;
-offx = 0.;
-offz = 0.25;
-h = -1.3;
-Point(1) = {-0.5, -0.5, -0.5, cl1};
-Point(2) = {-0.5, 0.5, -0.5, cl1};
-Point(3) = {1, 0.5, -0.5, cl1};
-Point(4) = {1, -0.5, -0.5, cl1};
-Point(5) = {-0.15+offx, 1.9+h, 0.4 + offz, cl2};
-Point(6) = {-0.15+offx, 1.9+h, -0.4 + offz, cl2};
-Point(7) = {0.65+offx, 1.9+h, -0.4 + offz, cl2};
-Point(8) = {0.65+offx, 1.9+h, 0.4 + offz, cl2};
-Point(11) = {-0.5, -0.5, 1, cl1};
-Point(12) = {-0.5, 0.5, 1, cl1};
-Point(13) = {1, 0.5, 1, cl1};
-Point(14) = {1, -0.5, 1, cl1};
-Line(1) = {1, 4};
-Line(2) = {4, 3};
-Line(3) = {3, 2};
-Line(4) = {2, 1};
-Line(11) = {11, 14};
-Line(12) = {14, 13};
-Line(13) = {13, 12};
-Line(14) = {12, 11};
-Line(15) = {14, 4};
-Line(16) = {13, 3};
-Line(17) = {11, 1};
-Line(18) = {12, 2};
-Line(19) = {8, 7};
-Line(20) = {7, 6};
-Line(21) = {6, 5};
-Line(22) = {5, 8};
-Line Loop(23) = {22, 19, 20, 21};
-Plane Surface(24) = {23};
-Extrude {0, 1.5, 0} {
- Surface{24};
-}
-Coherence;
-
-Line Loop(26) = {-12, 15, 2, -16};
-Plane Surface(26) = {26};
-Line Loop(28) = {-1, -4, -3, -2};
-Plane Surface(28) = {28};
-Line Loop(30) = {-17, -14, 18, 4};
-Plane Surface(30) = {30};
-Line Loop(32) = {11, 12, 13, 14};
-Plane Surface(32) = {32};
-Line Loop(34) = {-15,1, 17, -11};
-Plane Surface(34) = {34};
-Line Loop(36) = {16, 3, -18, -13};
-Plane Surface(36) = {36};
-
-Surface Loop(50) = {36, 26, 32, 34, 28, 30};
-Volume(50) = {50};
-
-
-Physical Surface("Top") = {46};
-Physical Surface("Bottom") = {34};
-Physical Surface("Contact") = {36};
-Physical Volume("Bottom_body") = {50};
-Physical Volume("Top_body") = {1};
diff --git a/test/test_contact/hertz_2D.cc b/test/test_contact/hertz_2D.cc
deleted file mode 100644
index 4b12cf992..000000000
--- a/test/test_contact/hertz_2D.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * @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
- *
- * @brief This file tests for the Hertz solution in 2D
- *
- * @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 "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_2D.geo b/test/test_contact/hertz_2D.geo
deleted file mode 100644
index e51c71e7d..000000000
--- a/test/test_contact/hertz_2D.geo
+++ /dev/null
@@ -1,30 +0,0 @@
-cl1 = 0.01;
-cl2 = 0.1;
-cl3 = 1;
-Dy = 0.1;
-Point(1) = {0, 0.1-Dy, 0, cl1};
-Point(2) = {0.5, 0.6-Dy, 0, cl2};
-Point(3) = {-0.5, 0.6-Dy, 0, cl2};
-Point(4) = {0.5, 0, 0, cl3};
-Point(5) = {-0.5, 0, 0, cl3};
-Point(6) = {-0.5, -0.25, 0, cl3};
-Point(7) = {0.5, -0.25, 0, cl3};
-Point(8) = {0, 0.6-Dy, 0, cl2};
-Circle(1) = {3, 8, 1};
-Circle(2) = {1, 8, 2};
-Line(3) = {2, 8};
-Line(13) = {8, 3};
-Line(4) = {6, 7};
-Line(5) = {7, 4};
-Line(6) = {4, 5};
-Line(7) = {5, 6};
-Line Loop(9) = {2, 3, 13, 1};
-Plane Surface(9) = {9};
-Line Loop(11) = {6, 7, 4, 5};
-Plane Surface(11) = {11};
-Physical Point(15) = {8};
-Physical Line("rigid") = {6};
-Physical Line("contact_surface") = {1, 2};
-Physical Line("top") = {3, 13};
-Physical Surface("Bottom_body") = {9};
-Physical Surface("Top_body") = {11};
diff --git a/test/test_contact/hertz_3D.cc b/test/test_contact/hertz_3D.cc
deleted file mode 100644
index 4606af351..000000000
--- a/test/test_contact/hertz_3D.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- * @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
- *
- * @brief This file tests for the Hertz solution in 3D
- *
- * @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 "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/hertz_3D.geo b/test/test_contact/hertz_3D.geo
deleted file mode 100644
index b305119b8..000000000
--- a/test/test_contact/hertz_3D.geo
+++ /dev/null
@@ -1,54 +0,0 @@
-cl1 = 0.02;
-cl2 = 0.2;
-cl3 = 0.4;
-Dy = 0.099;
-Dz = 1;
-Point(1) = {0, 0.1-Dy, 0, cl1};
-Point(2) = {0.5, 0.6-Dy, 0, cl2};
-Point(3) = {-0.5, 0.6-Dy, 0, cl2};
-Point(4) = {0, 0.6-Dy, 0, cl2};
-Point(5) = {0, 0.6-Dy, -0.5, cl2};
-Point(6) = {0, 0.6-Dy, 0.5, cl2};
-
-Point(7) = {0, 0, 0, cl3};
-Point(8) = {0.5, 0, 0, cl3};
-Point(9) = {-0.5, 0, 0, cl3};
-Point(10) = {0, 0, -0.5, cl3};
-Point(11) = {0, 0, 0.5, cl3};
-
-Circle(1) = {3, 4, 1};
-Circle(2) = {1, 4, 2};
-Circle(3) = {6, 4, 1};
-Circle(4) = {1, 4, 5};
-Circle(5) = {3, 4, 6};
-Circle(6) = {6, 4, 2};
-Circle(7) = {2, 4, 5};
-Circle(8) = {5, 4, 3};
-Line Loop(1) = {3, 2, -6};
-Ruled Surface(1) = {1};
-Line Loop(2) = {-2, -7, 4};
-Ruled Surface(2) = {2};
-Line Loop(3) = {-4, -8, -1};
-Ruled Surface(3) = {3};
-Line Loop(4) = {1, -3, -5};
-Ruled Surface(4) = {4};
-Line Loop(5) = {6, 7, 8, 5};
-Plane Surface(5) = {5};
-Surface Loop(1) = {3, 2, 1, 4, 5};
-Volume(1) = {1};
-
-Circle(9) = {9, 7, 11};
-Circle(10) = {11, 7, 8};
-Circle(11) = {8, 7, 10};
-Circle(12) = {10, 7, 9};
-Line Loop(6) = {10, 11, 12, 9};
-Plane Surface(6) = {6};
-Extrude {0, -cl3, 0} {
- Surface{6};
-}
-
-Physical Surface("top_surface") = {5};
-Physical Surface("rigid_surface") = {6};
-Physical Volume("top_body") = {1};
-Physical Volume("bottom_body") = {2};
-Physical Surface("contact_surface") = {1, 2, 4, 3};
diff --git a/test/test_contact/hertz_3D.msh b/test/test_contact/hertz_3D.msh
deleted file mode 100644
index f6016cdc7..000000000
--- a/test/test_contact/hertz_3D.msh
+++ /dev/null
@@ -1,1390 +0,0 @@
-$MeshFormat
-2.2 0 8
-$EndMeshFormat
-$PhysicalNames
-5
-2 1 "top_surface"
-2 2 "rigid_surface"
-2 5 "contact_surface"
-3 3 "top_body"
-3 4 "bottom_body"
-$EndPhysicalNames
-$Nodes
-255
-1 0 0.001000000000000001 0
-2 0.5 0.501 0
-3 -0.5 0.501 0
-4 0 0.501 -0.5
-5 0 0.501 0.5
-6 0.5 0 0
-7 -0.5 0 0
-8 0 0 -0.5
-9 0 0 0.5
-10 0 -0.4 0.5
-11 0.5 -0.4 0
-12 0 -0.4 -0.5
-13 -0.5 -0.4 0
-14 -0.4730796551792242 0.3391493285293314 0
-15 -0.4135075340975027 0.2199101224792991 0
-16 -0.3433344173611988 0.1375148175575157 0
-17 -0.2744210546535532 0.08303698158469625 0
-18 -0.2121938879102612 0.04825972795262901 0
-19 -0.1584897754141341 0.02678381397386137 0
-20 -0.1133366829850978 0.01401458308288589 0
-21 -0.07595969997654682 0.006803557297836271 0
-22 -0.04530856472185216 0.003057097688052457 0
-23 -0.02031411946831165 0.001412833881586639 0
-24 0.02031411946826269 0.001412833881584641 0
-25 0.04530856472172527 0.003057097688040911 0
-26 0.07595969997632691 0.006803557297802465 0
-27 0.1133366829847357 0.01401458308280162 0
-28 0.1584897754135451 0.02678381397366447 0
-29 0.212193887909383 0.04825972795221739 0
-30 0.2744210546523341 0.08303698158389583 0
-31 0.3433344173596708 0.1375148175560723 0
-32 0.4135075340964653 0.219910122477773 0
-33 0.4730796551788679 0.3391493285282898 0
-34 0 0.3391493285293314 0.4730796551792242
-35 0 0.2199101224792991 0.4135075340975027
-36 0 0.1375148175575157 0.3433344173611988
-37 0 0.08303698158469625 0.2744210546535532
-38 0 0.04825972795262901 0.2121938879102612
-39 0 0.02678381397386137 0.1584897754141341
-40 0 0.01401458308288589 0.1133366829850978
-41 0 0.006803557297836271 0.07595969997654682
-42 0 0.003057097688052457 0.04530856472185216
-43 0 0.001412833881586639 0.02031411946831165
-44 0 0.001412833881584641 -0.02031411946826269
-45 0 0.003057097688040911 -0.04530856472172527
-46 0 0.006803557297802465 -0.07595969997632691
-47 0 0.01401458308280162 -0.1133366829847357
-48 0 0.02678381397366447 -0.1584897754135451
-49 0 0.04825972795221739 -0.212193887909383
-50 0 0.08303698158389583 -0.2744210546523341
-51 0 0.1375148175560723 -0.3433344173596708
-52 0 0.219910122477773 -0.4135075340964653
-53 0 0.3391493285282898 -0.4730796551788679
-54 -0.4619397662558402 0.501 0.1913417161820697
-55 -0.3535533905939495 0.501 0.353553390592598
-56 -0.1913417161829417 0.501 0.461939766255479
-57 0.1913417161820697 0.501 0.4619397662558402
-58 0.353553390592598 0.501 0.3535533905939495
-59 0.461939766255479 0.501 0.1913417161829417
-60 0.4619397662558402 0.501 -0.1913417161820697
-61 0.3535533905939495 0.501 -0.353553390592598
-62 0.1913417161829417 0.501 -0.461939766255479
-63 -0.1913417161820697 0.501 -0.4619397662558402
-64 -0.353553390592598 0.501 -0.3535533905939495
-65 -0.461939766255479 0.501 -0.1913417161829417
-66 -0.3535533905939495 0 0.353553390592598
-67 0.353553390592598 0 0.3535533905939495
-68 0.3535533905939495 0 -0.353553390592598
-69 -0.353553390592598 0 -0.3535533905939495
-70 0.353553390592598 -0.4 0.3535533905939495
-71 0.3535533905939495 -0.4 -0.353553390592598
-72 -0.353553390592598 -0.4 -0.3535533905939495
-73 -0.3535533905939495 -0.4 0.353553390592598
-74 0.2165895618827998 0.06304866863627323 0.1062430846698083
-75 0.08507612113069998 0.0223838080273715 0.1169982666323503
-76 0.0846496262749751 0.01073916017282484 0.04978704353001893
-77 0.435265769256691 0.3283326324163895 0.175298859908236
-78 0.02173485398373546 0.002247690878807052 0.02781600741630191
-79 0.142473318791986 0.05013353132222681 0.1625447041722115
-80 0.2985939223752105 0.114770018032847 0.108018843496121
-81 0.2144708024194287 0.1055379000491655 0.2182017470416827
-82 0.3276664822504659 0.212628598944634 0.2438782718139735
-83 0.06493565406722934 0.03665849747010214 0.1736960847547749
-84 0.3930792848983679 0.2096583370949671 0.1029985982405483
-85 0.218004800845571 0.2054225722847053 0.3392755385133044
-86 0.05041052466017076 0.004917714927704875 0.03689370462472565
-87 0.03972712688834505 0.009537065674900647 0.08298156164932304
-88 0.03310469885666096 0.01785529780762651 0.124399661000553
-89 0.09941879446251915 0.06565090839625876 0.2249156992017602
-90 0.1471792920422236 0.02743973011055395 0.0638664761528681
-91 0.3241323405583345 0.3676838435152894 0.3566020586372434
-92 0.02250560223639071 0.004431491246393304 0.05397419737426968
-93 0.2524847100343562 0.0728797949699565 0.05444778456375094
-94 0.127754499309493 0.3226606072892193 0.4493037379253935
-95 0.4830665977541143 0.4141165073472678 0.09538302175296909
-96 0.1051649012996272 0.1909898993411952 0.3779339638404537
-97 0.1109313791979213 0.1205736235044582 0.3049098246625045
-98 0.07943790904334799 0.01331155022808822 -0.07648264225227989
-99 0.0583776521460639 0.005047450098916662 -0.02496233115168833
-100 0.1753803791094287 0.3283743344530903 -0.4352494712436991
-101 0.02665149278251632 0.002306374904515129 -0.02437962718310969
-102 0.1598404770656313 0.05054565865026095 -0.1467716193635684
-103 0.121149297385937 0.1137010990910994 -0.2920999984554115
-104 0.2279890976830623 0.111064948085316 -0.2144099499229356
-105 0.244160192363017 0.2127582935383042 -0.3275706322631871
-106 0.1934843105317411 0.04480564886414079 -0.06671233446514353
-107 0.1030044314052508 0.2096640013795568 -0.3930819545828962
-108 0.3513190686707289 0.2152035012110137 -0.2118850472975584
-109 0.0509144780257505 0.006344858867574577 -0.05219202313213744
-110 0.08829164278504546 0.01005906077221003 -0.03437411823528548
-111 0.235555599243274 0.07645386245321412 -0.1194744188487546
-112 0.08945771689221538 0.02714909775985408 -0.1321462800635411
-113 0.1277721006368913 0.02199906977998684 -0.06505689161955271
-114 0.3570264334538266 0.3679409264307405 -0.3237706113224776
-115 0.03765283241446835 0.01561902179781272 -0.1139630212422248
-116 0.09540358124300211 0.4141274653617582 -0.4830645085405648
-117 0.4503344982968038 0.3259921914102403 -0.128728810203373
-118 0.08169438220288008 0.05585563909499192 -0.2125382927167752
-119 0.150084641871484 0.07765329778001479 -0.2196637657734464
-120 0.04228884034430652 0.03174559991136355 -0.1673677447412961
-121 0.3054291477580638 0.1197251521265316 -0.1065012961369314
-122 0.3832532333870211 0.1938327003388854 -0.09362269552460328
-123 0.2462961650705099 0.06994080458893132 -0.05938155541177966
-124 -0.2110519866857369 0.06418122806651344 -0.1210223921533704
-125 -0.08266448192845306 0.02294188860808999 -0.1209422405940145
-126 -0.08927354817570843 0.01458704592141646 -0.07370665981215827
-127 -0.4352363344237281 0.3283232494088527 -0.1753626898820825
-128 -0.140256197961748 0.05136640413852644 -0.1678029451648452
-129 -0.2980095084395045 0.1152031909362835 -0.1111357503051973
-130 -0.2100257933731645 0.1096012775866648 -0.2295565425144355
-131 -0.1260029488506564 0.01924803627921851 -0.04514756175154669
-132 -0.3274916753321522 0.2126469863019327 -0.2441346802061977
-133 -0.3930624642388476 0.2096382202713128 -0.1030058858503559
-134 -0.1377414157094548 0.03113853921493565 -0.1012793664439137
-135 -0.1837584330923711 0.03932459639539482 -0.05557571388620624
-136 -0.04481392763519742 0.00988195154271021 -0.08243042138319094
-137 -0.2094740885420212 0.2149426441037691 -0.3525504153552319
-138 -0.07521605699446073 0.00791551692341036 -0.03478846531967798
-139 -0.06531543207173005 0.03648831904394434 -0.1730976388881802
-140 -0.02675645878115182 0.003107347545271977 -0.03724242936608655
-141 -0.09583227149044218 0.07055155942353086 -0.2356487125920023
-142 -0.03888821862350794 0.01985250619428225 -0.1303257290667006
-143 -0.3242855760349301 0.3710830892471844 -0.3577156153652485
-144 -0.2382429598580649 0.0653238881213587 -0.0585373181515702
-145 -0.1077486976584885 0.1268390580246744 -0.3136778724313156
-146 -0.4830630802292958 0.414114472302875 -0.095398981106598
-147 -0.1463026782018779 0.3487538448363644 -0.4532291193081574
-148 -0.0811582162331508 0.2212159869637915 -0.406367136942947
-149 -0.1276107561129365 0.06593723234649607 0.2107982047503202
-150 -0.1220801448173375 0.02365951772000219 0.08510289194896387
-151 -0.05307174182177589 0.01107310412048446 0.08458739216848449
-152 -0.05169687645593012 0.005011266150083793 0.03636768976244218
-153 -0.1928282823974884 0.3176820155563101 0.4233341116507593
-154 -0.02352210971946236 0.002276959252752064 0.02687078305826674
-155 -0.1631188237662109 0.04753007216550154 0.1332564215447143
-156 -0.1049003239427436 0.1147641772996066 0.2996961983403488
-157 -0.2404700989938842 0.1114880991445034 0.2011333154447799
-158 -0.2212883920065129 0.182065242614978 0.3151381730208657
-159 -0.1709264827687797 0.03396832027046554 0.05162894166360223
-160 -0.102998050604012 0.2096580968951863 0.3930792503644001
-161 -0.0933916370338518 0.02991688777820761 0.139135558041672
-162 -0.08383120440708541 0.01050095183397221 0.0488161132811513
-163 -0.05261999367637136 0.03979035590894975 0.185786976031436
-164 -0.3425569736617763 0.2168003917822398 0.2277834552476467
-165 -0.02597937104259768 0.004542856594365485 0.05343572813902969
-166 -0.1243863629557978 0.01782384115537544 0.03269299978256259
-167 -0.03848928023711887 0.0219340374716438 0.1378926352406396
-168 -0.3538544094545784 0.3698995952023901 0.328023994200812
-169 -0.05762953958337545 0.06545538587521432 0.2387042632093104
-170 -0.3156983064741865 0.1284734616857344 0.1075107322127452
-171 -0.2534710249002152 0.07670560197956588 0.075674984932353
-172 -0.0954136687094799 0.4141335181522915 0.4830636046679561
-173 -0.4494105540238104 0.3264964368315083 0.1325845404770558
-174 -0.1777405304838007 0.1142354697779946 0.2623385255456938
-175 -0.2887756817473827 0.263871202151006 0.3322326577295273
-176 -0.3836700782387754 0.1958091381423351 0.09826397561073739
-177 0 0.501 0
-178 0.25 0.501 -0.04972809184478087
-179 -0.25 0.501 0.04972809184478087
-180 -0.04051704835486511 0.501 -0.2036929572993333
-181 0.0405170483548651 0.501 0.2036929572993333
-182 -0.1657176666716914 0.501 0.2480140149160559
-183 0.2480140149160559 0.501 0.1657176666716914
-184 0.1657176666716914 0.501 -0.2480140149160559
-185 -0.2480140149160559 0.501 -0.1657176666716914
-186 -0.3123259623660284 0.501 0.1896088164961787
-187 0.1916334594949479 0.501 0.3084633471684052
-188 0.3123259623660284 0.501 -0.1896088164961787
-189 -0.1916334594949479 0.501 -0.3084633471684052
-190 0.3611117168052297 0.501 0.05565373344995961
-191 -0.3611117168052297 0.501 -0.05565373344995961
-192 0.05900241851885195 0.501 -0.3583179230142754
-193 -0.05900241851885195 0.501 0.3583179230142754
-194 0.1412841281997918 0.501 0.05700179487148319
-195 0.1087158718002082 0.501 -0.1067298867162641
-196 -0.1087158718002082 0.501 0.1067298867162641
-197 -0.1412841281997918 0.501 -0.05700179487148319
-198 0.3770754890854197 0.501 -0.07500497821461394
-199 -0.3770754890854197 0.501 0.07500497821461394
-200 -0.07566646484542018 0.501 -0.3804010069479554
-201 0.07289796110260614 0.501 0.3664827987475708
-202 0 0 -1.806251016219083e-18
-203 0.2322100814617679 0 0.06581527448811327
-204 -0.2322100814617679 -0 -0.06581527448811327
-205 0.05072002804593711 0 -0.2250941140464751
-206 -0.05072002804593711 0 0.2250941140464751
-207 0.4619397662554605 -0.2 0.1913417161829864
-208 0.1913417161821035 -0.2 0.4619397662558262
-209 0.1913417161829864 -0.2 -0.4619397662554605
-210 0.4619397662558262 -0.2 -0.1913417161821035
-211 -0.4619397662554605 -0.2 -0.1913417161829864
-212 -0.1913417161821035 -0.2 -0.4619397662558262
-213 -0.1913417161829864 -0.2 0.4619397662554605
-214 -0.4619397662558262 -0.2 0.1913417161821035
-215 0 -0.4 1.806251016219083e-18
-216 -0.06581527448811327 -0.4 0.2322100814617679
-217 0.2283031375248289 -0.4 0.04920727987091737
-218 0.02700372320841774 -0.4 -0.2216015347510933
-219 -0.2197521824364575 -0.4 -0.02832376079942922
-220 0.02299718301224581 0.2511445834658444 0.02064819150212004
-221 0.02194450210373 0.1558073109730609 0.01514374991128849
-222 -0.02485952661308913 0.1531560090712724 -0.1199315050310883
-223 -0.1553905389363228 0.1943319430752262 -0.004569572116810727
-224 -0.01156008344953839 0.1370822854228775 0.1506733783124888
-225 0.008905847012670125 0.06277424322096692 0.008905847012691584
-226 0.1731655237155815 0.2168151339181799 0.03248019351003553
-227 0.1312066933962472 0.2845147299571598 -0.1557389243163806
-228 -0.08046528840242292 0.0986993867277498 0.01967856046728051
-229 -0.1623284412415345 0.301149813315956 0.1500296229906809
-230 0.06902243494332924 0.09441738725982655 -0.04591735206136249
-231 0.106799202159151 0.3483404575033952 0.2267422402623986
-232 -0.1111891196310109 0.32507859528968 -0.1294339775742908
-233 -0.01817237001894838 0.07179524020414875 -0.05287087375340723
-234 0.05796725988949247 0.09665870038904446 0.07542504674899228
-235 -0.02317077652148489 0.07195625057658296 0.0697879449538196
-236 -0.1068697031933587 0.09578305895319485 -0.08258796665385035
-237 0.09154941239736276 0.1669143618780818 -0.1257191456718838
-238 -0.2830123577922874 0.3262901965126527 -0.02285002534186089
-239 0.05493031621402608 0.05159530137005672 -0.007074043664281555
-240 0.007409151552480313 0.2463137348284158 -0.2364951862329169
-241 -0.0457463814862057 0.2482209345843405 0.2417535833456651
-242 0.01575203213457178 0.08545736877115366 -0.1175148703607351
-243 0.134112498409321 0.3505667337798891 -0.006334280976417715
-244 -0.03371829664129062 0.06032435460162649 0.01316038227945489
-245 -0.1402825501855814 0.1474920709316569 0.1273619985264371
-246 0.2675911824086226 0.3276952401642054 0.1270432913306665
-247 -0.004285758068775724 0.03158228706091545 -0.01392868123516653
-248 -0.1495106567958615 0.1913973904478573 -0.1444242089573229
-249 0.1757898240916013 0.1518458765706439 -0.0692618548827785
-250 0.2998421209408237 0.3177115680111848 -0.05367116740470231
-251 0.1147909573751037 0.176576726700094 0.1599536503429053
-252 -0.06466395022322634 0.3641759080245217 0.05838224552096206
-253 0.1290436097322548 0.09134243330132084 0.01187750410539126
-254 -0.07068034381074993 0.2178519946864788 0.08072662271773798
-255 0.01599560954945456 0.03940698948097516 0.03838739241997892
-$EndNodes
-$Elements
-1118
-1 2 2 5 1 43 1 24
-2 2 2 5 1 95 33 2
-3 2 2 5 1 59 95 2
-4 2 2 5 1 34 94 5
-5 2 2 5 1 94 57 5
-6 2 2 5 1 78 24 25
-7 2 2 5 1 43 24 78
-8 2 2 5 1 86 25 26
-9 2 2 5 1 25 86 78
-10 2 2 5 1 76 26 27
-11 2 2 5 1 76 86 26
-12 2 2 5 1 27 28 90
-13 2 2 5 1 90 76 27
-14 2 2 5 1 28 29 90
-15 2 2 5 1 93 29 30
-16 2 2 5 1 29 74 90
-17 2 2 5 1 93 74 29
-18 2 2 5 1 30 31 80
-19 2 2 5 1 93 30 80
-20 2 2 5 1 84 31 32
-21 2 2 5 1 31 84 80
-22 2 2 5 1 33 84 32
-23 2 2 5 1 33 95 77
-24 2 2 5 1 33 77 84
-25 2 2 5 1 94 34 35
-26 2 2 5 1 36 96 35
-27 2 2 5 1 35 96 94
-28 2 2 5 1 37 97 36
-29 2 2 5 1 36 97 96
-30 2 2 5 1 38 89 37
-31 2 2 5 1 89 97 37
-32 2 2 5 1 83 38 39
-33 2 2 5 1 38 83 89
-34 2 2 5 1 88 39 40
-35 2 2 5 1 39 88 83
-36 2 2 5 1 87 40 41
-37 2 2 5 1 88 40 87
-38 2 2 5 1 92 41 42
-39 2 2 5 1 41 92 87
-40 2 2 5 1 42 43 78
-41 2 2 5 1 78 92 42
-42 2 2 5 1 91 58 57
-43 2 2 5 1 94 91 57
-44 2 2 5 1 91 59 58
-45 2 2 5 1 77 59 91
-46 2 2 5 1 95 59 77
-47 2 2 5 1 92 86 87
-48 2 2 5 1 78 86 92
-49 2 2 5 1 88 87 75
-50 2 2 5 1 75 87 76
-51 2 2 5 1 87 86 76
-52 2 2 5 1 81 97 89
-53 2 2 5 1 89 83 79
-54 2 2 5 1 89 79 81
-55 2 2 5 1 82 91 85
-56 2 2 5 1 81 82 85
-57 2 2 5 1 82 77 91
-58 2 2 5 1 82 80 84
-59 2 2 5 1 81 80 82
-60 2 2 5 1 82 84 77
-61 2 2 5 1 94 85 91
-62 2 2 5 1 96 85 94
-63 2 2 5 1 85 96 97
-64 2 2 5 1 97 81 85
-65 2 2 5 1 74 93 80
-66 2 2 5 1 81 74 80
-67 2 2 5 1 75 90 79
-68 2 2 5 1 76 90 75
-69 2 2 5 1 90 74 79
-70 2 2 5 1 88 75 83
-71 2 2 5 1 83 75 79
-72 2 2 5 1 74 81 79
-73 2 2 5 2 1 44 24
-74 2 2 5 2 33 117 2
-75 2 2 5 2 117 60 2
-76 2 2 5 2 116 53 4
-77 2 2 5 2 62 116 4
-78 2 2 5 2 25 24 101
-79 2 2 5 2 24 44 101
-80 2 2 5 2 25 99 26
-81 2 2 5 2 25 101 99
-82 2 2 5 2 110 27 26
-83 2 2 5 2 99 110 26
-84 2 2 5 2 27 113 28
-85 2 2 5 2 27 110 113
-86 2 2 5 2 106 29 28
-87 2 2 5 2 113 106 28
-88 2 2 5 2 29 123 30
-89 2 2 5 2 29 106 123
-90 2 2 5 2 30 121 31
-91 2 2 5 2 30 123 121
-92 2 2 5 2 31 122 32
-93 2 2 5 2 31 121 122
-94 2 2 5 2 117 33 32
-95 2 2 5 2 32 122 117
-96 2 2 5 2 101 44 45
-97 2 2 5 2 46 109 45
-98 2 2 5 2 45 109 101
-99 2 2 5 2 115 46 47
-100 2 2 5 2 46 115 109
-101 2 2 5 2 115 47 48
-102 2 2 5 2 120 48 49
-103 2 2 5 2 120 115 48
-104 2 2 5 2 118 49 50
-105 2 2 5 2 118 120 49
-106 2 2 5 2 50 51 103
-107 2 2 5 2 118 50 103
-108 2 2 5 2 107 51 52
-109 2 2 5 2 51 107 103
-110 2 2 5 2 53 107 52
-111 2 2 5 2 53 100 107
-112 2 2 5 2 53 116 100
-113 2 2 5 2 114 61 60
-114 2 2 5 2 117 114 60
-115 2 2 5 2 114 62 61
-116 2 2 5 2 100 62 114
-117 2 2 5 2 116 62 100
-118 2 2 5 2 98 112 113
-119 2 2 5 2 113 112 102
-120 2 2 5 2 113 110 98
-121 2 2 5 2 106 113 102
-122 2 2 5 2 112 118 102
-123 2 2 5 2 120 118 112
-124 2 2 5 2 119 118 103
-125 2 2 5 2 118 119 102
-126 2 2 5 2 111 123 106
-127 2 2 5 2 123 111 121
-128 2 2 5 2 111 102 104
-129 2 2 5 2 104 121 111
-130 2 2 5 2 111 106 102
-131 2 2 5 2 98 115 112
-132 2 2 5 2 112 115 120
-133 2 2 5 2 104 119 103
-134 2 2 5 2 119 104 102
-135 2 2 5 2 105 100 114
-136 2 2 5 2 105 114 108
-137 2 2 5 2 117 108 114
-138 2 2 5 2 110 99 109
-139 2 2 5 2 101 109 99
-140 2 2 5 2 104 103 105
-141 2 2 5 2 104 105 108
-142 2 2 5 2 105 107 100
-143 2 2 5 2 105 103 107
-144 2 2 5 2 108 122 121
-145 2 2 5 2 122 108 117
-146 2 2 5 2 110 109 98
-147 2 2 5 2 115 98 109
-148 2 2 5 2 121 104 108
-149 2 2 5 3 126 134 125
-150 2 2 5 3 136 126 125
-151 2 2 5 3 125 134 128
-152 2 2 5 3 139 125 128
-153 2 2 5 3 125 142 136
-154 2 2 5 3 142 125 139
-155 2 2 5 3 126 131 134
-156 2 2 5 3 126 138 131
-157 2 2 5 3 136 138 126
-158 2 2 5 3 132 133 127
-159 2 2 5 3 132 127 143
-160 2 2 5 3 14 127 133
-161 2 2 5 3 127 65 143
-162 2 2 5 3 14 146 127
-163 2 2 5 3 146 65 127
-164 2 2 5 3 124 130 128
-165 2 2 5 3 134 124 128
-166 2 2 5 3 130 124 129
-167 2 2 5 3 124 144 129
-168 2 2 5 3 135 124 134
-169 2 2 5 3 144 124 135
-170 2 2 5 3 141 128 130
-171 2 2 5 3 128 141 139
-172 2 2 5 3 130 129 132
-173 2 2 5 3 132 129 133
-174 2 2 5 3 16 133 129
-175 2 2 5 3 144 17 129
-176 2 2 5 3 17 16 129
-177 2 2 5 3 130 132 137
-178 2 2 5 3 137 145 130
-179 2 2 5 3 145 141 130
-180 2 2 5 3 134 131 135
-181 2 2 5 3 135 131 19
-182 2 2 5 3 138 20 131
-183 2 2 5 3 19 131 20
-184 2 2 5 3 132 143 137
-185 2 2 5 3 14 133 15
-186 2 2 5 3 133 16 15
-187 2 2 5 3 135 18 144
-188 2 2 5 3 135 19 18
-189 2 2 5 3 140 138 136
-190 2 2 5 3 136 46 140
-191 2 2 5 3 142 47 136
-192 2 2 5 3 136 47 46
-193 2 2 5 3 147 137 143
-194 2 2 5 3 137 148 145
-195 2 2 5 3 148 137 147
-196 2 2 5 3 140 22 138
-197 2 2 5 3 20 138 21
-198 2 2 5 3 138 22 21
-199 2 2 5 3 49 139 141
-200 2 2 5 3 139 48 142
-201 2 2 5 3 139 49 48
-202 2 2 5 3 140 23 22
-203 2 2 5 3 44 23 140
-204 2 2 5 3 44 140 45
-205 2 2 5 3 140 46 45
-206 2 2 5 3 50 141 145
-207 2 2 5 3 50 49 141
-208 2 2 5 3 142 48 47
-209 2 2 5 3 147 143 63
-210 2 2 5 3 143 64 63
-211 2 2 5 3 143 65 64
-212 2 2 5 3 144 18 17
-213 2 2 5 3 51 145 148
-214 2 2 5 3 50 145 51
-215 2 2 5 3 146 14 3
-216 2 2 5 3 65 146 3
-217 2 2 5 3 147 53 148
-218 2 2 5 3 53 147 4
-219 2 2 5 3 147 63 4
-220 2 2 5 3 51 148 52
-221 2 2 5 3 148 53 52
-222 2 2 5 3 44 1 23
-223 2 2 5 4 151 161 150
-224 2 2 5 4 167 161 151
-225 2 2 5 4 161 149 155
-226 2 2 5 4 150 161 155
-227 2 2 5 4 163 149 161
-228 2 2 5 4 161 167 163
-229 2 2 5 4 164 170 157
-230 2 2 5 4 170 171 157
-231 2 2 5 4 164 176 170
-232 2 2 5 4 16 170 176
-233 2 2 5 4 17 171 170
-234 2 2 5 4 17 170 16
-235 2 2 5 4 174 157 149
-236 2 2 5 4 157 174 158
-237 2 2 5 4 149 157 155
-238 2 2 5 4 171 155 157
-239 2 2 5 4 157 158 164
-240 2 2 5 4 152 165 151
-241 2 2 5 4 162 152 151
-242 2 2 5 4 165 41 151
-243 2 2 5 4 150 162 151
-244 2 2 5 4 40 167 151
-245 2 2 5 4 151 41 40
-246 2 2 5 4 168 175 153
-247 2 2 5 4 175 158 153
-248 2 2 5 4 175 168 164
-249 2 2 5 4 158 175 164
-250 2 2 5 4 158 160 153
-251 2 2 5 4 34 153 160
-252 2 2 5 4 153 56 168
-253 2 2 5 4 34 172 153
-254 2 2 5 4 172 56 153
-255 2 2 5 4 156 174 149
-256 2 2 5 4 174 156 158
-257 2 2 5 4 152 154 165
-258 2 2 5 4 22 154 152
-259 2 2 5 4 152 162 21
-260 2 2 5 4 22 152 21
-261 2 2 5 4 159 150 155
-262 2 2 5 4 171 159 155
-263 2 2 5 4 166 162 150
-264 2 2 5 4 166 150 159
-265 2 2 5 4 166 20 162
-266 2 2 5 4 19 166 159
-267 2 2 5 4 166 19 20
-268 2 2 5 4 165 154 42
-269 2 2 5 4 41 165 42
-270 2 2 5 4 158 156 160
-271 2 2 5 4 36 160 156
-272 2 2 5 4 34 160 35
-273 2 2 5 4 160 36 35
-274 2 2 5 4 176 164 173
-275 2 2 5 4 173 164 168
-276 2 2 5 4 15 176 173
-277 2 2 5 4 16 176 15
-278 2 2 5 4 149 169 156
-279 2 2 5 4 169 149 163
-280 2 2 5 4 169 37 156
-281 2 2 5 4 37 36 156
-282 2 2 5 4 173 168 54
-283 2 2 5 4 168 55 54
-284 2 2 5 4 168 56 55
-285 2 2 5 4 163 38 169
-286 2 2 5 4 169 38 37
-287 2 2 5 4 172 34 5
-288 2 2 5 4 56 172 5
-289 2 2 5 4 14 173 3
-290 2 2 5 4 173 54 3
-291 2 2 5 4 173 14 15
-292 2 2 5 4 23 154 22
-293 2 2 5 4 23 43 154
-294 2 2 5 4 43 42 154
-295 2 2 5 4 39 163 167
-296 2 2 5 4 163 39 38
-297 2 2 5 4 171 18 159
-298 2 2 5 4 18 171 17
-299 2 2 5 4 40 39 167
-300 2 2 5 4 162 20 21
-301 2 2 5 4 159 18 19
-302 2 2 5 4 1 43 23
-303 2 2 1 5 177 196 181
-304 2 2 1 5 177 197 196
-305 2 2 1 5 179 196 197
-306 2 2 1 5 179 182 196
-307 2 2 1 5 181 196 182
-308 2 2 1 5 179 191 199
-309 2 2 1 5 3 199 191
-310 2 2 1 5 179 199 186
-311 2 2 1 5 54 186 199
-312 2 2 1 5 3 54 199
-313 2 2 1 5 178 183 190
-314 2 2 1 5 178 194 183
-315 2 2 1 5 178 184 195
-316 2 2 1 5 178 195 194
-317 2 2 1 5 178 198 188
-318 2 2 1 5 178 190 198
-319 2 2 1 5 178 188 184
-320 2 2 1 5 180 200 189
-321 2 2 1 5 180 189 185
-322 2 2 1 5 63 189 200
-323 2 2 1 5 64 185 189
-324 2 2 1 5 63 64 189
-325 2 2 1 5 179 185 191
-326 2 2 1 5 65 191 185
-327 2 2 1 5 3 191 65
-328 2 2 1 5 177 195 180
-329 2 2 1 5 177 180 197
-330 2 2 1 5 177 194 195
-331 2 2 1 5 177 181 194
-332 2 2 1 5 180 192 200
-333 2 2 1 5 180 184 192
-334 2 2 1 5 180 195 184
-335 2 2 1 5 180 185 197
-336 2 2 1 5 179 186 182
-337 2 2 1 5 55 182 186
-338 2 2 1 5 54 55 186
-339 2 2 1 5 59 190 183
-340 2 2 1 5 181 187 183
-341 2 2 1 5 181 183 194
-342 2 2 1 5 58 183 187
-343 2 2 1 5 58 59 183
-344 2 2 1 5 179 197 185
-345 2 2 1 5 4 200 192
-346 2 2 1 5 62 192 184
-347 2 2 1 5 4 192 62
-348 2 2 1 5 60 188 198
-349 2 2 1 5 2 198 190
-350 2 2 1 5 2 60 198
-351 2 2 1 5 4 63 200
-352 2 2 1 5 61 184 188
-353 2 2 1 5 60 61 188
-354 2 2 1 5 64 65 185
-355 2 2 1 5 2 190 59
-356 2 2 1 5 181 193 201
-357 2 2 1 5 181 182 193
-358 2 2 1 5 181 201 187
-359 2 2 1 5 61 62 184
-360 2 2 1 5 5 201 193
-361 2 2 1 5 56 193 182
-362 2 2 1 5 5 193 56
-363 2 2 1 5 57 187 201
-364 2 2 1 5 57 58 187
-365 2 2 1 5 5 57 201
-366 2 2 1 5 55 56 182
-367 2 2 2 6 202 206 203
-368 2 2 2 6 202 203 205
-369 2 2 2 6 202 204 206
-370 2 2 2 6 202 205 204
-371 2 2 2 6 206 67 203
-372 2 2 2 6 68 205 203
-373 2 2 2 6 6 203 67
-374 2 2 2 6 6 68 203
-375 2 2 2 6 66 206 204
-376 2 2 2 6 9 206 66
-377 2 2 2 6 9 67 206
-378 2 2 2 6 205 69 204
-379 2 2 2 6 7 66 204
-380 2 2 2 6 7 204 69
-381 2 2 2 6 8 205 68
-382 2 2 2 6 8 69 205
-383 4 2 3 1 45 101 109 247
-384 4 2 3 1 220 224 241 254
-385 4 2 3 1 220 243 232 252
-386 4 2 3 1 231 243 220 252
-387 4 2 3 1 200 232 147 240
-388 4 2 3 1 227 232 220 243
-389 4 2 3 1 108 188 227 250
-390 4 2 3 1 200 180 232 240
-391 4 2 3 1 101 239 109 247
-392 4 2 3 1 40 39 88 235
-393 4 2 3 1 220 241 231 252
-394 4 2 3 1 170 171 17 223
-395 4 2 3 1 137 147 232 240
-396 4 2 3 1 220 221 224 254
-397 4 2 3 1 195 232 227 243
-398 4 2 3 1 189 147 200 232
-399 4 2 3 1 137 148 147 240
-400 4 2 3 1 24 1 43 247
-401 4 2 3 1 170 171 223 245
-402 4 2 3 1 148 52 53 240
-403 4 2 3 1 230 237 226 249
-404 4 2 3 1 180 189 200 232
-405 4 2 3 1 200 53 192 240
-406 4 2 3 1 147 148 53 240
-407 4 2 3 1 20 21 138 228
-408 4 2 3 1 107 53 52 240
-409 4 2 3 1 178 227 188 250
-410 4 2 3 1 25 24 78 255
-411 4 2 3 1 100 227 184 240
-412 4 2 3 1 185 132 232 238
-413 4 2 3 1 45 109 233 247
-414 4 2 3 1 149 169 224 241
-415 4 2 3 1 198 33 190 250
-416 4 2 3 1 220 227 226 237
-417 4 2 3 1 21 138 228 244
-418 4 2 3 1 198 178 188 250
-419 4 2 3 1 147 53 200 240
-420 4 2 3 1 198 188 117 250
-421 4 2 3 1 232 238 132 248
-422 4 2 3 1 150 151 162 235
-423 4 2 3 1 137 240 232 248
-424 4 2 3 1 35 34 231 241
-425 4 2 3 1 196 181 229 252
-426 4 2 3 1 227 232 180 240
-427 4 2 3 1 180 200 192 240
-428 4 2 3 1 39 38 83 224
-429 4 2 3 1 167 39 40 235
-430 4 2 3 1 226 237 227 249
-431 4 2 3 1 17 144 129 223
-432 4 2 3 1 108 117 188 250
-433 4 2 3 1 161 224 167 235
-434 4 2 3 1 222 223 220 232
-435 4 2 3 1 186 229 173 238
-436 4 2 3 1 195 177 232 243
-437 4 2 3 1 192 100 184 240
-438 4 2 3 1 167 224 39 235
-439 4 2 3 1 186 173 199 238
-440 4 2 3 1 232 243 177 252
-441 4 2 3 1 166 20 19 228
-442 4 2 3 1 186 199 179 238
-443 4 2 3 1 174 241 149 245
-444 4 2 3 1 224 245 241 254
-445 4 2 3 1 192 53 100 240
-446 4 2 3 1 180 184 227 240
-447 4 2 3 1 180 227 195 232
-448 4 2 3 1 150 162 228 235
-449 4 2 3 1 137 145 240 248
-450 4 2 3 1 46 45 109 233
-451 4 2 3 1 83 234 224 251
-452 4 2 3 1 167 163 39 224
-453 4 2 3 1 137 232 132 248
-454 4 2 3 1 186 164 173 229
-455 4 2 3 1 157 229 174 245
-456 4 2 3 1 174 229 241 245
-457 4 2 3 1 226 231 220 251
-458 4 2 3 1 18 135 144 223
-459 4 2 3 1 153 229 182 241
-460 4 2 3 1 186 179 229 238
-461 4 2 3 1 225 221 233 244
-462 4 2 3 1 173 229 176 238
-463 4 2 3 1 161 163 167 224
-464 4 2 3 1 223 229 245 254
-465 4 2 3 1 107 100 53 240
-466 4 2 3 1 178 243 227 250
-467 4 2 3 1 114 108 188 227
-468 4 2 3 1 175 153 158 229
-469 4 2 3 1 220 231 226 243
-470 4 2 3 1 174 156 149 241
-471 4 2 3 1 149 241 224 245
-472 4 2 3 1 30 93 80 226
-473 4 2 3 1 109 239 233 247
-474 4 2 3 1 221 226 234 253
-475 4 2 3 1 95 190 33 246
-476 4 2 3 1 166 19 159 228
-477 4 2 3 1 40 88 87 235
-478 4 2 3 1 221 230 226 253
-479 4 2 3 1 180 192 184 240
-480 4 2 3 1 198 190 178 250
-481 4 2 3 1 108 249 121 250
-482 4 2 3 1 166 150 162 228
-483 4 2 3 1 164 176 173 229
-484 4 2 3 1 33 246 190 250
-485 4 2 3 1 141 222 240 248
-486 4 2 3 1 41 235 87 255
-487 4 2 3 1 170 176 229 238
-488 4 2 3 1 149 156 169 241
-489 4 2 3 1 182 229 181 241
-490 4 2 3 1 108 227 249 250
-491 4 2 3 1 169 37 224 241
-492 4 2 3 1 141 222 50 240
-493 4 2 3 1 19 223 228 236
-494 4 2 3 1 153 182 193 241
-495 4 2 3 1 223 252 229 254
-496 4 2 3 1 121 108 104 249
-497 4 2 3 1 118 120 112 242
-498 4 2 3 1 161 149 163 224
-499 4 2 3 1 142 136 47 233
-500 4 2 3 1 161 151 150 235
-501 4 2 3 1 153 193 34 241
-502 4 2 3 1 185 127 132 238
-503 4 2 3 1 150 166 159 228
-504 4 2 3 1 170 229 157 245
-505 4 2 3 1 125 139 128 236
-506 4 2 3 1 223 220 252 254
-507 4 2 3 1 153 158 229 241
-508 4 2 3 1 108 227 104 249
-509 4 2 3 1 94 34 201 231
-510 4 2 3 1 24 43 78 255
-511 4 2 3 1 161 224 235 245
-512 4 2 3 1 221 222 230 233
-513 4 2 3 1 132 137 143 232
-514 4 2 3 1 149 169 163 224
-515 4 2 3 1 169 37 38 224
-516 4 2 3 1 139 49 141 222
-517 4 2 3 1 233 239 225 247
-518 4 2 3 1 35 231 96 241
-519 4 2 3 1 132 143 185 232
-520 4 2 3 1 18 144 17 223
-521 4 2 3 1 19 131 135 236
-522 4 2 3 1 226 227 220 243
-523 4 2 3 1 139 142 48 242
-524 4 2 3 1 137 145 148 240
-525 4 2 3 1 186 168 164 229
-526 4 2 3 1 223 220 232 252
-527 4 2 3 1 185 143 189 232
-528 4 2 3 1 21 20 162 228
-529 4 2 3 1 153 193 172 34
-530 4 2 3 1 154 165 42 255
-531 4 2 3 1 86 25 78 255
-532 4 2 3 1 153 34 160 241
-533 4 2 3 1 223 228 221 254
-534 4 2 3 1 193 182 181 241
-535 4 2 3 1 170 176 164 229
-536 4 2 3 1 154 43 247 255
-537 4 2 3 1 141 240 145 248
-538 4 2 3 1 129 238 223 248
-539 4 2 3 1 127 191 146 238
-540 4 2 3 1 141 49 50 222
-541 4 2 3 1 37 36 97 241
-542 4 2 3 1 21 228 162 244
-543 4 2 3 1 171 18 17 223
-544 4 2 3 1 223 232 222 248
-545 4 2 3 1 83 79 75 234
-546 4 2 3 1 196 181 182 229
-547 4 2 3 1 94 35 34 231
-548 4 2 3 1 198 117 33 250
-549 4 2 3 1 28 106 113 253
-550 4 2 3 1 41 40 87 235
-551 4 2 3 1 157 158 174 229
-552 4 2 3 1 114 188 184 227
-553 4 2 3 1 49 120 118 242
-554 4 2 3 1 24 247 43 255
-555 4 2 3 1 20 166 162 228
-556 4 2 3 1 25 239 24 255
-557 4 2 3 1 174 229 158 241
-558 4 2 3 1 154 42 43 255
-559 4 2 3 1 96 35 94 231
-560 4 2 3 1 94 201 187 231
-561 4 2 3 1 150 228 159 245
-562 4 2 3 1 139 49 222 242
-563 4 2 3 1 103 237 227 240
-564 4 2 3 1 29 93 30 226
-565 4 2 3 1 104 227 103 237
-566 4 2 3 1 36 96 97 241
-567 4 2 3 1 101 24 239 247
-568 4 2 3 1 141 50 145 240
-569 4 2 3 1 178 184 188 227
-570 4 2 3 1 53 192 100 116
-571 4 2 3 1 101 24 25 239
-572 4 2 3 1 178 190 246 250
-573 4 2 3 1 178 195 227 243
-574 4 2 3 1 87 235 234 255
-575 4 2 3 1 225 221 234 239
-576 4 2 3 1 104 227 237 249
-577 4 2 3 1 127 146 14 238
-578 4 2 3 1 151 161 167 235
-579 4 2 3 1 21 22 138 244
-580 4 2 3 1 241 245 229 254
-581 4 2 3 1 180 184 195 227
-582 4 2 3 1 77 95 33 246
-583 4 2 3 1 31 30 80 226
-584 4 2 3 1 115 98 112 242
-585 4 2 3 1 175 164 168 229
-586 4 2 3 1 139 48 49 242
-587 4 2 3 1 228 235 162 244
-588 4 2 3 1 86 92 87 255
-589 4 2 3 1 159 228 223 245
-590 4 2 3 1 169 38 163 224
-591 4 2 3 1 227 226 249 250
-592 4 2 3 1 104 103 119 237
-593 4 2 3 1 160 34 35 241
-594 4 2 3 1 221 225 235 244
-595 4 2 3 1 225 239 234 255
-596 4 2 3 1 231 243 194 246
-597 4 2 3 1 180 195 177 232
-598 4 2 3 1 74 80 226 251
-599 4 2 3 1 79 234 83 251
-600 4 2 3 1 113 102 112 230
-601 4 2 3 1 88 234 87 235
-602 4 2 3 1 178 195 184 227
-603 4 2 3 1 136 138 140 233
-604 4 2 3 1 223 238 229 252
-605 4 2 3 1 170 164 157 229
-606 4 2 3 1 230 233 222 242
-607 4 2 3 1 228 233 221 244
-608 4 2 3 1 93 74 80 226
-609 4 2 3 1 233 236 222 242
-610 4 2 3 1 106 28 29 253
-611 4 2 3 1 79 90 75 234
-612 4 2 3 1 1 24 44 247
-613 4 2 3 1 170 16 176 238
-614 4 2 3 1 27 230 110 239
-615 4 2 3 1 163 38 39 224
-616 4 2 3 1 108 114 105 227
-617 4 2 3 1 88 83 75 234
-618 4 2 3 1 97 241 231 251
-619 4 2 3 1 185 191 127 238
-620 4 2 3 1 161 149 224 245
-621 4 2 3 1 224 221 234 235
-622 4 2 3 1 225 244 233 247
-623 4 2 3 1 96 231 97 241
-624 4 2 3 1 178 246 243 250
-625 4 2 3 1 102 112 230 237
-626 4 2 3 1 142 233 47 242
-627 4 2 3 1 199 173 14 238
-628 4 2 3 1 230 233 109 239
-629 4 2 3 1 80 246 226 251
-630 4 2 3 1 127 133 132 238
-631 4 2 3 1 223 232 238 252
-632 4 2 3 1 124 223 236 248
-633 4 2 3 1 181 187 201 231
-634 4 2 3 1 230 237 112 242
-635 4 2 3 1 234 235 225 255
-636 4 2 3 1 24 101 44 247
-637 4 2 3 1 136 46 47 233
-638 4 2 3 1 186 182 168 229
-639 4 2 3 1 44 101 45 247
-640 4 2 3 1 196 177 181 252
-641 4 2 3 1 85 231 91 246
-642 4 2 3 1 169 156 37 241
-643 4 2 3 1 94 187 91 231
-644 4 2 3 1 102 230 113 249
-645 4 2 3 1 223 238 232 248
-646 4 2 3 1 126 131 138 236
-647 4 2 3 1 153 160 158 241
-648 4 2 3 1 82 81 85 251
-649 4 2 3 1 222 237 230 242
-650 4 2 3 1 174 158 156 241
-651 4 2 3 1 154 244 165 255
-652 4 2 3 1 234 239 221 253
-653 4 2 3 1 98 113 112 230
-654 4 2 3 1 226 243 231 246
-655 4 2 3 1 232 240 222 248
-656 4 2 3 1 109 233 230 242
-657 4 2 3 1 183 231 194 246
-658 4 2 3 1 85 94 91 231
-659 4 2 3 1 165 41 42 255
-660 4 2 3 1 1 23 43 247
-661 4 2 3 1 30 121 123 249
-662 4 2 3 1 161 150 155 245
-663 4 2 3 1 185 232 197 238
-664 4 2 3 1 186 164 168 173
-665 4 2 3 1 106 102 113 249
-666 4 2 3 1 227 243 226 250
-667 4 2 3 1 178 194 243 246
-668 4 2 3 1 110 27 113 230
-669 4 2 3 1 109 101 99 239
-670 4 2 3 1 23 154 43 247
-671 4 2 3 1 230 221 239 253
-672 4 2 3 1 221 228 235 254
-673 4 2 3 1 29 226 30 249
-674 4 2 3 1 127 185 132 143
-675 4 2 3 1 177 197 232 252
-676 4 2 3 1 108 114 188 117
-677 4 2 3 1 197 238 232 252
-678 4 2 3 1 98 230 112 242
-679 4 2 3 1 164 175 158 229
-680 4 2 3 1 225 234 221 235
-681 4 2 3 1 86 239 25 255
-682 4 2 3 1 226 249 29 253
-683 4 2 3 1 124 134 128 236
-684 4 2 3 1 103 104 105 227
-685 4 2 3 1 124 135 134 236
-686 4 2 3 1 104 108 105 227
-687 4 2 3 1 179 182 186 229
-688 4 2 3 1 199 191 179 238
-689 4 2 3 1 118 112 237 242
-690 4 2 3 1 102 237 230 249
-691 4 2 3 1 229 238 179 252
-692 4 2 3 1 226 246 231 251
-693 4 2 3 1 145 51 148 240
-694 4 2 3 1 74 81 80 251
-695 4 2 3 1 85 96 94 231
-696 4 2 3 1 36 35 96 241
-697 4 2 3 1 221 235 224 254
-698 4 2 3 1 121 104 111 249
-699 4 2 3 1 157 164 158 229
-700 4 2 3 1 82 85 91 246
-701 4 2 3 1 110 109 99 239
-702 4 2 3 1 221 235 228 244
-703 4 2 3 1 92 41 87 255
-704 4 2 3 1 106 29 249 253
-705 4 2 3 1 101 25 99 239
-706 4 2 3 1 183 181 194 231
-707 4 2 3 1 189 180 185 232
-708 4 2 3 1 97 231 85 251
-709 4 2 3 1 130 145 137 248
-710 4 2 3 1 145 50 51 240
-711 4 2 3 1 196 182 179 229
-712 4 2 3 1 129 133 16 238
-713 4 2 3 1 183 187 181 231
-714 4 2 3 1 102 104 119 237
-715 4 2 3 1 196 229 179 252
-716 4 2 3 1 155 150 159 245
-717 4 2 3 1 157 174 149 245
-718 4 2 3 1 27 26 76 239
-719 4 2 3 1 152 21 162 244
-720 4 2 3 1 133 14 15 238
-721 4 2 3 1 180 177 197 232
-722 4 2 3 1 178 190 183 246
-723 4 2 3 1 176 15 173 238
-724 4 2 3 1 125 128 134 236
-725 4 2 3 1 122 117 108 250
-726 4 2 3 1 148 51 52 240
-727 4 2 3 1 230 249 226 253
-728 4 2 3 1 97 96 85 231
-729 4 2 3 1 127 14 133 238
-730 4 2 3 1 79 83 89 251
-731 4 2 3 1 27 28 113 253
-732 4 2 3 1 165 235 41 255
-733 4 2 3 1 140 45 233 247
-734 4 2 3 1 178 183 194 246
-735 4 2 3 1 84 77 33 246
-736 4 2 3 1 140 45 46 233
-737 4 2 3 1 176 16 15 238
-738 4 2 3 1 136 140 46 233
-739 4 2 3 1 90 76 75 234
-740 4 2 3 1 104 102 111 249
-741 4 2 3 1 124 236 128 248
-742 4 2 3 1 103 118 119 237
-743 4 2 3 1 130 137 132 248
-744 4 2 3 1 87 88 75 234
-745 4 2 3 1 29 30 123 249
-746 4 2 3 1 165 244 235 255
-747 4 2 3 1 222 236 223 248
-748 4 2 3 1 179 191 185 238
-749 4 2 3 1 74 29 90 253
-750 4 2 3 1 81 97 85 251
-751 4 2 3 1 26 86 76 239
-752 4 2 3 1 151 167 40 235
-753 4 2 3 1 104 237 102 249
-754 4 2 3 1 103 51 50 240
-755 4 2 3 1 76 87 75 234
-756 4 2 3 1 154 247 244 255
-757 4 2 3 1 108 121 122 250
-758 4 2 3 1 161 155 149 245
-759 4 2 3 1 102 118 112 237
-760 4 2 3 1 91 183 77 246
-761 4 2 3 1 179 185 197 238
-762 4 2 3 1 48 120 49 242
-763 4 2 3 1 76 239 234 253
-764 4 2 3 1 170 157 171 245
-765 4 2 3 1 142 47 48 242
-766 4 2 3 1 230 239 27 253
-767 4 2 3 1 173 15 14 238
-768 4 2 3 1 130 141 145 248
-769 4 2 3 1 185 180 197 232
-770 4 2 3 1 26 25 86 239
-771 4 2 3 1 118 102 119 237
-772 4 2 3 1 156 36 37 241
-773 4 2 3 1 98 110 113 230
-774 4 2 3 1 27 113 230 253
-775 4 2 3 1 131 134 135 236
-776 4 2 3 1 106 29 123 249
-777 4 2 3 1 51 107 52 240
-778 4 2 3 1 76 234 90 253
-779 4 2 3 1 179 238 197 252
-780 4 2 3 1 81 74 79 251
-781 4 2 3 1 103 107 51 240
-782 4 2 3 1 152 165 154 244
-783 4 2 3 1 243 246 226 250
-784 4 2 3 1 32 33 117 250
-785 4 2 3 1 155 159 171 245
-786 4 2 3 1 91 77 82 246
-787 4 2 3 1 129 130 132 248
-788 4 2 3 1 56 153 193 172
-789 4 2 3 1 32 117 122 250
-790 4 2 3 1 120 115 112 242
-791 4 2 3 1 133 15 16 238
-792 4 2 3 1 165 151 41 235
-793 4 2 3 1 160 156 158 241
-794 4 2 3 1 27 239 76 253
-795 4 2 3 1 151 40 41 235
-796 4 2 3 1 153 56 193 182
-797 4 2 3 1 157 155 171 245
-798 4 2 3 1 191 65 127 146
-799 4 2 3 1 60 198 188 117
-800 4 2 3 1 42 41 92 255
-801 4 2 3 1 157 149 155 245
-802 4 2 3 1 102 106 111 249
-803 4 2 3 1 29 28 90 253
-804 4 2 3 1 235 244 225 255
-805 4 2 3 1 56 153 168 182
-806 4 2 3 1 43 42 78 255
-807 4 2 3 1 199 186 54 173
-808 4 2 3 1 26 27 110 239
-809 4 2 3 1 126 125 134 236
-810 4 2 3 1 191 65 185 127
-811 4 2 3 1 131 126 134 236
-812 4 2 3 1 22 23 140 247
-813 4 2 3 1 128 141 130 248
-814 4 2 3 1 86 78 92 255
-815 4 2 3 1 65 185 127 143
-816 4 2 3 1 91 183 59 77
-817 4 2 3 1 114 62 100 184
-818 4 2 3 1 26 110 99 239
-819 4 2 3 1 123 121 111 249
-820 4 2 3 1 62 114 61 184
-821 4 2 3 1 65 64 185 143
-822 4 2 3 1 183 91 59 58
-823 4 2 3 1 94 57 187 201
-824 4 2 3 1 152 22 21 244
-825 4 2 3 1 192 62 100 116
-826 4 2 3 1 33 198 190 2
-827 4 2 3 1 55 56 168 182
-828 4 2 3 1 62 192 100 184
-829 4 2 3 1 97 81 89 251
-830 4 2 3 1 32 31 84 250
-831 4 2 3 1 124 130 129 248
-832 4 2 3 1 192 53 4 116
-833 4 2 3 1 95 33 190 2
-834 4 2 3 1 156 160 36 241
-835 4 2 3 1 177 195 194 243
-836 4 2 3 1 199 173 3 14
-837 4 2 3 1 33 198 2 117
-838 4 2 3 1 54 186 168 173
-839 4 2 3 1 198 60 2 117
-840 4 2 3 1 114 60 188 117
-841 4 2 3 1 82 84 80 246
-842 4 2 3 1 47 115 48 242
-843 4 2 3 1 54 199 173 3
-844 4 2 3 1 106 123 111 249
-845 4 2 3 1 91 94 57 187
-846 4 2 3 1 23 1 44 247
-847 4 2 3 1 121 31 122 250
-848 4 2 3 1 61 114 188 184
-849 4 2 3 1 186 55 168 182
-850 4 2 3 1 115 120 48 242
-851 4 2 3 1 124 128 130 248
-852 4 2 3 1 178 194 195 243
-853 4 2 3 1 22 152 154 244
-854 4 2 3 1 223 245 228 254
-855 4 2 3 1 25 26 99 239
-856 4 2 3 1 244 247 225 255
-857 4 2 3 1 94 57 201 5
-858 4 2 3 1 81 79 89 251
-859 4 2 3 1 160 35 36 241
-860 4 2 3 1 196 179 197 252
-861 4 2 3 1 140 44 45 247
-862 4 2 3 1 200 192 53 4
-863 4 2 3 1 34 94 201 5
-864 4 2 3 1 183 91 58 187
-865 4 2 3 1 140 23 44 247
-866 4 2 3 1 64 189 185 143
-867 4 2 3 1 193 34 201 5
-868 4 2 3 1 78 42 92 255
-869 4 2 3 1 193 172 34 5
-870 4 2 3 1 147 200 53 4
-871 4 2 3 1 82 77 84 246
-872 4 2 3 1 27 76 90 253
-873 4 2 3 1 63 189 143 147
-874 4 2 3 1 189 63 200 147
-875 4 2 3 1 63 200 147 4
-876 4 2 3 1 197 177 196 252
-877 4 2 3 1 31 32 122 250
-878 4 2 3 1 186 55 54 168
-879 4 2 3 1 61 114 60 188
-880 4 2 3 1 59 95 190 2
-881 4 2 3 1 191 65 146 3
-882 4 2 3 1 62 192 4 116
-883 4 2 3 1 58 91 57 187
-884 4 2 3 1 28 27 90 253
-885 4 2 3 1 189 64 63 143
-886 4 2 3 1 193 56 172 5
-887 4 2 3 1 150 235 245 161
-888 4 2 3 1 245 235 150 228
-889 4 2 3 1 142 236 233 242
-890 4 2 3 1 19 159 223 18
-891 4 2 3 1 223 159 19 228
-892 4 2 3 1 135 19 223 18
-893 4 2 3 1 135 223 19 236
-894 4 2 3 1 241 252 181 231
-895 4 2 3 1 181 252 241 229
-896 4 2 3 1 252 241 254 220
-897 4 2 3 1 252 254 241 229
-898 4 2 3 1 139 142 236 125
-899 4 2 3 1 232 147 143 189
-900 4 2 3 1 232 143 147 137
-901 4 2 3 1 86 239 234 76
-902 4 2 3 1 86 234 239 255
-903 4 2 3 1 87 86 234 76
-904 4 2 3 1 87 234 86 255
-905 4 2 3 1 228 233 222 221
-906 4 2 3 1 228 222 233 236
-907 4 2 3 1 223 228 222 221
-908 4 2 3 1 223 222 228 236
-909 4 2 3 1 19 131 228 20
-910 4 2 3 1 228 131 19 236
-911 4 2 3 1 131 138 228 20
-912 4 2 3 1 228 138 131 236
-913 4 2 3 1 242 139 236 222
-914 4 2 3 1 242 236 139 142
-915 4 2 3 1 124 135 223 144
-916 4 2 3 1 223 135 124 236
-917 4 2 3 1 240 100 105 107
-918 4 2 3 1 240 105 100 227
-919 4 2 3 1 103 240 105 107
-920 4 2 3 1 103 105 240 227
-921 4 2 3 1 221 223 220 222
-922 4 2 3 1 221 220 223 254
-923 4 2 3 1 118 242 222 49
-924 4 2 3 1 222 242 118 237
-925 4 2 3 1 118 222 50 49
-926 4 2 3 1 227 100 114 105
-927 4 2 3 1 227 114 100 184
-928 4 2 3 1 223 159 171 18
-929 4 2 3 1 223 171 159 245
-930 4 2 3 1 234 90 74 79
-931 4 2 3 1 234 74 90 253
-932 4 2 3 1 251 234 74 79
-933 4 2 3 1 29 226 74 93
-934 4 2 3 1 29 74 226 253
-935 4 2 3 1 129 238 132 133
-936 4 2 3 1 132 238 129 248
-937 4 2 3 1 138 228 233 236
-938 4 2 3 1 138 233 228 244
-939 4 2 3 1 223 129 124 144
-940 4 2 3 1 223 124 129 248
-941 4 2 3 1 246 95 183 77
-942 4 2 3 1 246 183 95 190
-943 4 2 3 1 183 95 59 77
-944 4 2 3 1 183 59 95 190
-945 4 2 3 1 229 223 170 238
-946 4 2 3 1 170 223 229 245
-947 4 2 3 1 31 226 249 30
-948 4 2 3 1 31 249 226 250
-949 4 2 3 1 121 31 249 30
-950 4 2 3 1 121 249 31 250
-951 4 2 3 1 183 231 91 187
-952 4 2 3 1 183 91 231 246
-953 4 2 3 1 235 245 254 228
-954 4 2 3 1 254 245 235 224
-955 4 2 3 1 168 229 153 175
-956 4 2 3 1 153 229 168 182
-957 4 2 3 1 110 109 230 98
-958 4 2 3 1 110 230 109 239
-959 4 2 3 1 152 165 235 151
-960 4 2 3 1 235 165 152 244
-961 4 2 3 1 152 235 162 151
-962 4 2 3 1 162 235 152 244
-963 4 2 3 1 241 251 220 231
-964 4 2 3 1 220 251 241 224
-965 4 2 3 1 113 249 253 106
-966 4 2 3 1 253 249 113 230
-967 4 2 3 1 255 247 239 24
-968 4 2 3 1 255 239 247 225
-969 4 2 3 1 226 234 74 251
-970 4 2 3 1 74 234 226 253
-971 4 2 3 1 109 242 98 115
-972 4 2 3 1 98 242 109 230
-973 4 2 3 1 47 115 233 46
-974 4 2 3 1 47 233 115 242
-975 4 2 3 1 233 115 109 46
-976 4 2 3 1 233 109 115 242
-977 4 2 3 1 251 82 80 246
-978 4 2 3 1 251 80 82 81
-979 4 2 3 1 33 84 250 32
-980 4 2 3 1 33 250 84 246
-981 4 2 3 1 233 239 221 225
-982 4 2 3 1 221 239 233 230
-983 4 2 3 1 246 85 251 82
-984 4 2 3 1 246 251 85 231
-985 4 2 3 1 247 154 22 23
-986 4 2 3 1 247 22 154 244
-987 4 2 3 1 88 83 224 39
-988 4 2 3 1 88 224 83 234
-989 4 2 3 1 235 88 224 39
-990 4 2 3 1 235 224 88 234
-991 4 2 3 1 221 226 237 220
-992 4 2 3 1 237 226 221 230
-993 4 2 3 1 221 237 222 220
-994 4 2 3 1 222 237 221 230
-995 4 2 3 1 34 231 193 201
-996 4 2 3 1 34 193 231 241
-997 4 2 3 1 193 231 181 201
-998 4 2 3 1 193 181 231 241
-999 4 2 3 1 37 224 89 38
-1000 4 2 3 1 89 224 83 38
-1001 4 2 3 1 89 83 224 251
-1002 4 2 3 1 142 136 236 125
-1003 4 2 3 1 142 236 136 233
-1004 4 2 3 1 236 136 126 125
-1005 4 2 3 1 236 139 248 222
-1006 4 2 3 1 236 248 139 128
-1007 4 2 3 1 248 139 141 222
-1008 4 2 3 1 248 141 139 128
-1009 4 2 3 1 140 22 233 138
-1010 4 2 3 1 140 233 22 247
-1011 4 2 3 1 233 22 244 138
-1012 4 2 3 1 233 244 22 247
-1013 4 2 3 1 138 236 136 126
-1014 4 2 3 1 136 236 138 233
-1015 4 2 3 1 226 31 246 80
-1016 4 2 3 1 226 246 31 250
-1017 4 2 3 1 246 31 84 80
-1018 4 2 3 1 246 84 31 250
-1019 4 2 3 1 220 251 221 226
-1020 4 2 3 1 220 221 251 224
-1021 4 2 3 1 221 251 234 226
-1022 4 2 3 1 221 234 251 224
-1023 4 2 3 1 237 240 220 227
-1024 4 2 3 1 220 240 237 222
-1025 4 2 3 1 240 232 220 227
-1026 4 2 3 1 220 232 240 222
-1027 4 2 3 1 252 181 194 177
-1028 4 2 3 1 252 194 181 231
-1029 4 2 3 1 243 252 194 177
-1030 4 2 3 1 243 194 252 231
-1031 4 2 3 1 170 16 223 17
-1032 4 2 3 1 223 16 170 238
-1033 4 2 3 1 16 129 223 17
-1034 4 2 3 1 223 129 16 238
-1035 4 2 3 1 3 191 14 146
-1036 4 2 3 1 14 191 3 199
-1037 4 2 3 1 191 238 14 146
-1038 4 2 3 1 14 238 191 199
-1039 4 2 3 1 118 222 240 50
-1040 4 2 3 1 118 240 222 237
-1041 4 2 3 1 103 118 240 50
-1042 4 2 3 1 103 240 118 237
-1043 4 2 3 1 224 89 97 37
-1044 4 2 3 1 224 97 89 251
-1045 4 2 3 1 241 224 97 37
-1046 4 2 3 1 241 97 224 251
-1047 4 2 4 2 202 215 206 219
-1048 4 2 4 2 215 203 202 206
-1049 4 2 4 2 219 206 214 216
-1050 4 2 4 2 206 204 219 214
-1051 4 2 4 2 218 205 212 204
-1052 4 2 4 2 202 206 204 219
-1053 4 2 4 2 215 206 219 216
-1054 4 2 4 2 205 218 202 204
-1055 4 2 4 2 210 217 218 71
-1056 4 2 4 2 205 210 68 203
-1057 4 2 4 2 204 206 66 214
-1058 4 2 4 2 73 219 214 216
-1059 4 2 4 2 208 67 203 206
-1060 4 2 4 2 205 69 212 204
-1061 4 2 4 2 210 6 68 203
-1062 4 2 4 2 10 208 70 216
-1063 4 2 4 2 66 204 214 7
-1064 4 2 4 2 8 205 69 212
-1065 4 2 4 2 208 9 67 206
-1066 4 2 4 2 73 219 13 214
-1067 4 2 4 2 217 210 11 71
-1068 4 2 4 2 218 12 72 212
-1069 4 2 4 2 73 10 216 213
-1070 4 2 4 2 8 205 209 68
-1071 4 2 4 2 206 9 66 213
-1072 4 2 4 2 207 217 11 70
-1073 4 2 4 2 6 207 67 203
-1074 4 2 4 2 204 69 211 7
-1075 4 2 4 2 202 219 218 215
-1076 4 2 4 2 218 219 202 204
-1077 4 2 4 2 202 218 203 215
-1078 4 2 4 2 202 203 218 205
-1079 4 2 4 2 203 218 217 215
-1080 4 2 4 2 215 203 216 217
-1081 4 2 4 2 216 203 215 206
-1082 4 2 4 2 216 208 203 206
-1083 4 2 4 2 7 13 204 214
-1084 4 2 4 2 7 204 13 211
-1085 4 2 4 2 204 13 219 214
-1086 4 2 4 2 9 10 216 208
-1087 4 2 4 2 9 216 10 213
-1088 4 2 4 2 206 9 216 208
-1089 4 2 4 2 206 216 9 213
-1090 4 2 4 2 12 8 205 209
-1091 4 2 4 2 12 205 8 212
-1092 4 2 4 2 218 205 12 212
-1093 4 2 4 2 11 6 203 207
-1094 4 2 4 2 11 203 6 210
-1095 4 2 4 2 217 11 203 207
-1096 4 2 4 2 217 203 11 210
-1097 4 2 4 2 72 69 204 212
-1098 4 2 4 2 72 204 69 211
-1099 4 2 4 2 73 66 216 214
-1100 4 2 4 2 73 216 66 213
-1101 4 2 4 2 216 66 206 214
-1102 4 2 4 2 216 206 66 213
-1103 4 2 4 2 71 68 205 210
-1104 4 2 4 2 71 205 68 209
-1105 4 2 4 2 218 71 205 210
-1106 4 2 4 2 70 67 203 208
-1107 4 2 4 2 70 203 67 207
-1108 4 2 4 2 217 203 70 207
-1109 4 2 4 2 203 218 210 217
-1110 4 2 4 2 210 218 203 205
-1111 4 2 4 2 204 13 72 219
-1112 4 2 4 2 72 13 204 211
-1113 4 2 4 2 205 12 71 218
-1114 4 2 4 2 205 71 12 209
-1115 4 2 4 2 204 72 218 219
-1116 4 2 4 2 204 218 72 212
-1117 4 2 4 2 203 70 216 217
-1118 4 2 4 2 203 216 70 208
-$EndElements
diff --git a/test/test_contact/material.dat b/test/test_contact/material.dat
deleted file mode 100644
index 8bbe418cd..000000000
--- a/test/test_contact/material.dat
+++ /dev/null
@@ -1,14 +0,0 @@
-material neohookean [
- name = Top_body
- E = 1
- nu = 0.3
- finite_deformation = 1
-]
-
-
-material neohookean [
- name = Bottom_body
- E = 10000
- nu = 0.3
- finite_deformation = 1
-]
diff --git a/test/test_contact/offset_1slave.cc b/test/test_contact/offset_1slave.cc
deleted file mode 100644
index 09ff226a1..000000000
--- a/test/test_contact/offset_1slave.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * @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
- *
- * @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)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_1slave.geo b/test/test_contact/offset_1slave.geo
deleted file mode 100644
index 073c862e2..000000000
--- a/test/test_contact/offset_1slave.geo
+++ /dev/null
@@ -1,27 +0,0 @@
-cl1 = 1;
-cl2 = -0.15;
-offset = 0.25;
-Point(1) = {-0.5, -0.5, 0, cl1};
-Point(2) = {-0.5, 0.5, 0, cl1};
-Point(3) = {0.5, 0.5, 0, cl1};
-Point(4) = {0.5, -0.5, 0, cl1};
-Point(5) = {offset, 0.7+cl2, 0, cl1};
-Point(6) = {0.5 + offset, 1.4+cl2, 0, cl1};
-Point(7) = {-0.5 + offset, 1.4+cl2, 0, cl1};
-Line(1) = {1, 4};
-Line(2) = {4, 3};
-Line(3) = {3, 2};
-Line(4) = {2, 1};
-Line(5) = {5, 6};
-Line(6) = {6, 7};
-Line(7) = {7, 5};
-Line Loop(9) = {1, 2, 3, 4};
-Plane Surface(9) = {9};
-Line Loop(11) = {5, 6, 7};
-Plane Surface(11) = {11};
-Physical Line("Bottom") = {1};
-Physical Line("Top") = {6};
-Physical Line("Contact") = {3};
-Physical Line("Dummy") = {2, 4, 5, 7};
-Physical Surface("Top_body") = {11};
-Physical Surface("Bottom_body") = {9};
diff --git a/test/test_contact/offset_2slaves.cc b/test/test_contact/offset_2slaves.cc
deleted file mode 100644
index 45f866efe..000000000
--- a/test/test_contact/offset_2slaves.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * @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
- *
- * @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)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_contact/offset_2slaves.geo b/test/test_contact/offset_2slaves.geo
deleted file mode 100644
index 3a0371bb6..000000000
--- a/test/test_contact/offset_2slaves.geo
+++ /dev/null
@@ -1,28 +0,0 @@
-cl1 = 1;
-cl2 = -0.15;
-offset = 0.25;
-Point(1) = {-0.5, -0.5, 0, cl1};
-Point(2) = {-0.5, 0.5, 0, cl1};
-Point(3) = {0.5, 0.5, 0, cl1};
-Point(4) = {0.5, -0.5, 0, cl1};
-Point(5) = {offset, 0.7+cl2, 0, cl1};
-Point(6) = {0.5 + offset, 1.4+cl2, 0, cl1};
-Point(7) = {-0.5 + offset, 1.4+cl2, 0, cl1};
-Point(8) = {-offset, 0.8+cl2, 0, cl1};
-Line(1) = {1, 4};
-Line(2) = {4, 3};
-Line(3) = {3, 2};
-Line(4) = {2, 1};
-Line(5) = {5, 6};
-Line(6) = {6, 7};
-Line(7) = {7, 8};
-Line(8) = {8, 5};
-Line Loop(9) = {1, 2, 3, 4};
-Plane Surface(9) = {9};
-Line Loop(11) = {5, 6, 7, 8};
-Plane Surface(11) = {11};
-Physical Line("Bottom") = {1};
-Physical Line("Top") = {6};
-Physical Line("Contact") = {3};
-Physical Surface("Top_body") = {11};
-Physical Surface("Bottom_body") = {9};
diff --git a/test/test_contact/steel.dat b/test/test_contact/steel.dat
deleted file mode 100644
index bb0440f47..000000000
--- a/test/test_contact/steel.dat
+++ /dev/null
@@ -1,7 +0,0 @@
-material elastic [
- name = steel
- rho = 7500 # kg/m^3
- E = 2e11 # GPa
- nu = 0.
- finite_deformation = 1
-]
diff --git a/test/test_contact/test_acurnier_2D_1.verified b/test/test_contact/test_acurnier_2D_1.verified
deleted file mode 100644
index 32bb1d688..000000000
--- a/test/test_contact/test_acurnier_2D_1.verified
+++ /dev/null
@@ -1,51 +0,0 @@
-*** INFO *** Obtaining penalty parameters automatically. Average value: 16727.9
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Force: 0.850644
diff --git a/test/test_contact/test_acurnier_2D_2.verified b/test/test_contact/test_acurnier_2D_2.verified
deleted file mode 100644
index 7fae38b2d..000000000
--- a/test/test_contact/test_acurnier_2D_2.verified
+++ /dev/null
@@ -1,51 +0,0 @@
-*** INFO *** Obtaining penalty parameters automatically. Average value: 14178.1
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 4
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Force: 1.53988
diff --git a/test/test_contact/test_acurnier_3D_1.verified b/test/test_contact/test_acurnier_3D_1.verified
deleted file mode 100644
index 960f18ee7..000000000
--- a/test/test_contact/test_acurnier_3D_1.verified
+++ /dev/null
@@ -1,51 +0,0 @@
-*** INFO *** Obtaining penalty parameters automatically. Average value: 2233.71
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Force: 0.293132
diff --git a/test/test_contact/test_acurnier_3D_2.verified b/test/test_contact/test_acurnier_3D_2.verified
deleted file mode 100644
index 21bc7983e..000000000
--- a/test/test_contact/test_acurnier_3D_2.verified
+++ /dev/null
@@ -1,51 +0,0 @@
-*** INFO *** Obtaining penalty parameters automatically. Average value: 3763.14
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 4
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 2
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Force: 0.439482
diff --git a/test/test_contact/test_acurnier_3D_3.verified b/test/test_contact/test_acurnier_3D_3.verified
deleted file mode 100644
index c5ff5b41c..000000000
--- a/test/test_contact/test_acurnier_3D_3.verified
+++ /dev/null
@@ -1,51 +0,0 @@
-*** INFO *** Obtaining penalty parameters automatically. Average value: 3050.58
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 4
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Force: 0.227002
diff --git a/test/test_contact/test_hertz_2D.verified b/test/test_contact/test_hertz_2D.verified
deleted file mode 100644
index 58557b0e2..000000000
--- a/test/test_contact/test_hertz_2D.verified
+++ /dev/null
@@ -1,145 +0,0 @@
-
-Contact object info:
- Search type: MasterAssignator search class. Search surfaces:
-
- Resolution type: Augmented-Lagrangian resolution type. Parameters:
- penalty = auto
- alpha = 0.4
- utol = 0.0001
- ntol = 0.0001
- usteps = 100
- nsteps = 100
- verbose = 0
-
- Slave nodes: 0 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
-
- Slave master pairs
- slave: 0, Master: Element [_segment_2, 47, not_ghost]
- slave: 16, Master: Element [_segment_2, 47, not_ghost]
- slave: 17, Master: Element [_segment_2, 47, not_ghost]
- slave: 18, Master: Element [_segment_2, 47, not_ghost]
- slave: 19, Master: Element [_segment_2, 47, not_ghost]
- slave: 20, Master: Element [_segment_2, 47, not_ghost]
- slave: 21, Master: Element [_segment_2, 47, not_ghost]
- slave: 22, Master: Element [_segment_2, 47, not_ghost]
- slave: 23, Master: Element [_segment_2, 47, not_ghost]
- slave: 24, Master: Element [_segment_2, 47, not_ghost]
- slave: 25, Master: Element [_segment_2, 47, not_ghost]
- slave: 26, Master: Element [_segment_2, 47, not_ghost]
- slave: 27, Master: Element [_segment_2, 47, not_ghost]
- slave: 28, Master: Element [_segment_2, 47, not_ghost]
- slave: 29, Master: Element [_segment_2, 47, not_ghost]
- slave: 30, Master: Element [_segment_2, 47, not_ghost]
- slave: 31, Master: Element [_segment_2, 47, not_ghost]
- slave: 32, Master: Element [_segment_2, 47, not_ghost]
- slave: 33, Master: Element [_segment_2, 47, not_ghost]
- slave: 34, Master: Element [_segment_2, 47, not_ghost]
- slave: 35, Master: Element [_segment_2, 47, not_ghost]
- slave: 36, Master: Element [_segment_2, 47, not_ghost]
- slave: 37, Master: Element [_segment_2, 47, not_ghost]
- slave: 38, Master: Element [_segment_2, 47, not_ghost]
- slave: 39, Master: Element [_segment_2, 47, not_ghost]
-
-*** INFO *** Obtaining penalty parameters automatically. Average value: 9.17857e+10
-Summary: Uzawa [14]: Newton [24]: 4 3 2 2 2 2 2 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [21]: 3 2 2 2 2 2 1 1 1 1 1 1 1 1
-Summary: Uzawa [15]: Newton [23]: 3 2 2 2 2 2 2 1 1 1 1 1 1 1 1
-Summary: Uzawa [15]: Newton [21]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [22]: 3 2 2 2 2 2 2 1 1 1 1 1 1 1
-Summary: Uzawa [16]: Newton [23]: 3 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [15]: Newton [20]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [15]: Newton [22]: 3 2 2 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [21]: 3 2 2 2 2 2 1 1 1 1 1 1 1 1
-Summary: Uzawa [15]: Newton [21]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [19]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [20]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [20]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [20]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [20]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [20]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [20]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [20]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [20]: 3 2 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [16]: Newton [21]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [16]: Newton [21]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [16]: Newton [21]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [23]: Newton [27]: 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [16]: Newton [21]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [16]: Newton [21]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [16]: Newton [21]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [16]: Newton [21]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [19]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [19]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [18]: Newton [22]: 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [19]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [14]: Newton [19]: 3 2 2 2 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [13]: Newton [18]: 3 2 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [18]: Newton [22]: 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
-
-Disp. ForceMax pressure
- 0.001 7.3e+07 3.1e+09
- 0.002 1.6e+08 4.5e+09
- 0.003 2.5e+08 5.6e+09
- 0.004 3.5e+08 6.5e+09
- 0.005 4.5e+08 7.2e+09
- 0.006 5.5e+08 8e+09
- 0.007 6.5e+08 8.7e+09
- 0.008 7.7e+08 9.3e+09
- 0.009 8.8e+08 9.9e+09
- 0.01 9.9e+08 1e+10
- 0.011 1.1e+09 1.1e+10
- 0.012 1.2e+09 1.2e+10
- 0.013 1.3e+09 1.2e+10
- 0.014 1.5e+09 1.2e+10
- 0.015 1.6e+09 1.3e+10
- 0.016 1.7e+09 1.3e+10
- 0.017 1.8e+09 1.4e+10
- 0.018 1.9e+09 1.4e+10
- 0.019 2.1e+09 1.5e+10
- 0.02 2.2e+09 1.5e+10
- 0.021 2.3e+09 1.5e+10
- 0.022 2.4e+09 1.6e+10
- 0.023 2.6e+09 1.6e+10
- 0.024 2.7e+09 1.6e+10
- 0.025 2.8e+09 1.7e+10
- 0.026 3e+09 1.7e+10
- 0.027 3.1e+09 1.7e+10
- 0.028 3.2e+09 1.8e+10
- 0.029 3.4e+09 1.8e+10
- 0.03 3.5e+09 1.8e+10
- 0.031 3.6e+09 1.9e+10
- 0.032 3.8e+09 1.9e+10
- 0.033 3.9e+09 1.9e+10
- 0.034 4.1e+09 2e+10
- 0.035 4.2e+09 2e+10
- 0.036 4.3e+09 2e+10
- 0.037 4.5e+09 2e+10
- 0.038 4.6e+09 2.1e+10
- 0.039 4.7e+09 2.1e+10
- 0.04 4.9e+09 2.1e+10
- 0.041 5e+09 2.1e+10
- 0.042 5.1e+09 2.2e+10
- 0.043 5.3e+09 2.2e+10
- 0.044 5.4e+09 2.2e+10
- 0.045 5.6e+09 2.2e+10
- 0.046 5.7e+09 2.2e+10
- 0.047 5.9e+09 2.3e+10
- 0.048 6e+09 2.3e+10
- 0.049 6.2e+09 2.3e+10
- 0.05 6.3e+09 2.3e+10
diff --git a/test/test_contact/test_hertz_3D.verified b/test/test_contact/test_hertz_3D.verified
deleted file mode 100644
index 2fd11fe6c..000000000
--- a/test/test_contact/test_hertz_3D.verified
+++ /dev/null
@@ -1,147 +0,0 @@
-- Adding areas to slave nodes.
-
-Contact object info:
- Search type: MasterAssignator search class. Search surfaces:
-
- Resolution type: Augmented-Lagrangian resolution type. Parameters:
- penalty = auto
- alpha = 0.125
- utol = 0.01
- ntol = 0.01
- usteps = 100
- nsteps = 100
- verbose = 0
-
- Slave nodes: 0 16 17 18 19 20 21 22 23 24 25 26 27 28 29 36 37 38 39 40 41 42 43 44 45 46 47 48 49 73 74 75 77 78 82 85 86 87 88 89 91 92 97 98 100 101 105 108 109 110 111 112 114 117 118 119 122 123 124 125 127 130 133 134 135 137 138 139 140 141 143 148 149 150 151 153 154 158 160 161 162 164 165 166 168 170
-
- Slave master pairs
- slave: 0, Master: none
- slave: 16, Master: none
- slave: 17, Master: none
- slave: 18, Master: none
- slave: 19, Master: none
- slave: 20, Master: none
- slave: 21, Master: none
- slave: 22, Master: none
- slave: 23, Master: none
- slave: 24, Master: none
- slave: 25, Master: none
- slave: 26, Master: none
- slave: 27, Master: none
- slave: 28, Master: none
- slave: 29, Master: none
- slave: 36, Master: none
- slave: 37, Master: none
- slave: 38, Master: none
- slave: 39, Master: none
- slave: 40, Master: none
- slave: 41, Master: none
- slave: 42, Master: none
- slave: 43, Master: none
- slave: 44, Master: none
- slave: 45, Master: none
- slave: 46, Master: none
- slave: 47, Master: none
- slave: 48, Master: none
- slave: 49, Master: none
- slave: 73, Master: none
- slave: 74, Master: none
- slave: 75, Master: none
- slave: 77, Master: none
- slave: 78, Master: none
- slave: 82, Master: none
- slave: 85, Master: none
- slave: 86, Master: none
- slave: 87, Master: none
- slave: 88, Master: none
- slave: 89, Master: none
- slave: 91, Master: none
- slave: 92, Master: none
- slave: 97, Master: none
- slave: 98, Master: none
- slave: 100, Master: none
- slave: 101, Master: none
- slave: 105, Master: none
- slave: 108, Master: none
- slave: 109, Master: none
- slave: 110, Master: none
- slave: 111, Master: none
- slave: 112, Master: none
- slave: 114, Master: none
- slave: 117, Master: none
- slave: 118, Master: none
- slave: 119, Master: none
- slave: 122, Master: none
- slave: 123, Master: none
- slave: 124, Master: none
- slave: 125, Master: none
- slave: 127, Master: none
- slave: 130, Master: none
- slave: 133, Master: none
- slave: 134, Master: none
- slave: 135, Master: none
- slave: 137, Master: none
- slave: 138, Master: none
- slave: 139, Master: none
- slave: 140, Master: none
- slave: 141, Master: none
- slave: 143, Master: none
- slave: 148, Master: none
- slave: 149, Master: none
- slave: 150, Master: none
- slave: 151, Master: none
- slave: 153, Master: none
- slave: 154, Master: none
- slave: 158, Master: none
- slave: 160, Master: none
- slave: 161, Master: none
- slave: 162, Master: none
- slave: 164, Master: none
- slave: 165, Master: none
- slave: 166, Master: none
- slave: 168, Master: none
- slave: 170, Master: none
-
-*** INFO *** Obtaining penalty parameters automatically. Average value: 2.78649e+09
-Summary: Uzawa [1]: Newton [1]: 1
-Summary: Uzawa [2]: Newton [3]: 2 1
-Summary: Uzawa [19]: Newton [22]: 3 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [9]: Newton [11]: 2 2 1 1 1 1 1 1 1
-Summary: Uzawa [8]: Newton [10]: 2 2 1 1 1 1 1 1
-Summary: Uzawa [11]: Newton [13]: 2 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [8]: Newton [10]: 2 2 1 1 1 1 1 1
-Summary: Uzawa [8]: Newton [10]: 2 2 1 1 1 1 1 1
-Summary: Uzawa [8]: Newton [10]: 2 2 1 1 1 1 1 1
-Summary: Uzawa [8]: Newton [10]: 2 2 1 1 1 1 1 1
-Summary: Uzawa [8]: Newton [10]: 2 2 1 1 1 1 1 1
-Summary: Uzawa [7]: Newton [9]: 2 2 1 1 1 1 1
-Summary: Uzawa [7]: Newton [9]: 2 2 1 1 1 1 1
-Summary: Uzawa [10]: Newton [11]: 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [10]: Newton [11]: 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [10]: Newton [11]: 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [10]: Newton [11]: 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [10]: Newton [11]: 2 1 1 1 1 1 1 1 1 1
-Summary: Uzawa [9]: Newton [10]: 2 1 1 1 1 1 1 1 1
-Summary: Uzawa [7]: Newton [8]: 2 1 1 1 1 1 1
-
- Disp. Force Max pressure
- 0 0 0
- 0.001 5690 2.068e+07
- 0.002 8.784e+06 9.241e+09
- 0.003 2.239e+07 1.187e+10
- 0.004 3.833e+07 1.575e+10
- 0.005 6.205e+07 1.904e+10
- 0.006 8.524e+07 2.027e+10
- 0.007 1.098e+08 2.043e+10
- 0.008 1.364e+08 2.079e+10
- 0.009 1.664e+08 2.094e+10
- 0.01 1.962e+08 2.136e+10
- 0.011 2.267e+08 2.396e+10
- 0.012 2.641e+08 2.49e+10
- 0.013 3.094e+08 2.509e+10
- 0.014 3.455e+08 2.532e+10
- 0.015 3.838e+08 2.564e+10
- 0.016 4.221e+08 2.608e+10
- 0.017 4.608e+08 2.869e+10
- 0.018 5.052e+08 3.074e+10
- 0.019 5.372e+08 3.212e+10
diff --git a/test/test_contact/test_offset_1slave.verified b/test/test_contact/test_offset_1slave.verified
deleted file mode 100644
index 885c23798..000000000
--- a/test/test_contact/test_offset_1slave.verified
+++ /dev/null
@@ -1,51 +0,0 @@
-*** INFO *** Obtaining penalty parameters automatically. Average value: 2e+11
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 5
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 4
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Force: 1.8352e+10
diff --git a/test/test_contact/test_offset_2slaves.verified b/test/test_contact/test_offset_2slaves.verified
deleted file mode 100644
index 621dc6431..000000000
--- a/test/test_contact/test_offset_2slaves.verified
+++ /dev/null
@@ -1,51 +0,0 @@
-*** INFO *** Obtaining penalty parameters automatically. Average value: 2e+11
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 3
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Generalized Newton iterations: 5
-Force: 1.62934e+10
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..27a972529 100644
--- a/test/test_fe_engine/test_gradient.cc
+++ b/test/test_fe_engine/test_gradient.cc
@@ -1,138 +1,144 @@
/**
* @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[]) {
+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";
+ std::stringstream meshfilename;
+ meshfilename << type << ".msh";
my_mesh.read(meshfilename.str());
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
+ FEEngine * fem = new FEEngineTemplate<IntegratorGauss, ShapeLagrange>(
+ my_mesh, dim, "my_fem");
fem->initShapeFunctions();
- Real alpha[2][3] = {{13, 23, 31},
- {11, 7, 5}};
+ 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;
+ // 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) {
+ 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);
+ 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);
+ 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;
+ // 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 (; 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);
- }
+ 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_gradient_hexahedron_20.verified b/test/test_fe_engine/test_gradient_hexahedron_20.verified
index d7efdffdb..039eba426 100644
--- a/test/test_fe_engine/test_gradient_hexahedron_20.verified
+++ b/test/test_fe_engine/test_gradient_hexahedron_20.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 81
- + nb_component : 2
- + allocated size : 81
- + memory size : 1.27KiByte
- + values : {{-33.5, -11.5}, {-20.5, -0.5}, {-10.5, -4.5}, {2.5, 6.5}, {-2.5, -6.5}, {10.5, 4.5}, {33.5, 11.5}, {20.5, 0.5}, {-27, -6}, {-30.25, -8.75}, {-23.75, -3.25}, {-4, 1}, {-7.25, -1.75}, {-0.75, 3.75}, {-22, -8}, {-27.75, -9.75}, {-16.25, -6.25}, {-9, 3}, {-14.75, 1.25}, {-3.25, 4.75}, {4, -1}, {0.75, -3.75}, {7.25, 1.75}, {22, 8}, {16.25, 6.25}, {27.75, 9.75}, {27, 6}, {30.25, 8.75}, {23.75, 3.25}, {9, -3}, {14.75, -1.25}, {3.25, -4.75}, {-18, -9}, {-25.75, -10.25}, {-10.25, -7.75}, {-5, 2}, {-12.75, 0.75}, {2.75, 3.25}, {18, 9}, {10.25, 7.75}, {25.75, 10.25}, {5, -2}, {-2.75, -3.25}, {12.75, -0.75}, {-15.5, -2.5}, {-21.25, -4.25}, {-18.75, -5.25}, {-9.75, -0.75}, {-12.25, 0.25}, {-11.5, -3.5}, {-19.25, -4.75}, {-14.75, -6.25}, {-3.75, -2.25}, {-8.25, -0.75}, {6.5, 5.5}, {-1.25, 4.25}, {0.75, 3.75}, {14.25, 6.75}, {12.25, 7.25}, {11.5, 3.5}, {8.25, 0.75}, {3.75, 2.25}, {19.25, 4.75}, {14.75, 6.25}, {-6.5, -5.5}, {-12.25, -7.25}, {-14.25, -6.75}, {1.25, -4.25}, {-0.75, -3.75}, {15.5, 2.5}, {9.75, 0.75}, {12.25, -0.25}, {21.25, 4.25}, {18.75, 5.25}, {0, 0}, {-7.75, -1.25}, {-5.75, -1.75}, {-3.25, -2.75}, {7.75, 1.25}, {5.75, 1.75}, {3.25, 2.75}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 216
- + nb_component : 6
- + allocated size : 216
- + memory size : 10.12KiByte
- + values : {{13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 81
- + nb_component : 3
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{-0.5, -0.5, -0.5}, {0.5, -0.5, -0.5}, {-0.5, 0.5, -0.5}, {0.5, 0.5, -0.5}, {-0.5, -0.5, 0.5}, {0.5, -0.5, 0.5}, {0.5, 0.5, 0.5}, {-0.5, 0.5, 0.5}, {0, -0.5, -0.5}, {-0.25, -0.5, -0.5}, {0.25, -0.5, -0.5}, {0, 0.5, -0.5}, {-0.25, 0.5, -0.5}, {0.25, 0.5, -0.5}, {-0.5, 0, -0.5}, {-0.5, -0.25, -0.5}, {-0.5, 0.25, -0.5}, {0.5, 0, -0.5}, {0.5, -0.25, -0.5}, {0.5, 0.25, -0.5}, {0, -0.5, 0.5}, {-0.25, -0.5, 0.5}, {0.25, -0.5, 0.5}, {0.5, 0, 0.5}, {0.5, -0.25, 0.5}, {0.5, 0.25, 0.5}, {0, 0.5, 0.5}, {0.25, 0.5, 0.5}, {-0.25, 0.5, 0.5}, {-0.5, 0, 0.5}, {-0.5, 0.25, 0.5}, {-0.5, -0.25, 0.5}, {-0.5, -0.5, 0}, {-0.5, -0.5, -0.25}, {-0.5, -0.5, 0.25}, {0.5, -0.5, 0}, {0.5, -0.5, -0.25}, {0.5, -0.5, 0.25}, {0.5, 0.5, 0}, {0.5, 0.5, -0.25}, {0.5, 0.5, 0.25}, {-0.5, 0.5, 0}, {-0.5, 0.5, -0.25}, {-0.5, 0.5, 0.25}, {0, 0, -0.5}, {0, -0.25, -0.5}, {-0.25, 0, -0.5}, {0, 0.25, -0.5}, {0.25, 0, -0.5}, {0, -0.5, 0}, {0, -0.5, -0.25}, {-0.25, -0.5, 0}, {0, -0.5, 0.25}, {0.25, -0.5, 0}, {0.5, 0, 0}, {0.5, 0, -0.25}, {0.5, -0.25, 0}, {0.5, 0, 0.25}, {0.5, 0.25, 0}, {0, 0.5, 0}, {-0.25, 0.5, 0}, {0, 0.5, -0.25}, {0, 0.5, 0.25}, {0.25, 0.5, 0}, {-0.5, 0, 0}, {-0.5, -0.25, 0}, {-0.5, 0, -0.25}, {-0.5, 0, 0.25}, {-0.5, 0.25, 0}, {0, 0, 0.5}, {0, -0.25, 0.5}, {-0.25, 0, 0.5}, {0, 0.25, 0.5}, {0.25, 0, 0.5}, {0, 0, 0}, {0, 0, -0.25}, {0, -0.25, 0}, {-0.25, 0, 0}, {0, 0, 0.25}, {0, 0.25, 0}, {0.25, 0, 0}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 216
- + nb_component : 9
- + allocated size : 216
- + memory size : 15.19KiByte
- + values : {{1, 5.41234e-16, 8.43076e-16, 9.4369e-16, 1, 0, 1.66533e-16, 1.66533e-16, 1}, {1, -1.56125e-16, -1.66533e-16, -1.11022e-16, 1, -3.60822e-16, -7.77156e-16, -6.93889e-16, 1}, {1, -7.59809e-16, -8.11851e-16, -2.08167e-17, 1, -3.1572e-16, -4.85723e-17, 5.30825e-16, 1}, {1, -3.46945e-16, -2.498e-16, -1.55155e-16, 1, -1.11022e-16, -4.44089e-16, -5.55112e-16, 1}, {1, -9.71445e-17, -1.38778e-16, -9.67996e-17, 1, -2.77556e-17, 5.55112e-17, 0, 1}, {1, -9.71445e-17, -2.498e-16, 1.01541e-17, 1, -3.81639e-17, -6.93889e-17, -6.93889e-17, 1}, {1, -6.93889e-17, -5.27356e-16, -6.10623e-16, 1, 2.77556e-17, 3.33067e-16, 0, 1}, {1, 1.73472e-17, -2.77556e-17, -8.32667e-17, 1, -3.60822e-16, -8.32667e-17, 4.16334e-17, 1}, {1, -7.97973e-17, 1.38778e-16, 5.55112e-17, 1, -4.51028e-16, 6.93889e-17, -6.93889e-18, 1}, {1, 2.91434e-16, -2.22045e-16, 0, 1, -1.11022e-16, 1.11022e-16, 1.94289e-16, 1}, {1, 1.52656e-16, 5.55112e-17, 2.22045e-16, 1, 0, 2.77556e-17, -8.32667e-17, 1}, {1, -1.52656e-16, -1.66533e-16, -8.32667e-17, 1, 2.77556e-17, 0, -6.59195e-17, 1}, {1, -1.11022e-16, -8.32667e-17, 1.53001e-16, 1, 5.55112e-17, -1.11022e-16, 0, 1}, {1, 0, 5.55112e-17, 0, 1, 0, 5.55112e-17, 0, 1}, {1, 0, 2.77556e-16, 2.19123e-17, 1, 1.31839e-16, -1.38778e-17, -2.77556e-17, 1}, {1, 5.55112e-17, 5.55112e-17, -2.22045e-16, 1, -1.66533e-16, -5.55112e-17, 0, 1}, {1, 2.77556e-17, 1.11022e-16, -1.11022e-16, 1, -2.498e-16, -2.77556e-17, 5.55112e-17, 1}, {1, -2.77556e-17, 1.11022e-16, -5.55112e-17, 1, -7.63278e-17, 2.77556e-17, -1.38778e-17, 1}, {1, -3.33067e-16, -2.42861e-17, -8.88178e-16, 1, 2.77556e-17, -7.21645e-16, -7.21645e-16, 1}, {1, -5.55112e-17, 2.08167e-17, -2.22045e-16, 1, 0, -8.32667e-17, -2.35922e-16, 1}, {1, 5.55112e-16, 3.46945e-18, -5.55112e-17, 1, -5.89806e-17, 0, 3.747e-16, 1}, {1, -5.55112e-17, -2.77556e-17, -2.07296e-17, 1, 0, -6.66134e-16, -3.33067e-16, 1}, {1, 1.11022e-16, 2.77556e-17, 1.32935e-16, 1, 2.77556e-17, 5.55112e-17, -1.38778e-16, 1}, {1, -5.55112e-17, -2.77556e-17, 8.9301e-18, 1, -1.73472e-17, -4.16334e-17, 2.08167e-17, 1}, {1, -1.11022e-16, -5.55112e-17, 0, 1, -2.77556e-17, 4.44089e-16, 0, 1}, {1, 0, 0, 0, 1, -2.77556e-17, 1.38778e-16, -6.93889e-17, 1}, {1, -5.55112e-17, 0, 0, 1, -1.17961e-16, -1.04083e-16, -1.21431e-16, 1}, {1, -2.04697e-16, -2.77556e-17, -3.33067e-16, 1, 1.11022e-16, 4.996e-16, 1.38778e-16, 1}, {1, 0, 0, -3.60822e-16, 1, 0, -1.94289e-16, 2.08167e-16, 1}, {1, -2.77556e-17, -1.38778e-17, -3.46945e-17, 1, -6.93889e-17, 6.93889e-17, -6.45317e-16, 1}, {1, -2.498e-16, 5.55112e-17, -7.76648e-17, 1, 1.52147e-17, -1.11022e-16, -2.22045e-16, 1}, {1, 0, 0, -1.11626e-17, 1, -2.71516e-18, -1.11022e-16, 5.55112e-17, 1}, {1, 1.66533e-16, 0, 1.63516e-17, 1, 3.22206e-17, -5.55112e-17, -1.11022e-16, 1}, {1, -3.46945e-17, 6.93889e-17, 2.77556e-16, 1, -5.55112e-17, 1.11022e-16, 5.55112e-17, 1}, {1, 0, 0, 0, 1, -5.55112e-17, 0, 0, 1}, {1, -2.08167e-17, 4.16334e-17, -2.77556e-17, 1, -2.77556e-17, 1.31839e-16, 5.20417e-17, 1}, {1, -2.77556e-17, -2.77556e-17, 4.44089e-16, 1, 2.22045e-16, 1.11022e-16, 1.66533e-16, 1}, {1, 0, 0, 2.22045e-16, 1, 0, 0, 0, 1}, {1, -4.16334e-16, -2.77556e-17, 1.38778e-16, 1, 0, 0, -6.245e-17, 1}, {1, 1.11022e-16, 0, -6.93889e-17, 1, 4.16334e-17, 2.22045e-16, 0, 1}, {1, 0, 0, 1.38778e-17, 1, 1.38778e-17, -1.11022e-16, 0, 1}, {1, 0, -1.11022e-16, 2.77556e-17, 1, -6.93889e-17, -5.55112e-17, -2.08167e-17, 1}, {1, -6.93889e-17, -3.60822e-16, -2.22045e-16, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 2.77556e-17, 0, 1}, {1, -9.71445e-17, -1.66533e-16, -2.77556e-17, 1, -1.11022e-16, 3.46945e-17, -5.20417e-17, 1}, {1, 2.77556e-17, 4.996e-16, -4.44089e-16, 1, 8.88178e-16, 3.33067e-16, -5.55112e-17, 1}, {1, 0, 0, -2.22045e-16, 1, 4.44089e-16, 8.32667e-17, 1.38778e-16, 1}, {1, 4.16334e-16, -2.22045e-16, 0, 1, 6.10623e-16, 2.08167e-17, 7.70217e-16, 1}, {1, -2.22045e-16, 0, -1.16711e-16, 1, 6.12002e-17, -4.44089e-16, 2.22045e-16, 1}, {1, 0, 0, 1.35329e-17, 1, 4.19782e-17, -1.11022e-16, -5.55112e-17, 1}, {1, 0, 1.11022e-16, -5.68906e-18, 1, -4.98221e-17, -2.77556e-17, -2.77556e-17, 1}, {1, -8.32667e-17, 0, 0, 1, 4.44089e-16, 0, -2.77556e-17, 1}, {1, 0, 0, 0, 1, -4.44089e-16, -1.38778e-16, -1.38778e-17, 1}, {1, -8.32667e-17, -5.55112e-17, 0, 1, 1.11022e-16, -1.17961e-16, -1.73472e-17, 1}, {1, 7.63278e-17, -2.11636e-16, 7.21645e-16, 1, -2.77556e-17, -1.11022e-16, 0, 1}, {1, -1.73472e-17, -4.16334e-17, -1.38778e-16, 1, 1.38778e-16, 2.77556e-16, 1.94289e-16, 1}, {1, 2.77556e-17, -1.04083e-17, -6.93889e-17, 1, 5.55112e-17, 6.93889e-17, 1.80411e-16, 1}, {1, 3.26128e-16, -2.498e-16, 1.55155e-16, 1, 1.11022e-16, -6.66134e-16, 5.55112e-17, 1}, {1, 8.32667e-17, -1.38778e-16, 9.67996e-17, 1, 2.77556e-17, -2.77556e-16, 2.22045e-16, 1}, {1, 2.08167e-17, -2.498e-16, -1.01541e-17, 1, 3.81639e-17, -5.55112e-17, 1.80411e-16, 1}, {1, -3.1225e-16, 2.22045e-16, 5.55112e-17, 1, -2.77556e-17, -8.88178e-16, 5.55112e-17, 1}, {1, 6.93889e-17, -8.32667e-17, 1.38778e-16, 1, 3.60822e-16, 5.55112e-17, -3.88578e-16, 1}, {1, -1.04083e-17, 9.4369e-16, 6.93889e-17, 1, -6.93889e-18, 1.17961e-16, -7.38992e-16, 1}, {1, -1.38778e-17, -5.55112e-17, -2.22045e-16, 1, -1.11022e-16, 0, 2.77556e-17, 1}, {1, 0, 2.77556e-17, 0, 1, -1.11022e-16, 8.32667e-17, 1.38778e-17, 1}, {1, 5.55112e-17, 1.66533e-16, -2.77556e-17, 1, -7.63278e-17, 6.93889e-18, -6.93889e-18, 1}, {1, 8.32667e-17, -2.498e-16, -1.53001e-16, 1, -5.55112e-17, 0, 0, 1}, {1, 0, 2.77556e-17, -1.38778e-17, 1, -2.77556e-17, 0, -5.55112e-17, 1}, {1, 0, -1.94289e-16, -2.50404e-17, 1, -1.04083e-16, 0, 8.32667e-17, 1}, {1, -6.93889e-16, -1.66533e-16, 2.22045e-16, 1, -3.33067e-16, 1.66533e-16, -8.32667e-17, 1}, {1, -4.16334e-17, 0, -1.11022e-16, 1, -5.55112e-17, 0, 5.55112e-17, 1}, {1, 2.22045e-16, 2.22045e-16, -2.77556e-17, 1, 1.38778e-17, 6.93889e-18, 1.21431e-16, 1}, {1, -2.77556e-17, -1.14492e-16, 0, 1, 2.77556e-17, 1.66533e-16, 0, 1}, {1, 2.77556e-17, 1.38778e-17, 0, 1, -5.55112e-17, 2.77556e-17, 2.77556e-17, 1}, {1, 0, -6.59195e-17, -1.11022e-16, 1, 6.59195e-17, -9.71445e-17, -1.38778e-17, 1}, {1, -3.33067e-16, 2.77556e-17, 6.99845e-17, 1, -8.32667e-17, 2.22045e-16, -1.11022e-16, 1}, {1, -5.55112e-17, 2.77556e-17, -1.32935e-16, 1, -2.77556e-17, -2.22045e-16, 2.498e-16, 1}, {1, 3.88578e-16, -2.77556e-17, -8.9301e-18, 1, 1.04083e-17, -8.32667e-17, -1.04083e-16, 1}, {1, 5.82867e-16, 2.77556e-17, 8.88178e-16, 1, -2.77556e-17, -9.4369e-16, -2.77556e-17, 1}, {1, -5.55112e-17, 0, 0, 1, -2.77556e-17, -5.55112e-17, -5.55112e-17, 1}, {1, -4.44089e-16, 0, -5.55112e-17, 1, -3.81639e-17, 7.63278e-17, -1.9082e-16, 1}, {1, 6.93889e-18, -8.32667e-17, 2.77556e-16, 1, -5.55112e-17, -1.11022e-16, -2.77556e-17, 1}, {1, -1.04083e-17, 1.38778e-17, -1.11022e-16, 1, 0, -1.38778e-16, -1.38778e-17, 1}, {1, 6.59195e-17, -2.77556e-17, 2.77556e-17, 1, -7.63278e-17, 2.15106e-16, 8.67362e-17, 1}, {1, 1.11022e-16, 0, -8.70775e-17, 1, 3.85053e-17, 6.66134e-16, 3.33067e-16, 1}, {1, -1.38778e-17, 0, 0, 1, 0, 0, 1.38778e-16, 1}, {1, -3.46945e-16, 0, 0, 1, 0, -8.32667e-17, -2.35922e-16, 1}, {1, -3.67761e-16, -1.38778e-17, -5.55112e-17, 1, 0, 5.55112e-17, 1.66533e-16, 1}, {1, 4.51028e-17, 0, 2.22045e-16, 1, 0, -2.77556e-17, -6.93889e-17, 1}, {1, -2.42861e-17, 6.93889e-18, 3.46945e-17, 1, -4.85723e-17, 1.45717e-16, 2.46331e-16, 1}, {1, -4.16334e-17, -1.11022e-16, 0, 1, 0, -5.55112e-17, 0, 1}, {1, -2.77556e-17, -1.11022e-16, -2.22045e-16, 1, -1.11022e-16, -5.55112e-17, 2.77556e-17, 1}, {1, 5.55112e-17, -1.38778e-16, 0, 1, 5.55112e-17, 2.08167e-17, 3.46945e-17, 1}, {1, -2.77556e-17, 0, 0, 1, 0, 0, 0, 1}, {1, -2.77556e-17, 0, 0, 1, 0, -5.55112e-17, 1.38778e-16, 1}, {1, 1.94289e-16, -2.22045e-16, 0, 1, 0, 1.38778e-17, -1.11022e-16, 1}, {1, -3.46945e-16, 2.498e-16, 0, 1, -2.22045e-16, 1.66533e-16, -1.94289e-16, 1}, {1, 6.93889e-17, 5.55112e-17, 0, 1, -3.33067e-16, 2.77556e-17, -2.63678e-16, 1}, {1, 6.93889e-17, -2.498e-16, -5.55112e-17, 1, 8.32667e-17, 2.77556e-17, -2.77556e-17, 1}, {1, -1.11022e-16, 4.996e-16, 0, 1, 0, -3.33067e-16, 5.55112e-17, 1}, {1, 0, -5.55112e-17, 0, 1, 0, 2.22045e-16, 0, 1}, {1, -2.77556e-17, -5.55112e-17, 0, 1, 5.55112e-17, 1.38778e-17, -3.81639e-17, 1}, {1, 1.11022e-16, 4.44089e-16, 0, 1, 0, 3.33067e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 2.77556e-17, 1}, {1, 1.11022e-16, -4.44089e-16, 0, 1, 0, -1.38778e-17, -1.38778e-16, 1}, {1, 7.49401e-16, 1.4988e-15, 8.88178e-16, 1, 0, -1.11022e-16, 1.11022e-16, 1}, {1, 1.11022e-16, 5.55112e-17, 2.22045e-16, 1, 0, 3.60822e-16, 2.63678e-16, 1}, {1, 1.94289e-16, -4.996e-16, -5.55112e-17, 1, 1.66533e-16, -1.04083e-16, -3.64292e-16, 1}, {1, 5.34295e-16, 4.54498e-16, -7.63278e-17, 1, -2.77556e-16, 7.63278e-17, -1.11022e-16, 1}, {1, 1.56125e-16, 1.66533e-16, 0, 1, -1.38778e-16, -4.16334e-17, -7.07767e-16, 1}, {1, -2.60209e-16, -4.57967e-16, -5.06539e-16, 1, -1.2837e-16, -3.43475e-16, 5.96745e-16, 1}, {1, 1.38778e-17, 2.498e-16, -1.73472e-17, 1, -5.55112e-17, 8.32667e-17, -1.66533e-16, 1}, {1, 9.71445e-17, 1.38778e-16, 8.32667e-17, 1, -8.32667e-17, 2.22045e-16, 1.11022e-16, 1}, {1, 5.13478e-16, 3.60822e-16, 6.93889e-17, 1, -7.28584e-17, 6.10623e-16, 1.45717e-16, 1}, {1, 4.85723e-17, 2.77556e-17, 4.16334e-17, 1, -3.05311e-16, 2.77556e-17, -8.32667e-17, 1}, {1, -1.73472e-17, 2.77556e-17, 1.04083e-16, 1, -3.60822e-16, 2.22045e-16, -6.93889e-17, 1}, {1, -1.73472e-17, 9.71445e-16, -3.1572e-16, 1, -2.87964e-16, -3.88578e-16, -7.63278e-17, 1}, {1, 4.30211e-16, -1.11022e-16, 5.55112e-17, 1, 1.66533e-16, 6.93889e-18, -2.77556e-17, 1}, {1, -1.52656e-16, -5.55112e-17, 2.77556e-17, 1, 0, 2.77556e-17, -1.38778e-16, 1}, {1, -2.91434e-16, 1.66533e-16, -2.498e-16, 1, -2.01228e-16, 8.32667e-17, -1.14492e-16, 1}, {1, 0, 5.55112e-17, 0, 1, 0, -1.38778e-17, 1.11022e-16, 1}, {1, 0, -5.55112e-17, 0, 1, 0, 5.55112e-17, 0, 1}, {1, -1.66533e-16, -5.55112e-17, -4.16334e-17, 1, 0, -5.55112e-17, 0, 1}, {1, 1.38778e-17, 1.66533e-16, 2.77556e-17, 1, -1.66533e-16, 0, 2.77556e-17, 1}, {1, -2.77556e-17, -1.11022e-16, 3.33067e-16, 1, -2.22045e-16, 1.11022e-16, 0, 1}, {1, -8.32667e-17, 0, 4.16334e-17, 1, -1.31839e-16, -8.32667e-17, -2.08167e-17, 1}, {1, 7.77156e-16, 5.20417e-17, -2.77556e-17, 1, 2.77556e-17, -8.32667e-17, 4.16334e-16, 1}, {1, 5.55112e-17, -2.08167e-17, -5.55112e-17, 1, 0, 1.11022e-16, -8.32667e-17, 1}, {1, -1.11022e-16, -3.46945e-18, -1.94289e-16, 1, 4.16334e-17, 2.63678e-16, -7.84095e-16, 1}, {1, 2.77556e-16, 2.77556e-17, 2.77556e-17, 1, 0, 5.55112e-17, -1.11022e-16, 1}, {1, -1.11022e-16, -2.77556e-17, -5.55112e-17, 1, 2.77556e-17, 2.22045e-16, -1.11022e-16, 1}, {1, 5.55112e-17, -5.55112e-17, -5.55112e-17, 1, -1.38778e-17, 8.60423e-16, -1.45717e-16, 1}, {1, 5.55112e-17, 5.55112e-17, 2.77556e-17, 1, -5.55112e-17, 5.55112e-17, -2.77556e-17, 1}, {1, 0, 0, 3.33067e-16, 1, -2.77556e-17, 5.55112e-17, -1.38778e-16, 1}, {1, 1.11022e-16, 1.11022e-16, -1.38778e-16, 1, -3.46945e-17, -1.66533e-16, 9.36751e-17, 1}, {1, -4.4062e-16, -6.93889e-18, 6.93889e-18, 1, 0, 7.63278e-17, -2.498e-16, 1}, {1, 4.51028e-17, 1.38778e-17, -1.249e-16, 1, 0, -2.35922e-16, 4.57967e-16, 1}, {1, 2.94903e-16, 0, 5.20417e-17, 1, 1.38778e-17, -3.1572e-16, -6.07153e-16, 1}, {1, -2.498e-16, -5.55112e-17, -3.46945e-18, 1, 3.85053e-17, 0, -2.22045e-16, 1}, {1, -1.38778e-17, 0, 0, 1, 0, 2.77556e-17, -1.38778e-16, 1}, {1, 2.22045e-16, 0, 0, 1, 0, -2.498e-16, 1.11022e-16, 1}, {1, 4.85723e-17, -4.16334e-17, 2.77556e-17, 1, 0, -5.55112e-17, 2.77556e-17, 1}, {1, -1.04083e-17, 0, -2.77556e-16, 1, 0, 2.22045e-16, 4.16334e-17, 1}, {1, 5.55112e-17, 2.08167e-17, -1.17961e-16, 1, 2.77556e-17, -1.38778e-16, 4.51028e-17, 1}, {1, 4.16334e-16, 2.77556e-17, 0, 1, -6.66134e-16, 3.46945e-18, -8.32667e-17, 1}, {1, 6.93889e-17, -8.32667e-17, -1.66533e-16, 1, 1.11022e-16, -4.85723e-17, 2.22045e-16, 1}, {1, 4.71845e-16, -2.22045e-16, -1.66533e-16, 1, 0, 2.25514e-16, -7.97973e-17, 1}, {1, 8.32667e-17, 0, 0, 1, 0, 1.38778e-17, 0, 1}, {1, 0, 0, 0, 1, 0, -5.55112e-17, -1.38778e-16, 1}, {1, 0, -2.22045e-16, 0, 1, 0, 5.55112e-17, 0, 1}, {1, 1.38778e-17, 2.77556e-17, 4.16334e-17, 1, 0, 0, 0, 1}, {1, -2.77556e-17, 5.55112e-17, -5.55112e-17, 1, 3.33067e-16, 0, -5.55112e-17, 1}, {1, -4.16334e-17, -2.77556e-17, -1.249e-16, 1, 1.94289e-16, 2.77556e-17, 0, 1}, {1, -5.82867e-16, 2.77556e-16, -5.55112e-17, 1, 4.44089e-16, -2.77556e-17, -2.77556e-17, 1}, {1, 1.11022e-16, -5.55112e-17, 2.77556e-16, 1, 0, -4.71845e-16, 4.44089e-16, 1}, {1, -1.94289e-16, 3.88578e-16, 1.66533e-16, 1, 3.33067e-16, -1.00614e-16, 4.78784e-16, 1}, {1, -1.11022e-16, 4.44089e-16, 0, 1, 0, 0, 3.88578e-16, 1}, {1, 0, 0, 0, 1, 0, 8.32667e-17, -1.38778e-16, 1}, {1, 1.11022e-16, -4.44089e-16, 0, 1, 0, -1.249e-16, -1.38778e-17, 1}, {1, -1.66533e-16, 2.22045e-16, 5.55112e-17, 1, 0, 5.55112e-17, 0, 1}, {1, 0, 5.55112e-17, -5.55112e-17, 1, 0, 0, -2.77556e-17, 1}, {1, -5.55112e-17, -7.77156e-16, -1.02696e-15, 1, -5.55112e-17, -1.38778e-16, -2.77556e-17, 1}, {1, 1.73472e-17, -3.46945e-16, -8.67362e-17, 1, -1.38778e-16, 1.17961e-16, 2.77556e-17, 1}, {1, 1.73472e-17, 4.16334e-17, -1.11022e-16, 1, 1.38778e-16, 1.80411e-16, 8.32667e-17, 1}, {1, 7.28584e-17, 3.22659e-16, 3.46945e-16, 1, -5.23886e-16, 1.66533e-16, 5.55112e-17, 1}, {1, -2.91434e-16, 2.498e-16, 1.73472e-17, 1, 5.55112e-17, 8.32667e-17, 3.33067e-16, 1}, {1, -8.32667e-17, 1.38778e-16, -8.32667e-17, 1, 1.11022e-16, -2.77556e-16, -2.77556e-16, 1}, {1, -1.11022e-16, 1.38778e-16, -6.93889e-17, 1, 7.28584e-17, 3.60822e-16, 4.64906e-16, 1}, {1, 6.93889e-18, 8.32667e-17, -4.85723e-17, 1, 2.77556e-16, -2.77556e-17, 0, 1}, {1, -6.93889e-17, 8.32667e-17, -6.93889e-17, 1, 3.60822e-16, 4.996e-16, 5.27356e-16, 1}, {1, -3.67761e-16, 8.88178e-16, 5.55112e-17, 1, -1.59595e-16, -2.498e-16, -2.94903e-16, 1}, {1, -1.38778e-17, -2.22045e-16, 0, 1, 1.11022e-16, 0, 0, 1}, {1, 0, -2.77556e-17, 2.77556e-17, 1, -1.38778e-16, 0, 0, 1}, {1, 5.55112e-17, 2.22045e-16, 6.38378e-16, 1, -1.17961e-16, 2.08167e-17, 6.93889e-18, 1}, {1, 0, 2.77556e-17, 0, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, -2.77556e-17, 0, 0, 1}, {1, 5.55112e-17, 2.77556e-17, 4.16334e-17, 1, 0, 0, 0, 1}, {1, 4.30211e-16, 5.55112e-17, -2.77556e-17, 1, -1.66533e-16, 0, -1.11022e-16, 1}, {1, 4.16334e-17, 0, 8.32667e-17, 1, -1.38778e-16, 0, 0, 1}, {1, -4.57967e-16, 0, -1.52656e-16, 1, -1.17961e-16, -8.32667e-17, 1.38778e-16, 1}, {1, -2.77556e-17, 2.42861e-17, 8.32667e-17, 1, 5.55112e-17, 4.85723e-17, 0, 1}, {1, -2.77556e-17, -1.38778e-17, -2.22045e-16, 1, -5.55112e-17, -2.22045e-16, 9.71445e-17, 1}, {1, 2.77556e-17, -1.04083e-17, -2.77556e-17, 1, -1.38778e-17, -2.42861e-17, -2.08167e-17, 1}, {1, -2.77556e-16, 2.77556e-17, 0, 1, -2.77556e-17, 4.16334e-17, -1.66533e-16, 1}, {1, 5.55112e-17, -2.77556e-17, 5.55112e-17, 1, -2.77556e-17, 2.77556e-16, 2.77556e-16, 1}, {1, 0, -5.55112e-17, 5.55112e-17, 1, 6.93889e-18, 5.82867e-16, -2.08167e-17, 1}, {1, 7.21645e-16, -2.77556e-17, 2.77556e-17, 1, 1.38778e-16, 5.55112e-17, 1.38778e-16, 1}, {1, 5.55112e-17, 0, -5.55112e-17, 1, -2.77556e-17, -1.66533e-16, 3.33067e-16, 1}, {1, -7.49401e-16, 2.77556e-17, 5.55112e-17, 1, -3.46945e-18, -2.22045e-16, 2.42861e-17, 1}, {1, -2.77556e-17, -2.77556e-17, -9.02056e-17, 1, 0, 9.36751e-17, -2.77556e-17, 1}, {1, 0, 0, 1.38778e-17, 1, 1.11022e-16, -2.35922e-16, 8.32667e-17, 1}, {1, 6.93889e-17, 3.46945e-17, 3.53884e-16, 1, 4.16334e-17, 2.46331e-16, 7.63278e-17, 1}, {1, 2.77556e-16, 0, 3.46945e-17, 1, 1.52147e-17, 6.93889e-17, 2.22045e-16, 1}, {1, 0, 0, 1.38778e-17, 1, -2.71516e-18, 1.38778e-16, 2.77556e-17, 1}, {1, -2.498e-16, 0, -4.51028e-17, 1, 3.22206e-17, -4.85723e-16, -2.35922e-16, 1}, {1, 1.17961e-16, -4.16334e-17, -5.55112e-17, 1, -5.55112e-17, 5.55112e-17, -1.38778e-16, 1}, {1, 0, 0, -1.11022e-16, 1, 0, 3.33067e-16, -2.77556e-16, 1}, {1, -3.26128e-16, 6.93889e-17, -7.63278e-17, 1, -6.93889e-18, 1.94289e-16, -9.02056e-17, 1}, {1, -1.38778e-17, 2.498e-16, 0, 1, 2.22045e-16, 3.46945e-17, 2.77556e-17, 1}, {1, 0, 0, -1.94289e-16, 1, 0, -1.11022e-16, 1.38778e-17, 1}, {1, -5.55112e-17, -2.77556e-17, -4.85723e-16, 1, -1.38778e-16, -2.77556e-17, -3.46945e-18, 1}, {1, 5.55112e-17, 0, 2.77556e-17, 1, 6.93889e-17, 2.77556e-17, 0, 1}, {1, 0, 0, 2.77556e-17, 1, 1.38778e-17, 1.38778e-16, -5.55112e-17, 1}, {1, 1.66533e-16, 1.11022e-16, -6.93889e-17, 1, -9.71445e-17, -2.63678e-16, -4.85723e-17, 1}, {1, 1.38778e-16, -1.66533e-16, 4.16334e-17, 1, 0, 2.77556e-17, -1.11022e-16, 1}, {1, 0, 0, 2.77556e-17, 1, 0, 0, 5.55112e-17, 1}, {1, 1.66533e-16, 1.11022e-16, 3.60822e-16, 1, 8.32667e-17, -2.22045e-16, -9.36751e-17, 1}, {1, -2.77556e-17, 2.22045e-16, 5.55112e-17, 1, 8.88178e-16, -6.93889e-18, 8.32667e-17, 1}, {1, 0, 0, -1.11022e-16, 1, 4.44089e-16, 1.38778e-17, 6.93889e-17, 1}, {1, 2.77556e-17, 3.88578e-16, -5.82867e-16, 1, -2.22045e-16, -9.29812e-16, -2.08167e-17, 1}, {1, 5.55112e-17, 0, 0, 1, 6.12002e-17, 2.77556e-17, 0, 1}, {1, 0, 0, 0, 1, 4.19782e-17, 2.77556e-17, -2.77556e-17, 1}, {1, -2.77556e-16, -1.11022e-16, -1.11022e-16, 1, -4.98221e-17, 2.63678e-16, -1.80411e-16, 1}, {1, 2.22045e-16, -4.44089e-16, 2.77556e-17, 1, -8.88178e-16, 8.32667e-17, -1.11022e-16, 1}, {1, 0, 0, -1.11022e-16, 1, -4.44089e-16, 0, -1.249e-16, 1}, {1, 2.77556e-16, 1.11022e-16, -1.66533e-16, 1, -3.33067e-16, 5.55112e-17, 7.28584e-17, 1}}
-]
-
diff --git a/test/test_fe_engine/test_gradient_hexahedron_8.verified b/test/test_fe_engine/test_gradient_hexahedron_8.verified
index 02a682dee..039eba426 100644
--- a/test/test_fe_engine/test_gradient_hexahedron_8.verified
+++ b/test/test_fe_engine/test_gradient_hexahedron_8.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 125
- + nb_component : 2
- + allocated size : 125
- + memory size : 1.95KiByte
- + values : {{0, 0}, {13, 11}, {23, 7}, {36, 18}, {31, 5}, {44, 16}, {54, 12}, {67, 23}, {57.25, 14.75}, {60.5, 17.5}, {63.75, 20.25}, {59.25, 21.75}, {51.5, 20.5}, {43.75, 19.25}, {32.75, 15.25}, {29.5, 12.5}, {26.25, 9.75}, {30.75, 8.25}, {38.5, 9.5}, {46.25, 10.75}, {7.75, 1.25}, {15.5, 2.5}, {23.25, 3.75}, {34.25, 7.75}, {37.5, 10.5}, {40.75, 13.25}, {36.25, 14.75}, {28.5, 13.5}, {20.75, 12.25}, {9.75, 8.25}, {6.5, 5.5}, {3.25, 2.75}, {17.25, 5.25}, {11.5, 3.5}, {5.75, 1.75}, {48.25, 10.25}, {42.5, 8.5}, {36.75, 6.75}, {61.25, 21.25}, {55.5, 19.5}, {49.75, 17.75}, {30.25, 16.25}, {24.5, 14.5}, {18.75, 12.75}, {51.5, 13}, {45.75, 11.25}, {40, 9.5}, {54.75, 15.75}, {49, 14}, {43.25, 12.25}, {58, 18.5}, {52.25, 16.75}, {46.5, 15}, {40.5, 16.5}, {48.25, 17.75}, {56, 19}, {37.25, 13.75}, {45, 15}, {52.75, 16.25}, {34, 11}, {41.75, 12.25}, {49.5, 13.5}, {26.5, 6.5}, {18.75, 5.25}, {11, 4}, {29.75, 9.25}, {22, 8}, {14.25, 6.75}, {33, 12}, {25.25, 10.75}, {17.5, 9.5}, {27, 13.5}, {21.25, 11.75}, {15.5, 10}, {23.75, 10.75}, {18, 9}, {12.25, 7.25}, {20.5, 8}, {14.75, 6.25}, {9, 4.5}, {25, 6.5}, {19.25, 4.75}, {13.5, 3}, {32.75, 7.75}, {27, 6}, {21.25, 4.25}, {40.5, 9}, {34.75, 7.25}, {29, 5.5}, {53.5, 20}, {45.75, 18.75}, {38, 17.5}, {47.75, 18.25}, {40, 17}, {32.25, 15.75}, {42, 16.5}, {34.25, 15.25}, {26.5, 14}, {50.25, 17.25}, {47, 14.5}, {43.75, 11.75}, {42.5, 16}, {39.25, 13.25}, {36, 10.5}, {34.75, 14.75}, {31.5, 12}, {28.25, 9.25}, {44.5, 15.5}, {41.25, 12.75}, {38, 10}, {36.75, 14.25}, {33.5, 11.5}, {30.25, 8.75}, {29, 13}, {25.75, 10.25}, {22.5, 7.5}, {38.75, 13.75}, {35.5, 11}, {32.25, 8.25}, {31, 12.5}, {27.75, 9.75}, {24.5, 7}, {23.25, 11.25}, {20, 8.5}, {16.75, 5.75}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 512
- + nb_component : 6
- + allocated size : 512
- + memory size : 24.00KiByte
- + values : {{13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 125
- + nb_component : 3
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0}, {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {1, 1, 1}, {0.25, 1, 1}, {0.5, 1, 1}, {0.75, 1, 1}, {1, 1, 0.75}, {1, 1, 0.5}, {1, 1, 0.25}, {0.75, 1, 0}, {0.5, 1, 0}, {0.25, 1, 0}, {0, 1, 0.25}, {0, 1, 0.5}, {0, 1, 0.75}, {0, 0, 0.25}, {0, 0, 0.5}, {0, 0, 0.75}, {0.25, 0, 1}, {0.5, 0, 1}, {0.75, 0, 1}, {1, 0, 0.75}, {1, 0, 0.5}, {1, 0, 0.25}, {0.75, 0, 0}, {0.5, 0, 0}, {0.25, 0, 0}, {0, 0.75, 0}, {0, 0.5, 0}, {0, 0.25, 0}, {0, 0.75, 1}, {0, 0.5, 1}, {0, 0.25, 1}, {1, 0.75, 1}, {1, 0.5, 1}, {1, 0.25, 1}, {1, 0.75, 0}, {1, 0.5, 0}, {1, 0.25, 0}, {0.25, 0.75, 1}, {0.25, 0.5, 1}, {0.25, 0.25, 1}, {0.5, 0.75, 1}, {0.5, 0.5, 1}, {0.5, 0.25, 1}, {0.75, 0.75, 1}, {0.75, 0.5, 1}, {0.75, 0.25, 1}, {0.75, 1, 0.25}, {0.75, 1, 0.5}, {0.75, 1, 0.75}, {0.5, 1, 0.25}, {0.5, 1, 0.5}, {0.5, 1, 0.75}, {0.25, 1, 0.25}, {0.25, 1, 0.5}, {0.25, 1, 0.75}, {0.25, 0, 0.75}, {0.25, 0, 0.5}, {0.25, 0, 0.25}, {0.5, 0, 0.75}, {0.5, 0, 0.5}, {0.5, 0, 0.25}, {0.75, 0, 0.75}, {0.75, 0, 0.5}, {0.75, 0, 0.25}, {0.75, 0.75, 0}, {0.75, 0.5, 0}, {0.75, 0.25, 0}, {0.5, 0.75, 0}, {0.5, 0.5, 0}, {0.5, 0.25, 0}, {0.25, 0.75, 0}, {0.25, 0.5, 0}, {0.25, 0.25, 0}, {0, 0.75, 0.25}, {0, 0.5, 0.25}, {0, 0.25, 0.25}, {0, 0.75, 0.5}, {0, 0.5, 0.5}, {0, 0.25, 0.5}, {0, 0.75, 0.75}, {0, 0.5, 0.75}, {0, 0.25, 0.75}, {1, 0.75, 0.75}, {1, 0.75, 0.5}, {1, 0.75, 0.25}, {1, 0.5, 0.75}, {1, 0.5, 0.5}, {1, 0.5, 0.25}, {1, 0.25, 0.75}, {1, 0.25, 0.5}, {1, 0.25, 0.25}, {0.75, 0.75, 0.75}, {0.5, 0.75, 0.75}, {0.25, 0.75, 0.75}, {0.75, 0.75, 0.5}, {0.5, 0.75, 0.5}, {0.25, 0.75, 0.5}, {0.75, 0.75, 0.25}, {0.5, 0.75, 0.25}, {0.25, 0.75, 0.25}, {0.75, 0.5, 0.75}, {0.5, 0.5, 0.75}, {0.25, 0.5, 0.75}, {0.75, 0.5, 0.5}, {0.5, 0.5, 0.5}, {0.25, 0.5, 0.5}, {0.75, 0.5, 0.25}, {0.5, 0.5, 0.25}, {0.25, 0.5, 0.25}, {0.75, 0.25, 0.75}, {0.5, 0.25, 0.75}, {0.25, 0.25, 0.75}, {0.75, 0.25, 0.5}, {0.5, 0.25, 0.5}, {0.25, 0.25, 0.5}, {0.75, 0.25, 0.25}, {0.5, 0.25, 0.25}, {0.25, 0.25, 0.25}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 512
- + nb_component : 9
- + allocated size : 512
- + memory size : 36.00KiByte
- + values : {{1, 2.22045e-16, 4.44089e-16, 1.11022e-16, 1, 2.22045e-16, 1.11022e-16, 1.38778e-16, 1}, {1, 8.32667e-17, 8.32667e-17, -1.38778e-16, 1, -2.22045e-16, 8.32667e-17, 1.38778e-16, 1}, {1, 4.44089e-16, 6.66134e-16, 0, 1, 3.33067e-16, -1.11022e-16, 1.11022e-16, 1}, {1, 4.44089e-16, -6.66134e-16, -2.77556e-17, 1, -4.44089e-16, -1.11022e-16, -2.22045e-16, 1}, {1, 2.22045e-16, 6.66134e-16, -4.44089e-16, 1, -6.66134e-16, 0, 0, 1}, {1, -1.66533e-16, 2.77556e-17, -3.33067e-16, 1, 3.33067e-16, -1.11022e-16, 2.22045e-16, 1}, {1, 0, 4.44089e-16, -2.22045e-16, 1, -2.22045e-16, 0, 0, 1}, {1, 6.66134e-16, 3.88578e-16, -1.11022e-16, 1, 3.33067e-16, 0, 0, 1}, {1, -1.11022e-16, 5.55112e-17, -5.55112e-17, 1, 1.11022e-16, -2.498e-16, -3.60822e-16, 1}, {1, 6.66134e-16, 6.66134e-16, 1.94289e-16, 1, 8.32667e-17, -1.94289e-16, -1.38778e-16, 1}, {1, 0, -6.66134e-16, -1.11022e-16, 1, 0, 3.88578e-16, 0, 1}, {1, 1.11022e-16, 5.55112e-17, 1.80411e-16, 1, 2.22045e-16, 1.66533e-16, 0, 1}, {1, 7.77156e-16, -1.11022e-16, -2.22045e-16, 1, 2.22045e-16, 0, 0, 1}, {1, 3.60822e-16, 5.55112e-17, 1.66533e-16, 1, 4.44089e-16, -2.22045e-16, 2.22045e-16, 1}, {1, 4.44089e-16, -4.44089e-16, 0, 1, -2.22045e-16, 2.22045e-16, 0, 1}, {1, 0, 5.55112e-16, 3.33067e-16, 1, 3.33067e-16, 0, 0, 1}, {1, 5.55112e-16, 1.11022e-16, 0, 1, -3.33067e-16, 2.08167e-17, 5.55112e-17, 1}, {1, 8.32667e-17, -4.16334e-16, -3.1225e-16, 1, -5.82867e-16, 2.08167e-17, 5.55112e-17, 1}, {1, 4.44089e-16, 0, 0, 1, -1.11022e-16, 2.77556e-17, 1.11022e-16, 1}, {1, -1.11022e-16, 0, -1.31839e-16, 1, -6.10623e-16, 2.77556e-17, 1.11022e-16, 1}, {1, 4.44089e-16, 1.11022e-16, 0, 1, -2.22045e-16, 8.32667e-17, 2.22045e-16, 1}, {1, -2.77556e-17, 5.27356e-16, -5.55112e-17, 1, 2.22045e-16, 8.32667e-17, 0, 1}, {1, 0, -2.22045e-16, 0, 1, -2.22045e-16, 0, 0, 1}, {1, -1.11022e-16, 0, -2.77556e-17, 1, -1.11022e-16, -1.11022e-16, 0, 1}, {1, 0, 2.22045e-16, 0, 1, -2.22045e-16, 0, 1.38778e-16, 1}, {1, -6.38378e-16, 1.11022e-16, -2.77556e-17, 1, 0, 2.77556e-17, -2.77556e-17, 1}, {1, 4.44089e-16, 2.22045e-16, 0, 1, -2.22045e-16, 0, 0, 1}, {1, 0, 3.33067e-16, 0, 1, 1.66533e-16, 0, -1.11022e-16, 1}, {1, 0, 5.55112e-17, 0, 1, 6.66134e-16, -6.93889e-18, -1.11022e-16, 1}, {1, -6.10623e-16, 1.11022e-16, 0, 1, 2.22045e-16, -6.93889e-18, -1.11022e-16, 1}, {1, 0, -4.44089e-16, 2.77556e-17, 1, 2.22045e-16, 2.77556e-17, 0, 1}, {1, 0, 5.55112e-16, 6.93889e-18, 1, -1.11022e-16, 2.77556e-17, 0, 1}, {1, 2.22045e-16, -1.11022e-16, 2.22045e-16, 1, -2.22045e-16, 0, -5.55112e-17, 1}, {1, 1.11022e-16, 9.71445e-17, 3.33067e-16, 1, 4.16334e-16, -2.77556e-17, 5.55112e-17, 1}, {1, 4.44089e-16, 4.44089e-16, -2.22045e-16, 1, 0, -3.33067e-16, -1.11022e-16, 1}, {1, 7.77156e-16, -2.22045e-16, 2.22045e-16, 1, 6.93889e-17, -2.22045e-16, -1.11022e-16, 1}, {1, 0, -5.55112e-17, -4.44089e-16, 1, -4.44089e-16, -4.44089e-16, -2.22045e-16, 1}, {1, 4.996e-16, 5.68989e-16, -3.33067e-16, 1, 5.55112e-17, -4.44089e-16, -4.44089e-16, 1}, {1, 4.44089e-16, -2.22045e-16, -4.44089e-16, 1, -2.22045e-16, 0, 0, 1}, {1, 2.22045e-16, -5.55112e-17, -2.22045e-16, 1, 1.66533e-16, 0, 0, 1}, {1, -2.22045e-16, 3.33067e-16, 1.66533e-16, 1, 5.55112e-17, -2.77556e-17, 2.22045e-16, 1}, {1, -7.77156e-16, -2.08167e-16, -9.71445e-17, 1, -1.52656e-16, -1.38778e-16, 1.66533e-16, 1}, {1, 0, 4.44089e-16, 2.22045e-16, 1, 5.55112e-17, -3.33067e-16, -2.22045e-16, 1}, {1, 1.11022e-16, -1.11022e-16, -4.16334e-16, 1, -2.77556e-17, -5.55112e-17, -2.22045e-16, 1}, {1, 2.22045e-16, 1.11022e-16, 2.22045e-16, 1, 0, -1.11022e-16, 4.44089e-16, 1}, {1, -5.55112e-17, -2.35922e-16, -2.22045e-16, 1, 2.22045e-16, -1.11022e-16, 4.44089e-16, 1}, {1, 0, 2.22045e-16, 0, 1, 2.22045e-16, 0, 0, 1}, {1, 2.22045e-16, -2.77556e-16, -3.88578e-16, 1, 5.55112e-17, 0, 0, 1}, {1, 3.33067e-16, -1.66533e-16, 0, 1, 5.55112e-17, -8.32667e-17, 2.77556e-17, 1}, {1, -8.04912e-16, -8.04912e-16, -1.66533e-16, 1, -4.996e-16, -8.32667e-17, 2.77556e-17, 1}, {1, -4.44089e-16, -2.22045e-16, 0, 1, 2.77556e-16, 2.77556e-17, 2.22045e-16, 1}, {1, 7.77156e-16, 2.22045e-16, -1.94289e-16, 1, -7.21645e-16, 2.77556e-17, 2.22045e-16, 1}, {1, 3.33067e-16, -5.55112e-17, 0, 1, 0, -5.55112e-17, 0, 1}, {1, -3.88578e-16, -2.08167e-16, 8.32667e-17, 1, 5.55112e-17, -5.55112e-17, 0, 1}, {1, -8.88178e-16, 0, 0, 1, 0, 0, 4.44089e-16, 1}, {1, 3.33067e-16, 2.22045e-16, -2.77556e-17, 1, 2.77556e-16, 0, 4.44089e-16, 1}, {1, 3.33067e-16, 4.996e-16, 0, 1, 5.55112e-17, -2.77556e-17, 1.11022e-16, 1}, {1, -1.38778e-16, -1.249e-16, -8.32667e-17, 1, 1.38778e-17, 8.32667e-17, 4.996e-16, 1}, {1, 0, -2.22045e-16, 0, 1, 5.55112e-17, 0, 3.33067e-16, 1}, {1, 1.11022e-16, 1.11022e-16, -1.11022e-16, 1, 1.249e-16, 1.11022e-16, 7.77156e-16, 1}, {1, 1.11022e-16, 2.22045e-16, 0, 1, 0, -1.38778e-17, 2.22045e-16, 1}, {1, 2.77556e-17, 1.38778e-17, 0, 1, -1.66533e-16, -1.38778e-17, 0, 1}, {1, 4.44089e-16, 4.44089e-16, 0, 1, 0, 0, 0, 1}, {1, 4.44089e-16, 2.77556e-16, 2.08167e-17, 1, -4.44089e-16, 0, 0, 1}, {1, 4.44089e-16, 3.33067e-16, 0, 1, -8.32667e-17, 3.05311e-16, 1.38778e-16, 1}, {1, 4.44089e-16, 2.91434e-16, 3.88578e-16, 1, 2.08167e-16, 3.05311e-16, 3.05311e-16, 1}, {1, 0, 3.33067e-16, -3.33067e-16, 1, -8.32667e-17, -3.33067e-16, -1.11022e-16, 1}, {1, 5.55112e-16, -5.55112e-17, 3.88578e-16, 1, 2.42861e-16, -3.33067e-16, -1.11022e-16, 1}, {1, 0, 2.22045e-16, -2.22045e-16, 1, 0, 2.22045e-16, 1.11022e-16, 1}, {1, 8.88178e-16, 3.19189e-16, -3.33067e-16, 1, -1.38778e-16, 1.66533e-16, 1.11022e-16, 1}, {1, 4.44089e-16, 2.22045e-16, -2.22045e-16, 1, -2.22045e-16, 0, 0, 1}, {1, 7.77156e-16, 1.11022e-16, -5.55112e-16, 1, -5.55112e-17, 0, 0, 1}, {1, -1.11022e-16, 0, 0, 1, -1.11022e-16, -2.08167e-16, -2.498e-16, 1}, {1, 3.60822e-16, -2.498e-16, 2.22045e-16, 1, 1.11022e-16, 1.38778e-17, -2.498e-16, 1}, {1, 0, 0, -2.22045e-16, 1, -1.94289e-16, 1.66533e-16, 3.33067e-16, 1}, {1, 0, -3.60822e-16, 3.19189e-16, 1, -6.93889e-18, 3.88578e-16, 3.33067e-16, 1}, {1, 1.11022e-16, -2.77556e-17, -6.66134e-16, 1, -3.33067e-16, 2.77556e-16, 3.33067e-16, 1}, {1, 4.71845e-16, -8.32667e-17, 1.11022e-16, 1, -1.11022e-16, 2.77556e-16, 3.33067e-16, 1}, {1, 0, -1.11022e-16, -4.44089e-16, 1, -2.22045e-16, 0, 0, 1}, {1, -1.11022e-16, -3.88578e-16, 0, 1, -5.55112e-17, -2.22045e-16, 0, 1}, {1, 1.11022e-16, 2.22045e-16, 0, 1, -2.77556e-16, 1.52656e-16, 1.94289e-16, 1}, {1, -1.38778e-16, 8.32667e-17, -1.59595e-16, 1, -1.38778e-17, 1.52656e-16, 8.32667e-17, 1}, {1, 4.44089e-16, -1.11022e-16, -2.22045e-16, 1, -2.77556e-16, 1.11022e-16, 5.55112e-16, 1}, {1, -5.55112e-16, -3.33067e-16, -1.38778e-16, 1, -2.08167e-17, 8.32667e-17, 5.55112e-16, 1}, {1, 1.11022e-16, 2.22045e-16, 0, 1, 1.11022e-16, 2.77556e-17, 1.11022e-16, 1}, {1, -1.11022e-16, 3.46945e-17, 8.32667e-17, 1, -2.77556e-17, 2.77556e-17, 3.33067e-16, 1}, {1, 4.44089e-16, 0, 0, 1, 1.11022e-16, 0, 0, 1}, {1, -5.55112e-16, -2.22045e-16, 2.77556e-17, 1, 1.38778e-16, 0, 0, 1}, {1, 3.33067e-16, 0, 0, 1, 0, -2.77556e-17, -1.94289e-16, 1}, {1, 4.16334e-16, 8.32667e-17, 2.77556e-17, 1, -1.31839e-16, -2.77556e-17, -2.77556e-17, 1}, {1, -4.44089e-16, 1.11022e-16, 0, 1, -2.77556e-17, 1.11022e-16, 1.11022e-16, 1}, {1, -2.22045e-16, 2.22045e-16, -2.77556e-17, 1, -1.52656e-16, 0, 5.55112e-16, 1}, {1, 2.22045e-16, -2.77556e-17, 0, 1, 0, 1.38778e-17, 0, 1}, {1, 5.27356e-16, 2.77556e-16, 0, 1, -1.38778e-16, 2.08167e-17, 0, 1}, {1, -4.44089e-16, 0, 0, 1, 0, -2.77556e-17, -4.44089e-16, 1}, {1, -1.11022e-16, -8.32667e-17, -6.93889e-18, 1, -1.66533e-16, -2.77556e-17, -4.44089e-16, 1}, {1, 0, -6.93889e-18, 2.22045e-16, 1, 0, -2.22045e-16, -1.66533e-16, 1}, {1, -5.55112e-16, -1.11022e-16, 1.11022e-16, 1, 0, -2.498e-16, -1.66533e-16, 1}, {1, -4.44089e-16, 0, 2.22045e-16, 1, 0, -5.55112e-17, 2.22045e-16, 1}, {1, 2.22045e-16, 0, 5.55112e-17, 1, 0, -5.55112e-17, -2.22045e-16, 1}, {1, 5.55112e-16, -6.93889e-18, 4.44089e-16, 1, -2.77556e-17, -1.11022e-16, -1.11022e-16, 1}, {1, 3.33067e-16, -2.77556e-17, -3.33067e-16, 1, 0, -3.33067e-16, -1.11022e-16, 1}, {1, 0, 0, 0, 1, 0, 0, 4.44089e-16, 1}, {1, 4.44089e-16, 0, -1.11022e-16, 1, 0, 0, 4.44089e-16, 1}, {1, 1.11022e-16, 6.93889e-18, 4.44089e-16, 1, 2.08167e-17, -1.52656e-16, -1.38778e-16, 1}, {1, 5.27356e-16, 5.55112e-17, -1.94289e-16, 1, -5.55112e-17, -9.71445e-17, -8.32667e-17, 1}, {1, 0, 0, 6.66134e-16, 1, 2.08167e-17, 1.11022e-16, 4.44089e-16, 1}, {1, 5.55112e-16, 0, -6.93889e-17, 1, -5.55112e-17, 1.11022e-16, 4.44089e-16, 1}, {1, -2.22045e-16, -1.38778e-17, 0, 1, 0, 0, 0, 1}, {1, 6.38378e-16, 8.32667e-17, -2.22045e-16, 1, 0, 0, 2.22045e-16, 1}, {1, 4.44089e-16, -2.77556e-17, 0, 1, 0, 0, 0, 1}, {1, 7.77156e-16, 0, -1.11022e-16, 1, 0, 0, 0, 1}, {1, 0, -6.93889e-18, 0, 1, 6.93889e-18, -7.63278e-17, -5.55112e-17, 1}, {1, 2.77556e-17, -5.55112e-17, 2.77556e-17, 1, 0, -7.63278e-17, -5.55112e-17, 1}, {1, -8.88178e-16, 2.77556e-17, 0, 1, 6.93889e-18, 2.77556e-17, 1.11022e-16, 1}, {1, 5.55112e-16, -1.11022e-16, -4.16334e-17, 1, 0, 2.77556e-17, 1.11022e-16, 1}, {1, 2.22045e-16, -2.08167e-17, 0, 1, 2.77556e-17, -2.77556e-17, -1.11022e-16, 1}, {1, 1.11022e-16, -5.55112e-17, 8.32667e-17, 1, 1.11022e-16, -2.77556e-17, 1.11022e-16, 1}, {1, -8.88178e-16, 2.77556e-17, 0, 1, 2.77556e-17, 0, 0, 1}, {1, -1.11022e-16, 0, 1.94289e-16, 1, 1.11022e-16, 0, 0, 1}, {1, -1.11022e-16, 1.38778e-17, 0, 1, 2.08167e-17, -2.77556e-17, -1.94289e-16, 1}, {1, 7.77156e-16, 8.32667e-17, 0, 1, 5.55112e-17, -2.77556e-17, -1.38778e-16, 1}, {1, -8.88178e-16, 0, 0, 1, 2.08167e-17, 0, -3.33067e-16, 1}, {1, -2.22045e-16, 0, 0, 1, 5.55112e-17, 0, -3.33067e-16, 1}, {1, 1.11022e-16, -1.38778e-17, 0, 1, 2.77556e-17, -1.38778e-17, 0, 1}, {1, 6.10623e-16, 0, 0, 1, -1.11022e-16, -1.38778e-17, 2.22045e-16, 1}, {1, -4.44089e-16, -2.77556e-17, 0, 1, 2.77556e-17, 0, 0, 1}, {1, 6.66134e-16, 0, 1.38778e-17, 1, -1.11022e-16, 0, 0, 1}, {1, 5.55112e-17, -3.33067e-16, -4.44089e-16, 1, 1.11022e-16, -2.22045e-16, -5.55112e-17, 1}, {1, 8.32667e-17, 1.11022e-16, -2.22045e-16, 1, 0, -3.60822e-16, 5.55112e-17, 1}, {1, -1.11022e-15, -8.88178e-16, -4.44089e-16, 1, -5.55112e-16, -1.11022e-16, 2.22045e-16, 1}, {1, -3.33067e-16, -3.33067e-16, -2.77556e-17, 1, 8.32667e-17, -1.11022e-16, 2.22045e-16, 1}, {1, -1.11022e-16, -7.21645e-16, 4.44089e-16, 1, 2.22045e-16, 3.33067e-16, 1.11022e-16, 1}, {1, -1.38778e-16, -5.55112e-17, -1.11022e-16, 1, -2.22045e-16, 2.22045e-16, 1.11022e-16, 1}, {1, -4.44089e-16, -4.44089e-16, 8.88178e-16, 1, 4.44089e-16, 0, 2.22045e-16, 1}, {1, -2.77556e-16, -1.16573e-15, -1.11022e-16, 1, -4.44089e-16, 2.22045e-16, 0, 1}, {1, -4.44089e-16, 2.77556e-16, 4.996e-16, 1, -3.33067e-16, -1.38778e-16, -1.38778e-16, 1}, {1, 3.60822e-16, 5.55112e-16, 3.46945e-16, 1, 2.77556e-17, -1.38778e-16, -8.32667e-17, 1}, {1, 2.22045e-16, -2.22045e-16, 5.55112e-17, 1, -4.44089e-16, 1.11022e-16, -2.22045e-16, 1}, {1, -3.88578e-16, 8.32667e-16, 4.71845e-16, 1, 1.94289e-16, 1.11022e-16, -2.22045e-16, 1}, {1, -5.55112e-17, 4.996e-16, 2.22045e-16, 1, 0, -5.55112e-17, 1.11022e-16, 1}, {1, 2.77556e-17, 6.66134e-16, 5.55112e-17, 1, -4.44089e-16, -2.77556e-16, 1.11022e-16, 1}, {1, 0, 2.22045e-16, 0, 1, 0, 2.22045e-16, 2.22045e-16, 1}, {1, -3.88578e-16, 3.88578e-16, -1.11022e-16, 1, 1.11022e-16, 2.22045e-16, 4.44089e-16, 1}, {1, 1.11022e-16, 3.33067e-16, 0, 1, -3.33067e-16, 2.08167e-17, 5.55112e-17, 1}, {1, -5.55112e-16, -4.44089e-16, -9.02056e-17, 1, -4.44089e-16, 2.08167e-17, 8.32667e-17, 1}, {1, 2.22045e-16, 0, 0, 1, -3.33067e-16, 2.77556e-17, 1.11022e-16, 1}, {1, 0, 0, 2.77556e-17, 1, -3.05311e-16, 2.77556e-17, 1.11022e-16, 1}, {1, -3.33067e-16, 3.33067e-16, 0, 1, -2.22045e-16, 8.32667e-17, 2.22045e-16, 1}, {1, -5.55112e-17, 3.88578e-16, -5.55112e-17, 1, -1.11022e-16, 8.32667e-17, -5.55112e-17, 1}, {1, 2.22045e-16, 2.22045e-16, 0, 1, -2.22045e-16, -1.11022e-16, -2.22045e-16, 1}, {1, -4.44089e-16, -2.22045e-16, -2.77556e-17, 1, 0, 0, 0, 1}, {1, 0, 1.11022e-16, 0, 1, -3.33067e-16, 0, 2.77556e-17, 1}, {1, 8.32667e-17, 4.44089e-16, -8.32667e-17, 1, -2.498e-16, 2.77556e-17, 5.55112e-17, 1}, {1, 0, 2.22045e-16, 0, 1, -3.33067e-16, 0, 1.11022e-16, 1}, {1, -8.88178e-16, 2.22045e-16, -5.55112e-17, 1, -5.55112e-17, 0, -1.11022e-16, 1}, {1, 0, 1.11022e-16, 0, 1, 6.66134e-16, -6.93889e-18, -1.11022e-16, 1}, {1, -1.38778e-16, 4.44089e-16, 0, 1, 3.33067e-16, -6.93889e-18, -5.55112e-17, 1}, {1, -2.22045e-16, 2.22045e-16, 2.77556e-17, 1, 2.22045e-16, 2.77556e-17, 0, 1}, {1, 0, 2.22045e-16, 6.93889e-18, 1, 0, 2.77556e-17, 0, 1}, {1, 3.33067e-16, -5.55112e-17, 1.11022e-16, 1, -1.11022e-16, -3.88578e-16, -2.498e-16, 1}, {1, -1.94289e-16, -1.11022e-16, 1.94289e-16, 1, -1.38778e-17, -4.996e-16, -3.33067e-16, 1}, {1, 2.22045e-16, 2.22045e-16, 2.22045e-16, 1, -5.55112e-17, 2.22045e-16, 0, 1}, {1, 4.996e-16, 5.55112e-17, 1.94289e-16, 1, -1.38778e-17, 1.11022e-16, 0, 1}, {1, 5.55112e-17, -3.33067e-16, -2.22045e-16, 1, 0, 0, 0, 1}, {1, -2.498e-16, 2.35922e-16, 3.33067e-16, 1, 5.55112e-17, 0, 0, 1}, {1, -2.22045e-16, 2.22045e-16, -2.22045e-16, 1, -2.22045e-16, -2.22045e-16, 0, 1}, {1, 1.66533e-16, -3.88578e-16, -1.11022e-16, 1, 3.33067e-16, -2.22045e-16, 0, 1}, {1, -1.11022e-16, 3.88578e-16, -2.77556e-16, 1, -2.22045e-16, -3.88578e-16, -2.498e-16, 1}, {1, -1.66533e-16, 2.91434e-16, -6.93889e-17, 1, -1.249e-16, -3.88578e-16, -1.38778e-16, 1}, {1, -2.22045e-16, -2.22045e-16, 2.22045e-16, 1, 0, -3.33067e-16, 0, 1}, {1, 5.55112e-16, 3.33067e-16, -2.08167e-16, 1, -4.16334e-17, -1.11022e-16, 0, 1}, {1, 4.44089e-16, 6.10623e-16, 2.22045e-16, 1, 4.44089e-16, 0, 1.11022e-16, 1}, {1, -4.44089e-16, 0, -2.77556e-16, 1, -5.55112e-17, 0, 2.22045e-16, 1}, {1, 2.22045e-16, 2.22045e-16, 0, 1, 0, 2.22045e-16, 2.22045e-16, 1}, {1, 5.55112e-17, 2.22045e-16, -2.22045e-16, 1, 0, 0, 2.22045e-16, 1}, {1, -5.55112e-16, -1.11022e-16, 2.22045e-16, 1, 2.77556e-16, 3.46945e-17, 1.66533e-16, 1}, {1, 5.55112e-17, 6.93889e-17, -9.71445e-17, 1, 0, 3.46945e-17, 5.55112e-17, 1}, {1, -6.66134e-16, 2.22045e-16, 2.498e-16, 1, 3.33067e-16, 0, 1.11022e-16, 1}, {1, -3.88578e-16, 1.66533e-16, 7.63278e-17, 1, -2.63678e-16, 0, 1.11022e-16, 1}, {1, -1.11022e-16, -5.55112e-17, 0, 1, 0, 2.77556e-17, 0, 1}, {1, -2.77556e-17, 1.38778e-16, -5.55112e-17, 1, -1.66533e-16, 2.77556e-17, 0, 1}, {1, -4.44089e-16, 2.22045e-16, 0, 1, 0, 1.11022e-16, 8.88178e-16, 1}, {1, -2.77556e-16, 5.55112e-16, -5.55112e-17, 1, -1.66533e-16, 1.11022e-16, 6.66134e-16, 1}, {1, -6.10623e-16, 0, 0, 1, 2.77556e-16, 2.77556e-17, 8.32667e-17, 1}, {1, 2.498e-16, 3.19189e-16, 0, 1, -1.66533e-16, 1.38778e-16, 3.60822e-16, 1}, {1, -4.44089e-16, 2.22045e-16, 0, 1, 2.77556e-16, 0, 1.11022e-16, 1}, {1, 1.66533e-16, 1.11022e-16, 2.77556e-17, 1, -2.498e-16, 1.11022e-16, 3.33067e-16, 1}, {1, -2.77556e-16, 5.55112e-17, 0, 1, -2.22045e-16, 0, 2.22045e-16, 1}, {1, 8.32667e-17, -1.11022e-16, 0, 1, 5.55112e-17, 0, 2.22045e-16, 1}, {1, -4.44089e-16, 4.44089e-16, 0, 1, -2.22045e-16, 2.77556e-17, 0, 1}, {1, 5.55112e-17, 2.77556e-16, 2.08167e-17, 1, -2.22045e-16, 0, 2.22045e-16, 1}, {1, 1.11022e-16, 0, 0, 1, -5.55112e-17, 2.498e-16, 1.66533e-16, 1}, {1, 1.66533e-16, 3.53884e-16, 3.88578e-16, 1, 9.71445e-17, 2.498e-16, 1.66533e-16, 1}, {1, 0, 2.22045e-16, 0, 1, -5.55112e-17, 5.55112e-17, 1.11022e-16, 1}, {1, 4.996e-16, 2.22045e-16, 6.93889e-16, 1, 1.59595e-16, 5.55112e-17, -1.66533e-16, 1}, {1, 1.66533e-16, 1.38778e-16, 0, 1, 0, 1.11022e-16, -1.11022e-16, 1}, {1, 1.94289e-16, 1.04083e-16, -3.33067e-16, 1, 2.77556e-17, 1.66533e-16, -5.55112e-17, 1}, {1, 2.22045e-16, 2.22045e-16, 2.22045e-16, 1, -1.11022e-16, -2.22045e-16, -2.22045e-16, 1}, {1, -3.33067e-16, 1.66533e-16, -3.33067e-16, 1, 2.77556e-17, 0, -2.22045e-16, 1}, {1, -1.11022e-16, -8.32667e-17, -2.77556e-16, 1, -5.55112e-17, -2.77556e-17, -5.55112e-17, 1}, {1, 2.498e-16, -9.02056e-17, -1.80411e-16, 1, -9.71445e-17, 2.77556e-17, 0, 1}, {1, 4.44089e-16, 1.11022e-16, 2.22045e-16, 1, 0, 1.66533e-16, 2.22045e-16, 1}, {1, -2.22045e-16, 2.77556e-17, -2.63678e-16, 1, -1.11022e-16, 1.66533e-16, 2.22045e-16, 1}, {1, 0, -1.11022e-16, 2.22045e-16, 1, 0, 1.66533e-16, 2.22045e-16, 1}, {1, 1.38778e-16, -1.45717e-16, 1.11022e-16, 1, -1.38778e-16, 1.66533e-16, 2.22045e-16, 1}, {1, 2.22045e-16, 2.22045e-16, 2.22045e-16, 1, 0, 0, 0, 1}, {1, 1.11022e-16, 0, 0, 1, 2.77556e-17, 0, 0, 1}, {1, 3.88578e-16, 1.94289e-16, 0, 1, 0, 3.46945e-17, 2.77556e-17, 1}, {1, 1.94289e-16, -7.63278e-17, 1.94289e-16, 1, 1.31839e-16, 3.46945e-17, 0, 1}, {1, 0, 1.11022e-16, 0, 1, -1.11022e-16, 8.32667e-17, 0, 1}, {1, -2.22045e-16, -1.11022e-16, 9.02056e-17, 1, -2.77556e-17, 1.11022e-16, 0, 1}, {1, 4.44089e-16, -2.77556e-17, 0, 1, 0, -5.55112e-17, 1.11022e-16, 1}, {1, 1.94289e-16, -6.93889e-18, 1.66533e-16, 1, 3.33067e-16, -5.55112e-17, 0, 1}, {1, 0, 1.11022e-16, 0, 1, 1.11022e-16, -1.11022e-16, -2.22045e-16, 1}, {1, -1.66533e-16, 2.77556e-16, 1.66533e-16, 1, 2.22045e-16, -1.11022e-16, -4.44089e-16, 1}, {1, 3.33067e-16, 8.32667e-17, 0, 1, -2.77556e-17, -1.11022e-16, -2.22045e-16, 1}, {1, -4.44089e-16, 1.45717e-16, 1.11022e-16, 1, 3.46945e-17, -1.11022e-16, -2.22045e-16, 1}, {1, 0, 2.22045e-16, 0, 1, 0, 1.11022e-16, 1.11022e-16, 1}, {1, 1.11022e-16, 2.77556e-17, 1.38778e-16, 1, 1.73472e-16, 1.11022e-16, 2.22045e-16, 1}, {1, -2.77556e-16, 3.33067e-16, 0, 1, -1.11022e-16, 0, -2.22045e-16, 1}, {1, -5.55112e-17, 3.67761e-16, 6.93889e-18, 1, 0, 6.93889e-18, -2.22045e-16, 1}, {1, -2.22045e-16, 2.22045e-16, 0, 1, -1.11022e-16, -2.77556e-17, -6.66134e-16, 1}, {1, -2.77556e-16, 5.55112e-17, 0, 1, -1.38778e-16, -2.77556e-17, -4.44089e-16, 1}, {1, 0, -1.38778e-17, 0, 1, 0, 0, -8.32667e-17, 1}, {1, -1.66533e-16, -1.11022e-16, -1.38778e-16, 1, 2.77556e-17, 0, -2.77556e-17, 1}, {1, -4.44089e-16, 0, 0, 1, 0, 3.88578e-16, 5.55112e-17, 1}, {1, 2.77556e-16, 0, 0, 1, 2.77556e-17, 3.88578e-16, 2.77556e-16, 1}, {1, 0, 0, -6.66134e-16, 1, 0, 2.77556e-16, 1.66533e-16, 1}, {1, 0, -8.32667e-17, 1.11022e-16, 1, 0, 5.55112e-17, 1.66533e-16, 1}, {1, -4.44089e-16, 2.77556e-17, -6.66134e-16, 1, 0, -2.22045e-16, -2.22045e-16, 1}, {1, -3.88578e-16, 0, -3.33067e-16, 1, 0, -2.22045e-16, 0, 1}, {1, 1.11022e-16, -6.93889e-18, -7.21645e-16, 1, 0, -2.77556e-17, -1.11022e-16, 1}, {1, -1.66533e-16, -5.55112e-17, 2.22045e-16, 1, 0, 8.32667e-17, 5.55112e-17, 1}, {1, 0, -2.77556e-17, -7.21645e-16, 1, 0, -2.77556e-16, -2.22045e-16, 1}, {1, -1.11022e-16, 0, 2.22045e-16, 1, 0, -3.33067e-16, -1.66533e-16, 1}, {1, 0, 6.93889e-18, 0, 1, 0, 2.22045e-16, 0, 1}, {1, 4.16334e-16, -8.32667e-17, -3.33067e-16, 1, 0, 0, -5.55112e-17, 1}, {1, 2.22045e-16, 0, 0, 1, 0, 2.22045e-16, 4.44089e-16, 1}, {1, -2.77556e-16, 0, -2.77556e-16, 1, 0, 4.44089e-16, 2.22045e-16, 1}, {1, 0, -2.77556e-17, 0, 1, 0, -9.71445e-17, -1.11022e-16, 1}, {1, 1.94289e-16, 2.77556e-17, -9.71445e-17, 1, -2.77556e-17, -9.71445e-17, -1.11022e-16, 1}, {1, -2.22045e-16, 2.77556e-17, 0, 1, 0, 0, 0, 1}, {1, 0, 0, -1.11022e-16, 1, -2.77556e-17, 0, 0, 1}, {1, 0, -2.08167e-17, 0, 1, 0, -5.55112e-17, -2.22045e-16, 1}, {1, 4.44089e-16, 2.77556e-17, 8.32667e-17, 1, 0, -5.55112e-17, -1.11022e-16, 1}, {1, 0, 0, 0, 1, 0, 1.11022e-16, 2.22045e-16, 1}, {1, 5.55112e-17, 0, 8.32667e-17, 1, 0, 1.11022e-16, 2.22045e-16, 1}, {1, 1.66533e-16, -2.77556e-17, 0, 1, 0, -5.55112e-17, -5.55112e-17, 1}, {1, 1.11022e-16, 1.11022e-16, 0, 1, -2.77556e-17, -5.55112e-17, -5.55112e-17, 1}, {1, -8.88178e-16, -2.77556e-17, 0, 1, 0, 0, 1.11022e-16, 1}, {1, -1.66533e-16, 0, -5.55112e-17, 1, -2.77556e-17, 0, 1.11022e-16, 1}, {1, 0, -1.38778e-17, 0, 1, 0, 0, 2.22045e-16, 1}, {1, -2.498e-16, 1.11022e-16, -1.38778e-17, 1, 0, 0, 2.22045e-16, 1}, {1, -6.66134e-16, -2.77556e-17, 0, 1, 0, 0, 2.22045e-16, 1}, {1, -1.11022e-16, 0, -1.38778e-17, 1, 0, 2.77556e-17, 2.22045e-16, 1}, {1, -2.22045e-16, -4.996e-16, 1.66533e-16, 1, -2.22045e-16, -1.94289e-16, -2.77556e-17, 1}, {1, -6.93889e-17, -2.77556e-17, -5.55112e-17, 1, 2.22045e-16, -2.498e-16, -2.77556e-17, 1}, {1, -2.22045e-16, 4.44089e-16, 1.11022e-16, 1, -2.77556e-16, -2.22045e-16, -5.55112e-17, 1}, {1, -1.66533e-16, -6.10623e-16, 8.32667e-17, 1, -8.32667e-17, 2.22045e-16, -5.55112e-17, 1}, {1, -1.66533e-16, 2.22045e-16, -2.22045e-16, 1, -4.44089e-16, 0, 5.55112e-17, 1}, {1, -3.88578e-16, -2.498e-16, 1.11022e-16, 1, 0, 1.11022e-16, 5.55112e-17, 1}, {1, -2.22045e-16, 4.44089e-16, 2.22045e-16, 1, -2.22045e-16, -2.22045e-16, 0, 1}, {1, -2.77556e-16, -4.44089e-16, 6.66134e-16, 1, 3.33067e-16, -2.22045e-16, 0, 1}, {1, 0, 3.88578e-16, 3.33067e-16, 1, 1.66533e-16, -1.11022e-16, -1.38778e-17, 1}, {1, -1.52656e-16, 4.16334e-16, 1.11022e-16, 1, -2.22045e-16, -1.11022e-16, -1.38778e-17, 1}, {1, -2.22045e-16, 2.22045e-16, 3.33067e-16, 1, -3.33067e-16, -5.55112e-17, -2.22045e-16, 1}, {1, -1.66533e-16, 3.33067e-16, -1.80411e-16, 1, -1.38778e-16, -5.55112e-17, -2.22045e-16, 1}, {1, 0, 5.55112e-17, -2.22045e-16, 1, 2.22045e-16, -2.22045e-16, 0, 1}, {1, 8.32667e-17, 2.77556e-16, 5.55112e-17, 1, 2.77556e-16, 0, 0, 1}, {1, 2.22045e-16, 0, -2.22045e-16, 1, 2.22045e-16, 2.22045e-16, 2.22045e-16, 1}, {1, -4.44089e-16, -2.22045e-16, 1.11022e-16, 1, 3.88578e-16, 2.22045e-16, 2.22045e-16, 1}, {1, 0, 3.33067e-16, 0, 1, 9.4369e-16, 7.63278e-17, 2.77556e-17, 1}, {1, 5.55112e-17, 1.11022e-16, 9.02056e-17, 1, 3.05311e-16, 7.63278e-17, 2.77556e-17, 1}, {1, -6.66134e-16, 0, 0, 1, 3.33067e-16, 2.77556e-17, 5.55112e-17, 1}, {1, -4.44089e-16, -1.11022e-16, 2.08167e-17, 1, 2.77556e-17, 2.77556e-17, 5.55112e-17, 1}, {1, 1.66533e-16, 5.55112e-17, 0, 1, 2.22045e-16, 1.11022e-16, 5.55112e-17, 1}, {1, 2.91434e-16, 7.49401e-16, -1.38778e-16, 1, -1.66533e-16, 1.11022e-16, 5.55112e-17, 1}, {1, -2.22045e-16, 0, -1.11022e-16, 1, 2.22045e-16, 0, 0, 1}, {1, -3.88578e-16, -3.33067e-16, -1.11022e-16, 1, -5.55112e-17, -1.11022e-16, 0, 1}, {1, -2.22045e-16, 1.11022e-16, 0, 1, -3.33067e-16, 0, 1.38778e-17, 1}, {1, -3.19189e-16, 4.16334e-16, 0, 1, 5.55112e-17, 2.77556e-17, 4.16334e-17, 1}, {1, -2.22045e-16, -2.22045e-16, -1.11022e-16, 1, 1.11022e-16, 0, -5.55112e-17, 1}, {1, -4.44089e-16, 2.22045e-16, 2.77556e-17, 1, 1.11022e-16, 0, -5.55112e-17, 1}, {1, -5.55112e-17, -3.33067e-16, 0, 1, 4.44089e-16, -6.93889e-18, -5.55112e-17, 1}, {1, -1.11022e-16, 1.66533e-16, -6.93889e-18, 1, 1.11022e-16, -6.93889e-18, -5.55112e-17, 1}, {1, -2.22045e-16, 2.22045e-16, 0, 1, 6.66134e-16, 2.77556e-17, 0, 1}, {1, -5.55112e-17, 3.33067e-16, 0, 1, 2.22045e-16, 2.77556e-17, 0, 1}, {1, -1.11022e-16, -5.55112e-17, 5.55112e-17, 1, 2.22045e-16, -2.22045e-16, -6.93889e-17, 1}, {1, -1.94289e-16, 5.55112e-16, 3.88578e-16, 1, 3.747e-16, -2.498e-16, -6.93889e-17, 1}, {1, -2.22045e-16, -2.22045e-16, 4.996e-16, 1, 2.77556e-16, -3.33067e-16, -1.11022e-16, 1}, {1, -2.77556e-16, -2.77556e-16, 3.88578e-16, 1, 3.33067e-16, -2.22045e-16, -1.11022e-16, 1}, {1, -1.66533e-16, -2.77556e-16, 0, 1, 2.22045e-16, -2.22045e-16, -1.11022e-16, 1}, {1, -2.22045e-16, -2.77556e-17, -1.11022e-16, 1, 5.55112e-17, -1.11022e-16, -1.11022e-16, 1}, {1, 0, -2.22045e-16, 0, 1, 2.22045e-16, 0, 0, 1}, {1, -2.22045e-16, -2.22045e-16, -1.11022e-16, 1, -1.66533e-16, 2.22045e-16, 0, 1}, {1, -1.11022e-16, 1.66533e-16, 0, 1, -1.11022e-16, 2.77556e-17, 2.77556e-17, 1}, {1, -4.44089e-16, 5.55112e-17, -5.55112e-17, 1, 1.66533e-16, 1.38778e-16, 2.77556e-17, 1}, {1, -2.22045e-16, 2.22045e-16, -5.55112e-17, 1, 5.55112e-17, -1.11022e-16, 0, 1}, {1, -1.11022e-16, -1.11022e-16, -2.08167e-16, 1, 1.38778e-17, -1.11022e-16, 0, 1}, {1, -5.55112e-17, 2.22045e-16, 0, 1, -2.22045e-16, -5.55112e-17, -5.55112e-17, 1}, {1, -2.498e-16, -2.498e-16, -1.66533e-16, 1, 5.55112e-17, -5.55112e-17, -5.55112e-17, 1}, {1, -4.44089e-16, 4.44089e-16, 0, 1, 0, 0, 0, 1}, {1, -3.33067e-16, 1.11022e-16, -2.22045e-16, 1, -2.22045e-16, 0, 0, 1}, {1, 5.55112e-17, -5.55112e-17, -2.498e-16, 1, -2.77556e-16, -3.46945e-17, -2.77556e-17, 1}, {1, 1.38778e-16, -5.55112e-17, 7.63278e-17, 1, -6.93889e-17, -3.46945e-17, -2.77556e-17, 1}, {1, 2.22045e-16, 4.44089e-16, -2.77556e-17, 1, -1.11022e-16, 2.77556e-17, 0, 1}, {1, -1.66533e-16, 4.996e-16, 1.80411e-16, 1, 2.77556e-17, 2.77556e-17, 0, 1}, {1, -5.55112e-17, 0, -2.22045e-16, 1, -2.22045e-16, 0, 0, 1}, {1, -5.55112e-17, 4.16334e-16, -2.77556e-17, 1, -1.66533e-16, 0, 0, 1}, {1, 0, 2.22045e-16, -1.11022e-16, 1, -2.22045e-16, 0, 0, 1}, {1, -2.77556e-16, 1.66533e-16, 0, 1, -3.33067e-16, 0, 2.22045e-16, 1}, {1, -3.33067e-16, 0, -1.11022e-16, 1, -2.77556e-16, 0, 0, 1}, {1, -1.38778e-17, 3.05311e-16, -2.77556e-17, 1, -8.32667e-17, 1.11022e-16, 1.11022e-16, 1}, {1, -4.44089e-16, 0, -1.11022e-16, 1, -2.77556e-16, 0, -1.11022e-16, 1}, {1, -3.88578e-16, -1.66533e-16, 2.77556e-17, 1, 1.80411e-16, 1.11022e-16, 1.11022e-16, 1}, {1, -2.22045e-16, -3.88578e-16, 0, 1, -2.22045e-16, 0, 1.11022e-16, 1}, {1, -3.60822e-16, 6.93889e-17, 2.08167e-17, 1, -1.66533e-16, 0, 1.11022e-16, 1}, {1, 0, 2.22045e-16, 0, 1, -2.22045e-16, 0, 0, 1}, {1, -2.77556e-16, -5.55112e-17, 1.38778e-17, 1, 2.22045e-16, 0, 0, 1}, {1, -1.11022e-16, -2.77556e-17, 5.55112e-17, 1, -1.66533e-16, 2.22045e-16, 5.55112e-17, 1}, {1, 1.38778e-17, 2.63678e-16, 1.11022e-16, 1, 7.63278e-17, 2.22045e-16, 5.55112e-17, 1}, {1, -2.22045e-16, 2.22045e-16, 5.55112e-17, 1, -2.498e-16, 4.44089e-16, 1.66533e-16, 1}, {1, -5.55112e-17, 1.94289e-16, 1.11022e-16, 1, 7.63278e-17, 4.44089e-16, 1.66533e-16, 1}, {1, -1.66533e-16, 1.66533e-16, 0, 1, -1.11022e-16, -1.11022e-16, -5.55112e-17, 1}, {1, -2.498e-16, 5.20417e-16, -2.77556e-16, 1, 0, -3.33067e-16, -5.55112e-17, 1}, {1, 0, 1.11022e-16, 2.22045e-16, 1, -1.11022e-16, 0, -2.22045e-16, 1}, {1, -5.55112e-16, 5.55112e-17, 1.66533e-16, 1, 0, -2.22045e-16, 0, 1}, {1, -5.55112e-17, -5.55112e-17, 0, 1, -1.38778e-16, -5.55112e-17, 0, 1}, {1, -1.66533e-16, 7.63278e-17, -5.13478e-16, 1, -4.16334e-17, 0, 0, 1}, {1, -2.22045e-16, -2.22045e-16, 2.22045e-16, 1, -1.66533e-16, -5.55112e-17, 5.55112e-17, 1}, {1, 1.11022e-16, 2.498e-16, 1.11022e-16, 1, -3.46945e-17, -5.55112e-17, 5.55112e-17, 1}, {1, -2.77556e-16, 5.55112e-17, 2.22045e-16, 1, -1.11022e-16, -5.55112e-17, -5.55112e-17, 1}, {1, -1.38778e-17, 1.80411e-16, 2.22045e-16, 1, 2.77556e-17, -5.55112e-17, -5.55112e-17, 1}, {1, -2.22045e-16, 0, 0, 1, -1.11022e-16, -2.22045e-16, 0, 1}, {1, 2.22045e-16, 1.94289e-16, 0, 1, 2.77556e-17, -2.22045e-16, 0, 1}, {1, 0, 1.94289e-16, 2.22045e-16, 1, -1.38778e-16, 9.71445e-17, 4.16334e-17, 1}, {1, -1.11022e-16, 4.16334e-17, -4.16334e-17, 1, -2.08167e-17, 9.71445e-17, 4.16334e-17, 1}, {1, 0, 1.11022e-16, 0, 1, -1.38778e-16, 1.11022e-16, 1.11022e-16, 1}, {1, -2.22045e-16, 3.88578e-16, -9.71445e-17, 1, -7.63278e-17, 1.11022e-16, 1.11022e-16, 1}, {1, 5.55112e-17, 2.77556e-17, 0, 1, -1.11022e-16, 2.77556e-17, 5.55112e-17, 1}, {1, 8.32667e-17, 2.77556e-17, 1.11022e-16, 1, 5.55112e-17, 1.38778e-16, 5.55112e-17, 1}, {1, 2.22045e-16, 2.22045e-16, 0, 1, 0, 0, 0, 1}, {1, -1.11022e-16, 1.11022e-16, 5.55112e-17, 1, 1.11022e-16, -1.11022e-16, 0, 1}, {1, -1.66533e-16, 8.32667e-17, 0, 1, -1.38778e-16, -2.77556e-17, -4.16334e-17, 1}, {1, -1.66533e-16, 1.38778e-16, 0, 1, 0, -2.77556e-17, -4.16334e-17, 1}, {1, -2.22045e-16, 2.22045e-16, 0, 1, -2.498e-16, 1.11022e-16, 1.66533e-16, 1}, {1, 1.66533e-16, 2.22045e-16, 2.77556e-17, 1, 0, 1.11022e-16, 1.66533e-16, 1}, {1, -5.55112e-17, 3.33067e-16, 0, 1, -1.11022e-16, 0, 0, 1}, {1, -1.94289e-16, 1.80411e-16, -6.93889e-18, 1, -2.77556e-17, 6.93889e-18, 0, 1}, {1, -4.44089e-16, 1.11022e-16, 0, 1, -1.11022e-16, -2.77556e-17, -2.22045e-16, 1}, {1, -1.11022e-16, 3.05311e-16, -6.93889e-18, 1, -2.77556e-17, -2.77556e-17, -2.22045e-16, 1}, {1, 1.11022e-16, 6.93889e-18, 5.55112e-17, 1, 0, 5.55112e-17, 0, 1}, {1, 5.55112e-17, 8.32667e-17, 2.22045e-16, 1, 2.77556e-17, 0, 0, 1}, {1, -2.22045e-16, 0, 4.996e-16, 1, 0, -1.66533e-16, -5.55112e-17, 1}, {1, -2.22045e-16, 1.11022e-16, 2.22045e-16, 1, 2.77556e-17, -1.11022e-16, -5.55112e-17, 1}, {1, -2.22045e-16, 1.38778e-17, 2.22045e-16, 1, 0, 1.11022e-16, 5.55112e-17, 1}, {1, -2.08167e-16, 8.32667e-17, 7.21645e-16, 1, 0, -5.55112e-17, 5.55112e-17, 1}, {1, -4.44089e-16, 2.77556e-17, 4.44089e-16, 1, 2.77556e-17, 2.22045e-16, 0, 1}, {1, -1.11022e-16, -1.11022e-16, 1.11022e-16, 1, 0, 0, 0, 1}, {1, -3.33067e-16, 6.93889e-18, -2.22045e-16, 1, -1.38778e-17, 1.94289e-16, 2.77556e-17, 1}, {1, -2.08167e-16, -1.11022e-16, 1.11022e-16, 1, 0, -1.38778e-16, 2.77556e-17, 1}, {1, -2.22045e-16, -2.77556e-17, -2.22045e-16, 1, -1.38778e-17, -1.11022e-16, 0, 1}, {1, -1.11022e-16, 0, 1.11022e-16, 1, 0, -1.11022e-16, 0, 1}, {1, -2.22045e-16, -6.93889e-18, 2.22045e-16, 1, 2.77556e-17, -1.11022e-16, 0, 1}, {1, -4.16334e-17, -8.32667e-17, -2.22045e-16, 1, 0, -1.11022e-16, -1.11022e-16, 1}, {1, -2.22045e-16, 0, 4.44089e-16, 1, 0, 0, 0, 1}, {1, -1.11022e-16, 0, -3.88578e-16, 1, 0, 0, 0, 1}, {1, 5.55112e-17, 0, 0, 1, 0, -9.02056e-17, -5.55112e-17, 1}, {1, -8.32667e-17, 0, -4.16334e-17, 1, -2.77556e-17, -9.02056e-17, -5.55112e-17, 1}, {1, -4.44089e-16, 0, 0, 1, 0, 2.77556e-17, 0, 1}, {1, -3.33067e-16, -1.11022e-16, -2.08167e-17, 1, -2.77556e-17, 2.77556e-17, 0, 1}, {1, 1.66533e-16, 0, 0, 1, 0, -2.77556e-17, 5.55112e-17, 1}, {1, -2.77556e-16, -5.55112e-17, 0, 1, 0, -2.77556e-17, 5.55112e-17, 1}, {1, -2.22045e-16, 0, 0, 1, 0, 1.11022e-16, 0, 1}, {1, -3.33067e-16, 0, 0, 1, 0, 1.11022e-16, 0, 1}, {1, -2.77556e-16, -2.77556e-17, 0, 1, 0, 0, 0, 1}, {1, -3.19189e-16, -2.77556e-17, 0, 1, -2.77556e-17, 0, 0, 1}, {1, -4.44089e-16, 0, 0, 1, 0, 0, -1.11022e-16, 1}, {1, -6.10623e-16, 0, 0, 1, -2.77556e-17, 0, -1.11022e-16, 1}, {1, -2.22045e-16, -1.38778e-17, 0, 1, 0, 0, 1.11022e-16, 1}, {1, -2.22045e-16, 2.77556e-17, 1.38778e-17, 1, 0, 0, 1.11022e-16, 1}, {1, -2.22045e-16, -2.77556e-17, 0, 1, 0, 0, 0, 1}, {1, -4.44089e-16, -1.11022e-16, 1.38778e-17, 1, 0, 0, 0, 1}, {1, -2.77556e-17, 5.55112e-17, 0, 1, 5.55112e-17, -1.38778e-16, -6.93889e-18, 1}, {1, -1.38778e-17, 1.11022e-16, -5.55112e-17, 1, -8.32667e-17, -1.66533e-16, -6.93889e-18, 1}, {1, 0, -2.22045e-16, 4.44089e-16, 1, 3.33067e-16, -3.33067e-16, -5.55112e-17, 1}, {1, 2.77556e-17, -6.10623e-16, 8.32667e-17, 1, 1.66533e-16, -3.33067e-16, -5.55112e-17, 1}, {1, -2.77556e-17, -3.88578e-16, -2.22045e-16, 1, -8.88178e-16, -1.11022e-16, -2.77556e-17, 1}, {1, -6.93889e-18, -1.38778e-16, 2.77556e-16, 1, -2.22045e-16, -4.44089e-16, 0, 1}, {1, -1.11022e-16, 0, -2.22045e-16, 1, -2.22045e-16, 0, -1.11022e-16, 1}, {1, 2.77556e-17, -2.77556e-16, 3.33067e-16, 1, 0, -2.22045e-16, -1.11022e-16, 1}, {1, -2.77556e-17, 4.996e-16, -5.55112e-17, 1, 5.55112e-17, -2.08167e-16, -6.93889e-18, 1}, {1, -1.38778e-17, 6.38378e-16, 4.71845e-16, 1, 1.66533e-16, -1.52656e-16, -6.93889e-18, 1}, {1, -1.11022e-16, -4.44089e-16, -1.11022e-16, 1, 1.66533e-16, 1.66533e-16, 1.38778e-16, 1}, {1, -8.32667e-17, -1.66533e-16, 4.996e-16, 1, 8.32667e-17, 4.44089e-16, 1.38778e-16, 1}, {1, -2.77556e-17, 6.66134e-16, 4.44089e-16, 1, 0, -1.11022e-16, 0, 1}, {1, 0, 4.71845e-16, 1.66533e-16, 1, 1.11022e-16, -1.11022e-16, 0, 1}, {1, 1.11022e-16, 0, 2.22045e-16, 1, 2.22045e-16, -2.22045e-16, 0, 1}, {1, -1.11022e-16, 5.55112e-17, 1.11022e-16, 1, 4.996e-16, -2.22045e-16, 0, 1}, {1, -2.77556e-17, 0, 1.11022e-16, 1, 1.66533e-16, 4.85723e-17, 1.38778e-17, 1}, {1, 3.46945e-17, 5.27356e-16, -1.38778e-16, 1, -2.498e-16, 4.85723e-17, 1.38778e-17, 1}, {1, 0, 0, 8.32667e-17, 1, 0, 5.55112e-17, 0, 1}, {1, 8.32667e-17, -2.22045e-16, -2.63678e-16, 1, -3.88578e-16, 5.55112e-17, 0, 1}, {1, 0, -5.55112e-17, -2.22045e-16, 1, 2.22045e-16, 2.77556e-17, 0, 1}, {1, 2.08167e-17, -1.66533e-16, 0, 1, 5.55112e-17, 2.77556e-17, 0, 1}, {1, 0, 0, -1.11022e-16, 1, 4.44089e-16, -1.11022e-16, -1.11022e-16, 1}, {1, 8.32667e-17, -2.22045e-16, 2.77556e-17, 1, 1.66533e-16, -1.11022e-16, -1.11022e-16, 1}, {1, 0, -1.11022e-16, -1.11022e-16, 1, 3.88578e-16, 2.77556e-17, -1.38778e-17, 1}, {1, 6.93889e-18, 1.38778e-16, 0, 1, 1.66533e-16, 5.55112e-17, 1.38778e-17, 1}, {1, 0, 2.22045e-16, -1.11022e-16, 1, 5.55112e-17, -1.11022e-16, -2.77556e-17, 1}, {1, 2.77556e-17, 3.33067e-16, 0, 1, 1.11022e-16, -1.11022e-16, -2.77556e-17, 1}, {1, 0, 5.55112e-17, 2.77556e-17, 1, -6.66134e-16, -1.38778e-17, 0, 1}, {1, -1.38778e-17, -1.94289e-16, -6.93889e-18, 1, -1.11022e-16, -1.38778e-17, 0, 1}, {1, 0, 2.22045e-16, 0, 1, -6.66134e-16, 0, -1.11022e-16, 1}, {1, 2.77556e-17, 5.55112e-16, -6.93889e-18, 1, 0, 0, -1.11022e-16, 1}, {1, 0, -1.66533e-16, 1.11022e-16, 1, 5.55112e-17, -1.38778e-16, 0, 1}, {1, -2.77556e-17, 7.21645e-16, 4.71845e-16, 1, 2.08167e-16, -1.38778e-16, 0, 1}, {1, 0, 0, 5.55112e-17, 1, -2.22045e-16, -3.33067e-16, -2.77556e-17, 1}, {1, -8.32667e-17, -1.05471e-15, 4.44089e-16, 1, 1.66533e-16, -2.22045e-16, -2.77556e-17, 1}, {1, 0, -1.11022e-16, 2.22045e-16, 1, -2.22045e-16, -1.11022e-16, -2.77556e-17, 1}, {1, -1.38778e-17, 6.38378e-16, -1.11022e-16, 1, 5.55112e-17, -1.11022e-16, 0, 1}, {1, 0, -2.22045e-16, 2.22045e-16, 1, -2.22045e-16, -2.22045e-16, 0, 1}, {1, -1.38778e-16, -9.4369e-16, -3.33067e-16, 1, -1.66533e-16, -2.22045e-16, 0, 1}, {1, -2.77556e-17, 0, 6.66134e-16, 1, 2.22045e-16, 1.66533e-16, 1.38778e-17, 1}, {1, 1.38778e-17, -5.13478e-16, 2.08167e-16, 1, 1.52656e-16, 1.66533e-16, 1.38778e-17, 1}, {1, -1.11022e-16, 2.22045e-16, 8.88178e-16, 1, 0, 1.66533e-16, 8.32667e-17, 1}, {1, 5.55112e-17, 6.66134e-16, 1.38778e-17, 1, 1.249e-16, 1.66533e-16, 8.32667e-17, 1}, {1, 0, -1.11022e-16, 0, 1, 0, -5.55112e-17, -2.77556e-17, 1}, {1, 0, 4.57967e-16, 0, 1, 0, -5.55112e-17, 0, 1}, {1, -1.11022e-16, 6.66134e-16, 0, 1, 0, -2.22045e-16, 0, 1}, {1, 2.77556e-17, 1.05471e-15, -1.66533e-16, 1, 5.55112e-17, -2.22045e-16, 0, 1}, {1, 2.77556e-17, 5.55112e-17, 2.77556e-16, 1, 1.11022e-16, 1.11022e-16, -6.93889e-18, 1}, {1, 2.77556e-17, -3.88578e-16, 1.04083e-16, 1, 2.08167e-16, 1.11022e-16, -6.93889e-18, 1}, {1, 0, -4.44089e-16, 2.77556e-16, 1, 1.11022e-16, -5.55112e-17, -5.55112e-17, 1}, {1, 5.55112e-17, 1.11022e-16, 0, 1, 5.55112e-17, -5.55112e-17, -5.55112e-17, 1}, {1, 0, -1.66533e-16, 1.11022e-16, 1, 0, 5.55112e-17, 0, 1}, {1, 2.77556e-17, -4.996e-16, 2.77556e-17, 1, 3.88578e-16, 5.55112e-17, 0, 1}, {1, 0, -2.22045e-16, 1.11022e-16, 1, 0, 0, 0, 1}, {1, 8.32667e-17, 1.66533e-16, 2.77556e-17, 1, 3.88578e-16, 0, 0, 1}, {1, 0, 1.11022e-16, 0, 1, 2.22045e-16, -2.77556e-17, 1.38778e-17, 1}, {1, 6.93889e-18, 8.32667e-17, -1.11022e-16, 1, -1.52656e-16, -2.77556e-17, 1.38778e-17, 1}, {1, 0, 2.22045e-16, 0, 1, 2.22045e-16, 1.11022e-16, 0, 1}, {1, 5.55112e-17, 1.11022e-16, -1.11022e-16, 1, -6.245e-16, 1.11022e-16, 0, 1}, {1, 0, -1.66533e-16, 0, 1, 2.22045e-16, -1.38778e-17, 0, 1}, {1, -6.93889e-18, -3.88578e-16, 2.08167e-17, 1, -1.66533e-16, -1.38778e-17, 0, 1}, {1, 0, 2.22045e-16, -2.77556e-17, 1, 2.22045e-16, 2.77556e-17, -1.11022e-16, 1}, {1, 0, 2.22045e-16, 3.46945e-17, 1, -2.22045e-16, 2.77556e-17, -1.11022e-16, 1}, {1, 0, -2.77556e-17, -5.55112e-17, 1, -2.22045e-16, -1.38778e-16, 0, 1}, {1, 2.08167e-17, 2.91434e-16, 4.71845e-16, 1, 2.77556e-16, -8.32667e-17, 0, 1}, {1, 1.11022e-16, 4.44089e-16, -1.11022e-16, 1, -2.22045e-16, 3.88578e-16, 5.55112e-17, 1}, {1, 0, 0, 6.93889e-16, 1, 6.93889e-17, 3.88578e-16, 5.55112e-17, 1}, {1, 0, -1.11022e-16, 2.22045e-16, 1, -1.11022e-16, 1.11022e-16, 0, 1}, {1, 0, 1.31839e-16, 3.88578e-16, 1, 0, 0, 0, 1}, {1, 1.11022e-16, 3.33067e-16, 2.22045e-16, 1, -1.11022e-16, -2.22045e-16, -1.11022e-16, 1}, {1, 0, 1.11022e-16, 3.88578e-16, 1, 0, -4.44089e-16, 0, 1}, {1, -2.77556e-17, 1.11022e-16, -2.22045e-16, 1, -1.38778e-16, -8.32667e-17, 2.77556e-17, 1}, {1, -2.08167e-17, 6.93889e-18, -2.498e-16, 1, -1.59595e-16, -1.38778e-16, 2.77556e-17, 1}, {1, -1.11022e-16, -2.22045e-16, 2.22045e-16, 1, -1.38778e-16, -2.77556e-16, -2.77556e-17, 1}, {1, 0, 2.498e-16, -1.66533e-16, 1, 2.08167e-17, -5.55112e-17, -2.77556e-17, 1}, {1, -2.77556e-17, 2.77556e-17, -4.44089e-16, 1, 0, 1.11022e-16, 2.77556e-17, 1}, {1, 6.93889e-18, -2.08167e-17, -1.11022e-16, 1, -1.38778e-16, 1.11022e-16, 2.77556e-17, 1}, {1, -1.11022e-16, 0, -4.44089e-16, 1, -2.22045e-16, -2.22045e-16, 0, 1}, {1, 5.55112e-17, -2.77556e-17, -5.55112e-17, 1, -1.11022e-16, -2.22045e-16, 0, 1}, {1, 0, 8.32667e-17, 2.77556e-17, 1, 5.55112e-17, 9.71445e-17, -6.93889e-18, 1}, {1, 1.38778e-17, 4.16334e-17, -1.31839e-16, 1, 2.77556e-17, 9.71445e-17, -6.93889e-18, 1}, {1, 0, 1.11022e-16, 2.22045e-16, 1, 5.55112e-17, 1.11022e-16, 5.55112e-17, 1}, {1, -8.32667e-17, -2.77556e-17, 8.32667e-17, 1, -2.01228e-16, 1.11022e-16, 5.55112e-17, 1}, {1, 0, -2.498e-16, -1.11022e-16, 1, 0, 2.77556e-17, 0, 1}, {1, 6.93889e-18, 1.45717e-16, 1.66533e-16, 1, 1.11022e-16, 1.38778e-16, -2.77556e-17, 1}, {1, 1.11022e-16, 0, 0, 1, 0, 0, 0, 1}, {1, -8.32667e-17, -2.498e-16, 8.32667e-17, 1, 1.38778e-16, -1.11022e-16, 0, 1}, {1, 0, 1.11022e-16, 0, 1, -1.38778e-16, -2.77556e-17, -6.93889e-18, 1}, {1, -6.93889e-18, -2.08167e-17, 0, 1, 2.77556e-17, -2.77556e-17, -6.93889e-18, 1}, {1, 0, 2.22045e-16, 0, 1, -2.498e-16, 1.11022e-16, 5.55112e-17, 1}, {1, -2.77556e-17, 2.22045e-16, 2.77556e-17, 1, 2.77556e-17, 1.11022e-16, 5.55112e-17, 1}, {1, -2.77556e-17, 3.88578e-16, 0, 1, -1.11022e-16, 0, 0, 1}, {1, -2.08167e-17, -6.93889e-18, -6.93889e-18, 1, -2.77556e-17, 6.93889e-18, 2.77556e-17, 1}, {1, 0, 3.33067e-16, 0, 1, -1.11022e-16, -2.77556e-17, -1.11022e-16, 1}, {1, 0, 1.38778e-16, -1.38778e-17, 1, -2.77556e-17, -2.77556e-17, -1.11022e-16, 1}, {1, 0, 6.93889e-18, -3.88578e-16, 1, 0, -1.38778e-16, 0, 1}, {1, -6.93889e-18, -1.11022e-16, 1.38778e-16, 1, 2.77556e-17, -1.94289e-16, 0, 1}, {1, 0, 0, -1.11022e-16, 1, 0, 5.55112e-17, 2.77556e-17, 1}, {1, -1.38778e-16, -1.11022e-16, 2.77556e-16, 1, 2.77556e-17, 5.55112e-17, 2.77556e-17, 1}, {1, 0, 0, -2.22045e-16, 1, 2.77556e-17, 1.66533e-16, 0, 1}, {1, -6.93889e-18, -1.11022e-16, -5.55112e-17, 1, 0, 1.66533e-16, 0, 1}, {1, 0, 0, -2.22045e-16, 1, 2.77556e-17, 0, 0, 1}, {1, -1.38778e-16, -1.11022e-16, 5.55112e-17, 1, 0, 0, 0, 1}, {1, 0, -6.93889e-18, -2.22045e-16, 1, -2.08167e-17, -5.55112e-17, 6.93889e-18, 1}, {1, -2.77556e-17, 2.77556e-17, -8.32667e-17, 1, -2.77556e-17, -1.11022e-16, 6.93889e-18, 1}, {1, -2.22045e-16, 0, -2.22045e-16, 1, -2.08167e-17, -3.33067e-16, -8.32667e-17, 1}, {1, 5.55112e-17, 0, -2.35922e-16, 1, -2.77556e-17, -3.33067e-16, -8.32667e-17, 1}, {1, -2.77556e-17, 6.93889e-18, 0, 1, 0, 0, -2.77556e-17, 1}, {1, -6.93889e-18, -2.77556e-17, -1.66533e-16, 1, 0, 2.22045e-16, -2.77556e-17, 1}, {1, -1.11022e-16, 0, -4.44089e-16, 1, 0, 2.22045e-16, 0, 1}, {1, 8.32667e-17, 0, -1.66533e-16, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 6.93889e-18, 2.77556e-17, -3.46945e-17, 1}, {1, -2.08167e-17, 0, 1.38778e-17, 1, 0, 2.77556e-17, -3.46945e-17, 1}, {1, 1.11022e-16, 2.77556e-17, 2.22045e-16, 1, 6.93889e-18, 2.77556e-17, 2.77556e-17, 1}, {1, -5.55112e-17, 0, -3.46945e-17, 1, 0, 2.77556e-17, 2.77556e-17, 1}, {1, 2.77556e-17, 1.38778e-17, 0, 1, 0, 0, -2.77556e-17, 1}, {1, -2.08167e-17, -5.55112e-17, 5.55112e-17, 1, 0, 0, -2.77556e-17, 1}, {1, 1.11022e-16, 0, 0, 1, 0, 1.11022e-16, 1.11022e-16, 1}, {1, 0, 0, 5.55112e-17, 1, 0, 1.11022e-16, 1.11022e-16, 1}, {1, 2.77556e-17, 6.93889e-18, 0, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, -2.77556e-17, 0, 0, 1}, {1, -1.11022e-16, -2.77556e-17, 0, 1, 0, 0, 0, 1}, {1, 5.55112e-17, 0, 0, 1, -2.77556e-17, 0, 0, 1}, {1, 2.77556e-17, 6.93889e-18, 0, 1, 0, 0, 0, 1}, {1, -6.93889e-18, 5.55112e-17, -1.38778e-17, 1, 0, 0, 0, 1}, {1, -1.11022e-16, -2.77556e-17, 0, 1, 0, 0, 0, 1}, {1, 5.55112e-17, 1.11022e-16, -1.38778e-17, 1, 0, 0, 0, 1}}
-]
-
diff --git a/test/test_fe_engine/test_gradient_pentahedron_15.verified b/test/test_fe_engine/test_gradient_pentahedron_15.verified
new file mode 100644
index 000000000..039eba426
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_pentahedron_15.verified
@@ -0,0 +1 @@
+Epsilon : 1e-12
diff --git a/test/test_fe_engine/test_gradient_pentahedron_6.verified b/test/test_fe_engine/test_gradient_pentahedron_6.verified
new file mode 100644
index 000000000..039eba426
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_pentahedron_6.verified
@@ -0,0 +1 @@
+Epsilon : 1e-12
diff --git a/test/test_fe_engine/test_gradient_quadrangle_4.verified b/test/test_fe_engine/test_gradient_quadrangle_4.verified
index 8d57f4bb7..039eba426 100644
--- a/test/test_fe_engine/test_gradient_quadrangle_4.verified
+++ b/test/test_fe_engine/test_gradient_quadrangle_4.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 9
- + nb_component : 2
- + allocated size : 9
- + memory size : 144.00Byte
- + values : {{0, 0}, {13, 11}, {36, 18}, {23, 7}, {6.5, 5.5}, {24.5, 14.5}, {29.5, 12.5}, {11.5, 3.5}, {18, 9}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 16
- + nb_component : 4
- + allocated size : 16
- + memory size : 512.00Byte
- + values : {{13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 9
- + nb_component : 2
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0.5, 0}, {1, 0.5}, {0.5, 1}, {0, 0.5}, {0.5, 0.5}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 16
- + nb_component : 4
- + allocated size : 16
- + memory size : 512.00Byte
- + values : {{1, 1.11022e-16, 0, 1}, {1, 1.11022e-16, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, 2.22045e-16, 1}, {1, 0, 1.11022e-16, 1}, {1, 0, 0, 1}, {1, 0, 1.11022e-16, 1}, {1, 5.55112e-17, 0, 1}, {1, 5.55112e-17, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}}
-]
-
diff --git a/test/test_fe_engine/test_gradient_quadrangle_8.verified b/test/test_fe_engine/test_gradient_quadrangle_8.verified
index 5c9b70533..039eba426 100644
--- a/test/test_fe_engine/test_gradient_quadrangle_8.verified
+++ b/test/test_fe_engine/test_gradient_quadrangle_8.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 21
- + nb_component : 2
- + allocated size : 21
- + memory size : 336.00Byte
- + values : {{0, 0}, {13, 11}, {36, 18}, {23, 7}, {6.5, 5.5}, {3.25, 2.75}, {9.75, 8.25}, {24.5, 14.5}, {18.75, 12.75}, {30.25, 16.25}, {29.5, 12.5}, {32.75, 15.25}, {26.25, 9.75}, {11.5, 3.5}, {17.25, 5.25}, {5.75, 1.75}, {18, 9}, {23.75, 10.75}, {21.25, 11.75}, {12.25, 7.25}, {14.75, 6.25}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 36
- + nb_component : 4
- + allocated size : 36
- + memory size : 1.12KiByte
- + values : {{13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 21
- + nb_component : 2
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0.5, 0}, {0.25, 0}, {0.75, 0}, {1, 0.5}, {1, 0.25}, {1, 0.75}, {0.5, 1}, {0.75, 1}, {0.25, 1}, {0, 0.5}, {0, 0.75}, {0, 0.25}, {0.5, 0.5}, {0.5, 0.75}, {0.75, 0.5}, {0.5, 0.25}, {0.25, 0.5}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 36
- + nb_component : 4
- + allocated size : 36
- + memory size : 1.12KiByte
- + values : {{1, -5.55112e-16, -8.88178e-16, 1}, {1, 0, -4.44089e-16, 1}, {1, 1.33227e-15, 8.88178e-16, 1}, {1, -4.44089e-16, 2.22045e-16, 1}, {1, 0, -1.54087e-24, 1}, {1, 6.66134e-16, -8.45356e-24, 1}, {1, -2.22045e-16, -8.88178e-16, 1}, {1, -1.11022e-16, 0, 1}, {1, 1.22125e-15, -4.44089e-16, 1}, {1, 1.66533e-16, 0, 1}, {1, 5.55112e-17, 8.88178e-16, 1}, {1, -2.77556e-17, -6.66134e-16, 1}, {1, 5.55112e-17, 1.11022e-16, 1}, {1, 0, 0, 1}, {1, 5.55112e-17, 2.22045e-16, 1}, {1, -2.77556e-17, 0, 1}, {1, 0, -8.88178e-16, 1}, {1, -8.32667e-17, -6.66134e-16, 1}, {1, -9.99201e-16, -4.44089e-16, 1}, {1, 2.22045e-16, 4.44089e-16, 1}, {1, 2.22045e-16, 0, 1}, {1, -1.11022e-15, -5.55112e-17, 1}, {1, 0, -1.88377e-24, 1}, {1, 0, -6.68904e-25, 1}, {1, -1.11022e-16, -8.88178e-16, 1}, {1, -1.11022e-16, 0, 1}, {1, 1.11022e-16, -5.55112e-17, 1}, {1, 8.32667e-17, 8.88178e-16, 1}, {1, 5.55112e-17, -2.22045e-16, 1}, {1, 1.11022e-16, 0, 1}, {1, 1.11022e-16, -5.55112e-17, 1}, {1, 0, 1.65376e-24, 1}, {1, -1.11022e-16, 5.70782e-25, 1}, {1, 2.77556e-17, -4.44089e-16, 1}, {1, 0, -2.22045e-16, 1}, {1, -2.77556e-17, 5.55112e-17, 1}}
-]
-
diff --git a/test/test_fe_engine/test_gradient_segment_2.verified b/test/test_fe_engine/test_gradient_segment_2.verified
index a5962d09c..039eba426 100644
--- a/test/test_fe_engine/test_gradient_segment_2.verified
+++ b/test/test_fe_engine/test_gradient_segment_2.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 11
- + nb_component : 2
- + allocated size : 11
- + memory size : 176.00Byte
- + values : {{0, 0}, {13, 11}, {1.3, 1.1}, {2.6, 2.2}, {3.9, 3.3}, {5.2, 4.4}, {6.5, 5.5}, {7.8, 6.6}, {9.1, 7.7}, {10.4, 8.8}, {11.7, 9.9}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 10
- + nb_component : 2
- + allocated size : 10
- + memory size : 160.00Byte
- + values : {{13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 11
- + nb_component : 1
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0}, {1}, {0.1}, {0.2}, {0.3}, {0.4}, {0.5}, {0.6}, {0.7}, {0.8}, {0.9}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 10
- + nb_component : 1
- + allocated size : 10
- + memory size : 80.00Byte
- + values : {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}}
-]
-
diff --git a/test/test_fe_engine/test_gradient_segment_3.verified b/test/test_fe_engine/test_gradient_segment_3.verified
index db3a56115..039eba426 100644
--- a/test/test_fe_engine/test_gradient_segment_3.verified
+++ b/test/test_fe_engine/test_gradient_segment_3.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 21
- + nb_component : 2
- + allocated size : 21
- + memory size : 336.00Byte
- + values : {{0, 0}, {13, 11}, {1.3, 1.1}, {2.6, 2.2}, {3.9, 3.3}, {5.2, 4.4}, {6.5, 5.5}, {7.8, 6.6}, {9.1, 7.7}, {10.4, 8.8}, {11.7, 9.9}, {0.65, 0.55}, {1.95, 1.65}, {3.25, 2.75}, {4.55, 3.85}, {5.85, 4.95}, {7.15, 6.05}, {8.45, 7.15}, {9.75, 8.25}, {11.05, 9.35}, {12.35, 10.45}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 20
- + nb_component : 2
- + allocated size : 20
- + memory size : 320.00Byte
- + values : {{13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}, {13, 11}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 21
- + nb_component : 1
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0}, {1}, {0.1}, {0.2}, {0.3}, {0.4}, {0.5}, {0.6}, {0.7}, {0.8}, {0.9}, {0.05}, {0.15}, {0.25}, {0.35}, {0.45}, {0.55}, {0.65}, {0.75}, {0.85}, {0.95}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 20
- + nb_component : 1
- + allocated size : 20
- + memory size : 160.00Byte
- + values : {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}}
-]
-
diff --git a/test/test_fe_engine/test_gradient_tetrahedron_10.verified b/test/test_fe_engine/test_gradient_tetrahedron_10.verified
index a224c8483..039eba426 100644
--- a/test/test_fe_engine/test_gradient_tetrahedron_10.verified
+++ b/test/test_fe_engine/test_gradient_tetrahedron_10.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 722
- + nb_component : 2
- + allocated size : 722
- + memory size : 11.28KiByte
- + values : {{0, 0}, {13, 11}, {23, 7}, {36, 18}, {31, 5}, {44, 16}, {54, 12}, {67, 23}, {57.25, 14.75}, {60.5, 17.5}, {63.75, 20.25}, {55.625, 13.375}, {58.875, 16.125}, {62.125, 18.875}, {65.375, 21.625}, {59.25, 21.75}, {51.5, 20.5}, {43.75, 19.25}, {63.125, 22.375}, {55.375, 21.125}, {47.625, 19.875}, {39.875, 18.625}, {32.75, 15.25}, {29.5, 12.5}, {26.25, 9.75}, {34.375, 16.625}, {31.125, 13.875}, {27.875, 11.125}, {24.625, 8.375}, {30.75, 8.25}, {38.5, 9.5}, {46.25, 10.75}, {26.875, 7.625}, {34.625, 8.875}, {42.375, 10.125}, {50.125, 11.375}, {7.75, 1.25}, {15.5, 2.5}, {23.25, 3.75}, {3.875, 0.625}, {11.625, 1.875}, {19.375, 3.125}, {27.125, 4.375}, {34.25, 7.75}, {37.5, 10.5}, {40.75, 13.25}, {32.625, 6.375}, {35.875, 9.125}, {39.125, 11.875}, {42.375, 14.625}, {36.25, 14.75}, {28.5, 13.5}, {20.75, 12.25}, {40.125, 15.375}, {32.375, 14.125}, {24.625, 12.875}, {16.875, 11.625}, {9.75, 8.25}, {6.5, 5.5}, {3.25, 2.75}, {11.375, 9.625}, {8.125, 6.875}, {4.875, 4.125}, {1.625, 1.375}, {17.25, 5.25}, {11.5, 3.5}, {5.75, 1.75}, {20.125, 6.125}, {14.375, 4.375}, {8.625, 2.625}, {2.875, 0.875}, {48.25, 10.25}, {42.5, 8.5}, {36.75, 6.75}, {51.125, 11.125}, {45.375, 9.375}, {39.625, 7.625}, {33.875, 5.875}, {61.25, 21.25}, {55.5, 19.5}, {49.75, 17.75}, {64.125, 22.125}, {58.375, 20.375}, {52.625, 18.625}, {46.875, 16.875}, {30.25, 16.25}, {24.5, 14.5}, {18.75, 12.75}, {33.125, 17.125}, {27.375, 15.375}, {21.625, 13.625}, {15.875, 11.875}, {49.0504, 14.0153}, {51.2148, 13.1141}, {56.9732, 17.9866}, {41.0324, 10.0151}, {46.7908, 14.8876}, {44.9874, 10.6014}, {56.1158, 16.1657}, {53.025, 17.4024}, {41.8967, 11.8381}, {52.5809, 12.5676}, {61.8914, 20.4457}, {36.1096, 7.5546}, {45.42, 15.4327}, {48.1011, 11.8577}, {46.6187, 10.4257}, {49.7324, 11.682}, {54.2324, 13.932}, {56.6829, 15.4578}, {53.6653, 14.6399}, {59.1116, 19.6183}, {57.1375, 19.3262}, {54.9991, 17.6945}, {37.6412, 8.88255}, {41.4645, 10.9266}, {38.0733, 9.79406}, {56.5445, 17.0761}, {59.9329, 18.2078}, {60.3616, 19.1183}, {40.8687, 8.67569}, {43.0099, 10.3082}, {38.8912, 8.38255}, {41.3233, 12.5441}, {44.3437, 13.3629}, {43.7704, 14.0688}, {48.2704, 16.3188}, {49.9079, 16.145}, {51.3875, 17.5762}, {43.7437, 9.55069}, {54.2625, 18.4512}, {58.3079, 16.8328}, {39.6983, 11.1691}, {50.1326, 13.5647}, {47.0189, 12.3084}, {52.5831, 15.0905}, {53.0118, 16.001}, {45.0414, 12.0152}, {51.0377, 15.7089}, {45.4735, 12.9267}, {47.9206, 14.4515}, {50.4155, 11.4088}, {51.8979, 12.8409}, {54.9155, 13.6588}, {59.4323, 19.2161}, {61.5707, 20.8478}, {35.1798, 7.6523}, {38.571, 8.78485}, {62.8207, 20.3478}, {36.4298, 7.1523}, {46.1054, 15.1601}, {43.085, 14.3413}, {47.585, 16.5913}, {33.5548, 6.2773}, {53.2905, 12.2838}, {64.4457, 21.7228}, {44.71, 15.7163}, {45, 15}, {54.745, 18.5437}, {41.0134, 16.3289}, {48.9866, 13.6711}, {35.255, 11.4563}, {49.0188, 18.4005}, {35.4167, 13.4543}, {54.5833, 16.5457}, {40.9812, 11.5995}, {38.5543, 17.1486}, {60.7561, 20.7295}, {29.2439, 9.2705}, {51.4457, 12.8514}, {54.1344, 20.0753}, {51.8819, 18.4721}, {56.9975, 20.1468}, {34.0834, 14.3522}, {38.2151, 14.8916}, {36.8817, 15.7894}, {55.9166, 15.6478}, {51.7849, 15.1084}, {53.1183, 14.2106}, {35.8656, 9.92474}, {38.1181, 11.5279}, {33.0025, 9.85317}, {59.2475, 19.3968}, {54.6642, 17.5447}, {59.1666, 18.3978}, {47.6183, 12.2106}, {44.9839, 12.6353}, {43.6156, 11.1747}, {42.3817, 17.7894}, {45.0161, 17.3647}, {46.3844, 18.8253}, {30.7525, 10.6032}, {35.3358, 12.4553}, {30.8334, 11.6022}, {32.4584, 12.9772}, {50.2594, 19.4503}, {39.7406, 10.5497}, {57.5416, 17.0228}, {47.0094, 16.7003}, {49.8725, 16.7718}, {43.0067, 15.6644}, {40.2084, 14.2272}, {40.1275, 13.2282}, {49.7916, 15.7728}, {46.9933, 14.3356}, {42.9906, 13.2997}, {57.7506, 19.6366}, {60.0031, 21.2397}, {39.7839, 16.7387}, {35.6522, 16.1993}, {50.2161, 13.2613}, {54.3478, 13.8007}, {32.2494, 10.3634}, {29.9969, 8.76025}, {62.2531, 20.4897}, {48.8478, 11.8007}, {41.1522, 18.1993}, {27.7469, 9.51025}, {26.1219, 8.13525}, {37.2772, 17.5743}, {52.7228, 12.4257}, {63.8781, 21.8647}, {22.0285, 8.0241}, {31.745, 11.5437}, {18.0134, 9.32887}, {25.9898, 6.67381}, {12.2581, 4.45903}, {26.022, 11.4032}, {12.4202, 6.45729}, {31.5868, 9.54867}, {17.9851, 4.60275}, {15.5543, 10.1486}, {37.7561, 13.7295}, {6.24441, 2.27095}, {28.4462, 5.85188}, {31.136, 13.0766}, {28.8835, 11.4734}, {33.9975, 13.1468}, {11.0851, 7.35364}, {15.2168, 7.89308}, {13.8817, 8.78943}, {32.9184, 8.64933}, {28.7883, 8.11124}, {30.1199, 7.2119}, {12.8675, 2.92638}, {15.1216, 4.53089}, {10.0041, 2.85451}, {36.2475, 12.3968}, {31.6659, 10.5462}, {36.1684, 11.3993}, {24.6199, 5.2119}, {21.9874, 5.63828}, {20.6175, 4.17638}, {19.3817, 10.7894}, {22.0177, 10.366}, {23.386, 11.8266}, {7.75406, 3.60451}, {12.3392, 5.45816}, {7.83512, 4.60364}, {9.46012, 5.97864}, {27.261, 12.4516}, {16.7425, 3.55138}, {34.5434, 10.0243}, {24.0252, 9.71365}, {26.8868, 9.78387}, {20.0209, 8.67648}, {17.2244, 7.24069}, {17.1433, 6.24156}, {26.8076, 8.78638}, {24.0091, 7.34895}, {20.0068, 6.31343}, {34.7506, 12.6366}, {37.0031, 14.2397}, {16.7839, 9.73872}, {12.6522, 9.19928}, {27.218, 6.26285}, {31.3481, 6.80094}, {9.25127, 3.36499}, {6.9972, 1.76047}, {39.2531, 13.4897}, {25.8481, 4.80094}, {18.1522, 11.1993}, {4.7472, 2.51047}, {3.1222, 1.13547}, {14.2772, 10.5743}, {29.7231, 5.42594}, {40.8781, 14.8647}, {18, 9}, {25.9732, 12.9866}, {20.2148, 8.11409}, {15.7852, 9.88591}, {10.0268, 5.01339}, {22.0188, 12.4005}, {25.1102, 11.164}, {10.8898, 6.83603}, {13.9812, 5.59948}, {30.8914, 15.4457}, {21.5809, 7.56763}, {14.4191, 10.4324}, {5.10863, 2.55432}, {28.1116, 14.6183}, {23.996, 12.6936}, {26.1344, 14.3253}, {28.9301, 13.207}, {25.5417, 12.0753}, {29.3616, 14.1183}, {12.7676, 9.06796}, {13.3375, 8.36097}, {10.3199, 7.54302}, {15.6156, 5.42474}, {17.098, 6.85678}, {18.7324, 6.68204}, {23.2324, 8.93204}, {22.6625, 9.63903}, {25.6801, 10.457}, {20.3844, 12.5753}, {18.902, 11.1432}, {17.2676, 11.318}, {7.88839, 3.3817}, {12.004, 5.30644}, {9.8656, 3.67474}, {7.06991, 4.79302}, {10.4583, 5.92471}, {6.63839, 3.8817}, {23.2594, 13.4503}, {27.3051, 11.832}, {8.69491, 6.16802}, {12.7406, 4.54974}, {21.5551, 10.082}, {21.9866, 10.9933}, {20.0094, 10.7003}, {19.1074, 8.55704}, {16.8926, 9.44296}, {15.9906, 7.29974}, {14.4449, 7.91802}, {14.0134, 7.0067}, {28.4323, 14.2161}, {31.8207, 15.3478}, {30.5707, 15.8478}, {12.0845, 9.34119}, {15.1021, 10.1591}, {20.8979, 7.84086}, {19.4155, 6.40881}, {16.5845, 11.5912}, {23.9155, 8.65881}, {7.56771, 3.78385}, {4.17932, 2.65216}, {5.42932, 2.15216}, {13.7095, 10.7162}, {22.2905, 7.28381}, {33.4457, 16.7228}, {2.55432, 1.27716}, {27, 6}, {25.2282, 6.44296}, {38.9598, 8.65774}, {15.0402, 3.34226}, {28.7718, 5.55704}, {17.4167, 4.45431}, {34.1102, 8.16397}, {36.5833, 7.54569}, {19.8898, 3.83603}, {24.1353, 6.71619}, {46.3371, 10.2971}, {7.66295, 1.70288}, {29.8647, 5.28381}, {21.2391, 5.84648}, {21.3224, 5.44863}, {17.3334, 4.85215}, {32.4301, 8.20698}, {29.6692, 7.30346}, {27.9891, 7.34648}, {42.4166, 8.89785}, {37.7715, 8.10171}, {43.6049, 9.45387}, {11.3951, 2.29613}, {17.465, 3.58915}, {13.8199, 2.54302}, {42.6049, 9.70387}, {36.535, 8.41085}, {40.1801, 9.45698}, {11.5834, 3.10215}, {16.2285, 3.89829}, {10.3951, 2.54613}, {21.5699, 3.79302}, {24.3308, 4.69654}, {26.0109, 4.65352}, {32.7609, 6.15352}, {32.6776, 6.55137}, {36.6666, 7.14785}, {14.4584, 3.97715}, {39.5416, 8.02285}, {36.3051, 8.83198}, {17.6949, 3.16802}, {26.1141, 6.22148}, {22.2084, 5.22715}, {30.5551, 7.08198}, {32.9799, 7.32887}, {21.0201, 4.67113}, {31.7916, 6.77285}, {23.4449, 4.91802}, {27.8859, 5.77852}, {20.6926, 5.98309}, {24.6817, 6.57957}, {27.4426, 7.48309}, {42.6484, 9.47743}, {47.2935, 10.2736}, {7.70647, 1.47644}, {11.3516, 2.52257}, {46.2935, 10.5236}, {6.70647, 1.72644}, {29.3183, 5.42043}, {26.5574, 4.51691}, {33.3074, 6.01691}, {3.83147, 0.851438}, {23.5676, 6.85809}, {50.1685, 11.1486}, {30.4324, 5.14191}, {39.9408, 16.9869}, {51.9532, 19.6563}, {38.2282, 17.443}, {41.7718, 16.557}, {28.0402, 14.3423}, {49.576, 18.5441}, {47.1029, 19.1623}, {32.8833, 14.8346}, {30.4101, 15.4528}, {59.336, 21.2969}, {37.1353, 17.7162}, {42.8647, 16.2838}, {20.6629, 12.7029}, {55.6016, 20.7031}, {49.5281, 19.4093}, {53.1764, 20.4562}, {55.413, 19.897}, {50.7646, 19.1002}, {56.6016, 20.4531}, {34.5666, 14.7923}, {37.3275, 15.6958}, {39.0109, 15.6535}, {34.2391, 16.8465}, {34.3192, 16.4479}, {30.3301, 15.8514}, {45.4264, 19.2062}, {42.6655, 18.3026}, {40.9891, 18.3465}, {45.7609, 17.1535}, {45.6739, 17.5506}, {49.663, 18.147}, {24.5801, 14.1014}, {29.2252, 14.8976}, {23.3951, 13.5461}, {24.3951, 13.2961}, {30.4617, 14.5884}, {26.8166, 13.5423}, {49.3014, 19.8312}, {52.538, 19.022}, {30.6916, 14.1673}, {27.4551, 14.9764}, {45.947, 18.3216}, {44.7584, 17.7655}, {43.5219, 18.0746}, {39.0845, 17.2149}, {40.8563, 16.7719}, {35.1755, 16.2199}, {36.4121, 15.9107}, {33.9905, 15.6646}, {59.293, 21.5234}, {55.6446, 20.4766}, {60.293, 21.2734}, {42.3183, 16.4204}, {39.5574, 15.5169}, {33.6926, 16.9831}, {37.6817, 17.5796}, {46.3074, 17.0169}, {40.4426, 18.4831}, {20.7065, 12.4764}, {24.3516, 13.5226}, {19.7065, 12.7264}, {43.4324, 16.1419}, {36.5676, 17.8581}, {63.168, 22.1484}, {16.8315, 11.8514}, {45.1759, 15.8856}, {39.5938, 12.0061}, {31.4708, 9.95054}, {35.9029, 13.7007}, {20.9022, 8.24591}, {28.7434, 10.6324}, {33.1755, 14.3826}, {27.8731, 11.7846}, {21.1179, 11.3435}, {35.5323, 10.9783}, {33.6869, 11.8256}, {37.7483, 12.8534}, {33.7335, 11.8954}, {31.888, 12.7427}, {29.672, 10.8676}, {19.934, 12.0468}, {18.4516, 10.6147}, {21.5684, 11.872}, {26.7497, 8.98732}, {24.9508, 9.90437}, {26.1865, 9.09822}, {24.3877, 10.0153}, {21.4653, 8.13501}, {39.1888, 12.2181}, {36.7417, 10.6934}, {5.67652, 2.41263}, {6.95368, 1.98691}, {6.38579, 2.1286}, {17.4417, 6.9227}, {15.4645, 6.62965}, {15.699, 5.0269}, {13.7218, 4.73385}, {19.1594, 6.35011}, {28.9657, 10.8624}, {20.8904, 12.0232}, {24.5791, 12.8429}, {32.4407, 6.55582}, {32.2779, 6.70324}, {28.609, 5.70446}, {29.1555, 5.56785}, {32.9872, 6.41921}, {31.0497, 7.1142}, {27.3808, 6.11543}, {33.824, 12.6222}, {30.9624, 12.552}, {33.8969, 13.9801}, {38.8373, 15.1289}, {36.7584, 14.0503}, {44.3221, 13.0107}, {40.2606, 11.9829}, {42.4766, 13.858}, {25.764, 13.3982}, {17.7685, 10.8879}, {42.3848, 13.9458}, {39.1757, 15.1341}, {36.3846, 13.1943}, {30.5243, 13.0836}, {36.5245, 13.8351}, {55.8591, 18.2651}, {55.4304, 17.3547}, {10.6423, 2.80661}, {34.3931, 14.2676}, {37.9219, 15.3438}, {19.5657, 10.3362}, {20.934, 11.7968}, {18.3361, 10.746}, {40.5394, 14.7932}, {60.046, 21.0132}, {34.1686, 11.3192}, {30.9594, 12.5075}, {28.3083, 11.2085}, {38.2291, 10.276}, {36.2516, 9.98282}, {37.5457, 9.88172}, {11.655, 6.64666}, {61.3237, 20.5876}, {55.3495, 16.3557}, {60.6137, 20.8713}, {30.1071, 10.2915}, {48.0608, 18.7814}, {30.2416, 8.94965}, {34.6826, 9.81016}, {31.9992, 11.0444}, {31.4268, 9.39818}, {26.9858, 8.53767}, {52.0133, 12.7095}, {51.3302, 12.9828}, {51.3005, 17.9732}, {26.9476, 11.5939}, {29.4526, 13.1189}, {30.3782, 13.3096}, {47.1132, 14.9505}, {31.5288, 9.7496}, {31.6079, 10.7471}, {42.7394, 16.1224}, {23.4046, 7.00529}, {22.7215, 7.27852}, {31.7928, 14.9177}, {29.1416, 13.6187}, {36.5582, 15.6847}, {33.907, 14.3857}, {30.1826, 11.3102}, {30.2634, 12.3091}, {11.574, 5.64753}, {27.7349, 9.78522}, {40.2875, 11.8028}, {44.2902, 12.8386}, {39.2768, 10.3319}, {43.9732, 11.1644}, {39.9705, 10.1286}, {34.9021, 7.78607}, {33.5111, 8.34445}, {38.8078, 8.78039}, {33.2969, 9.00303}, {38.0885, 9.77588}, {34.0271, 8.74811}, {29.2354, 7.97527}, {23.3784, 5.0799}, {24.4791, 9.37324}, {26.9268, 10.8982}, {32.0801, 12.0433}, {17.541, 11.5676}, {34.7228, 16.2971}, {18.9374, 4.21939}, {24.728, 7.27665}, {25.6803, 6.89329}, {30.1213, 7.75379}, {15.896, 7.54097}, {16.5801, 6.35247}, {11.1425, 4.73621}, {16.6612, 7.3516}, {37.8448, 17.4324}, {53.3491, 19.1}, {50.486, 19.0284}, {42.2969, 13.503}, {49.9605, 17.2146}, {48.5646, 17.7709}, {47.0974, 17.1431}, {46.1394, 17.524}, {26.2145, 13.9267}, {27.5971, 13.3915}, {24.946, 12.0926}, {21.8292, 10.8353}, {24.4955, 11.5641}, {47.3759, 17.2148}, {42.5584, 16.4362}, {18.3437, 9.06591}, {19.4511, 8.62296}, {22.9366, 10.3923}, {34.0133, 16.5809}, {31.7127, 15.3163}, {35.1554, 16.0494}, {35.7018, 15.9128}, {21.8645, 7.20478}, {28.7303, 8.31217}, {23.9511, 7.12296}, {24.8228, 9.43915}, {27.8717, 8.31619}, {18.1086, 11.4257}, {42.2906, 11.3037}, {40.3104, 15.0067}, {36.852, 10.085}, {36.8717, 12.8162}, {39.0877, 14.6913}, {8.84487, 3.35813}, {8.1356, 3.64217}, {38.5825, 13.4882}, {39.2679, 13.2156}, {33.0618, 13.7464}, {33.4933, 14.6577}, {26.6896, 7.99334}, {40.7854, 9.07353}, {47.0885, 14.2759}, {36.6838, 10.8943}, {44.2813, 15.7223}, {43.5959, 15.9949}, {17.9712, 5.79409}, {18.8158, 6.2842}, {23.0801, 7.54335}, {25.5877, 11.6913}, {23.3717, 9.81619}, {13.6492, 3.90064}, {12.5335, 4.17783}, {45.088, 15.4428}, {52.4891, 18.5293}, {49.459, 11.4324}, {45.4043, 12.5601}, {45.0873, 10.8859}, {50.1007, 13.3926}, {48.8914, 11.5743}, {51.0746, 16.9361}, {54.4632, 18.8214}, {49.1005, 16.644}, {41.3468, 14.2942}, {44.4639, 15.5516}, {57.0405, 19.9203}, {52.5512, 14.9184}, {21.3623, 8.11593}, {32.2638, 15.0676}, {22.8581, 7.14191}, {37.0944, 15.3557}, {29.1428, 12.7733}, {29.5743, 13.6846}, {27.9567, 13.0635}, {14.1027, 8.1716}, {15.434, 9.79675}, {58.1546, 19.6417}, {44.1424, 15.8582}, {35.8649, 15.7656}, {41.5881, 14.5811}, {49.8796, 16.2156}, {50.6458, 16.0256}, {47.8548, 14.0859}, {33.9432, 9.25596}, {25.4124, 8.41906}, {27.236, 7.85673}, {38.3912, 17.2958}, {39.6208, 16.8859}, {16.074, 4.14753}, {20.396, 6.04097}, {48.7759, 11.7056}, {58.3182, 19.4947}, {27.0311, 12.8727}, {22.9433, 10.5568}, {39.764, 15.1433}, {41.0971, 16.3915}, {15.2065, 10.4764}, {28.4179, 9.51199}, {34.8784, 13.4806}, {20.1467, 9.12096}, {47.3984, 16.9797}, {39.1308, 12.4191}, {37.4244, 11.7312}, {47.6618, 11.9841}, {31.5542, 15.3514}, {43.6235, 17.9217}, {43.899, 10.3299}, {23.5699, 11.3734}, {16.7691, 8.9004}, {41.702, 16.6643}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 1364
- + nb_component : 6
- + allocated size : 1364
- + memory size : 63.94KiByte
- + values : {{13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 722
- + nb_component : 3
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0}, {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {1, 1, 1}, {0.25, 1, 1}, {0.5, 1, 1}, {0.75, 1, 1}, {0.125, 1, 1}, {0.375, 1, 1}, {0.625, 1, 1}, {0.875, 1, 1}, {1, 1, 0.75}, {1, 1, 0.5}, {1, 1, 0.25}, {1, 1, 0.875}, {1, 1, 0.625}, {1, 1, 0.375}, {1, 1, 0.125}, {0.75, 1, 0}, {0.5, 1, 0}, {0.25, 1, 0}, {0.875, 1, 0}, {0.625, 1, 0}, {0.375, 1, 0}, {0.125, 1, 0}, {0, 1, 0.25}, {0, 1, 0.5}, {0, 1, 0.75}, {0, 1, 0.125}, {0, 1, 0.375}, {0, 1, 0.625}, {0, 1, 0.875}, {0, 0, 0.25}, {0, 0, 0.5}, {0, 0, 0.75}, {0, 0, 0.125}, {0, 0, 0.375}, {0, 0, 0.625}, {0, 0, 0.875}, {0.25, 0, 1}, {0.5, 0, 1}, {0.75, 0, 1}, {0.125, 0, 1}, {0.375, 0, 1}, {0.625, 0, 1}, {0.875, 0, 1}, {1, 0, 0.75}, {1, 0, 0.5}, {1, 0, 0.25}, {1, 0, 0.875}, {1, 0, 0.625}, {1, 0, 0.375}, {1, 0, 0.125}, {0.75, 0, 0}, {0.5, 0, 0}, {0.25, 0, 0}, {0.875, 0, 0}, {0.625, 0, 0}, {0.375, 0, 0}, {0.125, 0, 0}, {0, 0.75, 0}, {0, 0.5, 0}, {0, 0.25, 0}, {0, 0.875, 0}, {0, 0.625, 0}, {0, 0.375, 0}, {0, 0.125, 0}, {0, 0.75, 1}, {0, 0.5, 1}, {0, 0.25, 1}, {0, 0.875, 1}, {0, 0.625, 1}, {0, 0.375, 1}, {0, 0.125, 1}, {1, 0.75, 1}, {1, 0.5, 1}, {1, 0.25, 1}, {1, 0.875, 1}, {1, 0.625, 1}, {1, 0.375, 1}, {1, 0.125, 1}, {1, 0.75, 0}, {1, 0.5, 0}, {1, 0.25, 0}, {1, 0.875, 0}, {1, 0.625, 0}, {1, 0.375, 0}, {1, 0.125, 0}, {0.5, 0.502191, 1}, {0.278522, 0.721478, 1}, {0.721478, 0.721478, 1}, {0.278522, 0.278765, 1}, {0.721478, 0.278765, 1}, {0.190862, 0.50027, 1}, {0.5, 0.809381, 1}, {0.809138, 0.50027, 1}, {0.5, 0.19116, 1}, {0.141906, 0.858094, 1}, {0.858094, 0.858094, 1}, {0.141906, 0.141947, 1}, {0.858094, 0.141947, 1}, {0.234692, 0.610874, 1}, {0.095431, 0.625135, 1}, {0.139261, 0.735739, 1}, {0.264261, 0.860739, 1}, {0.375, 0.904691, 1}, {0.389261, 0.76543, 1}, {0.860739, 0.735739, 1}, {0.904569, 0.625135, 1}, {0.765308, 0.610874, 1}, {0.264261, 0.139383, 1}, {0.389261, 0.234962, 1}, {0.375, 0.0955798, 1}, {0.610739, 0.76543, 1}, {0.625, 0.904691, 1}, {0.735739, 0.860739, 1}, {0.095431, 0.375135, 1}, {0.234692, 0.389518, 1}, {0.139261, 0.264383, 1}, {0.625, 0.0955798, 1}, {0.610739, 0.234962, 1}, {0.735739, 0.139383, 1}, {0.860739, 0.264383, 1}, {0.765308, 0.389518, 1}, {0.904569, 0.375135, 1}, {0.095431, 0.500135, 1}, {0.904569, 0.500135, 1}, {0.5, 0.904691, 1}, {0.5, 0.0955798, 1}, {0.389261, 0.611834, 1}, {0.345431, 0.501231, 1}, {0.5, 0.655786, 1}, {0.610739, 0.611834, 1}, {0.389261, 0.390478, 1}, {0.654569, 0.501231, 1}, {0.5, 0.346675, 1}, {0.610739, 0.390478, 1}, {0.0709532, 0.804047, 1}, {0.210214, 0.789786, 1}, {0.195953, 0.929047, 1}, {0.789786, 0.789786, 1}, {0.929047, 0.804047, 1}, {0.195953, 0.0709735, 1}, {0.210214, 0.210356, 1}, {0.804047, 0.929047, 1}, {0.0709532, 0.195973, 1}, {0.789786, 0.210356, 1}, {0.804047, 0.0709735, 1}, {0.929047, 0.195973, 1}, {0.0709532, 0.0709735, 1}, {0.0709532, 0.929047, 1}, {0.929047, 0.929047, 1}, {0.929047, 0.0709735, 1}, {0.5, 1, 0.5}, {0.721478, 1, 0.721478}, {0.721478, 1, 0.278522}, {0.278522, 1, 0.721478}, {0.278522, 1, 0.278522}, {0.809138, 1, 0.5}, {0.5, 1, 0.190862}, {0.5, 1, 0.809138}, {0.190862, 1, 0.5}, {0.858094, 1, 0.141906}, {0.858094, 1, 0.858094}, {0.141906, 1, 0.141906}, {0.141906, 1, 0.858094}, {0.904569, 1, 0.625}, {0.765308, 1, 0.610739}, {0.860739, 1, 0.735739}, {0.625, 1, 0.095431}, {0.610739, 1, 0.234692}, {0.735739, 1, 0.139261}, {0.375, 1, 0.904569}, {0.389261, 1, 0.765308}, {0.264261, 1, 0.860739}, {0.095431, 1, 0.375}, {0.234692, 1, 0.389261}, {0.139261, 1, 0.264261}, {0.735739, 1, 0.860739}, {0.610739, 1, 0.765308}, {0.625, 1, 0.904569}, {0.139261, 1, 0.735739}, {0.234692, 1, 0.610739}, {0.095431, 1, 0.625}, {0.860739, 1, 0.264261}, {0.765308, 1, 0.389261}, {0.904569, 1, 0.375}, {0.264261, 1, 0.139261}, {0.389261, 1, 0.234692}, {0.375, 1, 0.095431}, {0.5, 1, 0.095431}, {0.904569, 1, 0.5}, {0.095431, 1, 0.5}, {0.5, 1, 0.904569}, {0.654569, 1, 0.5}, {0.610739, 1, 0.610739}, {0.610739, 1, 0.389261}, {0.5, 1, 0.345431}, {0.389261, 1, 0.389261}, {0.5, 1, 0.654569}, {0.389261, 1, 0.610739}, {0.345431, 1, 0.5}, {0.789786, 1, 0.789786}, {0.929047, 1, 0.804047}, {0.789786, 1, 0.210214}, {0.804047, 1, 0.0709532}, {0.210214, 1, 0.789786}, {0.195953, 1, 0.929047}, {0.210214, 1, 0.210214}, {0.0709532, 1, 0.195953}, {0.804047, 1, 0.929047}, {0.0709532, 1, 0.804047}, {0.929047, 1, 0.195953}, {0.195953, 1, 0.0709532}, {0.0709532, 1, 0.0709532}, {0.929047, 1, 0.0709532}, {0.0709532, 1, 0.929047}, {0.929047, 1, 0.929047}, {0.502191, 0, 0.5}, {0.721478, 0, 0.721478}, {0.721478, 0, 0.278522}, {0.278765, 0, 0.721478}, {0.278765, 0, 0.278522}, {0.809381, 0, 0.5}, {0.50027, 0, 0.190862}, {0.50027, 0, 0.809138}, {0.19116, 0, 0.5}, {0.858094, 0, 0.141906}, {0.858094, 0, 0.858094}, {0.141947, 0, 0.141906}, {0.141947, 0, 0.858094}, {0.904691, 0, 0.625}, {0.76543, 0, 0.610739}, {0.860739, 0, 0.735739}, {0.625135, 0, 0.095431}, {0.610874, 0, 0.234692}, {0.735739, 0, 0.139261}, {0.375135, 0, 0.904569}, {0.389518, 0, 0.765308}, {0.264383, 0, 0.860739}, {0.0955798, 0, 0.375}, {0.234962, 0, 0.389261}, {0.139383, 0, 0.264261}, {0.735739, 0, 0.860739}, {0.610874, 0, 0.765308}, {0.625135, 0, 0.904569}, {0.139383, 0, 0.735739}, {0.234962, 0, 0.610739}, {0.0955798, 0, 0.625}, {0.860739, 0, 0.264261}, {0.76543, 0, 0.389261}, {0.904691, 0, 0.375}, {0.264383, 0, 0.139261}, {0.389518, 0, 0.234692}, {0.375135, 0, 0.095431}, {0.500135, 0, 0.095431}, {0.904691, 0, 0.5}, {0.0955798, 0, 0.5}, {0.500135, 0, 0.904569}, {0.655786, 0, 0.5}, {0.611834, 0, 0.610739}, {0.611834, 0, 0.389261}, {0.501231, 0, 0.345431}, {0.390478, 0, 0.389261}, {0.501231, 0, 0.654569}, {0.390478, 0, 0.610739}, {0.346675, 0, 0.5}, {0.789786, 0, 0.789786}, {0.929047, 0, 0.804047}, {0.789786, 0, 0.210214}, {0.804047, 0, 0.0709532}, {0.210356, 0, 0.789786}, {0.195973, 0, 0.929047}, {0.210356, 0, 0.210214}, {0.0709735, 0, 0.195953}, {0.804047, 0, 0.929047}, {0.0709735, 0, 0.804047}, {0.929047, 0, 0.195953}, {0.195973, 0, 0.0709532}, {0.0709735, 0, 0.0709532}, {0.929047, 0, 0.0709532}, {0.0709735, 0, 0.929047}, {0.929047, 0, 0.929047}, {0.5, 0.5, 0}, {0.721478, 0.721478, 0}, {0.278522, 0.721478, 0}, {0.721478, 0.278522, 0}, {0.278522, 0.278522, 0}, {0.809138, 0.5, 0}, {0.5, 0.809138, 0}, {0.5, 0.190862, 0}, {0.190862, 0.5, 0}, {0.858094, 0.858094, 0}, {0.141906, 0.858094, 0}, {0.858094, 0.141906, 0}, {0.141906, 0.141906, 0}, {0.860739, 0.735739, 0}, {0.765308, 0.610739, 0}, {0.904569, 0.625, 0}, {0.625, 0.904569, 0}, {0.610739, 0.765308, 0}, {0.735739, 0.860739, 0}, {0.735739, 0.139261, 0}, {0.610739, 0.234692, 0}, {0.625, 0.095431, 0}, {0.095431, 0.625, 0}, {0.234692, 0.610739, 0}, {0.139261, 0.735739, 0}, {0.264261, 0.860739, 0}, {0.389261, 0.765308, 0}, {0.375, 0.904569, 0}, {0.904569, 0.375, 0}, {0.765308, 0.389261, 0}, {0.860739, 0.264261, 0}, {0.139261, 0.264261, 0}, {0.234692, 0.389261, 0}, {0.095431, 0.375, 0}, {0.375, 0.095431, 0}, {0.389261, 0.234692, 0}, {0.264261, 0.139261, 0}, {0.904569, 0.5, 0}, {0.5, 0.904569, 0}, {0.5, 0.095431, 0}, {0.095431, 0.5, 0}, {0.5, 0.654569, 0}, {0.610739, 0.610739, 0}, {0.654569, 0.5, 0}, {0.389261, 0.610739, 0}, {0.610739, 0.389261, 0}, {0.345431, 0.5, 0}, {0.5, 0.345431, 0}, {0.389261, 0.389261, 0}, {0.789786, 0.789786, 0}, {0.804047, 0.929047, 0}, {0.929047, 0.804047, 0}, {0.804047, 0.0709532, 0}, {0.789786, 0.210214, 0}, {0.210214, 0.789786, 0}, {0.0709532, 0.804047, 0}, {0.929047, 0.195953, 0}, {0.195953, 0.929047, 0}, {0.210214, 0.210214, 0}, {0.195953, 0.0709532, 0}, {0.0709532, 0.195953, 0}, {0.929047, 0.0709532, 0}, {0.0709532, 0.929047, 0}, {0.929047, 0.929047, 0}, {0.0709532, 0.0709532, 0}, {0, 0.5, 0.5}, {0, 0.721478, 0.278522}, {0, 0.721478, 0.721478}, {0, 0.278522, 0.278522}, {0, 0.278522, 0.721478}, {0, 0.5, 0.190862}, {0, 0.809138, 0.5}, {0, 0.5, 0.809138}, {0, 0.190862, 0.5}, {0, 0.858094, 0.141906}, {0, 0.858094, 0.858094}, {0, 0.141906, 0.141906}, {0, 0.141906, 0.858094}, {0, 0.735739, 0.139261}, {0, 0.610739, 0.234692}, {0, 0.625, 0.095431}, {0, 0.904569, 0.375}, {0, 0.765308, 0.389261}, {0, 0.860739, 0.264261}, {0, 0.625, 0.904569}, {0, 0.610739, 0.765308}, {0, 0.735739, 0.860739}, {0, 0.139261, 0.264261}, {0, 0.234692, 0.389261}, {0, 0.095431, 0.375}, {0, 0.860739, 0.735739}, {0, 0.765308, 0.610739}, {0, 0.904569, 0.625}, {0, 0.375, 0.095431}, {0, 0.389261, 0.234692}, {0, 0.264261, 0.139261}, {0, 0.095431, 0.625}, {0, 0.234692, 0.610739}, {0, 0.139261, 0.735739}, {0, 0.264261, 0.860739}, {0, 0.389261, 0.765308}, {0, 0.375, 0.904569}, {0, 0.5, 0.095431}, {0, 0.5, 0.904569}, {0, 0.904569, 0.5}, {0, 0.095431, 0.5}, {0, 0.610739, 0.389261}, {0, 0.5, 0.345431}, {0, 0.654569, 0.5}, {0, 0.610739, 0.610739}, {0, 0.389261, 0.389261}, {0, 0.5, 0.654569}, {0, 0.345431, 0.5}, {0, 0.389261, 0.610739}, {0, 0.804047, 0.0709532}, {0, 0.789786, 0.210214}, {0, 0.929047, 0.195953}, {0, 0.789786, 0.789786}, {0, 0.804047, 0.929047}, {0, 0.0709532, 0.195953}, {0, 0.210214, 0.210214}, {0, 0.929047, 0.804047}, {0, 0.195953, 0.0709532}, {0, 0.210214, 0.789786}, {0, 0.0709532, 0.804047}, {0, 0.195953, 0.929047}, {0, 0.0709532, 0.0709532}, {0, 0.929047, 0.0709532}, {0, 0.929047, 0.929047}, {0, 0.0709532, 0.929047}, {1, 0.498905, 0.498905}, {1, 0.721356, 0.721356}, {1, 0.721478, 0.278522}, {1, 0.278522, 0.721478}, {1, 0.278522, 0.278522}, {1, 0.499865, 0.809003}, {1, 0.809003, 0.499865}, {1, 0.19074, 0.499878}, {1, 0.499878, 0.19074}, {1, 0.858073, 0.858073}, {1, 0.858094, 0.141906}, {1, 0.141906, 0.858094}, {1, 0.141906, 0.141906}, {1, 0.860678, 0.735678}, {1, 0.76518, 0.610611}, {1, 0.904501, 0.624932}, {1, 0.624932, 0.904501}, {1, 0.610611, 0.76518}, {1, 0.735678, 0.860678}, {1, 0.0953701, 0.624939}, {1, 0.234631, 0.610678}, {1, 0.139261, 0.735739}, {1, 0.735739, 0.139261}, {1, 0.610678, 0.234631}, {1, 0.624939, 0.0953701}, {1, 0.904501, 0.374932}, {1, 0.76524, 0.389193}, {1, 0.860739, 0.264261}, {1, 0.264261, 0.860739}, {1, 0.389193, 0.76524}, {1, 0.374932, 0.904501}, {1, 0.374939, 0.0953701}, {1, 0.3892, 0.234631}, {1, 0.264261, 0.139261}, {1, 0.139261, 0.264261}, {1, 0.234631, 0.3892}, {1, 0.0953701, 0.374939}, {1, 0.904501, 0.499932}, {1, 0.499932, 0.904501}, {1, 0.0953701, 0.499939}, {1, 0.499939, 0.0953701}, {1, 0.610131, 0.610131}, {1, 0.499385, 0.653954}, {1, 0.653954, 0.499385}, {1, 0.610191, 0.388713}, {1, 0.388713, 0.610191}, {1, 0.499391, 0.344822}, {1, 0.344822, 0.499391}, {1, 0.388713, 0.388713}, {1, 0.929037, 0.804037}, {1, 0.789715, 0.789715}, {1, 0.804037, 0.929037}, {1, 0.210214, 0.789786}, {1, 0.0709532, 0.804047}, {1, 0.804047, 0.0709532}, {1, 0.789786, 0.210214}, {1, 0.195953, 0.929047}, {1, 0.929047, 0.195953}, {1, 0.0709532, 0.195953}, {1, 0.210214, 0.210214}, {1, 0.195953, 0.0709532}, {1, 0.0709532, 0.929047}, {1, 0.929047, 0.0709532}, {1, 0.929037, 0.929037}, {1, 0.0709532, 0.0709532}, {0.714627, 0.67977, 0.65326}, {0.384087, 0.668738, 0.619989}, {0.423487, 0.335588, 0.588613}, {0.764413, 0.335588, 0.588613}, {0.423487, 0.335588, 0.247688}, {0.423487, 0.676512, 0.247688}, {0.764413, 0.676512, 0.247688}, {0.682024, 0.369799, 0.338757}, {0.815437, 0.205866, 0.186526}, {0.403787, 0.502163, 0.604301}, {0.59395, 0.335588, 0.588613}, {0.57425, 0.502163, 0.604301}, {0.533055, 0.519268, 0.479373}, {0.723218, 0.352693, 0.463685}, {0.552756, 0.352693, 0.463685}, {0.907719, 0.227933, 0.0932632}, {0.768458, 0.242194, 0.0932632}, {0.812288, 0.352933, 0.0932632}, {0.462839, 0.167794, 0.544306}, {0.592107, 0.184899, 0.419378}, {0.423487, 0.335588, 0.41815}, {0.552756, 0.352693, 0.293222}, {0.462839, 0.167794, 0.373844}, {0.610874, 0.139383, 0.904569}, {0.500135, 0.0955798, 0.904569}, {0.141927, 0.0709532, 0.0709532}, {0.0709735, 0.0709532, 0.141906}, {0.0709532, 0.141906, 0.0709532}, {0.307175, 0.417794, 0.123844}, {0.351005, 0.307055, 0.123844}, {0.095431, 0.5, 0.095431}, {0.139261, 0.389261, 0.095431}, {0.211744, 0.417794, 0.219275}, {0.633302, 0.167794, 0.544306}, {0.907719, 0.173886, 0.164216}, {0.907719, 0.242194, 0.232524}, {0.0709532, 0.210234, 0.860739}, {0.141927, 0.0709735, 0.929047}, {0.0709735, 0.139261, 0.789786}, {0.0709735, 0.0709532, 0.858094}, {0.0709532, 0.141927, 0.929047}, {0.210336, 0.0709735, 0.860739}, {0.139383, 0.139261, 0.721478}, {0.742945, 0.167794, 0.655045}, {0.786897, 0.167794, 0.544306}, {0.904691, 0.139261, 0.610739}, {0.882206, 0.307055, 0.655045}, {0.860739, 0.139261, 0.721478}, {0.442043, 0.585464, 0.809994}, {0.461744, 0.418889, 0.794306}, {0.632206, 0.418889, 0.794306}, {0.907719, 0.352872, 0.188633}, {0.836765, 0.173886, 0.0932632}, {0.549357, 0.674254, 0.636624}, {0.73952, 0.678141, 0.450474}, {0.57425, 0.672625, 0.433838}, {0.723218, 0.523156, 0.293222}, {0.698326, 0.524784, 0.496008}, {0.721478, 0.860739, 0.860739}, {0.610739, 0.904691, 0.860739}, {0.0709735, 0.139261, 0.210214}, {0.882206, 0.263164, 0.544245}, {0.882206, 0.417246, 0.543759}, {0.768458, 0.102933, 0.232524}, {0.907719, 0.102933, 0.218263}, {0.836765, 0.102933, 0.164216}, {0.73952, 0.507679, 0.620936}, {0.929047, 0.929037, 0.858083}, {0.403787, 0.672625, 0.433838}, {0.59395, 0.676512, 0.247688}, {0.552756, 0.523156, 0.293222}, {0.307175, 0.417929, 0.794306}, {0.351005, 0.307176, 0.794306}, {0.095431, 0.904569, 0.5}, {0.500135, 0.095431, 0.095431}, {0.858094, 0.929047, 0.929047}, {0.5, 0.904691, 0.904569}, {0.929047, 0.858083, 0.929037}, {0.423487, 0.50605, 0.41815}, {0.904569, 0.904501, 0.499932}, {0.139261, 0.860739, 0.278522}, {0.139261, 0.904569, 0.389261}, {0.351005, 0.838256, 0.263105}, {0.211744, 0.742825, 0.373844}, {0.211744, 0.698995, 0.263105}, {0.141906, 0.929047, 0.929047}, {0.210214, 0.860739, 0.929047}, {0.904569, 0.500068, 0.904501}, {0.745703, 0.184899, 0.419378}, {0.904691, 0.0953701, 0.499939}, {0.841012, 0.280269, 0.419318}, {0.607314, 0.59098, 0.82663}, {0.461879, 0.167794, 0.698875}, {0.572483, 0.167794, 0.655045}, {0.882206, 0.417726, 0.698808}, {0.0709532, 0.789786, 0.139261}, {0.139261, 0.721478, 0.139261}, {0.882206, 0.588195, 0.219214}, {0.841012, 0.434839, 0.264749}, {0.882206, 0.587709, 0.373296}, {0.841012, 0.434352, 0.418831}, {0.389261, 0.904569, 0.139261}, {0.5, 0.904569, 0.095431}, {0.389383, 0.095431, 0.139261}, {0.278522, 0.860739, 0.139261}, {0.287474, 0.834369, 0.559994}, {0.331304, 0.834369, 0.670734}, {0.192043, 0.695108, 0.670734}, {0.139261, 0.860739, 0.721478}, {0.095431, 0.860739, 0.610739}, {0.139261, 0.278644, 0.860739}, {0.278644, 0.139383, 0.860739}, {0.139261, 0.389383, 0.904569}, {0.192043, 0.584369, 0.559994}, {0.192043, 0.584369, 0.714563}, {0.211744, 0.417794, 0.698875}, {0.211744, 0.417794, 0.544306}, {0.0955798, 0.139261, 0.610739}, {0.351005, 0.698995, 0.123844}, {0.461744, 0.742825, 0.123844}, {0.461744, 0.838256, 0.219275}, {0.929047, 0.141906, 0.0709532}, {0.858094, 0.929047, 0.0709532}, {0.0955798, 0.095431, 0.5}, {0.307323, 0.167794, 0.544306}, {0.211744, 0.263225, 0.544306}, {0.211744, 0.307055, 0.655045}, {0.461744, 0.263225, 0.123844}, {0.351126, 0.167794, 0.263105}, {0.278644, 0.139261, 0.139261}, {0.461879, 0.167794, 0.219275}, {0.929047, 0.929047, 0.141906}, {0.860739, 0.860678, 0.721417}, {0.904569, 0.860678, 0.610678}, {0.442043, 0.834369, 0.559994}, {0.718053, 0.839885, 0.687369}, {0.857314, 0.700563, 0.687308}, {0.761883, 0.839885, 0.57663}, {0.857314, 0.744386, 0.576562}, {0.904569, 0.499939, 0.0953701}, {0.786775, 0.588256, 0.123844}, {0.745581, 0.434899, 0.169378}, {0.701751, 0.32416, 0.169378}, {0.748731, 0.287832, 0.262642}, {0.857314, 0.589817, 0.731131}, {0.857314, 0.589337, 0.576082}, {0.572483, 0.307055, 0.123844}, {0.461744, 0.417794, 0.123844}, {0.591012, 0.434899, 0.169378}, {0.929047, 0.858094, 0.0709532}, {0.882206, 0.713256, 0.123844}, {0.882206, 0.767303, 0.194797}, {0.882206, 0.698995, 0.263105}, {0.351126, 0.167794, 0.433567}, {0.351126, 0.167794, 0.655045}, {0.211744, 0.417794, 0.373844}, {0.423487, 0.50605, 0.247688}, {0.211744, 0.588256, 0.373844}, {0.929047, 0.0709532, 0.141906}, {0.287474, 0.584504, 0.809994}, {0.929047, 0.0709532, 0.858094}, {0.192043, 0.738938, 0.559994}, {0.461744, 0.838256, 0.373844}, {0.632206, 0.838256, 0.373844}, {0.139261, 0.210214, 0.0709532}, {0.210234, 0.139261, 0.0709532}, {0.789786, 0.0709735, 0.860739}, {0.721478, 0.139383, 0.860739}, {0.610739, 0.904569, 0.139261}, {0.721478, 0.860739, 0.139261}, {0.0709532, 0.929047, 0.141906}, {0.095431, 0.500135, 0.904569}, {0.442043, 0.834369, 0.714563}, {0.461744, 0.263374, 0.794306}, {0.860739, 0.278644, 0.860739}, {0.929047, 0.210234, 0.860739}, {0.211744, 0.307055, 0.263105}, {0.139261, 0.610739, 0.095431}, {0.211744, 0.588256, 0.219275}, {0.632206, 0.588256, 0.123844}, {0.461744, 0.588256, 0.123844}, {0.139383, 0.139261, 0.278522}, {0.139261, 0.278522, 0.139261}, {0.607314, 0.839885, 0.57663}, {0.904569, 0.610813, 0.860678}, {0.0709532, 0.858094, 0.929047}, {0.331304, 0.695108, 0.809994}, {0.139261, 0.721478, 0.860739}, {0.278522, 0.860739, 0.860739}, {0.0709532, 0.929047, 0.858094}, {0.718053, 0.700624, 0.82663}, {0.860739, 0.721417, 0.860678}, {0.761883, 0.59002, 0.82663}, {0.742945, 0.307176, 0.794306}, {0.786775, 0.417929, 0.794306}, {0.860739, 0.929037, 0.789776}, {0.389261, 0.904691, 0.860739}, {0.307175, 0.588256, 0.123844}, {0.789786, 0.860739, 0.0709532}, {0.0709532, 0.858094, 0.0709532}, {0.742945, 0.838256, 0.263105}, {0.632206, 0.742825, 0.123844}, {0.742945, 0.698995, 0.123844}, {0.841012, 0.32416, 0.308639}, {0.610874, 0.139261, 0.095431}, {0.782719, 0.102933, 0.0932632}, {0.860739, 0.789776, 0.929037}, {0.929047, 0.141927, 0.929047}, {0.811253, 0.838256, 0.194797}, {0.858094, 0.0709735, 0.929047}, {0.607314, 0.839885, 0.731199}, {0.607314, 0.744576, 0.82663}, {0.442043, 0.73906, 0.809994}, {0.389383, 0.0955798, 0.860739}, {0.141906, 0.929047, 0.0709532}, {0.0709532, 0.860739, 0.210214}, {0.929047, 0.860739, 0.210214}, {0.860739, 0.860739, 0.278522}, {0.139383, 0.095431, 0.389261}, {0.211744, 0.263225, 0.373844}, {0.139261, 0.789786, 0.929047}, {0.789786, 0.929047, 0.860739}, {0.904691, 0.139261, 0.389261}, {0.701751, 0.184899, 0.308639}, {0.929047, 0.139261, 0.789786}, {0.786775, 0.838256, 0.373844}, {0.875, 0.0709532, 0.0709532}, {0.210214, 0.929047, 0.139261}, {0.572483, 0.838256, 0.263105}, {0.591147, 0.184899, 0.264809}, {0.904569, 0.389396, 0.860739}, {0.572483, 0.307176, 0.794306}, {0.331304, 0.834369, 0.449255}, {0.139261, 0.929047, 0.789786}, {0.860739, 0.789786, 0.0709532}, {0.904569, 0.860739, 0.389261}, {0.139261, 0.610739, 0.904569}, {0.812409, 0.102933, 0.343263}, {0.657854, 0.102933, 0.188694}, {0.857314, 0.700624, 0.465891}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 1364
- + nb_component : 9
- + allocated size : 1364
- + memory size : 95.91KiByte
- + values : {{1, 2.22045e-16, 4.44089e-16, -1.94289e-16, 1, -5.55112e-17, 9.4369e-16, 1.44329e-15, 1}, {1, -4.44089e-16, 4.44089e-16, -8.32667e-16, 1, -1.04083e-15, -1.11022e-16, -5.27356e-16, 1}, {1, 1.11022e-16, -4.44089e-16, 2.22045e-16, 1, 5.55112e-17, 8.88178e-16, 4.44089e-16, 1}, {1, 0, 0, 5.55112e-17, 1, 4.44089e-16, 4.44089e-16, 4.44089e-16, 1}, {1, -2.22045e-16, 6.93889e-18, -2.22045e-16, 1, 0, 4.44089e-16, -1.11022e-15, 1}, {1, 2.35922e-16, 2.42861e-17, 8.88178e-16, 1, 0, -8.88178e-16, -4.44089e-16, 1}, {1, -4.996e-16, -9.71445e-17, 1.77636e-15, 1, 0, 3.55271e-15, -4.44089e-16, 1}, {1, -5.13478e-16, 1.38778e-17, -1.33227e-15, 1, 2.77556e-17, 1.77636e-15, 8.88178e-16, 1}, {1, 1.38778e-16, 0, 1.11022e-16, 1, -3.05311e-16, 0, -2.22045e-16, 1}, {1, 2.77556e-16, -1.94289e-15, -1.11022e-16, 1, -4.16334e-16, -1.22125e-15, 3.33067e-16, 1}, {1, 2.22045e-16, -8.88178e-16, 1.66533e-16, 1, 3.05311e-16, 4.44089e-16, 4.44089e-16, 1}, {1, -4.44089e-16, -8.88178e-16, 8.88178e-16, 1, 5.55112e-16, 3.33067e-16, -3.33067e-16, 1}, {1, 2.498e-16, 1.33227e-15, -2.22045e-16, 1, 8.88178e-16, -1.77636e-15, 0, 1}, {1, 2.77556e-17, -1.33227e-15, 8.88178e-16, 1, 8.88178e-16, -2.22045e-15, -3.33067e-16, 1}, {1, 0, -1.77636e-15, 1.11022e-15, 1, 4.44089e-16, 0, 4.44089e-16, 1}, {1, 8.32667e-17, 4.44089e-16, 1.77636e-15, 1, 1.77636e-15, 0, 2.22045e-16, 1}, {1, 0, 0, 3.33067e-16, 1, 0, 6.66134e-16, 0, 1}, {1, 0, 0, -1.11022e-16, 1, 0, 0, 0, 1}, {1, 0, 0, -8.88178e-16, 1, 0, -2.22045e-16, 0, 1}, {1, 0, 0, 1.11022e-16, 1, 0, -4.44089e-16, 0, 1}, {1, 1.11022e-16, -1.11022e-16, -6.67462e-17, 1, 7.80964e-17, 4.73796e-17, -1.71975e-16, 1}, {1, -2.77556e-16, 5.55112e-17, -2.168e-16, 1, -2.46724e-16, 3.66867e-17, 9.24147e-17, 1}, {1, -2.22045e-16, -1.11022e-16, -3.33067e-16, 1, 1.11022e-16, -1.11022e-16, 1.11022e-16, 1}, {1, -1.11022e-16, -1.11022e-16, 1.11022e-16, 1, 0, 1.11022e-16, -5.55112e-17, 1}, {1, 8.88178e-16, 2.22045e-16, 2.77556e-16, 1, -5.55112e-17, -3.98986e-16, 1.94289e-16, 1}, {1, 8.88178e-16, -1.66533e-16, -2.22045e-16, 1, 1.11022e-16, 1.8735e-16, -4.996e-16, 1}, {1, -4.44089e-16, -1.11022e-16, 1.11022e-16, 1, -1.11022e-16, 3.33067e-16, 4.44089e-16, 1}, {1, -8.88178e-16, -1.11022e-16, 4.44089e-16, 1, 4.44089e-16, 5.55112e-17, 1.77636e-15, 1}, {1, 3.33067e-16, 4.44089e-16, -6.10623e-16, 1, 2.498e-16, 9.4369e-16, 3.88578e-16, 1}, {1, 2.22045e-16, 6.66134e-16, 5.55112e-17, 1, 0, -4.44089e-16, 4.996e-16, 1}, {1, -4.44089e-16, 0, -2.22045e-16, 1, 1.08247e-15, 8.88178e-16, 2.22045e-16, 1}, {1, 0, -1.44329e-15, 2.22045e-16, 1, 0, 0, 0, 1}, {1, 3.33067e-16, -1.11022e-16, -4.44089e-16, 1, -1.11022e-16, 2.22045e-16, 4.996e-16, 1}, {1, -5.55112e-16, -6.66134e-16, -2.22045e-15, 1, 2.22045e-16, -4.44089e-16, 1.66533e-16, 1}, {1, -8.88178e-16, -8.88178e-16, 1.33227e-15, 1, 0, 0, -5.55112e-17, 1}, {1, 4.44089e-16, -2.22045e-16, 0, 1, 0, -8.88178e-16, 2.22045e-16, 1}, {1, -4.44089e-16, -4.44089e-16, -5.55112e-17, 1, -2.66454e-15, 3.75568e-16, 6.70471e-16, 1}, {1, -7.77156e-16, -3.55271e-15, 5.55112e-17, 1, -1.77636e-15, 9.80119e-17, 2.08167e-16, 1}, {1, -6.66134e-16, -3.55271e-15, 1.11022e-16, 1, 1.77636e-15, -1.66533e-16, 3.88578e-16, 1}, {1, -8.32667e-17, 1.77636e-15, 0, 1, 0, 0, -2.22045e-16, 1}, {1, -2.77556e-16, -1.11022e-16, -1.11022e-16, 1, -4.44089e-16, 8.32667e-17, 1.38778e-17, 1}, {1, -4.44089e-16, 1.88738e-15, -4.44089e-16, 1, 8.88178e-16, 2.22045e-16, -2.77556e-16, 1}, {1, 1.66533e-16, 2.66454e-15, -1.38778e-17, 1, 2.94209e-15, 0, -9.71445e-17, 1}, {1, 3.33067e-16, 0, 0, 1, -3.55271e-15, 2.77556e-16, 1.11022e-16, 1}, {1, 0, 2.88658e-15, -4.44089e-16, 1, 2.22045e-16, -1.11022e-16, -1.38778e-17, 1}, {1, 0, -2.22045e-16, -9.4369e-16, 1, 6.66134e-16, 5.55112e-17, 0, 1}, {1, 0, -3.55271e-15, -1.33227e-15, 1, -7.10543e-15, 0, 1.38778e-17, 1}, {1, 0, 8.88178e-16, 3.33067e-16, 1, -1.33227e-15, 2.22045e-16, 0, 1}, {1, -1.94289e-16, -5.82867e-16, 1.11022e-15, 1, -2.22045e-16, 1.73472e-15, 8.32667e-17, 1}, {1, -1.66533e-16, -5.55112e-17, -4.44089e-16, 1, 2.22045e-16, 3.70537e-15, -1.38778e-17, 1}, {1, 0, 1.77636e-15, 8.88178e-16, 1, 4.44089e-16, -4.44089e-16, -3.33067e-16, 1}, {1, 2.22045e-16, -4.44089e-16, -8.88178e-16, 1, 0, -6.66134e-16, -3.33067e-16, 1}, {1, -3.33067e-16, -2.22045e-16, 7.77156e-16, 1, 7.77156e-16, -5.55112e-17, 2.77556e-17, 1}, {1, 7.39148e-16, -1.14957e-15, -2.22045e-16, 1, -4.44089e-16, 5.55112e-17, 1.11022e-16, 1}, {1, 1.11022e-15, 1.33227e-15, -1.11022e-16, 1, 3.33067e-16, 4.44089e-16, -2.22045e-16, 1}, {1, 0, -8.88178e-16, 0, 1, -8.88178e-16, 4.44089e-16, 1.11022e-16, 1}, {1, -1.55431e-15, 0, 1.77636e-15, 1, -1.11022e-16, -5.27356e-16, 2.08167e-16, 1}, {1, -2.22045e-16, -6.66134e-16, -2.22045e-15, 1, -3.88578e-16, -9.99201e-16, 1.38778e-16, 1}, {1, -8.88178e-16, 0, 4.44089e-16, 1, -5.55112e-17, 1.66533e-16, -2.498e-16, 1}, {1, -4.44089e-16, -2.22045e-16, 0, 1, 4.44089e-16, 0, -6.10623e-16, 1}, {1, -2.77556e-16, 0, -2.22045e-15, 1, 2.77556e-17, -1.55431e-15, 3.33067e-16, 1}, {1, -3.88578e-16, -2.77556e-17, -8.88178e-16, 1, 2.77556e-17, 2.44249e-15, -2.77556e-16, 1}, {1, -1.11022e-16, 0, -1.9984e-15, 1, -5.55112e-17, -1.77636e-15, 1.33227e-15, 1}, {1, -2.22045e-16, 0, -4.44089e-15, 1, -1.11022e-16, 1.11022e-15, 1.11022e-16, 1}, {1, -6.80012e-16, -8.32667e-17, -3.33067e-16, 1, -8.04912e-16, -5.55112e-16, 0, 1}, {1, -1.52656e-16, -1.66533e-16, 1.77636e-15, 1, 2.77556e-16, -1.11022e-16, 3.33067e-16, 1}, {1, 1.36002e-15, 9.71445e-17, -8.88178e-16, 1, -4.44089e-16, 6.66134e-16, 7.77156e-16, 1}, {1, 3.60822e-16, -1.94289e-16, -4.44089e-16, 1, 0, -8.88178e-16, -4.44089e-16, 1}, {1, -1.77636e-15, 0, -1.55431e-15, 1, -1.9984e-15, 6.66134e-16, 8.88178e-16, 1}, {1, -8.88178e-16, -8.88178e-16, -4.44089e-16, 1, 1.19349e-15, 6.66134e-16, 1.11022e-15, 1}, {1, -1.77636e-15, -1.77636e-15, 3.33067e-16, 1, 8.88178e-16, 4.44089e-16, 1.11022e-16, 1}, {1, 4.44089e-16, -4.44089e-16, 1.27676e-15, 1, 6.38378e-16, 0, 1.77636e-15, 1}, {1, 5.55112e-16, -2.22045e-16, 0, 1, -1.11022e-16, 2.77556e-17, 6.66134e-16, 1}, {1, 1.11022e-16, 3.88578e-16, 0, 1, -5.55112e-17, -2.77556e-17, 1.11022e-16, 1}, {1, 1.66533e-16, 0, 0, 1, -6.66134e-16, 0, -3.88578e-16, 1}, {1, 2.22045e-16, 2.22045e-15, 0, 1, 3.33067e-16, 0, 0, 1}, {1, -6.66134e-16, 1.11022e-16, 1.11022e-15, 1, 1.93422e-16, -8.88178e-16, 5.55112e-16, 1}, {1, -5.55112e-17, -3.33067e-16, 6.66134e-16, 1, -1.02782e-15, -8.88178e-16, -2.22045e-16, 1}, {1, -4.44089e-16, 4.44089e-16, 8.88178e-16, 1, 0, 0, 2.22045e-16, 1}, {1, -2.22045e-16, 0, 0, 1, 8.88178e-16, 0, 0, 1}, {1, -2.77556e-17, 2.22045e-16, 0, 1, 0, 1.33227e-15, 0, 1}, {1, -2.77556e-17, -2.77556e-16, -8.88178e-16, 1, -7.77156e-16, -4.44089e-16, 2.77556e-17, 1}, {1, 0, 5.55112e-17, 0, 1, 0, 2.22045e-15, 2.77556e-17, 1}, {1, 0, -4.44089e-16, -8.88178e-16, 1, 0, 3.55271e-15, 4.44089e-16, 1}, {1, -1.70003e-16, -7.28584e-16, 4.44089e-16, 1, -5.55112e-16, -1.13798e-15, -4.16334e-16, 1}, {1, 6.48787e-16, -1.34615e-15, 0, 1, -1.22125e-15, 1.16573e-15, -1.4988e-15, 1}, {1, -3.33067e-16, -3.33067e-16, -1.38778e-17, 1, 1.42247e-15, -8.88178e-16, 0, 1}, {1, -8.32667e-17, -4.71845e-16, 8.88178e-16, 1, 0, 0, -4.44089e-16, 1}, {1, -2.22045e-16, 1.9984e-15, 8.88178e-16, 1, 3.55271e-15, -1.77636e-15, 4.44089e-16, 1}, {1, -2.22045e-16, -2.22045e-16, 0, 1, 2.22045e-15, -1.77636e-15, -4.44089e-16, 1}, {1, -2.22045e-16, 2.88658e-15, -5.32907e-15, 1, 0, 1.77636e-15, 0, 1}, {1, 8.88178e-16, 8.88178e-16, -1.77636e-15, 1, -4.44089e-16, 0, 0, 1}, {1, -9.99201e-16, 0, -1.66533e-16, 1, -2.08167e-16, 4.16334e-17, -2.77556e-17, 1}, {1, 4.44089e-16, -3.33067e-16, -1.66533e-16, 1, -1.66533e-16, 2.35922e-16, 8.32667e-17, 1}, {1, 2.22045e-16, -1.66533e-16, 0, 1, -4.44089e-16, -8.11851e-16, -7.38992e-16, 1}, {1, 0, 0, 4.44089e-16, 1, -2.22045e-16, -1.11022e-16, -4.44089e-16, 1}, {1, 0, 0, 9.71445e-16, 1, -1.11022e-15, 2.498e-16, 2.22045e-16, 1}, {1, -6.66134e-16, -8.88178e-16, -8.32667e-17, 1, -4.44089e-16, 2.77556e-17, -1.11022e-16, 1}, {1, 1.11022e-15, 6.66134e-16, -4.44089e-16, 1, 1.77636e-15, -1.11022e-16, -2.22045e-16, 1}, {1, -4.44089e-16, -8.88178e-16, 4.44089e-16, 1, -1.77636e-15, 1.11022e-16, -3.33067e-16, 1}, {1, 0, 1.11022e-15, 0, 1, -1.33227e-15, 0, -8.88178e-16, 1}, {1, 8.88178e-16, -2.22045e-16, 0, 1, -6.66134e-16, -3.51628e-17, 0, 1}, {1, 1.77636e-15, 2.22045e-16, -5.55112e-17, 1, 0, 0, 0, 1}, {1, -1.77636e-15, 0, 0, 1, 8.88178e-16, 0, 0, 1}, {1, 0, 0, 0, 1, -1.76153e-16, 2.22045e-16, 1.66967e-17, 1}, {1, 0, 0, -8.88178e-16, 1, 1.06372e-16, -1.11022e-15, -1.4138e-16, 1}, {1, 0, 5.55112e-17, -2.22045e-16, 1, -1.05527e-16, -4.44089e-16, 1.74014e-17, 1}, {1, 0, -5.55112e-17, 0, 1, -2.23281e-16, -8.88178e-16, 1.23057e-17, 1}, {1, -2.22045e-15, 0, -6.66134e-16, 1, -6.66134e-16, 4.44089e-16, -4.44089e-16, 1}, {1, 4.44089e-16, 0, 4.44089e-16, 1, 0, 1.77636e-15, 1.77636e-15, 1}, {1, -2.22045e-15, -8.88178e-16, 0, 1, 2.22045e-16, 0, -3.55271e-15, 1}, {1, 0, 0, 0, 1, 0, 0, -8.88178e-16, 1}, {1, 0, 0, -2.22045e-15, 1, -2.22045e-15, 4.44089e-16, 1.33227e-15, 1}, {1, 0, 0, 2.22045e-16, 1, 8.88178e-16, -2.22045e-16, 4.44089e-16, 1}, {1, 0, 0, 2.22045e-16, 1, 0, -8.88178e-16, -1.77636e-15, 1}, {1, 0, 0, -8.88178e-16, 1, 0, 2.22045e-16, 4.44089e-16, 1}, {1, -1.9984e-15, 0, -8.88178e-16, 1, -8.88178e-16, -4.88498e-15, -8.88178e-16, 1}, {1, -6.66134e-16, -1.11022e-15, -1.77636e-15, 1, 0, -8.88178e-16, -5.77316e-15, 1}, {1, 2.22045e-15, -2.22045e-16, 0, 1, 0, 0, -5.32907e-15, 1}, {1, -1.77636e-15, -8.88178e-16, 0, 1, 0, -3.10862e-15, -8.88178e-16, 1}, {1, -2.16493e-15, -1.94289e-15, 6.38378e-16, 1, 2.77556e-16, -4.44089e-16, -2.22045e-16, 1}, {1, -6.66134e-16, 2.77556e-16, -4.85723e-16, 1, 5.13478e-16, 2.22045e-16, 4.44089e-16, 1}, {1, -1.77636e-15, -8.88178e-16, 5.55112e-16, 1, 0, -2.77556e-16, 3.88578e-16, 1}, {1, 8.88178e-16, -2.22045e-16, -5.55112e-17, 1, -1.73472e-16, -8.88178e-16, -4.44089e-16, 1}, {1, 1.33227e-15, 8.88178e-16, 3.64726e-16, 1, -1.05764e-15, 1.77636e-15, 0, 1}, {1, 8.88178e-16, 2.22045e-16, 1.76248e-15, 1, 6.0531e-16, 4.44089e-16, 8.88178e-16, 1}, {1, -4.44089e-16, 1.11022e-15, -6.69603e-16, 1, 1.06078e-15, 0, 0, 1}, {1, 0, 8.88178e-16, 2.41343e-16, 1, -3.28839e-16, 0, -8.88178e-16, 1}, {1, 6.66134e-16, -1.11022e-16, 1.11022e-16, 1, 1.11022e-16, -1.11022e-16, 4.44089e-16, 1}, {1, 1.11022e-15, -1.11022e-16, 1.11022e-16, 1, -5.55112e-16, 3.33067e-16, 4.44089e-16, 1}, {1, 4.44089e-16, 0, 0, 1, 2.22045e-16, 1.11022e-16, -8.88178e-16, 1}, {1, 2.22045e-16, 0, -4.996e-16, 1, -1.11022e-16, 4.44089e-16, 0, 1}, {1, -4.44089e-16, 0, -3.88578e-16, 1, -1.77636e-15, -1.60982e-15, -2.22045e-16, 1}, {1, -2.66454e-15, -2.66454e-15, 5.55112e-16, 1, 4.44089e-16, -6.10623e-16, -4.44089e-15, 1}, {1, -1.77636e-15, -1.77636e-15, 5.55112e-17, 1, 0, 4.44089e-16, -5.32907e-15, 1}, {1, -1.77636e-15, 0, 0, 1, 1.77636e-15, -6.66134e-16, 1.77636e-15, 1}, {1, 3.20924e-17, -4.44089e-16, 0, 1, 0, 1.77636e-15, 1.11022e-15, 1}, {1, -3.30031e-16, -1.77636e-15, -4.44089e-16, 1, -4.44089e-16, 0, 1.11022e-15, 1}, {1, 2.66454e-15, 0, 0, 1, 0, -1.77636e-15, 0, 1}, {1, 0, 1.77636e-15, 0, 1, 0, 0, -8.88178e-16, 1}, {1, 2.22045e-16, 1.11022e-15, -2.22045e-16, 1, -4.44089e-16, -1.33227e-15, 5.55112e-16, 1}, {1, 4.44089e-16, 7.77156e-16, 2.10942e-15, 1, 8.88178e-16, 0, 0, 1}, {1, 4.44089e-16, 8.88178e-16, 4.44089e-16, 1, 0, -8.88178e-16, 6.66134e-16, 1}, {1, -8.88178e-16, 3.60822e-16, 0, 1, 4.44089e-16, 0, 0, 1}, {1, -1.11022e-15, -7.77156e-16, 9.99201e-16, 1, -1.11022e-16, -5.55112e-16, 1.11022e-16, 1}, {1, 1.11022e-16, -1.11022e-16, 1.11022e-15, 1, 7.77156e-16, -7.77156e-16, 5.55112e-16, 1}, {1, 6.66134e-16, 4.44089e-16, 0, 1, 0, 4.44089e-16, -4.44089e-16, 1}, {1, -8.88178e-16, 4.44089e-16, 6.66134e-16, 1, 2.22045e-16, 0, 0, 1}, {1, -5.55112e-17, 4.44089e-16, -1.11022e-16, 1, 1.11022e-16, -1.11022e-16, 0, 1}, {1, 0, 4.44089e-16, 4.44089e-16, 1, -3.33067e-16, -2.22045e-16, 0, 1}, {1, 0, 8.88178e-16, -2.22045e-15, 1, -8.88178e-16, 8.88178e-16, 0, 1}, {1, 2.22045e-16, -8.88178e-16, 0, 1, -2.22045e-16, -8.88178e-16, -2.22045e-16, 1}, {1, -4.996e-16, 4.44089e-16, -1.22125e-15, 1, -1.11022e-15, 4.44089e-16, -5.55112e-16, 1}, {1, 5.55112e-16, -1.33227e-15, 3.33067e-16, 1, 1.05471e-15, 4.44089e-16, -7.77156e-16, 1}, {1, 4.44089e-16, 1.11022e-15, 0, 1, 8.88178e-16, -8.88178e-16, 0, 1}, {1, 0, 8.88178e-16, 1.11022e-15, 1, 1.11022e-16, -8.88178e-16, 3.33067e-16, 1}, {1, -8.88178e-16, -5.55112e-17, 2.22045e-16, 1, 0, 0, -6.66134e-16, 1}, {1, 8.88178e-16, 0, -2.77556e-16, 1, 0, -1.94289e-16, -1.11022e-15, 1}, {1, 0, -2.22045e-16, -2.22045e-16, 1, 2.22045e-16, 0, 4.44089e-16, 1}, {1, 0, 0, -2.22045e-16, 1, 0, 2.22045e-16, 8.88178e-16, 1}, {1, 0, -4.44089e-16, -3.33067e-16, 1, -4.44089e-16, -3.33067e-16, -2.22045e-15, 1}, {1, -1.77636e-15, 0, 2.77556e-16, 1, 8.88178e-16, -4.44089e-16, 8.88178e-16, 1}, {1, 0, -4.44089e-16, 1.11022e-16, 1, 1.77636e-15, 8.88178e-16, 0, 1}, {1, -1.77636e-15, 0, -4.44089e-16, 1, -3.55271e-15, 0, 0, 1}, {1, 7.77156e-16, -1.94289e-16, -4.44089e-16, 1, -3.33067e-16, -4.44089e-16, 1.33227e-15, 1}, {1, -3.05311e-16, -8.32667e-17, 1.22125e-15, 1, 4.996e-16, 4.44089e-16, 5.55112e-16, 1}, {1, -1.11022e-16, 3.33067e-16, 4.12864e-16, 1, 2.72352e-16, 0, -4.44089e-16, 1}, {1, 2.22045e-16, 4.44089e-16, 8.88178e-16, 1, 4.44089e-16, 1.33227e-15, 6.66134e-16, 1}, {1, 9.99201e-16, 1.38778e-16, -1.66533e-16, 1, -5.55112e-16, -1.33227e-15, -3.33067e-15, 1}, {1, 9.99201e-16, 5.55112e-17, -1.05471e-15, 1, 0, 3.33067e-16, 2.66454e-15, 1}, {1, -1.11022e-16, 5.55112e-17, 0, 1, -1.11022e-16, -2.22045e-16, -8.88178e-16, 1}, {1, -4.44089e-16, 1.11022e-16, 2.22045e-16, 1, 0, -4.44089e-16, 8.88178e-16, 1}, {1, 0, 2.77556e-16, 6.66134e-16, 1, -2.35922e-16, 3.33067e-16, 0, 1}, {1, 0, 2.22045e-16, -1.38778e-17, 1, -4.51028e-16, -1.249e-16, 0, 1}, {1, 0, 2.22045e-16, -2.22045e-16, 1, -2.22045e-16, -1.11022e-15, 2.77556e-17, 1}, {1, 2.77556e-17, 0, 1.55431e-15, 1, 0, -4.44089e-16, 2.77556e-17, 1}, {1, -6.66134e-16, 0, 2.22045e-16, 1, 0, 1.11022e-16, 1.33227e-15, 1}, {1, 2.22045e-15, 0, -1.11022e-16, 1, 3.46945e-17, 1.11022e-16, -2.22045e-16, 1}, {1, 1.77636e-15, -1.66533e-16, 6.66134e-16, 1, -1.45717e-16, -2.22045e-16, -4.44089e-16, 1}, {1, -2.22045e-16, 0, 0, 1, -1.38778e-17, 0, 0, 1}, {1, 5.55112e-16, 1.11022e-16, -2.91434e-16, 1, -3.33067e-16, 1.66533e-16, 1.33227e-15, 1}, {1, 4.44089e-16, 5.55112e-17, 2.35922e-16, 1, 5.55112e-17, 2.22045e-16, 0, 1}, {1, 0, -4.44089e-16, -3.33067e-16, 1, 1.11022e-16, 2.22045e-16, 8.88178e-16, 1}, {1, 6.66134e-16, 0, 0, 1, -4.44089e-16, 4.44089e-16, 0, 1}, {1, 3.88578e-16, -8.88178e-16, -4.996e-16, 1, -1.22125e-15, 2.22045e-16, -1.11022e-16, 1}, {1, -2.22045e-16, 0, 5.55112e-17, 1, -6.66134e-16, -1.11022e-16, -2.77556e-17, 1}, {1, -2.22045e-16, -8.88178e-16, -8.88178e-16, 1, -2.44249e-15, 0, 2.22045e-16, 1}, {1, 0, -1.77636e-15, 4.44089e-16, 1, 8.88178e-16, 3.88578e-16, 1.94289e-16, 1}, {1, 3.33067e-16, -8.88178e-16, 0, 1, 2.22045e-16, 5.55112e-17, -3.33067e-16, 1}, {1, 3.33067e-16, -2.22045e-15, 1.11022e-16, 1, 1.33227e-15, -2.22045e-16, -7.77156e-16, 1}, {1, 4.44089e-16, 0, -2.77556e-17, 1, -3.33067e-16, 0, 0, 1}, {1, 0, 1.33227e-15, 1.38778e-17, 1, 3.55271e-15, -5.55112e-17, -2.22045e-16, 1}, {1, -5.55112e-16, -9.15934e-16, -5.55112e-17, 1, -8.88178e-16, 0, -3.33067e-16, 1}, {1, 8.60423e-16, 6.66134e-16, 0, 1, -4.44089e-16, -1.66533e-16, 3.33067e-16, 1}, {1, 2.22045e-16, 0, -4.44089e-16, 1, -2.66454e-15, 5.55112e-17, 0, 1}, {1, 0, 6.66134e-16, 1.11022e-16, 1, 4.44089e-16, 0, 4.44089e-16, 1}, {1, 0, 0, 1.11022e-16, 1, 1.11022e-15, 8.88178e-16, 0, 1}, {1, -1.89111e-16, -8.88178e-16, -4.16334e-17, 1, 2.22045e-16, 6.38378e-16, -1.11022e-16, 1}, {1, 2.29571e-16, 8.88178e-16, -6.93889e-17, 1, 0, 2.22045e-16, -2.22045e-16, 1}, {1, 0, 0, -1.11022e-16, 1, 0, 1.11022e-16, 1.11022e-16, 1}, {1, 0, 2.498e-16, 2.77556e-17, 1, -4.44089e-16, -2.22045e-16, -2.77556e-17, 1}, {1, 0, 2.66454e-15, -2.77556e-17, 1, -4.44089e-16, -3.88578e-16, -1.11022e-16, 1}, {1, 0, 0, -1.66533e-16, 1, -1.33227e-15, -2.22045e-16, 2.77556e-17, 1}, {1, 0, 0, 0, 1, -8.88178e-16, -3.33067e-16, 2.77556e-17, 1}, {1, -1.77636e-15, -5.55112e-17, -2.22045e-16, 1, 1.38778e-17, 2.77556e-16, -6.66134e-16, 1}, {1, -8.88178e-16, -2.22045e-16, 8.32667e-16, 1, -1.249e-16, -1.66533e-16, 7.77156e-16, 1}, {1, 4.44089e-16, 0, 0, 1, 1.11022e-16, -1.77636e-15, -8.88178e-16, 1}, {1, -8.88178e-16, -2.22045e-16, 0, 1, -2.22045e-16, 0, 1.77636e-15, 1}, {1, -6.66134e-16, -1.38778e-16, 5.55112e-16, 1, -2.77556e-17, 1.88738e-15, 1.9984e-15, 1}, {1, 6.66134e-16, -2.77556e-17, 3.33067e-16, 1, 1.80411e-16, -1.9984e-15, -6.66134e-16, 1}, {1, 3.55271e-15, 0, -8.88178e-16, 1, -5.55112e-17, 4.44089e-16, 8.88178e-16, 1}, {1, 2.22045e-16, 3.33067e-16, -5.55112e-17, 1, -4.23273e-16, 0, -1.77636e-15, 1}, {1, 2.22045e-16, -1.11022e-16, 9.99201e-16, 1, 4.71845e-16, -5.55112e-16, -8.32667e-17, 1}, {1, 0, 2.77556e-16, 9.99201e-16, 1, -1.38778e-16, -5.55112e-17, 0, 1}, {1, -2.22045e-16, 0, -8.88178e-16, 1, -2.22045e-16, 0, 1.11022e-16, 1}, {1, 2.22045e-16, 0, 1.77636e-15, 1, 4.44089e-16, 0, 2.22045e-16, 1}, {1, 0, 0, 4.16334e-17, 1, -1.11022e-15, 0, 0, 1}, {1, -5.55112e-17, -1.33227e-15, 0, 1, -2.22045e-16, 0, -5.55112e-17, 1}, {1, -2.77556e-17, -4.44089e-16, 1.11022e-16, 1, -1.77636e-15, 0, 0, 1}, {1, 1.38778e-16, -1.77636e-15, 2.77556e-17, 1, 8.88178e-16, 0, -8.32667e-17, 1}, {1, 0, 0, 8.88178e-16, 1, 2.77556e-17, 1.33227e-15, -4.44089e-16, 1}, {1, 4.44089e-16, 0, 2.88658e-15, 1, 2.77556e-17, 8.88178e-16, -8.88178e-16, 1}, {1, 0, 0, -1.55431e-15, 1, -2.77556e-17, -1.77636e-15, 3.55271e-15, 1}, {1, 0, 0, -8.88178e-16, 1, 1.11022e-16, -8.88178e-16, -8.88178e-16, 1}, {1, -2.60584e-18, -5.31208e-16, 2.18319e-16, 1, 6.66134e-16, 0, 0, 1}, {1, 8.92406e-18, 1.72411e-16, -1.37759e-17, 1, -6.66134e-16, -2.77556e-17, 0, 1}, {1, -1.22116e-17, 6.19045e-16, 3.29106e-16, 1, -1.11022e-15, 0, 0, 1}, {1, -3.50572e-17, 1.09807e-15, 1.47434e-16, 1, 1.77636e-15, 8.32667e-17, 0, 1}, {1, 6.17562e-16, 0, -2.22045e-16, 1, 2.22045e-16, 1.11022e-16, -4.44089e-16, 1}, {1, 2.84495e-16, 1.52656e-16, 2.22045e-16, 1, 6.66134e-16, 1.11022e-16, 1.11022e-16, 1}, {1, 2.22045e-16, 4.44089e-16, 0, 1, 4.44089e-16, 2.22045e-16, 0, 1}, {1, 2.22045e-16, -8.88178e-16, -2.22045e-16, 1, -8.88178e-16, 0, -4.44089e-16, 1}, {1, 0, 0, -6.66134e-16, 1, 5.55112e-17, 0, 4.44089e-16, 1}, {1, 0, 0, 4.44089e-16, 1, 0, -2.66454e-15, -1.33227e-15, 1}, {1, 0, 0, 1.33227e-15, 1, 0, -8.88178e-16, -1.77636e-15, 1}, {1, 0, 0, 0, 1, 0, -4.44089e-16, -2.22045e-15, 1}, {1, -2.77556e-16, 0, -3.60822e-16, 1, 2.08167e-16, 0, -2.77556e-17, 1}, {1, 6.66134e-16, -5.55112e-17, -3.05311e-16, 1, -2.08167e-16, 5.55112e-16, 2.77556e-17, 1}, {1, -5.55112e-16, 0, -8.88178e-16, 1, 2.22045e-16, 1.11022e-16, -1.66533e-16, 1}, {1, -2.22045e-16, 0, -7.77156e-16, 1, -1.11022e-16, 0, 0, 1}, {1, 1.11022e-16, -4.44089e-16, 0, 1, 0, 4.996e-16, 0, 1}, {1, -5.55112e-17, -3.33067e-16, -1.66533e-16, 1, -1.66533e-16, 3.33067e-16, 4.44089e-16, 1}, {1, -4.44089e-16, -8.88178e-16, -1.66533e-16, 1, -1.38778e-16, 1.11022e-16, 3.05311e-16, 1}, {1, 1.00614e-16, -7.63278e-17, 0, 1, -2.22045e-16, 8.88178e-16, 0, 1}, {1, 0, 4.44089e-16, 8.88178e-16, 1, 1.11022e-16, -8.88178e-16, -8.88178e-16, 1}, {1, -1.77636e-15, -2.22045e-16, 8.88178e-16, 1, -3.33067e-16, 8.88178e-16, 8.88178e-16, 1}, {1, 1.77636e-15, -1.11022e-16, 3.55271e-15, 1, 0, 0, 0, 1}, {1, 0, 0, -2.22045e-15, 1, 3.33067e-16, 0, 0, 1}, {1, -2.22045e-16, -2.0911e-15, 0, 1, -1.33227e-15, 2.78979e-17, -1.88068e-16, 1}, {1, -3.33067e-16, -2.44065e-15, -5.55112e-17, 1, 8.88178e-16, 4.7915e-17, 2.22045e-16, 1}, {1, 5.55112e-17, 2.66454e-15, 1.11022e-16, 1, 1.77636e-15, -1.11022e-16, -2.1535e-17, 1}, {1, 2.22045e-16, 8.88178e-16, 0, 1, -1.77636e-15, 1.11022e-16, -5.55112e-17, 1}, {1, -2.22045e-16, -6.10623e-16, -4.44089e-16, 1, -1.11022e-15, -1.77636e-15, -1.33227e-15, 1}, {1, 8.32667e-17, -1.94289e-16, 8.88178e-16, 1, -2.22045e-16, 1.77636e-15, -4.44089e-16, 1}, {1, 4.44089e-16, 1.33227e-15, -1.11022e-15, 1, -1.22125e-15, -1.77636e-15, -1.77636e-15, 1}, {1, -7.21645e-16, -1.66533e-16, 8.88178e-16, 1, 0, -4.44089e-16, -1.33227e-15, 1}, {1, -1.77636e-15, -3.55271e-15, -8.88178e-16, 1, -1.11022e-15, 6.66134e-16, 1.11022e-15, 1}, {1, -1.77636e-15, -8.88178e-16, 4.44089e-16, 1, 2.22045e-16, 0, 4.44089e-16, 1}, {1, 5.32907e-15, 1.77636e-15, -6.66134e-16, 1, 0, 8.88178e-16, -1.11022e-15, 1}, {1, 0, -8.88178e-16, 0, 1, 0, 8.88178e-16, -8.88178e-16, 1}, {1, 6.66134e-16, 4.44089e-16, -1.38778e-16, 1, 2.22045e-16, 8.32667e-17, 4.44089e-16, 1}, {1, -1.33227e-15, -4.44089e-16, 4.16334e-16, 1, 1.44329e-15, -2.77556e-16, 0, 1}, {1, 8.88178e-16, 0, -3.33067e-16, 1, -2.22045e-16, 2.22045e-16, 8.88178e-16, 1}, {1, 1.55431e-15, 6.66134e-16, 0, 1, 4.44089e-16, -4.44089e-16, -1.77636e-15, 1}, {1, 2.22045e-16, 8.88178e-16, 4.996e-16, 1, 9.15934e-16, 1.33227e-15, 8.88178e-16, 1}, {1, 2.22045e-16, 1.77636e-15, -5.55112e-16, 1, -5.27356e-16, -2.22045e-15, 2.22045e-16, 1}, {1, 0, 1.33227e-15, 1.55431e-15, 1, -2.22045e-16, 3.55271e-15, 1.77636e-15, 1}, {1, 8.88178e-16, 0, -1.11022e-16, 1, 1.94289e-16, -5.55112e-16, 5.55112e-16, 1}, {1, 2.10942e-15, 4.996e-16, 4.44089e-16, 1, -8.88178e-16, 0, 1.77636e-15, 1}, {1, -1.22125e-15, 3.88578e-16, -1.33227e-15, 1, -2.22045e-15, 2.66454e-15, 0, 1}, {1, 6.66134e-16, 1.11022e-16, 0, 1, 0, 2.66454e-15, -8.88178e-16, 1}, {1, -8.88178e-16, 0, 8.88178e-16, 1, -8.88178e-16, 0, -1.77636e-15, 1}, {1, -3.33067e-16, -5.55112e-17, -1.11022e-15, 1, 1.11022e-16, 1.11022e-15, 1.11022e-16, 1}, {1, -5.55112e-16, -1.11022e-16, -6.66134e-16, 1, -5.55112e-17, -4.44089e-16, 0, 1}, {1, 2.22045e-16, -1.11022e-16, 0, 1, 0, -8.88178e-16, -5.55112e-16, 1}, {1, 2.22045e-16, -2.22045e-16, 8.88178e-16, 1, 3.33067e-16, 0, 0, 1}, {1, 1.9984e-15, -1.66533e-16, -4.996e-16, 1, -2.77556e-17, 4.996e-16, 2.22045e-16, 1}, {1, 4.44089e-16, -2.77556e-16, 2.77556e-16, 1, 1.8735e-16, 3.88578e-16, -2.77556e-17, 1}, {1, 4.44089e-16, 0, 8.88178e-16, 1, 0, 9.99201e-16, -9.71445e-17, 1}, {1, 0, 0, 4.44089e-16, 1, 5.55112e-17, 0, 4.44089e-16, 1}, {1, 1.66533e-16, 2.22045e-16, -1.11022e-16, 1, -4.44089e-16, 0, -1.11022e-16, 1}, {1, 0, -8.88178e-16, 2.22045e-16, 1, 5.55112e-16, 0, 2.22045e-16, 1}, {1, -2.22045e-16, 8.88178e-16, 4.44089e-16, 1, 0, -1.77636e-15, 2.22045e-16, 1}, {1, -4.44089e-16, -4.44089e-16, 0, 1, -4.44089e-16, 0, 4.44089e-16, 1}, {1, 5.55112e-16, -4.44089e-16, 0, 1, 0, 0, -5.55112e-17, 1}, {1, 3.33067e-16, 5.55112e-17, 0, 1, -2.77556e-17, 0, 2.22045e-16, 1}, {1, 4.44089e-16, -1.66533e-16, 0, 1, 2.77556e-17, 0, -5.55112e-17, 1}, {1, 2.22045e-16, 5.55112e-17, 0, 1, 0, 1.11022e-16, -2.22045e-16, 1}, {1, -2.22045e-16, -5.55112e-17, 1.11022e-15, 1, 4.44089e-16, -1.33227e-15, 1.55431e-15, 1}, {1, 3.46945e-16, 1.38778e-15, 4.44089e-16, 1, 1.11022e-16, 2.22045e-16, 0, 1}, {1, 2.22045e-16, -1.33227e-15, 0, 1, -5.55112e-17, 8.88178e-16, 8.88178e-16, 1}, {1, 0, 0, -8.88178e-16, 1, 0, 0, 5.55112e-16, 1}, {1, 4.44089e-16, -4.16334e-16, -8.88178e-16, 1, -6.66134e-16, 2.22045e-16, -1.11022e-16, 1}, {1, -1.11022e-16, 1.66533e-16, -2.22045e-15, 1, -5.55112e-16, -5.55112e-17, -4.44089e-16, 1}, {1, 0, -2.22045e-16, 8.88178e-16, 1, -2.22045e-16, 4.44089e-16, 4.44089e-16, 1}, {1, -4.44089e-16, 4.996e-16, 0, 1, 2.22045e-16, -4.44089e-16, -6.66134e-16, 1}, {1, 8.10882e-16, 3.21126e-16, -1.74633e-15, 1, -6.18672e-17, -3.10862e-15, -3.10862e-15, 1}, {1, 1.31799e-15, 2.85541e-17, 1.55283e-15, 1, 1.69489e-16, 4.44089e-16, 0, 1}, {1, 1.77636e-15, -1.11022e-16, -8.88178e-16, 1, 2.22045e-16, -1.77636e-15, 0, 1}, {1, 2.66454e-15, -1.11022e-16, -6.21725e-15, 1, 0, -1.77636e-15, 0, 1}, {1, -1.11022e-16, -2.22045e-16, 4.44089e-16, 1, 8.88178e-16, 3.33067e-16, 1.11022e-16, 1}, {1, -7.77156e-16, 1.11022e-16, 2.44249e-15, 1, 5.55112e-16, -5.55112e-16, 2.77556e-16, 1}, {1, 0, 1.66533e-16, -2.66454e-15, 1, 2.77556e-16, 4.44089e-16, -1.11022e-16, 1}, {1, -4.44089e-16, -3.88578e-16, 4.44089e-16, 1, 2.77556e-16, -8.88178e-16, -2.22045e-16, 1}, {1, 1.55431e-15, 1.11022e-16, 8.88178e-16, 1, 5.55112e-16, 3.10862e-15, -1.9984e-15, 1}, {1, 2.66454e-15, 0, -4.88498e-15, 1, -8.88178e-16, -1.77636e-15, 6.66134e-16, 1}, {1, 8.88178e-16, 8.88178e-16, -2.66454e-15, 1, -4.44089e-16, 8.88178e-16, 1.77636e-15, 1}, {1, -1.33227e-15, -5.55112e-17, -3.55271e-15, 1, -8.88178e-16, 1.77636e-15, 0, 1}, {1, 6.66134e-16, 1.11022e-16, 0, 1, -5.55112e-17, -1.11022e-15, -4.71845e-16, 1}, {1, -2.22045e-16, 2.22045e-16, -4.44089e-16, 1, 1.11022e-16, 8.88178e-16, 5.27356e-16, 1}, {1, -8.88178e-16, -2.77556e-16, 0, 1, 2.22045e-16, 0, 0, 1}, {1, 0, 0, 0, 1, 2.22045e-16, 8.88178e-16, 8.88178e-16, 1}, {1, 0, -8.88178e-16, 0, 1, 8.88178e-16, 0, 0, 1}, {1, -1.33227e-15, -1.77636e-15, -4.44089e-16, 1, 6.66134e-16, 0, 0, 1}, {1, 0, 0, 0, 1, 2.22045e-16, 0, 0, 1}, {1, 0, -8.88178e-16, 0, 1, 0, 0, 0, 1}, {1, 8.88178e-16, 0, 0, 1, 0, 0, 0, 1}, {1, 6.66134e-16, 0, 0, 1, 0, 0, -2.22045e-16, 1}, {1, -1.77636e-15, 0, 0, 1, 0, 0, -2.22045e-16, 1}, {1, -2.22045e-16, 0, 0, 1, 0, -2.22045e-16, -1.77636e-15, 1}, {1, -8.32667e-17, 3.60822e-16, 1.66533e-16, 1, -1.59595e-16, 0, 0, 1}, {1, 2.22045e-16, -9.4369e-16, -2.63678e-16, 1, -4.23273e-16, -1.11022e-16, 3.33067e-16, 1}, {1, 4.44089e-16, 4.44089e-16, -7.77156e-16, 1, 2.22045e-16, -2.22045e-16, -1.66533e-16, 1}, {1, 1.11022e-16, 0, 5.55112e-16, 1, 1.11022e-16, 0, 0, 1}, {1, -9.71445e-17, 1.11022e-16, 5.55112e-17, 1, -1.77636e-15, 2.22045e-16, -1.11022e-16, 1}, {1, 1.11022e-16, -8.88178e-16, 8.88178e-16, 1, -2.22045e-16, -2.77556e-16, 1.38778e-16, 1}, {1, -2.77556e-16, 2.22045e-16, 8.88178e-16, 1, 0, 4.71845e-16, -6.93889e-17, 1}, {1, 5.55112e-17, -2.22045e-16, 3.24393e-16, 1, 8.70831e-16, 2.22045e-16, 2.22045e-16, 1}, {1, 1.11022e-16, 1.249e-16, 1.78979e-16, 1, 5.57165e-16, 0, 0, 1}, {1, 7.21645e-16, 0, 6.79568e-17, 1, 2.24099e-16, 2.22045e-16, 7.77156e-16, 1}, {1, 0, 2.22045e-16, 8.88178e-16, 1, 8.88178e-16, 3.33067e-16, -2.22045e-16, 1}, {1, 1.11022e-16, 3.33067e-16, 0, 1, -2.22045e-16, 0, 0, 1}, {1, 2.44012e-18, -3.62653e-16, 5.55112e-17, 1, 7.77156e-16, 3.33067e-16, 0, 1}, {1, 6.81698e-18, 5.58336e-17, 5.55112e-17, 1, 2.22045e-16, -1.11022e-15, 0, 1}, {1, -6.17603e-17, -1.94511e-16, -2.22045e-16, 1, -1.44329e-15, 0, 0, 1}, {1, 6.81698e-18, 5.58336e-17, 0, 1, 8.88178e-16, -2.22045e-16, 0, 1}, {1, 0, 0, -1.55431e-15, 1, -2.22935e-19, 1.33227e-15, 4.48209e-16, 1}, {1, 0, 0, 2.22045e-16, 1, 3.43579e-18, -8.88178e-16, 1.19262e-18, 1}, {1, -8.32667e-17, 0, -8.88178e-16, 1, -3.22922e-17, -6.66134e-16, 1.14004e-16, 1}, {1, 8.32667e-17, 0, 0, 1, 2.49899e-17, 8.88178e-16, -3.9362e-16, 1}, {1, 4.44089e-16, 1.11022e-16, -1.11022e-16, 1, -1.22125e-15, 0, 4.44089e-16, 1}, {1, 4.44089e-16, 0, 0, 1, 3.33067e-16, 0, 6.66134e-16, 1}, {1, 2.22045e-16, 5.55112e-16, 1.66533e-16, 1, -3.33067e-16, 0, 0, 1}, {1, 2.22045e-16, -4.44089e-16, -8.88178e-16, 1, -4.44089e-16, 3.33067e-16, -2.22045e-16, 1}, {1, 0, 0, 2.22045e-16, 1, 0, -5.61363e-19, -1.33713e-15, 1}, {1, 4.44089e-16, -7.58595e-17, 2.22045e-16, 1, 0, 2.97954e-16, 1.01603e-16, 1}, {1, 8.88178e-16, 0, 8.88178e-16, 1, 5.55112e-17, -2.41724e-16, -1.91886e-15, 1}, {1, 0, 0, 4.44089e-16, 1, -5.55112e-17, -1.71813e-16, -2.31562e-16, 1}, {1, 1.11022e-16, 5.55112e-17, 8.88178e-16, 1, 5.55112e-16, -8.88178e-16, -1.11022e-16, 1}, {1, 1.38778e-16, 1.11022e-16, 2.66454e-15, 1, 0, 4.44089e-16, -1.94289e-16, 1}, {1, -2.77556e-17, 2.22045e-16, -1.77636e-15, 1, 0, 8.88178e-16, -2.77556e-17, 1}, {1, 1.11022e-16, 8.88178e-16, -1.77636e-15, 1, 0, 0, -2.77556e-17, 1}, {1, -5.55112e-17, 5.55112e-16, -1.22125e-15, 1, -3.88578e-16, 3.40006e-16, 2.64545e-17, 1}, {1, 0, -5.55112e-16, -1.66533e-16, 1, 3.33067e-16, 3.322e-16, 1.51788e-17, 1}, {1, 0, -8.88178e-16, -2.77556e-16, 1, 8.32667e-17, -3.92048e-16, -1.56125e-17, 1}, {1, 0, 1.11022e-16, 4.44089e-16, 1, 2.22045e-16, 4.06793e-16, -4.77049e-18, 1}, {1, 4.44089e-16, 1.9984e-15, 3.10862e-15, 1, -6.66134e-16, 2.44249e-15, 1.33227e-15, 1}, {1, 0, 4.44089e-16, 8.88178e-16, 1, 1.11022e-15, -2.22045e-16, 6.66134e-16, 1}, {1, 1.77636e-15, 0, 0, 1, 8.88178e-16, 4.44089e-16, -4.44089e-16, 1}, {1, -8.88178e-16, 4.44089e-16, 8.88178e-16, 1, 1.66533e-15, 0, -8.88178e-16, 1}, {1, 3.33067e-16, 7.21645e-16, 0, 1, 4.16334e-16, 1.33227e-15, 0, 1}, {1, -7.21645e-16, -4.16334e-16, -6.66134e-16, 1, -9.4369e-16, -2.22045e-16, 5.55112e-16, 1}, {1, 0, -2.77556e-16, -1.11022e-16, 1, 4.16334e-17, -1.77636e-15, 0, 1}, {1, -1.11022e-16, 2.498e-16, 8.88178e-16, 1, 1.11022e-16, 1.33227e-15, 4.44089e-16, 1}, {1, 2.66454e-15, 2.22045e-16, 1.11022e-16, 1, -4.44089e-16, 1.80411e-16, -2.63678e-16, 1}, {1, 0, 8.88178e-16, 1.11022e-16, 1, 0, -1.80411e-16, 3.88578e-16, 1}, {1, 6.66134e-16, 2.22045e-16, 4.44089e-16, 1, 8.88178e-16, 2.22045e-16, -4.44089e-16, 1}, {1, 0, 8.88178e-16, 0, 1, 8.88178e-16, 4.44089e-16, -4.996e-16, 1}, {1, 0, -8.88178e-16, 2.22045e-15, 1, 8.88178e-16, 8.88178e-16, 0, 1}, {1, 0, 4.44089e-16, 8.88178e-16, 1, -4.44089e-16, 2.22045e-15, -2.77556e-17, 1}, {1, -2.77556e-17, 1.55431e-15, 0, 1, -1.77636e-15, 0, 0, 1}, {1, 0, 0, -4.44089e-16, 1, -4.44089e-16, 0, 0, 1}, {1, 0, -2.22045e-16, -1.66533e-16, 1, -6.66134e-16, -4.44089e-16, 1.4988e-15, 1}, {1, 0, 0, 3.33067e-16, 1, 0, 0, 3.33067e-15, 1}, {1, -4.44089e-16, 0, 2.22045e-16, 1, 8.88178e-16, 5.55112e-17, 0, 1}, {1, -8.88178e-16, -8.88178e-16, -4.44089e-16, 1, -8.88178e-16, -3.33067e-16, 1.77636e-15, 1}, {1, 8.88178e-16, 4.44089e-16, -2.22045e-16, 1, -4.996e-16, 1.11022e-15, 8.88178e-16, 1}, {1, 1.76324e-15, 1.00228e-15, -1.11022e-16, 1, 8.88178e-16, 1.11022e-16, 6.66134e-16, 1}, {1, 4.44089e-16, 2.22045e-16, -2.22045e-16, 1, -2.22045e-16, 2.22045e-16, -5.55112e-16, 1}, {1, 1.33227e-15, 0, -2.22045e-16, 1, -1.38778e-16, -8.88178e-16, 0, 1}, {1, -6.66134e-16, -6.66134e-16, 4.44089e-16, 1, -3.33067e-16, 0, 6.66134e-16, 1}, {1, -4.44089e-16, -4.44089e-16, -4.44089e-16, 1, 2.22045e-16, 4.44089e-16, 0, 1}, {1, 8.88178e-16, 0, 0, 1, 8.88178e-16, 0, 2.22045e-16, 1}, {1, -9.99201e-16, -2.22045e-16, 1.77636e-15, 1, -4.16334e-16, 0, 0, 1}, {1, -3.53434e-18, -6.808e-17, 7.77156e-16, 1, 5.55112e-16, -5.55112e-16, 0, 1}, {1, 8.42526e-19, 5.35613e-16, -1.11022e-16, 1, 5.55112e-16, 1.11022e-16, 0, 1}, {1, -3.48628e-17, 6.44042e-16, 0, 1, -2.22045e-16, -4.44089e-16, 2.22045e-16, 1}, {1, 1.89815e-17, -2.27088e-16, 4.44089e-16, 1, 0, 7.77156e-16, 0, 1}, {1, -6.66134e-16, -1.11022e-16, 1.17961e-16, 1, -5.81132e-17, 3.33067e-16, 1.11022e-16, 1}, {1, 0, 1.11022e-16, -2.74086e-16, 1, 6.93889e-17, -3.33067e-16, -1.11022e-16, 1}, {1, 2.22045e-16, 2.22045e-16, -4.44089e-16, 1, 0, 0, 0, 1}, {1, -2.22045e-16, 1.11022e-16, -2.22045e-16, 1, -5.55112e-17, -4.44089e-16, -2.22045e-16, 1}, {1, 3.19189e-16, 2.22045e-15, -3.33067e-16, 1, -8.88178e-16, -5.55112e-17, -2.22045e-16, 1}, {1, -3.60822e-16, 3.33067e-15, -2.22045e-16, 1, 0, -1.11022e-16, 1.11022e-16, 1}, {1, 2.22045e-16, 0, -4.44089e-16, 1, -1.77636e-15, 5.55112e-17, 6.66134e-16, 1}, {1, 0, 8.88178e-16, -8.88178e-16, 1, 0, 2.22045e-16, 0, 1}, {1, 0, -1.77636e-15, -8.88178e-16, 1, -3.55271e-15, 4.06359e-16, 3.38813e-17, 1}, {1, 0, 1.33227e-15, 1.9984e-15, 1, 3.9968e-15, -4.78784e-16, -2.11962e-17, 1}, {1, 0, 8.88178e-16, 8.88178e-16, 1, 1.77636e-15, 6.37945e-16, 7.86047e-18, 1}, {1, 0, 0, -1.77636e-15, 1, -1.77636e-15, 1.61329e-16, -4.25007e-17, 1}, {1, -6.10623e-16, -4.44089e-16, -1.04083e-17, 1, 0, 0, -5.55112e-17, 1}, {1, 6.10623e-16, -4.44089e-16, -1.11022e-16, 1, -2.22045e-16, 0, 2.77556e-16, 1}, {1, 4.44089e-16, 1.77636e-15, -1.73472e-17, 1, 0, 0, 2.22045e-16, 1}, {1, 0, 8.88178e-16, -1.04083e-17, 1, 0, 0, -2.35922e-16, 1}, {1, -1.11022e-16, 2.66454e-15, -5.55112e-16, 1, 1.55431e-15, 4.44089e-15, 2.22045e-16, 1}, {1, 1.11022e-16, 2.66454e-15, 1.88738e-15, 1, 0, -2.22045e-16, 2.22045e-16, 1}, {1, 0, 0, -4.44089e-16, 1, 0, 0, 0, 1}, {1, -6.66134e-16, 0, 0, 1, 0, -1.77636e-15, -4.44089e-16, 1}, {1, -2.66454e-15, 0, 2.22045e-16, 1, 0, -6.245e-17, 1.80411e-16, 1}, {1, -1.11022e-16, -1.11022e-16, -2.22045e-16, 1, 2.22045e-16, 1.3739e-15, 1.70003e-15, 1}, {1, 4.44089e-16, 0, 8.88178e-16, 1, 0, -8.88178e-16, -5.55112e-16, 1}, {1, 8.88178e-16, 0, 1.11022e-16, 1, 0, -5.55112e-16, -5.55112e-16, 1}, {1, -7.21645e-16, -4.44089e-16, 0, 1, -6.66134e-16, -5.55112e-17, -5.55112e-16, 1}, {1, 3.33067e-16, -5.55112e-16, 0, 1, 0, 0, -1.22125e-15, 1}, {1, 0, 8.88178e-16, 0, 1, -2.22045e-16, 5.55112e-17, -3.88578e-16, 1}, {1, 4.94396e-16, 1.17961e-16, 0, 1, 0, 0, -4.44089e-16, 1}, {1, -4.44089e-16, 5.55112e-17, 0, 1, 1.11022e-16, -2.77556e-17, -1.33227e-15, 1}, {1, -4.44089e-16, 0, 0, 1, 5.55112e-17, 2.77556e-17, -8.88178e-16, 1}, {1, 0, 4.44089e-16, 1.11022e-16, 1, -4.44089e-16, 0, 0, 1}, {1, 1.77636e-15, 4.44089e-16, 2.77556e-17, 1, -1.66533e-16, 0, 4.44089e-16, 1}, {1, 3.33067e-16, 4.44089e-16, -4.33681e-16, 1, -9.71445e-16, -6.38378e-16, -3.33067e-16, 1}, {1, 2.77556e-16, 2.22045e-16, -4.12864e-16, 1, -7.77156e-16, 4.85723e-16, 1.55431e-15, 1}, {1, -6.66134e-16, 0, -5.27356e-16, 1, -3.33067e-16, 0, -4.44089e-16, 1}, {1, 4.44089e-16, -8.88178e-16, -1.94289e-16, 1, -7.77156e-16, 1.38778e-16, 2.22045e-16, 1}, {1, 1.33227e-15, 1.33227e-15, -3.33067e-16, 1, -4.44089e-16, -2.22045e-16, -6.66134e-16, 1}, {1, 1.55431e-15, 0, 2.22045e-16, 1, -1.11022e-16, 7.77156e-16, 1.9984e-15, 1}, {1, -8.88178e-16, 8.88178e-16, 1.11022e-16, 1, -5.55112e-16, 0, 2.66454e-15, 1}, {1, -1.77636e-15, -8.88178e-16, 0, 1, 0, 5.55112e-16, 6.66134e-16, 1}, {1, 9.15934e-16, -1.11022e-15, -1.11022e-15, 1, -6.66134e-16, 1.66533e-16, -1.11022e-16, 1}, {1, -7.21645e-16, -2.22045e-16, 5.55112e-16, 1, 0, 6.66134e-16, 1.66533e-16, 1}, {1, 8.88178e-16, 0, 3.33067e-16, 1, 0, 7.77156e-16, 4.44089e-16, 1}, {1, -4.44089e-16, -8.88178e-16, 4.44089e-16, 1, 0, 2.22045e-16, 0, 1}, {1, 1.61693e-17, 1.77636e-15, -1.64002e-15, 1, -1.11022e-16, 0, 5.55112e-17, 1}, {1, 1.62402e-16, -1.77636e-15, -4.69564e-15, 1, -1.33227e-15, 0, -1.66533e-16, 1}, {1, -2.22045e-16, -2.66454e-15, -8.88178e-16, 1, 1.77636e-15, 0, -6.66134e-16, 1}, {1, 0, -8.88178e-16, 0, 1, -8.88178e-16, -2.22045e-16, -1.66533e-16, 1}, {1, -8.88178e-16, 0, 0, 1, 0, 4.44089e-16, 6.66134e-16, 1}, {1, 1.11022e-15, 0, -8.88178e-16, 1, 0, 1.33227e-15, 8.88178e-16, 1}, {1, 8.88178e-16, 0, 1.77636e-15, 1, 0, 1.77636e-15, 0, 1}, {1, 8.88178e-16, 0, 4.44089e-16, 1, 0, 0, -8.88178e-16, 1}, {1, 2.77556e-16, 8.32667e-17, 5.55112e-17, 1, -1.11022e-16, 0, 6.66134e-16, 1}, {1, 2.22045e-16, 4.71845e-16, 0, 1, -4.44089e-16, 0, -9.99201e-16, 1}, {1, 3.60822e-16, 1.66533e-16, -2.22045e-16, 1, -6.66134e-16, 0, -8.88178e-16, 1}, {1, 0, 0, 0, 1, 3.33067e-16, 0, 6.66134e-16, 1}, {1, 3.33067e-16, -8.32667e-17, -1.11022e-16, 1, 5.55112e-16, 1.94289e-16, 1.11022e-16, 1}, {1, 1.11022e-16, -5.55112e-17, 1.11022e-16, 1, 2.22045e-16, -3.05311e-16, 1.77636e-15, 1}, {1, -2.63678e-16, -6.93889e-18, 4.44089e-16, 1, -4.44089e-16, -3.81639e-16, -7.35523e-16, 1}, {1, 4.44089e-16, 0, 0, 1, 4.44089e-16, 2.22045e-16, 8.88178e-16, 1}, {1, 4.44089e-16, 2.77556e-17, 4.44089e-16, 1, 0, -3.33067e-16, 6.66134e-16, 1}, {1, -2.22045e-16, 2.77556e-17, 2.77556e-17, 1, 0, -3.33067e-16, -1.9984e-15, 1}, {1, 4.44089e-16, -1.11022e-16, -1.11022e-16, 1, 0, 0, 8.88178e-16, 1}, {1, -2.22045e-16, 0, 8.32667e-17, 1, 0, -4.44089e-16, 0, 1}, {1, 0, 0, -2.22045e-16, 1, -2.77556e-16, -1.11022e-16, 7.21645e-16, 1}, {1, 1.08907e-15, 2.19655e-16, -1.11022e-15, 1, 5.55112e-17, -6.66134e-16, 0, 1}, {1, 0, 0, 8.88178e-16, 1, 0, 6.66134e-16, -2.22045e-16, 1}, {1, 0, 0, 0, 1, -1.11022e-16, -4.44089e-16, 0, 1}, {1, -5.55112e-16, -2.22045e-16, -2.22045e-16, 1, 9.74568e-17, -8.88178e-16, -7.21645e-16, 1}, {1, 2.22045e-16, -1.11022e-16, 0, 1, 6.83595e-17, -3.88578e-16, 8.32667e-17, 1}, {1, -1.77636e-15, 5.55112e-17, 6.66134e-16, 1, 1.20782e-17, -4.44089e-16, -1.22125e-15, 1}, {1, 4.44089e-16, 4.44089e-16, 0, 1, -3.53222e-17, 0, 0, 1}, {1, 0, 2.22045e-16, 6.66134e-16, 1, 5.55112e-16, 5.55112e-17, -1.38778e-17, 1}, {1, 0, 1.11022e-15, -2.22045e-16, 1, -8.88178e-16, 1.66533e-16, -4.16334e-17, 1}, {1, 2.22045e-16, -8.88178e-16, -2.22045e-16, 1, -2.22045e-16, -8.88178e-16, -1.11022e-16, 1}, {1, -5.55112e-17, 4.44089e-16, 0, 1, 4.44089e-16, 1.4988e-15, 0, 1}, {1, 2.35922e-16, -1.59595e-16, -1.11022e-16, 1, 3.88578e-16, 0, 8.88178e-16, 1}, {1, 2.42861e-17, 7.63278e-17, -1.11022e-15, 1, -1.11022e-16, -3.33067e-16, 5.55112e-17, 1}, {1, 4.16334e-17, -1.45717e-16, 2.22045e-16, 1, 3.33067e-16, -4.44089e-16, 2.22045e-16, 1}, {1, -5.55112e-17, -5.55112e-17, 0, 1, 2.22045e-16, 1.11022e-16, -8.32667e-17, 1}, {1, -2.22045e-16, -1.77636e-15, 0, 1, -2.22045e-16, -1.11022e-16, -5.55112e-17, 1}, {1, 4.996e-16, 1.33227e-15, -1.11022e-16, 1, 2.22045e-16, 1.11022e-16, 1.11022e-16, 1}, {1, 7.21645e-16, 1.55431e-15, -5.55112e-17, 1, 8.88178e-16, 4.44089e-16, 0, 1}, {1, 0, -1.77636e-15, 0, 1, -8.88178e-16, 7.21645e-16, 0, 1}, {1, 1.11022e-16, -2.22045e-16, -2.498e-16, 1, -1.06859e-15, 0, -5.55112e-17, 1}, {1, 3.33067e-16, 2.22045e-16, -4.85723e-17, 1, -2.08167e-16, 5.55112e-16, -1.66533e-16, 1}, {1, 5.55112e-16, 4.44089e-16, 4.44089e-16, 1, 0, 4.44089e-16, 2.22045e-16, 1}, {1, 1.11022e-16, -4.44089e-16, 2.22045e-16, 1, 4.44089e-16, -4.44089e-16, 2.77556e-16, 1}, {1, -1.11022e-15, 0, -1.94289e-16, 1, 0, 0, -1.77636e-15, 1}, {1, 2.22045e-16, 0, 3.60822e-16, 1, 2.77556e-17, 0, -8.88178e-16, 1}, {1, 8.88178e-16, 0, -3.33067e-16, 1, 2.77556e-17, 0, 0, 1}, {1, 0, 0, -1.11022e-16, 1, 0, 0, 8.88178e-16, 1}, {1, -1.11022e-15, 4.44089e-16, -4.44089e-16, 1, 5.55112e-16, -7.77156e-16, -1.33227e-15, 1}, {1, 0, -2.22045e-16, -1.33227e-15, 1, -2.22045e-16, 1.22125e-15, -6.66134e-16, 1}, {1, 1.11022e-15, 2.22045e-16, 8.88178e-16, 1, 8.88178e-16, -1.77636e-15, 0, 1}, {1, 8.88178e-16, 8.88178e-16, -1.33227e-15, 1, 8.88178e-16, -4.44089e-16, 0, 1}, {1, 1.38778e-17, 1.88738e-15, -9.85323e-16, 1, -2.22045e-16, 0, -5.55112e-17, 1}, {1, 2.77556e-17, 4.44089e-16, 3.95517e-16, 1, -1.33227e-15, -4.44089e-16, 0, 1}, {1, 1.38778e-17, 2.22045e-16, 8.88178e-16, 1, 8.88178e-16, -2.22045e-16, 5.55112e-17, 1}, {1, 0, 8.88178e-16, 0, 1, 8.88178e-16, 0, -2.22045e-16, 1}, {1, 0, 8.88178e-16, -4.996e-16, 1, 0, 3.03577e-16, 1.38778e-17, 1}, {1, 0, 4.44089e-16, -3.88578e-16, 1, 5.55112e-16, 8.93383e-17, 1.73472e-17, 1}, {1, 0, -1.77636e-15, 1.11022e-16, 1, 1.11022e-15, -1.76942e-16, 5.72459e-17, 1}, {1, 5.55112e-17, -1.11022e-15, 0, 1, 8.88178e-16, 5.42968e-16, -2.64545e-17, 1}, {1, -1.77636e-15, -8.88178e-16, -1.11022e-15, 1, 4.44089e-16, -2.22045e-16, 6.66134e-16, 1}, {1, -4.44089e-16, 8.88178e-16, 1.55431e-15, 1, -6.66134e-16, 2.22045e-16, 8.88178e-16, 1}, {1, 1.77636e-15, -3.55271e-15, 2.22045e-16, 1, -6.66134e-16, -1.11022e-15, 2.22045e-16, 1}, {1, -8.88178e-16, 0, -8.88178e-16, 1, -2.66454e-15, 0, -8.88178e-16, 1}, {1, 2.01011e-16, 8.88178e-16, 1.77636e-15, 1, 0, 0, -2.22045e-16, 1}, {1, 6.44883e-16, 0, -4.44089e-16, 1, 8.88178e-16, -8.88178e-16, 6.66134e-16, 1}, {1, 0, 0, -1.33227e-15, 1, -1.33227e-15, 0, 2.22045e-16, 1}, {1, 8.88178e-16, 3.55271e-15, 0, 1, 0, -1.77636e-15, 0, 1}, {1, 0, 1.38778e-16, -1.52656e-15, 1, -3.43475e-16, 1.29063e-15, 4.44089e-16, 1}, {1, 1.33227e-15, 8.32667e-17, -1.30451e-15, 1, 0, 2.22045e-16, 7.77156e-16, 1}, {1, 0, -1.11022e-16, 1.77636e-15, 1, 0, -1.11022e-15, 1.88738e-15, 1}, {1, 0, 8.32667e-17, -1.77636e-15, 1, -6.66134e-16, -7.91034e-16, -1.66533e-15, 1}, {1, -8.88178e-16, 1.33227e-15, 1.11022e-16, 1, 2.22045e-15, 2.22045e-16, 4.44089e-16, 1}, {1, 4.44089e-16, 0, 0, 1, 1.33227e-15, -8.32667e-17, -4.44089e-16, 1}, {1, -5.32907e-15, -1.77636e-15, 2.77556e-17, 1, -8.88178e-16, -1.38778e-17, 1.77636e-15, 1}, {1, 0, 1.77636e-15, -5.55112e-17, 1, 8.88178e-16, -1.94289e-16, 1.77636e-15, 1}, {1, 6.66134e-16, 6.66134e-16, -2.77556e-16, 1, -1.9984e-15, -2.77556e-17, 3.33067e-16, 1}, {1, -8.88178e-16, 4.44089e-16, 3.60822e-16, 1, 8.88178e-16, 2.35922e-16, 6.66134e-16, 1}, {1, 8.88178e-16, -3.33067e-16, 0, 1, -8.88178e-16, 2.22045e-16, 4.44089e-16, 1}, {1, -8.88178e-16, 0, 8.32667e-17, 1, -4.85723e-16, 0, -2.22045e-16, 1}, {1, 4.16334e-16, 3.60822e-16, 0, 1, -5.55112e-17, 0, 5.55112e-16, 1}, {1, 0, 4.16334e-17, 2.77556e-16, 1, 8.32667e-17, -7.21645e-16, -2.22045e-16, 1}, {1, 0, -1.38778e-16, 2.22045e-16, 1, 1.11022e-16, 2.77556e-16, 4.44089e-16, 1}, {1, 4.16334e-16, -3.46945e-17, 1.11022e-16, 1, 1.94289e-16, 2.22045e-16, 0, 1}, {1, -2.31195e-15, -1.83112e-15, 1.11022e-16, 1, -1.77636e-15, 1.43262e-16, 2.44249e-15, 1}, {1, 1.9984e-15, 1.37056e-15, 1.66533e-16, 1, 0, -1.65065e-16, 1.77636e-15, 1}, {1, -1.77636e-15, 8.88178e-16, -2.22045e-16, 1, 0, 2.22045e-16, 5.32907e-15, 1}, {1, 4.44089e-15, -1.77636e-15, -1.11022e-16, 1, 0, 2.22045e-16, 1.77636e-15, 1}, {1, 2.22045e-16, 0, 1.77636e-15, 1, 1.77636e-15, -5.27356e-16, -2.08167e-16, 1}, {1, 4.44089e-16, 2.22045e-16, 6.66134e-16, 1, -6.66134e-16, -5.82867e-16, -5.27356e-16, 1}, {1, 0, -4.44089e-16, -1.77636e-15, 1, 0, 1.11022e-15, -1.11022e-16, 1}, {1, 8.88178e-16, -8.88178e-16, 2.22045e-16, 1, -7.77156e-16, 1.66533e-16, 3.33067e-16, 1}, {1, -1.05471e-15, 3.88578e-16, 0, 1, -2.22045e-16, 9.71445e-17, 5.55112e-16, 1}, {1, -2.77556e-16, 3.33067e-16, 6.66134e-16, 1, 2.22045e-16, 2.498e-16, -2.56739e-16, 1}, {1, -4.44089e-16, 8.88178e-16, 8.88178e-16, 1, -2.22045e-16, -1.11022e-16, -2.22045e-16, 1}, {1, -4.44089e-16, 0, 0, 1, 4.44089e-16, -6.93889e-16, -4.71845e-16, 1}, {1, -2.22045e-16, -4.44089e-16, -3.33067e-16, 1, -6.66134e-16, -4.44089e-16, 3.33067e-16, 1}, {1, -2.63678e-16, -6.66134e-16, -1.11022e-16, 1, 6.66134e-16, 2.77556e-16, 0, 1}, {1, -1.66533e-16, -1.11022e-15, 8.88178e-16, 1, 0, -1.11022e-16, -2.22045e-16, 1}, {1, 1.11022e-16, 0, -8.67362e-17, 1, -6.93889e-17, -1.11022e-16, 0, 1}, {1, 2.77556e-16, 3.60822e-16, 0, 1, -2.63678e-16, 1.66533e-16, 4.71845e-16, 1}, {1, 3.88578e-16, 7.49401e-16, -5.55112e-17, 1, -2.22045e-16, 1.11022e-16, 4.44089e-16, 1}, {1, -1.11022e-16, -2.77556e-16, -1.11022e-16, 1, -8.32667e-17, -5.55112e-17, -1.11022e-16, 1}, {1, -6.66134e-16, 1.11022e-16, 0, 1, -2.22045e-16, 2.22045e-16, -1.55431e-15, 1}, {1, -1.11022e-16, 0, 9.99201e-16, 1, 2.44249e-15, -8.88178e-16, -2.22045e-16, 1}, {1, -3.33067e-16, 8.88178e-16, -1.33227e-15, 1, -1.77636e-15, -4.44089e-16, -1.11022e-16, 1}, {1, 4.44089e-16, 1.77636e-15, -8.88178e-16, 1, -2.66454e-15, 4.44089e-16, 0, 1}, {1, 1.11022e-16, 2.22045e-16, 8.88178e-16, 1, 0, 0, 2.22045e-16, 1}, {1, -2.498e-16, -1.38778e-16, -4.44089e-15, 1, -3.55271e-15, 2.44249e-15, 2.22045e-16, 1}, {1, 4.16334e-16, 2.498e-16, -8.88178e-16, 1, 0, 2.22045e-16, 6.66134e-16, 1}, {1, 2.22045e-16, 2.22045e-16, -3.55271e-15, 1, 0, 2.22045e-16, 9.99201e-16, 1}, {1, -2.41474e-15, -1.02696e-15, -8.88178e-16, 1, -8.88178e-16, 8.88178e-16, 0, 1}, {1, -2.22045e-16, 2.22045e-16, 1.44329e-15, 1, 1.55431e-15, 4.16334e-16, -1.11022e-16, 1}, {1, 1.11022e-15, -4.44089e-16, -2.77556e-16, 1, 1.11022e-15, -2.77556e-17, 4.44089e-16, 1}, {1, -4.44089e-16, -1.33227e-15, -8.88178e-16, 1, 1.77636e-15, 4.44089e-16, 8.88178e-16, 1}, {1, 0, 0, -6.66134e-16, 1, -8.88178e-16, 1.49186e-16, -2.08167e-17, 1}, {1, -7.63278e-16, -7.21645e-16, -3.60822e-16, 1, -3.10862e-15, 1.59595e-16, -1.80411e-16, 1}, {1, 1.249e-16, -7.21645e-16, 6.93889e-16, 1, -1.33227e-15, 1.83881e-16, 1.38778e-17, 1}, {1, 4.44089e-16, 0, -5.44703e-16, 1, 9.71445e-16, -1.11022e-16, -2.22045e-16, 1}, {1, -4.44089e-16, 0, 2.22045e-16, 1, 0, -5.55112e-17, -4.44089e-16, 1}, {1, 1.33227e-15, 0, 0, 1, 0, -5.55112e-17, 4.44089e-16, 1}, {1, -1.11022e-15, -8.88178e-16, 0, 1, 0, 0, -4.44089e-16, 1}, {1, 0, -4.44089e-16, 0, 1, 0, 0, 8.88178e-16, 1}, {1, 0, 0, 0, 1, 0, 0, 4.44089e-16, 1}, {1, -1.26722e-15, -1.33227e-15, -2.22045e-16, 1, 0, -5.27356e-16, -2.498e-16, 1}, {1, -7.12971e-16, -8.88178e-16, -4.44089e-16, 1, 1.33227e-15, 7.49401e-16, 8.60423e-16, 1}, {1, 1.33227e-15, 0, 0, 1, -8.88178e-16, -2.77556e-16, 7.21645e-16, 1}, {1, 0, 0, 0, 1, 0, 4.44089e-16, -5.55112e-16, 1}, {1, -1.33227e-15, -1.33227e-15, 3.66704e-15, 1, 6.00106e-16, -4.44089e-16, 1.45832e-15, 1}, {1, 3.55271e-15, 2.66454e-15, -4.44089e-16, 1, -2.44683e-15, -4.44089e-16, -6.64688e-16, 1}, {1, 0, 0, 0, 1, 1.77636e-15, 3.55271e-15, -2.66454e-15, 1}, {1, -3.55271e-15, 0, -1.77636e-15, 1, -1.77636e-15, 8.88178e-16, 1.77636e-15, 1}, {1, 0, -8.88178e-16, 0, 1, 0, -1.11022e-15, 1.55431e-15, 1}, {1, -8.88178e-16, 8.88178e-16, -1.33227e-15, 1, -8.88178e-16, -4.44089e-16, 8.88178e-16, 1}, {1, 2.22045e-16, 1.33227e-15, 0, 1, 0, 6.66134e-16, 0, 1}, {1, 0, 8.88178e-16, -1.77636e-15, 1, -1.77636e-15, 0, 0, 1}, {1, -1.11022e-16, 8.88178e-16, 1.55431e-15, 1, -1.9984e-15, -6.66134e-16, -6.10623e-16, 1}, {1, -1.11022e-16, 1.11022e-15, -1.9984e-15, 1, 1.9984e-15, 0, 7.77156e-16, 1}, {1, 0, 0, -2.66454e-15, 1, 1.77636e-15, -2.22045e-15, -7.21645e-16, 1}, {1, 8.88178e-16, 0, 0, 1, -4.44089e-16, 0, -4.44089e-16, 1}, {1, 2.77556e-16, 3.33067e-16, 5.05151e-15, 1, 5.38458e-15, -8.88178e-16, 2.66454e-15, 1}, {1, 6.10623e-16, 5.55112e-16, 1.38778e-15, 1, 9.99201e-16, -8.88178e-16, -1.77636e-15, 1}, {1, -4.44089e-16, -1.33227e-15, 1.77636e-15, 1, 1.77636e-15, 3.55271e-15, -3.55271e-15, 1}, {1, 5.55112e-16, 9.99201e-16, -1.77636e-15, 1, 0, -8.88178e-16, 0, 1}, {1, -1.11022e-16, -1.11022e-15, 6.66134e-16, 1, -6.66134e-16, 2.22045e-16, 8.32667e-17, 1}, {1, 1.11022e-16, -6.66134e-16, -8.88178e-16, 1, 4.44089e-16, -3.33067e-16, 1.38778e-16, 1}, {1, -7.77156e-16, 0, 0, 1, -8.88178e-16, -6.66134e-16, -9.99201e-16, 1}, {1, 0, -8.88178e-16, -4.44089e-16, 1, 0, 0, 2.22045e-16, 1}, {1, 4.996e-16, 1.36002e-15, 1.77636e-15, 1, 0, 3.9968e-15, -4.44089e-16, 1}, {1, -3.60822e-16, -3.88578e-16, 8.88178e-16, 1, -4.44089e-16, -2.66454e-15, 1.9984e-15, 1}, {1, 1.16573e-15, 9.99201e-16, -8.88178e-16, 1, -2.66454e-15, 1.77636e-15, 0, 1}, {1, -1.11022e-15, 6.66134e-16, 0, 1, 1.33227e-15, -3.55271e-15, 0, 1}, {1, -5.55112e-17, 8.88178e-16, -6.93889e-18, 1, -1.02696e-15, -1.66533e-16, 0, 1}, {1, 0, 1.11022e-15, -4.16334e-17, 1, 2.77556e-16, 1.66533e-16, -2.22045e-16, 1}, {1, 2.77556e-17, 8.88178e-16, 4.16334e-17, 1, 1.72085e-15, -2.22045e-16, 0, 1}, {1, -5.55112e-17, 0, 5.55112e-17, 1, 1.55431e-15, 0, 5.55112e-17, 1}, {1, -1.33227e-15, 0, -1.77636e-15, 1, -4.44089e-16, 3.33067e-16, -2.498e-16, 1}, {1, 1.11022e-15, 1.9984e-15, 1.33227e-15, 1, -4.44089e-16, 2.77556e-16, 3.60822e-16, 1}, {1, 0, 1.77636e-15, -2.22045e-16, 1, 4.44089e-16, 5.55112e-16, 9.4369e-16, 1}, {1, 8.88178e-16, -5.55112e-16, 2.66454e-15, 1, 8.88178e-16, 6.66134e-16, 1.11022e-16, 1}, {1, -2.498e-16, -4.44089e-16, 0, 1, -4.44089e-16, -2.77556e-17, -1.11022e-16, 1}, {1, 0, -3.10862e-15, 0, 1, 1.11022e-15, 2.77556e-17, 4.44089e-16, 1}, {1, 9.71445e-17, 1.77636e-15, -1.11022e-16, 1, 8.88178e-16, 0, 0, 1}, {1, 2.22045e-16, -1.77636e-15, 0, 1, 6.66134e-16, 0, 2.22045e-16, 1}, {1, -8.88178e-16, -4.44089e-16, -3.33067e-16, 1, -8.88178e-16, -4.44089e-16, 4.44089e-16, 1}, {1, -2.22045e-16, 8.88178e-16, -5.55112e-16, 1, 0, -3.33067e-16, -2.44249e-15, 1}, {1, -1.77636e-15, -1.77636e-15, 4.44089e-16, 1, 0, 4.44089e-16, -8.88178e-16, 1}, {1, -1.66533e-15, 0, 0, 1, 0, 0, -8.88178e-16, 1}, {1, 0, -5.55112e-17, 5.55112e-17, 1, 0, -1.11022e-16, -2.22045e-16, 1}, {1, 1.11022e-16, -4.44089e-16, 1.11022e-16, 1, -3.33067e-16, -4.44089e-16, 4.996e-16, 1}, {1, -1.11022e-16, 0, -2.22045e-16, 1, 0, -2.22045e-16, 4.44089e-16, 1}, {1, 2.77556e-16, 2.22045e-16, -5.55112e-17, 1, 3.33067e-16, -2.22045e-16, 1.66533e-16, 1}, {1, 8.88178e-16, 2.66454e-15, 0, 1, 4.44089e-16, 5.55112e-17, 2.22045e-16, 1}, {1, -4.44089e-16, 3.55271e-15, -3.33067e-16, 1, 1.77636e-15, 5.55112e-17, -2.22045e-16, 1}, {1, -3.55271e-15, 1.77636e-15, 3.40006e-16, 1, 1.44329e-15, -1.52656e-16, -4.996e-16, 1}, {1, -1.77636e-15, -4.44089e-15, 0, 1, 0, 0, 0, 1}, {1, -5.55112e-17, 6.66134e-16, -4.44089e-16, 1, 1.4086e-15, 1.22125e-15, -4.16334e-17, 1}, {1, -5.55112e-17, -2.22045e-16, 4.44089e-16, 1, 5.68989e-16, -1.11022e-16, 4.16334e-17, 1}, {1, 0, 6.66134e-16, 8.88178e-16, 1, 8.88178e-16, 0, 4.16334e-17, 1}, {1, 0, -8.88178e-16, 2.66454e-15, 1, -8.88178e-16, -1.77636e-15, -1.11022e-16, 1}, {1, 0, 4.44089e-16, 2.77556e-17, 1, 0, 0, 0, 1}, {1, -1.94289e-16, -3.33067e-16, 0, 1, -4.44089e-16, 0, -2.77556e-17, 1}, {1, -2.77556e-17, 2.22045e-16, 0, 1, 0, 0, 0, 1}, {1, 2.77556e-17, -4.44089e-16, -5.55112e-17, 1, -5.55112e-17, 0, 0, 1}, {1, -1.11022e-16, -4.89864e-17, -1.44329e-15, 1, -4.44089e-16, 0, 6.66134e-16, 1}, {1, -1.33227e-15, -1.41321e-17, 1.11022e-16, 1, 1.66533e-16, -4.44089e-16, 2.22045e-16, 1}, {1, -3.33067e-16, -1.41321e-17, 8.88178e-16, 1, -5.55112e-17, 0, 0, 1}, {1, 8.88178e-16, -5.91e-18, -3.33067e-16, 1, -1.66533e-16, 0, 0, 1}, {1, -2.77556e-17, -2.77556e-17, 3.33067e-16, 1, 5.55112e-17, -2.22045e-16, 0, 1}, {1, -5.82867e-16, 0, 3.33067e-16, 1, 0, -1.11022e-16, -1.11022e-16, 1}, {1, 5.55112e-17, 0, -2.22045e-16, 1, 0, 4.44089e-16, 0, 1}, {1, 1.11022e-16, 0, 4.44089e-16, 1, 0, -1.11022e-16, -1.11022e-16, 1}, {1, -5.55112e-17, -1.38778e-17, 1.11022e-16, 1, 0, -5.55112e-17, 2.77556e-16, 1}, {1, 6.66134e-16, 0, -5.55112e-17, 1, 1.11022e-16, 0, -2.22045e-16, 1}, {1, -2.22045e-16, 0, 0, 1, -2.77556e-17, -1.11022e-16, -2.22045e-16, 1}, {1, 0, 2.77556e-17, 4.44089e-16, 1, -2.77556e-17, -4.44089e-16, 0, 1}, {1, 1.66533e-16, -1.38778e-17, 1.66533e-16, 1, 1.11022e-16, -3.33067e-16, -4.44089e-16, 1}, {1, -4.44089e-16, -9.71445e-17, 1.11022e-16, 1, 3.33067e-16, -5.55112e-17, 2.22045e-16, 1}, {1, 0, 0, -5.55112e-16, 1, -1.11022e-16, 2.22045e-16, 1.77636e-15, 1}, {1, -1.11022e-16, 2.22045e-16, 0, 1, 0, -5.55112e-17, -4.44089e-16, 1}, {1, 3.33067e-16, 2.77556e-17, -1.66533e-16, 1, -1.66533e-16, 2.22045e-16, 4.44089e-16, 1}, {1, 6.66134e-16, -3.88578e-16, -1.11022e-16, 1, -1.11022e-16, 4.996e-16, 8.88178e-16, 1}, {1, 0, 0, -4.996e-16, 1, -5.55112e-17, -2.22045e-16, -4.44089e-16, 1}, {1, 8.88178e-16, 2.22045e-16, 0, 1, 0, 0, 4.44089e-16, 1}, {1, 1.33227e-15, 0, -6.66134e-16, 1, 0, 0, -2.66454e-15, 1}, {1, -6.66134e-16, -2.77556e-17, 2.22045e-16, 1, 0, 1.77636e-15, 0, 1}, {1, 2.22045e-16, -2.77556e-17, -2.22045e-16, 1, 0, 0, 1.77636e-15, 1}, {1, 1.77636e-15, -1.11022e-16, 0, 1, 0, 0, 3.55271e-15, 1}, {1, 1.33227e-15, 2.22045e-16, 0, 1, 0, 4.16334e-17, -6.66134e-16, 1}, {1, 2.22045e-15, -1.11022e-16, 0, 1, 5.55112e-17, 0, -1.9984e-15, 1}, {1, 0, 5.55112e-17, 0, 1, 5.55112e-17, 2.77556e-17, -2.22045e-15, 1}, {1, 3.10862e-15, 2.22045e-16, 0, 1, 0, 0, 0, 1}, {1, 3.33067e-16, 1.11022e-15, 2.77556e-17, 1, -9.99201e-16, -2.22045e-16, -5.55112e-16, 1}, {1, -4.44089e-16, -1.55431e-15, -8.32667e-17, 1, -5.55112e-16, -2.22045e-16, -7.77156e-16, 1}, {1, 8.88178e-16, 0, -1.66533e-16, 1, 4.44089e-16, 1.66533e-16, 2.22045e-16, 1}, {1, -3.33067e-16, -4.44089e-16, 1.11022e-16, 1, 7.77156e-16, 2.22045e-16, 1.33227e-15, 1}, {1, 4.44089e-16, -2.22045e-16, 1.9984e-15, 1, 1.11022e-15, -2.22045e-15, -1.33227e-15, 1}, {1, 1.55431e-15, 6.66134e-16, 6.66134e-16, 1, -6.66134e-16, -2.22045e-16, -6.66134e-16, 1}, {1, 8.88178e-16, -8.88178e-16, -2.22045e-16, 1, 4.44089e-16, 0, 0, 1}, {1, 1.11022e-15, -2.22045e-16, 0, 1, 0, 0, 3.88578e-16, 1}, {1, -2.33501e-16, -1.15473e-17, 0, 1, 0, 3.81034e-17, 1.11022e-15, 1}, {1, -1.74958e-15, 5.56848e-17, 0, 1, 0, 1.98274e-17, -1.55431e-15, 1}, {1, -2.29369e-15, -8.8428e-17, 0, 1, 0, 6.03412e-18, -1.11022e-15, 1}, {1, -4.30553e-16, -1.01638e-17, 0, 1, 0, 1.55712e-18, -8.88178e-16, 1}, {1, 2.61726e-16, 1.3713e-15, 2.22045e-16, 1, 4.44089e-16, 1.38415e-16, 1.11022e-15, 1}, {1, -6.28404e-16, -2.18575e-15, 1.66533e-16, 1, 0, -2.50877e-18, -6.66134e-16, 1}, {1, -5.6205e-16, -6.93889e-18, 0, 1, 0, -8.48087e-18, 6.66134e-16, 1}, {1, -6.48353e-16, -9.93129e-16, 5.55112e-17, 1, 0, -1.74128e-16, 0, 1}, {1, -3.33067e-16, 4.44089e-16, -2.22045e-16, 1, 2.22045e-16, -6.17562e-16, -6.93889e-18, 1}, {1, -1.11022e-16, 8.88178e-16, -2.22045e-16, 1, 2.22045e-16, 5.48173e-16, 3.46945e-17, 1}, {1, -2.22045e-16, 8.88178e-16, 8.88178e-16, 1, -1.77636e-15, -2.66454e-15, -2.22045e-16, 1}, {1, 0, 0, 4.44089e-16, 1, -8.88178e-16, 0, -4.44089e-16, 1}, {1, -2.55351e-15, -1.66533e-16, 1.30451e-15, 1, 2.498e-16, 1.11022e-15, 8.88178e-16, 1}, {1, 1.1241e-15, -2.22045e-16, -3.60822e-16, 1, -6.52256e-16, -6.66134e-16, 4.44089e-16, 1}, {1, 3.55271e-15, -3.05311e-16, 4.44089e-16, 1, -2.77556e-17, 2.66454e-15, 0, 1}, {1, 3.55271e-15, -1.52656e-16, 3.33067e-16, 1, 0, -1.11022e-15, -1.66533e-15, 1}, {1, 0, 1.11022e-15, 0, 1, 6.66134e-16, -5.55112e-17, -2.22045e-16, 1}, {1, 4.44089e-16, -8.88178e-16, 1.11022e-16, 1, -8.88178e-16, -8.32667e-17, 6.66134e-16, 1}, {1, -2.22045e-16, -8.88178e-16, 0, 1, -8.88178e-16, 2.22045e-16, 2.22045e-16, 1}, {1, 8.88178e-16, 8.88178e-16, 0, 1, 8.88178e-16, -2.22045e-16, 0, 1}, {1, 0, -4.44089e-16, 0, 1, 0, 0, 2.22045e-16, 1}, {1, 8.88178e-16, -3.33067e-16, 1.11022e-15, 1, -1.11022e-16, 3.46254e-16, 1.05667e-16, 1}, {1, 8.88178e-16, 0, -3.33067e-16, 1, 6.10623e-16, 0, 0, 1}, {1, 1.11022e-16, 1.05471e-15, 0, 1, 0, 0, 0, 1}, {1, 6.66134e-16, -5.55112e-17, 5.55112e-16, 1, 1.38778e-16, -2.77556e-16, -5.55112e-16, 1}, {1, -6.66134e-16, 2.77556e-17, 4.44089e-16, 1, -8.32667e-17, -1.11022e-16, 1.66533e-16, 1}, {1, 0, -2.22045e-16, -3.33067e-16, 1, -4.71845e-16, 0, -8.88178e-16, 1}, {1, 4.44089e-16, 5.55112e-17, 0, 1, 0, -2.22045e-16, 0, 1}, {1, 5.55112e-17, -1.66533e-16, -6.66134e-16, 1, 5.55112e-17, -1.11022e-16, -2.77556e-17, 1}, {1, 5.55112e-17, 3.88578e-16, 2.77556e-16, 1, -5.55112e-17, 3.33067e-16, 2.77556e-17, 1}, {1, -5.55112e-17, -2.22045e-16, 4.44089e-16, 1, 0, 5.55112e-17, -2.77556e-17, 1}, {1, -2.22045e-16, -6.66134e-16, 3.33067e-16, 1, 5.55112e-17, 0, -2.22045e-16, 1}, {1, 5.55112e-17, -1.11022e-16, 5.55112e-17, 1, 3.05311e-16, -3.33067e-16, -8.32667e-17, 1}, {1, 0, -7.21645e-16, 1.66533e-16, 1, 1.38778e-16, 1.11022e-16, -2.77556e-16, 1}, {1, 0, -1.11022e-16, 2.22045e-16, 1, 2.22045e-16, -2.22045e-16, 1.11022e-16, 1}, {1, -2.22045e-16, 0, 5.55112e-17, 1, 2.77556e-17, 4.44089e-16, 4.44089e-16, 1}, {1, -4.44089e-16, -3.33067e-16, 9.99201e-16, 1, 2.498e-16, -4.32987e-15, -1.27676e-15, 1}, {1, 0, -2.22045e-16, 1.83187e-15, 1, 2.77556e-17, 3.88578e-15, -5.55112e-16, 1}, {1, 2.22045e-16, 4.44089e-16, -2.66454e-15, 1, -8.88178e-16, -7.10543e-15, -2.22045e-15, 1}, {1, 0, 0, -4.44089e-16, 1, -1.66533e-16, 2.22045e-15, -6.66134e-16, 1}, {1, -4.44089e-16, 2.77556e-17, 2.22045e-16, 1, 0, -7.77156e-16, -9.99201e-16, 1}, {1, 2.22045e-16, 0, 6.66134e-16, 1, -5.55112e-17, -9.99201e-16, -2.77556e-16, 1}, {1, 8.88178e-16, 0, 1.44329e-15, 1, 0, 1.33227e-15, 8.88178e-16, 1}, {1, 1.11022e-15, 0, 0, 1, -1.38778e-17, 8.88178e-16, 0, 1}, {1, -2.22045e-16, -1.66533e-16, -5.55112e-16, 1, 0, 8.88178e-16, 1.11022e-16, 1}, {1, 2.22045e-16, 0, -3.33067e-16, 1, 0, -4.44089e-16, 7.77156e-16, 1}, {1, -1.66533e-16, -1.11022e-16, 4.44089e-16, 1, 0, 1.77636e-15, -4.44089e-16, 1}, {1, 0, 0, 3.33067e-16, 1, 1.11022e-16, -1.33227e-15, -6.66134e-16, 1}, {1, 2.77556e-16, -2.77556e-17, 7.21645e-16, 1, 0, 1.27676e-15, 5.75928e-16, 1}, {1, 5.55112e-17, 0, 3.88578e-16, 1, 0, 8.32667e-17, -6.93889e-17, 1}, {1, -2.22045e-16, 0, -8.88178e-16, 1, 0, 8.88178e-16, 0, 1}, {1, 5.55112e-16, 0, 0, 1, 0, 2.66454e-15, 0, 1}, {1, 7.77156e-16, 8.88178e-16, -4.44089e-16, 1, -2.22045e-16, 0, 7.77156e-16, 1}, {1, 4.44089e-15, 3.33067e-15, 2.77556e-17, 1, -8.88178e-16, -8.32667e-17, 1.33227e-15, 1}, {1, 8.88178e-16, -1.33227e-15, 1.11022e-16, 1, 0, 0, 1.33227e-15, 1}, {1, 0, 1.77636e-15, -1.11022e-16, 1, -1.33227e-15, 2.77556e-17, 0, 1}, {1, 2.22045e-16, -8.88178e-16, 0, 1, 2.22045e-15, 0, -4.44089e-16, 1}, {1, 4.44089e-16, -1.77636e-15, 0, 1, -4.44089e-16, 8.32667e-17, 2.22045e-16, 1}, {1, 0, 3.55271e-15, 1.11022e-16, 1, 0, -2.77556e-17, -4.44089e-16, 1}, {1, -4.44089e-16, 1.77636e-15, 1.11022e-16, 1, 1.77636e-15, -5.55112e-17, 4.78784e-16, 1}, {1, -1.11022e-16, -1.11022e-16, 2.32229e-17, 1, 8.88178e-16, 5.55112e-17, -1.22125e-15, 1}, {1, 4.44089e-16, 9.99201e-16, 1.45552e-16, 1, 0, 0, 1.11022e-15, 1}, {1, 8.88178e-16, 0, 7.93707e-19, 1, 2.22045e-16, 0, 8.88178e-16, 1}, {1, 1.11022e-15, -6.66134e-16, -1.04209e-17, 1, -8.88178e-16, 5.55112e-17, -4.44089e-16, 1}, {1, 5.32907e-15, 4.44089e-16, 1.55431e-15, 1, 1.11022e-16, -1.16573e-15, -1.38778e-15, 1}, {1, 0, -5.55112e-16, -8.88178e-16, 1, 0, -2.77556e-16, -1.22125e-15, 1}, {1, 0, 2.22045e-16, 4.44089e-16, 1, 0, -6.66134e-16, 0, 1}, {1, -4.44089e-16, 0, 8.88178e-16, 1, 0, -1.11022e-15, 8.32667e-16, 1}, {1, 1.11022e-16, -2.22045e-16, -1.11022e-16, 1, 4.44089e-16, 0, -4.44089e-16, 1}, {1, -4.44089e-16, -4.44089e-16, 5.55112e-17, 1, 8.88178e-16, 0, 0, 1}, {1, 0, 0, 0, 1, -6.66134e-16, 0, 1.11022e-16, 1}, {1, 4.44089e-16, 4.44089e-16, 0, 1, -8.88178e-16, 0, 8.88178e-16, 1}, {1, 1.77636e-15, 0, 0, 1, 0, -1.38778e-17, -8.88178e-16, 1}, {1, -8.88178e-16, 1.11022e-16, -2.77556e-17, 1, 3.33067e-16, 1.38778e-17, -2.22045e-16, 1}, {1, 1.77636e-15, -8.88178e-16, 2.77556e-17, 1, 2.22045e-16, -1.38778e-17, 0, 1}, {1, -1.77636e-15, -2.22045e-16, 1.11022e-16, 1, 0, 0, 0, 1}, {1, -5.55112e-16, -6.10623e-16, 0, 1, 2.77556e-16, -1.38778e-17, -6.93889e-17, 1}, {1, 3.33067e-16, 2.77556e-16, 0, 1, 5.55112e-17, 5.55112e-17, 6.93889e-17, 1}, {1, -4.44089e-16, -1.11022e-16, 0, 1, 8.32667e-17, -3.46945e-17, 2.77556e-17, 1}, {1, 1.66533e-16, 4.16334e-17, -2.22045e-16, 1, -2.22045e-16, 8.32667e-17, -5.55112e-17, 1}, {1, 6.66134e-16, 3.33067e-16, 0, 1, 0, -1.11022e-16, -3.33067e-16, 1}, {1, -2.22045e-15, -3.33067e-16, 1.74518e-16, 1, -2.10643e-17, -3.33067e-16, 3.33067e-16, 1}, {1, -1.33227e-15, -2.22045e-16, 0, 1, 0, 2.22045e-16, 1.38778e-16, 1}, {1, -4.44089e-16, 0, 0, 1, 0, 0, 0, 1}, {1, -4.44089e-16, -5.55112e-17, 8.88178e-16, 1, 0, -4.44089e-16, -1.66533e-16, 1}, {1, -1.11022e-16, 0, 8.88178e-16, 1, 0, -4.44089e-16, 1.11022e-16, 1}, {1, -8.88178e-16, 0, 8.88178e-16, 1, 0, 2.44249e-15, 8.32667e-16, 1}, {1, -6.66134e-16, 2.77556e-17, -1.33227e-15, 1, 2.77556e-17, -1.77636e-15, 0, 1}, {1, 0, 1.77636e-15, 0, 1, 8.88178e-16, 0, -4.44089e-16, 1}, {1, -1.33227e-15, -2.22045e-15, -1.38778e-17, 1, 2.44249e-15, 0, -8.88178e-16, 1}, {1, -3.55271e-15, -8.88178e-16, -1.11022e-16, 1, 0, 1.11022e-16, 1.77636e-15, 1}, {1, 0, 1.77636e-15, 0, 1, 3.9968e-15, 0, 0, 1}, {1, -7.77156e-16, -5.55112e-17, 2.22045e-16, 1, -2.32453e-16, 0, -2.22045e-16, 1}, {1, -3.60822e-16, -2.22045e-16, -7.77156e-16, 1, -1.66533e-16, 8.88178e-16, 2.22045e-16, 1}, {1, 1.11022e-15, -8.32667e-17, -1.77636e-15, 1, -3.1225e-17, 8.88178e-16, 0, 1}, {1, 1.33227e-15, 0, -8.88178e-16, 1, -3.33067e-16, -8.88178e-16, 0, 1}, {1, -1.11022e-16, -1.11022e-16, -4.44089e-16, 1, 1.11022e-16, 5.8494e-16, -4.44089e-16, 1}, {1, 2.22045e-16, -6.66134e-16, -1.66533e-16, 1, -4.44089e-16, 1.23292e-16, 2.22045e-16, 1}, {1, 0, -2.66454e-15, 1.11022e-16, 1, 2.66454e-15, 1.44231e-16, 6.66134e-16, 1}, {1, 8.04912e-16, 6.93889e-16, 5.55112e-17, 1, 0, 3.41526e-16, 1.77636e-15, 1}, {1, -4.16334e-16, -2.22045e-16, -3.9968e-15, 1, -6.43929e-15, -8.88178e-16, 2.22045e-16, 1}, {1, 6.66134e-16, -4.16334e-16, 2.22045e-15, 1, 3.77476e-15, 0, -1.55431e-15, 1}, {1, 1.55431e-15, 3.33067e-15, -3.55271e-15, 1, -3.55271e-15, 4.44089e-16, 0, 1}, {1, 2.22045e-16, 2.77556e-16, 1.77636e-15, 1, 2.66454e-15, 0, -8.88178e-16, 1}, {1, 2.77556e-17, -1.77636e-15, 1.77636e-15, 1, 1.77636e-15, 0, 0, 1}, {1, 0, 4.44089e-16, 2.22045e-16, 1, 2.22045e-15, -8.88178e-16, 0, 1}, {1, 2.77556e-17, 1.77636e-15, 0, 1, 0, 2.22045e-16, -5.55112e-17, 1}, {1, 0, 0, -8.88178e-16, 1, -1.77636e-15, 8.88178e-16, 0, 1}, {1, -2.22045e-15, -1.55431e-15, 0, 1, -1.33227e-15, 0, 4.44089e-16, 1}, {1, -8.88178e-16, -2.22045e-16, 0, 1, 8.88178e-16, 0, -8.88178e-16, 1}, {1, -1.77636e-15, 8.88178e-16, 0, 1, -1.77636e-15, 0, 0, 1}, {1, -8.88178e-16, -2.66454e-15, 0, 1, 8.88178e-16, 0, 0, 1}, {1, -1.80411e-16, 1.94289e-16, 4.44089e-16, 1, -1.11022e-16, 8.88178e-16, 0, 1}, {1, 5.55112e-17, -4.996e-16, 4.44089e-16, 1, -2.498e-16, 0, -1.11022e-16, 1}, {1, 1.11022e-16, 6.66134e-16, 1.77636e-15, 1, 0, 1.77636e-15, -2.22045e-16, 1}, {1, -1.94289e-16, -3.88578e-16, 2.88658e-15, 1, 2.77556e-16, 3.55271e-15, 0, 1}, {1, 8.88178e-16, 8.88178e-16, -2.22045e-15, 1, -1.33227e-15, -2.88658e-15, -3.10862e-15, 1}, {1, 0, 4.44089e-16, -2.66454e-15, 1, 1.33227e-15, -2.66454e-15, -4.44089e-15, 1}, {1, 1.9984e-15, 4.44089e-16, 0, 1, 0, -1.77636e-15, -3.55271e-15, 1}, {1, -8.88178e-16, 0, 0, 1, -1.77636e-15, -8.88178e-16, 3.55271e-15, 1}, {1, 4.44089e-16, 0, 4.44089e-16, 1, 4.44089e-16, 3.9968e-15, 5.55112e-16, 1}, {1, -4.44089e-16, -4.44089e-16, 4.44089e-16, 1, -3.88578e-16, 4.44089e-16, 8.32667e-17, 1}, {1, 2.22045e-16, -4.44089e-16, 4.44089e-16, 1, 1.66533e-16, -3.9968e-15, -4.71845e-16, 1}, {1, -6.10623e-16, -5.55112e-16, -1.77636e-15, 1, -4.44089e-16, 0, 0, 1}, {1, -2.22045e-16, -8.88178e-16, 0, 1, -1.33227e-15, 0, 0, 1}, {1, -3.88578e-16, -3.55271e-15, 0, 1, 0, 1.11022e-16, 3.88578e-16, 1}, {1, 4.44089e-16, 3.55271e-15, -2.77556e-17, 1, -1.77636e-15, 1.38778e-17, -4.44089e-16, 1}, {1, 0, 0, 0, 1, 0, -1.38778e-17, 2.22045e-16, 1}, {1, -4.996e-16, -4.44089e-16, -8.88178e-16, 1, -4.44089e-16, -1.33227e-15, -4.44089e-16, 1}, {1, 1.66533e-16, 2.22045e-15, 4.44089e-16, 1, 4.44089e-16, -6.66134e-16, -1.94289e-16, 1}, {1, -8.88178e-16, -1.77636e-15, 0, 1, 0, 4.44089e-16, 7.21645e-16, 1}, {1, 0, -1.77636e-15, -4.44089e-16, 1, 4.44089e-16, 0, 1.11022e-16, 1}, {1, -2.77556e-16, -1.11022e-15, 0, 1, 0, 4.44089e-16, -1.11022e-16, 1}, {1, 2.08167e-16, 2.22045e-16, 4.44089e-16, 1, -4.44089e-16, -1.77636e-15, 5.55112e-16, 1}, {1, 1.38778e-17, -2.22045e-16, 0, 1, 4.44089e-16, -3.55271e-15, 0, 1}, {1, 0, -8.88178e-16, 0, 1, 0, -8.88178e-16, -2.77556e-16, 1}, {1, 8.56581e-18, 8.27028e-16, 4.44089e-16, 1, -8.88178e-16, 3.55271e-15, 0, 1}, {1, -3.5146e-17, -2.44423e-16, -8.88178e-16, 1, 4.44089e-16, 0, 0, 1}, {1, 3.80641e-17, 4.79871e-16, -1.77636e-15, 1, 8.88178e-16, -8.88178e-16, 0, 1}, {1, -1.24812e-16, 6.16835e-16, 8.88178e-16, 1, -1.11022e-15, 0, 0, 1}, {1, 1.11022e-15, 1.66533e-16, 5.55112e-16, 1, -3.33067e-16, -6.66134e-16, 9.99201e-16, 1}, {1, 2.22045e-15, -1.11022e-16, 2.22045e-16, 1, 5.55112e-17, 0, -4.44089e-16, 1}, {1, -1.33227e-15, -1.38778e-16, -4.44089e-16, 1, -2.77556e-17, 0, -4.44089e-16, 1}, {1, 0, 8.32667e-17, -4.44089e-16, 1, -1.94289e-16, 0, 8.88178e-16, 1}, {1, 1.58207e-15, -1.38778e-17, 6.66134e-16, 1, 4.996e-16, -9.99201e-16, 1.7486e-15, 1}, {1, -2.22045e-16, 3.747e-16, -2.22045e-16, 1, -2.77556e-16, -5.55112e-16, 1.02696e-15, 1}, {1, 1.33227e-15, 5.55112e-16, -8.88178e-16, 1, -2.22045e-16, 4.44089e-16, -4.44089e-16, 1}, {1, 0, 1.11022e-16, 1.11022e-15, 1, -2.498e-16, 8.88178e-16, 8.88178e-16, 1}, {1, -1.31839e-15, 1.31839e-16, -4.996e-16, 1, -3.33067e-16, 3.33067e-16, 0, 1}, {1, 1.1241e-15, -3.40006e-16, -5.55112e-17, 1, 1.11022e-16, -1.66533e-16, -6.66134e-16, 1}, {1, 4.44089e-16, 2.22045e-16, -2.22045e-16, 1, 2.22045e-16, 2.22045e-16, 8.88178e-16, 1}, {1, -4.44089e-16, 4.44089e-16, 4.44089e-16, 1, 2.22045e-16, -2.22045e-16, -1.77636e-15, 1}, {1, -1.05471e-15, -6.66134e-16, 7.77156e-16, 1, -3.33067e-16, 4.44089e-16, 1.77636e-15, 1}, {1, 4.44089e-16, -5.55112e-17, -3.33067e-16, 1, -4.44089e-16, -4.44089e-16, -6.66134e-16, 1}, {1, -1.33227e-15, 0, 4.44089e-16, 1, -6.66134e-16, -8.88178e-16, -4.44089e-16, 1}, {1, 3.33067e-16, 6.66134e-16, 2.22045e-16, 1, -6.66134e-16, 0, 1.33227e-15, 1}, {1, 0, 4.44089e-16, -1.33227e-15, 1, -1.02327e-15, 4.44089e-16, -2.77556e-17, 1}, {1, 0, -2.22045e-16, -2.22045e-15, 1, 6.77626e-17, 4.44089e-16, 0, 1}, {1, 0, 8.88178e-16, -1.77636e-15, 1, -8.88178e-16, 0, 0, 1}, {1, 0, -4.44089e-16, -1.77636e-15, 1, -8.88178e-16, 4.44089e-16, 0, 1}, {1, -1.11022e-15, 1.11022e-16, -1.4988e-15, 1, 1.66533e-16, 6.66134e-16, -1.11022e-16, 1}, {1, 8.88178e-16, 2.22045e-16, -4.44089e-16, 1, 0, -1.33227e-15, -8.88178e-16, 1}, {1, -4.44089e-16, 1.11022e-16, -4.44089e-16, 1, 5.55112e-17, 0, -4.44089e-16, 1}, {1, 0, 1.66533e-16, -9.4369e-16, 1, 0, 0, 2.22045e-16, 1}, {1, -1.06859e-15, -6.31439e-16, -8.88178e-16, 1, -1.11022e-16, -2.22045e-16, 6.66134e-16, 1}, {1, 3.33067e-16, 7.56339e-16, 0, 1, 1.11022e-16, 5.55112e-16, -4.44089e-16, 1}, {1, 3.88578e-16, -8.32667e-17, -1.66533e-16, 1, -5.55112e-17, 8.88178e-16, -8.88178e-16, 1}, {1, -4.30211e-16, 3.50414e-16, -8.88178e-16, 1, -4.44089e-16, -7.77156e-16, -2.22045e-16, 1}, {1, 2.22045e-16, -4.44089e-16, 4.44089e-16, 1, 4.44089e-15, 1.66533e-16, -2.91434e-16, 1}, {1, 0, 2.66454e-15, -3.55271e-15, 1, -1.33227e-15, 6.93889e-16, -7.63278e-17, 1}, {1, -2.22045e-16, 8.88178e-16, 8.88178e-16, 1, -1.77636e-15, -1.05471e-15, 8.32667e-17, 1}, {1, -2.22045e-16, -8.88178e-16, 0, 1, 0, 2.22045e-16, 2.22045e-16, 1}, {1, 0, 4.44089e-16, 8.88178e-16, 1, 8.88178e-16, -8.88178e-16, 1.38778e-17, 1}, {1, 0, 1.77636e-15, -3.10862e-15, 1, -4.44089e-16, 3.55271e-15, 1.11022e-16, 1}, {1, 0, -8.88178e-16, -1.77636e-15, 1, 1.77636e-15, 0, -1.38778e-17, 1}, {1, 0, 0, 3.55271e-15, 1, 1.77636e-15, -1.77636e-15, -2.77556e-17, 1}, {1, 1.22125e-15, -2.77556e-17, 0, 1, -2.77556e-17, -1.88738e-15, -9.71445e-16, 1}, {1, 3.33067e-16, -1.11022e-16, 0, 1, 1.11022e-16, -1.05471e-15, -1.02696e-15, 1}, {1, 0, 0, -8.88178e-16, 1, -2.77556e-17, 6.66134e-16, -6.66134e-16, 1}, {1, 0, 0, 1.77636e-15, 1, 0, 4.44089e-16, -2.91434e-16, 1}, {1, -4.44089e-16, 2.77556e-17, -2.22045e-16, 1, -2.77556e-17, -2.22045e-16, -7.77156e-16, 1}, {1, 0, 2.77556e-17, 3.33067e-16, 1, -2.77556e-17, 3.88578e-16, 4.44089e-16, 1}, {1, 0, 1.11022e-16, 2.22045e-16, 1, 0, -2.22045e-16, 4.44089e-16, 1}, {1, -4.44089e-16, 2.77556e-17, -6.66134e-16, 1, -1.38778e-17, 4.44089e-16, -1.77636e-15, 1}, {1, -2.22045e-16, -2.22045e-16, -1.66533e-16, 1, 1.66533e-16, 5.55112e-16, 0, 1}, {1, 6.66134e-16, -5.55112e-17, 1.66533e-16, 1, -5.55112e-17, -4.44089e-16, -2.22045e-16, 1}, {1, -2.22045e-16, 1.11022e-16, 0, 1, -6.66134e-16, 0, 8.88178e-16, 1}, {1, 8.88178e-16, -2.22045e-16, 0, 1, 2.22045e-16, -4.44089e-16, 0, 1}, {1, 8.88178e-16, -1.38778e-16, -7.77156e-16, 1, -1.33227e-15, 0, -1.44329e-15, 1}, {1, 2.77556e-16, -1.08247e-15, 1.11022e-16, 1, 1.33227e-15, -1.55431e-15, 2.22045e-16, 1}, {1, -1.11022e-16, -2.22045e-16, -4.44089e-16, 1, -1.33227e-15, -4.44089e-16, 0, 1}, {1, -9.71445e-16, -6.93889e-17, 1.33227e-15, 1, 8.88178e-16, -5.55112e-16, -1.11022e-15, 1}, {1, 4.44089e-16, 2.77556e-17, 0, 1, 0, -2.22045e-15, 4.88498e-15, 1}, {1, 0, 0, 1.33227e-15, 1, 0, 5.77316e-15, 6.66134e-16, 1}, {1, -8.88178e-16, -2.77556e-17, 0, 1, 0, 5.32907e-15, 3.55271e-15, 1}, {1, 8.88178e-16, 0, 0, 1, 0, -1.77636e-15, 8.88178e-16, 1}, {1, 1.66533e-15, 2.22045e-15, -6.66134e-16, 1, -2.66454e-15, 5.55112e-16, -1.11022e-16, 1}, {1, 1.22125e-15, 1.77636e-15, -6.66134e-16, 1, 6.66134e-16, 1.66533e-16, 5.55112e-16, 1}, {1, -2.22045e-15, 1.77636e-15, 0, 1, 8.88178e-16, 0, 2.22045e-16, 1}, {1, 8.88178e-16, 0, 4.44089e-16, 1, 8.88178e-16, -6.66134e-16, 0, 1}, {1, -4.44089e-16, -1.9984e-15, 1.11022e-16, 1, -2.22045e-15, -2.22045e-16, -1.73472e-17, 1}, {1, -1.66533e-16, 1.11022e-15, -4.44089e-16, 1, -1.55431e-15, 9.71445e-17, -1.35308e-16, 1}, {1, -9.02056e-17, -7.77156e-16, 0, 1, 0, 1.11022e-16, 9.71445e-17, 1}, {1, 4.44089e-16, 2.66454e-15, 0, 1, 1.33227e-15, 0, -2.77556e-17, 1}, {1, 0, -3.60822e-16, -1.33227e-15, 1, -4.44089e-16, -1.55431e-15, -2.77556e-17, 1}, {1, 0, -5.27356e-16, 1.77636e-15, 1, 7.21645e-16, -2.44249e-15, 0, 1}, {1, 2.22045e-16, 6.66134e-16, 4.44089e-16, 1, 3.33067e-16, -2.66454e-15, 0, 1}, {1, 0, 8.32667e-17, 0, 1, 2.22045e-16, 0, 0, 1}, {1, -1.32533e-15, 4.51028e-17, 0, 1, 8.32667e-17, -2.77556e-17, -2.22045e-16, 1}, {1, -9.15934e-16, -1.38778e-17, 0, 1, -2.77556e-17, -2.77556e-17, -6.66134e-16, 1}, {1, 6.66134e-16, 3.05311e-16, 0, 1, 6.66134e-16, 0, -4.44089e-16, 1}, {1, -6.66134e-16, -4.16334e-17, 0, 1, 0, -2.77556e-17, 0, 1}, {1, 4.44089e-16, 0, -1.11022e-16, 1, 2.77556e-17, -1.66533e-16, -4.44089e-16, 1}, {1, -1.33227e-15, -2.77556e-17, -1.66533e-16, 1, 0, 2.77556e-16, 4.88498e-15, 1}, {1, 0, 0, -5.55112e-17, 1, 0, 4.44089e-16, -1.77636e-15, 1}, {1, 0, 0, 2.22045e-16, 1, -1.11022e-16, -6.66134e-16, 8.88178e-16, 1}, {1, 2.66454e-15, -3.33067e-16, -3.64292e-17, 1, -6.93889e-18, 0, -4.44089e-16, 1}, {1, -8.88178e-16, 0, 4.25007e-17, 1, 1.17961e-16, 5.55112e-17, -2.22045e-15, 1}, {1, 3.55271e-15, 4.44089e-16, 5.55112e-17, 1, 4.44089e-16, 1.11022e-16, 1.77636e-15, 1}, {1, 3.55271e-15, 4.44089e-16, 0, 1, 4.44089e-16, 0, 1.77636e-15, 1}, {1, -6.66134e-16, 2.22045e-16, -1.38778e-17, 1, 0, 2.77556e-17, -2.22045e-15, 1}, {1, 4.44089e-16, 4.996e-16, -2.63678e-16, 1, -2.22045e-16, -4.44089e-16, -1.33227e-15, 1}, {1, 0, -2.22045e-16, 0, 1, 2.22045e-16, 2.22045e-16, -1.77636e-15, 1}, {1, -1.55431e-15, 1.59595e-16, -6.59195e-17, 1, -1.59595e-16, 0, 0, 1}, {1, 8.32667e-17, -6.93889e-17, 9.02056e-17, 1, -5.55112e-17, -2.22045e-16, -2.22045e-16, 1}, {1, 5.27356e-16, 2.77556e-17, 1.17961e-16, 1, 0, -1.11022e-16, -4.44089e-16, 1}, {1, 4.44089e-16, 0, 1.11022e-16, 1, 2.22045e-16, 4.44089e-16, 4.44089e-16, 1}, {1, 8.88178e-16, 0, 2.22045e-16, 1, -1.66533e-16, 2.22045e-16, 8.88178e-16, 1}, {1, 2.22045e-16, -1.38778e-16, 0, 1, 4.44089e-16, 5.55112e-17, -2.22045e-16, 1}, {1, 8.88178e-16, -1.11022e-16, 5.55112e-17, 1, 2.77556e-16, 0, -4.44089e-16, 1}, {1, 1.07553e-16, 4.19803e-16, 0, 1, 6.66134e-16, 0, -1.77636e-15, 1}, {1, -4.44089e-16, -2.22045e-16, 0, 1, 1.66533e-16, 5.55112e-17, 0, 1}, {1, 3.33067e-15, -2.22045e-16, 2.77556e-17, 1, -3.88578e-16, -5.55112e-17, -3.10862e-15, 1}, {1, -4.44089e-16, -9.99201e-16, 0, 1, -6.10623e-16, 0, 3.55271e-15, 1}, {1, -2.66454e-15, 6.66134e-16, 1.11022e-16, 1, -2.22045e-16, 1.11022e-16, -1.77636e-15, 1}, {1, 0, -4.44089e-16, 0, 1, 5.55112e-17, 0, 4.44089e-16, 1}, {1, 3.33067e-16, 4.44089e-16, 5.55112e-17, 1, 6.66134e-16, -2.22045e-16, -3.33067e-16, 1}, {1, -1.66533e-16, 4.44089e-16, -4.996e-16, 1, -8.88178e-16, -6.66134e-16, -1.38778e-16, 1}, {1, -2.22045e-16, 0, 1.249e-15, 1, 1.9984e-15, 6.66134e-16, -1.11022e-16, 1}, {1, -3.33067e-16, 8.88178e-16, 0, 1, 0, 0, -1.11022e-16, 1}, {1, 0, -2.22045e-15, -3.55271e-15, 1, 8.88178e-16, 8.88178e-16, 1.11022e-16, 1}, {1, 5.55112e-17, -4.44089e-16, 0, 1, 8.88178e-16, -2.66454e-15, -1.38778e-16, 1}, {1, 8.32667e-17, -3.55271e-15, -5.32907e-15, 1, 0, 2.66454e-15, 1.38778e-16, 1}, {1, 2.77556e-17, -3.55271e-15, 0, 1, 3.55271e-15, 6.10623e-16, -5.55112e-17, 1}, {1, 0, -2.22045e-16, 1.66533e-16, 1, 4.44089e-16, 1.11022e-16, -1.77636e-15, 1}, {1, 5.55112e-16, -6.66134e-16, -2.05391e-15, 1, -4.44089e-16, -4.44089e-16, -1.33227e-15, 1}, {1, -1.55431e-15, -6.66134e-16, -4.44089e-16, 1, -7.10543e-15, 0, -2.22045e-16, 1}, {1, -1.77636e-15, 1.33227e-15, -6.66134e-16, 1, 0, -4.44089e-16, 0, 1}, {1, 0, 0, 1.11022e-15, 1, 8.88178e-16, 4.06285e-16, -1.57944e-15, 1}, {1, 0, 4.44089e-16, -1.9984e-15, 1, -4.44089e-16, 2.22475e-16, 4.72351e-16, 1}, {1, 8.88178e-16, 4.44089e-16, -8.88178e-16, 1, 0, -5.20129e-16, -7.85165e-17, 1}, {1, 0, 0, -2.22045e-16, 1, -8.88178e-16, 2.75257e-16, 1.70998e-15, 1}, {1, -1.77636e-15, -7.77156e-16, 1.38778e-16, 1, 1.05471e-15, -5.55112e-17, 2.22045e-16, 1}, {1, 8.88178e-16, -6.66134e-16, 3.33067e-16, 1, 3.88578e-16, 1.11022e-16, -5.55112e-16, 1}, {1, 8.88178e-16, -4.44089e-16, -2.77556e-17, 1, -2.22045e-16, -1.66533e-16, 0, 1}, {1, -8.88178e-16, -8.88178e-16, 0, 1, 8.88178e-16, 2.22045e-16, 1.88738e-15, 1}, {1, -4.44089e-16, -4.55434e-17, -1.11022e-16, 1, 1.11022e-16, -3.06234e-16, 7.22333e-16, 1}, {1, -2.22045e-16, -1.54349e-16, 2.22045e-16, 1, 5.55112e-17, -1.74285e-16, -2.88658e-15, 1}, {1, -8.88178e-16, 5.55112e-17, -2.22045e-16, 1, -1.11022e-16, -2.77556e-16, -1.77636e-15, 1}, {1, -1.77636e-15, 1.11022e-16, -2.22045e-16, 1, -1.11022e-16, 1.66533e-16, 0, 1}, {1, 2.22045e-16, 2.22045e-16, -2.22045e-16, 1, 1.11022e-16, 1.11022e-16, 1.33227e-15, 1}, {1, 4.44089e-16, -1.11022e-16, 1.66533e-16, 1, 7.77156e-16, 2.77556e-17, -8.88178e-16, 1}, {1, -1.77636e-15, 0, 1.66533e-16, 1, -4.44089e-16, 2.22045e-16, -2.22045e-16, 1}, {1, 4.44089e-16, -2.22045e-16, 1.66533e-16, 1, 2.22045e-16, 1.38778e-17, -1.77636e-15, 1}, {1, -4.13754e-17, 1.3179e-15, 0, 1, -2.22045e-16, 0, 0, 1}, {1, 2.60585e-18, 9.59361e-16, -5.55112e-17, 1, -2.22045e-16, 0, 0, 1}, {1, 3.14306e-17, 5.23429e-16, 2.22045e-16, 1, 0, -2.77556e-17, 0, 1}, {1, -2.53135e-17, 6.82473e-18, -1.66533e-16, 1, -1.77636e-15, 0, 0, 1}, {1, 5.55112e-17, 0, 8.32667e-17, 1, -1.11022e-16, 7.77156e-16, 5.55112e-17, 1}, {1, -1.11022e-16, 0, -7.91034e-16, 1, -8.32667e-16, 2.22045e-16, 1.94289e-16, 1}, {1, -1.38778e-16, -4.44089e-16, -5.27356e-16, 1, -5.55112e-17, -4.44089e-16, -2.22045e-16, 1}, {1, -1.11022e-16, 0, 1.66533e-16, 1, -1.11022e-15, 2.77556e-16, -2.77556e-17, 1}, {1, 3.60822e-16, 4.996e-15, -1.77636e-15, 1, -3.55271e-15, -1.11022e-16, 0, 1}, {1, 3.747e-16, 1.11022e-16, -8.88178e-16, 1, -8.88178e-16, 8.32667e-16, 2.08167e-16, 1}, {1, -2.22045e-16, 1.77636e-15, 0, 1, -3.55271e-15, 0, -1.66533e-16, 1}, {1, 2.22045e-16, 0, -8.88178e-16, 1, 1.77636e-15, -1.94289e-15, -1.66533e-16, 1}, {1, -2.77556e-16, 2.22045e-15, 8.88178e-16, 1, 1.77003e-15, 3.27483e-15, 6.32643e-17, 1}, {1, -2.22045e-16, 1.77636e-15, 1.9984e-15, 1, 8.67577e-16, -1.33227e-15, 6.32394e-18, 1}, {1, -1.11022e-16, 1.77636e-15, -8.88178e-16, 1, 6.21725e-15, 8.88178e-16, 5.55112e-17, 1}, {1, 0, -3.55271e-15, -1.77636e-15, 1, 8.88178e-16, -8.88178e-16, -1.11022e-16, 1}, {1, 1.11022e-16, 0, 2.22045e-16, 1, 0, -2.22045e-16, 2.22045e-16, 1}, {1, -4.996e-16, 0, 2.77556e-16, 1, -1.38778e-17, -1.33227e-15, -1.11022e-16, 1}, {1, 0, 0, 0, 1, 0, -4.44089e-16, -2.22045e-16, 1}, {1, 2.77556e-16, 2.77556e-17, 5.55112e-17, 1, 1.38778e-17, 0, 4.44089e-16, 1}, {1, -2.22045e-16, -8.32667e-17, 0, 1, -5.55112e-17, 0, 4.44089e-16, 1}, {1, 4.92661e-16, 0, 0, 1, 8.32667e-16, 0, 4.44089e-16, 1}, {1, -2.22045e-16, -1.38778e-16, 0, 1, -5.55112e-16, 0, 3.33067e-16, 1}, {1, -4.44089e-16, -5.55112e-17, 0, 1, -2.22045e-16, 0, -4.44089e-16, 1}, {1, 0, 2.22045e-16, 0, 1, -8.95414e-16, 1.33227e-15, 1.24092e-15, 1}, {1, 1.11022e-15, 1.33227e-15, 3.10862e-15, 1, 6.85127e-17, -8.88178e-16, -7.92758e-16, 1}, {1, 1.77636e-15, 1.77636e-15, -8.88178e-16, 1, -1.77636e-15, 8.88178e-16, 1.77636e-15, 1}, {1, 1.55431e-15, 8.88178e-16, 0, 1, -8.88178e-16, 0, 8.88178e-16, 1}, {1, 2.22045e-16, 4.16334e-17, 4.44089e-16, 1, 0, -4.44089e-16, 9.71445e-17, 1}, {1, -2.77556e-17, 0, -4.44089e-16, 1, 0, 1.11022e-15, 2.08167e-16, 1}, {1, -2.77556e-16, 1.38778e-17, 0, 1, 0, 8.88178e-16, 1.11022e-16, 1}, {1, -2.22045e-16, 1.38778e-17, -4.44089e-16, 1, 0, -1.11022e-15, -6.93889e-17, 1}, {1, -3.33067e-16, -9.15934e-16, -4.44089e-16, 1, -1.11022e-15, -2.66454e-15, 3.33067e-16, 1}, {1, 2.77556e-17, 1.38778e-15, 0, 1, 1.77636e-15, 0, 1.11022e-16, 1}, {1, 0, 0, -8.88178e-16, 1, -1.33227e-15, -1.77636e-15, -4.44089e-16, 1}, {1, -4.44089e-16, 0, -1.77636e-15, 1, -8.88178e-16, -8.88178e-16, 2.22045e-16, 1}, {1, 7.21645e-16, 9.4369e-16, 1.77636e-15, 1, 0, -8.88178e-16, -2.66454e-15, 1}, {1, -1.38778e-15, -6.10623e-16, 1.77636e-15, 1, 4.44089e-16, 0, 8.88178e-16, 1}, {1, 5.55112e-16, 0, 0, 1, 8.88178e-16, 1.77636e-15, -8.88178e-16, 1}, {1, 4.44089e-16, -1.77636e-15, -1.77636e-15, 1, -1.77636e-15, -8.88178e-16, 0, 1}, {1, 0, -4.44089e-16, 0, 1, -8.88178e-16, 6.66134e-16, 0, 1}, {1, 0, 2.66454e-15, 0, 1, 5.32907e-15, -3.33067e-16, 0, 1}, {1, 0, -1.77636e-15, -8.88178e-16, 1, 0, 4.44089e-16, 0, 1}, {1, 0, -2.22045e-16, 0, 1, 0, 5.55112e-16, 0, 1}, {1, -1.11022e-16, 0, -4.44089e-16, 1, -1.94494e-17, 0, 3.33067e-16, 1}, {1, 3.33067e-16, 0, 1.11022e-16, 1, -1.54929e-17, -1.11022e-16, -2.22045e-16, 1}, {1, 0, 0, 4.44089e-16, 1, -1.94494e-17, 2.22045e-16, -4.44089e-16, 1}, {1, -8.32667e-17, 0, -4.44089e-16, 1, -1.94229e-17, 2.22045e-16, 2.22045e-16, 1}, {1, -1.11022e-15, 5.55112e-16, 8.88178e-16, 1, 3.88578e-16, 4.21885e-15, 0, 1}, {1, -3.55271e-15, -6.10623e-16, -6.66134e-16, 1, -3.33067e-16, 1.9984e-15, 0, 1}, {1, 0, 0, -1.11022e-16, 1, -3.88578e-16, 3.55271e-15, 0, 1}, {1, -2.22045e-16, -3.33067e-16, 8.88178e-16, 1, -8.88178e-16, 2.44249e-15, 1.33227e-15, 1}, {1, 0, 4.44089e-16, -1.9984e-15, 1, -2.22045e-16, 8.88178e-16, -1.77636e-15, 1}, {1, 1.77636e-15, 8.88178e-16, -8.88178e-16, 1, -1.66533e-16, -5.32907e-15, -3.9968e-15, 1}, {1, 3.55271e-15, -8.88178e-16, -1.66533e-16, 1, -4.16334e-17, 0, -1.77636e-15, 1}, {1, -1.77636e-15, 0, -1.77636e-15, 1, 0, -1.77636e-15, 0, 1}, {1, -8.88178e-16, -6.10623e-16, 1.9984e-15, 1, 5.55112e-16, 2.66454e-15, 1.77636e-15, 1}, {1, 6.66134e-16, 0, 1.33227e-15, 1, -5.55112e-17, 5.32907e-15, 3.55271e-15, 1}, {1, -2.22045e-16, 0, -8.88178e-16, 1, -6.66134e-16, 0, 0, 1}, {1, -1.77636e-15, -8.88178e-16, -2.22045e-16, 1, 1.66533e-16, 0, -1.77636e-15, 1}, {1, 1.77636e-15, 3.67761e-16, 1.4988e-15, 1, 8.32667e-17, -1.77636e-15, -2.22045e-15, 1}, {1, 6.66134e-16, -4.16334e-16, 2.55351e-15, 1, -2.98372e-16, -2.66454e-15, -1.77636e-15, 1}, {1, 0, 5.55112e-16, 8.88178e-16, 1, 4.44089e-16, -3.55271e-15, -3.55271e-15, 1}, {1, -1.33227e-15, -2.77556e-16, -1.77636e-15, 1, -4.44089e-16, -1.77636e-15, -2.66454e-15, 1}, {1, 8.88178e-16, -1.33227e-15, 1.11022e-16, 1, 8.04912e-16, 0, 0, 1}, {1, -2.22045e-15, 1.33227e-15, -6.245e-16, 1, 9.71445e-16, 8.88178e-16, 1.33227e-15, 1}, {1, 0, 3.55271e-15, 4.44089e-16, 1, 1.33227e-15, -4.44089e-16, 0, 1}, {1, 8.88178e-16, 0, -1.11022e-15, 1, -1.77636e-15, -4.44089e-16, 0, 1}, {1, 4.44089e-16, 1.33227e-15, -3.88578e-16, 1, -1.44329e-15, 6.38378e-16, 2.22045e-16, 1}, {1, -8.88178e-16, 4.44089e-16, 9.71445e-16, 1, 4.44089e-16, -1.38778e-16, -3.33067e-16, 1}, {1, -1.77636e-15, -1.77636e-15, -1.11022e-16, 1, -4.44089e-16, 2.22045e-16, 1.77636e-15, 1}, {1, -1.77636e-15, 1.77636e-15, -4.44089e-16, 1, -8.88178e-16, 4.996e-16, 5.55112e-16, 1}, {1, 1.38778e-17, -3.05311e-16, 5.55112e-17, 1, -2.77556e-16, 3.33067e-16, -1.11022e-16, 1}, {1, 1.52656e-16, 4.57967e-16, -5.55112e-17, 1, -6.66134e-16, -5.55112e-17, 2.22045e-16, 1}, {1, 0, 2.22045e-16, 0, 1, 1.11022e-16, 0, -4.44089e-16, 1}, {1, 0, 0, 2.22045e-16, 1, 4.44089e-16, -1.249e-16, -2.63678e-16, 1}, {1, -2.08167e-16, -5.55112e-16, -5.55112e-17, 1, 5.55112e-16, -1.11022e-16, -1.11022e-16, 1}, {1, 3.46945e-17, -2.22045e-16, 1.66533e-16, 1, 4.44089e-16, 1.11022e-16, -2.77556e-17, 1}, {1, 1.38778e-17, -1.66533e-16, -4.44089e-16, 1, 0, -4.44089e-16, 2.77556e-17, 1}, {1, 7.28584e-17, -8.88178e-16, 0, 1, 0, 4.44089e-16, -5.55112e-17, 1}, {1, 4.85723e-17, 3.46945e-18, 0, 1, 8.88178e-16, 1.11022e-16, 2.77556e-17, 1}, {1, -1.73472e-17, 4.23273e-16, -5.55112e-17, 1, -3.33067e-16, -2.498e-16, 3.88578e-16, 1}, {1, -1.38778e-17, -1.38778e-16, -5.55112e-17, 1, -4.44089e-16, -1.66533e-16, -2.22045e-16, 1}, {1, -5.55112e-17, -4.996e-16, 1.66533e-16, 1, 5.55112e-17, 3.05311e-16, 2.22045e-16, 1}, {1, 4.44089e-16, 6.21725e-15, -5.09141e-16, 1, 1.31839e-15, -1.66533e-16, 0, 1}, {1, 4.44089e-16, 0, -1.55258e-16, 1, -1.38778e-16, -1.22125e-15, 4.44089e-15, 1}, {1, -1.77636e-15, 1.77636e-15, -2.77556e-16, 1, -2.66454e-15, 8.88178e-16, 7.10543e-15, 1}, {1, 1.77636e-15, 0, 1.66533e-16, 1, 1.77636e-15, -3.05311e-16, -1.33227e-15, 1}, {1, -1.55431e-15, 2.22045e-16, -8.32667e-16, 1, 8.88178e-16, 2.22045e-16, 0, 1}, {1, 1.11022e-15, 8.88178e-16, 4.71845e-16, 1, 1.77636e-15, 4.44089e-16, -8.88178e-16, 1}, {1, -8.32667e-17, 2.77556e-16, 2.22045e-16, 1, 3.55271e-15, 2.22045e-16, 3.55271e-15, 1}, {1, -8.88178e-16, 0, 1.66533e-16, 1, 3.55271e-15, -3.33067e-16, -1.77636e-15, 1}, {1, -1.77636e-15, -1.77636e-15, 0, 1, -4.44089e-16, 5.55112e-17, 0, 1}, {1, 4.44089e-16, 2.22045e-16, 0, 1, -2.44249e-15, -5.55112e-17, -2.22045e-15, 1}, {1, -6.66134e-16, -3.33067e-16, 2.22045e-16, 1, 1.77636e-15, 0, 0, 1}, {1, 0, 1.77636e-15, 0, 1, 1.33227e-15, 0, 4.44089e-16, 1}, {1, -5.55112e-17, -1.38778e-16, 6.66134e-16, 1, -2.22045e-16, 4.44089e-16, -6.66134e-16, 1}, {1, -4.16334e-16, 2.498e-16, -1.11022e-15, 1, 2.22045e-16, 0, 0, 1}, {1, -2.22045e-16, -8.88178e-16, -6.66134e-16, 1, 1.11022e-16, 1.77636e-15, 0, 1}, {1, -2.22045e-16, 0, 8.88178e-16, 1, 0, -4.44089e-16, 3.33067e-16, 1}, {1, 1.94289e-16, -2.77556e-16, 7.97973e-16, 1, -5.44269e-16, 1.77636e-15, 2.22045e-16, 1}, {1, 2.498e-16, 2.22045e-16, -3.25261e-16, 1, -3.26995e-16, -1.33227e-15, -5.55112e-16, 1}, {1, 8.88178e-16, 2.22045e-16, -3.43475e-16, 1, -6.03684e-16, -3.55271e-15, -8.88178e-16, 1}, {1, 0, -2.22045e-16, 3.96384e-16, 1, 3.44343e-16, -8.88178e-16, -4.44089e-16, 1}, {1, 2.22045e-15, 4.44089e-15, -1.9984e-15, 1, -1.9984e-15, 6.66134e-16, 2.66454e-15, 1}, {1, -4.21885e-15, 0, -8.88178e-16, 1, -2.22045e-15, 1.9984e-15, 1.11022e-15, 1}, {1, -5.32907e-15, -3.55271e-15, -8.88178e-16, 1, 8.88178e-16, -9.99201e-16, 1.88738e-15, 1}, {1, 2.44249e-15, 1.33227e-15, 4.44089e-16, 1, -6.66134e-16, 8.88178e-16, 1.77636e-15, 1}, {1, 0, 3.55271e-15, 3.38618e-15, 1, 2.498e-15, 2.22045e-16, 7.77156e-16, 1}, {1, 4.44089e-15, 2.66454e-15, -4.38538e-15, 1, 2.16493e-15, 1.11022e-16, 3.88578e-16, 1}, {1, -3.55271e-15, 3.55271e-15, 0, 1, -3.55271e-15, -1.11022e-15, -2.22045e-16, 1}, {1, 0, 8.88178e-16, -5.32907e-15, 1, -3.55271e-15, 1.11022e-16, 8.32667e-16, 1}, {1, -7.77156e-16, -1.33227e-15, -1.77636e-15, 1, -4.44089e-15, 1.77636e-15, 1.33227e-15, 1}, {1, -1.11022e-16, -1.44329e-15, -2.66454e-15, 1, -2.66454e-15, -8.88178e-16, -1.33227e-15, 1}, {1, 6.66134e-16, -4.44089e-16, 0, 1, 1.77636e-15, -8.88178e-16, 0, 1}, {1, -8.88178e-16, -8.88178e-16, 0, 1, 0, 1.77636e-15, -8.88178e-16, 1}, {1, -5.55112e-16, -4.02456e-16, 7.99361e-15, 1, -2.66454e-15, -2.22045e-15, 1.77636e-15, 1}, {1, 8.74301e-16, -4.45477e-15, -5.32907e-15, 1, -8.88178e-15, -4.44089e-16, 4.88498e-15, 1}, {1, -8.88178e-16, 0, -3.55271e-15, 1, 0, 0, 0, 1}, {1, 0, 0, 8.88178e-16, 1, -1.77636e-15, 0, -1.77636e-15, 1}, {1, 4.16334e-17, 1.02696e-15, -3.16414e-15, 1, -1.94289e-16, -1.33227e-15, 2.77556e-16, 1}, {1, -2.56739e-16, -5.55112e-16, -1.05471e-15, 1, -3.05311e-16, 4.44089e-16, 3.88578e-16, 1}, {1, -4.44089e-16, 2.22045e-16, 8.88178e-16, 1, 1.33227e-15, 0, 2.22045e-16, 1}, {1, 0, -2.22045e-16, -8.88178e-16, 1, -4.44089e-16, -1.05471e-15, 1.94289e-16, 1}, {1, 1.14492e-16, 1.01308e-15, 7.21645e-16, 1, 4.85723e-16, -1.33227e-15, 5.55112e-17, 1}, {1, 8.39606e-16, -3.19189e-16, 1.94289e-16, 1, 3.747e-16, 4.44089e-16, 5.55112e-17, 1}, {1, 0, 8.88178e-16, 4.44089e-16, 1, 3.33067e-16, -1.77636e-15, 1.11022e-16, 1}, {1, 5.55112e-16, 0, 8.32667e-16, 1, 7.35523e-16, 4.44089e-16, -5.55112e-17, 1}, {1, 1.76716e-16, 0, -6.66134e-16, 1, 0, -1.33227e-15, 0, 1}, {1, -1.13795e-16, 3.33067e-16, 5.55112e-16, 1, 4.44089e-16, -1.9984e-15, -5.55112e-17, 1}, {1, -2.77299e-18, -3.33067e-16, 8.88178e-16, 1, 8.88178e-16, 8.88178e-16, 0, 1}, {1, -1.15844e-16, 4.44089e-16, -8.88178e-16, 1, 0, 1.66533e-16, -5.55112e-16, 1}, {1, -1.66533e-16, 2.22045e-16, -1.38778e-16, 1, 3.60822e-16, 0, -7.77156e-16, 1}, {1, 0, -5.55112e-16, 1.94289e-16, 1, 2.63678e-16, 8.88178e-16, -2.22045e-16, 1}, {1, 1.11022e-16, -1.11022e-16, 1.33227e-15, 1, 2.22045e-16, 2.66454e-15, 2.22045e-16, 1}, {1, -2.22045e-16, 0, 4.44089e-16, 1, 8.88178e-16, 2.22045e-16, 8.32667e-17, 1}, {1, 0, -5.55112e-17, -2.56739e-16, 1, -1.15359e-16, 1.99146e-15, 7.84095e-16, 1}, {1, -1.11022e-15, -2.22045e-16, 8.32667e-17, 1, -3.9118e-16, -2.08167e-17, -7.97973e-16, 1}, {1, 4.44089e-16, 0, -1.33227e-15, 1, -5.55112e-17, -4.44089e-16, 6.66134e-16, 1}, {1, -4.44089e-16, -2.22045e-16, 1.33227e-15, 1, 1.11022e-16, 4.44089e-16, 4.44089e-16, 1}, {1, -6.66134e-16, 0, 8.88178e-16, 1, 0, 2.22045e-15, 4.44089e-16, 1}, {1, 4.44089e-16, 0, 0, 1, 0, -4.44089e-16, 4.44089e-16, 1}, {1, 8.88178e-16, -5.55112e-17, 0, 1, 0, 1.77636e-15, 0, 1}, {1, -8.88178e-16, 0, 0, 1, 0, -4.44089e-16, 6.66134e-16, 1}, {1, -5.55112e-17, 1.88738e-15, -1.77636e-15, 1, -2.66454e-15, 3.33067e-16, -1.11022e-16, 1}, {1, 2.22045e-16, -2.88658e-15, 1.33227e-15, 1, 4.44089e-16, 7.77156e-16, 1.11022e-16, 1}, {1, 1.11022e-16, 0, 4.21885e-15, 1, 1.4988e-15, -1.33227e-15, -2.77556e-16, 1}, {1, -5.55112e-17, 0, 0, 1, 0, 4.44089e-16, -2.22045e-16, 1}, {1, 4.44089e-16, 3.55271e-15, -4.44089e-16, 1, -4.73001e-16, -3.46945e-16, -1.01224e-16, 1}, {1, 5.55112e-16, -3.9968e-15, 8.88178e-16, 1, 7.88592e-16, -3.55271e-15, -6.69475e-17, 1}, {1, -8.88178e-16, -3.55271e-15, 8.88178e-16, 1, 8.88178e-16, 8.88178e-16, -8.88178e-16, 1}, {1, 3.33067e-16, -4.44089e-16, 8.88178e-16, 1, 2.66454e-15, 1.77636e-15, 2.22045e-16, 1}, {1, 0, 4.44089e-16, 1.77636e-15, 1, 8.88178e-16, 8.88178e-16, 0, 1}, {1, -2.22045e-16, 2.22045e-16, 0, 1, -4.44089e-16, -1.33227e-15, 2.22045e-16, 1}, {1, 2.77556e-17, -1.33227e-15, -1.33227e-15, 1, -4.44089e-16, 0, -1.11022e-16, 1}, {1, 0, 0, 1.77636e-15, 1, 0, -1.77636e-15, -5.55112e-17, 1}, {1, 0, -2.88658e-15, -3.10862e-15, 1, 2.22045e-16, 4.44089e-16, 2.22045e-16, 1}, {1, -3.33067e-16, 6.66134e-16, 2.66454e-15, 1, -4.44089e-16, -1.77636e-15, -5.55112e-16, 1}, {1, -4.44089e-16, 3.55271e-15, 1.33227e-15, 1, -8.88178e-16, 0, -4.44089e-16, 1}, {1, 0, 0, 8.88178e-16, 1, 1.77636e-15, 0, 4.44089e-16, 1}, {1, -6.93889e-17, -4.44089e-16, 3.33067e-16, 1, -6.66134e-16, 3.33067e-16, 1.38778e-16, 1}, {1, 5.55112e-17, -5.55112e-16, -7.63278e-16, 1, -1.22125e-15, 7.49401e-16, 1.38778e-16, 1}, {1, 3.46945e-18, -5.55112e-17, -1.11022e-16, 1, 8.88178e-16, 2.22045e-16, -2.22045e-16, 1}, {1, 1.11022e-16, 4.44089e-16, -5.55112e-17, 1, -6.66134e-16, 8.55219e-16, 1.43982e-16, 1}, {1, -1.66533e-16, -7.21645e-16, 6.66134e-16, 1, 1.11022e-16, -5.55112e-17, -5.55112e-17, 1}, {1, -5.55112e-17, 3.33067e-16, 2.22045e-16, 1, -6.66134e-16, -4.44089e-16, 0, 1}, {1, 1.94289e-16, -1.249e-16, 0, 1, 4.44089e-16, -8.88178e-16, 2.22045e-16, 1}, {1, -4.44089e-16, -2.22045e-16, 6.80012e-16, 1, -1.52656e-16, 0, -2.22045e-16, 1}, {1, 3.33067e-16, 6.66134e-16, -1.12381e-16, 1, -8.88178e-16, 4.44089e-16, -4.44089e-16, 1}, {1, 0, -9.99201e-16, 1.32396e-18, 1, -3.33067e-16, 1.11022e-16, -1.11022e-16, 1}, {1, 0, 0, 1.04111e-17, 1, -4.44089e-16, 3.33067e-16, 4.44089e-16, 1}, {1, -3.33067e-16, -5.55112e-16, 2.82279e-17, 1, -4.44089e-16, -1.11022e-16, -1.66533e-16, 1}, {1, 2.22045e-16, 4.44089e-16, 5.55112e-17, 1, 2.22045e-16, -2.22045e-16, -5.55112e-17, 1}, {1, 5.55112e-17, 4.44089e-16, 5.55112e-17, 1, -4.44089e-16, 0, -2.22045e-16, 1}, {1, 6.66134e-16, 4.44089e-16, -9.92156e-17, 1, -2.31383e-16, -4.44089e-16, 6.66134e-16, 1}, {1, 0, -2.22045e-16, -4.72231e-18, 1, -2.91307e-16, -4.44089e-16, 2.22045e-16, 1}, {1, 1.33227e-15, 0, 6.66134e-16, 1, 7.77156e-16, 1.9984e-15, -1.11022e-15, 1}, {1, -6.66134e-16, -3.33067e-16, -1.55431e-15, 1, 3.33067e-16, 6.66134e-16, 1.77636e-15, 1}, {1, 1.11022e-15, 6.66134e-16, 8.88178e-16, 1, 8.88178e-16, 0, 0, 1}, {1, -8.88178e-16, -4.44089e-16, -4.44089e-16, 1, -1.11022e-16, -1.38778e-15, 0, 1}, {1, -1.11022e-15, 4.44089e-16, 4.16334e-16, 1, 5.55112e-16, -2.22045e-16, -4.44089e-16, 1}, {1, 6.66134e-16, 2.22045e-16, 1.66533e-16, 1, -3.05311e-16, 0, 2.22045e-16, 1}, {1, -1.11022e-15, -1.55431e-15, 0, 1, 0, 0, 0, 1}, {1, -8.88178e-16, -8.88178e-16, -1.33227e-15, 1, -4.44089e-16, 2.22045e-16, -2.22045e-16, 1}, {1, -5.55112e-16, -1.11022e-16, 3.55271e-15, 1, 1.66533e-16, -3.33067e-15, -4.71845e-16, 1}, {1, 1.11022e-16, -5.55112e-17, 0, 1, -5.55112e-17, 2.88658e-15, 1.94289e-16, 1}, {1, -1.11022e-16, 1.94289e-16, 1.77636e-15, 1, -4.44089e-16, 5.32907e-15, 8.88178e-16, 1}, {1, 1.11022e-16, 0, 2.66454e-15, 1, 1.249e-16, -7.10543e-15, -5.55112e-17, 1}, {1, 5.55112e-17, 1.11022e-16, 2.66454e-15, 1, 4.44089e-16, -6.66134e-16, -4.44089e-16, 1}, {1, 1.11022e-16, 5.55112e-17, -4.44089e-15, 1, 2.77556e-16, 1.77636e-15, 1.11022e-16, 1}, {1, 4.44089e-16, -2.08167e-16, -5.32907e-15, 1, -4.44089e-16, 0, -4.44089e-16, 1}, {1, 0, -1.11022e-16, -1.77636e-15, 1, -1.11022e-16, 1.77636e-15, -2.22045e-16, 1}, {1, 0, 0, 1.31341e-15, 1, -2.95344e-16, -3.55271e-15, 0, 1}, {1, 0, 0, -1.41415e-15, 1, 1.63762e-16, 2.22045e-15, 0, 1}, {1, 0, 0, -1.77636e-15, 1, 0, 1.77636e-15, 0, 1}, {1, 0, 0, -1.77636e-15, 1, -2.22045e-16, -1.33227e-15, 0, 1}, {1, 0, -2.35515e-17, 1.11022e-15, 1, 0, 3.10862e-15, -3.05311e-16, 1}, {1, 2.77556e-17, -1.66533e-16, -2.66454e-15, 1, -1.66533e-16, 3.10862e-15, 1.80411e-16, 1}, {1, -5.55112e-17, 1.38778e-16, 1.77636e-15, 1, -1.11022e-16, -1.77636e-15, 0, 1}, {1, 1.11022e-16, 2.02697e-16, 8.88178e-16, 1, -5.55112e-17, -8.88178e-16, -6.10623e-16, 1}, {1, -2.66454e-15, -1.11022e-15, -1.11022e-15, 1, -4.44089e-16, 2.77556e-16, 7.49401e-16, 1}, {1, -8.88178e-16, 1.11022e-15, 0, 1, -4.44089e-16, -2.22045e-16, -4.71845e-16, 1}, {1, 3.55271e-15, 1.77636e-15, 4.44089e-16, 1, -8.88178e-16, 1.33227e-15, 1.77636e-15, 1}, {1, 1.67227e-15, 1.52309e-15, 0, 1, 0, 8.88178e-16, 8.88178e-16, 1}, {1, -8.88178e-16, 4.996e-16, -2.22045e-16, 1, -2.22045e-16, -4.44089e-16, -2.10942e-15, 1}, {1, 1.33227e-15, 2.88658e-15, 8.88178e-16, 1, 2.22045e-16, -1.44329e-15, -2.22045e-15, 1}, {1, -1.77636e-15, 0, -4.44089e-16, 1, 4.44089e-16, -8.88178e-16, 1.77636e-15, 1}, {1, 0, 8.88178e-16, 4.44089e-16, 1, 0, 4.44089e-16, 2.66454e-15, 1}, {1, -1.33227e-15, -1.11022e-16, -2.22045e-16, 1, 1.94289e-16, 0, -3.33067e-16, 1}, {1, 8.88178e-16, -3.33067e-16, 6.10623e-16, 1, 2.77556e-16, 0, 8.88178e-16, 1}, {1, 3.55271e-15, 0, 4.44089e-16, 1, -2.22045e-16, 2.77556e-16, 6.66134e-16, 1}, {1, -8.88178e-16, 1.11022e-16, 3.33067e-16, 1, 0, 2.22045e-16, 0, 1}, {1, 1.77636e-15, 1.55431e-15, 4.44089e-16, 1, -2.22045e-16, 5.55112e-17, -4.44089e-16, 1}, {1, 8.43769e-15, -4.71845e-16, -5.55112e-16, 1, 3.33067e-16, 1.11022e-16, -1.11022e-15, 1}, {1, -1.77636e-15, 4.44089e-16, -4.44089e-16, 1, -2.22045e-16, -1.66533e-16, 4.44089e-16, 1}, {1, -2.22045e-15, -5.55112e-17, 1.11022e-16, 1, 2.22045e-16, 2.22045e-16, 0, 1}, {1, -1.77636e-15, 4.44089e-16, 2.63678e-16, 1, 0, 1.11022e-16, -1.77636e-15, 1}, {1, -8.88178e-16, -2.22045e-16, -1.52656e-16, 1, -5.55112e-17, 0, -8.88178e-16, 1}, {1, -1.77636e-15, 1.11022e-16, -2.22045e-16, 1, 2.77556e-17, -1.11022e-16, -8.88178e-16, 1}, {1, 3.55271e-15, -1.66533e-16, 0, 1, 2.22045e-16, 4.44089e-16, 0, 1}, {1, 8.88178e-16, 2.77556e-16, 0, 1, 7.63278e-17, 2.498e-16, 7.21645e-16, 1}, {1, -1.77636e-15, 6.66134e-16, -6.52256e-16, 1, -8.60423e-16, -4.16334e-16, 5.55112e-17, 1}, {1, 0, 6.66134e-16, 2.22045e-16, 1, 1.11022e-16, 2.22045e-16, -6.66134e-16, 1}, {1, 8.88178e-16, -3.33067e-16, -4.44089e-16, 1, -3.33067e-16, -1.80411e-16, 8.32667e-16, 1}, {1, 8.88178e-16, 0, -1.44329e-15, 1, 2.22045e-16, 1.55431e-15, 1.33227e-15, 1}, {1, -1.33227e-15, 0, -6.66134e-16, 1, 1.94289e-16, -2.22045e-16, 8.88178e-16, 1}, {1, 1.77636e-15, 4.44089e-16, 0, 1, -6.66134e-16, -2.22045e-16, -4.44089e-16, 1}, {1, 8.88178e-16, -2.22045e-16, 4.44089e-16, 1, 0, -4.44089e-16, -8.88178e-16, 1}, {1, 1.33227e-15, -1.66533e-16, 4.16334e-16, 1, 9.02056e-17, 2.77556e-16, 1.66533e-16, 1}, {1, 0, -2.77556e-16, -1.94289e-16, 1, 7.63278e-17, -1.66533e-16, -6.66134e-16, 1}, {1, 8.88178e-16, 2.22045e-16, 1.33227e-15, 1, 2.22045e-16, 3.60822e-16, -7.21645e-16, 1}, {1, -1.11022e-15, -3.88578e-16, -1.77636e-15, 1, -2.22045e-16, 4.44089e-16, 0, 1}, {1, -1.77636e-15, -3.33067e-16, -4.44089e-16, 1, -2.22045e-16, 1.11022e-16, -1.33227e-15, 1}, {1, -3.10862e-15, -9.99201e-16, -8.88178e-16, 1, 6.66134e-16, -4.44089e-16, -8.88178e-16, 1}, {1, 1.77636e-15, 4.44089e-16, -1.77636e-15, 1, -8.88178e-16, 0, 0, 1}, {1, 0, 4.44089e-16, 0, 1, 2.22045e-16, 0, 0, 1}, {1, 2.22045e-16, 0, 9.99201e-16, 1, -1.66533e-16, -6.66134e-16, 1.9984e-15, 1}, {1, 2.22045e-15, 3.33067e-16, -3.88578e-16, 1, -3.46945e-16, 1.66533e-15, 8.88178e-16, 1}, {1, 8.88178e-16, 2.22045e-16, -8.88178e-16, 1, -6.66134e-16, 4.44089e-16, 8.88178e-16, 1}, {1, 4.44089e-16, -1.66533e-16, -8.88178e-16, 1, -2.22045e-16, 0, 8.88178e-16, 1}, {1, 6.66134e-16, -5.55112e-17, -3.33067e-16, 1, -1.11022e-16, -1.55431e-15, 2.22045e-16, 1}, {1, 2.22045e-16, -5.55112e-17, 3.33067e-16, 1, 1.66533e-16, 2.22045e-15, 1.66533e-16, 1}, {1, 0, 2.22045e-16, 0, 1, 1.66533e-16, 0, -4.44089e-16, 1}, {1, -2.22045e-16, 0, 0, 1, 0, 1.33227e-15, 3.33067e-16, 1}, {1, 1.66533e-16, -1.66533e-16, -2.22045e-16, 1, 1.66533e-16, -4.44089e-16, 1.66533e-16, 1}, {1, 2.22045e-16, -2.77556e-16, -8.88178e-16, 1, -2.22045e-16, -2.22045e-16, -7.77156e-16, 1}, {1, 0, -2.22045e-16, 7.77156e-16, 1, 2.77556e-16, 0, 0, 1}, {1, 0, -1.11022e-16, 0, 1, 0, -8.88178e-16, -1.11022e-16, 1}, {1, 1.22125e-15, 2.22045e-16, 8.88178e-16, 1, -1.17961e-15, -6.10623e-16, -3.05311e-16, 1}, {1, 3.33067e-16, 1.11022e-15, 1.77636e-15, 1, 1.45717e-15, -1.77636e-15, -4.16334e-16, 1}, {1, 0, -8.88178e-16, -1.77636e-15, 1, 8.88178e-16, -1.77636e-15, 2.22045e-16, 1}, {1, 0, 8.88178e-16, 0, 1, 0, 0, 4.44089e-16, 1}, {1, 1.11022e-16, 4.44089e-16, 2.22045e-15, 1, 6.66134e-16, 1.16573e-15, 2.77556e-16, 1}, {1, -6.66134e-16, 0, -4.44089e-16, 1, -1.33227e-15, 1.38778e-15, -1.11022e-16, 1}, {1, 0, 0, 0, 1, -8.88178e-16, 6.66134e-16, 1.11022e-16, 1}, {1, 0, 0, -3.60822e-16, 1, -2.22045e-15, 0, 2.22045e-16, 1}, {1, 2.38698e-15, -4.44089e-16, 1.77636e-15, 1, 2.10942e-15, 0, 7.77156e-16, 1}, {1, 7.21645e-16, 5.32907e-15, 8.88178e-16, 1, 3.21965e-15, -2.22045e-16, -6.66134e-16, 1}, {1, 8.88178e-16, -3.55271e-15, 0, 1, 0, -2.22045e-16, 0, 1}, {1, -4.44089e-16, 8.88178e-16, 0, 1, 8.88178e-16, -1.77636e-15, -4.44089e-16, 1}, {1, 6.66134e-16, 1.55431e-15, -6.66134e-16, 1, -2.22045e-16, -7.28584e-16, -2.56739e-16, 1}, {1, -3.33067e-16, 0, -2.66454e-15, 1, -8.88178e-16, -8.39606e-16, 2.5327e-16, 1}, {1, 0, 3.55271e-15, -4.44089e-16, 1, 0, -1.16573e-15, -9.15934e-16, 1}, {1, -3.88578e-16, -8.88178e-16, 0, 1, 0, -1.11022e-16, 2.77556e-16, 1}, {1, -3.33067e-16, -1.77636e-15, 0, 1, -6.66134e-16, 6.66134e-16, 4.16334e-17, 1}, {1, -2.77556e-17, -2.22045e-15, -3.33067e-16, 1, -4.44089e-16, 8.88178e-16, 6.245e-16, 1}, {1, 4.44089e-16, -3.55271e-15, -1.11022e-16, 1, 1.77636e-15, -1.77636e-15, -4.44089e-16, 1}, {1, 2.77556e-17, -5.55112e-16, 8.88178e-16, 1, 1.77636e-15, 4.44089e-16, 2.77556e-16, 1}, {1, -2.20543e-16, -1.38426e-15, 1.83894e-15, 1, 1.3913e-15, -1.11022e-16, -1.11022e-16, 1}, {1, 0, 0, 8.88178e-16, 1, 4.44089e-16, 2.22045e-16, -2.22045e-16, 1}, {1, 6.66134e-16, 8.88178e-16, 1.77636e-15, 1, 4.44089e-16, 0, -2.22045e-16, 1}, {1, 2.22045e-16, 4.44089e-16, 8.88178e-16, 1, 0, 0, -1.11022e-16, 1}, {1, -8.04912e-16, -6.66134e-16, -6.66134e-16, 1, 0, 8.88178e-16, 2.77556e-16, 1}, {1, -7.49401e-16, -8.88178e-16, -4.44089e-16, 1, -8.88178e-16, 6.10623e-16, 6.10623e-16, 1}, {1, -8.88178e-16, 8.88178e-16, -1.77636e-15, 1, -8.88178e-16, 0, 4.44089e-16, 1}, {1, 0, 1.77636e-15, 4.44089e-16, 1, 1.11022e-15, -2.22045e-16, 5.55112e-17, 1}, {1, 8.88178e-16, -3.33067e-16, -4.44089e-16, 1, 8.88178e-16, 0, -3.10862e-15, 1}, {1, 5.55112e-16, 6.66134e-16, -2.22045e-16, 1, 5.55112e-16, 0, -2.22045e-15, 1}, {1, 1.11022e-15, 2.22045e-16, 8.88178e-16, 1, 3.55271e-15, 4.44089e-16, 1.77636e-15, 1}, {1, 0, 0, 4.996e-16, 1, 1.55431e-15, 2.22045e-16, -8.88178e-16, 1}, {1, 2.22045e-16, 3.88578e-16, 8.32667e-16, 1, -3.747e-16, 6.10623e-16, 6.66134e-16, 1}, {1, 4.44089e-16, 6.66134e-16, 2.22045e-16, 1, 9.99201e-16, 3.33067e-16, 8.88178e-16, 1}, {1, 8.32667e-17, -4.09395e-16, 4.44089e-16, 1, -6.66134e-16, 0, -8.88178e-16, 1}, {1, 4.44089e-16, 4.44089e-16, 0, 1, 2.22045e-16, 6.10623e-16, 4.44089e-16, 1}, {1, 2.22045e-16, 1.64184e-25, -1.11022e-16, 1, 0, -2.22045e-16, -8.88178e-16, 1}, {1, 4.44089e-16, 1.11022e-15, -5.55112e-16, 1, -4.44089e-16, -1.11022e-16, 1.77636e-15, 1}, {1, -8.88178e-16, 4.44089e-16, 0, 1, -4.44089e-16, -4.44089e-16, 0, 1}, {1, 1.77636e-15, 0, -4.44089e-16, 1, 0, 0, 0, 1}, {1, -1.55431e-15, -1.33227e-15, -3.05311e-16, 1, -8.32667e-17, -1.11022e-16, 4.44089e-16, 1}, {1, 4.44089e-16, 5.55112e-16, -2.63678e-16, 1, 6.52256e-16, -6.66134e-16, -1.33227e-15, 1}, {1, -4.44089e-16, 3.33067e-16, 4.44089e-16, 1, -4.44089e-16, 4.44089e-16, 0, 1}, {1, -1.77636e-15, -4.44089e-16, 1.11022e-16, 1, 0, -5.55112e-16, 0, 1}, {1, 1.33227e-15, 2.44249e-15, 0, 1, 0, 5.55112e-17, -3.10862e-15, 1}, {1, 2.22045e-16, 1.33227e-15, 0, 1, -6.66134e-16, 1.11022e-16, -1.11022e-15, 1}, {1, -1.9984e-15, -1.11022e-16, 2.22045e-16, 1, -1.77636e-15, -2.22045e-16, -5.32907e-15, 1}, {1, 0, 0, 0, 1, 6.66134e-16, 0, -1.77636e-15, 1}, {1, 5.55112e-16, 0, -9.08995e-16, 1, -2.498e-15, -9.4369e-16, -3.55271e-15, 1}, {1, -1.38778e-15, 0, 4.51028e-16, 1, 2.33147e-15, 0, -8.88178e-16, 1}, {1, -2.22045e-16, -4.44089e-16, -5.55112e-16, 1, -1.77636e-15, 0, 3.55271e-15, 1}, {1, -1.11022e-16, -8.32667e-16, 3.33067e-16, 1, 1.77636e-15, 6.10623e-16, 0, 1}, {1, 1.44329e-15, 4.44089e-16, 1.66533e-16, 1, 2.22045e-15, 1.66533e-16, -2.22045e-16, 1}, {1, 8.88178e-16, -2.22045e-16, -1.66533e-16, 1, 1.33227e-15, 2.22045e-16, -2.22045e-16, 1}, {1, 4.44089e-16, -4.44089e-16, -2.22045e-16, 1, -1.77636e-15, -2.22045e-16, -1.77636e-15, 1}, {1, -1.33227e-15, -3.10862e-15, -1.11022e-16, 1, 0, 2.22045e-16, 6.66134e-16, 1}, {1, -1.11022e-15, -4.44089e-16, -6.93889e-16, 1, 2.22045e-15, 1.94289e-16, 2.22045e-15, 1}, {1, 1.11022e-15, 4.44089e-16, -7.77156e-16, 1, -8.88178e-16, 8.32667e-17, 0, 1}, {1, -8.88178e-16, 6.66134e-16, -4.44089e-16, 1, 1.77636e-15, 4.44089e-16, -1.77636e-15, 1}, {1, 8.88178e-16, 0, 6.66134e-16, 1, 8.88178e-16, 5.55112e-17, 2.22045e-15, 1}, {1, 0, -3.33067e-16, 9.71445e-17, 1, 3.19189e-16, 1.11022e-16, -1.55431e-15, 1}, {1, -1.33227e-15, 8.88178e-16, -2.15106e-16, 1, 4.44089e-16, -2.22045e-16, 6.66134e-16, 1}, {1, -8.88178e-16, -8.88178e-16, 2.22045e-16, 1, 0, 1.11022e-16, 4.44089e-16, 1}, {1, -2.22045e-16, -1.11022e-16, -4.44089e-16, 1, 1.33227e-15, 4.44089e-16, 0, 1}, {1, -2.22045e-15, 0, -5.89806e-16, 1, -5.75928e-16, -4.82253e-16, -9.01037e-16, 1}, {1, -2.66454e-15, 1.9984e-15, -6.03684e-16, 1, 1.73472e-16, 4.05925e-16, -1.28581e-17, 1}, {1, -1.77636e-15, -1.77636e-15, -1.33227e-15, 1, -4.44089e-16, 1.34026e-16, 2.38399e-16, 1}, {1, -1.33227e-15, -4.44089e-16, 0, 1, 1.77636e-15, 9.04793e-16, 3.14936e-16, 1}, {1, 0, -6.66134e-16, 5.55112e-16, 1, 3.33067e-16, 0, -1.60462e-17, 1}, {1, -2.22045e-16, -4.44089e-16, -1.44329e-15, 1, 3.33067e-16, 0, -6.76542e-17, 1}, {1, 0, 0, 0, 1, -8.88178e-16, -2.22045e-16, -1.43115e-17, 1}, {1, -5.55112e-17, 3.60822e-16, 0, 1, 0, 0, -1.64799e-17, 1}, {1, -2.22045e-16, -2.77556e-16, 1.40513e-15, 1, 3.08781e-16, 2.22045e-16, 0, 1}, {1, 1.11022e-16, -6.10623e-16, 8.08381e-16, 1, 7.18176e-16, -6.66134e-16, -1.66533e-16, 1}, {1, -2.22045e-16, -4.44089e-16, 0, 1, 1.11022e-16, -6.66134e-16, 0, 1}, {1, -7.21645e-16, -2.77556e-16, -2.22045e-16, 1, 2.22045e-16, -8.88178e-16, -2.22045e-16, 1}, {1, 4.44089e-16, 0, -5.68989e-16, 1, -8.76035e-17, -4.44089e-16, 3.9968e-15, 1}, {1, 1.77636e-15, -2.22045e-16, 1.16573e-15, 1, -3.81639e-17, -7.54952e-15, -5.32907e-15, 1}, {1, -1.77636e-15, 0, 0, 1, -5.55112e-17, -1.06581e-14, -1.06581e-14, 1}, {1, 0, 0, -1.77636e-15, 1, 1.11022e-16, 1.33227e-15, -4.44089e-16, 1}, {1, 4.44089e-16, 0, 8.88178e-16, 1, -1.11022e-16, 1.33227e-15, 2.22045e-15, 1}, {1, -2.66454e-15, -5.55112e-17, -4.44089e-16, 1, 0, 2.66454e-15, 0, 1}, {1, -4.44089e-16, -1.11022e-16, -1.77636e-15, 1, -1.94289e-16, -1.77636e-15, -1.77636e-15, 1}, {1, 1.77636e-15, -2.22045e-16, -8.88178e-16, 1, 0, 8.88178e-16, 0, 1}, {1, 7.77156e-16, 6.93889e-18, 0, 1, 0, 2.38698e-15, 9.4369e-16, 1}, {1, 1.66533e-16, -1.38778e-17, 0, 1, 0, -3.38618e-15, 2.77556e-16, 1}, {1, -6.66134e-16, -8.32667e-17, 3.55271e-15, 1, 0, 1.77636e-15, -3.55271e-15, 1}, {1, 1.83187e-15, 1.38778e-17, 4.44089e-15, 1, 0, 1.77636e-15, 0, 1}, {1, 1.77636e-15, 8.32667e-17, -4.996e-16, 1, 6.93889e-18, -1.16573e-15, 5.55112e-16, 1}, {1, -4.44089e-16, -2.77556e-17, 1.83187e-15, 1, 1.17961e-16, -4.44089e-16, 1.30451e-15, 1}, {1, 9.99201e-16, 5.55112e-17, -4.44089e-15, 1, -1.11022e-16, 0, 8.88178e-16, 1}, {1, -8.88178e-16, 0, -4.44089e-15, 1, -4.44089e-16, 0, -4.44089e-16, 1}, {1, 4.16334e-16, -8.88178e-16, 2.77556e-16, 1, 2.22045e-16, 1.11022e-15, -2.22045e-16, 1}, {1, -2.22045e-16, -1.9984e-15, -5.55112e-16, 1, -1.77636e-15, -4.44089e-16, 2.22045e-16, 1}, {1, 2.22045e-16, -8.88178e-16, 0, 1, 0, -4.44089e-16, 3.33067e-16, 1}, {1, 3.27863e-16, 4.996e-16, 0, 1, 0, 4.44089e-16, 0, 1}, {1, -1.66533e-16, -8.88178e-16, -1.11022e-16, 1, 3.33067e-16, -1.11022e-16, -3.33067e-16, 1}, {1, -5.55112e-17, -4.44089e-16, -7.77156e-16, 1, -5.55112e-17, -1.11022e-16, 5.55112e-17, 1}, {1, 0, 0, 4.44089e-16, 1, -2.22045e-16, -8.88178e-16, 1.11022e-16, 1}, {1, 1.66533e-16, -1.11022e-15, 0, 1, 0, 4.44089e-16, 5.55112e-17, 1}, {1, 8.88178e-16, 5.55112e-17, -1.44329e-15, 1, 0, 4.996e-16, -6.10623e-16, 1}, {1, -1.11022e-15, -8.32667e-17, -6.66134e-16, 1, 2.77556e-17, 2.60902e-15, 1.60982e-15, 1}, {1, 0, 1.11022e-16, 8.88178e-16, 1, 0, 1.33227e-15, 4.44089e-16, 1}, {1, 5.55112e-16, -3.33067e-16, 4.44089e-16, 1, -1.11022e-16, -6.66134e-16, -1.77636e-15, 1}, {1, -1.33227e-15, 0, 1.68762e-16, 1, -1.9456e-17, -1.22125e-15, 1.83187e-15, 1}, {1, -2.22045e-16, 0, 1.68762e-16, 1, -1.9456e-17, 8.88178e-16, 7.21645e-16, 1}, {1, 8.88178e-16, 0, -9.73313e-16, 1, -6.77982e-17, -2.66454e-15, 0, 1}, {1, -8.88178e-16, 0, 5.01367e-16, 1, -1.94892e-17, 8.88178e-16, 8.88178e-16, 1}, {1, 1.22125e-15, 5.82867e-16, -2.88658e-15, 1, -2.22045e-16, 4.16334e-17, -4.44089e-16, 1}, {1, 1.66533e-16, -2.498e-16, 2.22045e-16, 1, -5.55112e-16, -7.63278e-16, -2.22045e-15, 1}, {1, -1.22125e-15, -8.32667e-17, -8.88178e-16, 1, -1.33227e-15, 8.88178e-16, 0, 1}, {1, 1.11022e-15, -1.11022e-16, 2.22045e-16, 1, -1.66533e-16, 8.88178e-16, 5.32907e-15, 1}, {1, -8.88178e-16, -8.88178e-16, -8.88178e-16, 1, 1.11022e-16, -2.22045e-15, -1.55431e-15, 1}, {1, -3.55271e-15, -1.55431e-15, -8.88178e-16, 1, -3.33067e-16, -1.55431e-15, -1.77636e-15, 1}, {1, 0, 8.88178e-16, 1.77636e-15, 1, 6.66134e-16, 0, -1.77636e-15, 1}, {1, -1.77636e-15, 0, 0, 1, 0, 1.33227e-15, -1.11022e-15, 1}, {1, -1.11022e-15, -1.11022e-15, 7.00828e-16, 1, -2.46331e-16, 1.9984e-15, -2.22045e-16, 1}, {1, 8.88178e-16, 1.11022e-16, -2.28983e-16, 1, -4.16334e-17, -7.77156e-16, 4.44089e-16, 1}, {1, 1.77636e-15, 1.33227e-15, 1.66533e-16, 1, -5.55112e-17, -1.33227e-15, -8.88178e-16, 1}, {1, -1.9984e-15, 3.33067e-16, 3.33067e-16, 1, 7.21645e-16, -1.77636e-15, 0, 1}, {1, 2.22045e-16, 0, -2.22045e-16, 1, 4.44089e-16, 0, -8.88178e-16, 1}, {1, 1.9984e-15, 2.66454e-15, 2.22045e-16, 1, -8.88178e-16, -4.44089e-16, -8.88178e-16, 1}, {1, 8.88178e-16, 0, 4.44089e-16, 1, 0, 8.88178e-16, 0, 1}, {1, -2.22045e-16, 4.44089e-16, -8.88178e-16, 1, 0, 2.22045e-16, 0, 1}, {1, 2.63678e-16, -1.08247e-15, 6.74015e-17, 1, -7.20498e-16, 0, 0, 1}, {1, 9.71445e-17, -1.16573e-15, 2.59454e-16, 1, -1.19934e-15, 1.11022e-16, 8.88178e-16, 1}, {1, 0, 0, 9.88249e-16, 1, 2.7573e-17, -8.88178e-16, -4.44089e-16, 1}, {1, 4.44089e-16, -8.88178e-16, -6.43355e-17, 1, -3.6462e-16, -2.22045e-16, 4.44089e-16, 1}, {1, -4.44089e-16, -2.22045e-16, 2.1107e-17, 1, 1.11022e-16, 0, 2.66454e-15, 1}, {1, -6.66134e-16, 1.11022e-16, 4.73275e-18, 1, 3.33067e-16, 0, -1.33227e-15, 1}, {1, 1.77636e-15, 0, 6.82027e-18, 1, -5.55112e-16, 0, 2.66454e-15, 1}, {1, -6.66134e-16, -5.55112e-16, 3.00862e-17, 1, 0, 0, 5.55112e-17, 1}, {1, -2.77556e-17, -3.19189e-16, -1.11022e-16, 1, 2.22045e-16, -2.22045e-16, 0, 1}, {1, -2.77556e-17, -1.38778e-16, 2.22045e-16, 1, 2.22045e-16, -5.55112e-17, 8.88178e-16, 1}, {1, 0, -2.22045e-16, 0, 1, -4.44089e-16, -2.22045e-16, 0, 1}, {1, 4.44089e-16, 8.88178e-16, -2.22045e-16, 1, 0, -1.11022e-16, 0, 1}, {1, 1.22125e-15, -2.22045e-15, -3.747e-16, 1, 8.88178e-16, 2.77556e-16, 4.44089e-16, 1}, {1, 4.44089e-16, 1.33227e-15, -3.747e-16, 1, -1.77636e-15, -3.33067e-16, -1.33227e-15, 1}, {1, 0, -8.88178e-16, 4.44089e-16, 1, 3.55271e-15, 0, 4.44089e-16, 1}, {1, 1.11022e-16, 1.9984e-15, 0, 1, 0, 0, 4.44089e-16, 1}, {1, 5.82867e-16, 6.38378e-16, -1.66533e-16, 1, 4.44089e-16, 0, -4.44089e-16, 1}, {1, 1.22125e-15, 5.82867e-16, -3.88578e-16, 1, -4.44089e-16, 1.11022e-16, -6.66134e-16, 1}, {1, -8.88178e-16, -8.88178e-16, 2.22045e-16, 1, 8.88178e-16, -1.11022e-16, 4.44089e-16, 1}, {1, -4.44089e-16, -8.88178e-16, 1.52656e-16, 1, 9.99201e-16, -2.22045e-16, -1.33227e-15, 1}, {1, -2.22045e-16, 8.88178e-16, 0, 1, -2.22045e-16, 5.55112e-17, 1.22125e-15, 1}, {1, -6.66134e-16, -4.44089e-16, 1.66533e-16, 1, -1.33227e-15, -7.77156e-16, -1.11022e-15, 1}, {1, 3.33067e-16, 0, -4.44089e-16, 1, 1.77636e-15, 0, -8.88178e-16, 1}, {1, 1.77636e-15, 0, 0, 1, 8.88178e-16, -6.66134e-16, -8.88178e-16, 1}, {1, -2.63678e-16, -9.02056e-16, 0, 1, -5.55112e-16, 0, 1.55431e-15, 1}, {1, -1.11716e-15, -1.02696e-15, -1.11022e-16, 1, -9.99201e-16, 0, 4.44089e-16, 1}, {1, 3.88578e-16, 1.4988e-15, -2.77556e-17, 1, 2.66454e-15, 0, 0, 1}, {1, -1.11022e-15, 3.33067e-16, 0, 1, 1.77636e-15, 0, 3.33067e-16, 1}, {1, -2.08167e-16, -3.33067e-16, -6.66134e-16, 1, -1.11022e-16, -4.44089e-16, 5.55112e-17, 1}, {1, 1.66533e-16, -2.77556e-16, -2.22045e-16, 1, 0, 4.44089e-16, 2.22045e-16, 1}, {1, 2.22045e-16, 0, 0, 1, -4.44089e-16, 1.77636e-15, 1.11022e-16, 1}, {1, -1.66533e-16, -9.99201e-16, -2.22045e-16, 1, -5.55112e-17, 1.77636e-15, 2.22045e-16, 1}, {1, 0, 1.06859e-15, -4.44089e-16, 1, 6.66134e-16, -4.44089e-16, 2.77556e-17, 1}, {1, 0, 1.38778e-16, -1.77636e-15, 1, 5.55112e-16, -2.22045e-15, 1.11022e-16, 1}, {1, 0, 2.22045e-16, 0, 1, 8.88178e-16, -8.88178e-16, 2.77556e-17, 1}, {1, 0, -4.44089e-16, 8.88178e-16, 1, 4.44089e-16, 8.88178e-16, 0, 1}, {1, 4.44089e-16, 3.33067e-16, 4.59702e-16, 1, 7.09502e-16, -1.77636e-15, -2.22045e-16, 1}, {1, 1.11022e-16, 9.99201e-16, 1.03043e-15, 1, -4.75314e-16, -1.33227e-15, 1.11022e-16, 1}, {1, -2.22045e-16, -4.44089e-16, 0, 1, -6.66134e-16, -8.88178e-16, -5.55112e-16, 1}, {1, 8.32667e-17, -2.22045e-16, 4.44089e-16, 1, 2.22045e-16, 2.66454e-15, -2.22045e-16, 1}, {1, 1.1189e-16, 2.86229e-16, -6.66134e-16, 1, 4.44089e-16, -2.22045e-16, 2.77556e-16, 1}, {1, 2.68448e-16, -4.97866e-16, -1.44329e-15, 1, -6.66134e-16, -6.66134e-16, 0, 1}, {1, -6.66134e-16, -8.88178e-16, 0, 1, 2.22045e-16, 0, -2.22045e-16, 1}, {1, 2.22045e-16, 4.44089e-16, 7.77156e-16, 1, -8.32667e-17, -1.77636e-15, -1.11022e-16, 1}, {1, 2.77556e-17, -4.44089e-16, -2.33147e-15, 1, -4.44089e-16, -6.66134e-16, 0, 1}, {1, 0, 1.38778e-16, 5.55112e-16, 1, -6.10623e-16, 0, 0, 1}, {1, 0, -4.44089e-16, 8.88178e-16, 1, 0, -8.88178e-16, 0, 1}, {1, 0, -4.44089e-16, 0, 1, -1.11022e-16, 3.33067e-16, -2.77556e-17, 1}, {1, 1.38778e-16, 2.77556e-17, -1.94289e-16, 1, -2.77556e-17, -1.77636e-15, 1.11022e-16, 1}, {1, 2.9577e-16, 5.55112e-17, 4.71845e-16, 1, 0, 1.33227e-15, -1.11022e-16, 1}, {1, 0, -2.22045e-16, 0, 1, 2.22045e-16, -1.77636e-15, 0, 1}, {1, -1.11022e-16, -1.11022e-16, 8.88178e-16, 1, 5.55112e-17, 0, 6.66134e-16, 1}, {1, 2.91434e-16, -2.22045e-16, -4.44089e-16, 1, -2.77556e-16, 3.33067e-16, -7.77156e-16, 1}, {1, -1.11022e-16, -4.71845e-16, -8.88178e-16, 1, 3.33067e-16, 2.9976e-15, 4.44089e-16, 1}, {1, 1.52656e-16, -1.11022e-16, 8.88178e-16, 1, 4.44089e-16, 0, 0, 1}, {1, 1.11022e-16, 8.88178e-16, -3.33067e-16, 1, -3.88578e-16, 8.88178e-16, 0, 1}, {1, -3.33067e-16, 3.88578e-16, 5.55112e-17, 1, 6.93889e-18, 1.11022e-16, -1.11022e-16, 1}, {1, 3.33067e-16, 2.77556e-16, -1.4988e-15, 1, 1.8735e-16, 1.11022e-16, 7.77156e-16, 1}, {1, -1.94289e-16, 1.94289e-16, 1.33227e-15, 1, -3.33067e-16, -8.88178e-16, -6.66134e-16, 1}, {1, 0, -2.22045e-16, 8.88178e-16, 1, 1.11022e-16, -8.88178e-16, 1.66533e-16, 1}, {1, -6.66134e-16, -1.44329e-15, 3.33067e-16, 1, -2.22045e-16, 3.33067e-16, -1.249e-15, 1}, {1, -2.22045e-16, 0, 4.44089e-16, 1, -1.11022e-16, -7.49401e-16, -5.55112e-16, 1}, {1, 1.77636e-15, 0, 4.44089e-16, 1, -1.11022e-16, 8.88178e-16, 8.88178e-16, 1}, {1, -2.22045e-16, 4.44089e-16, 4.44089e-16, 1, 0, -1.33227e-15, 0, 1}, {1, -1.77636e-15, -4.44089e-16, 6.66134e-16, 1, -3.33067e-16, -3.55271e-15, -1.11022e-15, 1}, {1, 1.11022e-15, -2.10942e-15, 4.44089e-16, 1, -2.22045e-16, 2.22045e-16, 1.9984e-15, 1}, {1, 3.55271e-15, 0, 4.44089e-16, 1, -1.11022e-15, 1.77636e-15, 0, 1}, {1, 4.44089e-16, 3.33067e-16, 8.88178e-16, 1, 0, 6.10623e-16, -8.88178e-16, 1}, {1, 1.33227e-15, 6.66134e-16, -1.80411e-15, 1, -2.22045e-16, 1.05471e-15, 2.10942e-15, 1}, {1, 4.44089e-16, 6.66134e-16, 1.44329e-15, 1, 5.55112e-16, -3.33067e-16, -9.4369e-16, 1}, {1, 1.77636e-15, 4.44089e-16, -1.33227e-15, 1, -8.88178e-16, 0, 0, 1}, {1, 8.88178e-16, 0, 0, 1, 2.22045e-16, 4.44089e-16, 8.88178e-16, 1}, {1, -1.55431e-15, 2.22045e-16, 1.11022e-15, 1, 8.88178e-16, -6.66134e-16, -1.22125e-15, 1}, {1, 1.33227e-15, -1.11022e-16, -1.55431e-15, 1, 4.44089e-16, 6.66134e-16, 1.11022e-16, 1}, {1, -8.88178e-16, -4.44089e-16, -8.88178e-16, 1, -4.44089e-16, -2.66454e-15, -8.88178e-16, 1}, {1, -1.33227e-15, 4.44089e-16, 1.11022e-15, 1, 9.99201e-16, 0, 0, 1}}
-]
-
diff --git a/test/test_fe_engine/test_gradient_tetrahedron_4.verified b/test/test_fe_engine/test_gradient_tetrahedron_4.verified
index e0220c9bf..039eba426 100644
--- a/test/test_fe_engine/test_gradient_tetrahedron_4.verified
+++ b/test/test_fe_engine/test_gradient_tetrahedron_4.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 131
- + nb_component : 2
- + allocated size : 131
- + memory size : 2.05KiByte
- + values : {{0, 0}, {13, 11}, {23, 7}, {36, 18}, {31, 5}, {44, 16}, {54, 12}, {67, 23}, {57.25, 14.75}, {60.5, 17.5}, {63.75, 20.25}, {59.25, 21.75}, {51.5, 20.5}, {43.75, 19.25}, {32.75, 15.25}, {29.5, 12.5}, {26.25, 9.75}, {30.75, 8.25}, {38.5, 9.5}, {46.25, 10.75}, {7.75, 1.25}, {15.5, 2.5}, {23.25, 3.75}, {34.25, 7.75}, {37.5, 10.5}, {40.75, 13.25}, {36.25, 14.75}, {28.5, 13.5}, {20.75, 12.25}, {9.75, 8.25}, {6.5, 5.5}, {3.25, 2.75}, {17.25, 5.25}, {11.5, 3.5}, {5.75, 1.75}, {48.25, 10.25}, {42.5, 8.5}, {36.75, 6.75}, {61.25, 21.25}, {55.5, 19.5}, {49.75, 17.75}, {30.25, 16.25}, {24.5, 14.5}, {18.75, 12.75}, {49.0504, 14.0153}, {51.2148, 13.1141}, {56.9732, 17.9866}, {41.0324, 10.0151}, {46.7908, 14.8876}, {44.9874, 10.6014}, {56.1158, 16.1657}, {53.025, 17.4024}, {41.8967, 11.8381}, {52.5809, 12.5676}, {61.8914, 20.4457}, {36.1096, 7.5546}, {45.42, 15.4327}, {45, 15}, {54.745, 18.5437}, {41.0134, 16.3289}, {48.9866, 13.6711}, {35.255, 11.4563}, {49.0188, 18.4005}, {35.4167, 13.4543}, {54.5833, 16.5457}, {40.9812, 11.5995}, {38.5543, 17.1486}, {60.7561, 20.7295}, {29.2439, 9.2705}, {51.4457, 12.8514}, {22.0285, 8.0241}, {31.745, 11.5437}, {18.0134, 9.32887}, {25.9898, 6.67381}, {12.2581, 4.45903}, {26.022, 11.4032}, {12.4202, 6.45729}, {31.5868, 9.54867}, {17.9851, 4.60275}, {15.5543, 10.1486}, {37.7561, 13.7295}, {6.24441, 2.27095}, {28.4462, 5.85188}, {18, 9}, {25.9732, 12.9866}, {20.2148, 8.11409}, {15.7852, 9.88591}, {10.0268, 5.01339}, {22.0188, 12.4005}, {25.1102, 11.164}, {10.8898, 6.83603}, {13.9812, 5.59948}, {30.8914, 15.4457}, {21.5809, 7.56763}, {14.4191, 10.4324}, {5.10863, 2.55432}, {27, 6}, {25.2282, 6.44296}, {38.9598, 8.65774}, {15.0402, 3.34226}, {28.7718, 5.55704}, {17.4167, 4.45431}, {34.1102, 8.16397}, {36.5833, 7.54569}, {19.8898, 3.83603}, {24.1353, 6.71619}, {46.3371, 10.2971}, {7.66295, 1.70288}, {29.8647, 5.28381}, {39.9408, 16.9869}, {51.9532, 19.6563}, {38.2282, 17.443}, {41.7718, 16.557}, {28.0402, 14.3423}, {49.576, 18.5441}, {47.1029, 19.1623}, {32.8833, 14.8346}, {30.4101, 15.4528}, {59.336, 21.2969}, {37.1353, 17.7162}, {42.8647, 16.2838}, {20.6629, 12.7029}, {45.1759, 15.8856}, {39.5938, 12.0061}, {31.4708, 9.95054}, {35.9029, 13.7007}, {20.9022, 8.24591}, {28.7434, 10.6324}, {33.1755, 14.3826}, {27.8731, 11.7846}, {21.1179, 11.3435}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 341
- + nb_component : 6
- + allocated size : 341
- + memory size : 15.98KiByte
- + values : {{13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}, {13, 11, 23, 7, 31, 5}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 131
- + nb_component : 3
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0}, {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {1, 1, 1}, {0.25, 1, 1}, {0.5, 1, 1}, {0.75, 1, 1}, {1, 1, 0.75}, {1, 1, 0.5}, {1, 1, 0.25}, {0.75, 1, 0}, {0.5, 1, 0}, {0.25, 1, 0}, {0, 1, 0.25}, {0, 1, 0.5}, {0, 1, 0.75}, {0, 0, 0.25}, {0, 0, 0.5}, {0, 0, 0.75}, {0.25, 0, 1}, {0.5, 0, 1}, {0.75, 0, 1}, {1, 0, 0.75}, {1, 0, 0.5}, {1, 0, 0.25}, {0.75, 0, 0}, {0.5, 0, 0}, {0.25, 0, 0}, {0, 0.75, 0}, {0, 0.5, 0}, {0, 0.25, 0}, {0, 0.75, 1}, {0, 0.5, 1}, {0, 0.25, 1}, {1, 0.75, 1}, {1, 0.5, 1}, {1, 0.25, 1}, {1, 0.75, 0}, {1, 0.5, 0}, {1, 0.25, 0}, {0.5, 0.502191, 1}, {0.278522, 0.721478, 1}, {0.721478, 0.721478, 1}, {0.278522, 0.278765, 1}, {0.721478, 0.278765, 1}, {0.190862, 0.50027, 1}, {0.5, 0.809381, 1}, {0.809138, 0.50027, 1}, {0.5, 0.19116, 1}, {0.141906, 0.858094, 1}, {0.858094, 0.858094, 1}, {0.141906, 0.141947, 1}, {0.858094, 0.141947, 1}, {0.5, 1, 0.5}, {0.721478, 1, 0.721478}, {0.721478, 1, 0.278522}, {0.278522, 1, 0.721478}, {0.278522, 1, 0.278522}, {0.809138, 1, 0.5}, {0.5, 1, 0.190862}, {0.5, 1, 0.809138}, {0.190862, 1, 0.5}, {0.858094, 1, 0.141906}, {0.858094, 1, 0.858094}, {0.141906, 1, 0.141906}, {0.141906, 1, 0.858094}, {0.502191, 0, 0.5}, {0.721478, 0, 0.721478}, {0.721478, 0, 0.278522}, {0.278765, 0, 0.721478}, {0.278765, 0, 0.278522}, {0.809381, 0, 0.5}, {0.50027, 0, 0.190862}, {0.50027, 0, 0.809138}, {0.19116, 0, 0.5}, {0.858094, 0, 0.141906}, {0.858094, 0, 0.858094}, {0.141947, 0, 0.141906}, {0.141947, 0, 0.858094}, {0.5, 0.5, 0}, {0.721478, 0.721478, 0}, {0.278522, 0.721478, 0}, {0.721478, 0.278522, 0}, {0.278522, 0.278522, 0}, {0.809138, 0.5, 0}, {0.5, 0.809138, 0}, {0.5, 0.190862, 0}, {0.190862, 0.5, 0}, {0.858094, 0.858094, 0}, {0.141906, 0.858094, 0}, {0.858094, 0.141906, 0}, {0.141906, 0.141906, 0}, {0, 0.5, 0.5}, {0, 0.721478, 0.278522}, {0, 0.721478, 0.721478}, {0, 0.278522, 0.278522}, {0, 0.278522, 0.721478}, {0, 0.5, 0.190862}, {0, 0.809138, 0.5}, {0, 0.5, 0.809138}, {0, 0.190862, 0.5}, {0, 0.858094, 0.141906}, {0, 0.858094, 0.858094}, {0, 0.141906, 0.141906}, {0, 0.141906, 0.858094}, {1, 0.498905, 0.498905}, {1, 0.721356, 0.721356}, {1, 0.721478, 0.278522}, {1, 0.278522, 0.721478}, {1, 0.278522, 0.278522}, {1, 0.499865, 0.809003}, {1, 0.809003, 0.499865}, {1, 0.19074, 0.499878}, {1, 0.499878, 0.19074}, {1, 0.858073, 0.858073}, {1, 0.858094, 0.141906}, {1, 0.141906, 0.858094}, {1, 0.141906, 0.141906}, {0.714627, 0.67977, 0.65326}, {0.384087, 0.668738, 0.619989}, {0.423487, 0.335588, 0.588613}, {0.764413, 0.335588, 0.588613}, {0.423487, 0.335588, 0.247688}, {0.423487, 0.676512, 0.247688}, {0.764413, 0.676512, 0.247688}, {0.682024, 0.369799, 0.338757}, {0.815437, 0.205866, 0.186526}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 341
- + nb_component : 9
- + allocated size : 341
- + memory size : 23.98KiByte
- + values : {{1, 0, 0, 0, 1, 5.55112e-17, 0, 0, 1}, {1, 8.32667e-17, 0, 0, 1, 0, -4.44089e-16, -2.22045e-16, 1}, {1, 0, -2.22045e-16, -6.93889e-18, 1, -3.81639e-17, 0, 0, 1}, {1, 0, 0, 0, 1, -5.55112e-17, -4.44089e-16, -4.44089e-16, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 5.55112e-17, 5.55112e-17, -1.11022e-16, 1, -5.55112e-17, 0, -1.11022e-16, 1}, {1, 0, 1.11022e-16, 2.22045e-16, 1, -5.55112e-17, 1.11022e-16, 2.22045e-16, 1}, {1, 0, 0, -4.16334e-17, 1, 1.66533e-16, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 1.11022e-16, 1}, {1, 0, 0, 0, 1, -4.44089e-16, 1.11022e-16, -1.11022e-16, 1}, {1, -3.88578e-16, 0, -1.11022e-16, 1, 2.22045e-16, 1.11022e-16, 0, 1}, {1, 0, 8.88178e-16, -2.22045e-16, 1, -8.88178e-16, 1.66533e-16, 0, 1}, {1, -1.11022e-16, 0, 1.94289e-16, 1, -1.38778e-17, 4.44089e-16, 0, 1}, {1, 0, 0, -1.66533e-16, 1, 0, -1.11022e-16, 5.55112e-17, 1}, {1, 0, -2.22045e-16, 0, 1, -2.22045e-16, 1.11022e-16, 8.32667e-17, 1}, {1, -1.11022e-16, 0, 4.44089e-16, 1, 0, 0, 2.22045e-16, 1}, {1, 6.245e-17, 1.45717e-16, -4.44089e-16, 1, -2.22045e-16, -2.77556e-17, -9.54098e-17, 1}, {1, 0, 0, 8.32667e-17, 1, -1.66533e-16, -2.77556e-16, 5.55112e-17, 1}, {1, 1.11022e-16, 1.11022e-16, 0, 1, 0, 0, -2.22045e-16, 1}, {1, 2.22045e-16, 5.55112e-16, 0, 1, 0, 2.22045e-16, 1.11022e-16, 1}, {1, 0, 0, 0, 1, 1.11022e-16, 0, 0, 1}, {1, 5.55112e-17, 5.55112e-17, 1.11022e-16, 1, 1.66533e-16, 4.44089e-16, -2.22045e-16, 1}, {1, -4.44089e-16, -4.44089e-16, 0, 1, 8.88178e-16, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 6.93889e-17, 2.46331e-16, 1}, {1, 1.09288e-16, 3.1225e-17, 2.22045e-16, 1, 0, -1.11022e-16, 1.11022e-16, 1}, {1, 0, -4.44089e-16, 0, 1, 4.44089e-16, 0, 0, 1}, {1, 0, 0, -2.65806e-16, 1, -1.3611e-16, -8.76035e-17, 0, 1}, {1, 0, 0, -8.88178e-16, 1, -4.44089e-16, 8.88178e-16, 8.88178e-16, 1}, {1, 0, 0, 0, 1, 0, -4.44089e-16, 0, 1}, {1, 0, 0, 0, 1, 0, -8.88178e-16, -8.88178e-16, 1}, {1, 2.22045e-16, 4.44089e-16, -1.66533e-16, 1, -1.38778e-16, 0, 2.498e-16, 1}, {1, -3.91896e-16, -9.7974e-17, 1.56125e-17, 1, 2.87097e-16, 0, 0, 1}, {1, 0, -1.11022e-16, 1.11022e-16, 1, 1.11022e-16, 0, 0, 1}, {1, 0, 0, 1.11022e-16, 1, 0, -1.11022e-16, 0, 1}, {1, -4.44089e-16, 0, 0, 1, 0, 0, 0, 1}, {1, -1.11022e-16, 0, -2.22045e-16, 1, -5.55112e-17, 2.22045e-16, 5.55112e-17, 1}, {1, 1.11022e-16, 1.52656e-16, -4.44089e-16, 1, -4.44089e-16, -1.11022e-16, 5.55112e-17, 1}, {1, 0, 0, 0, 1, 2.22045e-16, -2.22045e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 0, -1.38778e-17, 8.32667e-16, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 5.55112e-16, 1.11022e-16, 0, 1, -5.55112e-17, 0, -2.22045e-16, 1}, {1, -2.22045e-16, 0, 0, 1, -2.22045e-16, 2.22045e-16, 0, 1}, {1, 0, 1.11022e-16, 0, 1, 0, 2.22045e-16, 0, 1}, {1, 0, 0, 1.38778e-16, 1, 1.70072e-16, -2.77556e-17, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 0, -4.44089e-16, 5.55112e-17, 1, 2.22045e-16, -1.11022e-16, 1.73472e-17, 1}, {1, -1.11022e-16, 4.44089e-16, 0, 1, -2.22045e-16, 0, 0, 1}, {1, -1.11022e-16, 0, -2.22045e-16, 1, 0, 0, 1.90783e-16, 1}, {1, 0, 0, 1.11022e-16, 1, 4.44089e-16, 0, 0, 1}, {1, 0, -4.44089e-16, 5.55112e-17, 1, -1.11022e-16, 0, 0, 1}, {1, 0, -5.55112e-17, 0, 1, 1.11022e-16, 2.22045e-16, 4.44089e-16, 1}, {1, 8.88178e-16, -2.22045e-16, 0, 1, 0, 2.22045e-16, -4.44089e-16, 1}, {1, -1.11022e-16, 0, 0, 1, -1.11022e-16, 0, 0, 1}, {1, 1.26038e-16, 4.44089e-16, 0, 1, -4.44089e-16, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 8.88178e-16, 0, 1}, {1, 0, 1.22997e-16, 1.11244e-16, 1, 7.65583e-17, 0, 0, 1}, {1, 0, 0, 0, 1, 2.22045e-16, 0, 2.77556e-17, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, -2.22045e-16, 0, -2.22045e-16, 1, -1.11022e-16, 0, 2.22045e-16, 1}, {1, -5.55112e-17, 2.22045e-16, -1.66533e-16, 1, 1.11022e-16, 1.66533e-16, 1.11022e-16, 1}, {1, 0, 0, 0, 1, -2.22045e-16, 0, 0, 1}, {1, 0, 0, -5.55112e-17, 1, 0, 0, 0, 1}, {1, 0, 5.55112e-17, 5.55112e-17, 1, 2.77556e-17, 0, 0, 1}, {1, 8.88178e-16, 0, 0, 1, 0, 0, 0, 1}, {1, 0, 0, -1.50921e-16, 1, 1.35308e-16, -1.11022e-16, 0, 1}, {1, 2.22045e-16, -2.77556e-16, -1.11022e-16, 1, -1.66533e-16, 0, 0, 1}, {1, 0, 2.22045e-16, 0, 1, 0, 0, -2.22045e-16, 1}, {1, -1.11022e-16, -5.55112e-17, -2.22045e-16, 1, 0, 2.22045e-16, 0, 1}, {1, 0, 0, 0, 1, -1.11022e-16, 0, 1.38778e-16, 1}, {1, 0, 0, 2.22045e-16, 1, -1.11022e-16, 2.22045e-16, 0, 1}, {1, 0, -1.26038e-16, 0, 1, 0, 0, 0, 1}, {1, 0, -2.22045e-16, -1.11022e-16, 1, -1.66533e-16, 0, -2.22045e-16, 1}, {1, -1.11022e-16, 0, -2.22045e-16, 1, 0, 0, 0, 1}, {1, 0, 0, -4.44089e-16, 1, 0, 0, 0, 1}, {1, -2.22045e-16, 1.50438e-16, -4.44089e-16, 1, 0, 1.11022e-16, -5.55112e-17, 1}, {1, 0, 0, -8.88178e-16, 1, 0, 4.44089e-16, 0, 1}, {1, -1.38778e-16, -1.11022e-16, 2.22045e-16, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 0, 2.22045e-16, 0, 1, 5.55112e-17, 0, 0, 1}, {1, 2.77556e-17, 1.66533e-16, 1.11022e-16, 1, 0, 1.80411e-16, 1.11022e-16, 1}, {1, 0, -5.55112e-17, 0, 1, 0, 0, 0, 1}, {1, 0, 1.48e-16, 1.66533e-16, 1, 1.11022e-16, 0, 0, 1}, {1, 0, 0, -9.06644e-17, 1, 0, -5.55112e-17, 7.88001e-17, 1}, {1, 1.11022e-16, -8.32667e-17, -1.11022e-16, 1, 4.16334e-17, 0, 2.22045e-16, 1}, {1, 0, 0, 0, 1, 0, 2.23904e-16, 7.43785e-18, 1}, {1, -6.30191e-17, 0, -4.44089e-16, 1, 0, 0, 0, 1}, {1, 0, 2.22045e-16, 1.11022e-16, 1, 0, -4.33681e-17, 0, 1}, {1, 4.44089e-16, 4.44089e-16, 0, 1, -4.44089e-16, -2.01228e-16, -5.20417e-18, 1}, {1, 2.22045e-16, -1.66533e-16, 0, 1, -1.11022e-16, -4.44089e-16, 2.22045e-16, 1}, {1, 1.34441e-16, -1.23165e-16, 0, 1, 0, 0, -5.55112e-17, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 2.22045e-16, 0, 0, 1, 0, 5.55112e-17, 0, 1}, {1, 0, 0, 2.22045e-16, 1, -5.55112e-17, 5.55112e-17, 8.32667e-17, 1}, {1, 0, 0, 0, 1, 0, 1.78677e-16, 2.5327e-16, 1}, {1, 0, 3.21718e-17, -5.55112e-17, 1, 1.11022e-16, 2.22045e-16, 0, 1}, {1, 2.22045e-16, 0, 0, 1, 0, -2.22045e-16, 0, 1}, {1, 2.22045e-16, 0, 0, 1, -8.88178e-16, -4.16334e-17, -8.32667e-17, 1}, {1, 0, 0, 0, 1, 0, 2.48065e-16, 0, 1}, {1, 0, 4.44089e-16, 0, 1, 1.11022e-16, 0, 0, 1}, {1, 0, 0, 4.44089e-16, 1, 0, 5.55112e-17, -6.93889e-17, 1}, {1, 0, 0, 0, 1, 0, -1.66533e-16, 8.32667e-17, 1}, {1, -1.11022e-16, 0, 0, 1, 2.22045e-16, 0, 2.22045e-16, 1}, {1, 0, -1.11022e-16, 0, 1, 1.11022e-16, 0, 0, 1}, {1, 1.11022e-16, 2.22045e-16, -7.28584e-17, 1, 1.38778e-16, 1.11022e-16, 0, 1}, {1, 0, 0, 1.11022e-16, 1, 1.80411e-16, -2.22045e-16, 0, 1}, {1, 0, 0, -7.58731e-17, 1, 1.02868e-16, -2.77556e-17, 2.77556e-17, 1}, {1, 0, 0, 8.88178e-16, 1, 0, 0, -1.11022e-16, 1}, {1, 0, 0, 0, 1, 0, 0, -4.44089e-16, 1}, {1, 5.55112e-17, -2.77556e-17, 0, 1, 2.22045e-16, 0, -2.22045e-16, 1}, {1, 0, 5.55112e-17, 0, 1, -1.11022e-16, 0, 1.66533e-16, 1}, {1, 0, 0, -1.11022e-16, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 0, -1.11022e-16, 1}, {1, 0, 0, -8.83958e-17, 1, -3.45724e-18, 0, -1.66533e-16, 1}, {1, 0, -2.22045e-16, 2.28983e-16, 1, -1.31839e-16, 0, 0, 1}, {1, -6.93889e-17, -5.55112e-17, 1.38778e-17, 1, 1.11022e-16, 0, 0, 1}, {1, 2.22045e-16, 0, 1.11022e-16, 1, 0, 0, 0, 1}, {1, 0, 4.44089e-16, 0, 1, -2.22045e-16, 0, 8.32667e-17, 1}, {1, 0, 0, 1.11022e-16, 1, 0, 2.22045e-16, 0, 1}, {1, -4.95182e-18, -1.91025e-17, 2.22045e-16, 1, 0, -4.44089e-16, 0, 1}, {1, 0, 0, 4.44089e-16, 1, 0, 4.44089e-16, 0, 1}, {1, 0, -4.44089e-16, 0, 1, 1.11022e-16, -1.9082e-17, 0, 1}, {1, 0, 8.88178e-16, 4.44089e-16, 1, 4.44089e-16, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 4.44089e-16, 1}, {1, 0, -1.11022e-16, 0, 1, 0, 5.27356e-16, 1.66533e-16, 1}, {1, -4.44089e-16, -4.44089e-16, 0, 1, 0, 0, 4.44089e-16, 1}, {1, 5.55112e-17, -1.66533e-16, -1.11022e-16, 1, -4.44089e-16, 5.55112e-17, 1.66533e-16, 1}, {1, 0, -5.55112e-17, 0, 1, -1.11022e-16, 0, -2.22045e-16, 1}, {1, 0, 0, 1.11022e-16, 1, 4.44089e-16, 0, -4.44089e-16, 1}, {1, -3.88578e-16, 2.22045e-16, -4.44089e-16, 1, 0, 1.11022e-16, 1.11022e-16, 1}, {1, -2.22045e-16, 0, 2.22045e-16, 1, -5.55112e-17, -5.55112e-17, 1.66533e-16, 1}, {1, -2.77556e-17, 1.11022e-16, 1.66533e-16, 1, 0, -1.11022e-16, -5.55112e-17, 1}, {1, 1.11022e-16, -5.55112e-17, 0, 1, 5.55112e-17, 1.11022e-16, 1.11022e-16, 1}, {1, 0, 0, 0, 1, 4.44089e-16, 3.33067e-16, 1.11022e-16, 1}, {1, 5.55112e-17, 5.55112e-17, 0, 1, 0, 3.88578e-16, 2.22045e-16, 1}, {1, -6.245e-17, -6.59195e-17, 0, 1, 0, 0, 0, 1}, {1, 2.22045e-16, 0, 2.22045e-16, 1, -6.66134e-16, 1.66533e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, -2.22045e-16, 0, -1.11022e-16, 1, 4.44089e-16, -3.747e-16, -2.08167e-16, 1}, {1, -4.44089e-16, -4.44089e-16, -4.44089e-16, 1, -4.44089e-16, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 0, -4.44089e-16, 1}, {1, 3.33067e-16, 2.22045e-16, 4.44089e-16, 1, 0, -1.11022e-16, -2.22045e-16, 1}, {1, 2.22045e-16, 4.44089e-16, 0, 1, -8.88178e-16, 0, 0, 1}, {1, 2.17708e-16, 3.1225e-17, 0, 1, 2.22045e-16, -2.22045e-16, 1.11022e-16, 1}, {1, -1.11022e-16, -5.55112e-17, -4.44089e-16, 1, 0, 0, -4.44089e-16, 1}, {1, 0, 0, 0, 1, 1.11022e-16, 0, 0, 1}, {1, 0, 0, 1.38778e-17, 1, -1.59595e-16, 2.08167e-16, -9.71445e-17, 1}, {1, 1.11022e-16, 4.44089e-16, 0, 1, 0, 0, 0, 1}, {1, 0, 0, -5.55112e-17, 1, -2.22045e-16, 5.55112e-17, 3.33067e-16, 1}, {1, -1.23689e-16, 0, 1.38778e-17, 1, 0, 0, 0, 1}, {1, 0, -8.88178e-16, 2.77556e-17, 1, -1.11022e-16, -2.77556e-17, 0, 1}, {1, 0, 0, 0, 1, 4.44089e-16, -4.44089e-16, 0, 1}, {1, -6.30191e-17, 0, 0, 1, 0, 0, 0, 1}, {1, -4.53726e-17, -1.57211e-16, 0, 1, 0, 0, 0, 1}, {1, 1.11022e-16, 0, 0, 1, 0, -2.22045e-16, -1.38778e-17, 1}, {1, -1.11022e-16, 0, 2.22045e-16, 1, 0, 0, 2.22045e-16, 1}, {1, 0, 0, 0, 1, 0, 5.41496e-17, 0, 1}, {1, -2.22045e-16, 0, 0, 1, 0, -5.55112e-17, 0, 1}, {1, 0, 0, 0, 1, 0, 8.88178e-16, 8.88178e-16, 1}, {1, 0, -2.52076e-16, 0, 1, 0, 0, -4.44089e-16, 1}, {1, -1.11022e-16, -4.44089e-16, 0, 1, 0, 0, 2.22045e-16, 1}, {1, 0, -2.22045e-16, 2.04697e-16, 1, -3.46945e-17, 0, 0, 1}, {1, -2.65838e-16, 0, 0, 1, 0, 0, -2.65838e-16, 1}, {1, -4.18285e-16, -4.02456e-16, 0, 1, 0, -3.34092e-17, 2.65806e-16, 1}, {1, 1.11022e-16, 0, -2.22045e-16, 1, -2.22045e-16, 0, -1.11022e-16, 1}, {1, 0, -1.11022e-16, -5.55112e-16, 1, -1.11022e-16, -4.44089e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 1.11022e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, -2.22045e-16, -3.99526e-17, 0, 1, 0, 2.22045e-16, 2.22045e-16, 1}, {1, 0, 2.22045e-16, 0, 1, 0, 0, 0, 1}, {1, 5.55112e-17, 0, 0, 1, 4.85723e-17, 0, 0, 1}, {1, 5.55112e-17, -5.55112e-17, -2.22045e-16, 1, -5.55112e-17, -8.88178e-16, -4.44089e-16, 1}, {1, -4.44089e-16, 0, 2.22045e-16, 1, 0, 4.996e-16, 0, 1}, {1, 5.55112e-17, 5.55112e-17, 4.44089e-16, 1, 1.11022e-16, 0, 0, 1}, {1, -1.11022e-16, 0, 4.44089e-16, 1, 0, 0, 0, 1}, {1, 0, 4.44089e-16, 0, 1, 4.44089e-16, 8.47598e-17, 0, 1}, {1, 2.22045e-16, 0, 1.26038e-16, 1, 0, 0, 0, 1}, {1, 2.22045e-16, 0, 0, 1, -2.24604e-16, 0, -4.44089e-16, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 1.11022e-16, 0, 0, 1, 0, 0, 2.22045e-16, 1}, {1, 0, 0, 0, 1, -2.22045e-16, 0, -4.44089e-16, 1}, {1, 0, 6.93889e-17, 0, 1, 0, 0, -1.38778e-16, 1}, {1, 0, 0, 0, 1, 0, 0, 1.66533e-16, 1}, {1, 0, 0, 0, 1, 0, 8.88178e-16, 1.11022e-16, 1}, {1, 0, -4.44089e-16, 0, 1, -4.44089e-16, 0, 0, 1}, {1, 0, 0, 4.44089e-16, 1, 5.55112e-17, 0, -2.22045e-16, 1}, {1, 2.22045e-16, -2.22045e-16, 0, 1, 0, 1.17653e-16, 1.97864e-16, 1}, {1, 2.22045e-16, 2.22045e-16, 0, 1, 8.88178e-16, 1.11022e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 4.44089e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, -1.11022e-16, -1.11022e-16, 0, 1, 0, 1.33227e-15, -1.11022e-16, 1}, {1, 0, 0, -4.44089e-16, 1, 0, 8.88178e-16, 8.88178e-16, 1}, {1, 0, 0, 0, 1, 2.22045e-16, 0, 0, 1}, {1, 2.22045e-16, 0, 0, 1, 0, 0, 0, 1}, {1, 0, 4.44089e-16, 0, 1, 0, -2.22045e-16, -1.11022e-16, 1}, {1, -2.22045e-16, -4.44089e-16, 0, 1, 0, 0, -2.22045e-16, 1}, {1, 0, 4.30682e-17, 0, 1, 0, 0, 0, 1}, {1, 0, 1.09995e-16, 0, 1, 1.09995e-16, -1.11022e-16, 1.11022e-16, 1}, {1, -4.44089e-16, -2.22045e-16, 0, 1, -1.11022e-16, -4.44089e-16, -4.44089e-16, 1}, {1, 0, 0, 0, 1, 0, 1.11022e-16, 2.22045e-16, 1}, {1, -2.22045e-16, -2.22045e-16, 1.11022e-16, 1, 2.22045e-16, 2.22045e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 0, -4.70394e-17, 2.22045e-16, 1, 1.11022e-16, 0, 0, 1}, {1, -1.38778e-16, -1.66533e-16, 1.11022e-16, 1, 0, 2.22045e-16, 2.22045e-16, 1}, {1, 1.11022e-16, 4.44089e-16, 4.44089e-16, 1, 0, 2.22045e-16, -2.77556e-17, 1}, {1, 0, 0, 0, 1, 0, 4.44089e-16, 0, 1}, {1, 2.22045e-16, 0, -4.44089e-16, 1, 0, 6.66134e-16, 1.11022e-16, 1}, {1, -2.22045e-16, 0, -1.11022e-16, 1, 0, 2.22045e-16, 2.22045e-16, 1}, {1, 0, 1.11022e-16, 0, 1, -1.11022e-16, -2.22045e-16, 0, 1}, {1, -8.32667e-17, 5.55112e-17, 0, 1, 2.22045e-16, 0, 4.44089e-16, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 4.44089e-16, 0, 0, 1, 0, 1.11022e-16, -5.55112e-17, 1}, {1, 0, 4.44089e-16, -1.11022e-16, 1, 4.44089e-16, 2.77556e-17, 2.77556e-17, 1}, {1, 0, 0, -1.83881e-16, 1, -1.11022e-16, 0, 0, 1}, {1, 3.33067e-16, 0, 0, 1, 1.11022e-16, 0, 2.77556e-17, 1}, {1, 0, 0, 0, 1, 0, 2.22045e-16, 0, 1}, {1, -4.44089e-16, 0, 0, 1, 0, 0, 4.44089e-16, 1}, {1, 0, 0, 2.77556e-17, 1, 0, 0, -4.44089e-16, 1}, {1, -2.22045e-16, 1.11022e-16, 2.77556e-16, 1, -2.77556e-17, 2.22045e-16, -2.22045e-16, 1}, {1, -1.11022e-16, -2.77556e-17, 0, 1, -2.22045e-16, 0, -2.22045e-16, 1}, {1, -8.88178e-16, 0, 0, 1, 1.11022e-16, 0, 0, 1}, {1, -1.11022e-16, -4.44089e-16, 1.38778e-16, 1, -1.66533e-16, -2.77556e-17, 0, 1}, {1, 6.30371e-17, 4.44089e-16, 0, 1, -8.88178e-16, 0, 0, 1}, {1, 2.22045e-16, -2.22045e-16, 0, 1, 0, -1.11022e-16, 0, 1}, {1, 0, 0, 4.44089e-16, 1, 0, -1.56835e-16, 2.60837e-16, 1}, {1, 0, 0, 2.22045e-16, 1, 1.11022e-16, 0, -2.22045e-16, 1}, {1, 0, 1.11022e-16, 0, 1, 0, 1.11022e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 0, 5.19189e-16, -1.69784e-16, 1, -4.44089e-16, 0, 0, 1}, {1, 1.11022e-16, 0, 1.38778e-16, 1, 2.22045e-16, 0, 0, 1}, {1, -2.22045e-16, 0, 0, 1, 0, 2.22045e-16, 0, 1}, {1, 1.11022e-16, 4.44089e-16, 0, 1, 0, 0, 0, 1}, {1, 0, 0, 1.11022e-16, 1, 0, 4.44089e-16, 0, 1}, {1, 0, 6.93889e-17, 0, 1, 0, 0, 2.22045e-16, 1}, {1, 0, -4.44089e-16, 0, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 0, 2.22045e-16, 2.22045e-16, 1, 1.11022e-16, 0, -2.22045e-16, 1}, {1, -1.11022e-16, 0, 2.22045e-16, 1, 2.22045e-16, -4.44089e-16, 0, 1}, {1, 0, 0, -2.22045e-16, 1, 0, -2.22045e-16, 0, 1}, {1, 0, 0, -8.85257e-17, 1, 0, 5.55112e-17, -1.66533e-16, 1}, {1, 0, -1.11022e-16, -3.88578e-16, 1, 0, -4.44089e-16, 0, 1}, {1, 0, 0, -1.11022e-16, 1, -1.38778e-16, 0, 0, 1}, {1, 0, 5.55112e-17, -4.44089e-16, 1, 0, 8.88178e-16, -8.88178e-16, 1}, {1, 4.44089e-16, 1.66533e-16, 0, 1, -1.11022e-16, 0, 1.77636e-15, 1}, {1, 8.88178e-16, 0, 2.22045e-16, 1, 4.44089e-16, 0, 0, 1}, {1, 0, 4.44089e-16, 1.11022e-16, 1, 2.22045e-16, 0, 0, 1}, {1, 0, 0, 0, 1, 2.77556e-17, 2.22045e-16, -2.22045e-16, 1}, {1, 1.0595e-17, -5.55112e-17, -2.22045e-16, 1, -8.88178e-16, 0, 1.6952e-16, 1}, {1, 1.38778e-17, 6.93889e-17, -1.23797e-16, 1, 2.22045e-16, 0, -1.11022e-16, 1}, {1, 0, 4.44089e-16, 0, 1, 0, 2.22045e-16, 0, 1}, {1, -1.11022e-16, -1.11022e-16, -2.22045e-16, 1, 0, 1.11022e-16, 0, 1}, {1, -3.33067e-16, -8.88178e-16, 0, 1, -4.44089e-16, 0, 0, 1}, {1, -1.11022e-16, 0, -2.30718e-16, 1, -1.73472e-18, -4.44089e-16, 0, 1}, {1, -2.22045e-16, -2.22045e-16, 6.245e-17, 1, 8.06646e-17, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 2.77556e-16, -2.22045e-16, 1}, {1, 0, 0, 0, 1, 8.88178e-16, 3.33067e-16, 2.22045e-16, 1}, {1, 0, 0, -4.44089e-16, 1, 8.88178e-16, -2.22045e-16, -4.44089e-16, 1}, {1, 0, 0, -1.77636e-15, 1, 0, 8.88178e-16, 0, 1}, {1, -5.55112e-17, 0, 0, 1, 0, 0, -2.22045e-16, 1}, {1, 0, 0, -1.11022e-16, 1, -8.32667e-17, 0, 0, 1}, {1, 7.19084e-17, -2.46466e-16, 0, 1, 0, 4.44089e-16, 0, 1}, {1, -1.48761e-16, -1.43135e-16, 0, 1, 0, 0, 0, 1}, {1, 1.11022e-16, 0, 2.22045e-16, 1, -5.55112e-17, 0, -1.11022e-16, 1}, {1, 0, 0, 0, 1, 0, 0, -4.44089e-16, 1}, {1, -2.22045e-16, 0, 0, 1, -1.11022e-15, 2.22045e-16, 0, 1}, {1, -2.22045e-16, 0, 0, 1, 0, 0, 1.11022e-16, 1}, {1, 0, 0, -3.33067e-16, 1, 1.66533e-16, 0, 0, 1}, {1, 0, 0, 3.33067e-16, 1, -1.11022e-16, 0, 0, 1}, {1, 1.11022e-16, -1.66533e-16, -1.11022e-16, 1, 0, -1.11022e-16, 0, 1}, {1, 0, 1.249e-16, 0, 1, -1.11022e-16, 0, 0, 1}, {1, -1.11022e-16, -1.11022e-16, 4.53894e-18, 1, 2.38892e-17, 0, 0, 1}, {1, 1.11022e-16, 0, 0, 1, 1.55736e-16, 0, 0, 1}, {1, 4.95181e-18, -1.41507e-17, 4.44089e-16, 1, -4.44089e-16, 0, 0, 1}, {1, -2.19918e-16, -6.61021e-17, 0, 1, 0, 0, 0, 1}, {1, 1.11022e-16, 9.71445e-17, 0, 1, 0, 8.88178e-16, 1.11022e-16, 1}, {1, 1.38778e-17, 0, 0, 1, 0, 0, 0, 1}, {1, 0, 0, -8.88178e-16, 1, 0, 8.88178e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}, {1, 0, 0, -2.22045e-16, 1, 0, 0, 4.44089e-16, 1}, {1, 0, 0, 3.33067e-16, 1, -2.22045e-16, 4.44089e-16, 0, 1}, {1, 0, 1.11022e-16, 0, 1, 1.66533e-16, -3.46945e-17, -1.66533e-16, 1}, {1, 0, -2.22045e-16, 0, 1, -2.22045e-16, -1.38778e-16, -4.71845e-16, 1}, {1, 0, 0, -1.11022e-16, 1, -1.23689e-16, 8.32667e-17, 2.22045e-16, 1}, {1, 0, 0, -1.11022e-16, 1, -1.11022e-16, 1.249e-16, 0, 1}, {1, 0, 1.11022e-16, 0, 1, 0, 0, 1.11022e-16, 1}, {1, 0, 0, 0, 1, 0, -2.77556e-16, -1.11022e-16, 1}, {1, 0, 0, -4.44089e-16, 1, 0, -2.22045e-16, 0, 1}, {1, 0, 0, 0, 1, 0, 4.44089e-16, 0, 1}, {1, 1.11022e-16, 0, 2.98372e-16, 1, 0, 0, 0, 1}, {1, 0, 1.11022e-16, 2.08167e-16, 1, -1.21431e-16, 4.44089e-16, 0, 1}, {1, 2.22045e-16, 4.44089e-16, 0, 1, 0, 4.44089e-16, 0, 1}, {1, 0, -4.44089e-16, 4.44089e-16, 1, 4.44089e-16, 0, 0, 1}, {1, -4.44089e-16, 0, 0, 1, 4.44089e-16, 5.55112e-17, -5.55112e-17, 1}, {1, 0, -4.44089e-16, 0, 1, 0, -5.55112e-17, -1.38778e-17, 1}, {1, 0, 0, 0, 1, 0, 2.22045e-16, 1.11022e-16, 1}, {1, 0, 0, 0, 1, 0, 2.22045e-16, 0, 1}, {1, 1.11022e-16, 0, -2.22045e-16, 1, 0, -1.11022e-16, 0, 1}, {1, 3.33067e-16, -1.66533e-16, 0, 1, 0, 0, 0, 1}, {1, 5.55112e-17, -1.11022e-16, 0, 1, -3.33067e-16, 0, -2.22045e-16, 1}, {1, 0, 2.22045e-16, 2.22045e-16, 1, 0, 1.11022e-16, 0, 1}, {1, 0, 1.11022e-16, 1.11022e-16, 1, -5.55112e-17, -2.22045e-16, 0, 1}, {1, -5.55112e-17, -5.55112e-16, 0, 1, 4.44089e-16, 0, 4.44089e-16, 1}, {1, 0, 0, 4.44089e-16, 1, 0, 0, 0, 1}, {1, 2.56739e-16, 0, 5.55112e-17, 1, -4.44089e-16, -1.11022e-16, 4.44089e-16, 1}, {1, -8.32667e-17, -1.38778e-16, 0, 1, 0, 0, -8.88178e-16, 1}, {1, -2.22045e-16, 2.22045e-16, -1.11022e-16, 1, -2.22045e-16, -1.09083e-16, 8.01746e-17, 1}, {1, 0, 4.44089e-16, 4.44089e-16, 1, -4.44089e-16, -8.12856e-17, -9.70941e-17, 1}, {1, 0, 0, 0, 1, -1.11022e-16, 2.04697e-16, 0, 1}, {1, -2.22045e-16, -6.66134e-16, 1.11022e-16, 1, 2.22045e-16, -1.43982e-16, 0, 1}, {1, 0, -1.11022e-16, 0, 1, 0, 0, 0, 1}, {1, -2.22045e-16, 1.66533e-16, 2.22045e-16, 1, -5.55112e-17, 0, -4.44089e-16, 1}, {1, 4.44089e-16, 0, 8.88178e-16, 1, 0, 0, 0, 1}, {1, 2.77556e-16, 1.38778e-17, -8.88178e-16, 1, 0, 0, 0, 1}, {1, 0, -4.44089e-16, -2.22045e-16, 1, 0, -4.44089e-16, 1.11022e-16, 1}, {1, 0, 0, 0, 1, 2.22045e-16, -2.22045e-16, 0, 1}, {1, 0, 0, 1.34228e-18, 1, 0, 2.22045e-16, 0, 1}, {1, 0, 0, -3.81481e-17, 1, 0, -4.44089e-16, 4.44089e-16, 1}, {1, -1.249e-16, 9.36751e-17, 0, 1, 0, 0, 0, 1}, {1, 0, 0, 5.55112e-17, 1, 1.66533e-16, 0, 0, 1}, {1, 0, 0, -1.11022e-16, 1, -5.55112e-17, 0, 0, 1}, {1, 0, 0, 5.81629e-17, 1, -1.06747e-17, 4.44089e-16, 0, 1}, {1, 0, -2.22045e-16, 1.45308e-16, 1, 7.44275e-17, 0, 0, 1}, {1, 0, 0, 0, 1, -8.6868e-17, 0, 0, 1}, {1, 0, 0, -1.00974e-28, 1, -1.89507e-16, 0, 0, 1}, {1, -2.22045e-16, 0, -2.22045e-16, 1, 0, 0, -1.11022e-16, 1}, {1, 0, 2.22045e-16, 0, 1, 0, -1.11022e-16, 0, 1}, {1, -5.55112e-17, -1.66533e-16, 1.11022e-16, 1, 0, 0, 4.44089e-16, 1}, {1, -8.32667e-17, -8.32667e-17, 0, 1, 0, 0, -4.44089e-16, 1}, {1, 1.11022e-16, 0, 0, 1, 0, 4.44089e-16, -1.11022e-16, 1}, {1, 0, 0, 0, 1, 4.44089e-16, -4.44089e-16, 0, 1}, {1, -2.22045e-16, 0, -2.22045e-16, 1, 0, 0, 5.55112e-17, 1}, {1, 2.22045e-16, 0, 4.44089e-16, 1, 1.11022e-16, 2.22045e-16, 0, 1}, {1, 0, -1.11022e-16, 4.44089e-16, 1, -2.22045e-16, 0, 0, 1}, {1, 1.11022e-16, 0, 0, 1, 7.63278e-17, 4.44089e-16, 0, 1}, {1, 0, -1.11022e-16, 0, 1, 1.11022e-16, 8.88178e-16, 0, 1}, {1, 2.22045e-16, -1.11022e-16, 0, 1, 0, 0, 2.22045e-16, 1}, {1, -4.44089e-16, -3.33067e-16, 2.498e-16, 1, 3.747e-16, 0, 2.22045e-16, 1}, {1, 0, 0, 1.66533e-16, 1, -1.66533e-16, 0, 0, 1}, {1, 0, 0, -4.44089e-16, 1, 0, 0, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 1}}
-]
-
diff --git a/test/test_fe_engine/test_gradient_triangle_3.verified b/test/test_fe_engine/test_gradient_triangle_3.verified
index d86386d19..039eba426 100644
--- a/test/test_fe_engine/test_gradient_triangle_3.verified
+++ b/test/test_fe_engine/test_gradient_triangle_3.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 13
- + nb_component : 2
- + allocated size : 13
- + memory size : 208.00Byte
- + values : {{0, 0}, {13, 11}, {36, 18}, {23, 7}, {6.5, 5.5}, {24.5, 14.5}, {29.5, 12.5}, {11.5, 3.5}, {18, 9}, {20.5, 8}, {27, 13.5}, {15.5, 10}, {9, 4.5}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 16
- + nb_component : 4
- + allocated size : 16
- + memory size : 512.00Byte
- + values : {{13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 13
- + nb_component : 2
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0.5, 0}, {1, 0.5}, {0.5, 1}, {0, 0.5}, {0.5, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.25}, {0.25, 0.25}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 16
- + nb_component : 4
- + allocated size : 16
- + memory size : 512.00Byte
- + values : {{1, 0, 0, 1}, {1, 0, 0, 1}, {1, 1.11022e-16, 0, 1}, {1, 0, -3.33067e-16, 1}, {1, 1.29199e-23, 0, 1}, {1, 2.22045e-16, 0, 1}, {1, 0, -1.42689e-23, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, -1.11022e-16, 1}, {1, 0, 0, 1}, {1, 1.58651e-24, 4.44089e-16, 1}, {1, 0, 0, 1}, {1, -4.44089e-16, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}}
-]
-
diff --git a/test/test_fe_engine/test_gradient_triangle_6.verified b/test/test_fe_engine/test_gradient_triangle_6.verified
index 508650c8c..039eba426 100644
--- a/test/test_fe_engine/test_gradient_triangle_6.verified
+++ b/test/test_fe_engine/test_gradient_triangle_6.verified
@@ -1,37 +1 @@
Epsilon : 1e-12
-Linear array on nodes : Array<double> [
- + id : const_val
- + size : 41
- + nb_component : 2
- + allocated size : 41
- + memory size : 656.00Byte
- + values : {{0, 0}, {13, 11}, {36, 18}, {23, 7}, {6.5, 5.5}, {3.25, 2.75}, {9.75, 8.25}, {24.5, 14.5}, {18.75, 12.75}, {30.25, 16.25}, {29.5, 12.5}, {32.75, 15.25}, {26.25, 9.75}, {11.5, 3.5}, {17.25, 5.25}, {5.75, 1.75}, {18, 9}, {20.5, 8}, {27, 13.5}, {15.5, 10}, {9, 4.5}, {21.75, 7.5}, {25, 10.25}, {4.5, 2.25}, {10.25, 4}, {31.5, 15.75}, {25.75, 14}, {14.25, 10.5}, {11, 7.75}, {14.75, 6.25}, {19.25, 8.5}, {16, 5.75}, {23.75, 10.75}, {22.5, 11.25}, {28.25, 13}, {13.5, 6.75}, {21.25, 11.75}, {12.25, 7.25}, {7.75, 5}, {16.75, 9.5}, {20, 12.25}}
-]
-
-Gradient on quad : Array<double> [
- + id : grad_on_quad
- + size : 48
- + nb_component : 4
- + allocated size : 48
- + memory size : 1.50KiByte
- + values : {{13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}, {13, 11, 23, 7}}
-]
-
-Node positions : Array<double> [
- + id : mesh:coordinates
- + size : 41
- + nb_component : 2
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0.5, 0}, {0.25, 0}, {0.75, 0}, {1, 0.5}, {1, 0.25}, {1, 0.75}, {0.5, 1}, {0.75, 1}, {0.25, 1}, {0, 0.5}, {0, 0.75}, {0, 0.25}, {0.5, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.25}, {0.25, 0.25}, {0.125, 0.875}, {0.375, 0.875}, {0.125, 0.125}, {0.125, 0.375}, {0.875, 0.875}, {0.875, 0.625}, {0.875, 0.125}, {0.625, 0.125}, {0.25, 0.5}, {0.375, 0.625}, {0.125, 0.625}, {0.5, 0.75}, {0.625, 0.625}, {0.625, 0.875}, {0.375, 0.375}, {0.75, 0.5}, {0.5, 0.25}, {0.375, 0.125}, {0.625, 0.375}, {0.875, 0.375}}
-]
-
-Gradient of nodes : Array<double> [
- + id : grad_coord_on_quad
- + size : 48
- + nb_component : 4
- + allocated size : 48
- + memory size : 1.50KiByte
- + values : {{1, 0, 0, 1}, {1, -7.40149e-16, -4.44089e-16, 1}, {1, 0, 2.22045e-16, 1}, {1, 2.22045e-16, 0, 1}, {1, 2.22045e-16, 0, 1}, {1, 1.33227e-15, 0, 1}, {1, -8.88178e-16, 0, 1}, {1, 4.44089e-16, 7.40149e-16, 1}, {1, 8.88178e-16, 0, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}, {1, 0, -8.88178e-16, 1}, {1, 1.11022e-16, 0, 1}, {1, -1.11022e-16, 1.38778e-16, 1}, {1, -4.44089e-16, 5.55112e-17, 1}, {1, -8.88178e-16, 4.44089e-16, 1}, {1, 0, -2.22045e-16, 1}, {1, 1.77636e-15, 0, 1}, {1, -1.77636e-15, -2.22045e-16, 1}, {1, -1.11022e-15, 2.22045e-16, 1}, {1, -4.44089e-16, 4.44089e-16, 1}, {1, 0, -2.22045e-16, 1}, {1, 3.70074e-16, 0, 1}, {1, 0, -4.44089e-16, 1}, {1, 0, 0, 1}, {1, 2.22045e-16, -8.88178e-16, 1}, {1, 0, 0, 1}, {1, -2.22045e-16, -4.44089e-16, 1}, {1, -2.77556e-16, 2.77556e-16, 1}, {1, -1.66533e-16, 0, 1}, {1, 2.22045e-16, 0, 1}, {1, 2.22045e-16, -3.70074e-16, 1}, {1, 2.22045e-16, 0, 1}, {1, 1.11022e-16, -1.77636e-15, 1}, {1, -1.11022e-16, 8.88178e-16, 1}, {1, 2.22045e-16, 8.88178e-16, 1}, {1, 0, 2.22045e-16, 1}, {1, 0, 1.94289e-16, 1}, {1, 0, -5.55112e-17, 1}, {1, 0, 0, 1}, {1, 6.66134e-16, 0, 1}, {1, 8.88178e-16, 0, 1}, {1, 0, 0, 1}, {1, -1.38778e-16, 0, 1}, {1, 1.66533e-16, 0, 1}, {1, 0, -3.55271e-15, 1}, {1, 0, -6.66134e-16, 1}, {1, 0, -8.88178e-16, 1}}
-]
-
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..f976e48ba 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[]){
+int main(){
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..409d17533 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[]) {
+int main() {
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..8d8159008 100644
--- a/test/test_geometry/CMakeLists.txt
+++ b/test/test_geometry/CMakeLists.txt
@@ -1,57 +1,55 @@
#===============================================================================
# @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: Tue Jan 19 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_diana.cc b/test/test_mesh_utils/test_mesh_io/test_mesh_io_diana.cc
deleted file mode 100644
index 0efc73f72..000000000
--- a/test/test_mesh_utils/test_mesh_io/test_mesh_io_diana.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * @file test_mesh_io_diana.cc
- *
- * @author David Simon Kammer <david.kammer@epfl.ch>
- * @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date Wed May 04 18:17:20 2011
- *
- * @brief test reading mesh diana
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-
-/* -------------------------------------------------------------------------- */
-#include <cstdlib>
-#include <iostream>
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "mesh.hh"
-#include "mesh_io.hh"
-#include "mesh_io_diana.hh"
-
-#ifdef AKANTU_USE_IOHELPER
-# include "io_helper.hh"
-#endif //AKANTU_USE_IOHELPER
-
-/* -------------------------------------------------------------------------- */
-
-using namespace akantu;
-
-int main(int argc, char *argv[]) {
- int dim = 3;
- const ElementType element_type = _tetrahedron_4;
- const UInt paraview_type = iohelper::TETRA1;
-
- akantu::MeshIODiana mesh_io;
- akantu::Mesh mesh(3);
-
- mesh_io.read("./dam.dat", mesh);
-
- std::cout << mesh << std::endl;
-
- UInt nb_nodes = mesh.getNbNodes();
- UInt nb_elements = mesh.getNbElement(element_type);
-
- std::vector<std::string> node_groups = mesh_io.getNodeGroupsNames();
- std::vector<std::string> element_groups = mesh_io.getElementGroupsNames();
-
-#ifdef AKANTU_USE_IOHELPER
- /// initialize the paraview output
- iohelper::DumperParaview dumper;
- dumper.SetMode(iohelper::TEXT);
- dumper.SetPoints(mesh.getNodes().storage(), dim, nb_nodes, "dam_diana");
- dumper.SetConnectivity((int *)mesh.getConnectivity(element_type).storage(), paraview_type, nb_elements, iohelper::C_MODE);
-
- UInt i = 0;
-
- Real * nodes_grps[node_groups.size()];
- std::cout << "Nb node groups : " << node_groups.size() << std::endl;
- std::vector<std::string>::iterator it_nodes;
- for(it_nodes = node_groups.begin(); it_nodes != node_groups.end(); ++it_nodes) {
- nodes_grps[i] = new Real[nb_nodes];
- std::fill_n(nodes_grps[i], nb_nodes, 0);
- const Array<UInt> & group = mesh_io.getNodeGroup(*it_nodes);
- for (UInt n = 0; n < group.getSize(); ++n) {
- nodes_grps[i][group(n)] = 1.;
- }
-
- dumper.AddNodeDataField(nodes_grps[i], 1, (*it_nodes).c_str());
-
- std::cout << " " << *it_nodes;
- i++;
- }
- std::cout << std::endl;
-
- i = 0;
- Real * elements_grps[element_groups.size()];
- std::cout << "Nb element groups : " << element_groups.size() << std::endl;
- std::vector<std::string>::iterator it_elements;
- for(it_elements = element_groups.begin(); it_elements != element_groups.end(); ++it_elements) {
- elements_grps[i] = new Real[nb_elements];
- std::fill_n(elements_grps[i], nb_elements, 0);
- const std::vector<Element> & group = mesh_io.getElementGroup(*it_elements);
- for (UInt n = 0; n < group.size(); ++n) {
- elements_grps[i][group[n].element] = 1.;
- }
-
- dumper.AddElemDataField(elements_grps[i], 1, (*it_elements).c_str());
-
- std::cout << " " << *it_elements;
- i++;
- }
- std::cout << std::endl;
-
-
- dumper.SetPrefix("paraview/");
- dumper.Init();
- dumper.Dump();
-#endif //AKANTU_USE_IOHELPER
-
- return EXIT_SUCCESS;
-}
-
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/squares.geo b/test/test_mesh_utils/test_mesh_partitionate/squares.geo
deleted file mode 100644
index a25dfaafa..000000000
--- a/test/test_mesh_utils/test_mesh_partitionate/squares.geo
+++ /dev/null
@@ -1,43 +0,0 @@
-// Element size
-//h = 0.5;
-h = 0.005;
-
-// Dimension of square
-H = 2;
-L = 1;
-
-// ------------------------------------------
-// Geometry
-// ------------------------------------------
-
-// Points
-Point(1) = {-L/2., 0, 0, h};
-Point(2) = {L/2., 0, 0, h};
-Point(3) = {L/2., H, 0, h};
-Point(4) = {-L/2., H, 0, h};
-
-Point(5) = {-L/2., 0, 0, h};
-Point(6) = {-L/2., -H, 0, h};
-Point(7) = {L/2., -H, 0, h};
-Point(8) = {L/2., 0, 0, h};
-
-// Lines
-Line(1) = {4, 1};
-Line(2) = {1, 2};
-Line(3) = {2, 3};
-Line(4) = {3, 4};
-
-Line(5) = {8, 5};
-Line(6) = {5, 6};
-Line(7) = {6, 7};
-Line(8) = {7, 8};
-
-// Geometric and Physical Surface
-Line Loop(1) = {1, 2, 3, 4};
-Plane Surface(1) = {1};
-
-Line Loop(2) = {5, 6, 7, 8};
-Plane Surface(2) = {2};
-
-Transfinite Surface "*";
-Recombine Surface "*";
diff --git a/test/test_mesh_utils/test_mesh_partitionate/squares_H.msh b/test/test_mesh_utils/test_mesh_partitionate/squares_H.msh
deleted file mode 100644
index c0fdce822..000000000
--- a/test/test_mesh_utils/test_mesh_partitionate/squares_H.msh
+++ /dev/null
@@ -1,87 +0,0 @@
-$MeshFormat
-2.2 0 8
-$EndMeshFormat
-$Nodes
-30
-1 -0.5 0 0
-2 0.5 0 0
-3 0.5 2 0
-4 -0.5 2 0
-5 -0.5 0 0
-6 -0.5 -2 0
-7 0.5 -2 0
-8 0.5 0 0
-9 -0.5 1.500000000000694 0
-10 -0.5 1.000000000002776 0
-11 -0.5 0.5000000000020817 0
-12 -1.040834085586084e-12 0 0
-13 0.5 0.4999999999987997 0
-14 0.5 0.9999999999980433 0
-15 0.5 1.499999999998675 0
-16 1.040834085586084e-12 2 0
-17 1.040834085586084e-12 0 0
-18 -0.5 -0.4999999999987997 0
-19 -0.5 -0.9999999999980433 0
-20 -0.5 -1.499999999998675 0
-21 -1.040834085586084e-12 -2 0
-22 0.5 -1.500000000000694 0
-23 0.5 -1.000000000002776 0
-24 0.5 -0.5000000000020817 0
-25 5.204170427930421e-13 1.499999999999684 0
-26 0 1.000000000000409 0
-27 -5.204309205808499e-13 0.5000000000004408 0
-28 5.20389287218676e-13 -0.5000000000004408 0
-29 2.036447582271663e-24 -1.000000000000409 0
-30 -5.203892872160472e-13 -1.499999999999685 0
-$EndNodes
-$Elements
-48
-1 15 2 0 1 1
-2 15 2 0 2 2
-3 15 2 0 3 3
-4 15 2 0 4 4
-5 15 2 0 5 5
-6 15 2 0 6 6
-7 15 2 0 7 7
-8 15 2 0 8 8
-9 1 2 0 1 4 9
-10 1 2 0 1 9 10
-11 1 2 0 1 10 11
-12 1 2 0 1 11 1
-13 1 2 0 2 1 12
-14 1 2 0 2 12 2
-15 1 2 0 3 2 13
-16 1 2 0 3 13 14
-17 1 2 0 3 14 15
-18 1 2 0 3 15 3
-19 1 2 0 4 3 16
-20 1 2 0 4 16 4
-21 1 2 0 5 8 17
-22 1 2 0 5 17 5
-23 1 2 0 6 5 18
-24 1 2 0 6 18 19
-25 1 2 0 6 19 20
-26 1 2 0 6 20 6
-27 1 2 0 7 6 21
-28 1 2 0 7 21 7
-29 1 2 0 8 7 22
-30 1 2 0 8 22 23
-31 1 2 0 8 23 24
-32 1 2 0 8 24 8
-33 3 2 0 1 4 9 25 16
-34 3 2 0 1 16 25 15 3
-35 3 2 0 1 9 10 26 25
-36 3 2 0 1 25 26 14 15
-37 3 2 0 1 10 11 27 26
-38 3 2 0 1 26 27 13 14
-39 3 2 0 1 11 1 12 27
-40 3 2 0 1 27 12 2 13
-41 3 2 0 2 8 17 28 24
-42 3 2 0 2 24 28 29 23
-43 3 2 0 2 23 29 30 22
-44 3 2 0 2 22 30 21 7
-45 3 2 0 2 17 5 18 28
-46 3 2 0 2 28 18 19 29
-47 3 2 0 2 29 19 20 30
-48 3 2 0 2 30 20 6 21
-$EndElements
diff --git a/test/test_mesh_utils/test_mesh_partitionate/squares_L.msh b/test/test_mesh_utils/test_mesh_partitionate/squares_L.msh
deleted file mode 100644
index 8919a07eb..000000000
--- a/test/test_mesh_utils/test_mesh_partitionate/squares_L.msh
+++ /dev/null
@@ -1,143 +0,0 @@
-$MeshFormat
-2.2 0 8
-$EndMeshFormat
-$Nodes
-54
-1 -2 0 0
-2 2 0 0
-3 2 1 0
-4 -2 1 0
-5 -2 0 0
-6 -2 -1 0
-7 2 -1 0
-8 2 0 0
-9 -2 0.5000000000013878 0
-10 -1.500000000001388 0 0
-11 -1.000000000002776 0 0
-12 -0.5000000000034694 0 0
-13 -4.163336342344337e-12 0 0
-14 0.4999999999965308 0 0
-15 0.9999999999972244 0 0
-16 1.499999999998612 0 0
-17 2 0.4999999999990217 0
-18 1.500000000001388 1 0
-19 1.000000000002776 1 0
-20 0.5000000000034694 1 0
-21 4.163336342344337e-12 1 0
-22 -0.4999999999965308 1 0
-23 -0.9999999999972244 1 0
-24 -1.499999999998612 1 0
-25 1.500000000001388 0 0
-26 1.000000000002776 0 0
-27 0.5000000000034694 0 0
-28 4.163336342344337e-12 0 0
-29 -0.4999999999965308 0 0
-30 -0.9999999999972244 0 0
-31 -1.499999999998612 0 0
-32 -2 -0.4999999999990217 0
-33 -1.500000000001388 -1 0
-34 -1.000000000002776 -1 0
-35 -0.5000000000034694 -1 0
-36 -4.163336342344337e-12 -1 0
-37 0.4999999999965308 -1 0
-38 0.9999999999972244 -1 0
-39 1.499999999998612 -1 0
-40 2 -0.5000000000013878 0
-41 -1.5 0.500000000001092 0
-42 -1 0.5000000000007963 0
-43 -0.4999999999999998 0.5000000000005005 0
-44 0 0.5000000000002047 0
-45 0.5000000000000001 0.499999999999909 0
-46 1 0.4999999999996132 0
-47 1.5 0.4999999999993174 0
-48 1.5 -0.500000000001092 0
-49 1 -0.5000000000007963 0
-50 0.5000000000000001 -0.5000000000005005 0
-51 8.145790329086651e-24 -0.5000000000002047 0
-52 -0.5000000000000001 -0.499999999999909 0
-53 -1 -0.4999999999996132 0
-54 -1.5 -0.4999999999993174 0
-$EndNodes
-$Elements
-80
-1 15 2 0 1 1
-2 15 2 0 2 2
-3 15 2 0 3 3
-4 15 2 0 4 4
-5 15 2 0 5 5
-6 15 2 0 6 6
-7 15 2 0 7 7
-8 15 2 0 8 8
-9 1 2 0 1 4 9
-10 1 2 0 1 9 1
-11 1 2 0 2 1 10
-12 1 2 0 2 10 11
-13 1 2 0 2 11 12
-14 1 2 0 2 12 13
-15 1 2 0 2 13 14
-16 1 2 0 2 14 15
-17 1 2 0 2 15 16
-18 1 2 0 2 16 2
-19 1 2 0 3 2 17
-20 1 2 0 3 17 3
-21 1 2 0 4 3 18
-22 1 2 0 4 18 19
-23 1 2 0 4 19 20
-24 1 2 0 4 20 21
-25 1 2 0 4 21 22
-26 1 2 0 4 22 23
-27 1 2 0 4 23 24
-28 1 2 0 4 24 4
-29 1 2 0 5 8 25
-30 1 2 0 5 25 26
-31 1 2 0 5 26 27
-32 1 2 0 5 27 28
-33 1 2 0 5 28 29
-34 1 2 0 5 29 30
-35 1 2 0 5 30 31
-36 1 2 0 5 31 5
-37 1 2 0 6 5 32
-38 1 2 0 6 32 6
-39 1 2 0 7 6 33
-40 1 2 0 7 33 34
-41 1 2 0 7 34 35
-42 1 2 0 7 35 36
-43 1 2 0 7 36 37
-44 1 2 0 7 37 38
-45 1 2 0 7 38 39
-46 1 2 0 7 39 7
-47 1 2 0 8 7 40
-48 1 2 0 8 40 8
-49 3 2 0 1 4 9 41 24
-50 3 2 0 1 24 41 42 23
-51 3 2 0 1 23 42 43 22
-52 3 2 0 1 22 43 44 21
-53 3 2 0 1 21 44 45 20
-54 3 2 0 1 20 45 46 19
-55 3 2 0 1 19 46 47 18
-56 3 2 0 1 18 47 17 3
-57 3 2 0 1 9 1 10 41
-58 3 2 0 1 41 10 11 42
-59 3 2 0 1 42 11 12 43
-60 3 2 0 1 43 12 13 44
-61 3 2 0 1 44 13 14 45
-62 3 2 0 1 45 14 15 46
-63 3 2 0 1 46 15 16 47
-64 3 2 0 1 47 16 2 17
-65 3 2 0 2 8 25 48 40
-66 3 2 0 2 40 48 39 7
-67 3 2 0 2 25 26 49 48
-68 3 2 0 2 48 49 38 39
-69 3 2 0 2 26 27 50 49
-70 3 2 0 2 49 50 37 38
-71 3 2 0 2 27 28 51 50
-72 3 2 0 2 50 51 36 37
-73 3 2 0 2 28 29 52 51
-74 3 2 0 2 51 52 35 36
-75 3 2 0 2 29 30 53 52
-76 3 2 0 2 52 53 34 35
-77 3 2 0 2 30 31 54 53
-78 3 2 0 2 53 54 33 34
-79 3 2 0 2 31 5 32 54
-80 3 2 0 2 54 32 6 33
-$EndElements
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..83091895d 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,120 @@
/**
* @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_paraview.hh"
#include "dumper_elemental_field.hh"
-#endif //AKANTU_USE_IOHELPER
+#endif // AKANTU_USE_IOHELPER
using namespace akantu;
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[])
-{
+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) {
+ 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);
+ for (UInt i(0); i < nb_element; ++i) {
+ Vector<Real> barycenter(dim);
+ Element element(*tit, i, gt);
+ mesh.getBarycenter(element, barycenter);
+
Real real_proc = barycenter[0] * nb_partitions;
- if(std::abs(real_proc - round(real_proc)) < 10*std::numeric_limits<Real>::epsilon()) {
+ 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;
+ 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);
+ akantu::MeshPartitionMeshData * partitioner =
+ new akantu::MeshPartitionMeshData(mesh, dim);
partitioner->setPartitionMapping(partition);
partitioner->partitionate(nb_partitions);
tit = mesh.firstType(dim, gt);
- for(; tit != tend; ++tit) {
+ 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");
+ for (UInt i(0); i < nb_element; ++i) {
+ AKANTU_DEBUG_ASSERT(type_partition(i) == type_partition_reference(i),
+ "Incorrect partitioning");
}
}
- //#define DEBUG_TEST
+//#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);
+ 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", 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..fc9fadad7 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,107 @@
/**
* @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[]) {
+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);
+ dist = DistributedSynchronizer::createDistributedSynchronizerMesh(
+ mesh, &partition);
} else {
- dist = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ 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) {
+ 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);
+ 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;
+ 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_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[-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())
+ 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_mesh_utils/test_segment_nodetype/test_segment_nodetype.sh b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.sh
index 723b4a48e..f49a62700 100755
--- a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.sh
+++ b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.sh
@@ -1,3 +1,3 @@
#!/bin/bash
-mpirun -np 8 test_segment_nodetype
+mpirun -np 8 ./test_segment_nodetype
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_bar2d_coarse_square_mesh.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_bar2d_coarse_square_mesh.cc
deleted file mode 100644
index 88fadc24a..000000000
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_bar2d_coarse_square_mesh.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * @file test_heat_transfer_model_bar2d_coarse_square_mesh.cc
- *
- * @author Rui Wang <rui.wang@epfl.ch>
- * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
- *
- * @date Sun May 01 19:14:43 2011
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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;
-
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-
-#include "io_helper.hh"
-akantu::UInt paraview_type = iohelper::TETRA1;
-void paraviewInit(iohelper::Dumper & dumper);
-void paraviewDump(iohelper::Dumper & dumper);
-
-#endif //AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
-
-akantu::UInt spatial_dimension = 3;
-akantu:: ElementType type = akantu::_tetrahedron_4;
-
-akantu::Real density;
-akantu::Real conductivity[3][3];
-akantu::Real capacity;
-
-/* -------------------------------------------------------------------------- */
-
-
-int readMaterial () {
-
- string str;
- ifstream myfile;
-
-
- myfile.open("material.dat");
- if(!myfile) //Always test the file open.
- {
- cout<<"Error opening output file"<<endl;
- return -1;
- }
-
- getline(myfile, str);
- density=atof(str.c_str());
-
- getline(myfile, str);
- capacity=atof(str.c_str());
-
- getline(myfile, str);
- char * cstr, *p;
- char * tmp_cstr;
- cstr = new char [str.size()+1];
- strcpy (cstr, str.c_str());
- // p=strtok (cstr," ");
- // conductivity[0][0]= atof(p);
- // cout<<conductivity[0][0]<<endl;
- // p=strtok(NULL, " ");
- // conductivity[0][1]= atof(p);
- // cout<<conductivity[0][1]<<endl;
- // p=strtok(NULL, " ");
- // conductivity[0][2]= atof(p);
- // cout<<conductivity[0][2]<<endl;
-
- tmp_cstr = cstr;
- for(int i=0;i<3;i++)
- for(int j=0; j<3;j++)
- {
- p=strtok(tmp_cstr, " "); tmp_cstr = NULL;
- conductivity[i][j]= atof(p);
- cout<<conductivity[i][j]<<endl;
- }
-
-
- return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-
-int main(int argc, char *argv[])
-{
- akantu::Mesh mesh(spatial_dimension);
- akantu::MeshIOMSH mesh_io;
-
- mesh_io.read("cube1.msh", mesh);
- //just for checking
- // mesh_io.read("square1.msh", mesh);
- // mesh_io.read("bar1.msh", mesh);
- // mesh_io.read("line.msh", mesh);
- readMaterial();
-
- cout<<"The density of the material is:"<< density <<endl;
- cout<<"The capacity of the material is:"<< capacity <<endl;
-
- model = new akantu::HeatTransferModel(mesh);
- //model initialization
- model->initModel();
- //initialize the vectors
- model->initArrays();
-
- nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- nb_element = model->getFEEngine().getMesh().getNbElement(type);
-
-
- akantu::UInt nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- model->getHeatFlux().clear();
- model->getLumped().clear();
- model->getTemperatureGradient(type).clear();
-
- // akantu::debug::setDebugLevel(akantu::dblDump);
- // std::cout << model->getTemperatureGradient(type) << std::endl;
- // akantu::debug::setDebugLevel(akantu::dblWarning);
-
-
-
- model->setDensity(density);
- model->setCapacity(capacity);
- model->SetConductivityMatrix(conductivity);
-
- //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::Array<akantu::Real> & heat_flux = model->getHeatFlux();
- akantu::Real eps = 1e-15;
-
- double t1, t2, length;
-
- t1 = 300.;
- t2 = 100.;
- length = 1.;
-
- 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) = 100.0;
- }
- //set the second boundary condition
- if(std::abs(nodes(i,0) - length) < eps) {
- boundary(i) = true;
- temperature(i) = 100.;
- }
- //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) {
- // if(std::abs(nodes(i,0) - length/2.) < 0.01 && std::abs(nodes(i,1) - length/2.) < 0.01) {
- boundary(i) = true;
- temperature(i) = 300.;
- }
-
-
- }
-
- iohelper::DumperParaview dumper;
- paraviewInit(dumper);
- model->assembleMassLumped(type);
-
-
- // //for testing
- int max_steps = 100000;
-
- for(int i=0; i<max_steps; i++)
- {
-
- model->updateHeatFlux();
- model->updateTemperature();
-
- if(i % 100 == 0)
- paraviewDump(dumper);
- 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;
-}
-
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
-
-void paraviewInit(iohelper::Dumper & dumper) {
- dumper.SetMode(iohelper::TEXT);
- dumper.SetPoints(model->getFEEngine().getMesh().getNodes().storage(),
- spatial_dimension, nb_nodes, "coordinates2");
- dumper.SetConnectivity((int *)model->getFEEngine().getMesh().getConnectivity(type).storage(),
- paraview_type, nb_element, iohelper::C_MODE);
- dumper.AddNodeDataField(model->getTemperature().storage(),
- 1, "temperature");
- dumper.AddNodeDataField(model->getHeatFlux().storage(),
- 1, "heat_flux");
- dumper.AddNodeDataField(model->getLumped().storage(),
- 1, "lumped");
- dumper.AddElemDataField(model->getTemperatureGradient(type).storage(),
- spatial_dimension, "temperature_gradient");
- dumper.SetPrefix("paraview/");
- dumper.Init();
- dumper.Dump();
-}
-
-/* -------------------------------------------------------------------------- */
-
-void paraviewDump(iohelper::Dumper & dumper) {
- dumper.Dump();
-}
-
-/* -------------------------------------------------------------------------- */
-#endif AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
-
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_bar2d_coarse_triangle_mesh.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_bar2d_coarse_triangle_mesh.cc
deleted file mode 100644
index 879ca640c..000000000
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_bar2d_coarse_triangle_mesh.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-/**
- * @file test_heat_transfer_model_bar2d_coarse_triangle_mesh.cc
- *
- *
- * @date Sun May 01 19:14:43 2011
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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;
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-
-#include "io_helper.hh"
-
-akantu::UInt paraview_type = iohelper::TETRA1;
-void paraviewInit(iohelper::Dumper & dumper);
-void paraviewDump(iohelper::Dumper & dumper);
-
-#endif //AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
-
-
-akantu::UInt spatial_dimension = 3;
-akantu:: ElementType type = akantu::_tetrahedron_4;
-akantu::Real density;
-akantu::Real conductivity[3][3];
-akantu::Real capacity;
-/* -------------------------------------------------------------------------- */
-
-
-int readMaterial () {
-
- string str;
- ifstream myfile;
-
-
- myfile.open("material.dat");
- if(!myfile) //Always test the file open.
- {
- cout<<"Error opening output file"<<endl;
- return -1;
- }
-
- getline(myfile, str);
- density=atof(str.c_str());
-
- getline(myfile, str);
- capacity=atof(str.c_str());
-
- getline(myfile, str);
- char * cstr, *p;
- char * tmp_cstr;
- cstr = new char [str.size()+1];
- strcpy (cstr, str.c_str());
- // p=strtok (cstr," ");
- // conductivity[0][0]= atof(p);
- // cout<<conductivity[0][0]<<endl;
- // p=strtok(NULL, " ");
- // conductivity[0][1]= atof(p);
- // cout<<conductivity[0][1]<<endl;
- // p=strtok(NULL, " ");
- // conductivity[0][2]= atof(p);
- // cout<<conductivity[0][2]<<endl;
-
- tmp_cstr = cstr;
- for(int i=0;i<3;i++)
- for(int j=0; j<3;j++)
- {
- p=strtok(tmp_cstr, " "); tmp_cstr = NULL;
- conductivity[i][j]= atof(p);
- cout<<conductivity[i][j]<<endl;
- }
-
-
- return 0;
-}
-/* -------------------------------------------------------------------------- */
-
-int main(int argc, char *argv[])
-{
- akantu::Mesh mesh(spatial_dimension);
- akantu::MeshIOMSH mesh_io;
-
- mesh_io.read("cube1.msh", mesh);
- //just for checking
- // mesh_io.read("square1.msh", mesh);
- // mesh_io.read("bar1.msh", mesh);
- // mesh_io.read("line.msh", mesh);
- readMaterial();
-
- cout<<"The density of the material is:"<< density <<endl;
- cout<<"The capacity of the material is:"<< capacity <<endl;
-
- model = new akantu::HeatTransferModel(mesh);
- //model initialization
- model->initModel();
- //initialize the vectors
- model->initArrays();
-
- nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- nb_element = model->getFEEngine().getMesh().getNbElement(type);
-
-
- akantu::UInt nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- model->getHeatFlux().clear();
- model->getLumped().clear();
- model->getTemperatureGradient(type).clear();
-
- // akantu::debug::setDebugLevel(akantu::dblDump);
- // std::cout << model->getTemperatureGradient(type) << std::endl;
- // akantu::debug::setDebugLevel(akantu::dblWarning);
-
-
-
- model->setDensity(density);
- model->setCapacity(capacity);
- model->SetConductivityMatrix(conductivity);
-
- //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::Array<akantu::Real> & heat_flux = model->getHeatFlux();
- akantu::Real eps = 1e-15;
-
- double t1, t2, length;
-
- t1 = 300.;
- t2 = 100.;
- length = 1.;
-
- 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) = 100.0;
- }
- //set the second boundary condition
- if(std::abs(nodes(i,0) - length) < eps) {
- boundary(i) = true;
- temperature(i) = 100.;
- }
- //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) {
- // if(std::abs(nodes(i,0) - length/2.) < 0.01 && std::abs(nodes(i,1) - length/2.) < 0.01) {
- boundary(i) = true;
- temperature(i) = 300.;
- }
-
-
- }
-
- iohelper::DumperParaview dumper;
- paraviewInit(dumper);
- model->assembleMassLumped(type);
-
-
- // //for testing
- int max_steps = 100000;
-
- for(int i=0; i<max_steps; i++)
- {
-
- model->updateHeatFlux();
- model->updateTemperature();
-
- if(i % 100 == 0)
- paraviewDump(dumper);
- 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;
-}
-
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
-
-void paraviewInit(iohelper::Dumper & dumper) {
- dumper.SetMode(iohelper::TEXT);
- dumper.SetPoints(model->getFEEngine().getMesh().getNodes().storage(),
- spatial_dimension, nb_nodes, "coordinates2");
- dumper.SetConnectivity((int *)model->getFEEngine().getMesh().getConnectivity(type).storage(),
- paraview_type, nb_element, iohelper::C_MODE);
- dumper.AddNodeDataField(model->getTemperature().storage(),
- 1, "temperature");
- dumper.AddNodeDataField(model->getHeatFlux().storage(),
- 1, "heat_flux");
- dumper.AddNodeDataField(model->getLumped().storage(),
- 1, "lumped");
- dumper.AddElemDataField(model->getTemperatureGradient(type).storage(),
- spatial_dimension, "temperature_gradient");
- dumper.SetPrefix("paraview/");
- dumper.Init();
- dumper.Dump();
-}
-
-/* -------------------------------------------------------------------------- */
-
-
-void paraviewDump(iohelper::Dumper & dumper) {
- dumper.Dump();
-}
-/* -------------------------------------------------------------------------- */
-#endif AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
-
-
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_bar2d_fine_square_mesh.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_bar2d_fine_square_mesh.cc
deleted file mode 100644
index bd9f284bf..000000000
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_bar2d_fine_square_mesh.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-/**
- * @file test_heat_transfer_model_bar2d_fine_square_mesh.cc
- *
- *
- * @date Sun May 01 19:14:43 2011
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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;
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-#include "io_helper.hh"
-
-akantu::UInt paraview_type = iohelper::TETRA1;
-void paraviewInit(iohelper::Dumper & dumper);
-void paraviewDump(iohelper::Dumper & dumper);
-
-#endif //AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
-akantu::UInt spatial_dimension = 3;
-akantu:: ElementType type = akantu::_tetrahedron_4;
-
-akantu::Real density;
-akantu::Real conductivity[3][3];
-akantu::Real capacity;
-/* -------------------------------------------------------------------------- */
-
-int readMaterial () {
-
- string str;
- ifstream myfile;
-
-
- myfile.open("Material.dat");
- if(!myfile) //Always test the file open.
- {
- cout<<"Error opening output file"<<endl;
- return -1;
- }
-
- getline(myfile, str);
- density=atof(str.c_str());
-
- getline(myfile, str);
- capacity=atof(str.c_str());
-
- getline(myfile, str);
- char * cstr, *p;
- char * tmp_cstr;
- cstr = new char [str.size()+1];
- strcpy (cstr, str.c_str());
- // p=strtok (cstr," ");
- // conductivity[0][0]= atof(p);
- // cout<<conductivity[0][0]<<endl;
- // p=strtok(NULL, " ");
- // conductivity[0][1]= atof(p);
- // cout<<conductivity[0][1]<<endl;
- // p=strtok(NULL, " ");
- // conductivity[0][2]= atof(p);
- // cout<<conductivity[0][2]<<endl;
-
- tmp_cstr = cstr;
- for(int i=0;i<3;i++)
- for(int j=0; j<3;j++)
- {
- p=strtok(tmp_cstr, " "); tmp_cstr = NULL;
- conductivity[i][j]= atof(p);
- cout<<conductivity[i][j]<<endl;
- }
-
-
- return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-
-
-int main(int argc, char *argv[])
-{
- akantu::Mesh mesh(spatial_dimension);
- akantu::MeshIOMSH mesh_io;
-
- mesh_io.read("cube1.msh", mesh);
- //just for checking
- // mesh_io.read("square1.msh", mesh);
- // mesh_io.read("bar1.msh", mesh);
- // mesh_io.read("line.msh", mesh);
- readMaterial();
-
- cout<<"The density of the material is:"<< density <<endl;
- cout<<"The capacity of the material is:"<< capacity <<endl;
-
- model = new akantu::HeatTransferModel(mesh);
- //model initialization
- model->initModel();
- //initialize the vectors
- model->initArrays();
-
- nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- nb_element = model->getFEEngine().getMesh().getNbElement(type);
-
-
- akantu::UInt nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- model->getHeatFlux().clear();
- model->getLumped().clear();
- model->getTemperatureGradient(type).clear();
-
- // akantu::debug::setDebugLevel(akantu::dblDump);
- // std::cout << model->getTemperatureGradient(type) << std::endl;
- // akantu::debug::setDebugLevel(akantu::dblWarning);
-
-
-
- model->setDensity(density);
- model->setCapacity(capacity);
- model->SetConductivityMatrix(conductivity);
-
- //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::Array<akantu::Real> & heat_flux = model->getHeatFlux();
- akantu::Real eps = 1e-15;
-
- double t1, t2, length;
-
- t1 = 300.;
- t2 = 100.;
- length = 1.;
-
- 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) = 100.0;
- }
- //set the second boundary condition
- if(std::abs(nodes(i,0) - length) < eps) {
- boundary(i) = true;
- temperature(i) = 100.;
- }
- //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) {
- // if(std::abs(nodes(i,0) - length/2.) < 0.01 && std::abs(nodes(i,1) - length/2.) < 0.01) {
- boundary(i) = true;
- temperature(i) = 300.;
- }
-
-
- }
-
- iohelper::DumperParaview dumper;
- paraviewInit(dumper);
- model->assembleMassLumped(type);
-
-
- // //for testing
- int max_steps = 100000;
-
- for(int i=0; i<max_steps; i++)
- {
-
- model->updateHeatFlux();
- model->updateTemperature();
-
- if(i % 100 == 0)
- paraviewDump(dumper);
- 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;
-}
-
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
-
-
-void paraviewInit(iohelper::Dumper & dumper) {
- dumper.SetMode(iohelper::TEXT);
- dumper.SetPoints(model->getFEEngine().getMesh().getNodes().storage(),
- spatial_dimension, nb_nodes, "coordinates2");
- dumper.SetConnectivity((int *)model->getFEEngine().getMesh().getConnectivity(type).storage(),
- paraview_type, nb_element, iohelper::C_MODE);
- dumper.AddNodeDataField(model->getTemperature().storage(),
- 1, "temperature");
- dumper.AddNodeDataField(model->getHeatFlux().storage(),
- 1, "heat_flux");
- dumper.AddNodeDataField(model->getLumped().storage(),
- 1, "lumped");
- dumper.AddElemDataField(model->getTemperatureGradient(type).storage(),
- spatial_dimension, "temperature_gradient");
- dumper.SetPrefix("paraview/");
- dumper.Init();
- dumper.Dump();
-}
-
-/* -------------------------------------------------------------------------- */
-
-
-void paraviewDump(iohelper::Dumper & dumper) {
- dumper.Dump();
-}
-
-/* -------------------------------------------------------------------------- */
-#endif //AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
-
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_anisotropy_conductivity.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_anisotropy_conductivity.cc
deleted file mode 100644
index 092576c25..000000000
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_cube3d_anisotropy_conductivity.cc
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * @file test_heat_transfer_model_cube3d_anisotropy_conductivity.cc
- *
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Rui Wang <rui.wang@epfl.ch>
- * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
- *
- * @date Sun May 01 19:14:43 2011
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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;
-/* -------------------------------------------------------------------------- */
-
-#ifdef AKANTU_USE_IOHELPER
-
-#include "io_helper.hh"
-
-akantu::UInt paraview_type = iohelper::TETRA1;
-void paraviewInit(iohelper::Dumper & dumper);
-void paraviewDump(iohelper::Dumper & dumper);
-#endif //AKANTU_USE_IOHELPER
-
-/* -------------------------------------------------------------------------- */
-akantu::UInt spatial_dimension = 3;
-akantu:: ElementType type = akantu::_tetrahedron_4;
-
-akantu::Real density;
-akantu::Real conductivity[3][3];
-akantu::Real capacity;
-/* -------------------------------------------------------------------------- */
-
-
-
-int readMaterial () {
-
- string str;
- ifstream myfile;
-
-
- myfile.open("material.dat");
- if(!myfile) //Always test the file open.
- {
- cout<<"Error opening output file"<<endl;
- return -1;
- }
-
-
-
- getline(myfile, str);
- density=atof(str.c_str());
-
- getline(myfile, str);
- capacity=atof(str.c_str());
-
- getline(myfile, str);
- char * cstr, *p;
- char * tmp_cstr;
- cstr = new char [str.size()+1];
- strcpy (cstr, str.c_str());
- // p=strtok (cstr," ");
- // conductivity[0][0]= atof(p);
- // cout<<conductivity[0][0]<<endl;
- // p=strtok(NULL, " ");
- // conductivity[0][1]= atof(p);
- // cout<<conductivity[0][1]<<endl;
- // p=strtok(NULL, " ");
- // conductivity[0][2]= atof(p);
- // cout<<conductivity[0][2]<<endl;
-
- tmp_cstr = cstr;
- for(int i=0;i<3;i++)
- for(int j=0; j<3;j++)
- {
- p=strtok(tmp_cstr, " "); tmp_cstr = NULL;
- conductivity[i][j]= atof(p);
- cout<<conductivity[i][j]<<endl;
- }
-
-
- return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-
-
-
-int main(int argc, char *argv[])
-{
- akantu::Mesh mesh(spatial_dimension);
- akantu::MeshIOMSH mesh_io;
-
- mesh_io.read("cube1.msh", mesh);
- //just for checking
- // mesh_io.read("square1.msh", mesh);
- // mesh_io.read("bar1.msh", mesh);
- // mesh_io.read("line.msh", mesh);
- readMaterial();
-
- cout<<"The density of the material is:"<< density <<endl;
- cout<<"The capacity of the material is:"<< capacity <<endl;
-
- model = new akantu::HeatTransferModel(mesh);
- //model initialization
- model->initModel();
- //initialize the vectors
- model->initArrays();
-
- nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- nb_element = model->getFEEngine().getMesh().getNbElement(type);
-
-
- akantu::UInt nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- model->getHeatFlux().clear();
- model->getLumped().clear();
- model->getTemperatureGradient(type).clear();
-
- // akantu::debug::setDebugLevel(akantu::dblDump);
- // std::cout << model->getTemperatureGradient(type) << std::endl;
- // akantu::debug::setDebugLevel(akantu::dblWarning);
-
-
-
- model->setDensity(density);
- model->setCapacity(capacity);
- model->SetConductivityMatrix(conductivity);
-
- //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::Array<akantu::Real> & heat_flux = model->getHeatFlux();
- akantu::Real eps = 1e-15;
-
- double t1, t2, length;
-
- t1 = 300.;
- t2 = 100.;
- length = 1.;
-
- 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) = 100.0;
- }
- //set the second boundary condition
- if(std::abs(nodes(i,0) - length) < eps) {
- boundary(i) = true;
- temperature(i) = 100.;
- }
- //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) {
- // if(std::abs(nodes(i,0) - length/2.) < 0.01 && std::abs(nodes(i,1) - length/2.) < 0.01) {
- boundary(i) = true;
- temperature(i) = 300.;
- }
-
-
- }
-
- iohelper::DumperParaview dumper;
- paraviewInit(dumper);
- model->assembleMassLumped(type);
-
-
- // //for testing
- int max_steps = 100000;
-
- for(int i=0; i<max_steps; i++)
- {
-
- model->updateHeatFlux();
- model->updateTemperature();
-
- if(i % 100 == 0)
- paraviewDump(dumper);
- 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;
-}
-
-void paraviewInit(iohelper::Dumper & dumper) {
- dumper.SetMode(iohelper::TEXT);
- dumper.SetPoints(model->getFEEngine().getMesh().getNodes().storage(),
- spatial_dimension, nb_nodes, "coordinates2");
- dumper.SetConnectivity((int *)model->getFEEngine().getMesh().getConnectivity(type).storage(),
- paraview_type, nb_element, iohelper::C_MODE);
- dumper.AddNodeDataField(model->getTemperature().storage(),
- 1, "temperature");
- dumper.AddNodeDataField(model->getHeatFlux().storage(),
- 1, "heat_flux");
- dumper.AddNodeDataField(model->getLumped().storage(),
- 1, "lumped");
- dumper.AddElemDataField(model->getTemperatureGradient(type).storage(),
- spatial_dimension, "temperature_gradient");
- dumper.SetPrefix("paraview/");
- dumper.Init();
- dumper.Dump();
-}
-
-
-void paraviewDump(iohelper::Dumper & dumper) {
- dumper.Dump();
-}
-
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..e6883d764 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,73 @@
/**
* @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>
+template <UInt dim>
class TestMaterial : public MaterialDamage<dim, MaterialElastic>,
- public MaterialNonLocal<dim>{
-
-/* -------------------------------------------------------------------------- */
-/* Constructor/Destructor */
-/* -------------------------------------------------------------------------- */
-
+ public MaterialNonLocal<dim> {
+ /* ------------------------------------------------------------------------ */
+ /* Constructor/Destructor */
+ /* ------------------------------------------------------------------------ */
public:
-
TestMaterial(SolidMechanicsModel & model, const ID & id);
- virtual ~TestMaterial() {};
+ virtual ~TestMaterial(){};
typedef MaterialNonLocal<dim> MyNonLocalParent;
typedef MaterialDamage<dim, MaterialElastic> MyLocalParent;
-/* -------------------------------------------------------------------------- */
-/* Methods */
-/* -------------------------------------------------------------------------- */
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
public:
void initMaterial();
- void computeNonLocalStresses(GhostType ghost_type) {};
+ void computeNonLocalStresses(__attribute__((unused)) GhostType ghost_type){};
void insertQuadsInNeighborhoods(GhostType ghost_type);
virtual void registerNeighborhood();
-protected:
-
-/* -------------------------------------------------------------------------- */
-/* Members */
-/* -------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------ */
+ /* Members */
+ /* ------------------------------------------------------------------------ */
private:
- InternalField<Real> grad_u_nl;
-
+ 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..01d51bdf3 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,72 @@
/**
* @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 */
-/* -------------------------------------------------------------------------- */
-
+template <UInt dim>
+class TestMaterialDamage : public MaterialDamage<dim, MaterialElastic>,
+ public MaterialNonLocal<dim> {
+ /* ------------------------------------------------------------------------ */
+ /* Constructor/Destructor */
+ /* ------------------------------------------------------------------------ */
public:
-
TestMaterialDamage(SolidMechanicsModel & model, const ID & id);
- virtual ~TestMaterialDamage() {};
+ virtual ~TestMaterialDamage(){};
typedef MaterialNonLocal<dim> MyNonLocalParent;
-/* -------------------------------------------------------------------------- */
-/* Methods */
-/* -------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
public:
void initMaterial();
- //void computeNonLocalStress(ElementType type, GhostType ghost_type = _not_ghost);
-
- void computeNonLocalStresses(GhostType ghost_type) {};
+ // void computeNonLocalStress(ElementType type, GhostType ghost_type =
+ // _not_ghost);
+ void computeNonLocalStresses(__attribute__((unused)) GhostType ghost_type){};
void insertQuadsInNeighborhoods(GhostType ghost_type);
-protected:
-
-
-/* -------------------------------------------------------------------------- */
-/* Members */
-/* -------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------------------ */
+ /* Members */
+ /* ------------------------------------------------------------------------ */
private:
- InternalField<Real> grad_u_nl;
-
+ 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 dab84747a..a86eef148 100644
--- a/test/test_model/test_solid_mechanics_model/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/CMakeLists.txt
@@ -1,231 +1,231 @@
#===============================================================================
# @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: Tue Jan 19 2016
#
# @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_akantu_test(test_boundary_conditions "test_boundary_conditions")
#===============================================================================
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
)
#===============================================================================
add_mesh(homogenized_plate homogenized_plate.geo 2 1)
register_test(test_elastic_homogenization
SOURCES test_elastic_homogenization.cc
DEPENDS homogenized_plate
FILES_TO_COPY material_orthotropic.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE implicit extra_materials
)
#===============================================================================
#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
)
+#add_mesh(test_pbc_parallel_mesh square_structured.geo 2 1 OUTPUT square_structured.msh)
#register_test(test_solid_mechanics_model_pbc_parallel
# SOURCES test_solid_mechanics_model_pbc_parallel.cc
# DEPENDS test_pbc_parallel_mesh
# FILES_TO_COPY material.dat
# DIRECTORIES_TO_CREATE paraview
# PACKAGE parallel
# )
#===============================================================================
add_mesh(test_cube3d_mesh1 cube.geo 3 1 OUTPUT cube1.msh)
add_mesh(test_cube3d_mesh2 cube.geo 3 2 OUTPUT cube2.msh)
add_mesh(test_cube3d_mesh_structured cube_structured.geo 3 1 OUTPUT cube_structured.msh)
register_test(test_solid_mechanics_model_cube3d
SOURCES test_solid_mechanics_model_cube3d.cc
DEPENDS test_cube3d_mesh1
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE core
)
register_test(test_solid_mechanics_model_cube3d_tetra10
SOURCES test_solid_mechanics_model_cube3d_tetra10.cc
DEPENDS test_cube3d_mesh2
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE core
)
register_test(test_solid_mechanics_model_cube3d_pbc
SOURCES test_solid_mechanics_model_cube3d_pbc.cc
DEPENDS test_cube3d_mesh_structured
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE core
)
#add_mesh(test_solid_mechanics_model_boundary_condition_mesh cube_physical_names.geo 3 1)
register_test(test_solid_mechanics_model_boundary_condition
SOURCES test_solid_mechanics_model_boundary_condition.cc
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/cube_physical_names.geo b/test/test_model/test_solid_mechanics_model/cube_physical_names.geo
deleted file mode 100644
index 662a31427..000000000
--- a/test/test_model/test_solid_mechanics_model/cube_physical_names.geo
+++ /dev/null
@@ -1,52 +0,0 @@
-h=0.4;
-
-Point(1) = {0, 0, 0, h};
-Point(2) = {0, -1, 0, h};
-Point(3) = {1, -1, 0, h};
-Point(4) = {1, 0, 0, h};
-
-Point(5) = {0, 0, 1, h};
-Point(6) = {0, -1, 1, h};
-Point(7) = {1, -1, 1, h};
-Point(8) = {1, 0, 1, h};
-
-
-Line(1) = {1, 5};
-Line(2) = {5, 8};
-Line(3) = {8, 4};
-Line(4) = {4, 1};
-Line(5) = {6, 2};
-Line(6) = {2, 3};
-Line(7) = {3, 7};
-Line(8) = {7, 6};
-Line(9) = {5, 6};
-Line(10) = {1, 2};
-Line(11) = {4, 3};
-Line(12) = {8, 7};
-
-Line Loop(26) = {4, 1, 2, 3};
-Plane Surface(26) = {26};
-Line Loop(28) = {9, -8, -12, -2};
-Plane Surface(28) = {28};
-Line Loop(30) = {-7, -11, -3, 12};
-Plane Surface(30) = {30};
-Line Loop(32) = {-10, -4, 11, -6};
-Plane Surface(32) = {32};
-Line Loop(34) = {10, -5, -9, -1};
-Plane Surface(34) = {34};
-Line Loop(36) = {8, 5, 6, 7};
-Plane Surface(36) = {36};
-
-Surface Loop(50) = {26, 28, 30, 32, 34, 36};
-Volume(50) = {50};
-
-Transfinite Surface "*";
-Recombine Surface "*";
-Transfinite Volume "*";
-
-Physical Volume ("PhysVol") = {50};
-Physical Surface ("Bottom") = {32}; // Bottom face
-Physical Surface ("Top") = {28}; // Top face
-Physical Surface ("Sides") = {26, 30, 34, 36}; // Side faces
-
-
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/data/material_check_stress.dat b/test/test_model/test_solid_mechanics_model/patch_tests/data/material_check_stress.dat
deleted file mode 100644
index 781c77d73..000000000
--- a/test/test_model/test_solid_mechanics_model/patch_tests/data/material_check_stress.dat
+++ /dev/null
@@ -1,6 +0,0 @@
-material elastic [
- name = steel
- rho = 7800 # density
- E = 2.1e11 # young's modulus
- nu = 0.3 # poisson's ratio
-]
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..822108949 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,42 @@
#===============================================================================
# @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")
+add_akantu_test(test_cohesive_linear_friction "test_cohesive_linear_friction")
#===============================================================================
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/tetrahedron.msh b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/tetrahedron.msh
deleted file mode 100644
index 9b858ee3c..000000000
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/tetrahedron.msh
+++ /dev/null
@@ -1,720 +0,0 @@
-$MeshFormat
-2.2 0 8
-$EndMeshFormat
-$Nodes
-476
-1 1 1 1
-2 -1 1 1
-3 -1 -1 1
-4 1 -1 1
-5 1 1 -1
-6 -1 1 -1
-7 -1 -1 -1
-8 1 -1 -1
-9 0 1 1
-10 0 -1 1
-11 0 -1 -1
-12 0 1 -1
-13 -1 2.081668171172169e-12 1
-14 -1 0.5000000000009475 1
-15 -1 -0.4999999999989593 1
-16 -0.5000000000013878 -1 1
-17 -0.7500000000005728 -1 1
-18 -0.2500000000006939 -1 1
-19 0 -2.081668171172169e-12 1
-20 0 -0.5000000000009475 1
-21 0 0.4999999999989593 1
-22 -0.4999999999990217 1 1
-23 -0.2499999999995832 1 1
-24 -0.7499999999995108 1 1
-25 0.4999999999990217 -1 1
-26 0.2499999999995832 -1 1
-27 0.7499999999995108 -1 1
-28 1 -2.081668171172169e-12 1
-29 1 -0.5000000000009475 1
-30 1 0.4999999999989593 1
-31 0.5000000000013878 1 1
-32 0.7500000000005728 1 1
-33 0.2500000000006939 1 1
-34 0 -1 2.081668171172169e-12
-35 0 -1 0.5000000000009475
-36 0 -1 -0.4999999999989593
-37 1 -1 2.081668171172169e-12
-38 1 -1 0.5000000000009475
-39 1 -1 -0.4999999999989593
-40 -1 -1 2.081668171172169e-12
-41 -1 -1 0.5000000000009475
-42 -1 -1 -0.4999999999989593
-43 -0.5000000000013878 -1 -1
-44 -0.7500000000005728 -1 -1
-45 -0.2500000000006939 -1 -1
-46 0.4999999999990217 -1 -1
-47 0.2499999999995832 -1 -1
-48 0.7499999999995108 -1 -1
-49 1 -2.081668171172169e-12 -1
-50 1 -0.5000000000009475 -1
-51 1 0.4999999999989593 -1
-52 1 1 -2.081668171172169e-12
-53 1 1 -0.5000000000009475
-54 1 1 0.4999999999989593
-55 0 1 -2.081668171172169e-12
-56 0 1 -0.5000000000009475
-57 0 1 0.4999999999989593
-58 -1 1 -2.081668171172169e-12
-59 -1 1 -0.5000000000009475
-60 -1 1 0.4999999999989593
-61 -1 -2.081668171172169e-12 -1
-62 -1 -0.5000000000009475 -1
-63 -1 0.4999999999989593 -1
-64 -0.5000000000013878 1 -1
-65 -0.7500000000005728 1 -1
-66 -0.2500000000006939 1 -1
-67 0.4999999999990217 1 -1
-68 0.2499999999995832 1 -1
-69 0.7499999999995108 1 -1
-70 0 -2.081668171172169e-12 -1
-71 0 -0.5000000000009475 -1
-72 0 0.4999999999989593 -1
-73 -0 -4.626114306442256e-13 -4.625929269271485e-18
-74 0 0.4999999999993061 -0.500000000000694
-75 -0 -0.500000000000694 -0.4999999999993061
-76 0 -0.5000000000007709 0.500000000000694
-77 0 0.4999999999999229 0.4999999999993061
-78 -0 -0.7500000000003471 -0.7499999999996531
-79 -0 -0.7500000000003471 -0.2499999999986122
-80 0 0.7499999999996531 -0.7500000000003471
-81 0 0.2499999999986122 -0.7500000000003471
-82 0 0.2499999999989206 0.7499999999996531
-83 0 0.7499999999999614 0.7499999999996529
-84 0 0.4999999999997687 -1.040836398550719e-12
-85 0 0.2499999999994218 -0.250000000000347
-86 0 0.7499999999996531 -0.2500000000013878
-87 -0 -1.272139800908197e-12 -0.5
-88 -0 -0.2500000000005783 -0.2499999999996531
-89 0 -0.5000000000002313 1.04083177262145e-12
-90 -0 -0.2500000000013878 -0.7499999999996531
-91 0 -0.2500000000014263 0.7500000000003471
-92 0 -0.2500000000006168 0.250000000000347
-93 0 -1.272139800908197e-12 0.5
-94 0 0.7499999999999614 0.2499999999986122
-95 0 -0.7500000000003855 0.2500000000013878
-96 0 0.2499999999997301 0.249999999999653
-97 0 -0.7500000000003855 0.7500000000003471
-98 1 -6.649912102455838e-13 1.445325340891183e-13
-99 1 0.4999999999991953 -0.5000000000006698
-100 1 -0.500000000000694 -0.4999999999993061
-101 1 -0.5000000000008047 0.500000000000718
-102 1 0.4999999999991953 0.5000000000000241
-103 1 0.7499999999995977 -0.7500000000003348
-104 1 0.2499999999985568 -0.7500000000003348
-105 1 -0.7500000000003471 -0.7499999999996531
-106 1 -0.7500000000003471 -0.2499999999986122
-107 1 0.2499999999992652 -0.2500000000002626
-108 1 -1.373329690708876e-12 -0.4999999999999277
-109 1 -0.2500000000006795 -0.2499999999995808
-110 1 -0.5000000000003325 1.113100352630644e-12
-111 1 -0.2500000000013878 -0.7499999999996531
-112 1 0.2499999999985568 0.750000000000012
-113 1 0.7499999999995977 0.750000000000012
-114 1 0.4999999999996675 -9.685678185415252e-13
-115 1 0.7499999999995977 -0.2500000000013757
-116 1 0.7499999999995977 0.2499999999989712
-117 1 -0.2500000000014432 0.750000000000359
-118 1 -0.2500000000007349 0.2500000000004313
-119 1 -1.373329690708876e-12 0.5000000000000723
-120 1 -0.7500000000004023 0.2500000000013998
-121 1 0.2499999999992652 0.2500000000000843
-122 1 -0.7500000000004023 0.750000000000359
-123 -1 0 4.625929269271485e-18
-124 -1 0.4999999999993061 -0.500000000000694
-125 -1 0.500000000000694 0.4999999999993061
-126 -1 -0.500000000000694 -0.4999999999993061
-127 -1 -0.4999999999993061 0.500000000000694
-128 -1 0.7499999999996531 -0.7500000000003471
-129 -1 0.2499999999986122 -0.7500000000003471
-130 -1 0.7500000000003471 0.7499999999996531
-131 -1 0.7500000000003471 0.2499999999986122
-132 -1 -0.7500000000003471 -0.7499999999996531
-133 -1 -0.7500000000003471 -0.2499999999986122
-134 -1 -0.7499999999996531 0.7500000000003471
-135 -1 -0.2499999999986122 0.7500000000003471
-136 -1 0.2499999999996531 -0.250000000000347
-137 -1 -1.040834085586084e-12 -0.5
-138 -1 -0.250000000000347 -0.2499999999996531
-139 -1 -0.5 1.040836398550719e-12
-140 -1 0.250000000000347 0.2499999999996531
-141 -1 0.5 -1.04083177262145e-12
-142 -1 1.040834085586084e-12 0.5
-143 -1 0.2500000000013878 0.7499999999996531
-144 -1 0.7499999999996531 -0.2500000000013878
-145 -1 -0.2500000000013878 -0.7499999999996531
-146 -1 -0.2499999999996531 0.250000000000347
-147 -1 -0.7499999999996531 0.2500000000013878
-148 -0.6222222222227157 -1 -0.5138888888879271
-149 -0.2916666666672449 -1 -0.6041666666662184
-150 -0.6166666666671755 -1 0.508333333334299
-151 -0.2694444444449919 -1 0.6055555555562224
-152 -0.3083333333335878 -1 0.2541666666681903
-153 -0.4430555555560837 -1 0.5569444444452607
-154 -0.1347222222224959 -1 0.302777777779152
-155 -0.1458333333336224 -1 -0.3020833333320684
-156 -0.4569444444449803 -1 -0.5590277777770727
-157 -0.3111111111113579 -1 -0.2569444444429227
-158 -0.8111111111113578 -1 -0.2569444444429227
-159 -0.5 -1 2.081668171172169e-12
-160 -0.8083333333335878 -1 0.2541666666681903
-161 -0.8111111111113578 -1 -0.7569444444439635
-162 -0.5611111111120517 -1 -0.7569444444439635
-163 -0.5583333333342817 -1 0.7541666666671495
-164 -0.8083333333335878 -1 0.7541666666671495
-165 -0.3958333333343164 -1 -0.8020833333331092
-166 -0.1458333333336224 -1 -0.8020833333331092
-167 -0.1347222222224959 -1 0.8027777777781112
-168 -0.3847222222231899 -1 0.8027777777781112
-169 0.3833333333329746 -1 -0.5083333333324466
-170 0.7305555555551697 -1 -0.605555555555099
-171 0.3777777777774299 -1 0.513888888889877
-172 0.7083333333329257 -1 0.6041666666673119
-173 0.688888888888715 -1 0.2569444444459794
-174 0.5430555555551778 -1 0.5590277777785945
-175 0.8541666666664629 -1 0.3020833333346968
-176 0.8652777777775849 -1 -0.3027777777765087
-177 0.5569444444440722 -1 -0.5569444444437728
-178 0.6916666666664872 -1 -0.2541666666651825
-179 0.5 -1 2.081668171172169e-12
-180 0.1916666666664873 -1 -0.2541666666651825
-181 0.188888888888715 -1 0.2569444444459794
-182 0.1916666666664873 -1 -0.7541666666662232
-183 0.4416666666659982 -1 -0.7541666666662232
-184 0.4388888888882258 -1 0.7569444444449385
-185 0.188888888888715 -1 0.7569444444449385
-186 0.6152777777770957 -1 -0.8027777777775496
-187 0.8652777777775849 -1 -0.8027777777775496
-188 0.8541666666664629 -1 0.8020833333336559
-189 0.6041666666659737 -1 0.8020833333336559
-190 0.6222222222227157 1 0.5138888888879271
-191 0.2916666666672449 1 0.6041666666662184
-192 0.3777777777774299 1 -0.513888888889877
-193 0.7083333333329257 1 -0.6041666666673119
-194 0.688888888888715 1 -0.2569444444459794
-195 0.5430555555551778 1 -0.5590277777785945
-196 0.8541666666664629 1 -0.3020833333346968
-197 0.3111111111113579 1 0.2569444444429227
-198 0.4569444444449803 1 0.5590277777770727
-199 0.1458333333336224 1 0.3020833333320684
-200 0.8111111111113578 1 0.2569444444429227
-201 0.5 1 -2.081668171172169e-12
-202 0.188888888888715 1 -0.2569444444459794
-203 0.5611111111120517 1 0.7569444444439635
-204 0.8111111111113578 1 0.7569444444439635
-205 0.4388888888882258 1 -0.7569444444449385
-206 0.188888888888715 1 -0.7569444444449385
-207 0.1458333333336224 1 0.8020833333331092
-208 0.3958333333343164 1 0.8020833333331092
-209 0.8541666666664629 1 -0.8020833333336559
-210 0.6041666666659737 1 -0.8020833333336559
-211 -0.3833333333329746 1 0.5083333333324466
-212 -0.7305555555551697 1 0.605555555555099
-213 -0.6222222222227157 1 -0.5138888888898816
-214 -0.2916666666672449 1 -0.6041666666673461
-215 -0.3111111111113579 1 -0.2569444444459816
-216 -0.4569444444449803 1 -0.5590277777786139
-217 -0.1458333333336224 1 -0.3020833333347139
-218 -0.6916666666664874 1 0.2541666666651825
-219 -0.5569444444440722 1 0.5569444444437728
-220 -0.8652777777775849 1 0.3027777777765087
-221 -0.1916666666664873 1 0.2541666666651825
-222 -0.5 1 -2.081668171172169e-12
-223 -0.8111111111113578 1 -0.2569444444459816
-224 -0.4416666666659982 1 0.7541666666662232
-225 -0.1916666666664873 1 0.7541666666662232
-226 -0.5611111111120517 1 -0.7569444444449408
-227 -0.8111111111113578 1 -0.7569444444449408
-228 -0.8652777777775849 1 0.8027777777775496
-229 -0.6152777777770957 1 0.8027777777775496
-230 -0.1458333333336224 1 -0.802083333333673
-231 -0.3958333333343164 1 -0.802083333333673
-232 0.6166666666671755 0.5083333333324601 1
-233 0.2694444444449919 0.6055555555551354 1
-234 0.3833333333329746 -0.5083333333342853 1
-235 0.7305555555551697 -0.6055555555561859 1
-236 0.6916666666664874 -0.2541666666681835 1
-237 0.5569444444440722 -0.5569444444452356 1
-238 0.8652777777775849 -0.3027777777791338 1
-239 0.3083333333335878 0.2541666666651892 1
-240 0.4430555555560837 0.5569444444437978 1
-241 0.1347222222224959 0.3027777777765269 1
-242 0.5 -2.081668171172169e-12 1
-243 0.8083333333335878 0.2541666666651892 1
-244 0.1916666666664873 -0.2541666666681835 1
-245 0.5583333333342817 0.7541666666662301 1
-246 0.8083333333335878 0.7541666666662301 1
-247 0.4416666666659982 -0.7541666666671427 1
-248 0.1916666666664873 -0.7541666666671427 1
-249 0.1347222222224959 0.8027777777775678 1
-250 0.3847222222231899 0.8027777777775678 1
-251 0.8652777777775849 -0.8027777777780929 1
-252 0.6152777777770957 -0.8027777777780929 1
-253 -0.6222222222227157 -0.5138888888885748 1
-254 -0.2916666666672449 -0.6041666666669124 1
-255 -0.3833333333329746 0.5083333333330016 1
-256 -0.7305555555551697 0.6055555555558852 1
-257 -0.3111111111113579 -0.2569444444453282 1
-258 -0.4569444444449803 -0.5590277777777436 1
-259 -0.1458333333336224 -0.3020833333344971 1
-260 -0.6916666666664874 0.2541666666675416 1
-261 -0.5569444444440722 0.5569444444444434 1
-262 -0.8652777777775849 0.3027777777789835 1
-263 -0.8111111111113578 -0.2569444444432465 1
-264 -0.5 0 1
-265 -0.1916666666664873 0.25416666666546 1
-266 -0.5611111111120517 -0.7569444444442874 1
-267 -0.8111111111113578 -0.7569444444442874 1
-268 -0.4416666666659982 0.7541666666665008 1
-269 -0.1916666666664873 0.7541666666665008 1
-270 -0.1458333333336224 -0.8020833333334563 1
-271 -0.3958333333343164 -0.8020833333334563 1
-272 -0.8652777777775849 0.8027777777779426 1
-273 -0.6152777777770957 0.8027777777779426 1
-274 -0.6166666666671755 0.5083333333324602 -1
-275 -0.2694444444449919 0.6055555555551354 -1
-276 -0.6166666666671755 -0.508333333334299 -1
-277 -0.2694444444449919 -0.6055555555562224 -1
-278 -0.1347222222224959 -0.302777777779152 -1
-279 -0.4430555555560837 -0.5569444444452607 -1
-280 -0.3083333333335878 -0.2541666666681903 -1
-281 -0.3083333333335878 0.2541666666651893 -1
-282 -0.4430555555560837 0.5569444444437979 -1
-283 -0.1347222222224959 0.3027777777765269 -1
-284 -0.8083333333335878 0.2541666666651893 -1
-285 -0.5 -2.081668171172169e-12 -1
-286 -0.8083333333335878 -0.2541666666681903 -1
-287 -0.5583333333342817 0.7541666666662301 -1
-288 -0.8083333333335878 0.7541666666662301 -1
-289 -0.8083333333335878 -0.7541666666671495 -1
-290 -0.5583333333342817 -0.7541666666671495 -1
-291 -0.1347222222224959 0.8027777777775678 -1
-292 -0.3847222222231899 0.8027777777775678 -1
-293 -0.3847222222231899 -0.8027777777781112 -1
-294 -0.1347222222224959 -0.8027777777781112 -1
-295 0.3833333333329746 0.5083333333324466 -1
-296 0.7305555555551697 0.605555555555099 -1
-297 0.3777777777774299 -0.513888888889877 -1
-298 0.7083333333329257 -0.6041666666673119 -1
-299 0.8541666666664629 -0.3020833333346968 -1
-300 0.5430555555551778 -0.5590277777785945 -1
-301 0.688888888888715 -0.2569444444459794 -1
-302 0.6916666666664874 0.2541666666651825 -1
-303 0.5569444444440722 0.5569444444437728 -1
-304 0.8652777777775849 0.3027777777765087 -1
-305 0.5 -2.081668171172169e-12 -1
-306 0.1916666666664873 0.2541666666651825 -1
-307 0.188888888888715 -0.2569444444459794 -1
-308 0.4416666666659982 0.7541666666662232 -1
-309 0.1916666666664873 0.7541666666662232 -1
-310 0.188888888888715 -0.7569444444449385 -1
-311 0.4388888888882258 -0.7569444444449385 -1
-312 0.8652777777775849 0.8027777777775496 -1
-313 0.6152777777770957 0.8027777777775496 -1
-314 0.6041666666659737 -0.8020833333336559 -1
-315 0.8541666666664629 -0.8020833333336559 -1
-316 -0.5614664609412165 0.8122102348391909 -0.4351431567238753
-317 -0.1393115268198863 0.2888304651603905 -0.3662376759809275
-318 -0.3775027635566263 -0.3360704556656302 -0.7756926111322943
-319 -0.5403016768768191 -0.6665750337665026 -0.5046892834124488
-320 -0.8083333333335878 -0.5041666666674964 -0.7499999999996531
-321 -0.5569444444440722 0.8027777777779426 0.7541666666662232
-322 -0.7305555555551697 0.8027777777779426 0.8027777777775496
-323 -0.8652777777775849 0.5527777777782896 0.7499999999996531
-324 -0.8652777777775849 0.7500000000003471 0.5527777777772025
-325 -0.6916666666664874 0.7500000000003471 0.5041666666658764
-326 -0.6194444444449456 -0.7541666666671495 -0.7569444444439635
-327 -0.4541666666672102 -0.7541666666671495 -0.8020833333331092
-328 -0.1916666666664873 0.5041666666664623 0.7499999999996531
-329 -0.6916666666664874 0.5041666666668478 0.7499999999996531
-330 -0.3833333333329746 0.7541666666665008 0.7541666666662232
-331 -0.1347222222224959 -0.7500000000003855 0.5527777777784582
-332 -0.3083333333335878 -0.7500000000003855 0.5041666666674964
-333 -0.8083333333335878 -0.7499999999996531 0.5041666666674964
-334 -0.5 -0.5000000000000385 0.500000000000694
-335 -0.5 -0.7499999999996531 0.2500000000013878
-336 -0.8111111111113578 -0.5069444444439404 0.7500000000003471
-337 -0.3111111111113579 -0.5069444444446729 0.7500000000003471
-338 -0.6194444444449456 -0.7569444444442874 0.7541666666671495
-339 -0.2805555555561184 -0.8020833333334563 0.8027777777781112
-340 -0.8111111111113578 0.7499999999996531 -0.5069444444452877
-341 -0.5 -0.7500000000003471 -0.2499999999986122
-342 -0.8111111111113578 -0.7500000000003471 -0.5069444444436166
-343 -0.5 -0.5 1.040836398550719e-12
-344 -0.5 -0.2500000000003855 0.250000000000347
-345 -0.5 -2.313057153221128e-13 0
-346 -0.5 0.2499999999993062 0.7499999999996531
-347 -0.5 0.5000000000003084 0.4999999999993061
-348 -0.2805555555561184 0.8027777777775678 -0.802083333333673
-349 -0.5 -0.2499999999993446 0.7500000000003471
-350 -0.5 -3.846922780326167e-14 0.5
-351 -0.1916666666664873 0.7499999999999615 0.5041666666658763
-352 -0.1458333333336224 -0.5520833333338417 0.7500000000003471
-353 -0.4541666666672102 0.7541666666662301 -0.802083333333673
-354 -0.6194444444449456 0.7541666666662301 -0.7569444444449408
-355 -0.8083333333335878 0.5041666666658832 -0.7500000000003471
-356 -0.5 0.2500000000001157 0.2499999999996531
-357 -0.2805555555561184 -0.8027777777781112 -0.8020833333331092
-358 -0.4541666666672102 -0.8020833333334563 0.7541666666671495
-359 -0.5 0.7500000000003471 0.2499999999986122
-360 -0.5 0.2499999999986122 -0.7500000000003471
-361 -0.6458333333336225 -0.7500000000003471 -0.5520833333327623
-362 -0.5 -0.250000000000347 -0.2499999999996531
-363 -0.1458333333336224 -0.7500000000003471 -0.5520833333327623
-364 -0.5 -0.2500000000013878 -0.7499999999996531
-365 -0.5 -1.272139800908197e-12 -0.5
-366 -0.1347222222224959 -0.5527777777784582 -0.7499999999996531
-367 -0.1347222222224959 0.5527777777772207 -0.7500000000003471
-368 -0.1458333333336224 0.7499999999996531 -0.55208333333402
-369 -0.5 -0.5000000000010408 -0.4999999999989592
-370 -0.3111111111113579 -0.7500000000003471 -0.5069444444436166
-371 -0.7807332304706083 0.6561051174199424 0.03242842163771542
-372 -0.2807332304706083 0.9061051174195954 -0.2175715783629785
-373 -0.2807332304706083 0.4061051174193641 -0.2175715783619376
-374 -0.7807332304706083 0.4061051174195954 -0.2175715783619376
-375 -0.7807332304706083 0.9061051174195954 -0.2175715783629785
-376 -0.2154890967435656 0.6444152325801953 -0.4852021713241368
-377 -0.06965576340994317 0.6444152325801953 -0.1831188379915046
-378 -0.380766874521301 0.6444152325801953 -0.4400632824354046
-379 -0.3779890967435309 0.3985818992464253 -0.6831188379904638
-380 -0.06965576340994317 0.3944152325798483 -0.4331188379908107
-381 -0.06965576340994317 0.1444152325799639 -0.1831188379904638
-382 -0.5918443415819661 0.9061051174195954 -0.4745160228068784
-383 -0.7807332304706083 0.6561051174192485 -0.4675715783622846
-384 -0.5 0.2499999999994217 -0.250000000000347
-385 -0.4970847151119009 -0.4222018944999646 -0.8878463055661472
-386 -0.6887513817783131 -0.1680352278338559 -0.8878463055661472
-387 -0.6887513817783131 -0.4180352278331621 -0.6378463055658001
-388 -0.3345847151119355 -0.6680352278328151 -0.6899296388992564
-389 -0.06965576340994317 0.1444152325791544 -0.6831188379904638
-390 -0.2043779856324391 0.4471930103577629 -0.6831188379904638
-391 -0.323473604000809 -0.4708130056109263 -0.8878463055661472
-392 -0.1887513817783131 -0.1680352278338559 -0.8878463055661472
-393 -0.5696557634099432 0.3944152325798483 -0.4331188379908107
-394 -0.1887513817783131 -0.4180352278331621 -0.6378463055658001
-395 -0.1887513817783131 -0.6680352278328151 -0.3878463055651063
-396 -0.3503889938805514 0.5505203499997906 -0.4006904163524014
-397 -0.5812619495497674 -0.8332875168832513 -0.509289086150188
-398 -0.415984171772032 -0.8332875168832513 -0.5544279750393336
-399 -0.7701508384384095 -0.5832875168835983 -0.5023446417058774
-400 -0.2701508384384095 -0.8332875168832513 -0.2523446417051836
-401 -0.2701508384384095 -0.5832875168835983 -0.5023446417058774
-402 -0.4589022202167227 -0.5013227447160664 -0.6401909472723715
-403 0.5174375176429749 -0.4992875456809998 -0.6750874519348145
-404 0.5174375176429749 -0.4992875456809998 0.6886125802993774
-405 0.7587187588214874 0.0003562271590977772 0.5943062901497007
-406 0.7587187588214874 -0.2496437728415407 0.8443062901496887
-407 0.7587187588214874 -0.2496437728408324 0.344306290149761
-408 0.7587187588214874 -0.2496437728408324 -0.337543725967335
-409 0.7587187588214874 -0.2496437728415407 -0.8375437259674072
-410 0.7587187588214874 0.0003562271590977772 -0.5875437259677421
-411 0.3083333333335878 0.5041666666661915 0.7499999999996531
-412 0.3111111111113579 0.7499999999999615 0.5069444444436165
-413 0.6194444444449456 0.7541666666662301 0.7569444444439635
-414 0.4541666666672102 0.7541666666662301 0.8020833333331092
-415 0.1458333333336224 0.7499999999999615 0.5520833333327623
-416 0.5 0.2499999999986122 -0.7500000000003471
-417 0.2587187588214874 0.0003562271591531774 -0.5875437259677543
-418 0.2587187588214874 -0.2496437728415407 -0.8375437259674072
-419 0.7587187588214874 -0.7496437728404999 -0.3375437259663664
-420 0.6239965365990723 -0.7496437728404999 -0.6403215037449568
-421 0.4503854254879748 -0.7496437728404999 -0.5917103926336305
-422 0.3805555555552023 -0.7541666666671427 0.7569444444449385
-423 0.4476076477102024 -0.5065882172854383 -0.8375437259674072
-424 0.2805555555561184 0.8027777777775678 0.8020833333331092
-425 0.8652777777775849 -0.5527777777784952 0.750000000000359
-426 0.7587187588214874 -0.4996437728409022 0.5943062901500478
-427 0.6239965365990723 -0.5524215506185928 0.8443062901496887
-428 0.2587187588214874 -0.7496437728404999 0.3443062901507296
-429 0.2587187588214874 -0.4996437728408853 0.5943062901500358
-430 0.4476076477102024 -0.7496437728404999 0.6012507345946272
-431 0.188888888888715 -0.7500000000003855 0.5069444444452855
-432 0.6128854254879503 -0.5517271061741558 -0.8375437259674072
-433 0.8541666666664629 -0.5520833333340029 -0.7499999999996531
-434 0.7587187588214874 -0.4996437728408469 -0.5875437259670603
-435 0.4503854254879748 -0.5038104395076426 0.8443062901496887
-436 0.5087187588209983 -0.7496437728404999 0.8443062901496887
-437 0.5 0.7499999999999615 0.2499999999986122
-438 0.1347222222224959 0.5527777777775291 0.7499999999996531
-439 0.2587187588214874 -0.4996437728408469 -0.5875437259670603
-440 0.1916666666664873 -0.7500000000003471 -0.5041666666658764
-441 0.3805555555552023 -0.7569444444449385 -0.7541666666662232
-442 0.188888888888715 -0.5069444444452855 -0.7499999999996531
-443 0.5 0.2499999999993663 -0.2500000000003349
-444 0.2587187588214874 -0.2496437728407312 -0.3375437259674072
-445 0.5 -5.638013204449047e-13 7.22639540799245e-14
-446 0.5 0.7499999999995977 -0.2500000000013757
-447 0.688888888888715 0.7499999999995977 -0.5069444444452734
-448 0.188888888888715 0.7499999999996531 -0.5069444444452855
-449 0.5 0.4999999999992507 -0.5000000000006819
-450 0.8541666666664629 -0.7500000000004023 0.5520833333340149
-451 0.7194444444440478 -0.8027777777780929 0.8020833333336559
-452 0.5 0.4999999999995591 -6.818712261491555e-13
-453 0.1916666666664873 -0.5041666666675282 0.7500000000003471
-454 0.2587187588214874 -0.7496437728404999 -0.3375437259663664
-455 0.1916666666664873 0.5041666666658764 -0.7500000000003471
-456 0.3805555555552023 0.7541666666662232 -0.7569444444449385
-457 0.6916666666664874 0.5041666666658209 -0.7500000000003348
-458 0.6128854254879503 -0.7496437728404999 0.6463896234833446
-459 0.7194444444440478 -0.8020833333336559 -0.8027777777775496
-460 0.8652777777775849 -0.7500000000003471 -0.5527777777772025
-461 0.5 0.2499999999989206 0.7499999999996531
-462 0.2587187588214874 -0.2496437728415407 0.8443062901496887
-463 0.2587187588214874 0.0003562271594615696 0.5943062901493418
-464 0.8111111111113578 0.7499999999995977 0.5069444444439756
-465 0.2587187588214874 -0.2496437728407312 0.3443062901496887
-466 0.5174375176429749 -0.4992875456809998 0.006762564182281494
-467 0.7587187588214874 -0.7496437728404999 0.3443062901507296
-468 0.2587187588214874 -0.4996437728408853 -0.08754372596706023
-469 0.8652777777775849 0.5527777777771472 -0.7500000000003348
-470 0.5 0.4999999999995591 0.499999999999665
-471 0.5 0.249999999999629 0.2499999999997253
-472 0.5087187588209983 -0.7496437728404999 -0.8375437259674072
-473 0.8541666666664629 0.7499999999995977 -0.5520833333339908
-474 0.5458333333329501 0.7541666666662232 -0.8020833333336559
-475 0.7194444444440478 0.8027777777775496 -0.8020833333336559
-476 0.8083333333335878 0.5041666666658278 0.750000000000012
-$EndNodes
-$Elements
-235
-1 11 2 47 44 276 61 7 126 286 62 289 320 132 145
-2 11 2 47 44 211 256 212 125 321 322 219 325 324 323
-3 11 2 47 44 2 22 256 212 24 273 272 228 322 229
-4 11 2 47 44 148 276 149 43 326 327 156 162 165 290
-5 11 2 47 44 9 19 255 77 21 265 269 83 328 82
-6 11 2 47 44 256 2 212 125 272 228 322 323 324 130
-7 11 2 47 44 211 256 125 255 321 323 325 330 329 261
-8 11 2 47 44 151 150 76 34 153 332 331 154 95 152
-9 11 2 47 44 150 127 76 34 333 334 332 152 95 335
-10 11 2 47 44 253 127 76 150 336 334 337 338 332 333
-11 11 2 47 44 16 151 254 10 168 339 271 18 270 167
-12 11 2 47 44 6 213 58 124 227 223 59 128 144 340
-13 11 2 47 44 34 126 148 40 341 342 157 159 158 133
-14 11 2 47 44 73 34 76 123 89 95 92 345 344 343
-15 11 2 47 44 77 19 255 125 82 265 328 347 329 346
-16 11 2 47 44 12 275 214 64 291 348 230 66 231 292
-17 11 2 47 44 76 13 19 125 349 264 91 350 346 143
-18 11 2 47 44 2 58 212 125 60 220 228 130 324 131
-19 11 2 47 44 150 253 3 16 338 267 164 163 17 266
-20 11 2 47 44 123 13 127 76 142 135 146 344 334 349
-21 11 2 47 44 55 9 211 77 57 225 221 94 351 83
-22 11 2 47 44 9 77 255 211 83 328 269 225 330 351
-23 11 2 47 44 77 255 211 125 328 330 351 347 325 329
-24 11 2 47 44 19 253 76 254 257 337 91 259 352 258
-25 11 2 47 44 276 148 7 43 326 161 289 290 44 162
-26 11 2 47 44 123 34 76 127 343 95 344 146 334 335
-27 11 2 47 44 19 13 255 125 264 260 265 346 329 143
-28 11 2 47 44 123 13 76 125 142 349 344 140 350 143
-29 11 2 47 44 274 275 64 214 282 292 287 353 231 348
-30 11 2 47 44 211 256 22 212 321 273 224 219 229 322
-31 11 2 47 44 255 13 256 125 260 262 261 329 323 143
-32 11 2 47 44 76 13 127 253 349 135 334 337 336 263
-33 11 2 47 44 274 213 64 6 354 226 287 288 65 227
-34 11 2 47 44 148 276 7 126 326 289 161 342 132 320
-35 11 2 47 44 274 61 124 6 284 129 355 288 128 63
-36 11 2 47 44 127 150 40 34 333 160 147 335 159 152
-37 11 2 47 44 58 211 212 125 218 219 220 131 324 325
-38 11 2 47 44 2 13 125 256 14 143 130 272 323 262
-39 11 2 47 44 76 151 10 254 331 167 97 352 270 339
-40 11 2 47 44 19 73 125 77 93 356 346 82 347 96
-41 11 2 47 44 40 148 7 126 158 161 42 133 132 342
-42 11 2 47 44 76 151 34 10 331 154 95 97 35 167
-43 11 2 47 44 213 274 64 214 354 287 226 216 231 353
-44 11 2 47 44 34 126 40 123 341 133 159 343 139 138
-45 11 2 47 44 127 150 3 40 333 164 134 147 41 160
-46 11 2 47 44 123 34 127 40 343 335 146 139 147 159
-47 11 2 47 44 76 13 253 19 349 263 337 91 257 264
-48 11 2 47 44 22 9 255 211 23 269 268 224 330 225
-49 11 2 47 44 276 277 149 43 279 357 327 290 165 293
-50 11 2 47 44 19 76 10 254 91 97 20 259 270 352
-51 11 2 47 44 253 150 76 254 338 332 337 258 352 358
-52 11 2 47 44 150 151 76 254 153 331 332 358 352 339
-53 11 2 47 44 150 253 16 254 338 266 163 358 271 258
-54 11 2 47 44 55 77 211 125 94 351 221 359 325 347
-55 11 2 47 44 253 13 127 3 263 135 336 267 134 15
-56 11 2 47 44 151 150 16 254 153 163 168 339 271 358
-57 11 2 47 44 213 274 124 6 354 355 340 227 128 288
-58 11 2 47 44 127 253 3 150 336 267 134 333 164 338
-59 11 2 47 44 277 11 149 43 294 166 357 293 165 45
-60 11 2 47 44 58 55 211 125 222 221 218 131 325 359
-61 11 2 47 44 70 124 274 61 360 355 281 285 284 129
-62 11 2 47 44 211 256 255 22 321 261 330 224 268 273
-63 11 2 47 44 76 73 123 125 92 345 344 350 140 356
-64 11 2 47 44 55 73 77 125 84 96 94 359 347 356
-65 11 2 47 44 19 73 76 125 93 92 91 346 350 356
-66 11 2 47 44 148 276 126 149 326 320 342 156 361 327
-67 11 2 47 44 34 73 75 123 89 88 79 343 362 345
-68 11 2 47 44 11 34 75 149 36 79 78 166 363 155
-69 11 2 47 44 73 70 75 61 87 90 88 365 364 285
-70 11 2 47 44 70 11 75 277 71 78 90 278 366 294
-71 11 2 47 44 277 149 11 75 357 166 294 366 78 363
-72 11 2 47 44 12 70 74 275 72 81 80 291 367 283
-73 11 2 47 44 275 12 214 74 291 230 348 367 368 80
-74 11 2 47 44 55 214 12 74 217 230 56 86 80 368
-75 11 2 47 44 126 123 34 61 138 343 341 145 369 137
-76 11 2 47 44 34 149 148 75 155 156 157 79 370 363
-77 11 2 47 44 73 125 55 316 356 359 84 373 372 371
-78 11 2 47 44 123 125 73 316 140 356 345 374 373 371
-79 11 2 47 44 55 125 58 316 359 131 222 372 375 371
-80 11 2 47 44 213 214 55 317 216 217 215 378 377 376
-81 11 2 47 44 274 214 213 317 353 216 354 379 378 376
-82 11 2 47 44 73 55 74 317 84 86 85 381 380 377
-83 11 2 47 44 55 58 213 316 222 223 215 372 382 375
-84 11 2 47 44 58 123 124 316 141 136 144 375 383 374
-85 11 2 47 44 124 213 58 316 340 223 144 383 375 382
-86 11 2 47 44 125 123 58 316 140 141 131 371 375 374
-87 11 2 47 44 123 61 124 73 137 129 136 345 384 365
-88 11 2 47 44 61 70 124 73 285 360 129 365 384 87
-89 11 2 47 44 126 276 61 318 320 286 145 387 386 385
-90 11 2 47 44 149 276 126 318 327 320 361 388 387 385
-91 11 2 47 44 275 274 70 317 282 281 283 390 389 379
-92 11 2 47 44 70 276 277 318 280 279 278 392 391 385
-93 11 2 47 44 73 74 70 317 85 81 87 381 389 380
-94 11 2 47 44 70 274 124 317 281 355 360 389 393 379
-95 11 2 47 44 274 213 124 317 354 340 355 379 393 378
-96 11 2 47 44 277 276 149 318 279 327 357 391 388 385
-97 11 2 47 44 275 214 274 317 348 353 282 390 379 376
-98 11 2 47 44 73 75 123 61 88 362 345 365 137 364
-99 11 2 47 44 34 123 75 61 343 362 79 369 364 137
-100 11 2 47 44 61 70 75 318 285 90 364 386 394 392
-101 11 2 47 44 75 70 277 318 90 278 366 394 391 392
-102 11 2 47 44 277 149 75 318 357 363 366 391 394 388
-103 11 2 47 44 74 275 70 317 367 283 81 380 389 390
-104 11 2 47 44 214 275 74 317 348 367 368 376 380 390
-105 11 2 47 44 55 214 74 317 217 368 86 377 380 376
-106 11 2 47 44 126 61 34 318 145 369 341 387 395 386
-107 11 2 47 44 124 123 73 316 136 345 384 383 373 374
-108 11 2 47 44 70 124 73 317 360 384 87 389 381 393
-109 11 2 47 44 61 75 34 318 364 79 369 386 395 394
-110 11 2 47 44 276 70 61 318 280 285 286 385 386 392
-111 11 2 47 44 55 73 316 317 84 373 372 377 396 381
-112 11 2 47 44 213 317 55 316 378 377 215 382 372 396
-113 11 2 47 44 124 213 316 317 340 382 383 393 396 378
-114 11 2 47 44 73 124 316 317 384 383 373 381 396 393
-115 11 2 47 44 126 148 149 319 342 156 361 399 398 397
-116 11 2 47 44 34 148 126 319 157 342 341 400 399 397
-117 11 2 47 44 75 148 34 319 370 157 79 401 400 397
-118 11 2 47 44 149 148 75 319 156 370 363 398 401 397
-119 11 2 47 44 126 149 318 319 361 388 387 399 402 398
-120 11 2 47 44 34 75 319 318 79 401 400 395 402 394
-121 11 2 47 44 75 149 319 318 363 398 401 394 402 388
-122 11 2 47 44 319 34 318 126 400 395 402 399 387 341
-123 11 2 48 46 102 28 404 98 112 406 405 121 407 119
-124 11 2 48 46 98 49 403 99 108 409 408 107 410 104
-125 11 2 48 46 77 232 190 191 411 413 412 415 198 414
-126 11 2 48 46 74 49 403 70 416 409 417 81 418 305
-127 11 2 48 46 37 403 170 169 419 420 176 178 177 421
-128 11 2 48 46 25 234 171 10 247 422 184 26 185 248
-129 11 2 48 46 70 403 297 49 418 423 307 305 301 409
-130 11 2 48 46 232 233 31 191 240 250 245 414 208 424
-131 11 2 48 46 28 101 235 404 117 425 238 406 427 426
-132 11 2 48 46 34 404 76 171 428 429 95 181 431 430
-133 11 2 48 46 403 298 49 100 432 299 409 434 111 433
-134 11 2 48 46 404 234 171 25 435 422 430 436 184 247
-135 11 2 48 46 55 52 190 77 201 200 197 94 412 437
-136 11 2 48 46 233 232 77 191 240 411 438 424 415 414
-137 11 2 48 46 403 169 75 297 421 440 439 423 442 441
-138 11 2 48 46 404 234 25 235 435 247 436 427 252 237
-139 11 2 48 46 99 73 403 98 443 444 410 107 408 445
-140 11 2 48 46 98 49 100 403 108 111 109 408 434 409
-141 11 2 48 46 28 101 404 98 117 426 406 119 407 118
-142 11 2 48 46 99 55 192 74 446 202 447 449 448 86
-143 11 2 48 46 101 235 172 4 425 451 450 122 188 251
-144 11 2 48 46 73 55 77 99 84 94 96 443 452 446
-145 11 2 48 46 234 10 19 76 248 20 244 453 91 97
-146 11 2 48 46 37 34 403 169 179 454 419 178 421 180
-147 11 2 48 46 99 74 192 295 449 448 447 457 456 455
-148 11 2 48 46 25 404 172 171 436 458 189 184 174 430
-149 11 2 48 46 235 25 172 4 252 189 451 251 188 27
-150 11 2 48 46 298 403 170 100 432 420 459 433 460 434
-151 11 2 48 46 37 98 100 403 110 109 106 419 434 408
-152 11 2 48 46 11 70 75 297 71 90 78 310 442 307
-153 11 2 48 46 77 28 19 404 461 242 82 463 462 406
-154 11 2 48 46 52 102 1 190 116 113 54 200 204 464
-155 11 2 48 46 73 404 403 98 465 466 444 445 408 407
-156 11 2 48 46 404 37 34 403 467 179 428 466 454 419
-157 11 2 48 46 10 34 76 171 35 95 97 185 431 181
-158 11 2 48 46 404 37 98 101 467 110 407 426 118 120
-159 11 2 48 46 192 74 12 295 448 80 206 456 309 455
-160 11 2 48 46 73 55 99 74 84 446 443 85 449 86
-161 11 2 48 46 404 34 76 403 428 95 429 466 468 454
-162 11 2 48 46 73 404 76 403 465 429 92 444 468 466
-163 11 2 48 46 296 5 99 49 312 103 469 304 104 51
-164 11 2 48 46 52 102 77 98 116 470 437 114 471 121
-165 11 2 48 46 295 192 67 12 456 205 308 309 68 206
-166 11 2 48 46 99 55 77 52 446 94 452 115 437 201
-167 11 2 48 46 70 403 75 297 418 439 90 307 442 423
-168 11 2 48 46 74 49 70 295 416 305 81 455 306 302
-169 11 2 48 46 73 19 76 404 93 91 92 465 429 462
-170 11 2 48 46 10 234 171 76 248 422 185 97 431 453
-171 11 2 48 46 11 34 169 75 36 180 182 78 440 79
-172 11 2 48 46 9 233 191 31 249 424 207 33 208 250
-173 11 2 48 46 404 234 19 76 435 244 462 429 91 453
-174 11 2 48 46 404 98 37 403 407 110 467 466 419 408
-175 11 2 48 46 169 403 46 297 421 472 183 441 311 423
-176 11 2 48 46 74 55 192 12 86 202 448 80 206 56
-177 11 2 48 46 404 172 37 101 458 175 467 426 120 450
-178 11 2 48 46 101 37 4 172 120 38 122 450 188 175
-179 11 2 48 46 99 192 193 295 447 195 473 457 474 456
-180 11 2 48 46 234 28 235 404 236 238 237 435 427 406
-181 11 2 48 46 403 298 297 49 432 300 423 409 301 299
-182 11 2 48 46 101 404 172 235 426 458 450 425 451 427
-183 11 2 48 46 19 233 232 77 241 240 239 82 411 438
-184 11 2 48 46 296 99 193 295 469 473 475 303 474 457
-185 11 2 48 46 296 99 295 49 469 457 303 304 302 104
-186 11 2 48 46 232 1 190 31 246 204 413 245 203 32
-187 11 2 48 46 70 73 403 74 87 444 418 81 417 85
-188 11 2 48 46 170 37 8 100 176 39 187 460 105 106
-189 11 2 48 46 49 298 8 100 299 315 50 111 105 433
-190 11 2 48 46 404 25 172 235 436 189 458 427 451 252
-191 11 2 48 46 170 298 8 46 459 315 187 186 48 314
-192 11 2 48 46 169 34 403 75 180 454 421 440 439 79
-193 11 2 48 46 74 49 99 403 416 104 449 417 410 409
-194 11 2 48 46 5 296 99 193 312 469 103 209 473 475
-195 11 2 48 46 37 170 403 100 176 420 419 106 434 460
-196 11 2 48 46 73 19 404 77 93 462 465 96 463 82
-197 11 2 48 46 298 170 8 100 459 187 315 433 105 460
-198 11 2 48 46 77 28 404 102 461 406 463 470 405 112
-199 11 2 48 46 74 49 295 99 416 302 455 449 457 104
-200 11 2 48 46 77 28 102 232 461 112 470 411 476 243
-201 11 2 48 46 232 102 190 1 476 464 413 246 204 113
-202 11 2 48 46 296 5 67 193 312 69 313 475 210 209
-203 11 2 48 46 77 28 232 19 461 243 411 82 239 242
-204 11 2 48 46 9 55 191 77 57 199 207 83 415 94
-205 11 2 48 46 19 233 77 9 241 438 82 21 83 249
-206 11 2 48 46 234 404 171 76 435 430 422 453 431 429
-207 11 2 48 46 295 296 67 193 303 313 308 474 210 475
-208 11 2 48 46 99 73 98 77 443 445 107 452 471 96
-209 11 2 48 46 192 99 193 52 447 473 195 194 196 115
-210 11 2 48 46 232 31 190 191 245 203 413 414 198 208
-211 11 2 48 46 73 34 403 76 89 454 444 92 468 95
-212 11 2 48 46 233 9 191 77 249 207 424 438 415 83
-213 11 2 48 46 102 404 77 98 405 463 470 121 471 407
-214 11 2 48 46 99 5 193 52 103 209 473 115 196 53
-215 11 2 48 46 55 77 190 191 94 412 197 199 198 415
-216 11 2 48 46 404 73 77 98 465 96 463 407 471 445
-217 11 2 48 46 295 74 12 70 455 80 309 306 72 81
-218 11 2 48 46 298 403 46 170 432 472 314 459 186 420
-219 11 2 48 46 73 34 75 403 89 79 88 444 439 454
-220 11 2 48 46 70 73 75 403 87 88 90 418 439 444
-221 11 2 48 46 403 169 46 170 421 183 472 420 186 177
-222 11 2 48 46 99 52 77 98 115 437 452 107 471 114
-223 11 2 48 46 404 37 172 171 467 175 458 430 174 173
-224 11 2 48 46 37 404 34 171 467 428 179 173 181 430
-225 11 2 48 46 99 73 74 403 443 85 449 410 417 444
-226 11 2 48 46 99 55 52 192 446 201 115 447 194 202
-227 11 2 48 46 101 28 235 4 117 238 425 122 251 29
-228 11 2 48 46 192 295 67 193 456 308 205 195 210 474
-229 11 2 48 46 11 169 46 297 182 183 47 310 311 441
-230 11 2 48 46 102 28 1 232 112 30 113 476 246 243
-231 11 2 48 46 403 298 46 297 432 314 472 423 311 300
-232 11 2 48 46 102 232 190 77 476 413 464 470 412 411
-233 11 2 48 46 52 102 190 77 116 464 200 437 412 470
-234 11 2 48 46 169 11 75 297 182 78 440 441 442 310
-235 11 2 48 46 234 28 404 19 236 406 435 244 462 242
-$EndElements
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..d9c816b9c 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,190 @@
/**
* @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: Mon Jan 18 2016
*
* @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/stiffness_matrix.verified b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/stiffness_matrix.verified
deleted file mode 100644
index 81770e0ca..000000000
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic_impl/stiffness_matrix.verified
+++ /dev/null
@@ -1,308 +0,0 @@
-%%MatrixMarket matrix coordinate real symmetric
-36 36 306
-1 1 4.5
-1 2 -1.85037170770859e-16
-1 5 1
-1 6 8.32667268468867e-17
-1 31 -2.12792746386488e-16
-1 32 0.5
-1 3 -4
-1 4 -2.77555756156289e-16
-1 11 -1.55431223447522e-15
-1 12 -5.55111512312579e-17
-1 9 3.02535774210355e-15
-1 10 -2
-2 2 4.5
-2 5 -0.5
-2 6 0.5
-2 31 0.5
-2 32 -6.47630097698008e-17
-2 3 2
-2 4 -2
-2 11 0
-2 12 -6.66133814775094e-16
-2 9 -2
-2 10 1.99840144432528e-15
-5 5 4.5
-5 6 -1.5
-5 31 0.5
-5 32 0
-5 3 -4
-5 4 2
-5 11 -2
-5 12 2.22044604925031e-16
-5 9 7.7715611723761e-16
-5 10 -2.22044604925031e-16
-6 6 4.5
-6 31 -0.5
-6 32 1
-6 3 -3.19189119579733e-16
-6 4 -2
-6 11 2
-6 12 -4
-6 9 -2.35922392732846e-16
-6 10 3.33066907387547e-16
-31 31 4.5
-31 32 2.32317978986721e-16
-31 3 -1.11022302462516e-16
-31 4 -4.93038065763132e-32
-31 11 -2
-31 12 2
-31 9 1.19348975147204e-15
-31 10 -2
-32 32 5.10406262854645
-32 3 0
-32 4 -2.22044604925031e-16
-32 11 0
-32 12 -4
-32 9 -2
-32 10 9.29811783123569e-16
-3 3 12
-3 4 -2
-3 11 1.22124532708767e-15
-3 12 -2
-3 9 -4
-3 10 2
-4 4 12
-4 11 -2
-4 12 -8.88178419700125e-16
-4 9 2
-4 10 -8
-11 11 12
-11 12 -2
-11 9 -8
-11 10 2
-12 12 12
-12 9 2
-12 10 -4
-9 9 24
-9 10 -4
-10 10 24
-1 13 0.5
-1 14 -0.5
-1 15 -4.16333634234434e-16
-1 16 -1.11022302462516e-16
-1 7 -2
-1 8 2
-2 13 -6.47630097698008e-17
-2 14 1
-2 15 7.40148683083438e-17
-2 16 -1.0547118733939e-15
-2 7 4.44089209850063e-16
-2 8 -4
-31 13 1
-31 14 -1.23259516440783e-32
-31 15 -4
-31 16 4.64635957973443e-16
-31 7 2.77555756156289e-17
-31 8 0
-32 13 -0.5
-32 14 0.197968685726773
-32 15 2
-32 16 -1.39593737145355
-32 7 -5.55111512312578e-17
-32 8 1.38777878078145e-17
-13 13 4.5
-13 14 -1.5
-13 9 0
-13 10 0
-13 15 -4
-13 16 2
-13 7 -2
-13 8 0
-14 14 5.10406262854645
-14 9 -1.11022302462516e-16
-14 10 4.44089209850063e-16
-14 15 -3.53613655510927e-16
-14 16 -1.39593737145355
-14 7 2
-14 8 -4
-9 15 -4
-9 16 2
-9 7 -8
-9 8 2
-10 15 2
-10 16 -8
-10 7 2
-10 8 -4
-15 15 12
-15 16 -2
-15 7 1.77635683940025e-15
-15 8 -2
-16 16 14.4162505141858
-16 7 -2
-16 8 2.22044604925031e-15
-7 7 12
-7 8 -2
-8 8 12
-33 33 4.5
-33 34 1.10000786939369e-16
-33 17 1
-33 18 1.20274161001059e-16
-33 29 -3.05311331771918e-16
-33 30 0.5
-33 35 -4
-33 36 -9.64236319054764e-16
-33 23 -1.22124532708767e-15
-33 24 -1.29526019539602e-16
-33 21 7.07767178198537e-16
-33 22 -2
-34 34 5.10406262854646
-34 17 -0.5
-34 18 0.197968685726773
-34 29 0.5
-34 30 -5.55111512312577e-17
-34 35 2
-34 36 -1.39593737145355
-34 23 5.55111512312578e-17
-34 24 -5.55111512312578e-16
-34 21 -2
-34 22 -2.4980018054066e-16
-17 17 4.5
-17 18 -1.5
-17 29 0.5
-17 30 0
-17 35 -4
-17 36 2
-17 23 -2
-17 24 1.66533453693773e-16
-17 21 3.33066907387547e-16
-17 22 -1.66533453693773e-16
-18 18 5.10406262854645
-18 29 -0.5
-18 30 1
-18 35 2.00957989624968e-16
-18 36 -1.39593737145355
-18 23 2
-18 24 -4
-18 21 -2.22044604925031e-16
-18 22 5.55111512312578e-16
-29 29 4.5
-29 30 0
-29 35 -1.11022302462516e-16
-29 36 1.66533453693773e-16
-29 23 -2
-29 24 2
-29 21 2.88657986402541e-15
-29 22 -2
-30 30 4.5
-30 35 0
-30 36 -2.22044604925031e-16
-30 23 0
-30 24 -4
-30 21 -2
-30 22 1.60982338570648e-15
-35 35 12
-35 36 -2
-35 23 7.7715611723761e-16
-35 24 -2
-35 21 -4
-35 22 2
-36 36 14.4162505141858
-36 23 -2
-36 24 0
-36 21 2
-36 22 -8
-23 23 12
-23 24 -2
-23 21 -8
-23 22 2
-24 24 12
-24 21 2
-24 22 -4
-21 21 24
-21 22 -4
-22 22 24
-33 25 0.5
-33 26 -0.5
-33 27 2.35922392732846e-16
-33 28 -3.88578058618805e-16
-33 19 -2
-33 20 2
-34 25 3.70074341541719e-17
-34 26 1
-34 27 -2.96059473233375e-16
-34 28 -8.32667268468867e-17
-34 19 -2.46519032881566e-32
-34 20 -4
-29 25 1
-29 26 0
-29 27 -4
-29 28 0
-29 19 3.33066907387547e-16
-29 20 0
-30 25 -0.5
-30 26 0.5
-30 27 2
-30 28 -2
-30 19 0
-30 20 1.66533453693773e-16
-25 25 4.5
-25 26 -1.5
-25 21 6.66133814775094e-16
-25 22 -2.22044604925031e-16
-25 27 -4
-25 28 2
-25 19 -2
-25 20 -1.11022302462516e-16
-26 26 4.5
-26 21 -5.55111512312578e-16
-26 22 1.33226762955019e-15
-26 27 5.55111512312578e-16
-26 28 -2
-26 19 2
-26 20 -4
-21 27 -4.00000000000001
-21 28 2
-21 19 -8
-21 20 2
-22 27 2
-22 28 -8.00000000000001
-22 19 2
-22 20 -4
-27 27 12
-27 28 -2
-27 19 8.88178419700125e-16
-27 20 -2
-28 28 12
-28 19 -2
-28 20 1.33226762955019e-15
-19 19 12
-19 20 -2
-20 20 12
-31 17 -1.19130347991335e-31
-31 18 -2.32317978986721e-16
-31 33 5.95651739956675e-32
-31 34 1.23259516440783e-32
-31 35 -1.19130347991335e-31
-31 36 -4.64635957973443e-16
-32 17 -2.32317978986721e-16
-32 18 -0.604062628546454
-32 33 1.23259516440783e-32
-32 34 0.302031314273227
-32 35 -4.64635957973443e-16
-32 36 -0.604062628546454
-13 17 5.95651739956675e-32
-13 18 -1.23259516440783e-32
-13 33 -1.19130347991335e-31
-13 34 2.32317978986721e-16
-13 35 -1.19130347991335e-31
-13 36 4.64635957973443e-16
-14 17 -1.23259516440783e-32
-14 18 0.302031314273227
-14 33 2.32317978986721e-16
-14 34 -0.604062628546455
-14 35 4.64635957973443e-16
-14 36 -0.604062628546455
-15 17 -1.19130347991335e-31
-15 18 -4.64635957973443e-16
-15 33 -1.19130347991335e-31
-15 34 4.64635957973443e-16
-15 35 -4.7652139196534e-31
-15 36 0
-16 17 -4.64635957973443e-16
-16 18 -0.604062628546454
-16 33 4.64635957973443e-16
-16 34 -0.604062628546454
-16 35 0
-16 36 -2.41625051418582
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/examples/optimization/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/CMakeLists.txt
similarity index 74%
rename from examples/optimization/CMakeLists.txt
rename to test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/CMakeLists.txt
index 49241bdcf..6d6ed5e7f 100644
--- a/examples/optimization/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/CMakeLists.txt
@@ -1,32 +1,37 @@
#===============================================================================
# @file CMakeLists.txt
#
-# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
+# @author Mauro Corrado <mauro.corrado@epfl.ch>
#
-# @date Mon Mar 24 11:30:00 2014
+# @date Wed Jan 13 11:56:18 2016
#
-# @brief configuration file for contact examples
+# @brief testing the correct behavior of the friction law included in
+# the cohesive linear law, in implicit
#
# @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
#
#===============================================================================
-register_example(fn_optimize fn_optimize.cc)
+register_test(test_cohesive_linear_friction
+ SOURCES test_cohesive_friction.cc
+ FILES_TO_COPY mesh_cohesive_friction.msh material.dat
+ PACKAGE cohesive_element
+ )
\ No newline at end of file
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/material.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/material.dat
new file mode 100644
index 000000000..cd9838d0c
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/material.dat
@@ -0,0 +1,17 @@
+material elastic [
+ name = bulk
+ rho = 2.7e-9 # density
+ E = 36000 # young's modulus
+ nu = 0.2 # poisson's ratio
+]
+
+material cohesive_linear_friction [
+ name = interface
+ beta = 1
+ G_c = 30e-3
+ penalty = 1.0e6
+ sigma_c = 2.0
+ contact_after_breaking = true
+ mu = 0.5
+ penalty_for_friction = 5.0e3
+]
\ No newline at end of file
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/mesh_cohesive_friction.msh b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/mesh_cohesive_friction.msh
new file mode 100644
index 000000000..d31ca4992
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/mesh_cohesive_friction.msh
@@ -0,0 +1,52 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+15
+1 -1 -1 0
+2 1 -1 0
+3 -1 0 0
+4 1 0 0
+5 -1 1 0
+6 1 1 0
+7 -2.752797989558076e-12 -1 0
+8 -2.752797989558076e-12 0 0
+9 -2.752797989558076e-12 1 0
+10 -1 -0.5000000000020591 0
+11 1 -0.5000000000020591 0
+12 -1 0.499999999998694 0
+13 1 0.499999999998694 0
+14 -2.75277023398246e-12 -0.5000000000020591 0
+15 -2.752825745133691e-12 0.499999999998694 0
+$EndNodes
+$Elements
+28
+1 15 2 0 1 1
+2 15 2 0 2 2
+3 15 2 0 3 3
+4 15 2 0 4 4
+5 15 2 0 5 5
+6 15 2 0 6 6
+7 1 2 0 1 1 7
+8 1 2 0 1 7 2
+9 1 2 0 2 3 8
+10 1 2 0 2 8 4
+11 1 2 0 3 5 9
+12 1 2 0 3 9 6
+13 1 2 0 4 1 10
+14 1 2 0 4 10 3
+15 1 2 0 5 2 11
+16 1 2 0 5 11 4
+17 1 2 0 6 3 12
+18 1 2 0 6 12 5
+19 1 2 0 7 4 13
+20 1 2 0 7 13 6
+21 3 2 0 1 1 7 14 10
+22 3 2 0 1 10 14 8 3
+23 3 2 0 1 7 2 11 14
+24 3 2 0 1 14 11 4 8
+25 3 2 0 2 3 8 15 12
+26 3 2 0 2 12 15 9 5
+27 3 2 0 2 8 4 13 15
+28 3 2 0 2 15 13 6 9
+$EndElements
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/test_cohesive_friction.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/test_cohesive_friction.cc
new file mode 100644
index 000000000..63ff01958
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/test_cohesive_friction.cc
@@ -0,0 +1,244 @@
+/**
+ * @file test_cohesive_friction.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Wed Jan 13 11:56:18 2016
+ *
+ * @brief testing the correct behavior of the friction law included in
+ * the cohesive linear law, in implicit
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "mesh_io.hh"
+#include "mesh_utils.hh"
+#include "static_communicator.hh"
+#include "solid_mechanics_model_cohesive.hh"
+#include "material.hh"
+#include "material_cohesive.hh"
+#include "aka_grid_dynamic.hh"
+#include "dof_synchronizer.hh"
+#include <cmath>
+#include <iostream>
+#include <fstream>
+#include <time.h>
+#include <string>
+
+#include <iomanip>
+
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+
+ initialize("material.dat", argc, argv);
+
+ Math::setTolerance(1.e-15);
+ UInt spatial_dimension = 2;
+ const ElementType type = _cohesive_2d_4;
+
+ Mesh mesh(spatial_dimension);
+
+ mesh.read("mesh_cohesive_friction.msh");
+
+ // Create the model
+ SolidMechanicsModelCohesive model(mesh);
+
+ // Model initialization
+ model.initFull(SolidMechanicsModelCohesiveOptions(_static, true));
+
+ // CohesiveElementInserter inserter(mesh);
+ model.limitInsertion(_y, -0.001, 0.001);
+ model.updateAutomaticInsertion();
+
+ Real eps = 1e-10;
+ Array<Real> & pos = mesh.getNodes();
+ Array<Real> & disp = model.getDisplacement();
+ Array<bool> & boun = model.getBlockedDOFs();
+ const Array<Real> & residual = model.getResidual();
+ Array<Real> & cohe_opening = const_cast<Array<Real> &>(model.getMaterial("interface").getInternal<Real>("opening")(type));
+ Array<Real> & friction_force = const_cast<Array<Real> &>(model.getMaterial("interface").getInternal<Real>("friction_force")(type));
+
+ // Boundary conditions
+ for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
+ if(pos(i,1) < -0.49 || pos(i,1) > 0.49){
+ boun(i,0) = true;
+ boun(i,1) = true;
+ }
+ }
+
+ bool passed = true;
+ Real tolerance = 1e-13;
+ Real error;
+ bool load_reduction = false;
+ Real tol_increase_factor = 1e5;
+ Real increment = 1.0e-4;
+
+ model.synchronizeBoundaries();
+ model.updateResidual();
+
+ /* -------------------------------------------- */
+ /* LOADING PHASE to introduce cohesive elements */
+ /* -------------------------------------------- */
+
+ for (UInt nstep = 0; nstep < 100; ++nstep){
+
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (pos(n,1) > 0.49)
+ disp(n,1) += increment;
+ }
+
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+
+ if (error > tolerance){
+ AKANTU_DEBUG_ERROR("Convergence not reached in the mode I loading phase");
+ passed = false;
+ }
+
+ }
+
+ /* --------------------------------------------------------- */
+ /* UNLOADING PHASE to bring cohesive elements in compression */
+ /* --------------------------------------------------------- */
+
+ for (UInt nstep = 0; nstep < 110; ++nstep){
+
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (pos(n,1) > 0.49)
+ disp(n,1) -= increment;
+ }
+
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+
+ if (error > tolerance){
+ AKANTU_DEBUG_ERROR("Convergence not reached in the mode I unloading phase");
+ passed = false;
+ }
+
+ }
+
+
+ /* -------------------------------------------------- */
+ /* SHEAR PHASE - displacement towards right */
+ /* -------------------------------------------------- */
+
+ increment *= 2;
+
+ for (UInt nstep = 0; nstep < 30; ++nstep){
+
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (pos(n,1) > 0.49)
+ disp(n,0) += increment;
+ }
+
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+
+ if (error > tolerance){
+ AKANTU_DEBUG_ERROR("Convergence not reached in the shear loading phase");
+ passed = false;
+ }
+
+ }
+
+ /* ---------------------------------------------------*/
+ /* Check the horizontal component of the reaction */
+ /* ---------------------------------------------------*/
+
+ // Friction + mode II cohesive behavior
+ Real reac_X = 0.;
+
+ for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
+ if (pos(i,1) > 0.49)
+ reac_X += residual(i,0);
+ }
+ if (std::abs(reac_X - (-13.987451183762181)) > eps)
+ passed = false;
+
+ // Only friction
+ Real friction = friction_force(0,0) + friction_force(1,0);
+
+ if (std::abs(friction - (-12.517967866999832)) > eps)
+ passed = false;
+
+
+ /* -------------------------------------------------- */
+ /* SHEAR PHASE - displacement back to zero */
+ /* -------------------------------------------------- */
+
+ for (UInt nstep = 0; nstep < 30; ++nstep){
+
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (pos(n,1) > 0.49)
+ disp(n,0) -= increment;
+ }
+
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+
+ if (error > tolerance){
+ AKANTU_DEBUG_ERROR("Convergence not reached in the shear unloading phase");
+ passed = false;
+ }
+
+ }
+
+
+ /* ------------------------------------------------------- */
+ /* Check the horizontal component of the reaction and */
+ /* the residual relative sliding in the cohesive elements */
+ /* ------------------------------------------------------- */
+
+ // Friction + mode II cohesive behavior
+ reac_X = 0.;
+
+ for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
+ if (pos(i,1) > 0.49)
+ reac_X += residual(i,0);
+ }
+ if (std::abs(reac_X - 12.400313187122208) > eps)
+ passed = false;
+
+ // Only friction
+ friction = 0.;
+ friction = friction_force(0,0) + friction_force(1,0);
+
+ if (std::abs(friction - 12.523300983293165) > eps)
+ passed = false;
+
+ // Residual sliding
+ Real sliding[2];
+ sliding[0] = cohe_opening(0,0);
+ sliding[1] = cohe_opening(1,0);
+
+ if (std::abs(sliding[0] - (-0.00044246686809147357)) > eps)
+ passed = false;
+
+
+ if (passed)
+ return EXIT_SUCCESS;
+ else
+ return EXIT_FAILURE;
+
+ finalize();
+
+ 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..184671df9 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: Wed Jan 20 2016
#
# @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
+ PACKAGE core lapack
)
#===============================================================================
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
+add_akantu_test(test_material_elasto_plastic_linear_isotropic_hardening "test the elasto plastic with linear isotropic hardening materials")
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/data/single_quadrangle_4.msh b/test/test_model/test_solid_mechanics_model/test_materials/data/single_quadrangle_4.msh
deleted file mode 100644
index cffbc4e30..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/data/single_quadrangle_4.msh
+++ /dev/null
@@ -1,22 +0,0 @@
-$MeshFormat
-2.1 0 8
-$EndMeshFormat
-$Nodes
-4
-1 0 0 0
-2 1 0 0
-3 1 1 0
-4 0 1 0
-$EndNodes
-$Elements
-9
-1 15 3 0 1 0 1
-2 15 3 0 2 0 2
-3 15 3 0 3 0 3
-4 15 3 0 4 0 4
-5 1 3 0 1 0 1 2
-6 1 3 0 2 0 2 3
-7 1 3 0 3 0 3 4
-8 1 3 0 4 0 4 1
-9 3 3 0 6 0 3 4 1 2
-$EndElements
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/data/single_triangle_3.msh b/test/test_model/test_solid_mechanics_model/test_materials/data/single_triangle_3.msh
deleted file mode 100644
index e663b551e..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/data/single_triangle_3.msh
+++ /dev/null
@@ -1,19 +0,0 @@
-$MeshFormat
-2.1 0 8
-$EndMeshFormat
-$Nodes
-3
-1 0 0 0
-2 1 0 0
-3 0.5 2 0
-$EndNodes
-$Elements
-7
-1 15 3 0 1 0 1
-2 15 3 0 2 0 2
-3 15 3 0 3 0 3
-4 1 3 0 1 0 1 2
-5 1 3 0 2 0 2 3
-6 1 3 0 3 0 3 1
-7 2 3 0 6 0 2 3 1
-$EndElements
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/data/test_material_elastic_caughey_quadrangle_4.msh b/test/test_model/test_solid_mechanics_model/test_materials/data/test_material_elastic_caughey_quadrangle_4.msh
deleted file mode 100644
index b158a5c76..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/data/test_material_elastic_caughey_quadrangle_4.msh
+++ /dev/null
@@ -1,174 +0,0 @@
-$MeshFormat
-2.1 0 8
-$EndMeshFormat
-$Nodes
-69
-1 0 0 0
-2 10 0 0
-3 10 1 0
-4 0 1 0
-5 0.4545454545445526 0 0
-6 0.9090909090891053 0 0
-7 1.363636363633658 0 0
-8 1.818181818178211 0 0
-9 2.272727272722763 0 0
-10 2.727272727267581 0 0
-11 3.181818181812663 0 0
-12 3.636363636357745 0 0
-13 4.090909090902828 0 0
-14 4.545454545447909 0 0
-15 4.999999999992991 0 0
-16 5.454545454539083 0 0
-17 5.909090909085175 0 0
-18 6.363636363631267 0 0
-19 6.818181818177358 0 0
-20 7.272727272723449 0 0
-21 7.727272727269542 0 0
-22 8.181818181815633 0 0
-23 8.636363636361724 0 0
-24 9.090909090907816 0 0
-25 9.545454545453909 0 0
-26 10 0.4999999999990217 0
-27 9.545454545454545 1 0
-28 9.090909090909092 1 0
-29 8.636363636363637 1 0
-30 8.181818181818182 1 0
-31 7.727272727272728 1 0
-32 7.272727272727273 1 0
-33 6.818181818181818 1 0
-34 6.363636363636364 1 0
-35 5.909090909090909 1 0
-36 5.454545454545455 1 0
-37 5 1 0
-38 4.545454545454546 1 0
-39 4.090909090909092 1 0
-40 3.636363636363637 1 0
-41 3.181818181818183 1 0
-42 2.727272727272728 1 0
-43 2.272727272727274 1 0
-44 1.81818181818182 1 0
-45 1.363636363636363 1 0
-46 0.9090909090909101 1 0
-47 0.4545454545454568 1 0
-48 0 0.5000000000013878 0
-49 0.4545454545450047 0.5000000000012803 0
-50 0.9090909090900077 0.5000000000011726 0
-51 1.363636363635011 0.5000000000010651 0
-52 1.818181818180015 0.5000000000009576 0
-53 2.272727272725019 0.50000000000085 0
-54 2.727272727270154 0.5000000000007425 0
-55 3.181818181815423 0.5000000000006348 0
-56 3.636363636360691 0.5000000000005274 0
-57 4.09090909090596 0.5000000000004199 0
-58 4.545454545451228 0.5000000000003123 0
-59 4.999999999996496 0.5000000000002047 0
-60 5.45454545454227 0.5000000000000971 0
-61 5.909090909088042 0.4999999999999897 0
-62 6.363636363633814 0.4999999999998821 0
-63 6.818181818179589 0.4999999999997745 0
-64 7.27272727272536 0.4999999999996669 0
-65 7.727272727271133 0.4999999999995595 0
-66 8.181818181816908 0.4999999999994519 0
-67 8.636363636362679 0.4999999999993443 0
-68 9.090909090908452 0.4999999999992368 0
-69 9.545454545454227 0.4999999999991291 0
-$EndNodes
-$Elements
-96
-1 15 3 0 101 0 1
-2 15 3 0 102 0 2
-3 15 3 0 103 0 3
-4 15 3 0 104 0 4
-5 1 3 0 101 0 1 5
-6 1 3 0 101 0 5 6
-7 1 3 0 101 0 6 7
-8 1 3 0 101 0 7 8
-9 1 3 0 101 0 8 9
-10 1 3 0 101 0 9 10
-11 1 3 0 101 0 10 11
-12 1 3 0 101 0 11 12
-13 1 3 0 101 0 12 13
-14 1 3 0 101 0 13 14
-15 1 3 0 101 0 14 15
-16 1 3 0 101 0 15 16
-17 1 3 0 101 0 16 17
-18 1 3 0 101 0 17 18
-19 1 3 0 101 0 18 19
-20 1 3 0 101 0 19 20
-21 1 3 0 101 0 20 21
-22 1 3 0 101 0 21 22
-23 1 3 0 101 0 22 23
-24 1 3 0 101 0 23 24
-25 1 3 0 101 0 24 25
-26 1 3 0 101 0 25 2
-27 1 3 0 102 0 2 26
-28 1 3 0 102 0 26 3
-29 1 3 0 103 0 3 27
-30 1 3 0 103 0 27 28
-31 1 3 0 103 0 28 29
-32 1 3 0 103 0 29 30
-33 1 3 0 103 0 30 31
-34 1 3 0 103 0 31 32
-35 1 3 0 103 0 32 33
-36 1 3 0 103 0 33 34
-37 1 3 0 103 0 34 35
-38 1 3 0 103 0 35 36
-39 1 3 0 103 0 36 37
-40 1 3 0 103 0 37 38
-41 1 3 0 103 0 38 39
-42 1 3 0 103 0 39 40
-43 1 3 0 103 0 40 41
-44 1 3 0 103 0 41 42
-45 1 3 0 103 0 42 43
-46 1 3 0 103 0 43 44
-47 1 3 0 103 0 44 45
-48 1 3 0 103 0 45 46
-49 1 3 0 103 0 46 47
-50 1 3 0 103 0 47 4
-51 1 3 0 104 0 4 48
-52 1 3 0 104 0 48 1
-53 3 3 0 101 0 1 5 49 48
-54 3 3 0 101 0 48 49 47 4
-55 3 3 0 101 0 5 6 50 49
-56 3 3 0 101 0 49 50 46 47
-57 3 3 0 101 0 6 7 51 50
-58 3 3 0 101 0 50 51 45 46
-59 3 3 0 101 0 7 8 52 51
-60 3 3 0 101 0 51 52 44 45
-61 3 3 0 101 0 8 9 53 52
-62 3 3 0 101 0 52 53 43 44
-63 3 3 0 101 0 9 10 54 53
-64 3 3 0 101 0 53 54 42 43
-65 3 3 0 101 0 10 11 55 54
-66 3 3 0 101 0 54 55 41 42
-67 3 3 0 101 0 11 12 56 55
-68 3 3 0 101 0 55 56 40 41
-69 3 3 0 101 0 12 13 57 56
-70 3 3 0 101 0 56 57 39 40
-71 3 3 0 101 0 13 14 58 57
-72 3 3 0 101 0 57 58 38 39
-73 3 3 0 101 0 14 15 59 58
-74 3 3 0 101 0 58 59 37 38
-75 3 3 0 101 0 15 16 60 59
-76 3 3 0 101 0 59 60 36 37
-77 3 3 0 101 0 16 17 61 60
-78 3 3 0 101 0 60 61 35 36
-79 3 3 0 101 0 17 18 62 61
-80 3 3 0 101 0 61 62 34 35
-81 3 3 0 101 0 18 19 63 62
-82 3 3 0 101 0 62 63 33 34
-83 3 3 0 101 0 19 20 64 63
-84 3 3 0 101 0 63 64 32 33
-85 3 3 0 101 0 20 21 65 64
-86 3 3 0 101 0 64 65 31 32
-87 3 3 0 101 0 21 22 66 65
-88 3 3 0 101 0 65 66 30 31
-89 3 3 0 101 0 22 23 67 66
-90 3 3 0 101 0 66 67 29 30
-91 3 3 0 101 0 23 24 68 67
-92 3 3 0 101 0 67 68 28 29
-93 3 3 0 101 0 24 25 69 68
-94 3 3 0 101 0 68 69 27 28
-95 3 3 0 101 0 25 2 26 69
-96 3 3 0 101 0 69 26 3 27
-$EndElements
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/data/test_material_elastic_caughey_triangle_3.msh b/test/test_model/test_solid_mechanics_model/test_materials/data/test_material_elastic_caughey_triangle_3.msh
deleted file mode 100644
index ef098a2ea..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/data/test_material_elastic_caughey_triangle_3.msh
+++ /dev/null
@@ -1,175 +0,0 @@
-$MeshFormat
-2.1 0 8
-$EndMeshFormat
-$Nodes
-72
-1 0 0 0
-2 10 0 0
-3 10 1 0
-4 0 1 0
-5 0.4545454545445526 0 0
-6 0.9090909090891053 0 0
-7 1.363636363633658 0 0
-8 1.818181818178211 0 0
-9 2.272727272722763 0 0
-10 2.727272727267581 0 0
-11 3.181818181812663 0 0
-12 3.636363636357745 0 0
-13 4.090909090902828 0 0
-14 4.545454545447909 0 0
-15 4.999999999992991 0 0
-16 5.454545454539083 0 0
-17 5.909090909085175 0 0
-18 6.363636363631267 0 0
-19 6.818181818177358 0 0
-20 7.272727272723449 0 0
-21 7.727272727269542 0 0
-22 8.181818181815633 0 0
-23 8.636363636361724 0 0
-24 9.090909090907816 0 0
-25 9.545454545453909 0 0
-26 10 0.4999999999990217 0
-27 9.545454545454545 1 0
-28 9.090909090909092 1 0
-29 8.636363636363637 1 0
-30 8.181818181818182 1 0
-31 7.727272727272728 1 0
-32 7.272727272727273 1 0
-33 6.818181818181818 1 0
-34 6.363636363636364 1 0
-35 5.909090909090909 1 0
-36 5.454545454545455 1 0
-37 5 1 0
-38 4.545454545454546 1 0
-39 4.090909090909092 1 0
-40 3.636363636363637 1 0
-41 3.181818181818183 1 0
-42 2.727272727272728 1 0
-43 2.272727272727274 1 0
-44 1.81818181818182 1 0
-45 1.363636363636363 1 0
-46 0.9090909090909101 1 0
-47 0.4545454545454568 1 0
-48 0 0.5000000000013878 0
-49 1.060606060605009 0.5 0
-50 1.540404040402513 0.5 0
-51 0.5303030303025048 0.5000000000003469 0
-52 1.999158249156266 0.5 0
-53 2.454405162736128 0.5 0
-54 3.333333333330512 0.5 0
-55 2.934320052372966 0.5 0
-56 4.307513186452407 0.5 0
-57 3.842592592589563 0.5 0
-58 8.030303030301651 0.5 0
-59 6.666666666664331 0.5 0
-60 5.702058197714926 0.5 0
-61 6.161616161613472 0.5 0
-62 7.550505050503335 0.5 0
-63 8.939393939393195 0.5 0
-64 7.066498316496261 0.5 0
-65 8.434343434342336 0.5 0
-66 9.469696969696598 0.4999999999997554 0
-67 0.2462121212117644 0.2500000000004337 0
-68 9.753787878787787 0.7499999999996942 0
-69 9.753787878787627 0.2499999999996943 0
-70 0.2462121212119904 0.7500000000004337 0
-71 4.756261074971252 0.5 0
-72 5.227901696960617 0.5 0
-$EndNodes
-$Elements
-94
-1 2 3 1 101 0 67 1 5
-2 2 3 1 101 0 48 1 67
-3 2 3 1 101 0 5 51 67
-4 2 3 1 101 0 68 3 27
-5 2 3 1 101 0 26 3 68
-6 2 3 1 101 0 27 66 68
-7 2 3 1 101 0 25 2 69
-8 2 3 1 101 0 69 2 26
-9 2 3 1 101 0 69 66 25
-10 2 3 1 101 0 47 4 70
-11 2 3 1 101 0 70 4 48
-12 2 3 1 101 0 70 51 47
-13 2 3 1 101 0 52 8 9
-14 2 3 1 101 0 53 52 9
-15 2 3 1 101 0 52 43 44
-16 2 3 1 101 0 43 52 53
-17 2 3 1 101 0 50 7 8
-18 2 3 1 101 0 52 50 8
-19 2 3 1 101 0 50 44 45
-20 2 3 1 101 0 44 50 52
-21 2 3 1 101 0 51 5 6
-22 2 3 1 101 0 49 51 6
-23 2 3 1 101 0 51 46 47
-24 2 3 1 101 0 46 51 49
-25 2 3 1 101 0 49 6 7
-26 2 3 1 101 0 50 49 7
-27 2 3 1 101 0 49 45 46
-28 2 3 1 101 0 45 49 50
-29 2 3 1 101 0 53 9 10
-30 2 3 1 101 0 55 53 10
-31 2 3 1 101 0 53 42 43
-32 2 3 1 101 0 42 53 55
-33 2 3 1 101 0 63 28 29
-34 2 3 1 101 0 65 63 29
-35 2 3 1 101 0 63 23 24
-36 2 3 1 101 0 23 63 65
-37 2 3 1 101 0 66 27 28
-38 2 3 1 101 0 63 66 28
-39 2 3 1 101 0 66 24 25
-40 2 3 1 101 0 24 66 63
-41 2 3 1 101 0 64 19 20
-42 2 3 1 101 0 64 32 33
-43 2 3 1 101 0 59 64 33
-44 2 3 1 101 0 19 64 59
-45 2 3 1 101 0 62 20 21
-46 2 3 1 101 0 62 31 32
-47 2 3 1 101 0 64 62 32
-48 2 3 1 101 0 20 62 64
-49 2 3 1 101 0 60 16 17
-50 2 3 1 101 0 60 35 36
-51 2 3 1 101 0 59 18 19
-52 2 3 1 101 0 59 33 34
-53 2 3 1 101 0 61 59 34
-54 2 3 1 101 0 18 59 61
-55 2 3 1 101 0 65 22 23
-56 2 3 1 101 0 65 29 30
-57 2 3 1 101 0 58 65 30
-58 2 3 1 101 0 22 65 58
-59 2 3 1 101 0 61 17 18
-60 2 3 1 101 0 61 34 35
-61 2 3 1 101 0 60 61 35
-62 2 3 1 101 0 17 61 60
-63 2 3 1 101 0 58 21 22
-64 2 3 1 101 0 58 30 31
-65 2 3 1 101 0 62 58 31
-66 2 3 1 101 0 21 58 62
-67 2 3 1 101 0 56 13 14
-68 2 3 1 101 0 56 38 39
-69 2 3 1 101 0 54 11 12
-70 2 3 1 101 0 57 54 12
-71 2 3 1 101 0 54 40 41
-72 2 3 1 101 0 40 54 57
-73 2 3 1 101 0 55 10 11
-74 2 3 1 101 0 54 55 11
-75 2 3 1 101 0 55 41 42
-76 2 3 1 101 0 41 55 54
-77 2 3 1 101 0 57 12 13
-78 2 3 1 101 0 56 57 13
-79 2 3 1 101 0 57 39 40
-80 2 3 1 101 0 39 57 56
-81 2 3 1 101 0 70 48 67
-82 2 3 1 101 0 51 70 67
-83 2 3 1 101 0 69 26 68
-84 2 3 1 101 0 66 69 68
-85 2 3 1 101 0 72 60 36
-86 2 3 1 101 0 36 37 72
-87 2 3 1 101 0 16 60 72
-88 2 3 1 101 0 72 15 16
-89 2 3 1 101 0 14 15 71
-90 2 3 1 101 0 71 56 14
-91 2 3 1 101 0 71 15 72
-92 2 3 1 101 0 71 37 38
-93 2 3 1 101 0 38 56 71
-94 2 3 1 101 0 72 37 71
-$EndElements
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/ref_files/test_material_elastic_caughey_quadrangle_4.ref b/test/test_model/test_solid_mechanics_model/test_materials/ref_files/test_material_elastic_caughey_quadrangle_4.ref
deleted file mode 100644
index 597175542..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/ref_files/test_material_elastic_caughey_quadrangle_4.ref
+++ /dev/null
@@ -1,201 +0,0 @@
-id epot ekin tot
-10 7.3448e+06 5.15321e+06 1.2498e+07
-20 5.50101e+06 4.12023e+06 9.62124e+06
-30 4.36107e+06 3.42357e+06 7.78464e+06
-40 3.60931e+06 2.91506e+06 6.52437e+06
-50 1.13168e+06 4.09962e+06 5.2313e+06
-60 2.6536e+06 2.23308e+06 4.88667e+06
-70 3.12018e+06 1.31935e+06 4.43953e+06
-80 2.07771e+06 1.795e+06 3.8727e+06
-90 1.8663e+06 1.63329e+06 3.49959e+06
-100 1.80906e+06 1.39043e+06 3.19948e+06
-110 1.54644e+06 1.37109e+06 2.91754e+06
-120 366055 2.20107e+06 2.56712e+06
-130 1.31143e+06 1.17707e+06 2.4885e+06
-140 896293 1.41052e+06 2.30682e+06
-150 1.12807e+06 1.03212e+06 2.16019e+06
-160 1.06019e+06 961836 2.02202e+06
-170 1.47648e+06 452424 1.9289e+06
-180 933730 856076 1.78981e+06
-190 1.48595e+06 228499 1.71445e+06
-200 832323 767634 1.59996e+06
-210 915280 599566 1.51485e+06
-220 698341 741091 1.43943e+06
-230 711262 662695 1.37396e+06
-240 469228 819057 1.28828e+06
-250 647397 604390 1.25179e+06
-260 603644 608913 1.21256e+06
-270 595863 551347 1.14721e+06
-280 516770 586222 1.10299e+06
-290 468157 596150 1.06431e+06
-300 523682 492510 1.01619e+06
-310 128862 826003 954864
-320 484552 457963 942515
-330 333098 565941 899038
-340 462283 414040 876323
-350 455823 390515 846338
-360 701264 135351 836615
-370 406538 386574 793112
-380 735168 45098.4 780266
-390 380319 364149 744468
-400 486087 238701 724788
-410 338268 356071 694339
-420 339361 341263 680624
-430 279354 376914 656268
-440 328351 313810 642161
-450 199255 426707 625962
-460 311568 297281 608848
-470 229420 362250 591671
-480 179264 395172 574436
-490 290192 271349 561541
-500 90958.4 448437 539395
-510 272272 261904 534176
-520 243871 273027 516897
-530 279069 231711 510779
-540 293006 203528 496533
-550 407713 85505.8 493219
-560 240254 234563 474817
-570 457404 13550.9 470955
-580 228583 224927 453510
-590 293236 153872 447108
-600 237086 195281 432367
-610 196122 229890 426012
-620 179217 235577 414794
-630 208381 199768 408149
-640 75366.8 323207 398574
-650 192609 199383 391992
-660 131728 251354 383082
-670 96528.3 278061 374590
-680 197578 171727 369305
-690 76161.7 282762 358923
-700 181553 174486 356039
-710 207218 140541 347759
-720 183689 160903 344592
-730 216422 120700 337122
-740 272321 62614.4 334936
-750 160085 165300 325385
-760 314523 9203.03 323726
-770 159615 154220 313835
-780 182780 128061 310841
-790 181187 121753 302939
-800 122940 175904 298844
-810 122786 169814 292600
-820 148427 140511 288938
-830 29114.4 253523 282637
-840 134460 145077 279536
-850 95340.5 178870 274211
-860 63464.7 206138 269603
-870 151670 115186 266857
-880 67798.8 193388 261187
-890 131066 128253 259319
-900 181189 73774.5 254964
-910 128534 123968 252502
-920 166732 81722.1 248454
-930 198443 48231.2 246674
-940 112837 128179 241017
-950 228829 11236.2 240065
-960 120972 113037 234009
-970 114941 117077 232019
-980 143575 83939.2 227514
-990 82425.4 142062 224488
-1000 88292.2 132411 220703
-1010 114716 103721 218436
-1020 10978.7 203106 214085
-1030 102070 110401 212471
-1040 81463.6 127552 209015
-1050 46756.5 159458 206215
-1060 124376 80270.9 204646
-1070 61947.9 139216 201164
-1080 98599.6 101192 199791
-1090 159046 38349.4 197395
-1100 94890.8 100380 195271
-1110 129463 63516.4 192979
-1120 153173 38332.2 191505
-1130 81986 105831 187817
-1140 172645 14513.3 187158
-1150 96337.8 86890.6 183228
-1160 72014.1 109616 181630
-1170 116640 62336.2 178977
-1180 59843.5 116749 176593
-1190 65851.7 108327 174179
-1200 94386.9 78299.9 172687
-1210 4454.24 165104 169558
-1220 81573.9 87087.5 168661
-1230 75923.7 90399.9 166324
-1240 36893.2 127518 164412
-1250 105167 58327.4 163495
-1260 57310.9 103839 161149
-1270 75978.2 84078.5 160057
-1280 139467 19238.6 158706
-1290 73355.8 83501 156857
-1300 100086 55390.8 155477
-1310 123054 31232.2 154286
-1320 60913.5 90772.3 151686
-1330 133611 17584 151195
-1340 79613.4 68911.4 148525
-1350 44489.6 102661 147150
-1360 96629.4 48936.5 145566
-1370 47634.7 96003.9 143639
-1380 50555.6 91470.6 142026
-1390 81154.4 59868.7 141023
-1400 3014.98 135672 138687
-1410 67156.6 71000.8 138157
-1420 73163.2 63381.4 136545
-1430 30458.1 104642 135100
-1440 89857.9 44712.8 134571
-1450 53365.8 79515.2 132881
-1460 59421 72543.6 131965
-1470 122108 9088.74 131197
-1480 59018 70581.4 129599
-1490 76654.6 52044.8 128699
-1500 101759 26008.8 127768
-1510 46412.8 79398.8 125812
-1520 105374 20066.5 125441
-1530 67872.2 55689.8 123562
-1540 26810.4 95542.9 122353
-1550 81293.8 40116.4 121410
-1560 41429.3 78410.5 119840
-1570 39756.4 78948.8 118705
-1580 71699.6 46335.5 118035
-1590 3799.11 112432 116232
-1600 56187.9 59705.6 115893
-1610 70997.3 43775.5 114773
-1620 25994 87603.2 113597
-1630 76753.5 36547.9 113301
-1640 49871.7 62155.6 112027
-1650 46964.8 64265 111230
-1660 106780 4019.58 110800
-1670 49189.1 60241.4 109431
-1680 58003.4 50781.9 108785
-1690 85976.2 22103.7 108080
-1700 36592.6 69940.4 106533
-1710 84333.6 21917.9 106252
-1720 59400 45499.1 104899
-1730 15558.4 88269.5 103828
-1740 69199.9 34077.2 103277
-1750 38599.8 63398.7 101998
-1760 31928.2 69223.2 101151
-1770 64243.8 36472.8 100717
-1780 5471.82 93811.9 99283.8
-1790 47396.7 51648.1 99044.8
-1800 68629.9 29637.3 98267.3
-1810 22791.7 74471.2 97262.9
-1820 65176.3 31929.2 97105.5
-1830 46702.4 49416.1 96118.6
-1840 37500.5 57904.6 95405.1
-1850 93304.5 1871.86 95176.4
-1860 42307.1 51703.8 94011
-1870 43267.3 50234.8 93502.1
-1880 73824.3 19161.7 92986
-1890 30158.8 61560.4 91719.2
-1900 68301.6 23201.1 91502.7
-1910 53078.9 37437.5 90516.4
-1920 8556.51 81006.6 89563.2
-1930 59410.5 29843.6 89254
-1940 37558 50659.4 88217.4
-1950 26144.6 61400.7 87545.2
-1960 57846.9 29431.1 87278.1
-1970 7391.53 78722.6 86114.2
-1980 40136.9 45786.1 85923.1
-1990 65843.4 19546.1 85389.5
-2000 20465 64041.8 84506.8
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/ref_files/test_material_elastic_caughey_triangle_3.ref b/test/test_model/test_solid_mechanics_model/test_materials/ref_files/test_material_elastic_caughey_triangle_3.ref
deleted file mode 100644
index de8ff1631..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/ref_files/test_material_elastic_caughey_triangle_3.ref
+++ /dev/null
@@ -1,201 +0,0 @@
-id epot ekin tot
-10 5.3753e+06 7.35442e+06 1.27297e+07
-20 6.03298e+06 6.04789e+06 1.20809e+07
-30 5.52192e+06 5.99549e+06 1.15174e+07
-40 5.45624e+06 5.56836e+06 1.10246e+07
-50 5.67011e+06 4.94603e+06 1.06161e+07
-60 5.27398e+06 4.93497e+06 1.02089e+07
-70 5.14567e+06 4.69723e+06 9.8429e+06
-80 4.6409e+06 4.84967e+06 9.49058e+06
-90 4.50455e+06 4.66877e+06 9.17331e+06
-100 5.03315e+06 3.85047e+06 8.88362e+06
-110 2.44212e+06 6.16691e+06 8.60903e+06
-120 6.92523e+06 1.42668e+06 8.35191e+06
-130 2.43815e+06 5.6168e+06 8.05496e+06
-140 3.39094e+06 4.45989e+06 7.85083e+06
-150 3.6832e+06 3.94975e+06 7.63296e+06
-160 3.83389e+06 3.58778e+06 7.42166e+06
-170 3.84378e+06 3.37349e+06 7.21727e+06
-180 3.73767e+06 3.28029e+06 7.01796e+06
-190 3.59228e+06 3.23748e+06 6.82976e+06
-200 3.17897e+06 3.46775e+06 6.64672e+06
-210 2.88697e+06 3.58548e+06 6.47245e+06
-220 4.53744e+06 1.77718e+06 6.31461e+06
-230 1.58527e+06 4.5732e+06 6.15847e+06
-240 4.58674e+06 1.4256e+06 6.01234e+06
-250 2.05231e+06 3.78883e+06 5.84114e+06
-260 2.73536e+06 2.98781e+06 5.72317e+06
-270 3.04052e+06 2.54961e+06 5.59013e+06
-280 2.92436e+06 2.53262e+06 5.45698e+06
-290 2.81266e+06 2.51727e+06 5.32994e+06
-300 2.70756e+06 2.49991e+06 5.20747e+06
-310 2.67986e+06 2.40923e+06 5.08908e+06
-320 2.26101e+06 2.71994e+06 4.98095e+06
-330 1.30197e+06 3.56722e+06 4.86919e+06
-340 3.70243e+06 1.07054e+06 4.77297e+06
-350 1.39222e+06 3.27889e+06 4.6711e+06
-360 3.22475e+06 1.35406e+06 4.5788e+06
-370 1.61976e+06 2.8474e+06 4.46716e+06
-380 2.0872e+06 2.30413e+06 4.39133e+06
-390 2.35602e+06 1.94788e+06 4.3039e+06
-400 2.12342e+06 2.0905e+06 4.21392e+06
-410 1.95632e+06 2.17521e+06 4.13152e+06
-420 1.81476e+06 2.23658e+06 4.05133e+06
-430 2.1857e+06 1.78477e+06 3.97047e+06
-440 2.46163e+06 1.44274e+06 3.90437e+06
-450 836581 2.99085e+06 3.82743e+06
-460 2.86321e+06 896734 3.75994e+06
-470 1.23693e+06 2.44984e+06 3.68677e+06
-480 2.42284e+06 1.20252e+06 3.62536e+06
-490 1.39137e+06 2.15709e+06 3.54846e+06
-500 1.68454e+06 1.81167e+06 3.4962e+06
-510 1.92002e+06 1.51515e+06 3.43516e+06
-520 1.75628e+06 1.61474e+06 3.37102e+06
-530 1.71959e+06 1.59628e+06 3.31587e+06
-540 1.26963e+06 1.99259e+06 3.26223e+06
-550 1.32758e+06 1.87193e+06 3.19951e+06
-560 2.38789e+06 766728 3.15461e+06
-570 820681 2.27999e+06 3.10067e+06
-580 2.20233e+06 849351 3.05169e+06
-590 1.01388e+06 1.98355e+06 2.99743e+06
-600 1.82633e+06 1.1293e+06 2.95563e+06
-610 1.18528e+06 1.71595e+06 2.90124e+06
-620 1.34298e+06 1.52068e+06 2.86365e+06
-630 1.47197e+06 1.34788e+06 2.81985e+06
-640 1.33776e+06 1.43335e+06 2.77111e+06
-650 1.76008e+06 970839 2.73092e+06
-660 1.42214e+06 1.27415e+06 2.69629e+06
-670 701450 1.94478e+06 2.64623e+06
-680 1.90412e+06 708210 2.61233e+06
-690 779365 1.79437e+06 2.57374e+06
-700 1.76045e+06 777588 2.53804e+06
-710 892517 1.60403e+06 2.49654e+06
-720 1.47042e+06 996122 2.46654e+06
-730 1.12661e+06 1.29967e+06 2.42628e+06
-740 1.27562e+06 1.12174e+06 2.39736e+06
-750 1.26978e+06 1.09597e+06 2.36575e+06
-760 722703 1.60498e+06 2.32768e+06
-770 1.26922e+06 1.02482e+06 2.29404e+06
-780 1.61301e+06 659045 2.27206e+06
-790 590094 1.64392e+06 2.23402e+06
-800 1.5145e+06 692493 2.20699e+06
-810 714873 1.46292e+06 2.17779e+06
-820 1.43019e+06 721192 2.15139e+06
-830 784571 1.33452e+06 2.11909e+06
-840 1.13382e+06 962835 2.09665e+06
-850 889205 1.17641e+06 2.06561e+06
-860 1.14302e+06 898139 2.04116e+06
-870 1.46868e+06 549943 2.01862e+06
-880 655347 1.33626e+06 1.99161e+06
-890 674515 1.28724e+06 1.96176e+06
-900 1.44162e+06 504162 1.94578e+06
-910 582195 1.33522e+06 1.91741e+06
-920 1.2503e+06 645360 1.89566e+06
-930 668727 1.20367e+06 1.8724e+06
-940 1.21993e+06 632261 1.8522e+06
-950 804651 1.02177e+06 1.82642e+06
-960 1.03681e+06 772654 1.80946e+06
-970 648866 1.13733e+06 1.78619e+06
-980 597045 1.16697e+06 1.76402e+06
-990 1.33766e+06 407820 1.74548e+06
-1000 932886 795232 1.72812e+06
-1010 475087 1.2277e+06 1.70279e+06
-1020 1.20955e+06 479706 1.68926e+06
-1030 564988 1.1026e+06 1.66759e+06
-1040 1.04111e+06 609028 1.65014e+06
-1050 571626 1.05956e+06 1.63118e+06
-1060 928160 687168 1.61533e+06
-1070 679180 914679 1.59386e+06
-1080 1.10067e+06 479349 1.58002e+06
-1090 909918 654204 1.56412e+06
-1100 322982 1.22264e+06 1.54562e+06
-1110 867401 660295 1.5277e+06
-1120 982812 533231 1.51604e+06
-1130 431919 1.0638e+06 1.49572e+06
-1140 1.01295e+06 470846 1.4838e+06
-1150 553637 912987 1.46662e+06
-1160 943026 509477 1.4525e+06
-1170 621358 815653 1.43701e+06
-1180 782201 642927 1.42513e+06
-1190 349478 1.0579e+06 1.40738e+06
-1200 723521 670196 1.39372e+06
-1210 1.09744e+06 284672 1.38211e+06
-1220 490168 878803 1.36897e+06
-1230 578648 773385 1.35203e+06
-1240 903112 439826 1.34294e+06
-1250 418398 908475 1.32687e+06
-1260 830691 485822 1.31651e+06
-1270 451446 851122 1.30257e+06
-1280 736140 554602 1.29074e+06
-1290 641863 635277 1.27714e+06
-1300 972919 295323 1.26824e+06
-1310 458235 797221 1.25546e+06
-1320 310696 931468 1.24216e+06
-1330 874566 356677 1.23124e+06
-1340 614532 607920 1.22245e+06
-1350 450575 757151 1.20773e+06
-1360 802270 397565 1.19983e+06
-1370 446978 739922 1.1869e+06
-1380 786629 391373 1.178e+06
-1390 478739 688146 1.16688e+06
-1400 515268 642269 1.15754e+06
-1410 300410 844428 1.14484e+06
-1420 836508 299659 1.13617e+06
-1430 756091 371676 1.12777e+06
-1440 293639 823456 1.11709e+06
-1450 632500 473458 1.10596e+06
-1460 632653 466845 1.0995e+06
-1470 381677 705653 1.08733e+06
-1480 653344 426990 1.08033e+06
-1490 357584 712011 1.06959e+06
-1500 668902 392511 1.06141e+06
-1510 626921 425018 1.05194e+06
-1520 711188 334346 1.04553e+06
-1530 203111 832171 1.03528e+06
-1540 435438 590175 1.02561e+06
-1550 747177 271592 1.01877e+06
-1560 382293 629033 1.01133e+06
-1570 485488 515252 1.00074e+06
-1580 619859 375421 995280
-1590 411583 573706 985289
-1600 638225 341043 979268
-1610 321512 649252 970763
-1620 372745 590707 963452
-1630 377672 576276 953948
-1640 800840 147816 948656
-1650 452072 489955 942027
-1660 274874 658045 932920
-1670 607681 318208 925889
-1680 428392 492320 920712
-1690 373151 538246 911397
-1700 504227 402209 906436
-1710 338101 559759 897859
-1720 634901 257218 892119
-1730 545827 339637 885464
-1740 457314 423085 880399
-1750 128667 742845 871513
-1760 533573 331608 865181
-1770 567930 292804 860733
-1780 279525 574069 853594
-1790 492378 353959 846338
-1800 476254 366038 842292
-1810 393225 441227 834453
-1820 482192 348053 830245
-1830 208148 615097 823244
-1840 333041 484302 817342
-1850 463748 346912 810661
-1860 667711 139697 807409
-1870 239926 561079 801005
-1880 322459 471502 793961
-1890 531756 258115 789871
-1900 297065 487679 784744
-1910 358998 418826 777824
-1920 396989 377171 774160
-1930 364484 402716 767200
-1940 587985 175334 763319
-1950 415939 342380 758319
-1960 263858 489803 753661
-1970 173268 573139 746408
-1980 568181 174645 742825
-1990 382830 356030 738861
-2000 256451 475996 732447
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..c197729d8 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: Tue Jan 19 2016
#
# @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
+ SOURCES test_material_non_local.cc custom_non_local_test_material.cc custom_non_local_test_material.hh
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/material_stiffness_proportional_damping.dat b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_stiffness_proportional_damping.dat
deleted file mode 100644
index 9397d959d..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_stiffness_proportional_damping.dat
+++ /dev/null
@@ -1,7 +0,0 @@
-material elastic_caughey [
- name = viscous_steel
- rho = 7800 # density
- E = 2.1e11 # young's modulus
- nu = 0.3 # poisson's ratio
- alpha = 6.5784e-6 # viscous ratio
-]
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_materials/test_material_viscoelastic/test_material_stiffness_proportional.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_stiffness_proportional.cc
deleted file mode 100644
index a0fb6b065..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_stiffness_proportional.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * @file test_material_stiffness_proportional.cc
- *
- * @author David Simon Kammer <david.kammer@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date Sun Sep 12 23:37:43 2010
- *
- * @brief test of the material elastic caughey
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-#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_tools.hh"
-#endif //AKANTU_USE_IOHELPER
-
-using namespace akantu;
-
-int main(int argc, char *argv[])
-{
- akantu::initialize(argc, argv);
- akantu::debug::setDebugLevel(akantu::dblWarning);
-
- const ElementType element_type = TYPE;
- UInt dim = Mesh::getSpatialDimension(element_type);
-
- /// load mesh
- Mesh mesh(dim);
- MeshIOMSH mesh_io;
- std::stringstream meshname_sstr;
- meshname_sstr << "test_material_elastic_caughey_" << element_type << ".msh";
- mesh_io.read(meshname_sstr.str().c_str(), mesh);
-
- UInt max_steps = 2000;
- Real time_factor = 0.8;
- UInt nb_nodes = mesh.getNbNodes();
-
- SolidMechanicsModel model(mesh);
-
- /* ------------------------------------------------------------------------ */
- /* Initialization */
- /* ------------------------------------------------------------------------ */
- model.initArrays();
- model.getForce().clear();
- model.getVelocity().clear();
- model.getAcceleration().clear();
- model.getDisplacement().clear();
- model.updateResidual();
-
- model.initExplicit();
- model.initModel();
- model.readMaterials("material_elastic_caughey.dat");
- model.initMaterials();
-
- std::cout << model.getMaterial(0) << std::endl;
-
- model.assembleMassLumped();
-
- /* ------------------------------------------------------------------------ */
- /* Boundary + initial conditions */
- /* ------------------------------------------------------------------------ */
- Real eps = 1e-16;
- for (UInt i = 0; i < nb_nodes; ++i) {
- if(mesh.getNodes().storage()[dim*i] >= 9)
- model.getDisplacement().storage()[dim*i]
- = (mesh.getNodes().storage()[dim*i] - 9) / 100.;
-
- if(mesh.getNodes().storage()[dim*i] <= eps)
- model.getBlockedDOFs().storage()[dim*i] = true;
-
- if(mesh.getNodes().storage()[dim*i + 1] <= eps ||
- mesh.getNodes().storage()[dim*i + 1] >= 1 - eps ) {
- model.getBlockedDOFs().storage()[dim*i + 1] = true;
- }
- }
-
- /// dump facet and surface information to paraview
-#ifdef AKANTU_USE_IOHELPER
- iohelper::DumperParaview dumper;
- paraviewInit(dumper, model, element_type, "test_mat_el_caughey");
-#endif //AKANTU_USE_IOHELPER
-
- std::stringstream filename_sstr;
- filename_sstr << "test_material_elastic_caughey_" << element_type << ".out";
- std::ofstream energy;
- energy.open(filename_sstr.str().c_str());
- energy << "id epot ekin tot" << std::endl;
-
- /// Setting time step
- Real time_step = model.getStableTimeStep() * time_factor;
- std::cout << "Time Step = " << time_step << "s" << std::endl;
- model.setTimeStep(time_step);
-
- /* ------------------------------------------------------------------------ */
- /* Main loop */
- /* ------------------------------------------------------------------------ */
- for(UInt s = 1; s <= max_steps; ++s) {
-
- model.explicitPred();
- model.updateResidual();
- model.updateAcceleration();
- model.explicitCorr();
-
- Real epot = model.getPotentialEnergy();
- Real ekin = model.getKineticEnergy();
-
- if(s % 10 == 0) {
- std::cerr << "passing step " << s << "/" << max_steps << std::endl;
- energy << s << " " << epot << " " << ekin << " " << epot + ekin
- << std::endl;
- }
-
-#ifdef AKANTU_USE_IOHELPER
- if(s % 10 == 0) paraviewDump(dumper);
-#endif //AKANTU_USE_IOHELPER
- }
-
- finalize();
- return EXIT_SUCCESS;
-}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_stiffness_proportional_damping.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_stiffness_proportional_damping.cc
deleted file mode 100644
index 3ca38950c..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_stiffness_proportional_damping.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * @file test_material_stiffness_proportional_damping.cc
- *
- * @author David Simon Kammer <david.kammer@epfl.ch>
- *
- * @date Mon Nov 14 09:15:53 2011
- *
- * @brief test of the material elastic caughey - physical aspecte
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-#include <iostream>
-
-/* -------------------------------------------------------------------------- */
-#include <limits>
-#include <fstream>
-
-/* -------------------------------------------------------------------------- */
-#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_tools.hh"
-#endif //AKANTU_USE_IOHELPER
-
-using namespace akantu;
-
-static bool testFloat(Real a, Real b, Real adm_error);
-
-int main(int argc, char *argv[])
-{
- akantu::initialize(argc, argv);
- akantu::debug::setDebugLevel(akantu::dblWarning);
-
- const ElementType element_type = TYPE;
- const UInt dim = ElementClass<TYPE>::getSpatialDimension();
-
- /// load mesh
- Mesh mesh(dim);
- MeshIOMSH mesh_io;
- std::stringstream meshname_sstr;
- meshname_sstr << "single_" << element_type << ".msh";
- mesh_io.read(meshname_sstr.str().c_str(), mesh);
-
- UInt max_steps = 1000;
- Real time_factor = 0.1;
- UInt nb_nodes = mesh.getNbNodes();
-
- SolidMechanicsModel model(mesh);
-
- /* ------------------------------------------------------------------------ */
- /* Initialization */
- /* ------------------------------------------------------------------------ */
- model.initArrays();
- model.getForce().clear();
- model.getVelocity().clear();
- model.getAcceleration().clear();
- model.getDisplacement().clear();
- model.updateResidual();
-
- model.initExplicit();
- model.initModel();
- model.readMaterials("material_elastic_caughey_damping.dat");
- Material & my_mat = model.getMaterial(0);
- Real a_value = 1e-6;//3.836e-06;
- my_mat.setProperty("alpha", a_value);
- model.initMaterials();
-
- std::cout << model.getMaterial(0) << std::endl;
-
- model.assembleMassLumped();
-
- /* ------------------------------------------------------------------------ */
- /* Boundary + initial conditions */
- /* ------------------------------------------------------------------------ */
- Array<UInt> the_nodes(0,1);
- Real imposed_disp = 0.1;
- for (UInt i = 0; i < nb_nodes; ++i) {
- // block lower nodes
- if(mesh.getNodes().storage()[i*dim+1] < 0.5) {
- for (UInt j=0; j<dim; ++j)
- model.getBlockedDOFs().storage()[dim*i + j] = true;
- }
- // impose displacement
- else {
- model.getBlockedDOFs().storage()[dim*i + 0] = true;
- model.getDisplacement().storage()[dim*i + 1] = imposed_disp;
- the_nodes.push_back(i);
- }
- }
- model.updateResidual();
-
-#ifdef AKANTU_USE_IOHELPER
- iohelper::DumperParaview dumper;
- paraviewInit(dumper, model, element_type, "test_mat_el_cau_dump");
-#endif //AKANTU_USE_IOHELPER
-
- /// Setting time step
- Real time_step = model.getStableTimeStep() * time_factor;
- std::cout << "Time Step = " << time_step << "s" << std::endl;
- model.setTimeStep(time_step);
-
- /* ------------------------------------------------------------------------ */
- /* Main loop */
- /* ------------------------------------------------------------------------ */
- for(UInt s = 1; s <= max_steps; ++s) {
-
- if (s%100 == 0)
- std::cout << "passing step " << s << "/" << max_steps << std::endl;
-
- model.explicitPred();
- model.updateResidual();
- model.updateAcceleration();
- model.explicitCorr();
-
-#ifdef AKANTU_USE_IOHELPER
- if(s % 100 == 0) dumper.Dump();
-#endif //AKANTU_USE_IOHELPER
- }
-
- /*
- for (UInt i=0; i<the_nodes.getSize(); ++i) {
- std::cout << "disp " << model.getDisplacement().storage()[the_nodes(i)*dim+1] << "; vel " << model.getVelocity().storage()[the_nodes(i)*dim+1] << std::endl;
- }
- */
-
- /* ------------------------------------------------------------------------ */
- /* Test solution */
- /* ------------------------------------------------------------------------ */
- Real disp_tol = 1e-07;
- Real velo_tol = 1e-03;
- // solution triangle_3
- Array<Real> disp_triangle_3(0,1); disp_triangle_3.push_back(-0.0344941);
- Array<Real> velo_triangle_3(0,1); velo_triangle_3.push_back(-433.9);
- // solution quadrangle_4
- Array<Real> disp_quadrangle_4(0,1);
- disp_quadrangle_4.push_back(0.0338388);
- disp_quadrangle_4.push_back(0.0338388);
- Array<Real> velo_quadrangle_4(0,1);
- velo_quadrangle_4.push_back(-307.221);
- velo_quadrangle_4.push_back(-307.221);
-
- // pointer to solution
- Array<Real> * disp = NULL;
- Array<Real> * velo = NULL;
- if (element_type == _triangle_3) {
- disp = &disp_triangle_3;
- velo = &velo_triangle_3;
- }
- else if (element_type == _quadrangle_4) {
- disp = &disp_quadrangle_4;
- velo = &velo_quadrangle_4;
- }
-
- for (UInt i=0; i<the_nodes.getSize(); ++i) {
- UInt node = the_nodes.storage()[i];
- if (!testFloat(model.getDisplacement().storage()[node*dim+1], disp->storage()[i], disp_tol)) {
- std::cout << "Node " << node << " has wrong disp. Computed = " << model.getDisplacement().storage()[node*dim+1] << " Solution = " << disp->storage()[i] << std::endl;
- return EXIT_FAILURE;
- }
- if (!testFloat(model.getVelocity().storage()[node*dim+1], velo->storage()[i], velo_tol)) {
- std::cout << "Node " << node << " has wrong velo. Computed = " << model.getVelocity().storage()[node*dim+1] << " Solution = " << velo->storage()[i] << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- finalize();
- std::cout << "Patch test successful!" << std::endl;
- return EXIT_SUCCESS;
-}
-
-/* -------------------------------------------------------------------------- */
-bool testFloat(Real a, Real b, Real adm_error) {
- if (fabs(a-b) < adm_error)
- return true;
- else
- return false;
-}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/triangle.geo b/test/test_model/test_solid_mechanics_model/test_materials/triangle.geo
deleted file mode 100644
index 571490830..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/triangle.geo
+++ /dev/null
@@ -1,43 +0,0 @@
-// CUBE ON CUBE (2 BODIES) 3D:
-
-// REMARKS:
-// Physical Surfaces are defined so that load_mesh_msh can load
-// directly the surface element structure. When creating Plane Surface,
-// the surface normal has to point to the inside of the body. Otherwise the
-// solvecontact3d algorithm won't work. The Physical Surface number
-// corresponds to the face number. The face numbering has to start with 1!
-// Physical Volume defines the material of each body. This can be read
-// by the load_mesh_msh function in adlib.
-
-// Mesh size
-h = 0.02; // Top cube
-hy = 0.5; // Top cube
-
-// Dimensions of top cube
-Lx = 1;
-Ly = 1;
-
-
-// ------------------------------------------
-// Geometry
-// ------------------------------------------
-
-// Base Cube
-Point(101) = { 0.0, 0.0, 0.0, h}; // Bottom Face
-Point(102) = { Lx, 0.0, 0.0, h}; // Bottom Face
-Point(103) = { Lx, Ly, 0.0, h}; // Bottom Face
-Point(104) = { 0.0, Ly, 0.0, h}; // Bottom Face
-
-// Base Cube
-Line(101) = {101,102}; // Bottom Face
-Line(102) = {102,103}; // Bottom Face
-Line(103) = {103,104}; // Bottom Face
-Line(104) = {104,101}; // Bottom Face
-
-// Base Cube
-Line Loop(101) = {101:104};
-
-// Base Cube
-Plane Surface(101) = {101};
-
-Physical Surface(6) = {101};
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model.cc
deleted file mode 100644
index 8b9d53dea..000000000
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * @file test_solid_mechanics_model.cc
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date Fri Sep 03 15:56:56 2010
- *
- * @brief test of the class SolidMechanicsModel
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "mesh.hh"
-#include "mesh_io.hh"
-#include "mesh_io_msh.hh"
-#include "solid_mechanics_model.hh"
-#include "material.hh"
-#include "fe_engine.hh"
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-# include "io_helper.hh"
-#endif //AKANTU_USE_IOHELPER
-
-using namespace akantu;
-
-int main(int argc, char *argv[])
-{
- akantu::initialize(argc, argv);
- UInt max_steps = 1;
- Real epot, ekin;
-
- Mesh mesh(2);
- MeshIOMSH mesh_io;
- mesh_io.read("triangle.msh", mesh);
- mesh.getBlockedDOFs().createBoundariesFromGeometry();
-
- SolidMechanicsModel * model = new SolidMechanicsModel(mesh);
-
- /// model initialization
- model->initArrays();
- UInt nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- memset(model->getForce().storage(), 0, 2*nb_nodes*sizeof(Real));
- memset(model->getVelocity().storage(), 0, 2*nb_nodes*sizeof(Real));
- memset(model->getAcceleration().storage(), 0, 2*nb_nodes*sizeof(Real));
- memset(model->getDisplacement().storage(), 0, 2*nb_nodes*sizeof(Real));
-
- model->readMaterials("material.dat");
- model->initMaterials();
- model->initModel();
-
- Real time_step = model->getStableTimeStep();
- model->setTimeStep(time_step/10.);
-
- model->assembleMass();
-
- std::cout << *model << std::endl;
-
- /// boundary conditions
- // Real eps = 1e-16;
- // for (UInt i = 0; i < nb_nodes; ++i) {
- // model->getDisplacement().storage()[2*i] = model->getFEEngine().getMesh().getNodes().storage()[2*i] / 100.;
-
- // if(model->getFEEngine().getMesh().getNodes().storage()[2*i] <= eps) {
- // model->getBlockedDOFs().storage()[2*i ] = true;
- // if(model->getFEEngine().getMesh().getNodes().storage()[2*i + 1] <= eps)
- // model->getBlockedDOFs().storage()[2*i + 1] = true;
- // }
- // if(model->getFEEngine().getMesh().getNodes().storage()[2*i + 1] <= eps) {
- // model->getBlockedDOFs().storage()[2*i + 1] = true;
- // }
-
- // }
-
- // Boundary condition (Neumann)
- Matrix<Real> stress(2,2);
- stress.eye(1e3);
- model.applyBC(BC::Neumann::FromHigherDim(stress), "0");
-
- // const Mesh::ConnectivityTypeList & type_list = fem_boundary.getMesh().getConnectivityTypeList();
- // Mesh::ConnectivityTypeList::const_iterator it;
- // for(it = type_list.begin(); it != type_list.end(); ++it) {
- // if(Mesh::getSpatialDimension(*it) != fem_boundary.getElementDimension()) continue;
-
- // // ElementType facet_type = Mesh::getFacetElementType(*it);
- // UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
- // UInt nb_quad = FEEngine::getNbQuadraturePoints(*it);
-
-
- // UInt nb_element;
- // const Array<Real> * shapes;
- // Array<Real> quad_coords(0,2,"quad_coords");
- // const Array<Real> * normals_on_quad;
-
- // nb_element = fem_boundary.getMesh().getNbElement(*it);
- // fem_boundary.interpolateOnQuadraturePoints(mesh.getNodes(), quad_coords, 2, _segment_2);
- // normals_on_quad = &(fem_boundary.getNormalsOnQuadPoints(*it));
-
- // shapes = &(fem_boundary.getShapes(*it));
-
- // Array<Real> * sigma_funct = new Array<Real>(nb_element, 4*nb_quad, "myfunction");
- // Array<Real> * funct = new Array<Real>(nb_element, 2*nb_quad, "myfunction");
-
- // Real * sigma_funct_val = sigma_funct->storage();
- // Real * shapes_val = shapes->storage();
-
- // /// compute t * \phi_i for each nodes of each element
- // for (UInt el = 0; el < nb_element; ++el) {
- // for (UInt q = 0; q < nb_quad; ++q) {
- // trac(quad_coords.storage()+el*nb_quad*2+q,sigma_funct_val);
- // sigma_funct_val += 4;
- // }
- // }
-
- // Math::matrix_vector(2,2,*sigma_funct,*normals_on_quad,*funct);
- // funct->extendComponentsInterlaced(nb_nodes_per_element,2);
-
- // Real * funct_val = funct->storage();
- // for (UInt el = 0; el < nb_element; ++el) {
- // for (UInt q = 0; q < nb_quad; ++q) {
- // for (UInt n = 0; n < nb_nodes_per_element; ++n) {
- // *funct_val++ *= *shapes_val;
- // *funct_val++ *= *shapes_val++;
- // }
- // }
- // }
-
-
- // Array<Real> * int_funct = new Array<Real>(nb_element, 2*nb_nodes_per_element,
- // "inte_funct");
- // fem_boundary.integrate(*funct, *int_funct, 2*nb_nodes_per_element, *it);
- // delete funct;
-
- // fem_boundary.assembleArray(*int_funct,model->getForce(), 2, *it);
- // delete int_funct;
- // }
-
-
- // model->getDisplacement().storage()[1] = 0.1;
-
-
-#ifdef AKANTU_USE_IOHELPER
- iohelper::DumperParaview dumper;
- dumper.SetMode(iohelper::TEXT);
-
- dumper.SetPoints(model->getFEEngine().getMesh().getNodes().storage(), 2, nb_nodes, "coordinates");
- dumper.SetConnectivity((int *)model->getFEEngine().getMesh().getConnectivity(_triangle_3).storage(),
- iohelper::TRIANGLE1, model->getFEEngine().getMesh().getNbElement(_triangle_3), iohelper::C_MODE);
- dumper.AddNodeDataField(model->getDisplacement().storage(), 2, "displacements");
- dumper.AddNodeDataField(model->getVelocity().storage(), 2, "velocity");
- dumper.AddNodeDataField(model->getForce().storage(), 2, "force");
- dumper.AddNodeDataField(model->getResidual().storage(), 2, "residual");
- dumper.AddElemDataField(model->getMaterial(0).getStrain(_triangle_3).storage(), 4, "strain");
- dumper.AddElemDataField(model->getMaterial(0).getStress(_triangle_3).storage(), 4, "stress");
- dumper.SetEmbeddedValue("displacements", 1);
- dumper.SetEmbeddedValue("force", 1);
- dumper.SetPrefix("paraview/");
- dumper.Init();
-#endif //AKANTU_USE_IOHELPER
-
- model->setPotentialEnergyFlagOn();
- for(UInt s = 0; s < max_steps; ++s) {
- model->explicitPred();
-
- model->updateResidual();
- model->updateAcceleration();
- model->explicitCorr();
-
- epot = model->getPotentialEnergy();
- ekin = model->getKineticEnergy();
-
- std::cout << s << " " << epot << " " << ekin << " " << epot + ekin
- << std::endl;
-
-#ifdef AKANTU_USE_IOHELPER
- if(s % 10 == 0) dumper.Dump();
-#endif //AKANTU_USE_IOHELPER
- }
-
- 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_mass_not_lumped.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_mass_not_lumped.cc
deleted file mode 100644
index aa1c7f751..000000000
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_mass_not_lumped.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * @file test_solid_mechanics_model_bar_traction2d_mass_not_lumped.cc
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date Tue Dec 20 15:37:09 2011
- *
- * @brief test of the class SolidMechanicsModel
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-#include <limits>
-#include <fstream>
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "mesh.hh"
-#include "mesh_io.hh"
-#include "mesh_io_msh.hh"
-#include "solid_mechanics_model.hh"
-#include "material.hh"
-/* -------------------------------------------------------------------------- */
-using namespace akantu;
-
-akantu::ElementType type = akantu::_triangle_3;
-
-akantu::SolidMechanicsModel * model;
-akantu::UInt spatial_dimension = 2;
-akantu::UInt nb_nodes;
-akantu::UInt nb_element;
-
-akantu::Array<akantu::Real> * lumped;
-
-int main(int argc, char *argv[])
-{
- akantu::initialize(argc, argv);
- akantu::UInt max_steps = 5000;
- akantu::Real time_factor = 0.8;
-
- // akantu::Real epot, ekin;
-
- akantu::Mesh mesh(spatial_dimension);
- akantu::MeshIOMSH mesh_io;
- mesh_io.read("bar1.msh", mesh);
-
- model = new akantu::SolidMechanicsModel(mesh);
-
- nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- nb_element = model->getFEEngine().getMesh().getNbElement(type);
-
- lumped = new akantu::Array<akantu::Real>(nb_nodes, spatial_dimension);
-
- /// model initialization
- model->initFull("material.dat");
- std::cout << model->getMaterial(0) << std::endl;
-
- model->initMaterials();
- model->initSolver();
- model->assembleMass();
-
- model->getMassMatrix().lump(*lumped);
-
- /// 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);
-
- model->updateResidual();
- model->initialAcceleration();
-
- model->setBaseName("bar2d_mass_not_lumped");
- model->addDumpField("displacement");
- model->addDumpField("velocity" );
- model->addDumpField("acceleration");
- model->addDumpField("force" );
- model->addDumpField("residual" );
- model->dump();
-
- std::ofstream energy;
- energy.open("energy_bar_2d_not_lumped.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->getPotentialEnergy();
- akantu::Real ekin = model->getKineticEnergy();
-
- energy << s << "," << (s-1)*time_step << "," << epot << "," << ekin << "," << epot + ekin
- << std::endl;
-
- if(s % 1 == 0) model->dump();
- if(s % 100 == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
- }
-
- energy.close();
-
- delete model;
-
- 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_pbc_parallel.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_pbc_parallel.cc
deleted file mode 100644
index 4c2b61b74..000000000
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_pbc_parallel.cc
+++ /dev/null
@@ -1,252 +0,0 @@
-/**
- * @file test_solid_mechanics_model_pbc_parallel.cc
- *
- * @author David Simon Kammer <david.kammer@epfl.ch>
- *
- * @date Fri Apr 13 16:31:38 2012
- *
- * @brief test if pbc works in parallel if partition is strips
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-#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"
-#endif //AKANTU_USE_IOHELPER
-
-#ifdef AKANTU_USE_IOHELPER
-akantu::ElementType type = akantu::_quadrangle_4;
-iohelper::ElemType paraview_type = iohelper::QUAD1;
-#endif //AKANTU_USE_IOHELPER
-
-#ifdef AKANTU_USE_IOHELPER
-static void paraviewInit(iohelper::Dumper & dumper, const akantu::SolidMechanicsModel & model);
-static void paraviewDump(iohelper::Dumper & dumper);
-#endif
-
-akantu::Array<akantu::Real> proc_rank(0,1);
-
-int main(int argc, char *argv[])
-{
- akantu::debug::setDebugLevel(akantu::dblWarning);
- akantu::initialize(argc, argv);
-
- akantu::StaticCommunicator & comm =
- akantu::StaticCommunicator::getStaticCommunicator();
- akantu::Int psize = comm->getNbProc();
- akantu::Int prank = comm->whoAmI();
-
- akantu::UInt spatial_dimension = 2;
- // akantu::UInt max_steps = 1;
- akantu::Real time_factor = 0.2;
-
- akantu::Mesh mesh(spatial_dimension);
-
- akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
- akantu::MeshIOMSH mesh_io;
- mesh_io.read("square_structured.msh", mesh);
- partition = new akantu::MeshPartitionScotch(mesh, spatial_dimension);
- partition->setNbPartition(psize);
-
- // create the partition
- akantu::Array<akantu::Int> part_tab(0,1);
- mesh.computeBoundingBox();
- akantu::Real rank_border = 0.5 * (mesh.getYMax() - mesh.getYMin());
- rank_border += 1e-10;
-
- akantu::Mesh::type_iterator it = mesh.firstType(spatial_dimension);
- akantu::Mesh::type_iterator end = mesh.lastType(spatial_dimension);
- for(; it != end; ++it) {
- akantu::ElementType c_type = *it;
- akantu::UInt nb_element = mesh.getNbElement(*it);
-
- for (akantu::UInt el=0; el<nb_element; ++el) {
- akantu::Real barycenter[spatial_dimension];
- mesh.getBarycenter(el,c_type,barycenter);
- if (barycenter[1] > rank_border)
- part_tab.push_back(0);
- else
- part_tab.push_back(1);
- }
- }
-
- partition->fillPartitionInformation(mesh,part_tab.storage());
- } else {
- mesh.computeBoundingBox();
- }
-
- akantu::SolidMechanicsModel * model = new akantu::SolidMechanicsModel(mesh);
- model->initParallel(partition);
-
- /// model initialization
- model->initArrays();
-
- /// set vectors to 0
- model->getForce().clear();
- model->getVelocity().clear();
- model->getAcceleration().clear();
- model->getDisplacement().clear();
-
- model->initExplicit();
- model->initModel();
- model->readMaterials("material.dat");
- model->initMaterials();
-
- if(prank == 0)
- std::cout << model->getMaterial(0) << std::endl;
-
- model->setPBC(1,0,0);
- model->initPBC();
- model->assembleMassLumped();
-
- akantu::UInt nb_element = mesh.getNbElement(type);
- akantu::UInt nb_quads = model->getFEEngine().getNbQuadraturePoints(type);
- for(akantu::UInt i=0; i<nb_element * nb_quads; ++i)
- proc_rank.push_back(prank);
-
- /// boundary conditions
- akantu::UInt nb_nodes = model->getFEEngine().getMesh().getNbNodes();
- akantu::Real eps = 1e-16;
- akantu::Array<akantu::Real> & coords = const_cast<akantu::Array<akantu::Real> & >(model->getFEEngine().getMesh().getNodes());
- for (akantu::UInt i = 0; i < nb_nodes; ++i) {
- // block top and bottom nodes
- if(std::abs(coords(i,1)-mesh.getYMax()) <= eps
- || std::abs(coords(i,1)-mesh.getYMin()) <= eps) {
- model->getBlockedDOFs().storage()[spatial_dimension*i + 1] = true;
- }
- // correct coordinates (gmsh's unprecision)
- for (akantu::UInt d=0; d<spatial_dimension; ++d) {
- akantu::Real cor = std::floor(10 * coords(i,d) + 0.5) / 10.;
- coords(i,d) = cor;
- //std::cout << cor << " ";
- }
- //std::cout << std::endl;
- }
- //std::cout << std::endl;
- model->synchronizeBoundaries();
-
- akantu::Real time_step = model->getStableTimeStep() * time_factor;
- if(prank == 0)
- std::cout << "Time Step = " << time_step << "s" << std::endl;
- model->setTimeStep(time_step);
-
-#ifdef AKANTU_USE_IOHELPER
- /// initialize the paraview output
- model->updateResidual();
- iohelper::DumperParaview dumper;
- paraviewInit(dumper, *model);
-#endif //AKANTU_USE_IOHELPER
-
- // modify displacements
- akantu::Array<akantu::Real> & displacement = model->getDisplacement();
- for (akantu::UInt i = 0; i < nb_nodes; ++i) {
- displacement(i,1) = std::abs(coords(i,1) - mesh.getYMin()) * 0.0001;
- }
- model->synchronizeBoundaries();
-
-#ifdef AKANTU_USE_IOHELPER
- /// initialize the paraview output
- model->updateResidual();
- model->synchronizeResidual();
- paraviewDump(dumper);
-#endif //AKANTU_USE_IOHELPER
-
- // test (traction at top and bottom boundary should be 2.826923077e7)
- // therefore the nodal residual should be 2.826923077e6
- akantu::Real solution = 2.826923077e6;
- akantu::Real adm_error = 1e-3;
- for (akantu::UInt i = 0; i < nb_nodes; ++i) {
- akantu::Real trac = std::abs(model->getResidual().storage()[spatial_dimension*i + 1]);
- if((std::abs(coords(i,1)-mesh.getYMax()) <= eps
- || std::abs(coords(i,1)-mesh.getYMin()) <= eps) &&
- std::abs(trac - solution) > adm_error) {
- std::cerr << "Boundary residual in y direction is " << trac <<
- " but should be " << solution << "!!!" << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- akantu::finalize();
- if(prank == 0)
- std::cout << "Test successful!" << std::endl;
- return EXIT_SUCCESS;
-}
-
-/* -------------------------------------------------------------------------- */
-/* iohelper::Dumper vars */
-/* -------------------------------------------------------------------------- */
-
-#ifdef AKANTU_USE_IOHELPER
-void paraviewInit(iohelper::Dumper & dumper, const akantu::SolidMechanicsModel & model) {
- akantu::StaticCommunicator * comm =
- akantu::StaticCommunicator::getStaticCommunicator();
- akantu::Int psize = comm->getNbProc();
- akantu::Int prank = comm->whoAmI();
-
- akantu::UInt spatial_dimension = model.getSpatialDimension();
- akantu::UInt nb_nodes = model.getFEEngine().getMesh().getNbNodes();
- akantu::UInt nb_element = model.getFEEngine().getMesh().getNbElement(type);
- dumper.SetParallelContext(prank, psize);
- dumper.SetPoints(model.getFEEngine().getMesh().getNodes().storage(),
- spatial_dimension, nb_nodes, "pbc_parallel");
- dumper.SetConnectivity((int *)model.getFEEngine().getMesh().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, "force");
- dumper.AddNodeDataField(model.getMass().storage(),
- spatial_dimension, "mass");
- dumper.AddNodeDataField(model.getForce().storage(),
- spatial_dimension, "applied_force");
- 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.AddElemDataField(proc_rank.storage(), 1, "rank");
- dumper.SetEmbeddedValue("displacements", 1);
- dumper.SetPrefix("paraview/");
- dumper.Init();
- dumper.Dump();
-}
-
-/* -------------------------------------------------------------------------- */
-void paraviewDump(iohelper::Dumper & dumper) {
- dumper.Dump();
-}
-#endif
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..1c60226cc 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,206 @@
/**
* @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);
+static Real analytical_solution(Real time, Real L, Real rho, Real E,
+ __attribute__((unused)) 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);
+ 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;
+ return 2. * F * pow(L, 3) / pow(M_PI, 4) / E / I * sum;
}
-
-//load
+// load
const Real F = 0.5e4;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]){
+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 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));
+ 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_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;
+
+ 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;
+ 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();
+ 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;
+ // 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;
+ model.getElementMaterial(type)(i, 0) = 0;
}
- for (UInt n =0; n<nb_nodes; ++n){
+ 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;
+ 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()) {
+ 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;
- /* -------------------------------------------------------------------------- */
+ 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;
+ 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;
+
+ 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;
+ 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 f268e6b8b..dead161f3 100644
--- a/test/test_python_interface/CMakeLists.txt
+++ b/test/test_python_interface/CMakeLists.txt
@@ -1,37 +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/>.
#
#===============================================================================
-package_is_activated(python_interface _python_act)
-if(_python_act)
- add_test(test_multiple_init
- python ${CMAKE_CURRENT_SOURCE_DIR}/test_multiple_init.py ${CMAKE_BINARY_DIR})
-endif()
-file(COPY input_test.dat mesh_dcb_2d.geo
- DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
+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_python_interface/input_test.dat b/test/test_python_interface/input_test.dat
index 7a80374a7..91b0c3ec1 100644
--- a/test/test_python_interface/input_test.dat
+++ b/test/test_python_interface/input_test.dat
@@ -1,23 +1,7 @@
material elastic [
name = bulk
rho = 2500
nu = 0.22
E = 71e9
# finite_deformation = 1
]
-
-material cohesive_exponential [
- name = coh
- sigma_c = 1.5e6
- beta = 1
- delta_c = 1e-4
- exponential_penalty = true
- contact_tangent = 1.0
-]
-
-mesh parameters [
-
- cohesive_surfaces = coh
-
-]
-
diff --git a/test/test_python_interface/test_multiple_init.py b/test/test_python_interface/test_multiple_init.py
old mode 100644
new mode 100755
index e2231b7a1..709a9e0c7
--- a/test/test_python_interface/test_multiple_init.py
+++ b/test/test_python_interface/test_multiple_init.py
@@ -1,60 +1,58 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ===============================================================================
# @file test_multiple_init.py
#
# @author Fabian Barras <fabian.barras@epfl.ch>
#
# @date creation: Tue Jan 5 2016
#
# @brief Testing multiple initialize calls through Python
#
# @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/>.
#
# ===============================================================================
import sys
import os
-from mpi4py import MPI
-
-comm = MPI.COMM_WORLD
-
-sys.path.append(sys.argv[1]+'/python/')
import akantu as aka
+
os.system('gmsh -order 2 -2 -o mesh_dcb_2d.msh mesh_dcb_2d.geo')
-print('First initialisation')
+
aka.initialize('input_test.dat')
+
+print 'First initialisation'
mesh = aka.Mesh(2)
mesh.read('mesh_dcb_2d.msh')
-model = aka.SolidMechanicsModelCohesive(mesh)
-model.initFull(aka.SolidMechanicsModelCohesiveOptions(aka._static))
+model = aka.SolidMechanicsModel(mesh)
+model.initFull(aka.SolidMechanicsModelOptions(aka._static))
del model
del mesh
-aka.clear()
-print('Second initialisation')
-aka.initialize('input_test.dat')
+
+print 'Second initialisation'
mesh = aka.Mesh(2)
mesh.read('mesh_dcb_2d.msh')
-model = aka.SolidMechanicsModelCohesive(mesh)
-model.initFull(aka.SolidMechanicsModelCohesiveOptions(aka._static))
+model = aka.SolidMechanicsModel(mesh)
+model.initFull(aka.SolidMechanicsModelOptions(aka._static))
del model
del mesh
+
aka.finalize()
-print('All right')
+print 'All right'
diff --git a/test/test_solver/CMakeCache.txt b/test/test_solver/CMakeCache.txt
deleted file mode 100644
index 44fc15c46..000000000
--- a/test/test_solver/CMakeCache.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-# 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 486a99d73..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
- DEPENDENCIES test_solver_petsc_mesh
+ DEPENDS test_solver_petsc_mesh
PACKAGE petsc
- )
\ No newline at end of file
+ )
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..0441ab957 100644
--- a/test/test_solver/test_petsc_matrix_diagonal.cc
+++ b/test/test_solver/test_petsc_matrix_diagonal.cc
@@ -1,147 +1,151 @@
/**
* @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 <iostream>
+
/* -------------------------------------------------------------------------- */
#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;
+ std::cout << "error in the stiffness matrix!!!" << std::endl;
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..a8e05726f 100644
--- a/test/test_synchronizer/CMakeLists.txt
+++ b/test/test_synchronizer/CMakeLists.txt
@@ -1,70 +1,74 @@
#===============================================================================
# @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: Wed Jan 20 2016
#
# @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)
+if(DEFINED AKANTU_DAMAGE_NON_LOCAL)
+ add_executable(test_grid_synchronizer_check_neighbors test_grid_synchronizer_check_neighbors.cc test_grid_tools.hh)
target_link_libraries(test_grid_synchronizer_check_neighbors akantu)
+ if(AKANTU_EXTRA_CXX_FLAGS)
+ set_target_properties(test_grid_synchronizer_check_neighbors PROPERTIES COMPILE_FLAGS ${AKANTU_EXTRA_CXX_FLAGS})
+ endif()
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/data_split.geo b/test/test_synchronizer/data_split.geo
deleted file mode 100644
index d416235d8..000000000
--- a/test/test_synchronizer/data_split.geo
+++ /dev/null
@@ -1,29 +0,0 @@
-a = DefineNumber[ .5, Name "Parameters/a" ];
-b = DefineNumber[ .1, Name "Parameters/b" ];
-lc = DefineNumber[ b, Name "Parameters/lc" ];
-
-Point(1) = {-a, -a, -a, lc};
-Extrude {2*a, 0, 0} { Point{1}; }
-Extrude {0, 0, 2*a} { Line{1}; }
-Extrude {0, 2*a, 0} { Surface{5}; Recombine; }
-
-Point(15) = {-b, -b, -b, lc};
-Extrude {2*b, 0, 0} { Point{15}; }
-Extrude {0, 0, 2*b} { Line{28}; }
-Extrude {0, 2*b, 0} { Surface{32}; Recombine; }
-
-Surface Loop(55) = {22, 5, 14, 18, 27, 26};
-Surface Loop(56) = {49, 32, 41, 45, 54, 53};
-
-Volume(57) = {55, 56};
-Physical Volume("volume") = {57};
-
-Physical Surface("inside") = {32, 53, 41, 54, 45, 49};
-Physical Surface("outside") = {27, 14, 26, 22, 18, 5};
-
-#Transfinite Surface "*";
-#Recombine Surface "*";
-
-#Transfinite Volume "*";
-
-
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..a1e0d549c 100644
--- a/third-party/cmake/iohelper.cmake
+++ b/third-party/cmake/iohelper.cmake
@@ -1,45 +1,84 @@
+#===============================================================================
+# @file iohelper.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Mar 30 2015
+# @date last modification: Tue Jan 19 2016
+#
+# @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)
+
+install(FILES ${IOHELPER_LIBRARIES}
+ DESTINATION lib
+ COMPONENT lib
+ )
+
+install(DIRECTORY ${IOHELPER_INCLUDE_DIR}
+ DESTINATION include
+ COMPONENT dev)
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