Page MenuHomec4science

No OneTemporary

File Metadata

Created
Sun, Mar 30, 09:44
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/.gitignore b/.gitignore
index def7b836a..ecf6dd5cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,13 @@
build*
.dir-locals.el
TAGS
third-party/blackdynamite/
third-party/cpp-array/
*~
release
.*.swp
+*.tar.gz
+*.tgz
+*.tbz
+*.tar.bz2
+.idea
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index ec8733613..dd3f1da62 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,12 +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/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 4023cd3ac..e65a837eb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,47 +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>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f7ce193ff..0d66fc747 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,189 +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 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
#===============================================================================
-option(AKANTU_PYTHON_INTERFACE "Generates the Akantu Python module" OFF)
-if(AKANTU_PYTHON_INTERFACE)
- list(APPEND AKANTU_BOOST_COMPONENTS python)
-endif()
-
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" 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
#===============================================================================
-if(AKANTU_PYTHON_INTERFACE)
- 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/Makefile b/Makefile
deleted file mode 100644
index 4f0fa5bc5..000000000
--- a/Makefile
+++ /dev/null
@@ -1,82 +0,0 @@
-# Configuration options.
-cc = not-set
-cxx = not-set
-prefix = not-set
-shared = not-set
-assert = not-set
-verbose = not-set
-doc = not-set
-latex = not-set
-build = not-set
-
-# Basically proxies everything to the builddir cmake.
-
-cputype = $(shell uname -m | sed "s/\\ /_/g")
-systype = $(shell uname -s)
-
-BUILDDIR = build/$(systype)-$(cputype)
-
-# Process configuration options.
-CONFIG_FLAGS = -DCMAKE_VERBOSE_MAKEFILE=0
-ifneq ($(assert), not-set)
- CONFIG_FLAGS += -DNDEGUB=$(assert)
-endif
-ifneq ($(prefix), not-set)
- CONFIG_FLAGS += -DCMAKE_INSTALL_PREFIX=$(prefix)
-endif
-ifneq ($(shared), not-set)
- CONFIG_FLAGS += -DAKANTU_SHARED=$(shared)
-endif
-ifneq ($(verbose), not-set)
- CONFIG_FLAGS += -DAKANTU_VERBOSE=$(verbose)
-endif
-ifneq ($(cxx), not-set)
- CONFIG_FLAGS += -DCMAKE_CXX_COMPILER=$(cxx)
-endif
-ifneq ($(cc), not-set)
- CONFIG_FLAGS += -DCMAKE_C_COMPILER=$(cc)
-endif
-ifneq ($(doc), not-set)
- CONFIG_FLAGS += -DDOCUMENTATION=$(doc)
-endif
-ifneq ($(latex), not-set)
- CONFIG_FLAGS += -DLaTeX=$(latex)
-endif
-ifneq ($(build), not-set)
- CONFIG_FLAGS += -DCMAKE_BUILD_TYPE=$(build)
-endif
-
-
-define run-config
-mkdir -p $(BUILDDIR)
-cd $(BUILDDIR) && cmake $(CURDIR) $(CONFIG_FLAGS)
-endef
-
-all clean install doc check examples package package_source depend edit_cache install/local install/strip list_install_components rebuild_cache a.out:
- @if [ ! -f $(BUILDDIR)/Makefile ]; then \
- more README; \
- else \
- make -C $(BUILDDIR) $@ $(MAKEFLAGS); \
- fi
-
-test:
- @if [ ! -f $(BUILDDIR)/Makefile ]; then \
- more README; \
- else \
- make -C $(BUILDDIR) test $(MAKEFLAGS); \
- fi
-
-uninstall:
- xargs rm < $(BUILDDIR)/install_manifest.txt
-
-config: distclean
- $(run-config)
-
-distclean:
- rm -rf $(BUILDDIR)
-
-remake:
- find . -name CMakeLists.txt -exec touch {} ';'
-
-
-.PHONY: config distclean all clean install uninstall remake dist doc check examples package package_source depend edit_cache install/local install/strip list_install_components rebuild_cache a.out test
\ No newline at end of file
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 26e420b05..220f915ec 100644
--- a/cmake/AkantuCPack.cmake
+++ b/cmake/AkantuCPack.cmake
@@ -1,88 +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_GENERATOR "TGZ")
+set(CPACK_SOURCE_GENERATOR "TGZ;TBZ2")
+if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ set(CPACK_GENERATOR "TGZ;DEB")
+else()
+ set(CPACK_GENERATOR "TGZ;NSIS")
-# General configuration
-set(CPACK_PACKAGE_VENDOR "LSMS")
-set(CPACK_PACKAGE_FILE_NAME "${PACKAGE_FILE_NAME}-${AKANTU_VERSION}-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
-set(CPACK_PACKAGE_VERSION "${AKANTU_VERSION}")
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A multipurpose finite element library, Akantu")
-set(CPACK_PACKAGE_NAME "akantu")
+ package_get_all_external_informations(
+ _external_include_dirs
+ _external_libraries
+ )
-# Debian config package
-set(CPACK_DEBIAN_PACKAGE_MAINTAINER "nicolas.richart@epfl.ch, guillaume.anciaux@epfl.ch")
-if(CMAKE_SYSTEM_PROCESSOR MATCHES "i.86" OR CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${_external_libraries})
+
+ include(InstallRequiredSystemLibraries)
+endif()
+
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "i.86" OR
+ CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR
+ CMAKE_SYSTEM_PROCESSOR MATCHES "[aA][mM][dD]64")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64" CACHE STRING "Architecture of debian package generation")
+ set(_arch "amd64")
else()
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "i386" CACHE STRING "Architecture of debian package generation")
+ set(_arch "i386")
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc")
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "powerpc" CACHE STRING "Architecture of debian package generation")
+ set(_arch "powerpc")
else()
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "unknown" CACHE STRING "Architecture of debian package generation")
+ set(_arch "unknown")
endif()
-set(CPACK_DEBIAN_PACKAGE_DEPENDS "${${_project}_PACKAGE_SYSTEM_DEBIAN_PACKAGE_DEPENDS}")
+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 "${_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)
-set(CPACK_COMPONENTS_ALL lib dev)
+# 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")
+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)
-list(APPEND CPACK_SOURCE_IGNORE_FILES ${AKANTU_EXCLUDE_SOURCE_FILES} ${AKANTU_TESTS_EXCLUDE_FILES} ${AKANTU_DOC_EXCLUDE_FILES})
-foreach(_pkg ${${_project}_PACKAGE_SYSTEM_PACKAGES_OFF})
- string(TOUPPER "${_pkg}" _pkg)
- list(APPEND CPACK_SOURCE_IGNORE_FILES ${CMAKE_SOURCE_DIR}/packages/${${_project}_${_pkg}_FILE})
-endforeach()
+# for debug
+# foreach(_file ${CPACK_SOURCE_IGNORE_FILES})
+# message("IGNORE ${_file}")
+# 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 08b71ee19..b53e58447 100644
--- a/cmake/AkantuConfig.cmake.in
+++ b/cmake/AkantuConfig.cmake.in
@@ -1,65 +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("${AKANTU_CMAKE_DIR}/../cmake/AkantuExamplesMacros.cmake")
-else()
+ 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 eb5612ed3..f745f7cdf 100644
--- a/cmake/AkantuInstall.cmake
+++ b/cmake/AkantuInstall.cmake
@@ -1,140 +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" "
-set(AKANTU_BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS})
-set(AKANTU_BOOST_LIBRARIES ${Boost_LIBRARIES})
+")
+
+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 2a426bc73..cdbca13c6 100644
--- a/cmake/AkantuMacros.cmake
+++ b/cmake/AkantuMacros.cmake
@@ -1,282 +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} ]")
+ 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 "")
+ 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++11 HAVE_CPP_11)
+ unset(_cpp_11_flag)
+ if(HAVE_CPP_11)
+ set(_cpp_11_flag "-std=c++11")
+ else()
+ 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(unordered_map HAVE_TR1_UNORDERED_MAP)
+ 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 009d47d87..f64074096 100644
--- a/cmake/AkantuPackagesSystem.cmake
+++ b/cmake/AkantuPackagesSystem.cmake
@@ -1,397 +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}
+ 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")
+ _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}
+ # 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\\
+ # 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_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)
+#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()
-#-------------------------------------------------------------------------------
-function(add_extra_mpi_options)
- package_is_activated(MPI _act)
- if(_act)
- unset(MPI_ID CACHE)
- package_get_include_dir(MPI _include_dir)
- foreach(_inc_dir ${_include_dir})
- if(EXISTS "${_inc_dir}/mpi.h")
- set(_include_file "${_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_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()
+# ------------------------------------------------------------------------------
+# 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})
- 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()
+ set(_files ${_extra_files_UNPARSED_ARGUMENTS})
- 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()
+ 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})
- if(NOT MPI_ID)
- set(MPI_ID "UNKNOWN" CACHE INTERNAL "")
- set(MPI_ID_VERSION "UNKNOWN" CACHE INTERNAL "")
+ 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()
- 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()
+ endforeach()
endif()
+ endforeach()
- message(STATUS "MPI ID: ${MPI_ID} ${MPI_ID_VERSION} - (MPI spec v${MPI_VERSION})")
+ package_set_variable(EXTRA_FILES ${pkg} ${_files})
+endfunction()
- set(MPI_EXTRA_COMPILE_FLAGS "${_flags}" CACHE STRING "Extra flags for MPI" FORCE)
- mark_as_advanced(MPI_EXTRA_COMPILE_FLAGS)
+# ------------------------------------------------------------------------------
+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()
- if(_flags)
- package_get_source_files(MPI _mpi_srcs _pub _priv)
- package_get_all_source_files(
- _srcs
- _public_hdrs
- _private_HDRS
- )
+function(package_get_files_for_package files)
+ package_get_project_variable(EXTRA_FILES _tmp)
+ set(${files} ${_tmp} PARENT_SCOPE)
+endfunction()
- foreach(_src ${_srcs})
- file(STRINGS "${_src}" _res REGEX "# *include *[<\"]mpi[a-z_]*\\.[h]+[>\"]")
- if(_res)
- list(APPEND _mpi_srcs ${_src})
- endif()
- endforeach()
- if(_mpi_srcs)
- set_property(SOURCE ${_mpi_srcs} PROPERTY COMPILE_FLAGS "${_flags}")
- endif()
- endif()
- endif()
-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 177206e77..0c15b2c35 100644
--- a/cmake/AkantuTestsMacros.cmake
+++ b/cmake/AkantuTestsMacros.cmake
@@ -1,252 +1,399 @@
#===============================================================================
-# @file AkantuTestAndExamples.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/>.
#
-# @section DESCRIPTION
-#
#===============================================================================
-set(AKANTU_DIFF_SCRIPT ${AKANTU_CMAKE_DIR}/akantu_diff.sh)
+#[=======================================================================[.rst:
+#AkantuTestsMacros
+#-----------------
+#
+#This modules provides the functions to helper to declare tests and folders
+#containing tests in akantu
+#
+#.. command:: add_test_tree
+#
+# add_test_tree(<test_direcotry>)
+#
+# ``<test_directory>`` is the entry direcroty of the full structure of
+# subfolders containing tests
+#
+#.. command:: add_akantu_test
+#
+# add_akantu_test(<dir> <desc>)
+#
+# This function add a subdirectory ``<dir>`` of tests that will be conditionnaly
+# activable and will be visible only if the parent folder as been activated An
+# option ``AKANTU_BUILD_TEST_<dir>`` will appear in ccmake with the description
+# ``<desc>``. The compilation of all tests can be forced with the option
+# ``AKANTU_BUILD_ALL_TESTS``
+#
+#.. command:: register_test
+#
+# register_test(<test_name>
+# SOURCES <sources>...
+# PACKAGE <akantu_packages>...
+# SCRIPT <scirpt>
+# [FILES_TO_COPY <filenames>...]
+# [DEPENDS <targets>...]
+# [DIRECTORIES_TO_CREATE <directories>...]
+# [COMPILE_OPTIONS <flags>...]
+# [EXTRA_FILES <filnames>...]
+# [UNSABLE]
+# [PARALLEL]
+# )
+#
+# This function defines a test ``<test_name>_run`` this test could be of
+# different nature depending on the context. If Just sources are provided the
+# test consist of running the executable generated. If a file ``<test_name>.sh``
+# is present the test will execute the script. And if a ``<test_name>.verified``
+# exists the output of the test will be compared to this reference file
+#
+# The options are:
+#
+# ``SOURCES <sources>...``
+# The list of source files to compile to generate the executable of the test
+#
+# ``PACKAGE <akantu_packages>...``
+# The list of package to which this test belongs. The test will be activable
+# only of all the packages listed are activated
+#
+# ``SCRIPT <script>``
+# The script to execute instead of the executable
+#
+# ``FILES_TO_COPY <filenames>...``
+# List of files to copy from the source directory to the build directory
+#
+# ``DEPENDS <targets>...``
+# List of targets the test depends on, for example if a mesh as to be generated
+#
+# ``DIRECTORIES_TO_CREATE <directories>...``
+# Obsolete. This specifies a list of directories that have to be created in
+# the build folder
+#
+# ``COMPILE_OPTIONS <flags>...``
+# List of extra compilations options to pass to the compiler
+#
+# ``EXTRA_FILES <filnames>...``
+# Files to consider when generating a package_source
+#
+# ``UNSABLE``
+# If this option is specified the test can be unacitivated by the glocal option
+# ``AKANTU_BUILD_UNSTABLE_TESTS``, this is mainly intendeed to remove test
+# under developement from the continious integration
+#
+# ``PARALLEL``
+# This specifies that this test should be run in parallel. It will generate a
+# series of test for different number of processors. This automaticaly adds a
+# dependency to the package ``AKANTU_PARALLEL``
+#
+#]=======================================================================]
+
+set(AKANTU_DRIVER_SCRIPT ${AKANTU_CMAKE_DIR}/akantu_test_driver.sh)
# ==============================================================================
-# this should be a macro due to the enable_testing
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 DEPENDENCIES DIRECTORIES_TO_CREATE COMPILE_OPTIONS EXTRA_FILES PACKAGE
+ SOURCES FILES_TO_COPY DEPENDS DIRECTORIES_TO_CREATE COMPILE_OPTIONS EXTRA_FILES PACKAGE
)
cmake_parse_arguments(_register_test
- "UNSTABLE"
- ""
+ "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}")
+ 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()
+
+ # add the extra compilation options
+ if(_register_test_COMPILE_OPTIONS)
+ set_target_properties(${test_name}
+ PROPERTIES COMPILE_DEFINITIONS "${_register_test_COMPILE_OPTIONS}")
+ endif()
+ if(AKANTU_EXTRA_CXX_FLAGS)
+ set_target_properties(${test_name}
+ PROPERTIES COMPILE_FLAGS "${AKANTU_EXTRA_CXX_FLAGS}")
+ endif()
+ else()
+ if(_register_test_UNPARSED_ARGUMENTS AND NOT _register_test_SCRIPT)
+ set(_register_test_SCRIPT ${_register_test_UNPARSED_ARGUMENTS})
+ endif()
endif()
- set(_test_all_files)
- # add the different dependencies (meshes, local libraries, ...)
- foreach(_dep ${_register_test_DEPENDENCIES})
- add_dependencies(${test_name} ${_dep})
- get_target_property(_dep_in_ressources ${_dep} RESSOURCES)
-
- if(_dep_in_ressources)
- list(APPEND _test_all_files ${_dep_in_ressources})
- endif()
- endforeach()
-
# 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()
+ foreach(_file ${_register_test_FILES_TO_COPY})
+ file(COPY "${_file}" DESTINATION .)
+ endforeach()
endif()
# create the needed folders in the build folder
if(_register_test_DIRECTORIES_TO_CREATE)
- foreach(_dir ${_register_test_DIRECTORIES_TO_CREATE})
- if(IS_ABSOLUTE ${dir})
- file(MAKE_DIRECTORY ${_dir})
- else()
- file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir})
- endif()
- endforeach()
+ 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()
-
# register the test for ctest
- if(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)
- add_test(${test_name}_run
- ${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)
+ set(_arguments -n "${test_name}")
+ if(_register_test_SCRIPT)
+ file(COPY ${_register_test_SCRIPT}
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+ DESTINATION .)
+ list(APPEND _arguments -e "${_register_test_SCRIPT}")
+ elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh")
+ file(COPY ${test_name}.sh DESTINATION .)
+ list(APPEND _arguments -e "${test_name}.sh")
else()
- add_test(${test_name}_run
- ${CMAKE_CURRENT_BINARY_DIR}/${test_name})
+ 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}")
+
+ # 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()
- # 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 2d404a38d..47fe71d83 100644
--- a/cmake/Modules/CMakePackagesSystem.cmake
+++ b/cmake/Modules/CMakePackagesSystem.cmake
@@ -1,854 +1,1016 @@
#===============================================================================
# @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
+#
+# package_list_packages(<regular_package_folder>
+# [ EXTRA_PACKAGE_FOLDER <extra_package_folder> ]
+# [ SOURCE_FOLDER <source_folder>]
+# [ TEST_FOLDER <test_folder> ]
+# [ MANUAL_FOLDER <manual_folder> ]
+# )
+#
+# This command will look for packages name like ``<regular_package_folder>/<package>.cmake``
+# OR ``<extra_package_folder>/<package>/package.cmake``
+#
+#A package is a cmake script that should contain at list the declaration of a
+#package
+#
+#.. command:: package_declare
#
-# It can also declare multiple informations:
-# source files:
-# package_declare_sources(<package real name>
-# <src1> <src2> ... <srcn>)
+# 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> ]]
+# )
#
-# a LaTeX documentation:
-# package_declare_documentation(<package real name>
-# <line1> <line2> ...<linen>)
+#.. command:: package_declare_sources
#
-# LaTeX documentation files
-# package_declare_documentation_files(<package real name>
-# <file1> <file2> ... <filen>)
+# It can also declare multiple informations:
+# source files:
#
-# Different function can also be retrieved from the package system by using the
-# different accessors
+# 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>)
# package_remove_dependencies(<pkg> <dep1> <dep2> ... <depn>)
# package_remove_dependency(<pkg> <dep>)
#
+#.. 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
+#.. 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>)
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
-#
-#===============================================================================
+#]=======================================================================]
+
include(CMakeParseArguments)
#===============================================================================
# Package Management
#===============================================================================
if(__CMAKE_PACKAGES_SYSTEM)
return()
endif()
set(__CMAKE_PACKAGES_SYSTEM TRUE)
if(CMAKE_VERSION VERSION_GREATER 3.1.2)
cmake_policy(SET CMP0054 NEW)
endif()
#===============================================================================
option(AUTO_MOVE_UNKNOWN_FILES
"Give to cmake the permission to move the unregistered files to the ${PROJECT_SOURCE_DIR}/tmp directory" FALSE)
mark_as_advanced(AUTO_MOVE_UNKNOWN_FILES)
include(CMakePackagesSystemGlobalFunctions)
include(CMakePackagesSystemPrivateFunctions)
# ==============================================================================
# "Public" Accessors
# ==============================================================================
# ------------------------------------------------------------------------------
# Package name
# ------------------------------------------------------------------------------
function(package_get_name pkg pkg_name)
string(TOUPPER ${PROJECT_NAME} _project)
string(REPLACE "-" "_" _str_pkg "${pkg}")
string(TOUPPER ${_str_pkg} _u_package)
set(${pkg_name} ${_project}_PKG_${_u_package} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Real name
# ------------------------------------------------------------------------------
function(package_get_real_name pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_real_name(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Option name
# ------------------------------------------------------------------------------
function(package_get_option_name pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_option_name(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Set if system package or compile external lib
# ------------------------------------------------------------------------------
function(package_use_system pkg ret)
package_get_name(${pkg} _pkg_name)
_package_use_system(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
function(package_add_third_party_script_variable pkg var)
package_get_name(${pkg} _pkg_name)
_package_add_third_party_script_variable(${_pkg_name} ${var} ${ARGN})
set(${var} ${ARGN} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Set if system package or compile external lib
# ------------------------------------------------------------------------------
function(package_add_to_export_list pkg)
package_get_name(${pkg} _pkg_name)
_package_add_to_export_list(${_pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Nature
# ------------------------------------------------------------------------------
function(package_get_nature pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_nature(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Description
# ------------------------------------------------------------------------------
function(package_get_description pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_description(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Package file name
# ------------------------------------------------------------------------------
function(package_get_filename pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_filename(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Source files
# ------------------------------------------------------------------------------
function(package_get_source_files pkg ret_srcs ret_pub ret_priv)
package_get_name(${pkg} _pkg_name)
_package_get_source_files(${_pkg_name} _tmp_srcs _tmp_pub _tmp_priv)
set(${ret_srcs} ${_tmp_srcs} PARENT_SCOPE)
set(${ret_pub} ${_tmp_pub} PARENT_SCOPE)
set(${ret_priv} ${_tmp_pric} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Source folder
# ------------------------------------------------------------------------------
function(package_get_sources_folder pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_sources_folder(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Test folder
# ------------------------------------------------------------------------------
function(package_get_tests_folder pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_tests_folder(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Manual folder
# ------------------------------------------------------------------------------
function(package_get_manual_folder pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_manual_folder(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------
# Extra option for the find_package
# ------------------------------------------------------------------------------
function(package_get_find_package_extra_options pkg ret)
package_get_name(${pkg} _pkg_name)
_package_get_find_package_extra_options(${_pkg_name} _tmp)
set(${ret} ${_tmp} PARENT_SCOPE)
endfunction()
function(package_set_find_package_extra_options pkg)
package_get_name(${pkg} _pkg_name)
_package_set_find_package_extra_options(${_pkg_name} ${ARGN})
endfunction()
# ------------------------------------------------------------------------------
# Compilation flags
# ------------------------------------------------------------------------------
-function(package_get_compile_flags pkg ret)
+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()
function(package_remove_dependencies pkg)
foreach(_dep ${ARGN})
package_remove_dependency(${pkg} _dep)
endforeach()
endfunction()
function(package_remove_dependency pkg dep)
package_get_name(${pkg} _pkg_name)
package_get_name(${dep} _dep_pkg_name)
_package_remove_dependency(${_pkg_name} ${_dep_pkg_name})
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)
- set(tmp_SRCS)
- set(tmp_PUBLIC_HEADERS)
- set(tmp_PRIVATE_HEADERS)
+ 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}
- _tmp_SRCS
- _tmp_PUBLIC_HEADERS
- _tmp_PRIVATE_HEADERS
+ _pkg_srcs
+ _pkg_public_headers
+ _pkg_private_headers
)
- list(APPEND tmp_SRCS ${_tmp_SRCS})
- list(APPEND tmp_PUBLIC_HEADERS ${tmp_PUBLIC_HEADERS})
- list(APPEND tmp_PRIVATE_HEADERS ${tmp_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)
+ 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)
-
- 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_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})
- package_get_name(${_pkg} _pkg_name)
- _package_set_filename(${_pkg_name} "${PACKAGE_FOLDER}/${_pkg_file}")
+ 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)
- _package_set_sources_folder(${_pkg_name} "${_abs_src_folder}")
- _package_set_tests_folder(${_pkg_name} "${_abs_test_folder}")
- _package_set_manual_folder(${_pkg_name} "${_abs_manual_folder}")
-
- list(APPEND _packages_list_all ${_pkg_name})
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")
- _package_set_sources_folder(${_pkg_name}
- "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/src")
+ set(_current_src_folder "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/src" CACHE INTERNAL "" FORCE)
if(EXISTS "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/test")
- _package_set_tests_folder(${_pkg_name}
- "${_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")
- _package_set_manual_folder(${_pkg_name}
- "${_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")
- list(APPEND _packages_list_all ${_pkg_name})
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()
- # Store the list of packages
- string(TOUPPER ${PROJECT_NAME} _project)
- set(${_project}_ALL_PACKAGES_LIST ${_packages_list_all}
- CACHE INTERNAL "List of available packages" FORCE)
-
_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 de1a072f6..268bb3999 100644
--- a/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
+++ b/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
@@ -1,96 +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 value_in)
+function(package_set_project_variable variable)
string(TOUPPER ${PROJECT_NAME} _u_project)
- set(${_u_project}_${variable} ${value_in} CACHE INTERNAL "" FORCE)
+ 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})
- list(REMOVE_DUPLICATES _tmp_list)
+ 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()
-# ==============================================================================
\ No newline at end of file
+# ==============================================================================
diff --git a/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake b/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
index 5a0ec65ab..65ab2b0ce 100644
--- a/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
+++ b/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
@@ -1,851 +1,924 @@
#===============================================================================
-# @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 " (version ${${_opt_name}_VERSION})")
+ set(_version "${${_opt_name}_VERSION}")
+ set(${_u_name}_VERSION "${_version}" CACHE INTERNAL "" FORCE)
elseif(${_u_name}_VERSION)
- set(_version " (version ${${_u_name}_VERSION})")
+ set(_version "${${_u_name}_VERSION}")
endif()
# load the script
- message(STATUS "${_name}: building as third-party${_version}")
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_get_compile_flags pkg_name flags)
- _package_get_variable(COMPILE_FLAGS ${pkg_name} _flags)
- set(${flags} ${_flags} PARENT_SCOPE)
+function(_package_unset_compile_flags pkg_name lang)
+ _package_variable_unset(COMPILE_${lang}_FLAGS ${pkg_name})
+endfunction()
+
+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()
function(_package_remove_dependency pkg_name dep)
set(_deps ${${pkg_name}_DEPENDENCIES})
_package_get_fdependencies(${dep} _fdeps)
# 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))
_package_get_description(${dep} _dep_desc)
_package_get_option_name(${dep} _dep_option_name)
set(${_dep_option_name} ${${dep}_OLD} CACHE BOOL "${_dep_desc}" FORCE)
unset(${dep}_OLD CACHE)
endif()
# remove the pkg_name form the reverse dependency
_package_remove_fdependency(${dep} ${pkg_name})
list(FIND _deps ${dep} pos)
if(NOT pos EQUAL -1)
list(REMOVE_AT _deps ${pos})
_package_set_variable(DEPENDENCIES ${pkg_name} ${_deps})
endif()
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})
-
- string(TOUPPER ${${pkg_name}} _u_package)
- if(${_u_package}_LIBRARIES)
- _package_set_libraries(${pkg_name} ${${_u_package}_LIBRARIES})
- endif()
- if(${_u_package}_INCLUDE_DIR)
- _package_set_include_dir(${pkg_name} ${${_u_package}_INCLUDE_DIR})
- endif()
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()
- _package_get_real_name(${pkg_name} _real_name)
# 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()
- string(TOUPPER ${${pkg_name}} _u_package)
set(_package_prefix ${_u_package})
endif()
set(_act FALSE)
set(_prefix_to_consider)
- if(_opt_pkg_FOUND)
- set(_act TRUE)
- set(_prefix_to_consider ${_package_prefix})
+ 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})
+ _package_set_include_dir(${pkg_name} ${${_prefix}_INCLUDE_DIRS})
elseif(DEFINED ${_prefix}_INCLUDE_DIR)
- _package_set_include_dir(${_pkg_name} ${${_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})
+ _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})
+ _package_set_libraries(${pkg_name} ${${_prefix}_LIBRARIES})
elseif(DEFINED ${_prefix}_LIBRARY)
- _package_set_libraries(${_pkg_name} ${${_prefix}_LIBRARY})
+ _package_set_libraries(${pkg_name} ${${_prefix}_LIBRARY})
endif()
endforeach()
- string(TOLOWER "${pkg_name}" _l_pkg_name)
- set(_output_file "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_l_pkg_name}.cmake")
- if(EXISTS "${_output_file}")
- include(${_output_file})
+ _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 a86330f5b..036e58910 100644
--- a/cmake/Modules/FindMumps.cmake
+++ b/cmake/Modules/FindMumps.cmake
@@ -1,113 +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)
-find_package_handle_standard_args(Mumps DEFAULT_MSG
- MUMPS_LIBRARIES MUMPS_INCLUDE_DIR)
\ No newline at end of file
+if(CMAKE_VERSION VERSION_GREATER 2.8.12)
+ if(MUMPS_INCLUDE_DIR)
+ file(STRINGS ${MUMPS_INCLUDE_DIR}/dmumps_c.h _versions
+ REGEX "^#define MUMPS_VERSION .*")
+ foreach(_ver ${_versions})
+ string(REGEX MATCH "MUMPS_VERSION *\"([0-9.]+)\"" _tmp "${_ver}")
+ set(_mumps_VERSION ${CMAKE_MATCH_1})
+ endforeach()
+ set(MUMPS_VERSION "${_mumps_VERSION}" CACHE INTERNAL "")
+ endif()
+
+ find_package_handle_standard_args(Mumps
+ REQUIRED_VARS
+ MUMPS_LIBRARY_DMUMPS
+ MUMPS_LIBRARY_COMMON
+ MUMPS_LIBRARY_PORD
+ MUMPS_INCLUDE_DIR
+ VERSION_VAR
+ MUMPS_VERSION)
+else()
+ find_package_handle_standard_args(Mumps DEFAULT_MSG
+ MUMPS_LIBRARIES MUMPS_INCLUDE_DIR)
+endif()
+
+
+if (MUMPS_FOUND AND NOT TARGET MUMPS::common)
+ set(MUMPS_LIBRARIES_ALL ${MUMPS_LIBRARY_DMUMPS})
+
+ if(MUMPS_LIBRARY_COMMON MATCHES ".*mumps_common.*${CMAKE_STATIC_LIBRARY_SUFFIX}")
+ # Assuming mumps was compiled as a static library
+ set(MUMPS_LIBRARY_TYPE STATIC CACHE INTERNAL "" FORCE)
+
+ set(_extra_dep_list pthread)
+ find_package(BLAS REQUIRED)
+ list(APPEND _extra_dep_list ${BLAS_LIBRARIES})
+
+ if (CMAKE_Fortran_COMPILER MATCHES ".*gfortran")
+ set(_compiler_specific gfortran)
+ elseif (CMAKE_Fortran_COMPILER MATCHES ".*ifort")
+ set(_compiler_specific ifcore)
+ endif()
+ list(APPEND _extra_dep_list ${_compiler_specific})
+
+ list(APPEND MUMPS_LIBRARIES_ALL
+ ${MUMPS_LIBRARY_COMMON}
+ ${MUMPS_LIBRARY_PORD}
+ pthread
+ ${_compiler_specific}
+ )
+
+ if("${Mumps_FIND_COMPONENTS}" STREQUAL "parallel")
+ find_package(MPI REQUIRED)
+ list(APPEND _extra_dep_list ${MPI_Fortran_LIBRARIES})
+
+ find_package(ScaLAPACK REQUIRED)
+ list(APPEND _extra_dep_list ScaLAPACK)
+
+ list(APPEND MUMPS_LIBRARIES_ALL
+ ${MPI_Fortran_LIBRARIES}
+ ${SCALAPACK_LIBRARIES}
+ )
+ endif()
+
+ list(APPEND MUMPS_LIBRARIES_ALL
+ ${BLAS_LIBRARIES})
+
+ if(_extra_dep_list)
+ set(_extra_dep ";${_extra_dep_list}")
+ else()
+ set(_extra_dep)
+ endif()
+ else()
+ set(MUMPS_LIBRARY_TYPE SHARED CACHE INTERNAL "" FORCE)
+ endif()
+
+ add_library(MUMPS::common ${MUMPS_LIBRARY_TYPE} IMPORTED GLOBAL)
+ add_library(MUMPS::pord ${MUMPS_LIBRARY_TYPE} IMPORTED GLOBAL)
+
+ #TODO adapt it for windows and dlls (check FindGSL as an example)
+ set_target_properties(MUMPS::pord PROPERTIES
+ IMPORTED_LOCATION "${MUMPS_LIBRARY_PORD}"
+ INTERFACE_INCLUDE_DIRECTORIES "${MUMPS_INCLUDE_DIR}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C")
+ set_target_properties(MUMPS::common PROPERTIES
+ IMPORTED_LOCATION "${MUMPS_LIBRARY_COMMON}"
+ INTERFACE_INCLUDE_DIRECTORIES "${MUMPS_INCLUDE_DIR}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C;Fortran"
+ INTERFACE_LINK_LIBRARIES "MUMPS::pord${_extra_dep}")
+
+ foreach(_precision s d c z)
+ string(TOUPPER "${_precision}" _u_precision)
+ set(_target MUMPS::${_precision}mumps)
+ add_library(${_target} ${MUMPS_LIBRARY_TYPE} IMPORTED GLOBAL)
+ set_target_properties(${_target} PROPERTIES
+ IMPORTED_LOCATION "${MUMPS_LIBRARY_${_u_precision}MUMPS}"
+ INTERFACE_INCLUDE_DIRECTORIES "${MUMPS_INCLUDE_DIR}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C;Fortran"
+ INTERFACE_LINK_LIBRARIES "MUMPS::common")
+ endforeach()
+
+ set(MUMPS_LIBRARIES ${MUMPS_LIBRARIES_ALL} CACHE INTERNAL "Libraries for MUMPS" FORCE)
+endif()
diff --git a/cmake/Modules/FindNLopt.cmake b/cmake/Modules/FindNLopt.cmake
index 1855f4578..725dc04a9 100644
--- a/cmake/Modules/FindNLopt.cmake
+++ b/cmake/Modules/FindNLopt.cmake
@@ -1,54 +1,53 @@
#===============================================================================
# @file FindNLopt.cmake
#
# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
#
-# @date creation: Fri Jan 04 2013
-# @date last modification: Thu Jul 24 2014
+# @date creation: Sun Oct 19 2014
#
# @brief The find_package file for NLopt optimization library
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+# (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
#
#===============================================================================
find_library(NLOPT_LIBRARIES NAMES nlopt_cxx
PATHS ${NLOPT_DIR} ${NLOPT_INTERNAL_DIR}
PATH_SUFFIXES lib
)
find_path(NLOPT_INCLUDE_DIR nlopt.hpp
PATHS ${NLOPT_DIR} ${NLOPT_INTERNAL_DIR}
PATH_SUFFIXES include
)
#===============================================================================
mark_as_advanced(NLOPT_LIBRARIES)
mark_as_advanced(NLOPT_INCLUDE_DIR)
#===============================================================================
if(NOT NLOPT_FOUND)
set(NLOPT_DIR "" CACHE PATH "Location of NLOPT source directory.")
endif()
#===============================================================================
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(NLopt DEFAULT_MSG NLOPT_LIBRARIES NLOPT_INCLUDE_DIR)
diff --git a/cmake/Modules/FindNumpy.cmake b/cmake/Modules/FindNumpy.cmake
new file mode 100644
index 000000000..2c21b0025
--- /dev/null
+++ b/cmake/Modules/FindNumpy.cmake
@@ -0,0 +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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+# (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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 ac83daed7..6dbfc4916 100644
--- a/cmake/Modules/FindPETSc.cmake
+++ b/cmake/Modules/FindPETSc.cmake
@@ -1,329 +1,334 @@
# - Try to find PETSc
# Once done this will define
#
# PETSC_FOUND - system has PETSc
# PETSC_INCLUDES - the PETSc include directories
# PETSC_LIBRARIES - Link these to use PETSc
# PETSC_COMPILER - Compiler used by PETSc, helpful to find a compatible MPI
# PETSC_DEFINITIONS - Compiler switches for using PETSc
# PETSC_MPIEXEC - Executable for running MPI programs
# PETSC_VERSION - Version string (MAJOR.MINOR.SUBMINOR)
#
# Usage:
# find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0
# find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler
# find_package(PETSc) - same as above
#
# Setting these changes the behavior of the search
# PETSC_DIR - directory in which PETSc resides
# PETSC_ARCH - build architecture
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
set(PETSC_VALID_COMPONENTS
C
CXX)
if(NOT PETSc_FIND_COMPONENTS)
set(PETSC_LANGUAGE_BINDINGS "C")
else()
# Right now, this is designed for compatability with the --with-clanguage option, so
# only allow one item in the components list.
list(LENGTH ${PETSc_FIND_COMPONENTS} components_length)
if(${components_length} GREATER 1)
message(FATAL_ERROR "Only one component for PETSc is allowed to be specified")
endif()
# This is a stub for allowing multiple components should that time ever come. Perhaps
# to also test Fortran bindings?
foreach(component ${PETSc_FIND_COMPONENTS})
list(FIND PETSC_VALID_COMPONENTS ${component} component_location)
if(${component_location} EQUAL -1)
message(FATAL_ERROR "\"${component}\" is not a valid PETSc component.")
else()
list(APPEND PETSC_LANGUAGE_BINDINGS ${component})
endif()
endforeach()
endif()
function (petsc_get_version)
if (EXISTS "${PETSC_DIR}/include/petscversion.h")
file (STRINGS "${PETSC_DIR}/include/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(RELEASE|MAJOR|MINOR|SUBMINOR|PATCH) ")
foreach (line ${vstrings})
string (REGEX REPLACE " +" ";" fields ${line}) # break line into three fields (the first is always "#define")
list (GET fields 1 var)
list (GET fields 2 val)
set (${var} ${val} PARENT_SCOPE)
set (${var} ${val}) # Also in local scope so we have access below
endforeach ()
if (PETSC_VERSION_RELEASE)
set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}p${PETSC_VERSION_PATCH}" PARENT_SCOPE)
else ()
# make dev version compare higher than any patch level of a released version
set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}.99" PARENT_SCOPE)
endif ()
else ()
message (SEND_ERROR "PETSC_DIR can not be used, ${PETSC_DIR}/include/petscversion.h does not exist")
endif ()
endfunction ()
find_path (PETSC_DIR include/petsc.h
HINTS ENV PETSC_DIR
PATHS
# Debian paths
/usr/lib/petscdir/3.5.1 /usr/lib/petscdir/3.5
/usr/lib/petscdir/3.4.2 /usr/lib/petscdir/3.4
/usr/lib/petscdir/3.3 /usr/lib/petscdir/3.2 /usr/lib/petscdir/3.1
/usr/lib/petscdir/3.0.0 /usr/lib/petscdir/2.3.3 /usr/lib/petscdir/2.3.2
# MacPorts path
/opt/local/lib/petsc
$ENV{HOME}/petsc
DOC "PETSc Directory")
find_program (MAKE_EXECUTABLE NAMES make gmake)
if (PETSC_DIR AND NOT PETSC_ARCH)
set (_petsc_arches
$ENV{PETSC_ARCH} # If set, use environment variable first
linux-gnu-c-debug linux-gnu-c-opt # Debian defaults
x86_64-unknown-linux-gnu i386-unknown-linux-gnu)
set (petscconf "NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
foreach (arch ${_petsc_arches})
if (NOT PETSC_ARCH)
find_path (petscconf petscconf.h
HINTS ${PETSC_DIR}
PATH_SUFFIXES ${arch}/include bmake/${arch}
NO_DEFAULT_PATH)
if (petscconf)
set (PETSC_ARCH "${arch}" CACHE STRING "PETSc build architecture")
endif (petscconf)
endif (NOT PETSC_ARCH)
endforeach (arch)
set (petscconf "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE)
endif (PETSC_DIR AND NOT PETSC_ARCH)
set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS
INCLUDE_DIR INCLUDE_CONF)
include (FindPackageMultipass)
find_package_multipass (PETSc petsc_config_current
STATES DIR ARCH
DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC ${petsc_slaves})
# Determine whether the PETSc layout is old-style (through 2.3.3) or
# new-style (>= 3.0.0)
if (EXISTS "${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/petscvariables") # > 3.5
set (petsc_conf_rules "${PETSC_DIR}/lib/petsc/conf/rules")
set (petsc_conf_variables "${PETSC_DIR}/lib/petsc/conf/variables")
elseif (EXISTS "${PETSC_DIR}/${PETSC_ARCH}/include/petscconf.h") # > 2.3.3
set (petsc_conf_rules "${PETSC_DIR}/conf/rules")
set (petsc_conf_variables "${PETSC_DIR}/conf/variables")
elseif (EXISTS "${PETSC_DIR}/bmake/${PETSC_ARCH}/petscconf.h") # <= 2.3.3
set (petsc_conf_rules "${PETSC_DIR}/bmake/common/rules")
set (petsc_conf_variables "${PETSC_DIR}/bmake/common/variables")
elseif (PETSC_DIR)
message (SEND_ERROR "The pair PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSc installation")
endif ()
+
+#message(petsc_conf_rules ${petsc_conf_rules})
+#message(petsc_conf_variables ${petsc_conf_variables})
+#message(petsc_config_current ${petsc_config_current})
+
if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current)
petsc_get_version()
# Put variables into environment since they are needed to get
# configuration (petscvariables) in the PETSc makefile
set (ENV{PETSC_DIR} "${PETSC_DIR}")
set (ENV{PETSC_ARCH} "${PETSC_ARCH}")
# A temporary makefile to probe the PETSc configuration
set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc")
file (WRITE "${petsc_config_makefile}"
"## This file was autogenerated by FindPETSc.cmake
# PETSC_DIR = ${PETSC_DIR}
# PETSC_ARCH = ${PETSC_ARCH}
include ${petsc_conf_rules}
include ${petsc_conf_variables}
show :
\t-@echo -n \${\${VARIABLE}}
")
macro (PETSC_GET_VARIABLE name var)
set (${var} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE)
execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} show VARIABLE=${name}
OUTPUT_VARIABLE ${var}
RESULT_VARIABLE petsc_return)
endmacro (PETSC_GET_VARIABLE)
petsc_get_variable (PETSC_LIB_DIR petsc_lib_dir)
petsc_get_variable (PETSC_EXTERNAL_LIB_BASIC petsc_libs_external)
petsc_get_variable (PETSC_CCPPFLAGS petsc_cpp_line)
petsc_get_variable (PETSC_INCLUDE petsc_include)
petsc_get_variable (PCC petsc_cc)
petsc_get_variable (PCC_FLAGS petsc_cc_flags)
petsc_get_variable (MPIEXEC petsc_mpiexec)
# We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid!
file (REMOVE ${petsc_config_makefile})
include (ResolveCompilerPaths)
# Extract include paths and libraries from compile command line
resolve_includes (petsc_includes_all "${petsc_cpp_line}")
#on windows we need to make sure we're linking against the right
#runtime library
if (WIN32)
if (petsc_cc_flags MATCHES "-MT")
set(using_md False)
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
set(using_md True)
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
if(${using_md} MATCHES "True")
message(WARNING "PETSc was built with /MT, but /MD is currently set.
See http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F")
endif(${using_md} MATCHES "True")
endif (petsc_cc_flags MATCHES "-MT")
endif (WIN32)
include (CorrectWindowsPaths)
convert_cygwin_path(petsc_lib_dir)
message (STATUS "petsc_lib_dir ${petsc_lib_dir}")
macro (PETSC_FIND_LIBRARY suffix name)
set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # Clear any stale value, if we got here, we need to find it again
if (WIN32)
set (libname lib${name}) #windows expects "libfoo", linux expects "foo"
else (WIN32)
set (libname ${name})
endif (WIN32)
find_library (PETSC_LIBRARY_${suffix} NAMES ${libname} HINTS ${petsc_lib_dir} NO_DEFAULT_PATH)
set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}")
mark_as_advanced (PETSC_LIBRARY_${suffix})
endmacro (PETSC_FIND_LIBRARY suffix name)
# Look for petscvec first, if it doesn't exist, we must be using single-library
petsc_find_library (VEC petscvec)
if (PETSC_LIBRARY_VEC)
petsc_find_library (SYS "petscsys;petsc") # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced)
petsc_find_library (MAT petscmat)
petsc_find_library (DM petscdm)
petsc_find_library (KSP petscksp)
petsc_find_library (SNES petscsnes)
petsc_find_library (TS petscts)
macro (PETSC_JOIN libs deps)
list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}})
endmacro (PETSC_JOIN libs deps)
petsc_join (VEC SYS)
petsc_join (MAT VEC)
petsc_join (DM MAT)
petsc_join (KSP DM)
petsc_join (SNES KSP)
petsc_join (TS SNES)
petsc_join (ALL TS)
else ()
set (PETSC_LIBRARY_VEC "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # There is no libpetscvec
petsc_find_library (SINGLE petsc)
foreach (pkg SYS VEC MAT DM KSP SNES TS ALL)
set (PETSC_LIBRARIES_${pkg} "${PETSC_LIBRARY_SINGLE}")
endforeach ()
endif ()
if (PETSC_LIBRARY_TS)
message (STATUS "Recognized PETSc install with separate libraries for each package")
else ()
message (STATUS "Recognized PETSc install with single library for all packages")
endif ()
include(Check${PETSC_LANGUAGE_BINDINGS}SourceRuns)
macro (PETSC_TEST_RUNS includes libraries runs)
if(${PETSC_LANGUAGE_BINDINGS} STREQUAL "C")
set(_PETSC_ERR_FUNC "CHKERRQ(ierr)")
elseif(${PETSC_LANGUAGE_BINDINGS} STREQUAL "CXX")
set(_PETSC_ERR_FUNC "CHKERRXX(ierr)")
endif()
if (PETSC_VERSION VERSION_GREATER 3.1)
set (_PETSC_TSDestroy "TSDestroy(&ts)")
else ()
set (_PETSC_TSDestroy "TSDestroy(ts)")
endif ()
set(_PETSC_TEST_SOURCE "
static const char help[] = \"PETSc test program.\";
#include <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 240bf48ff..b73aa3cdd 100644
--- a/cmake/Modules/FindScotch.cmake
+++ b/cmake/Modules/FindScotch.cmake
@@ -1,107 +1,92 @@
#===============================================================================
# @file FindScotch.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Sep 01 2010
-# @date last modification: Tue Sep 09 2014
+# @date creation: Fri Oct 24 2014
+# @date last modification: Wed Jan 13 2016
#
# @brief The find_package file for Scotch
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+# (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
#
#===============================================================================
#===============================================================================
-#if(SCOTCH_DIR)
-# set(SCOTCH_LIBRARY "NOTFOUND" CACHE INTERNAL "Cleared" FORCE)
-#endif(SCOTCH_DIR)
-
-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)
-#===============================================================================
-if(NOT SCOTCH_FOUND)
- set(SCOTCH_DIR "" CACHE PATH "Location of Scotch library.")
- mark_as_advanced(SCOTCH_DIR)
-endif()
-
#===============================================================================
include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Scotch DEFAULT_MSG
- SCOTCH_LIBRARY SCOTCH_LIBRARY_ERR SCOTCH_INCLUDE_DIR)
-
-
+if(CMAKE_VERSION VERSION_GREATER 2.8.12)
+ if(SCOTCH_INCLUDE_DIR)
+ file(STRINGS ${SCOTCH_INCLUDE_DIR}/scotch.h _versions
+ REGEX "^#define\ +SCOTCH_(VERSION|RELEASE|PATCHLEVEL) .*")
+ foreach(_ver ${_versions})
+ string(REGEX MATCH "SCOTCH_(VERSION|RELEASE|PATCHLEVEL) *([0-9.]+)" _tmp "${_ver}")
+ set(_scotch_${CMAKE_MATCH_1} ${CMAKE_MATCH_2})
+ endforeach()
+ set(SCOTCH_VERSION "${_scotch_VERSION}.${_scotch_PATCHLEVEL}" CACHE INTERNAL "")
+ endif()
+ find_package_handle_standard_args(Scotch
+ REQUIRED_VARS SCOTCH_LIBRARIES SCOTCH_INCLUDE_DIR
+ VERSION_VAR SCOTCH_VERSION)
+else()
+ find_package_handle_standard_args(Scotch DEFAULT_MSG
+ SCOTCH_LIBRARIES SCOTCH_INCLUDE_DIR)
+endif()
diff --git a/cmake/Modules/FindSubversion.cmake b/cmake/Modules/FindSubversion.cmake
index 39a7ca234..b7ea48d7e 100644
--- a/cmake/Modules/FindSubversion.cmake
+++ b/cmake/Modules/FindSubversion.cmake
@@ -1,89 +1,118 @@
+#===============================================================================
+# @file FindSubversion.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Sun Oct 19 2014
+#
+# @brief find_package for subversion
+#
+# @section LICENSE
+#
+# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+# (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
find_program(Subversion_SVN_EXECUTABLE svn
DOC "subversion command line client")
mark_as_advanced(Subversion_SVN_EXECUTABLE)
if(Subversion_SVN_EXECUTABLE)
# the subversion commands should be executed with the C locale, otherwise
# the message (which are parsed) may be translated, Alex
set(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}")
set(ENV{LC_ALL} C)
execute_process(COMMAND ${Subversion_SVN_EXECUTABLE} --version
OUTPUT_VARIABLE Subversion_VERSION_SVN
OUTPUT_STRIP_TRAILING_WHITESPACE)
# restore the previous LC_ALL
set(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL})
string(REGEX REPLACE "^(.*\n)?svn, version ([.0-9]+).*"
"\\2" Subversion_VERSION_SVN "${Subversion_VERSION_SVN}")
macro(Subversion_WC_INFO dir prefix)
# the subversion commands should be executed with the C locale, otherwise
# the message (which are parsed) may be translated, Alex
set(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}")
set(ENV{LC_ALL} C)
execute_process(COMMAND ${Subversion_SVN_EXECUTABLE} info ${dir}
OUTPUT_VARIABLE ${prefix}_WC_INFO
ERROR_VARIABLE Subversion_svn_info_error
RESULT_VARIABLE Subversion_svn_info_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT ${Subversion_svn_info_result} EQUAL 0)
set(${prefix}_WC_FOUND FALSE)
if(NOT "${ARGV2}" STREQUAL "ERROR_QUIET")
message(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} info ${dir}\" failed with output:\n${Subversion_svn_info_error}")
endif(NOT "${ARGV2}" STREQUAL "ERROR_QUIET")
else(NOT ${Subversion_svn_info_result} EQUAL 0)
set(${prefix}_WC_FOUND TRUE)
string(REGEX REPLACE "^(.*\n)?URL: ([^\n]+).*"
"\\2" ${prefix}_WC_URL "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Repository Root: ([^\n]+).*"
"\\2" ${prefix}_WC_ROOT "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Revision: ([^\n]+).*"
"\\2" ${prefix}_WC_REVISION "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Last Changed Author: ([^\n]+).*"
"\\2" ${prefix}_WC_LAST_CHANGED_AUTHOR "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Last Changed Rev: ([^\n]+).*"
"\\2" ${prefix}_WC_LAST_CHANGED_REV "${${prefix}_WC_INFO}")
string(REGEX REPLACE "^(.*\n)?Last Changed Date: ([^\n]+).*"
"\\2" ${prefix}_WC_LAST_CHANGED_DATE "${${prefix}_WC_INFO}")
endif()
# restore the previous LC_ALL
set(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL})
endmacro()
macro(Subversion_WC_LOG dir prefix)
# This macro can block if the certificate is not signed:
# svn ask you to accept the certificate and wait for your answer
# This macro requires a svn server network access (Internet most of the time)
# and can also be slow since it access the svn server
execute_process(COMMAND
${Subversion_SVN_EXECUTABLE} --non-interactive log -r BASE ${dir}
OUTPUT_VARIABLE ${prefix}_LAST_CHANGED_LOG
ERROR_VARIABLE Subversion_svn_log_error
RESULT_VARIABLE Subversion_svn_log_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT ${Subversion_svn_log_result} EQUAL 0)
message(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} log -r BASE ${dir}\" failed with output:\n${Subversion_svn_log_error}")
endif()
endmacro()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Subversion REQUIRED_VARS Subversion_SVN_EXECUTABLE
VERSION_VAR Subversion_VERSION_SVN )
# for compatibility
set(Subversion_FOUND ${SUBVERSION_FOUND})
set(Subversion_SVN_FOUND ${SUBVERSION_FOUND})
diff --git a/cmake/Modules/PCHgcc.cmake b/cmake/Modules/PCHgcc.cmake
index cc3ccf1e5..528ff6a86 100644
--- a/cmake/Modules/PCHgcc.cmake
+++ b/cmake/Modules/PCHgcc.cmake
@@ -1,84 +1,83 @@
#===============================================================================
# @file PCHgcc.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
-# @date creation: Wed Aug 31 2011
-# @date last modification: Sun Jan 06 2013
+# @date creation: Sun Oct 19 2014
#
# @brief
#
# @section LICENSE
#
-# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+# (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
#
#===============================================================================
# (ADD_PCH_RULE _header_filename _src_list)
# Version 7/26/2010 4:55pm
#
# use this macro before "add_executable"
#
# _header_filename
# header to make a .gch
#
# _src_list
# the variable name (do not use ${..}) which contains a
# a list of sources (a.cpp b.cpp c.cpp ...)
# This macro will append a header file to it, then this src_list can be used in
# "add_executable..."
#
#
# Now a .gch file should be generated and gcc should use it.
# (add -Winvalid-pch to the cpp flags to verify)
#
# make clean should delete the pch file
#
# example : ADD_PCH_RULE(headers.h myprog_SRCS)
function(ADD_PCH_RULE _header_filename _src_list)
set(_gch_filename "${CMAKE_CURRENT_BINARY_DIR}/${_header_filename}.gch")
list(APPEND ${_src_list} ${_gch_filename})
set(_args ${CMAKE_CXX_FLAGS} -D__aka_inline__=inline)
get_filename_component(_gch_filename_path ${_gch_filename} PATH)
file(MAKE_DIRECTORY ${_gch_filename_path})
# list(APPEND _args -c ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename})
list(APPEND _args -c ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename} -o ${_gch_filename} -Winvalid-pch)
get_directory_property(DIRINC INCLUDE_DIRECTORIES)
foreach (_inc ${DIRINC})
list(APPEND _args "-I" ${_inc})
endforeach(_inc ${DIRINC})
separate_arguments(_args)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_header_filename} PROPERTIES GENERATED 1)
set_source_files_properties(${_gch_filename} PROPERTIES GENERATED 1)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_header_filename}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename} ${CMAKE_CURRENT_BINARY_DIR}/${_header_filename} # ensure same directory! Required by gcc
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename}
)
add_custom_command(OUTPUT ${_gch_filename}
COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} ${_args}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_header_filename}
)
endfunction(ADD_PCH_RULE _header_filename _src_list)
diff --git a/cmake/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
new file mode 100755
index 000000000..0e01c69ba
--- /dev/null
+++ b/cmake/akantu_test_driver.sh
@@ -0,0 +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: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 7d397ee62..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 =
+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 a169945f5..6d54d9781 100644
--- a/doc/manual/CMakeLists.txt
+++ b/doc/manual/CMakeLists.txt
@@ -1,154 +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}}{${_file}}}"
+ "{\\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-elements.tex b/doc/manual/manual-appendix-elements.tex
index 9ba02a1d4..1bfd5b593 100644
--- a/doc/manual/manual-appendix-elements.tex
+++ b/doc/manual/manual-appendix-elements.tex
@@ -1,275 +1,608 @@
\chapter{Shape Functions\index{Elements}}
\label{app:elements}
-Schmatic overview of all the element types defined in \akantu is described in Chapter~\ref{chap:elements}. In this appendix, more detailed information (shape function, location of Gaussian quadrature points, and so on) of each of these types is listed. For each element type, the coordinates of the nodes are given in the isoparametric frame of reference, together with the shape functions (and their derivatives) on these respective nodes. Also all the Gaussian quadrature points within each element are assigned (together with the weight that is applied on these points). The graphical representations of all the element types can be found in Chapter~\ref{chap:elements}.
+Schmatic overview of all the element types defined in \akantu is described in Section~\ref{sec:elements}. In this appendix, more detailed information (shape function, location of Gaussian quadrature points, and so on) of each of these types is listed. For each element type, the coordinates of the nodes are given in the isoparametric frame of reference, together with the shape functions (and their derivatives) on these respective nodes. Also all the Gaussian quadrature points within each element are assigned (together with the weight that is applied on these points). The graphical representations of all the element types can be found in Section~\ref{sec:elements}.
%%%%%%%%%% 1D %%%%%%%%%
%\section{Isoparametric Elements in 1D\index{Elements!1D}}
\section{1D-Shape Functions\index{Elements!1D}}
\subsection{Segment 2\index{Elements!1D!Segment 2}}
\begin{Element}{1D}
1 & \inelemone{-1} & $\half\left(1-\xi\right)$ & \inelemone{-\half} \\
\elemline
2 & \inelemone{1} & $\half\left(1+\xi\right)$ & \inelemone{\half} \\
\end{Element}
\begin{QuadPoints}{lc}
Coord. \elemcooroned & 0 \\
\elemline
Weight & 2 \\
\end{QuadPoints}
\subsection{Segment 3\index{Elements!1D!Segment 3}}
\begin{Element}{1D}
1 & \inelemone{-1} & $\half\xi\left(\xi-1\right)$ & \inelemone{\xi-\half} \\
\elemline
2 & \inelemone{1} & $\half\xi\left(\xi+1\right)$ & \inelemone{\xi+\half} \\
\elemline
3 & \inelemone{0} & $1-\xi^{2}$ & \inelemone{-2\xi} \\
\end{Element}
\begin{QuadPoints}{lcc}
Coord. \elemcooroned & $-1/\sqrt{3}$ & $1/\sqrt{3}$ \\
\elemline
Weight & 1 & 1 \\
\end{QuadPoints}
%%%%%%%%%% 2D %%%%%%%%%
%\section{Isoparametric Elements in 2D\index{Elements!2D}}
\section{2D-Shape Functions\index{Elements!2D}}
\subsection{Triangle 3\index{Elements!2D!Triangle 3}}
\begin{Element}{2D}
1 & \inelemtwo{0}{0} & $1-\xi-\eta$ & \inelemtwo{-1}{-1} \\
\elemline
2 & \inelemtwo{1}{0} & $\xi$ & \inelemtwo{1}{0} \\
\elemline
3 & \inelemtwo{0}{1} & $\eta$ & \inelemtwo{0}{1} \\
\end{Element}
\begin{QuadPoints}{lc}
Coord. \elemcoortwod & \inquadtwo{\third}{\third} \\
\elemline
Weight & 1 \\
\end{QuadPoints}
\subsection{Triangle 6\index{Elements!2D!Triangle 6}}
\begin{Element}{2D}
1 & \inelemtwo{0}{0} & $-\left(1-\xi-\eta\right)\left(1-2\left(1-\xi-\eta\right)\right)$ & \inelemtwo{1-4\left(1-\xi-\eta\right)}{1-4\left(1-\xi-\eta\right)} \\
\elemline
2 & \inelemtwo{1}{0} & $-\xi\left(1-2\xi\right)$ & \inelemtwo{4\xi-1}{0} \\
\elemline
3 & \inelemtwo{0}{1} & $-\eta\left(1-2\eta\right)$ & \inelemtwo{0}{4\eta-1} \\
\elemline
4 & \inelemtwo{\half}{0} & $4\xi\left(1-\xi-\eta\right)$ & \inelemtwo{4\left(1-2\xi-\eta\right)}{-4\xi} \\
\elemline
5 & \inelemtwo{\half}{\half} & $4\xi\eta$ & \inelemtwo{4\eta}{4\xi} \\
\elemline
6 & \inelemtwo{0}{\half} & $4\eta\left(1-\xi-\eta\right)$ & \inelemtwo{-4\eta}{4\left(1-\xi-2\eta\right)} \\
\elemline
\end{Element}
\begin{QuadPoints}{lccc}
Coord. \elemcoortwod & \inquadtwo{\sixth}{\sixth} & \inquadtwo{\twothird}{\sixth} & \inquadtwo{\sixth}{\twothird} \\
\elemline
Weight & \sixth & \sixth & \sixth \\
\end{QuadPoints}
\clearpage
\subsection{Quadrangle 4\index{Elements!2D!Quadrangle 4}}
\begin{Element}{2D}
1 & \inelemtwo{-1}{-1} & $\quart\left(1-\xi\right)\left(1-\eta\right)$ & \inelemtwo{-\quart\left(1-\eta\right)}{-\quart\left(1-\xi\right)} \\
\elemline
2 & \inelemtwo{1}{-1} & $\quart\left(1+\xi\right)\left(1-\eta\right)$ & \inelemtwo{\quart\left(1-\eta\right)}{-\quart\left(1+\xi\right)} \\
\elemline
3 & \inelemtwo{1}{1} & $\quart\left(1+\xi\right)\left(1+\eta\right)$ & \inelemtwo{\quart\left(1+\eta\right)}{\quart\left(1+\xi\right)} \\
\elemline
4 & \inelemtwo{-1}{1} & $\quart\left(1-\xi\right)\left(1+\eta\right)$ & \inelemtwo{-\quart\left(1+\eta\right)}{\quart\left(1-\xi\right)} \\
\end{Element}
\begin{QuadPoints}{lcccc}
\elemcoortwod & \inquadtwo{-\invsqrtthree}{-\invsqrtthree} & \inquadtwo{\invsqrtthree}{-\invsqrtthree}
& \inquadtwo{\invsqrtthree}{\invsqrtthree} & \inquadtwo{-\invsqrtthree}{\invsqrtthree} \\
\elemline
Weight & 1 & 1 & 1 & 1 \\
\end{QuadPoints}
\subsection{Quadrangle 8\index{Elements!2D!Quadrangle 8}}
\begin{Element}{2D}
1 & \inelemtwo{-1}{-1} & $\quart\left(1-\xi\right)\left(1-\eta\right)\left(-1-\xi-\eta\right)$
& \inelemtwo{\quart\left(1-\eta\right)\left(2\xi+\eta\right)}
{\quart\left(1-\xi\right)\left(\xi+2\eta\right)} \\
\elemline
2 & \inelemtwo{1}{-1} & $\quart\left(1+\xi\right)\left(1-\eta\right)\left(-1+\xi-\eta\right)$
& \inelemtwo{\quart\left(1-\eta\right)\left(2\xi-\eta\right)}
{-\quart\left(1+\xi\right)\left(\xi-2\eta\right)} \\
\elemline
3 & \inelemtwo{1}{1} & $\quart\left(1+\xi\right)\left(1+\eta\right)\left(-1+\xi+\eta\right)$
& \inelemtwo{\quart\left(1+\eta\right)\left(2\xi+\eta\right)}
{\quart\left(1+\xi\right)\left(\xi+2\eta\right)} \\
\elemline
4 & \inelemtwo{-1}{1} & $\quart\left(1-\xi\right)\left(1+\eta\right)\left(-1-\xi+\eta\right)$
& \inelemtwo{\quart\left(1+\eta\right)\left(2\xi-\eta\right)}
{-\quart\left(1-\xi\right)\left(\xi-2\eta\right)} \\
\elemline
5 & \inelemtwo{0}{-1} & $\half\left(1-\xi^{2}\right)\left(1-\eta\right)$
& \inelemtwo{-\xi\left(1-\eta\right)}
{-\half\left(1-\xi^{2}\right)} \\
\elemline
6 & \inelemtwo{1}{0} & $\half\left(1+\xi\right)\left(1-\eta^{2}\right)$
& \inelemtwo{\half\left(1-\eta^{2}\right)}
{-\eta\left(1+\xi\right)} \\
\elemline
7 & \inelemtwo{0}{1} & $\half\left(1-\xi^{2}\right)\left(1+\eta\right)$
& \inelemtwo{-\xi\left(1+\eta\right)}
{\half\left(1-\xi^{2}\right)} \\
\elemline
8 & \inelemtwo{-1}{0} & $\half\left(1-\xi\right)\left(1-\eta^{2}\right)$
& \inelemtwo{-\half\left(1-\eta^{2}\right)}
{-\eta\left(1-\xi\right)} \\
\end{Element}
\begin{QuadPoints}{lccccc}
Coord. \elemcoortwod & \inquadtwo{0}{0} & \inquadtwo{\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}} & \inquadtwo{-\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}}
& \inquadtwo{-\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} & \inquadtwo{\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} \\
\elemline
Weight & 64/81 & 25/81 & 25/81 & 25/81 & 25/81 \\
\elemline
Coord. \elemcoortwod & \inquadtwo{0}{\sqrt{\tfrac{3}{5}}} & \inquadtwo{-\sqrt{\tfrac{3}{5}}}{0}
& \inquadtwo{0}{-\sqrt{\tfrac{3}{5}}} & \inquadtwo{\sqrt{\tfrac{3}{5}}}{0} & \\
\elemline
Weight & 40/81 & 40/81 & 40/81 & 40/81 & \\
\end{QuadPoints}
\clearpage
%%%%%%%%%% 3D %%%%%%%%%
\section{3D-Shape Functions\index{Elements!3D}}
%\section{Isoparametric Elements in 3D\index{Elements!3D}}
\subsection{Tetrahedron 4\index{Elements!3D!Tetrahedron 4}}
\begin{Element}{3D}
1 & \inelemthree{0}{0}{0} & $1-\xi-\eta-\zeta$ & \inelemthree{-1}{-1}{-1} \\
\elemline
2 & \inelemthree{1}{0}{0} & $\xi$ & \inelemthree{1}{0}{0} \\
\elemline
3 & \inelemthree{0}{1}{0} & $\eta$ & \inelemthree{0}{1}{0} \\
\elemline
4 & \inelemthree{0}{0}{1} & $\zeta$ & \inelemthree{0}{0}{1} \\
\end{Element}
\begin{QuadPoints}{lc}
Coord. \elemcoorthreed & \inquadthree{\quart}{\quart}{\quart} \\
\elemline
Weight & \sixth \\
\end{QuadPoints}
\subsection{Tetrahedron 10\index{Elements!3D!Tetrahedron 10}}
\begin{Element}{3D}
1 & \inelemthree{0}{0}{0} & $\left(1-\xi-\eta-\zeta\right)\left(1-2\xi-2\eta-2\zeta\right)$
& \inelemthreecolumn{4\xi+4\eta+4\zeta-3}{4\xi+4\eta+4\zeta-3}{4\xi+4\eta+4\zeta-3}\\
\elemline
2 & \inelemthree{1}{0}{0} & $\xi\left(2\xi-1\right)$
& \inelemthree{4\xi-1}{0}{0} \\
\elemline
3 & \inelemthree{0}{1}{0} & $\eta\left(2\eta-1\right)$
& \inelemthree{0}{4\eta-1}{0} \\
\elemline
4 & \inelemthree{0}{0}{1} & $\zeta\left(2\zeta-1\right)$
& \inelemthree{0}{0}{4\zeta-1} \\
\elemline
5 & \inelemthree{\half}{0}{0} & $4\xi\left(1-\xi-\eta-\zeta\right)$
& \inelemthree{4-8\xi-4\eta-4\zeta}{-4\xi}{-4\xi} \\
\elemline
6 & \inelemthree{\half}{\half}{0} & $4\xi\eta$
& \inelemthree{4\eta}{4\xi}{0} \\
\elemline
7 & \inelemthree{0}{\half}{0} & $4\eta\left(1-\xi-\eta-\zeta\right)$
& \inelemthree{-4\eta}{4-4\xi-8\eta-4\zeta}{-4\eta} \\
\elemline
8 & \inelemthree{0}{0}{\half} & $4\zeta\left(1-\xi-\eta-\zeta\right)$
& \inelemthree{-4\zeta}{-4\zeta}{4-4\xi-4\eta-8\zeta} \\
\elemline
9 & \inelemthree{\half}{0}{\half} & $4\xi\zeta$
& \inelemthree{4\zeta}{0}{4\xi} \\
\elemline
10 & \inelemthree{0}{\half}{\half} & $4\eta\zeta$
& \inelemthree{0}{4\zeta}{4\eta} \\
\end{Element}
\begin{QuadPoints}{lcc}
Coord. \elemcoorthreed & \inquadthree{\quada}{\quada}{\quada} & \inquadthree{\quadb}{\quada}{\quada} \\
\elemline
Weight & 1/24 & 1/24 \\
\elemline
Coord. \elemcoorthreed & \inquadthree{\quada}{\quadb}{\quada} & \inquadthree{\quada}{\quada}{\quadb} \\
\elemline
Weight & 1/24 & 1/24 \\
\end{QuadPoints}
\clearpage
\subsection{Hexahedron 8\index{Elements!3D!Hexahedron 8}}
\begin{Element}{3D}
1 & \inelemthree{-1}{-1}{-1} & $\eighth\left(1-\xi\right)\left(1-\eta\right)\left(1-\zeta\right)$
& \inelemthree{-\eighth\left(1-\eta\right)\left(1-\zeta\right)}
{-\eighth\left(1-\xi\right)\left(1-\zeta\right)}
{-\eighth\left(1-\xi\right)\left(1-\eta\right)} \\
\elemline
2 & \inelemthree{1}{-1}{-1} & $\eighth\left(1+\xi\right)\left(1-\eta\right)\left(1-\zeta\right)$
& \inelemthree{ \eighth\left(1-\eta\right)\left(1-\zeta\right)}
{-\eighth\left(1+\xi\right)\left(1-\zeta\right)}
{-\eighth\left(1+\xi\right)\left(1-\eta\right)} \\
\elemline
3 & \inelemthree{1}{1}{-1} & $\eighth\left(1+\xi\right)\left(1+\eta\right)\left(1-\zeta\right)$
& \inelemthree{ \eighth\left(1+\eta\right)\left(1-\zeta\right)}
{ \eighth\left(1+\xi\right)\left(1-\zeta\right)}
{-\eighth\left(1+\xi\right)\left(1+\eta\right)} \\
\elemline
4 & \inelemthree{-1}{1}{-1} & $\eighth\left(1-\xi\right)\left(1+\eta\right)\left(1-\zeta\right)$
& \inelemthree{-\eighth\left(1+\eta\right)\left(1-\zeta\right)}
{ \eighth\left(1-\xi\right)\left(1-\zeta\right)}
{-\eighth\left(1-\xi\right)\left(1+\eta\right)} \\
\elemline
5 & \inelemthree{-1}{-1}{1} & $\eighth\left(1-\xi\right)\left(1-\eta\right)\left(1+\zeta\right)$
& \inelemthree{-\eighth\left(1-\eta\right)\left(1+\zeta\right)}
{-\eighth\left(1-\xi\right)\left(1+\zeta\right)}
{ \eighth\left(1-\xi\right)\left(1-\eta\right)} \\
\elemline
6 & \inelemthree{1}{-1}{1} & $\eighth\left(1+\xi\right)\left(1-\eta\right)\left(1+\zeta\right)$
& \inelemthree{ \eighth\left(1-\eta\right)\left(1+\zeta\right)}
{-\eighth\left(1+\xi\right)\left(1+\zeta\right)}
{ \eighth\left(1+\xi\right)\left(1-\eta\right)} \\
\elemline
7 & \inelemthree{1}{1}{1} & $\eighth\left(1+\xi\right)\left(1+\eta\right)\left(1+\zeta\right)$
& \inelemthree{ \eighth\left(1+\eta\right)\left(1+\zeta\right)}
{ \eighth\left(1+\xi\right)\left(1+\zeta\right)}
{ \eighth\left(1+\xi\right)\left(1+\eta\right)} \\
\elemline
8 & \inelemthree{-1}{1}{1} & $\eighth\left(1-\xi\right)\left(1+\eta\right)\left(1+\zeta\right)$
& \inelemthree{-\eighth\left(1+\eta\right)\left(1+\zeta\right)}
{ \eighth\left(1-\xi\right)\left(1+\zeta\right)}
{ \eighth\left(1-\xi\right)\left(1+\eta\right)} \\
\end{Element}
\begin{QuadPoints}{lcccc}
-\elemcoortwod & \inquadthree{-\invsqrtthree}{-\invsqrtthree}{-\invsqrtthree} & \inquadthree{\invsqrtthree}{-\invsqrtthree}{-\invsqrtthree}
+\elemcoorthreed & \inquadthree{-\invsqrtthree}{-\invsqrtthree}{-\invsqrtthree} & \inquadthree{\invsqrtthree}{-\invsqrtthree}{-\invsqrtthree}
& \inquadthree{\invsqrtthree}{\invsqrtthree}{-\invsqrtthree} & \inquadthree{-\invsqrtthree}{\invsqrtthree}{-\invsqrtthree} \\
\elemline
Weight & 1 & 1 & 1 & 1 \\
\elemline
-\elemcoortwod & \inquadthree{-\invsqrtthree}{-\invsqrtthree}{\invsqrtthree} & \inquadthree{\invsqrtthree}{-\invsqrtthree}{\invsqrtthree}
+\elemcoorthreed & \inquadthree{-\invsqrtthree}{-\invsqrtthree}{\invsqrtthree} & \inquadthree{\invsqrtthree}{-\invsqrtthree}{\invsqrtthree}
& \inquadthree{\invsqrtthree}{\invsqrtthree}{\invsqrtthree} & \inquadthree{-\invsqrtthree}{\invsqrtthree}{\invsqrtthree} \\
\elemline
Weight & 1 & 1 & 1 & 1 \\
\end{QuadPoints}
+\subsection{Pentahedron 6\index{Elements!3D!Pentahedron 6}}
+
+\begin{Element}{3D}
+ 1 & \inelemthree{-1}{1}{0} & $\half\left(1-\xi\right)\eta$
+ & \inelemthree{-\half\eta}
+ { \half\left(1-\xi\right)}
+ {0.0} \\
+\elemline
+ 2 & \inelemthree{-1}{0}{1} & $\half\left(1-\xi\right)\zeta$
+ & \inelemthree{-\half\zeta}
+ {0.0}
+ {\half\left(1-\xi\right)} \\
+\elemline
+ 3 & \inelemthree{-1}{0}{0} & $\half\left(1-\xi\right)\left(1-\eta-\zeta\right)$
+ & \inelemthree{-\half\left(1-\eta-\zeta\right)}
+ {-\half\left(1-\xi\right)}
+ {-\half\left(1-\xi\right)} \\
+\elemline
+ 4 & \inelemthree{1}{1}{0} & $\half\left(1+\xi\right)\eta$
+ & \inelemthree{ \half\eta}
+ { \half\left(1+\xi\right)}
+ {0.0} \\
+\elemline
+ 5 & \inelemthree{1}{0}{1} & $\half\left(1+\xi\right)\zeta$
+ & \inelemthree{ \half\zeta}
+ {0.0}
+ { \half\left(1+\xi\right)} \\
+\elemline
+ 6 & \inelemthree{1}{0}{0} & $\half\left(1+\xi\right)\left(1-\eta-\zeta\right)$
+ & \inelemthree{ \half\left(1-\eta-\zeta\right)}
+ {-\half\left(1+\xi\right)}
+ {-\half\left(1+\xi\right)} \\
+\end{Element}
+
+\begin{QuadPoints}{lcccccc}
+\elemcoorthreed & \inquadthree{-\invsqrtthree}{0.5}{0.5}
+ & \inquadthree{-\invsqrtthree}{0.0}{0.5}
+ & \inquadthree{-\invsqrtthree}{0.5}{0.0}
+ & \inquadthree{\invsqrtthree}{0.5}{0.5}
+ & \inquadthree{\invsqrtthree}{0.0}{0.5}
+ & \inquadthree{\invsqrtthree}{0.5}{0.0} \\
+\elemline
+Weight & 1/6 & 1/6 & 1/6 & 1/6 & 1/6 & 1/6 \\
+\end{QuadPoints}
+
+
+\clearpage
+\subsection{Hexahedron 20\index{Elements!3D!Hexahedron 20}}
+
+\begin{Element_part1}{3D}
+ 1 & \inelemthree{-1}{-1}{-1} & $\eighth\left(1-\xi\right)\left(1-\eta\right)\left(1-\zeta\right)\left(-2-\xi-\eta-\zeta\right)$ \\
+\elemline
+ 2 & \inelemthree{1}{-1}{-1} & $\eighth\left(1+\xi\right)\left(1-\eta\right)\left(1-\zeta\right)\left(-2+\xi-\eta-\zeta\right)$ \\
+\elemline
+ 3 & \inelemthree{1}{1}{-1} & $\eighth\left(1+\xi\right)\left(1+\eta\right)\left(1-\zeta\right)\left(-2+\xi+\eta-\zeta\right)$ \\
+\elemline
+ 4 & \inelemthree{-1}{1}{-1} & $\eighth\left(1-\xi\right)\left(1+\eta\right)\left(1-\zeta\right)\left(-2-\xi+\eta-\zeta\right)$ \\
+\elemline
+ 5 & \inelemthree{-1}{-1}{1} & $\eighth\left(1-\xi\right)\left(1-\eta\right)\left(1+\zeta\right)\left(-2-\xi-\eta+\zeta\right)$ \\
+\elemline
+ 6 & \inelemthree{1}{-1}{1} & $\eighth\left(1+\xi\right)\left(1-\eta\right)\left(1+\zeta\right)\left(-2+\xi-\eta+\zeta\right)$ \\
+\elemline
+ 7 & \inelemthree{1}{1}{1} & $\eighth\left(1+\xi\right)\left(1+\eta\right)\left(1+\zeta\right)\left(-2+\xi+\eta+\zeta\right)$ \\
+\elemline
+ 8 & \inelemthree{-1}{1}{1} & $\eighth\left(1-\xi\right)\left(1+\eta\right)\left(1+\zeta\right)\left(-2-\xi+\eta+\zeta\right)$ \\
+\elemline
+ 9 & \inelemthree{0}{-1}{-1} & $\quart\left(1-\xi^{2}\right)\left(1-\eta\right)\left(1-\zeta\right)$ \\
+\elemline
+10 & \inelemthree{1}{0}{-1} & $\quart\left(1+\xi\right)\left(1-\eta^{2}\right)\left(1-\zeta\right)$ \\
+\elemline
+11 & \inelemthree{0}{1}{-1} & $\quart\left(1-\xi^{2}\right)\left(1+\eta\right)\left(1-\zeta\right)$ \\
+\elemline
+12 & \inelemthree{-1}{0}{-1} & $\quart\left(1-\xi\right)\left(1-\eta^{2}\right)\left(1-\zeta\right)$ \\
+\elemline
+13 & \inelemthree{-1}{-1}{0} & $\quart\left(1-\xi\right)\left(1-\eta\right)\left(1-\zeta^{2}\right)$ \\
+\elemline
+14 & \inelemthree{1}{-1}{0} & $\quart\left(1+\xi\right)\left(1-\eta\right)\left(1-\zeta^{2}\right)$ \\
+\elemline
+15 & \inelemthree{1}{1}{0} & $\quart\left(1+\xi\right)\left(1+\eta\right)\left(1-\zeta^{2}\right)$ \\
+\elemline
+16 & \inelemthree{-1}{1}{0} & $\quart\left(1-\xi\right)\left(1+\eta\right)\left(1-\zeta^{2}\right)$ \\
+\elemline
+ 17 & \inelemthree{0}{-1}{1} & $\quart\left(1-\xi^{2}\right)\left(1-\eta\right)\left(1+\zeta\right)$ \\
+\elemline
+18 & \inelemthree{1}{0}{1} & $\quart\left(1+\xi\right)\left(1-\eta^{2}\right)\left(1+\zeta\right)$ \\
+\elemline
+19 & \inelemthree{0}{1}{1} & $\quart\left(1-\xi^{2}\right)\left(1+\eta\right)\left(1+\zeta\right)$ \\
+\elemline
+20 & \inelemthree{-1}{0}{1} & $\quart\left(1-\xi\right)\left(1-\eta^{2}\right)\left(1+\zeta\right)$ \\
+
+\end{Element_part1}
+
+\clearpage
+\begin{Element_part2}{3D}
+ 1 & \inelemthree{ \quart\left(\xi+\half\left(\eta+\zeta+1\right)\right)\left(\eta-1\right)\left(\zeta-1\right)}
+ { \quart\left(\eta+\half\left(\xi+\zeta+1\right)\right)\left(\xi-1\right)\left(\zeta-1\right)}
+ { \quart\left(\zeta+\half\left(\xi+\eta+1\right)\right)\left(\xi-1\right)\left(\eta-1\right)} \\
+\elemline
+ 2 & \inelemthree{ \quart\left(\xi-\half\left(\eta+\zeta+1\right)\right)\left(\eta-1\right)\left(\zeta-1\right)}
+ {-\quart\left(\eta-\half\left(\xi-\zeta-1\right)\right)\left(\xi+1\right)\left(\zeta-1\right)}
+ {-\quart\left(\zeta-\half\left(\xi-\eta-1\right)\right)\left(\xi+1\right)\left(\eta-1\right)} \\
+\elemline
+ 3 & \inelemthree{-\quart\left(\xi+\half\left(\eta-\zeta-1\right)\right)\left(\eta+1\right)\left(\zeta-1\right)}
+ {-\quart\left(\eta+\half\left(\xi-\zeta-1\right)\right)\left(\xi+1\right)\left(\zeta-1\right)}
+ { \quart\left(\zeta-\half\left(\xi+\eta-1\right)\right)\left(\xi+1\right)\left(\eta+1\right)} \\
+\elemline
+ 4 & \inelemthree{-\quart\left(\xi-\half\left(\eta-\zeta-1\right)\right)\left(\eta+1\right)\left(\zeta-1\right)}
+ { \quart\left(\eta-\half\left(\xi+\zeta+1\right)\right)\left(\xi-1\right)\left(\zeta-1\right)}
+ {-\quart\left(\zeta+\half\left(\xi-\eta+1\right)\right)\left(\xi-1\right)\left(\eta+1\right)} \\
+\elemline
+ 5 & \inelemthree{-\quart\left(\xi+\half\left(\eta-\zeta+1\right)\right)\left(\eta-1\right)\left(\zeta+1\right)}
+ {-\quart\left(\eta+\half\left(\xi-\zeta+1\right)\right)\left(\xi-1\right)\left(\zeta+1\right)}
+ { \quart\left(\zeta-\half\left(\xi+\eta+1\right)\right)\left(\xi-1\right)\left(\eta-1\right)} \\
+\elemline
+ 6 & \inelemthree{-\quart\left(\xi-\half\left(\eta-\zeta+1\right)\right)\left(\eta-1\right)\left(\zeta+1\right)}
+ { \quart\left(\eta-\half\left(\xi+\zeta-1\right)\right)\left(\xi+1\right)\left(\zeta+1\right)}
+ {-\quart\left(\zeta+\half\left(\xi-\eta-1\right)\right)\left(\xi+1\right)\left(\eta-1\right)} \\
+\elemline
+ 7 & \inelemthree{ \quart\left(\xi+\half\left(\eta+\zeta-1\right)\right)\left(\eta+1\right)\left(\zeta+1\right)}
+ { \quart\left(\eta+\half\left(\xi+\zeta-1\right)\right)\left(\xi+1\right)\left(\zeta+1\right)}
+ { \quart\left(\zeta+\half\left(\xi+\eta-1\right)\right)\left(\xi+1\right)\left(\eta+1\right)} \\
+\elemline
+ 8 & \inelemthree{ \quart\left(\xi-\half\left(\eta+\zeta-1\right)\right)\left(\eta+1\right)\left(\zeta+1\right)}
+ {-\quart\left(\eta-\half\left(\xi-\zeta+1\right)\right)\left(\xi-1\right)\left(\zeta+1\right)}
+ {-\quart\left(\zeta-\half\left(\xi-\eta+1\right)\right)\left(\xi-1\right)\left(\eta+1\right)} \\
+\elemline
+ 9 & \inelemthree{-\half\xi\left(\eta-1\right)\left(\zeta-1\right)}
+ {-\quart\left(\xi^{2}-1\right)\left(\zeta-1\right)}
+ {-\quart\left(\xi^{2}-1\right)\left(\eta-1\right)} \\
+\elemline
+10 & \inelemthree{ \quart\left(\eta^{2}-1\right)\left(\zeta-1\right)}
+ { \half\eta\left(\xi+1\right)\left(\zeta-1\right)}
+ { \quart\left(\xi+1\right)\left(\eta^{2}-1\right)} \\
+\elemline
+11 & \inelemthree{ \half\xi\left(\eta+1\right)\left(\zeta-1\right)}
+ { \quart\left(\xi^{2}-1\right)\left(\zeta-1\right)}
+ { \quart\left(\xi^{2}-1\right)\left(\eta+1\right)} \\
+\elemline
+12 & \inelemthree{-\quart\left(\eta^{2}-1\right)\left(\zeta-1\right)}
+ {-\half\eta\left(\xi-1\right)\left(\zeta-1\right)}
+ {-\quart\left(\xi-1\right)\left(\eta^{2}-1\right)} \\
+\elemline
+13 & \inelemthree{-\quart\left(\eta-1\right)\left(\zeta^{2}-1\right)}
+ {-\quart\left(\xi-1\right)\left(\zeta^{2}-1\right)}
+ {-\half\zeta\left(\xi-1\right)\left(\eta-1\right)} \\
+\elemline
+14 & \inelemthree{ \quart\left(\eta-1\right)\left(\zeta^{2}-1\right)}
+ { \quart\left(\xi+1\right)\left(\zeta^{2}-1\right)}
+ { \half\zeta\left(\xi+1\right)\left(\eta-1\right)} \\
+\elemline
+15 & \inelemthree{-\quart\left(\eta+1\right)\left(\zeta^{2}-1\right)}
+ {-\quart\left(\xi+1\right)\left(\zeta^{2}-1\right)}
+ {-\half\zeta\left(\xi+1\right)\left(\eta+1\right)} \\
+\elemline
+16 & \inelemthree{ \quart\left(\eta+1\right)\left(\zeta^{2}-1\right)}
+ { \quart\left(\xi-1\right)\left(\zeta^{2}-1\right)}
+ { \half\zeta\left(\xi-1\right)\left(\eta+1\right)} \\
+\elemline
+ 17 & \inelemthree{ \half\xi\left(\eta-1\right)\left(\zeta+1\right)}
+ { \quart\left(\xi^{2}-1\right)\left(\zeta+1\right)}
+ { \quart\left(\xi^{2}-1\right)\left(\eta-1\right)} \\
+\elemline
+18 & \inelemthree{-\quart\left(\eta^{2}-1\right)\left(\zeta+1\right)}
+ {-\half\eta\left(\xi+1\right)\left(\zeta+1\right)}
+ {-\quart\left(\xi+1\right)\left(\eta^{2}-1\right)} \\
+\elemline
+19 & \inelemthree{-\half\xi\left(\eta+1\right)\left(\zeta+1\right)}
+ {-\quart\left(\xi^{2}-1\right)\left(\zeta+1\right)}
+ {-\quart\left(\xi^{2}-1\right)\left(\eta+1\right)} \\
+\elemline
+20 & \inelemthree{ \quart\left(\eta^{2}-1\right)\left(\zeta+1\right)}
+ { \half\eta\left(\xi-1\right)\left(\zeta+1\right)}
+ { \quart\left(\xi-1\right)\left(\eta^{2}-1\right)} \\
+
+\end{Element_part2}
+
+\begin{QuadPoints}{lcccc}
+Coord. \elemcoorthreed & \inquadthree{-\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} {-\sqrt{\tfrac{3}{5}}} & \inquadthree{-\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} {0}
+ & \inquadthree{-\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} {\sqrt{\tfrac{3}{5}}} & \inquadthree{-\sqrt{\tfrac{3}{5}}}{0} {-\sqrt{\tfrac{3}{5}}} \\
+\elemline
+Weight & 125/729 & 200/729 & 125/729 & 200/729 \\
+\elemline
+Coord. \elemcoorthreed & \inquadthree{-\sqrt{\tfrac{3}{5}}}{0}{0} & \inquadthree{-\sqrt{\tfrac{3}{5}}}{0}{\sqrt{\tfrac{3}{5}}}
+ & \inquadthree{-\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} & \inquadthree{-\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}}{0} \\
+\elemline
+Weight & 320/729 & 200/729 & 125/729 & 200/729 \\
+
+\elemline
+Coord. \elemcoorthreed & \inquadthree{-\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}} & \inquadthree{0}{-\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}}
+ & \inquadthree{0}{-\sqrt{\tfrac{3}{5}}}{0} & \inquadthree{0}{-\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}} \\
+\elemline
+Weight & 125/729 & 200/729 & 320/729 & 200/729 \\
+
+\elemline
+Coord. \elemcoorthreed & \inquadthree{0}{0}{-\sqrt{\tfrac{3}{5}}} & \inquadthree{0}{0}{0}
+ & \inquadthree{0}{0}{\sqrt{\tfrac{3}{5}}} & \inquadthree{0}{\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} \\
+\elemline
+Weight & 320/729 & 512/729 & 320/729 & 200/729 \\
+
+\elemline
+Coord. \elemcoorthreed & \inquadthree{0}{\sqrt{\tfrac{3}{5}}}{0} & \inquadthree{0}{\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}}
+ & \inquadthree{\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} & \inquadthree{\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}}{0} \\
+\elemline
+Weight & 320/729 & 200/729 & 125/729 & 200/729 \\
+
+\elemline
+Coord. \elemcoorthreed & \inquadthree{\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}} & \inquadthree{\sqrt{\tfrac{3}{5}}}{0}{-\sqrt{\tfrac{3}{5}}}
+ & \inquadthree{\sqrt{\tfrac{3}{5}}}{0}{0} & \inquadthree{\sqrt{\tfrac{3}{5}}}{0}{\sqrt{\tfrac{3}{5}}} \\
+\elemline
+Weight & 125/729 & 200/729 & 320/729 & 200/729 \\
+
+\elemline
+Coord. \elemcoorthreed & \inquadthree{\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} & \inquadthree{\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}}{0}
+ & \inquadthree{\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}} & \\
+\elemline
+Weight & 125/729 & 200/729 & 125/729 & \\
+
+\end{QuadPoints}
+
+
+\clearpage
+\subsection{Pentahedron 15\index{Elements!3D!Pentahedron 15}}
+
+\begin{Element_part1}{3D}
+ 1 & \inelemthree{-1}{1}{0} & $\half\eta\left(1-\xi\right)\left(2\eta-2-\xi\right)$ \\
+\elemline
+ 2 & \inelemthree{-1}{0}{1} & $\half\zeta\left(1-\xi\right)\left(2\zeta-2-\xi\right)$ \\
+\elemline
+ 3 & \inelemthree{-1}{0}{0} & $\half\left(\xi-1\right)\left(1-\eta-\zeta\right)\left(\xi+2\eta+2\zeta\right)$ \\
+\elemline
+ 4 & \inelemthree{1}{1}{0} & $\half\eta\left(1+\xi\right)\left(2\eta-2+\xi\right)$ \\
+\elemline
+ 5 & \inelemthree{1}{0}{1} & $\half\zeta\left(1+\xi\right)\left(2\zeta-2+\xi\right)$ \\
+\elemline
+ 6 & \inelemthree{1}{0}{0} & $\half\left(-\xi-1\right)\left(1-\eta-\zeta\right)\left(-\xi+2\eta+2\zeta\right)$ \\
+\elemline
+ 7 & \inelemthree{-1}{0.5}{0.5} & $2\eta\zeta\left(1-\xi\right)$ \\
+\elemline
+ 8 & \inelemthree{-1}{0}{0.5} & $2\zeta\left(1-\eta-\zeta\right)\left(1-\xi\right)$ \\
+\elemline
+ 9 & \inelemthree{-1}{0.5}{0} & $2\eta\left(1-\xi\right)\left(1-\eta-\zeta\right)$ \\
+\elemline
+10 & \inelemthree{0}{1}{0} & $\eta\left(1-\xi^{2}\right)$ \\
+\elemline
+11 & \inelemthree{0}{0}{1} & $\zeta\left(1-\xi^{2}\right)$ \\
+\elemline
+12 & \inelemthree{0}{0}{0} & $\left(1-\xi^{2}\right)\left(1-\eta-\zeta\right)$ \\
+\elemline
+13 & \inelemthree{1}{0.5}{0.5} & $2\eta\zeta\left(1+\xi\right)$ \\
+\elemline
+14 & \inelemthree{1}{0}{0.5} & $2\zeta\left(1+\xi\right)\left(1-\eta-\zeta\right)$ \\
+\elemline
+15 & \inelemthree{1}{0.5}{0} & $2\eta\left(1+\xi\right)\left(1-\eta-\zeta\right)$ \\
+
+\end{Element_part1}
+
+\clearpage
+\begin{Element_part2}{3D}
+ 1 & \inelemthree{ \half\eta\left(2\xi-2\eta+1\right)}
+ {-\half\left(\xi-1\right)\left(4\eta-\xi-2\right)}
+ { 0.0} \\
+\elemline
+ 2 & \inelemthree{ \half\zeta\left(2\xi-2\zeta+1\right)}
+ { 0.0}
+ {-\half\left(\xi-1\right)\left(4\zeta-\xi-2\right)} \\
+\elemline
+ 3 & \inelemthree{-\half\left(2\xi+2\eta+2\zeta-1\right)\left(\eta+\zeta-1\right)}
+ {-\half\left(\xi-1\right)\left(4\eta+\xi+2\left(2\zeta-1\right)\right)}
+ {-\half\left(\xi-1\right)\left(4\zeta+\xi+2\left(2\eta-1\right)\right)} \\
+\elemline
+ 4 & \inelemthree{ \half\eta\left(2\xi+2\eta-1\right)}
+ { \half\left(\xi+1\right)\left(4\eta+\xi-2\right)}
+ { 0.0} \\
+\elemline
+ 5 & \inelemthree{ \half\zeta\left(2\xi+2\zeta-1\right)}
+ { 0.0}
+ { \half\left(\xi+1\right)\left(4\zeta+\xi-2\right)} \\
+\elemline
+ 6 & \inelemthree{-\half\left(\eta+\zeta-1\right)\left(2\xi-2\eta-2\zeta+1\right)}
+ { \half\left(\xi+1\right)\left(4\eta-\xi+2\left(2\zeta-1\right)\right)}
+ { \half\left(\xi+1\right)\left(4\zeta-\xi+2\left(2\eta-1\right)\right)} \\
+\elemline
+ 7 & \inelemthree{-2\eta\zeta}
+ {-2\left(\xi-1\right)\zeta}
+ {-2\left(\xi-1\right)\eta} \\
+\elemline
+ 8 & \inelemthree{ 2\zeta\left(\eta+\zeta-1\right)}
+ { 2\zeta-\left(\xi-1\right)}
+ { 2\left(\xi-1\right)\left(2\zeta+\eta-1\right)} \\
+\elemline
+ 9 & \inelemthree{ 2\eta\left(\eta+\zeta-1\right)}
+ { 2\left(2\eta+\zeta-1\right)\left(\xi-1\right)}
+ { 2\eta\left(\xi-1\right)} \\
+\elemline
+10 & \inelemthree{-2\xi\eta}
+ {-\left(\xi^{2}-1\right)}
+ { 0.0} \\
+\elemline
+11 & \inelemthree{-2\xi\zeta}
+ { 0.0}
+ {-\left(\xi^{2}-1\right)} \\
+\elemline
+12 & \inelemthree{ 2\xi\left(\eta+\zeta-1\right)}
+ { \left(\xi^{2}-1\right)}
+ { \left(\xi^{2}-1\right)} \\
+\elemline
+13 & \inelemthree{ 2\eta\zeta}
+ { 2\zeta\left(\xi+1\right)}
+ { 2\eta\left(\xi+1\right)} \\
+\elemline
+14 & \inelemthree{-2\zeta\left(\eta+\zeta-1\right)}
+ {-2\zeta\left(\xi+1\right)}
+ {-2\left(\xi+1\right)\left(2\zeta+\eta-1\right)} \\
+\elemline
+15 & \inelemthree{-2\eta\left(\eta+\zeta-1\right)}
+ {-2\left(2\eta+\zeta-1\right)\left(\xi+1\right)}
+ {-2\eta\left(\xi+1\right)} \\
+
+\end{Element_part2}
+
+\begin{QuadPoints}{lcccc}
+Coord. \elemcoorthreed & \inquadthree{-{\tfrac{1}{\sqrt{3}}}}{\tfrac{1}{3}}{\tfrac{1}{3}} & \inquadthree{-{\tfrac{1}{\sqrt{3}}}}{0.6}{0.2}
+ & \inquadthree{-{\tfrac{1}{\sqrt{3}}}}{0.2}{0.6} & \inquadthree{-{\tfrac{1}{\sqrt{3}}}}{0.2}{0.2} \\
+\elemline
+Weight & -27/96 & 25/96 & 25/96 & 25/96 \\
+\elemline
+Coord. \elemcoorthreed & \inquadthree{{\tfrac{1}{\sqrt{3}}}}{\tfrac{1}{3}}{\tfrac{1}{3}} & \inquadthree{{\tfrac{1}{\sqrt{3}}}}{0.6}{0.2}
+ & \inquadthree{{\tfrac{1}{\sqrt{3}}}}{0.2}{0.6} & \inquadthree{{\tfrac{1}{\sqrt{3}}}}{0.2}{0.2} \\
+\elemline
+Weight & -27/96 & 25/96 & 25/96 & 25/96 \\
+
+\end{QuadPoints}
+
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual-appendix-materials-cohesive.tex b/doc/manual/manual-appendix-materials-cohesive.tex
index 4a585f729..88a7b6c4e 100644
--- a/doc/manual/manual-appendix-materials-cohesive.tex
+++ b/doc/manual/manual-appendix-materials-cohesive.tex
@@ -1,47 +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}
-\matparam{penalty}{Real}{penalty coefficient $\alpha$ (optional)}
-\matparam{volume\_s \& m\_s}{Reals}{OPTIONAL: to adapt statistical distribution following~\cite{Zhou_Molinari_2004}}
+\matparam{beta}{Real}{$\beta$ parameter (default 1)}
+\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{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}
-\matparam{penalty}{Real}{Penalty coefficient $\alpha$}
-\matparam{delta\_0}{Real}{Elastic limit displacement $\delta_0$}
+\matparam{beta}{Real}{$\beta$ parameter (default 1)}
+\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}$}
+\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}
+\matparam{beta}{Real}{$\beta$ parameter (default 1)}
+\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}
+\matparam{beta}{Real}{$\beta$ parameter (default 1)}
\matparam{G\_c}{Real}{Mode I fracture energy}
-\matparam{kappa}{Real}{$\kappa$ parameter}
-\matparam{penalty}{Real}{penalty coefficient $\alpha$}
-\matparam{delta\_f}{Real}{Characteristic opening displacement $\delta_\mathrm{f}$}
+\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-bibliography.bib b/doc/manual/manual-bibliography.bib
index e66e6d33a..4ebe2f8ff 100644
--- a/doc/manual/manual-bibliography.bib
+++ b/doc/manual/manual-bibliography.bib
@@ -1,569 +1,582 @@
% This file was created with JabRef 2.10b2.
% Encoding: UTF-8
@Article{aifantis84a,
Title = {On the microstructural origin of certain inelastic models},
Author = {E. C. Aifantis},
Journal = {Journal of Engineering Materials and Technology},
Year = {1984},
Pages = {326 - 330},
Volume = {106}
}
@Article{Aragon:2013d,
Title = {A hierarchical detection framework for computational contact mechanics},
Author = {Alejandro M. Arag{\'o}n and Jean-Fran{\c c}ois Molinari},
Journal = {Computer Methods in Applied Mechanics and Engineering},
Year = {2014},
Number = {0},
Pages = {574 - 588},
Volume = {268},
Bdsk-url-1 = {http://www.sciencedirect.com/science/article/pii/S0045782513002533},
Bdsk-url-2 = {http://dx.doi.org/10.1016/j.cma.2013.10.001},
Date-added = {2014-05-22 09:14:48 +0000},
Date-modified = {2014-05-22 09:14:48 +0000},
Doi = {10.1016/j.cma.2013.10.001},
ISSN = {0045-7825},
Url = {http://dx.doi.org/10.1016/j.cma.2013.10.001}
}
@Article{bazant86a,
Title = {Mechanics of distributed cracking},
Author = {Zden\v{e}k P. Ba\v{z}ant},
Journal = {Applied Mechanics Reviews},
Year = {1986},
Number = {5},
Pages = {675 - 705},
Volume = {39}
}
@Article{bazant76a,
Title = {Instability, Ductility, and Size Effect in Strain-Softening Concrete},
Author = {Zden\v{e}k P. Ba\v{z}ant},
Journal = {Journal of the Engineering Mechanics Division},
Year = {1976},
Number = {5},
Pages = {331 - 344},
Volume = {102}
}
@Article{bazant85a,
Title = {Wave Propagation in a Strain-Softening Bar: Exact Solution},
Author = {Zden\v{e}k P. Ba\v{z}ant and Ted Belytschko},
Journal = {Journal of Engineering Mechanics},
Year = {1985},
Number = {3},
Pages = {381 - 389},
Volume = {111}
}
@Article{bazant88a,
Title = {{Nonlocal Continuum Damage, Localization Instability and Convergence}},
Author = {Zden\v{e}k P. Ba\v{z}ant and Gilles Pijaudier-Cabot},
Journal = {Journal of Applied Mechanics},
Year = {1988},
Number = {2},
Pages = {287-293},
Volume = {55},
Optdoi = {10.1115/1.3173674},
Publisher = {ASME}
}
@Article{belytschko03a,
Title = {Dynamic crack propagation based on loss of hyperbolicity and a new discontinuous enrichment},
Author = {T Belytschko and H Chen and J Xu and G Zi},
Journal = {International Journal for Numerical Methods in Engineering},
Year = {2003},
Pages = {1875-1905},
Volume = {58}
}
@Article{camacho_computational_1996,
Title = {Computational modelling of impact damage in brittle materials},
Author = {Camacho, {G.T.} and Ortiz, M.},
Journal = {International Journal of Solids and Structures},
Year = {1996},
Month = aug,
Number = {20{\textendash}22},
Pages = {2899--2938},
Volume = {33},
Urldate = {2012-01-17}
}
@Article{caughey1960,
Title = {Classical normal modes in damped linear dynamic systems},
Author = {Caughey, TK},
Journal = {Journal of Applied Mechanics},
Year = {1960},
Number = {2},
Pages = {269--271},
Volume = {27},
Publisher = {American Society of Mechanical Engineers}
}
@Book{courant56a,
Title = {On the partial difference equations of mathematical physics},
Author = {Courant, Richard and Friedrichs, Kurt Otto and Lewy, H.},
Publisher = {Courant Institute of Mathematical Sciences, New York University},
Year = {1956},
Address = {New York}
}
@Book{curnier92a,
Title = {M{\'e}thodes num{\'e}riques en m{\'e}canique des solides},
Author = {Curnier, A.},
Publisher = {EPFL},
Year = {1992},
Bdsk-url-1 = {http://books.google.ch/books?id=-Z2zygAACAAJ},
Url = {http://books.google.ch/books?id=-Z2zygAACAAJ}
}
@Article{youn10a,
Title = {Studies of dynamic crack propagation and crack branching with peridynamics},
Author = {Youn Doh-Ha and Florin Bobaru},
Journal = {International Journal of Fracture},
Year = {2010},
Pages = {229-1244},
Volume = {162}
}
@Book{frey2009,
Title = {M{\'e}thodes des {\'e}l{\'e}ments finis: Analyse des structures et milieux continus},
Author = {Frey, F. and Jirousek, J.},
Publisher = {PPUR},
Year = {2009},
Series = {Trait{\'e} de g{\'e}nie civil de l'Ecole Polytechnique F{\'e}d{\'e}rale de Lausanne},
Bdsk-url-1 = {http://books.google.fr/books?id=bCBtQgAACAAJ},
ISBN = {9782880748524},
Url = {http://books.google.fr/books?id=bCBtQgAACAAJ}
}
@Article{gmsh,
Title = {Gmsh: A 3-D finite element mesh generator with built-in pre- and post-processing facilities},
Author = {Geuzaine, Christophe and Remacle, Jean-Fran{\c c}ois},
Journal = {International Journal for Numerical Methods in Engineering},
Year = {2009},
Number = {11},
Pages = {1309--1331},
Volume = {79},
Bdsk-url-1 = {http://dx.doi.org/10.1002/nme.2579},
Doi = {10.1002/nme.2579},
ISSN = {1097-0207},
Keywords = {computer-aided design, mesh generation, post-processing, finite element method, open-source software},
Publisher = {John Wiley \& Sons, Ltd.},
Url = {http://dx.doi.org/10.1002/nme.2579}
}
@Article{giry11a,
Title = {Stress-based nonlocal damage model},
Author = {C. Giry and F. Dufour and J. Mazars},
Journal = {International Journal of Solids and Structures},
Year = {2011},
Pages = {3431 - 3443},
Volume = {48}
}
@Article{hughes-83a,
Title = {A precis of developments in computational methods for transient analysis},
Author = {Hughes, T.J.R. and Belytschko, T.},
Journal = {Journal. of Applied Mechanics (ASME)},
Year = {1983},
Pages = {1033-1041},
Volume = {50}
}
@Article{hughes83a,
Title = {{A Pr{\'e}cis of Developments in Computational Methods for Transient Analysis}},
Author = {{Hughes}, T.~J.~R. and {Belytschko}, T.},
Journal = {Journal of Applied Mechanics},
Year = {1983},
Month = {December},
Pages = {1033},
Volume = {50},
Optdoi = {10.1115/1.3167186}
}
@Article{jirasek07a,
Title = {Mathematical analysis of strain localization},
Author = {Milan Jir\'asek},
Journal = {Revue Europeenne de Genie Civil},
Year = {2007},
Pages = {977 - 991},
Volume = {11}
}
@Article{jirasek07b,
Title = {Nonlocal damage mechanics},
Author = {Milan Jir\'asek},
Journal = {Revue Europeenne de Genie Civil},
Year = {2007},
Pages = {993 - 1021},
Volume = {11}
}
@Article{jirasek98a,
Title = {Nonlocal models for damage and fracture: comparison of approaches},
Author = {Milan Jir\'asek},
Journal = {International Journal of Solids and Structures},
Year = {1998},
Pages = {4133 - 4145},
Volume = {35}
}
@Article{jirasek03a,
Title = {Comparison of integral-type nonlocal plasticity models for strain-softening materials},
Author = {Milan Jir\'asek and Simon Rolshoven},
Journal = {International Journal of Engineering Science},
Year = {2003},
Pages = {1553-1602},
Volume = {41}
}
@Article{jirasek04a,
Title = {Size effect on fracture energy induced by non-locality},
Author = {Milan Jir\'asek and S Rolshoven and P Grassl},
Journal = {International Journal for numerical and analytical methods in geomechanics},
Year = {2004},
Pages = {653 - 670},
Volume = {28}
}
@Article{ladeveze92a,
Title = {A damage computational method for composite structures},
Author = {P. Ladeveze},
Journal = {Computational \& Structures},
Year = {1992},
Pages = {79-87},
Volume = {44}
}
@Book{Laursen:2002,
Title = {Computational Contact and Impact Mechanics: Fundamentals of Modeling Interfacial Phenomena in Nonlinear Finite Element Analysis},
Author = {Laursen, T.A.},
Publisher = {Springer},
Year = {2002},
Series = {Engineering online library},
Bdsk-url-1 = {http://books.google.ch/books?id=umzsErNuyFgC},
Date-added = {2014-03-21 13:24:56 +0000},
Date-modified = {2014-03-21 13:24:56 +0000},
ISBN = {9783540429067},
Lccn = {2002511027}
}
@Book{lemaitre96a,
Title = {A Course on Damage Mechanics},
Author = {Lemaitre, Jean},
Publisher = {Springer Berlin Heidelberg},
Year = {1996},
ISBN = {978-3-540-60980-3}
}
@PhdThesis{levy10a,
Title = {Exploring the {P}hysics behind {D}ynamic {F}ragmentation through {P}arallel {S}imulations},
Author = {Levy, Sarah},
School = {ENAC},
Year = {2010},
Address = {Lausanne},
Affiliation = {EPFL},
Doctoral = {EDME},
Institute = {IIC},
Original-unit = {LSMS},
Publisher = {EPFL},
Unit = {LSMS}
}
@Article{marigo81a,
Title = {{Formulation d'une loi d'endommagement d'un mat\'eriau \'elastique}},
Author = {Marigo, Jean-Jacques},
Journal = {{C. R. Acad. Sci., Paris, S\'er. II}},
Year = {1981},
Number = {19},
Pages = {1309-1312},
Volume = {292},
ISSN = {0249-6305}
}
@PhdThesis{mazars84a,
Title = {{Application de la m\'ecanique de l'endommagement au comportement non lin\'eaire et \`a la rupture du b\'eton de structure}},
Author = {Mazars, Jacky},
School = {Universit\'e Paris 6},
Year = {1984}
}
@Article{needleman88a,
Title = {Material rate dependence and mesh sensitivity in localization problems},
Author = {A. Needleman},
Journal = {Computer Methods in Applied Mechanics and Engineering},
Year = {1988},
Number = {1},
Pages = {69 - 85},
Volume = {67},
ISSN = {0045-7825},
Optdoi = {10.1016/0045-7825(88)90069-2}
}
@Article{newmark59a,
Title = {{A Method of Computation for Structural Dynamics}},
Author = {Nathan M. Newmark},
Journal = {Journal of the Engineering Mechanics Division},
Year = {1959},
Month = {July},
Number = {3},
Pages = {67-94},
Volume = {85},
Editor = {ASCE}
}
@Article{nguyen2001,
Title = {A cohesive model of fatigue crack growth},
Author = {Nguyen, O. and Repetto, E. A. and Ortiz, M. and Radovitzky, R. A.},
Journal = {International Journal of Fracture},
Year = {2001},
Month = aug,
Number = {4},
Pages = {351--369},
Volume = {110},
Doi = {10.1023/A:1010839522926},
ISSN = {0376-9429, 1573-2673},
Language = {en},
Urldate = {2015-02-17}
}
@TechReport{Omohundro:1989,
Title = {Five Balltree Construction Algorithms},
Author = {Stephen M. Omohundro},
Institution = {International Computer Science Institute, University of California at Berkeley},
Year = {1989},
Number = {TR-89-063},
Type = {Technical Report},
Bdsk-url-1 = {http://ftp.icsi.berkeley.edu/ftp/pub/techreports/1989/tr-89-063.pdf},
Date-added = {2014-05-22 09:47:58 +0000},
Date-modified = {2014-05-22 09:47:58 +0000},
Url = {http://ftp.icsi.berkeley.edu/ftp/pub/techreports/1989/tr-89-063.pdf}
}
@Article{ortiz1999,
Title = {Finite-deformation irreversible cohesive elements for three-dimensional crack-propagation analysis},
Author = {Ortiz, M. and Pandolfi, A.},
Journal = {International Journal for Numerical Methods in Engineering (IJNME)},
Year = {1999},
Pages = {1267-1282},
Volume = {44}
}
@Article{ortiz99a,
Title = {Finite-deformation irreversible cohesive elements for three-dimensional crack-propagation analysis},
Author = {M Ortiz and A Pandolfi},
Journal = {International Journal for Numerical Methods in Engineering},
Year = {1999},
Pages = {1267-1282},
Volume = {44}
}
@Article{pandolfi12a,
Title = {An eigenerosion approach to brittle fracture},
Author = {A Pandolfi and M Ortiz},
Journal = {International Journal for Numerical Methods in Engineering},
Year = {2012},
Pages = {694-714},
Volume = {92}
}
@Article{patzak01a,
Title = {Parallel explicit finite element dynamics with nonlocal constitutive models},
Author = {B. Patz{\'a}k and D. Rypl and Z. Bittnar},
Journal = {{Computers \& Structures}},
Year = {2001},
Number = {26--28},
Pages = {2287 - 2297},
Volume = {79},
ISSN = {0045-7949}
}
@PhdThesis{Pietrzak:1997,
Title = {Continuum mechanics modelling and augmented Lagrangian formulation of large deformation frictional contact problems},
Author = {Pietrzak, Grzegorz},
School = {{\'E}cole {P}olytechnique {F}{\'e}d{\'e}rale de {L}ausanne},
Year = {1997},
Date-added = {2014-09-16 12:23:01 +0000},
Date-modified = {2014-09-16 12:41:09 +0000},
Doi = {10.5075/epfl-thesis-1656}
}
@Article{pijaudier87a,
Title = {Nonlocal damage theory},
Author = {Gilles Pijaudier-Cabot and Zden\v{e}k P. Ba\v{z}ant},
Journal = {Journal of Engineering Mechanics},
Year = {1987},
Number = {10},
Pages = {1512 - 1533},
Volume = {113}
}
@Article{rice76a,
Title = {The Localisation of Plastic Deformation},
Author = {James R. Rice},
Journal = {Theoretical and Applied Mechanics (14th International Congress on Theoretical and Applied Mechanics, Delft, 1976, ed. W.T. Koiter)},
Year = {1976},
Pages = {207 - 220},
Volume = {1}
}
@Article{sharon96a,
Title = {Microbranching instability and the dynamic fracture of brittle materials},
Author = {Eran Sharon and Jay Fineberg},
Journal = {Physical Review B},
Year = {1996},
Number = {10},
Pages = {7128 - 7139},
Volume = {54}
}
@Article{silling00a,
Title = {Reformulation of elasticity theory for discontinuities and long-range forces},
Author = {S A Silling},
Journal = {Journal of the Mechanics and Physics of Solids},
Year = {2000},
Pages = {175-209},
Volume = {48}
}
@Book{simo92,
Title = {Computational Inelasticity},
Author = {Simo, J.C. and Hughes, T.J.R.},
Publisher = {Springer},
Year = {1992}
}
@Article{snozzi_cohesive_2013,
Title = {A cohesive element model for mixed mode loading with frictional contact capability},
Author = {Snozzi, Leonardo and Molinari, Jean-Francois},
Journal = {International Journal for Numerical Methods in Engineering},
Year = {2013},
Month = feb,
Number = {5},
Pages = {510--526},
Volume = {93}
}
@Book{Belytschko:2000,
Title = {Nonlinear Finite Elements for Continua and Structures},
Author = {Ted Belytschko, Wing Kam Liu, Brian Moran},
Publisher = {Wiley},
Year = {2000}
}
@Article{devree95,
Title = {Comparison of nonlocal approaches in continuum damage mechanics},
Author = {J.H.P. de Vree and W.A.M. Brekelmans and M.A.J. van Gils},
Journal = {Computers \&; Structures},
Year = {1995},
Number = {4},
Pages = {581 - 588},
Volume = {55},
ISSN = {0045-7949},
Optdoi = {10.1016/0045-7949(94)00501-S}
}
+@Unpublished{vocialta15,
+ Title = {3D dynamic fragmentation with parallel dynamic insertion of cohesive elements},
+ Author = {M. Vocialta and N. Richart and J.-F. Molinari},
+ Note = {Submitted to IJNME},
+ Year = {2015}
+}
+
@Unpublished{wolff14a,
Title = {A non-local continuum damage approach to model dynamic crack branching},
- Author = {C. Wolff and N. Richart and JF Molinari},
+ Author = {C. Wolff and N. Richart and J.-F. Molinari},
Note = {Submitted to IJNME},
Year = {2014}
}
@Article{Zhou_Molinari_2004,
Title = {Dynamic crack propagation with cohesive elements: a methodology to address mesh dependency},
Author = {F. Zhou and J. F. Molinari},
Journal = {International Journal for Numerical Methods in Engineering},
Year = {2004},
Timestamp = {2015.07.30}
}
@Misc{abaqus,
Title = {Simulia ABAQUS FEA},
Bdsk-url-1 = {http://www.3ds.com/products-services/simulia/portfolio/abaqus/},
Key = {Unified FEA},
Url = {\url{http://www.3ds.com/products-services/simulia/portfolio/abaqus/}}
}
@Misc{cmake,
Title = {CMake - Cross Platform Make},
Bdsk-url-1 = {http://www.cmake.org/},
Url = {\url{http://www.cmake.org/}}
}
@Misc{diana,
Title = {TNO DIANA},
Bdsk-url-1 = {http://tnodiana.com/content/DIANA},
Key = {FEM},
Url = {\url{http://tnodiana.com/content/DIANA}}
}
@Misc{mayavi,
Title = {The MayaVi Data Visualizer},
Bdsk-url-1 = {http://mayavi.sourceforge.net/},
Url = {\url{http://mayavi.sourceforge.net/}}
}
@Misc{mumps,
Title = {MUMPS : a parallel sparse direct solver},
Bdsk-url-1 = {http://graal.ens-lyon.fr/MUMPS/},
Key = {sparse matrix, direct solver, parallelisme},
Url = {\url{http://graal.ens-lyon.fr/MUMPS/}}
}
+@Misc{numpy,
+ Title = {NumPy - Fundamental package for scientific computing with Python},
+
+ Bdsk-url-1 = {http://www.numpy.org/},
+ Url = {\url{http://www.numpy.org/}}
+}
@Misc{paraview,
Title = {ParaView - Open Source Scientific Visualization},
Bdsk-url-1 = {http://www.paraview.org/},
Url = {\url{http://www.paraview.org/}}
}
@Misc{scotch,
Title = {SCOTCH: Static Mapping, Graph, Mesh and Hypergraph Partitioning},
Bdsk-url-1 = {http://www.labri.fr/perso/pelegrin/scotch/},
Url = {\url{http://www.labri.fr/perso/pelegrin/scotch/}}
}
@Misc{visit,
Title = {VisIt Visualization Tool},
Bdsk-url-1 = {http://wci.llnl.gov/codes/visit/},
Url = {\url{http://wci.llnl.gov/codes/visit/}}
}
diff --git a/doc/manual/manual-cohesive_elements.tex b/doc/manual/manual-cohesive_elements.tex
index 8443fbc07..ccfed70fe 100644
--- a/doc/manual/manual-cohesive_elements.tex
+++ b/doc/manual/manual-cohesive_elements.tex
@@ -1,116 +1,116 @@
-\section{Cohesive Elements}
+\subsection{Cohesive Elements}
The cohesive elements that have been implemented in \akantu are based
on the work of Ortiz and Pandolfi~\cite{ortiz1999}. Their main
properties are reported in Table~\ref{tab:coh:cohesive_elements}.
\begin{table}[!htb]
\begin{center}
\begin{tabular}{l|llcc}
\toprule
Element type & Facet type & Order & \# nodes & \# quad. points \\
\midrule
\texttt{\_cohesive\_1d\_2} & \texttt{\_point\_1} & linear & 2 & 1 \\
\hline
\texttt{\_cohesive\_2d\_4} & \texttt{\_segment\_2} & linear & 4 & 1 \\
\texttt{\_cohesive\_2d\_6} & \texttt{\_segment\_3} & quadratic & 6 & 2 \\
\hline
\texttt{\_cohesive\_3d\_6} & \texttt{\_triangle\_3} & linear & 6 & 1 \\
\texttt{\_cohesive\_3d\_12} & \texttt{\_triangle\_6} & quadratic & 12 & 3 \\
\bottomrule
\end{tabular}
\end{center}
\caption{Some basic properties of the cohesive elements in \akantu.}
\label{tab:coh:cohesive_elements}
\end{table}
\begin{figure}
\centering
\includegraphics[width=.6\textwidth]{figures/cohesive2d}
\caption{Cohesive element in 2D for quadratic triangular elements
T6.}
\label{fig:smm:coh:cohesive2d}
\end{figure}
Cohesive element insertion can be either realized at the beginning of
the simulation or it can be carried out dynamically during the
simulation. The first approach is called \emph{intrinsic}, the second
one \emph{extrinsic}. When an element is present from the beginning, a
bilinear or exponential cohesive law should be used instead of a
linear one. A bilinear law works exactly like a linear one except for
an additional parameter $\delta_0$ separating an initial linear
elastic part from the linear irreversible one. For additional details
concerning cohesive laws see Section~\ref{sec:cohesive-laws}.
\begin{figure}
\centering
\includegraphics[width=.75\textwidth]{figures/insertion}
\caption{Insertion of a cohesive element.}
\label{fig:smm:coh:insertion}
\end{figure}
Extrinsic cohesive elements are dynamically inserted between two
standard elements when
\begin{equation}
\sigma_\mathrm{eff} > \sigma_\mathrm{c} \quad\text{with}\quad
\sigma_\mathrm{eff} = \sqrt{\sigma_\mathrm{n}^2 +
\frac{\tau^2}{\beta^2}}
\end{equation}
in which $\sigma_\mathrm{n}$ is the tensile normal traction and $\tau$
the resulting tangential one (Figure~\ref{fig:smm:coh:insertion}).
For the static analysis of the structures containing cohesive
elements, the stiffness of the cohesive elements should also be added
to the total stiffness of the structure. Considering a 2D quadratic
cohesive element as that in Figure~\ref{fig:smm:coh:cohesive2d}, the
opening displacement along the mid-surface can be written as:
\begin{equation}
\label{eq:opening}
\vec{\Delta}(s) = \llbracket \mat{u}\rrbracket \,\mat{N}(s) =
\begin{bmatrix}
u_3-u_0 & u_4-u_1 & u_5-u_2\\
v_3-v_0 & v_4-v_1 & v_5-v_2
\end{bmatrix}
\begin{bmatrix}
N_0(s) \\ N_1(s) \\ N_2(s)
\end{bmatrix} =
\mat{N}^\mathrm{k} \mat{A U} = \mat{PU}
\end{equation}
The \mat{U}, \mat{A} and $\mat{N}^\mathrm{k}$ are as following:
\begin{align}
\mat{U} &= \left [
\begin{array}{c c c c c c c c c c c c}
u_0 & v_0 & u_1 & v_1 & u_2 & v_2 & u_3 & v_3 & u_4 & v_4 & u_5 & v_5
\end{array}\right ]\\[1ex]
\mat{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 ]\\[1ex]
\mat{N}^\mathrm{k} &= \begin{bmatrix}
N_0(s) & 0 & N_1(s) &0 & N_2(s) & 0\\
0 & N_0(s)& 0 &N_1(s)& 0 & N_2(s)
\end{bmatrix}
\end{align}
The consistent stiffness matrix for the element is obtained as
\begin{equation}
\label{eq:cohesive_stiffness}
\mat{K} = \int_{S_0} \mat{P}^\mathrm{T}\,
\frac{\partial{\vec{T}}} {\partial{\delta}} \mat{P} \,\mathrm{d}
S_0
\end{equation}
where $\vec{T}$ is the cohesive traction and $\delta$ the opening
displacement (for more details check
Section~\ref{tab:coh:cohesive_elements}).
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual-cohesive_elements_insertion.tex b/doc/manual/manual-cohesive_elements_insertion.tex
index 9bc6e6f28..ea551500f 100644
--- a/doc/manual/manual-cohesive_elements_insertion.tex
+++ b/doc/manual/manual-cohesive_elements_insertion.tex
@@ -1,76 +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
+\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}).
+
\subsection{Insertion of Cohesive Elements}
-Cohesive elements are currently compatible only with static simulation and dynamic simualtion 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 but during the simulation. At any time during the simulation, it is possible to access the following energies with the relative function:
+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:
\begin{cpp}
Real Ed = model.getEnergy("dissipated");
Real Er = model.getEnergy("reversible");
Real Ec = model.getEnergy("contact");
\end{cpp}
-\subsubsection{Extrinsic approach}
-The dynamic insertion of extrinsic cohesive elements should be initialized
-the following way:
+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));
- model.updateAutomaticInsertion();
\end{cpp}
-During the simulation, stress has to be checked along each facet in order to
-eventually insert cohesive elements.
-This check is performed by calling the method \code{checkCohesiveStress}, as
-example before each step resolution:
+
+
+\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 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 stress 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}
- SolidMechanicsModelCohesive model(mesh);
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
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}
- SolidMechanicsModelCohesive model(mesh);
- model.initFull(SolidMechanicsModelCohesiveOptions(_static));
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. At this purpose, cohesive elements can be easily inserted along a
-specific group of surface elements identified in a GMSH geometry file. This can
-be achieved, in the input file, by specifying the name of these physical groups
-in the \textit{mesh parameters} section as well as their corresponding cohesive
-materials. 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}% [
+ material %\emph{cohesive\_constitutive\_law}% [
name = weak_interface
sigma_c = $value$
...
]
- material %\emph{cohesive constitutive\_law}% [
+ 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 eb0642369..b8ff2201e 100644
--- a/doc/manual/manual-cohesive_laws.tex
+++ b/doc/manual/manual-cohesive_laws.tex
@@ -1,199 +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. 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.
+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-non_local.tex b/doc/manual/manual-constitutive-laws-non_local.tex
index 8b1378917..dff71d672 100644
--- a/doc/manual/manual-constitutive-laws-non_local.tex
+++ b/doc/manual/manual-constitutive-laws-non_local.tex
@@ -1 +1,50 @@
+\section{Non-Local Constitutive Laws \label{sect:smm:CLNL}}\index{Material}
+
+Continuum damage modeling of quasi-brittle materials undergo significant softening after the onset of damage. This fast growth of damage causes a loss of ellipticity of partial differential equations of equilibrium. Therefore, the numerical simulation results won't be objective anymore, because the dissipated energy will depend on mesh size used in the simulation. One way to avoid this effect is the use of non-local damage formulations. In this approach a local quantity such as the strain is replaced by its non-local average, where the size of the domain, over which the quantitiy is averaged, depends on the underlying material microstructure.
+\akantu provides non-local versions of many constitutive laws for damage. Examples are for instance the material Mazar and the material Marigo, that can be used in a non-local context. In order to use the corresponding non-local formulation the user has to define the non-local material he wishes to use in the text input file:
+\begin{cpp}
+ material %\emph{constitutive\_law\_non\_local}% [
+ name = %\emph{material\_name}
+ rho = $value$
+ ...
+ ]
+\end{cpp}
+where \emph{constitutive\_law\_non\_local} is the name of the non-local constitutive law, \textit{e.g.} \emph{marigo\_non\_local}.
+In addition to the material the non-local neighborhood, that should be used for the averaging process needs to be defined in the material file as well:
+\begin{cpp}
+ non_local %\emph{neighborhood\_name}% %\emph{weight\_function\_type}% [
+ radius = $value$
+ ...
+ weight_function weight_parameter [
+ damage_limit = $value$
+ ...
+ ]
+ ]
+\end{cpp}
+for the non-local averaging, \textit{e.g.} \emph{base\_wf}, followed by the properties of the non-local neighborhood, such as the radius, and the weight function parameters. It is important to notice that the non-local neighborhood must have the same name as the material to which the neighborhood belongs!
+The following two sections list the non-local constitutive laws and different type of weight functions available in \akantu.
+\subsection{Non-local constitutive laws}
+Let us consider a body having a volume $V$ and a boundary $\Gamma$. The stress-strain relation for a non-local damage model can be described as follows:
+\begin{equation}
+ \label{eq:non-local-const}
+ \vec{\sigma} = (1-\bar{d}) \vec{D}:\epsilon
+\end{equation}
+with $\vec{D}$ the elastic moduli tensor, $\sigma$ the stress tensor, $\epsilon$ the strain tensor and $\bar{d}$ the non-local damage variable. Note that this stres-strain relationship is similar to the relationship defined in Damage model except $\bar{d}$. The non-local damage model can be extended to the damage constitutive laws: Marigo (Section~\ref{ssect:smm:cl:damage-marigo}) and Mazars (Section~\ref{ssect:smm:cl:damage-mazars}).
+
+The non-local damage variable $\bar{d}$ is defined as follows:
+\begin{equation}
+ \label{eq:non-local-const}
+ \bar{d}(\vec{x}) = \int_{V}W(\vec{x}, \vec{y}) d(\vec{y}) dV(\vec{y})
+\end{equation}
+with $W(\vec{x},\vec{y})$ the weight function which averages local damage variables to describe the non-local interactions. A list of available weight functions and its functionalities in \akantu are explained in the next section.
+
+\subsection{Non-local weight functions}
+The available weight functions in \akantu are follows:
+\begin{itemize}
+\item \emph{base\_weight\_function}: This weight function averages local damage variables by using a bell-shape function on spatial dimensions.
+\item \emph{damaged\_weight\_function}: A linear-shape weight function is applied to average local damage variables. Its slope is determined by damage variables. For example, the damage variables for an element which is highly damaged are averaged over large spatial dimension (linear function including a small slope).
+\item \emph{remove\_damaged\_weight\_function}: This weight function averages damage values by using a bell-shape function as \emph{base\_weight\_function}, but excludes elements which are fully damaged.
+\item \emph{remove\_damaged\_with\_damage\_rate\_weight\_function}: A bell-shape function is applied to average local damage variables for elements having small damage rates.
+\item \emph{stress\_based\_weight\_function}: Non local integral takes stress states, and use the states to construct weight function: an ellipsoid shape. Detailed explanations of this weight function are given in Giry et al.: Stress-based nonlocal damage model IJSS, 48, 2011.
+\end{itemize}
diff --git a/doc/manual/manual-constitutive-laws.tex b/doc/manual/manual-constitutive-laws.tex
index 3f46d34be..20ca5dcf8 100644
--- a/doc/manual/manual-constitutive-laws.tex
+++ b/doc/manual/manual-constitutive-laws.tex
@@ -1,544 +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) in a text file (\eg material.dat) as
-follows:
-\begin{cpp}
- material %\emph{constitutive\_law}% %\emph{<optional flavor>}% [
- name = $value$
- rho = $value$
- ...
- ]
-\end{cpp}
-\index{Constitutive\_laws} where \emph{constitutive\_law} is the adopted
-constitutive law, followed by the material properties listed one by line in the
-bracket (\eg \code{name} and density \code{rho}). Some constitutive laws can
-also have an \emph{optional flavor}. For example a non-local constitutive law
-can be flavored by a weight function. The file needs to be loaded in \akantu
-using the \code{initialize} method of \akantu (as shown in
-Section~\ref{sec:writing_main})
-\begin{cpp}
- initialize("material.dat", argc, argv);
-\end{cpp}
-% or, alternatively, the \code{initFull} method.
-% \begin{cpp}
-% model.initFull("material.dat");
-% \end{cpp}
-
+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 material input file,
+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:
+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 can be substituted with any number. Currently
-\akantu is can reproduce always the same distribution when the seed is
-specified \emph{only} in serial.
+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 poison ratios follow the rule $\nu_{ij} = \nu_{ji} E_i / E_j$.
+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-elements.tex b/doc/manual/manual-elements.tex
index cc5830d6e..403724feb 100644
--- a/doc/manual/manual-elements.tex
+++ b/doc/manual/manual-elements.tex
@@ -1,172 +1,172 @@
-\chapter{Elements\index{Elements}}
-\label{chap:elements}
+\section{Elements\index{Elements}}
+\label{sec:elements}
The base for every Finite-Elements computation is its mesh and the elements that
are used within that mesh. The element types that can be used depend on the
mesh, but also on the dimensionality of the problem (1D, 2D or 3D). In \akantu,
several isoparametric Lagrangian element types are supported (and one
serendipity element). Each of these types is discussed in some detail below,
starting with the 1D-elements all the way to the 3D-elements. More detailed
information (shape function, location of Gaussian quadrature points, and so on)
can be found in Appendix~\ref{app:elements}.
%%%%%%%%%% 1D %%%%%%%%%
-\section{Isoparametric Elements\index{Elements!Isoparametric}}
+\subsection{Isoparametric Elements\index{Elements!Isoparametric}}
-\subsection*{1D\index{Elements!1D}}
+\subsubsection*{1D\index{Elements!1D}}
In \akantu, there are two types of isoparametric elements defined in 1D. These
element types are called \code{\_segment\_2} and \code{\_segment\_3}, and are
depicted schematically in Figure~\ref{fig:elements:1D}. Some of the basic
properties of these elements are listed in Table~\ref{tab:elements:1D}.
\begin{figure}[!htb]
\begin{center}
\begin{tabular}{m{0.31\textwidth}m{0.1\textwidth}m{0.31\textwidth}}
\subfloat[\code{\_segment\_2}]{
\includegraphics[width=0.29\textwidth,clip,trim=1cm 0 1.5cm 0]{figures/elements/segment_2}
\label{fig:elements:segment2}
} & &
\subfloat[\code{\_segment\_3}]{
\includegraphics[width=0.29\textwidth,clip,trim=1cm 0 1.5cm 0]{figures/elements/segment_3}
\label{fig:elements:segment3}
}
\end{tabular}
\end{center}
\caption{Schematic overview of the two 1D element types in \akantu. In each
element, the node numbering as used in \akantu is indicated and also the
quadrature points are highlighted (gray circles).}
\label{fig:elements:1D}
\end{figure}
\begin{table}[!htb]
\begin{center}
\begin{tabular}{l|ccc}
\toprule
Element type & Order & \# nodes & \# quad. points \\
\midrule
\texttt{\_segment\_2} & linear & 2 & 1 \\
\texttt{\_segment\_3} & quadratic & 3 & 2 \\
\bottomrule
\end{tabular}
\end{center}
\caption{Some basic properties of the two 1D isoparametric elements in \akantu.}
\label{tab:elements:1D}
\end{table}
%%%%%%%%%% 2D %%%%%%%%%
-\subsection*{2D\index{Elements!2D}}
+\subsubsection*{2D\index{Elements!2D}}
In \akantu, there are four types of isoparametric elements defined in 2D. These
element types are called \code{\_triangle\_3}, \code{\_triangle\_6},
\code{\_quadrangle\_4} and \code{\_quadrangle\_8}, and all of them are depicted
in Figure~\ref{fig:elements:2D}. As with the 1D elements, some of the most basic
properties of these elements are listed in Table~\ref{tab:elements:2D}. It is
important to note that the first element is linear, the next two quadratic and
the last one cubic. Furthermore, the last element type (\code{\_quadrangle\_8})
is not a Lagrangian but a serendipity element.
\begin{figure}[!htb]
\begin{center}
\begin{tabular}{m{0.31\textwidth}m{0.1\textwidth}m{0.31\textwidth}}
\subfloat[\code{\_triangle\_3}]{
\includegraphics[width=0.29\textwidth]{figures/elements/triangle_3}
\label{fig:elements:triangle3}
} & &
\subfloat[\code{\_triangle\_6}]{
\includegraphics[width=0.29\textwidth]{figures/elements/triangle_6}
\label{fig:elements:triangle6}
} \\
\subfloat[\code{\_quadrangle\_4}]{
\includegraphics[width=0.29\textwidth]{figures/elements/quadrangle_4}
\label{fig:elements:quadrangle4}
} & &
\subfloat[\code{\_quadrangle\_8}]{
\includegraphics[width=0.29\textwidth]{figures/elements/quadrangle_8}
\label{fig:elements:quadrangle8}
}
\end{tabular}
\end{center}
\caption{Schematic overview of the four 2D element types in \akantu. In each
element, the node numbering as used in \akantu is indicated and also the
quadrature points are highlighted (gray circles).}
\label{fig:elements:2D}
\end{figure}
\begin{table}[!htb]
\begin{center}
\begin{tabular}{l|ccc}
\toprule
Element type & Order & \# nodes & \# quad. points \\
\midrule
\texttt{\_triangle\_3} & linear & 3 & 1 \\
\texttt{\_triangle\_6} & quadratic & 6 & 3 \\
\hline
\texttt{\_quadrangle\_4} & quadratic & 4 & 4 \\
\texttt{\_quadrangle\_8} & cubic & 8 & 9 \\
\bottomrule
\end{tabular}
\end{center}
\caption{Some basic properties of the four 2D isoparametric elements in \akantu.}
\label{tab:elements:2D}
\end{table}
%%%%%%%%%% 3D %%%%%%%%%
-\subsection*{3D\index{Elements!3D}}
+\subsubsection*{3D\index{Elements!3D}}
In \akantu, there are three types of isoparametric elements defined in 3D. These
element types are called \code{\_tetrahedron\_4}, \code{\_tetrahedron\_10} and
\code{\_hexahedron\_8}, and all of them are depicted schematically in
Figure~\ref{fig:elements:3D}. As with the 1D and 2D elements some of the most
basic properties of these elements are listed in Table~\ref{tab:elements:3D}.
\begin{figure}[!htb]
\begin{center}
\begin{tabular}{m{0.3\linewidth}m{0.3\linewidth}m{0.3\linewidth}}
\subfloat[\code{\_tetrahedron\_4}]{
\includegraphics[width=0.9\linewidth]{figures/elements/tetrahedron_4}
\label{fig:elements:tetrahedron4}
} &
\subfloat[\code{\_tetrahedron\_10}]{
\includegraphics[width=0.9\linewidth]{figures/elements/tetrahedron_10}
\label{fig:elements:tetrahedron10}
} &
\subfloat[\code{\_hexahedron\_8}]{
\includegraphics[width=0.9\linewidth]{figures/elements/hexahedron_8}
\label{fig:elements:hexahedron8}
}
\end{tabular}
\caption{Schematic overview of the three 3D element types in \akantu. In each
element, the node numbering as used in \akantu is indicated and also the
quadrature points are highlighted (gray spheres).}
\label{fig:elements:3D}
\end{center}
\end{figure}
\begin{table}[!htb]
\begin{center}
\begin{tabular}{l|ccc}
\toprule
Element type & Order & \# nodes & \# quad. points \\
\midrule
\texttt{\_tetrahedron\_4} & linear & 4 & 1 \\
\texttt{\_tetrahedron\_10} & quadratic & 10 & 4 \\
\hline
\texttt{\_hexahedron\_8} & cubic & 8 & 8 \\
\bottomrule
\end{tabular}
\end{center}
\caption{Some basic properties of the three 3D isoparametric elements in \akantu.}
\label{tab:elements:3D}
\end{table}
%%%%%%%%%% COHESIVE ELEMENTS %%%%%%%%%
\IfFileExists{manual-cohesive_elements.tex}{\input{manual-cohesive_elements}}{}
%%%%%%%%%% STRUCTURAL ELEMENTS %%%%%%%%%
\IfFileExists{manual-structuralmechanicsmodel-elements.tex}{\input{manual-structuralmechanicsmodel-elements}}{}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual-feengine.tex b/doc/manual/manual-feengine.tex
new file mode 100644
index 000000000..9c221b578
--- /dev/null
+++ b/doc/manual/manual-feengine.tex
@@ -0,0 +1,75 @@
+\chapter{FEEngine\index{FEEngine}}
+\label{chap:feengine}
+The \code{FEEngine} interface is dedicated to handle the
+finite-element approximations and the numerical integration of the
+weak form. As we will see in Chapter \ref{sect:smm}, \code{Model}
+creates its own \code{FEEngine} object so the explicit creation of the
+object is not required.
+
+\section{Mathematical Operations\label{sect:fe:mathop}}
+Using the \code{FEEngine} object, one can compute a interpolation, an
+integration or a gradient. A simple example is given below.
+
+\begin{cpp}
+// having a FEEngine object
+FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh,
+ dim,
+ "my_fem");
+// instead of this, a FEEngine object can be get using the model:
+// model.getFEEngine()
+
+//compute the gradient
+Array<Real> u; //append the values you want
+Array<Real> nablauq; //gradient array to be computed
+// compute the gradient
+fem->gradientOnIntegrationPoints(const Array<Real> &u,
+ Array<Real> &nablauq,
+ const UInt nb_degree_of_freedom,
+ const ElementType & type);
+
+// interpolate
+Array<Real> uq; //interpolated array to be computed
+// compute the interpolation
+fem->interpolateOnIntegrationPoints(const Array<Real> &u,
+ Array<Real> &uq,
+ UInt nb_degree_of_freedom,
+ const ElementType & type);
+
+// interpolated function can be integrated over the elements
+Array<Real> int_val_on_elem;
+// integrate
+fem->integrate(const Array<Real> &uq,
+ Array<Real> &int_uq,
+ UInt nb_degree_of_freedom,
+ const ElementType & type);
+\end{cpp}
+
+Another example below shows how to integrate stress and strain fields
+over elements assigned to a particular material.
+
+\begin{cpp}
+UInt sp_dim = 3; //spatial dimension
+UInt m = 1; //material index of interest
+const ElementType type = _tetrahedron_4; //element type
+
+// get the stress and strain arrays associated to the material index m
+const Array<Real> & strain_vec = model.getMaterial(m).getGradU(type);
+const Array<Real> & stress_vec = model.getMaterial(m).getStress(type);
+
+// get the element filter for the material index
+const Array<UInt> & elem_filter = model.getMaterial(m).getElementFilter(type);
+
+// initialize the integrated stress and strain arrays
+Array<Real> int_strain_vec(elem_filter.getSize(),
+ sp_dim*sp_dim, "int_of_strain");
+Array<Real> int_stress_vec(elem_filter.getSize(),
+ sp_dim*sp_dim, "int_of_stress");
+
+// integrate the fields
+model.getFEEngine().integrate(strain_vec, int_strain_vec,
+ sp_dim*sp_dim, type, _not_ghost, elem_filter);
+model.getFEEngine().integrate(stress_vec, int_stress_vec,
+ sp_dim*sp_dim, type, _not_ghost, elem_filter);
+\end{cpp}
+
+\input{manual-elements}
\ No newline at end of file
diff --git a/doc/manual/manual-gettingstarted.tex b/doc/manual/manual-gettingstarted.tex
index 4135c1cf1..13538ecfb 100644
--- a/doc/manual/manual-gettingstarted.tex
+++ b/doc/manual/manual-gettingstarted.tex
@@ -1,424 +1,450 @@
\chapter{Getting Started}
\section{Downloading the Code}
The \akantu source code can be requested using the form accessible at the URL
\url{http://lsms.epfl.ch/akantu}. There, you will be asked to accept the LGPL
license terms.
\section{Compiling \akantu}
\akantu is a \code{cmake} project, so to configure it, you can either
follow the usual way:
\begin{command}
> cd akantu
> mkdir build
> cd build
> ccmake ..
[ Set the options that you need ]
> make
> make install
\end{command}
\noindent Or, use the \code{Makefile} we added for your convenience to
handle the \code{cmake} configuration
\begin{command}
> cd akantu
> make config
> make
> make install
\end{command}
\noindent All the \akantu options are documented in Appendix
\ref{app:package-dependencies}.
\section{Writing a \texttt{main} Function\label{sect:common:main}}
\label{sec:writing_main}
First of all, \akantu needs to be initialized. The memory management
included in the core library handles the correct allocation and
de-allocation of vectors, structures and/or objects. Moreover, in
parallel computations, the initialization procedure performs the
communication setup. This is achieved by a pair of functions
(\code{initialize} and \code{finalize}) that are used as follows:
\begin{cpp}
#include "aka_common.hh"
#include "..."
using namespace akantu;
int main(int argc, char *argv[]) {
- initialize("material.dat", argc, argv);
+ initialize("input_file.dat", argc, argv);
// your code
...
finalize();
}
\end{cpp}
-The \code{initialize} function takes the material file and the program
-parameters which can be interpreted by \akantu in due form. Obviously
-it is necessary to include all files needed in main. In this manual
+The \code{initialize} function takes the text inpute file and the program
+parameters which can be parsed by \akantu in due form (see \ref{sect:parser}).
+Obviously it is necessary to include all files needed in main. In this manual
all provided code implies the usage of \code{akantu} as namespace.
\section{Creating and Loading a Mesh\label{sect:common:mesh}}
In its current state, \akantu supports three types of meshes: Gmsh~\cite{gmsh},
Abaqus~\cite{abaqus} and Diana~\cite{diana}. Once a \code{Mesh} object is
created with a given spatial dimension, it can be filled by reading a mesh input file.
The method \code{read} of the class \code{Mesh} infers the mesh type from the file extension. If a non-standard file extension is used, the mesh type has to be specified.
\begin{cpp}
UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
// Reading Gmsh files
mesh.read("my_gmsh_mesh.msh");
mesh.read("my_gmsh_mesh", _miot_gmsh);
// Reading Abaqus files
mesh.read("my_abaqus_mesh.inp");
mesh.read("my_abaqus_mesh", _miot_abaqus);
// Reading Diana files
mesh.read("my_diana_mesh.dat");
mesh.read("my_diana_mesh", _miot_diana);
\end{cpp}
The Gmsh reader adds the geometrical and physical tags as mesh data. The physical
values are stored as a \code{UInt} data called \code{tag\_0}, if a string
name is provided it is stored as a \code{std::string} data named
\code{physical\_names}. The geometrical tag is stored as a \code{UInt} data named
\code{tag\_1}.
The Abaqus reader stores the \code{ELSET} in ElementGroups and the \code{NSET}
in NodeGroups. The material assignment can be retrieved from the
\code{std::string} mesh data named \code{abaqus\_material}.
% \akantu supports meshes generated with Gmsh~\cite{gmsh}, a free
% software available at \url{http://geuz.org/gmsh/} where a detailed
% documentation can be found. Consequently, this manual will not provide
% Gmsh usage directions. Gmsh outputs meshes in \code{.msh} format that can be read
% by \akantu. In order to import a mesh, it is necessary to create
% a \code{Mesh} object through the following function calls:
% \begin{cpp}
% UInt spatial_dimension = 2;
% Mesh mesh(spatial_dimension);
% \end{cpp}
% The only parameter that has to be specified by the user is the spatial
% dimension of the problem. Now it is possible to read a \code{.msh} file with
% a \code{MeshIOMSH} object that takes care of loading a mesh to memory.
% This step is carried out by:
% \begin{cpp}
% mesh.read("square.msh");
% \end{cpp}
% where the \code{MeshIOMSH} object is first created before being
% used to read the \code{.msh} file. The mesh file name as well as the \code{Mesh}
% object must be specified by the user.
% The \code{MeshIOMSH} object can also write mesh files. This feature
% is useful to save a mesh that has been modified during a
% simulation. The \code{write} method takes care of it:
% \begin{cpp}
% mesh_io.write("square_modified.msh", mesh);
% \end{cpp}
% which works exactly like the \code{read} method.
% \akantu supports also meshes generated by
% DIANA (\url{http://tnodiana.com}), but only in reading mode. A similar
% procedure applies where the only
% difference is that the \code{MeshIODiana} object should be used
% instead of the \code{MeshIOMSH} one. Additional mesh readers can be
% introduced into \akantu by coding new \code{MeshIO} classes.
\section{Using \texttt{Arrays}}
Data in \akantu can be stored in data containers implemented by
the \code{Array} class. In its most basic usage, the \code{Array} class
implemented in \akantu is similar to the \code{vector} class of
the Standard Template Library (STL) for C++. A simple \code{Array}
-containing a sequence of \code{nb\_element} values can be generated with:
+containing a sequence of \code{nb\_element} values (of a given type) can be generated with:
\begin{cpp}
Array<type> example_array(nb_element);
\end{cpp}
where \code{type} usually is \code{Real}, \code{Int}, \code{UInt} or
\code{bool}. Each value is associated to an index, so that data can be
accessed by typing:
\begin{cpp}
type & val = example_array(index)
\end{cpp}
\code{Arrays} can also contain tuples of values for each index. In
that case, the number of components per tuple must be specified at the
\code{Array} creation. For example, if we want to create an
\code{Array} to store the coordinates (sequences of three values) of
ten nodes, the appropriate code is the following:
\begin{cpp}
UInt nb_nodes = 10;
UInt spatial_dimension = 3;
Array<Real> position(nb_nodes, spatial_dimension);
\end{cpp}
In this case the $x$ position of the eighth node number will be given by
\code{position(7, 0)} (in C++, numbering starts at 0 and not
1). If the number of components for the sequences is not specified, the
default value of 1 is used.
+Here is a list of some basic operations that can be performed on \code{Array}:
+\begin{itemize}
+ \item \code{resize(size)} change the size of the \code{Array}.
+ \item \code{clear()} set all entries of the \code{Array} to zero.
+ \item \code{set(t)} set all entries of the \code{Array} to \code{t}.
+ \item \code{copy(const Array<T> $\&$ other)} copy another \code{Array} into the current one. The two \code{Array} should have the same number of components.
+ \item \code{push$\_$back(tuple)} append a tuple with the correct number of components at the end of the \code{Array}.
+ \item \code{erase(i) erase the value at the i-th position.}
+ \item \code{find(value)} search \code{value} in the current \code{Array}. Return position index of the first occurence or $-1$ if not found.
+ \item \code{storage()} Return the address of the allocated memory of the \code{Array}.
+\end{itemize}
+
+\subsection{\texttt{Arrays} iterators}
It is very common in \akantu to loop over arrays to perform a specific
treatment. This ranges from geometric calculation on nodal quantities
to tensor algebra (in constitutive laws for example).
The \code{Array} object has the possibility to request iterators
in order to make the writing of loops easier and enhance readability.
For instance, a loop over the nodal coordinates can be performed like:
\begin{cpp}
- //accessing the nodal coordinates Array
+ //accessing the nodal coordinates Array (spatial_dimension components)
Array<Real> nodes = mesh.getNodes();
//creating the iterators
Array<Real>::vector_iterator it = nodes.begin(spatial_dimension);
Array<Real>::vector_iterator end = nodes.end(spatial_dimension);
for (; it != end; ++it){
Vector<Real> & coords = (*it);
//do what you need
....
}
\end{cpp}
In that example, each \code{Vector<Real>} is a geometrical array of
size \code{spatial\_dimension} and the iteration is conveniently
performed by the \code{Array} iterator.
The \code{Array} object is intensively used to store second order
tensor values. In that case, it should be specified that the returned
object type is a matrix when constructing the iterator. This is done
when calling the \code{begin} function. For instance, assuming that we
have a \code{Array} storing stresses, we can loop over the stored
tensors by:
\begin{cpp}
//creating the iterators
Array<Real>::matrix_iterator it = stresses.begin(spatial_dimension,spatial_dimension);
Array<Real>::matrix_iterator end = stresses.end(spatial_dimension,spatial_dimension);
for (; it != end; ++it){
Matrix<Real> & stress = (*it);
//do what you need
....
}
\end{cpp}
In that last example, the \code{Matrix} objects are
\code{spatial\_dimension} $\times$ \code{spatial\_dimension} matrices.
The light objects \code{Matrix} and \code{Vector} can be used and
-combined to do most common linear algebra.
+combined to do most common linear algebra. If the number of component
+is 1, it is possible to use a scalar\_iterator rather than the
+vector/matrix one.
In general, a mesh consists of several kinds of elements.
Consequently, the amount of data to be stored can differ for each
element type. The straightforward example is the connectivity array,
namely the sequences of nodes belonging to each element (linear
triangular elements have fewer nodes than, say, rectangular quadratic
elements etc.). A particular data structure called
\code{ElementTypeMapArray} is provided to easily manage this kind of
data. It consists of a group of \code{Arrays}, each associated to an
element type. The following code can retrieve the
\code{ElementTypeMapArray} which stores the connectivity arrays for a
mesh:
\begin{cpp}
ElementTypeMapArray<UInt> & connectivities = mesh.getConnectivities();
\end{cpp}
Then, the specific array associated to a given element type can be obtained by
\begin{cpp}
Array<UInt> & connectivity_triangle = connectivities(_triangle_3);
\end{cpp}
where the first order 3-node triangular element was used in the presented piece
of code.
\subsection{Vector \& Matrix}
The \code{Array} iterators as presented in the previous section can be shaped as
\code{Vector} or \code{Matrix}. This objects represent $1^{st}$ and $2^{nd}$
order tensors. As such they come with some functionalities that we will present
a bit more into detail in this here.
\subsubsection{\texttt{Vector<T>}}
\begin{enumerate}
\item Accessors:
\begin{itemize}
\item \code{v(i)} gives the $i^{th}$ component of the vector \code{v}
\item \code{v[i]} gives the $i^{th}$ component of the vector \code{v}
\item \code{v.size()} gives the number of component
\end{itemize}
\item Level 1: (results are scalars)
\begin{itemize}
\item \code{v.norm()} returns the geometrical norm ($L_2$)
\item \code{v.norm<N>()} returns the $L_N$ norm defined as $\left(\sum_i
|\code{v(i)}|^N\right)^{1/N}$. N can take any positive
integer value. There are also some particular values for the most commonly
used norms, \code{L\_1} for the Manhattan norm, \code{L\_2} for the
geometrical norm and \code{L\_inf} for the norm infinity.
\item \code{v.dot(x)} return the dot product of \code{v} and \code{x}
\item \code{v.distance(x)} return the geometrical norm of $\code{v} -
\code{x}$
\end{itemize}
\item Level 2: (results are vectors)
\begin{itemize}
\item \code{v += s}, \code{v -= s}, \code{v *= s}, \code{v /= s} those are
element-wise operators that sum, substract, multiply or divide all the
component of \code{v} by the scalar \code{s}
\item \code{v += x}, \code{v -= x} sums or substracts the vector \code{x}
to/from \code{v}
\item \code{v.mul(A, x, alpha)} stores the result of $\alpha \mat{A} \vec{x}$ in \code{v},
$\alpha$ is equal to 1 by default
\item \code{v.solve(A, b)} stores the result of the resolution of the system $\mat{A} \vec{x} =
\vec{b}$ in \code{v}
\item \code{v.crossProduct(v1, v2)} computes the cross product of \code{v1} and \code{v2} and
stores the result in \code{v}
\end{itemize}
\end{enumerate}
\subsubsection{\texttt{Matrix<T>}}
\begin{enumerate}
\item Accessors:
\begin{itemize}
\item \code{A(i, j)} gives the component $A_{ij}$ of the matrix \code{A}
\item \code{A(i)} gives the $i^{th}$ column of the matrix as a \code{Vector}
\item \code{A[k]} gives the $k^{th}$ component of the matrix, matrices are
stored in a column major way, which means that to access $A_{ij}$, $k = i +
j M$
\item \code{A.rows()} gives the number of rows of \code{A} ($M$)
\item \code{A.cols()} gives the number of columns of \code{A} ($N$)
\item \code{A.size()} gives the number of component in the matrix ($M \times N$)
\end{itemize}
\item Level 1: (results are scalars)
\begin{itemize}
- \item \code{A.norm<N>()} returns the $L_N$ norm defined as $\left(\sum_i
- |\code{A(i)}|^N\right)^{1/N}$. N can take any positive
- integer value.
\item \code{A.norm()} is equivalent to \code{A.norm<L\_2>()}
+ \item \code{A.norm<N>()} returns the $L_N$ norm defined as
+ $\left(\sum_i\sum_j |\code{A(i,j)}|^N\right)^{1/N}$. N can take
+ any positive integer value. There are also some particular values
+ for the most commonly used norms, \code{L\_1} for the Manhattan
+ norm, \code{L\_2} for the geometrical norm and \code{L\_inf} for
+ the norm infinity.
\item \code{A.trace()} return the trace of \code{A}
\item \code{A.det()} return the determinant of \code{A}
\item \code{A.doubleDot(B)} return the double dot product of \code{A} and
\code{B}, $\mat{A}:\mat{B}$
\end{itemize}
\item Level 3: (results are matrices)
\begin{itemize}
\item \code{A.eye(s)}, \code{Matrix<T>::eye(s)} fills/creates a matrix with
the $s\mat{I}$ with $\mat{I}$ the identity matrix
\item \code{A.inverse(B)} stores $\mat{B}^{-1}$ in \code{A}
\item \code{A.transpose()} returns $\mat{A}^{t}$
\item \code{A.outerProduct(v1, v2)} stores $\vec{v_1} \vec{v_2}^{t}$ in
\code{A}
\item \code{C.mul<t\_A, t\_B>(A, B, alpha)}: stores the result of the product of
\code{A} and code{B} time the scalar \code{alpha} in \code{C}. \code{t\_A}
and \code{t\_B} are boolean defining if \code{A} and \code{B} should be
transposed or not.
\begin{tabular}{ccl}
\toprule
\code{t\_A} & \code{t\_B} & result \\
\midrule
false & false & $\mat{C} = \alpha \mat{A} \mat{B}$\\
false & true & $\mat{C} = \alpha \mat{A} \mat{B}^t$\\
true & false & $\mat{C} = \alpha \mat{A}^t \mat{B}$\\
true & true & $\mat{C} = \alpha \mat{A}^t \mat{B}^t$\\
\bottomrule
\end{tabular}
\item \code{A.eigs(d, V)} this method computes the eigenvalues and
eigenvectors of \code{A} and store the results in \code{d} and \code{V} such
that $\code{d(i)} = \lambda_i$ and $\code{V(i)} = \vec{v_i}$ with
$\mat{A}\vec{v_i} = \lambda_i\vec{v_i}$ and $\lambda_1 > ... > \lambda_i >
... > \lambda_N$
\end{itemize}
\end{enumerate}
+\subsubsection{\texttt{Tensor3<T>}}
+Accessors:
+\begin{itemize}
+ \item \code{t(i, j, k)} gives the component $T_{ijk}$ of the tensor \code{t}
+ \item \code{t(k)} gives the $k^{th}$ two-dimensional tensor as a \code{Matrix}
+ \item \code{t[k]} gives the $k^{th}$ two-dimensional tensor as a \code{Matrix}
+\end{itemize}
-\section{Manipulating group of nodes and/or elements}
+
+\section{Manipulating group of nodes and/or elements\label{sect:common:groups}}
\akantu provides the possibility to manipulate
subgroups of elements and nodes.
Any \code{ElementGroup} and/or \code{NodeGroup} must be managed
by a \code{GroupManager}. Such a manager has the role to
associate group objects to names. This is a useful feature,
in particular for the application of the boundary conditions,
as will be demonstrated in section \ref{sect:smm:boundary}.
To most general group manager is the \code{Mesh} class
which inheritates from the \code{GroupManager} class.
For instance, the following code shows how to request
an element group to a mesh:
\begin{cpp}
// request creation of a group of nodes
NodeGroup & my_node_group = mesh.createNodeGroup("my_node_group");
// request creation of a group of elements
ElementGroup & my_element_group = mesh.createElementGroup("my_element_group");
/* fill and use the groups */
\end{cpp}
\subsection{The \texttt{NodeGroup} object}
A group of nodes is stored in \code{NodeGroup} objects.
They are quite simple objects which store the indexes
of the selected nodes in a \code{Array<UInt>}.
Nodes are selected by adding them when calling
\code{NodeGroup::add}. For instance you can select nodes
having a positive $X$ coordinate with the following code:
\begin{cpp}
Array<Real> & nodes = mesh.getNodes();
NodeGroup & group = mesh.createNodeGroup("XpositiveNode");
Array<Real>::const_vector_iterator it = nodes.begin(spatial_dimension);
Array<Real>::const_vector_iterator end = nodes.end(spatial_dimension);
UInt index = 0;
for (; it != end ; ++it , ++index){
const Vector<Real> & position = *it;
if (position(0) > 0) group.add(index);
}
\end{cpp}
\subsection{The \texttt{ElementGroup} object}
A group of elements is stored in \code{ElementGroup} objects.
Since a group can contain elements of various types
the \code{ElementGroup} object stores indexes in
a \code{ElementTypeMapArray<UInt>} object.
Then elements can be added to the group by calling \code{addElement}.
For instance, selecting the elements for which the barycenter of the nodes
has a positive $X$ coordinate can be made with:
\begin{cpp}
ElementGroup & group = mesh.createElementGroup("XpositiveElement");
Mesh::type_iterator it = mesh.firstType();
Mesh::type_iterator end = mesh.lastType();
Vector<Real> barycenter(spatial_dimension);
for(; it != end; ++it){
UInt nb_element = mesh.getNbElement(*it);
for(UInt e = 0; e < nb_element; ++e) {
ElementType type = *it;
mesh.getBarycenter(e, type, barycenter.storage());
if (barycenter(0) > 0) group.add(type,e);
}
}
\end{cpp}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual-io.tex b/doc/manual/manual-io.tex
index 8091205eb..a053b08f8 100644
--- a/doc/manual/manual-io.tex
+++ b/doc/manual/manual-io.tex
@@ -1,112 +1,270 @@
-
\chapter{Input/Output}\index{I\/O}
-\section{Generic data}
+\section{Input file \label{sect:parser}}
+
+The text input file of a simulation should be precised using the method \code{initialize} which will instantiate the static \code{Parser} object of \akantu. This section explains how to manipulate \code{Parser} objects to input data in \akantu.
+\begin{cpp}
+int main(int argc, char *argv[]) {
+ initialize("input_files.dat", argc, argv);
+ ...
+\end{cpp}
+
+\subsection{Akantu Parser}
+
+\akantu file parser has a tree organization.
+\begin{itemize}
+\item \code{Parser}, the root of the tree, can be accessed using
+\begin{cpp}
+Parser & parser = getStaticParser();
+\end{cpp}
+\item \code{ParserSection}, branch of the tree, contains map a of sub-sections (\code{SectionType}, \code{ParserSection}) and a \code{ParserSection *} pointing to the parent section. The user section of the input file can directly be accessed by
+\begin{cpp}
+const ParserSection & usersect = getUserParser();
+\end{cpp}
+\item \code{ParserParameter}, the leaf of the tree, carries data of the input file which can be casted to the correct type with
+\begin{cpp}
+Real mass = usersect.getParameter("mass");
+\end{cpp}
+or used directly within an expression
+\begin{cpp}
+Real dead_weight = 9.81 * usersect.getParameterValue<Real>("mass");
+\end{cpp}
+\end{itemize}
+
+\subsection{Grammar}
+
+The structure of text input files consists of different sections containing a list of parameters. As example, the file parsed in the previous section will look like
+\begin{cpp}
+ user parameters [
+ mass = 10.5
+ ]
+\end{cpp}
+Basically every standard arithmetic operations can be used inside of input files as well as the constant \code{pi} and \code{e} and the exponent operator \code{\^{}}. Operations between \code{ParserParameter} are also possible with the convention that only parameters of the current and the parent sections are available. \code{Vector} and \code{Matrix} can also be read according to the \code{NumPy}\cite{numpy} writing convention (a.e. cauchy$\_$stress$\_$tensor = [[$\sigma_{xx}$, $\sigma_{xy}$],[$\sigma_{yx}$,$\sigma_{yy}$]]).
+An example illustrating how to parse the following input file can be found in \code{example$\backslash$io$\backslash$parser$\backslash$example$\_$parser.cc}.
+\begin{cpp}
+user parameters [
+ spatial$\_$dimension = 2
+ mesh$\_$file = swiss$\_$cheese.msh
+ inner$\_$holes = holes
+ outter$\_$crust = crust
+ lactostatic$\_$p = 30e3
+ stress = [[lactostatic$\_$p,0],[0,lactostatic$\_$p]]
+ max$\_$nb$\_$iterations = 100
+ precision = 1e-9
+]
+\end{cpp}
+\subsection{Material section \label{sect:io:material}}
+The input file should also be used to specify material characteristics (constitutive behavior and material properties). The dedicated material section is then read by \code{initFull} method of \code{SolidMechanicsModel} which initializes the different materials specified with the following convention:
+\begin{cpp}
+ material %\emph{constitutive\_law}% %\emph{<optional flavor>}% [
+ name = $value$
+ rho = $value$
+ ...
+ ]
+\end{cpp}
+\index{Constitutive\_laws} where \emph{constitutive\_law} is the adopted
+constitutive law, followed by the material properties listed one by line in the
+bracket (\eg \code{name} and density \code{rho}). Some constitutive laws can
+also have an \emph{optional flavor}. More information can be found in sections relative to material
+constitutive laws \ref{sect:smm:CL} or in Appendix \ref{app:material-parameters}.
+
+\section{Output data}
+
+\subsection{Generic data}
In this chapter, we address ways to get the internal data in human-readable formats.
The models in \akantu handle data associated to the
mesh, but this data can be split into several \code{Arrays}. For example, the
data stored per element type in a \code{ElementTypeMapArray} is composed of as
many \code{Array}s as types in the mesh.
In order to get this data in a visualization software, the models contain a
object to dump \code{VTK} files. These files can be visualized in software such
as \code{ParaView}\cite{paraview}, \code{ViSit}\cite{visit} or \code{Mayavi}\cite{mayavi}.
The internal dumper of the model can be configured to specify which data fields
are to be written. This is done with the
\code{addDumpField}\index{I\/O!addDumpField} method. By default all the files
are generated in a folder called \code{paraview/}
\begin{cpp}
model.setBaseName("output"); // prefix for all generated files
model.addDumpField("displacement");
model.addDumpField("stress");
...
model.dump()
\end{cpp}
The fields are dumped with the number of components of the memory. For example, in 2D, the memory has
\code{Vector}s of 2 components, or the $2^{nd}$ order tensors with $2\times2$ components.
This memory can be dealt with \code{addDumpFieldVector}\index{I\/O!addDumpFieldVector} which always dumps
\code{Vector}s with 3 components or \code{addDumpFieldTensor}\index{I\/O!addDumpFieldTensor} which dumps $2^{nd}$
order tensors with $3\times3$ components respectively. The routines \code{addDumpFieldVector}\index{I\/O!addDumpFieldVector} and
-\code{addDumpFieldTensor}\index{I\/O!addDumpFieldTensor} were introduced because of Paraview which mostly manipulate 3D data.
+\code{addDumpFieldTensor}\index{I\/O!addDumpFieldTensor} were introduced because of \code{ParaView} which mostly manipulate 3D data.
Those fields which are stored by quadrature point are modified to be seen in the
\code{VTK} file as elemental data. To do this, the default is to average the
values of all the quadrature points.
The list of fields depends on the models (for
\code{SolidMechanicsModel} see table~\ref{tab:io:smm_field_list}).
\begin{table}
\centering
\begin{tabular}{llll}
\toprule
key & type & support \\
\midrule
displacement & Vector<Real> & nodes \\
mass & Vector<Real> & nodes \\
velocity & Vector<Real> & nodes \\
acceleration & Vector<Real> & nodes \\
force & Vector<Real> & nodes \\
residual & Vector<Real> & nodes \\
increment & Vector<Real> & nodes \\
{blocked\_dofs} & Vector<bool> & nodes \\
partitions & Real & elements \\
material\_index & variable & elements\\
strain & Matrix<Real> & quadrature points \\
Green strain & Matrix<Real> & quadrature points \\
principal strain & Vector<Real> & quadrature points \\
principal Green strain & Vector<Real> & quadrature points \\
grad\_u & Matrix<Real> & quadrature points \\
stress & Matrix<Real> & quadrature points \\
Von Mises stress & Real & quadrature points \\
material\_index & variable & quadrature points \\
\bottomrule
\end{tabular}
\caption{List of dumpable fields for \code{SolidMechanicsModel}.}
\label{tab:io:smm_field_list}
\end{table}
-The user can also register external fields which have the same mesh as the mesh from the model as support. To do this, an object of type \code{Field} has to be created.\index{I\/O!addDumpFieldExternal}
-
-\begin{itemize}
-\item For nodal fields :
-\begin{cpp}
- Vector<T> vect(nb_nodes, nb_component);
- dumper::Field * field = new dumper::NodalField<T>(vect);
- model.addDumpFieldExternal("my_field", field);
-\end{cpp}
-
-\item For elemental fields :
-\begin{cpp}
- ElementTypeMapArray<T> arr;
- dumper::Field * field = new dumper::ElementalField<T>(arr, spatial_dimension);
- model.addDumpFieldExternal("my_field", field);
-\end{cpp}
-\end{itemize}
-
-\section{Cohesive elements' data}
+\subsection{Cohesive elements' data}
Cohesive elements and their relative data can be easily dumped thanks
to a specific dumper contained in
\code{SolidMechanicsModelCohesive}. In order to use it, one has just
to add the string \code{"cohesive elements"} when calling each method
already illustrated. Here is an example on how to dump displacement
and damage:
\begin{cpp}
model.setBaseNameToDumper("cohesive elements", "cohesive_elements_output");
model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
model.addDumpFieldToDumper("cohesive elements", "damage");
...
model.dump("cohesive elements");
\end{cpp}
+\subsubsection{Fragmentation data}
+
+Whenever the \code{SolidMechanicsModelCohesive} is used, it is
+possible to dump additional data about the fragments that get formed
+in the simulation both in serial and parallel. This task is carried
+out by the \code{FragmentManager} class, that takes care of computing
+the following quantities for each fragment:
+\begin{itemize}
+\item index;
+\item mass;
+\item moments of inertia;
+\item velocity;
+\item number of elements.
+\end{itemize}
+These computations can be realized at once by calling the function
+\code{computeAllData}, or individually by calling the other public
+functions of the class. The data can be dumped to be visualized in
+Paraview, or can be accessed within the simulation. An example of
+usage is:
+\begin{cpp}
+ FragmentManager fragment_manager(model);
+ fragment_manager.buildAllData();
+ ...
+
+ model.addDumpField("fragments"); // this field contains the indices
+ model.addDumpField("fragments mass");
+ model.addDumpField("moments of inertia");
+ model.addDumpField("elements per fragment");
+ ...
+
+ for (UInt step = 1; step <= total_steps; ++step) {
+ ...
+
+ fragment_manager.buildAllData();
+ model.dump();
+ }
+ ...
+
+ const Array<Real> & fragment_velocities = fragment_manager.getVelocity();
+ ...
+\end{cpp}
+At the end of this example the velocities of the fragments are
+accessed with a reference to a \code{const Array<Real>}. The size of
+this array is the number of fragments, and its number of components is
+the spatial dimension in this case.
+
+
+\subsection{Advanced dumping}
+
+\subsubsection{Arbitrary fields}
+In addition to the predetermined fields from the models and materials, the user
+can add any data to a dumper as long as the support is the same. That is to say
+data that have the size of the full mesh on if the dumper is dumping the mesh,
+or of the size of an element group if it is a filtered dumper.
+
+For this the easiest is to use the ``external'' fields register functions\index{I\/O!addDumpFieldExternal}
+
+The simple case force nodal and elemental data are to pass directly the data
+container itself if it as the good size.
+\begin{itemize}
+\item For nodal fields :
+\begin{cpp}
+ Array<T> nodal_data(nb_nodes, nb_component);
+ ...
+ model.addDumpFieldExternal("my_field", nodal_data);
+\end{cpp}
+
+\item For elemental fields :
+\begin{cpp}
+ ElementTypeMapArray<T> elem_data;
+ ...
+ model.addDumpFieldExternal("my_field", elem_data);
+\end{cpp}
+\end{itemize}
+
+If some changes have to be applied on the data as for example a padding for
+\code{ParaView} vectors, this can be done by using the
+field interface.
+
+\begin{cpp}
+ model.addDumpFieldExternal(const std::string & field_name,
+ dumper::Field * field);
+\end{cpp}
+
+An example of code presenting this interface is present in the
+\shellcode{\examplesdir/io/dumper}. This interface is part of the
+\code{Dumpable} class from which the \code{Mesh} inherits.
+
+\subsubsection{Creating a new dumper}
+
+You can also create you own dumpers, \akantu uses a third-party library in order
+to write the output files, \code{IOHelper}. \akantu supports the \code{ParaView}
+format and a Text format defined by \code{IOHelper}.
+
+This two files format are handled by the classes
+\code{DumperParaview}\index{I\/O!DumperParaview} and
+\code{DumperText}\index{I\/O!DumperText}.
+
+In order to use them you can instantiate on of this object in your code. This
+dumper have a simple interface. You can register a mesh
+\code{registerMesh}\index{I\/O!registerMesh},
+\code{registerFilteredMesh}\index{I\/O!registerFilteredMesh} or a field,
+\code{registerField}\index{I\/O!registerField}.
+
+An example of code presenting this low level interface is present in the
+\shellcode{\examplesdir/io/dumper}. The different types of \code{Field} that can
+be created are present in the source folder \shellcode{src/io/dumper}.
-%%% Local Variables:
+%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual-parallel.tex b/doc/manual/manual-parallel.tex
index bfd89a089..215c2a052 100644
--- a/doc/manual/manual-parallel.tex
+++ b/doc/manual/manual-parallel.tex
@@ -1,113 +1,129 @@
\chapter{Parallel Computation}
This section explains how to launch a parallel computation.
The strategy adopted by \akantu uses a mesh partitioning
where elements are mapped to processors. Mesh partitions are
then distributed to available processors by adequate routines
as will be described below.
The sequence of additional operations to be performed by the user are:
\begin{itemize}
\item Initializing the parallel context
\item Partitioning the mesh
\item Distributing mesh partitions
\end{itemize}
After these steps, the \code{Model}
object proceeds with the interprocess communication automatically
without the user having to explicitly take care of them.
In what follows we show how it works on a \code{SolidMechanics} model.
\section{Initializing the Parallel Context}
The user must initialize \akantu by forwarding the arguments passed to the
program by using the function \code{initialize}, and close \akantu instances
at the end of the program by calling the \code{finalize} function.
\note{This step does not change from the sequential case as it was stated in
Section \ref{sect:common:main}. It only gives a additional motivation in the parallel/MPI context.}
The \code{initialize} function builds a \code{StaticCommunicator} object
responsible for handling the interprocess communications later on. The
\code{StaticCommunicator} can, for instance, be used to ask the total number of
declared processors available for computations as well as the process rank
through the functions \code{getNbProc} and \code{whoAmI} respectively.
An example of the initializing sequence and basic usage of the
\code{StaticCommunicator} is:
\begin{cpp}
int main(int argc, char *argv[])
{
initialize("material.dat", argc, argv);
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Int psize = comm.getNbProc();
Int prank = comm.whoAmI();
...
finalize();
}
\end{cpp}
\section{Partitioning the Mesh}
The mesh is partitioned after the correct initialization of the
processes playing a role in the computation. We assume that a
\code{Mesh} object is constructed as presented in
Section~\ref{sect:common:mesh}. Then a partition must be computed by
using an appropriate mesh partitioner. At present time, the only
partitioner available is \code{MeshPartitionScotch} which implements
the function \code{partitionate} using the
\textbf{Scotch}\cite{scotch} program. This is achieved by the
following code
\begin{cpp}
Mesh mesh(spatial_dimension);
MeshPartition * partition = NULL;
if(prank == 0) {
mesh.read("my_mesh.msh");
partition = new MeshPartitionScotch(mesh, spatial_dimension);
partition->partitionate(psize);
}
\end{cpp}
+The algorithm that partition the mesh needs the generation of a random
+distribution of values. Therefore, in order to run several time a
+simulation with the same partition of the mesh, the \emph{seed} has to
+be set manually. This can be done either 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, or by setting
+it directly in the code with the command:
+\begin{cpp}
+ RandGenerator:: seed(1.0)
+\end{cpp}
+The latter command, with empty brackets, can be used to check the value
+of the \emph{seed} used in the simulation.
+
\note{Only the processor of rank $0$ should load the mesh file to
partition it. Nevertheless, the \code{Mesh} object must by declared
for all processors since the mesh distribution will store mesh pieces to that object.}
\section{Distributing Mesh Partitions}
The distribution of the mesh is done automatically by the
\code{SolidMechanicsModel} through the \code{initParallel} method. Thus,
after creating a \code{SolidMechanicsModel} with our mesh as the initial
parameter, the \code{initParallel} method must be called receiving the partition
as a parameter.
\begin{cpp}
SolidMechanicsModel model(mesh);
model.initParallel(partition);
\end{cpp}
After that point, everything remains as in the sequential case from
the user point of view. This allows the user to care only
about his simulation without concern for the parallelism.
An example of an explicit dynamic 2D bar in compression in a parallel
context can be found in \shellcode{\examplesdir/parallel\_2d}.
\section{Launching a Parallel Program}
Using \textbf{MPI} a parallel run can be launched from a shell
using the command
\begin{cpp}
mpirun -np #procs program_name parameter1 parameter2 ...
\end{cpp}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
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 eb64db99b..b06c528ff 100644
--- a/doc/manual/manual-solidmechanicsmodel.tex
+++ b/doc/manual/manual-solidmechanicsmodel.tex
@@ -1,1017 +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 as shown in the following code:
+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 displacement in x-direction
- blocked(i, 1) = true; //block displacement in y-direction
+ 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.\label{fig:smm:dirichlet_bc}}
+ \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:
+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.
+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.
-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}).
-
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}.}
+% \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.
+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:
+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-structuralmechanicsmodel-elements.tex b/doc/manual/manual-structuralmechanicsmodel-elements.tex
index 7540ee1d6..3cb81d17a 100644
--- a/doc/manual/manual-structuralmechanicsmodel-elements.tex
+++ b/doc/manual/manual-structuralmechanicsmodel-elements.tex
@@ -1,37 +1,37 @@
-\section{Structural Elements\index{Elements!Structural}}
+\subsection{Structural Elements\index{Elements!Structural}}
-\subsection*{Bernoulli Beam Elements\index{Elements!Bernoulli}}
+\subsubsection*{Bernoulli Beam Elements\index{Elements!Bernoulli}}
These elements allow to compute the displacements and rotations of
structures constituted by Bernoulli beams. \akantu defines them for
both 2D and 3D problems respectively in the element types
\code{\_bernoulli\_beam\_2} and \code{\_bernoulli\_beam\_3}. A
schematic depiction of a beam element is shown in
Figure~\ref{fig:elements:bernoulli} and some of its properties are
listed in Table~\ref{tab:elements:bernoulli}.
\note{Beam elements are of mixed order: the axial displacement is
linearly interpolated while transverse displacements and rotations
use cubic shape functions.}
\begin{figure}[htb]
\centering
\includegraphics[width=0.3\textwidth]{figures/elements/bernoulli_2}
\caption{Schematic depiction of a Bernoulli beam element (applied to
2D and 3D) in \akantu. The node numbering as used in \akantu is
indicated, and also the quadrature points are highlighted (gray
circles).}
\label{fig:elements:bernoulli}
\end{figure}
\begin{table}[htb]
\centering
\begin{tabular}{c|cccc}
\toprule
Element type & Dimension & \# nodes &\# quad. points & \# d.o.f.\\
\midrule
\texttt{\_bernoulli\_beam\_2} & 2D& 2& 3& 6\\
\texttt{\_bernoulli\_beam\_3} & 3D& 2& 3& 12\\
\bottomrule
\end{tabular}
\caption{Some basic properties of the beam elements in \akantu}
\label{tab:elements:bernoulli}
\end{table}
diff --git a/doc/manual/manual.sty b/doc/manual/manual.sty
index 36dcb2425..690c3205b 100644
--- a/doc/manual/manual.sty
+++ b/doc/manual/manual.sty
@@ -1,328 +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 b27df2847..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-elements}
+\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 0206e7bfa..2aa9a3139 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,52 +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 an explicit simulation" PACKAGE implicit)
-add_example(parallel_2d "Example of how to write a parallel code with Akantu" PACKAGE parallel)
+add_example(static "Example on how to run a static simulation" PACKAGE implicit)
+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)
-#===============================================================================
\ No newline at end of file
+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 aa209f7a6..65c03b0af 100644
--- a/examples/boundary_conditions/CMakeLists.txt
+++ b/examples/boundary_conditions/CMakeLists.txt
@@ -1,39 +1,32 @@
#===============================================================================
# @file CMakeLists.txt
#
-# @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+# @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@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
+# @brief CMakeLists for the cohesive examples
#
# @section LICENSE
#
-# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
-# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+# (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
#
-# @section DESCRIPTION
-#
#===============================================================================
-add_mesh(plate_mesh square.geo 2 1)
-
-register_example(plate plate.cc)
-add_dependencies(plate plate_mesh)
-
-file(COPY material.dat DESTINATION .)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
\ No newline at end of file
+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/plate.cc b/examples/boundary_conditions/plate.cc
deleted file mode 100644
index 9211fc1d4..000000000
--- a/examples/boundary_conditions/plate.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file plate.cc
- *
- * @author Dana Christen <dana.christen@epfl.ch>
- * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Fri May 11 2012
- * @date last modification: Mon Apr 07 2014
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model.hh"
-/* -------------------------------------------------------------------------- */
-#include <iostream>
-/* -------------------------------------------------------------------------- */
-
-using namespace akantu;
-
-int main(int argc, char *argv[]) {
- initialize("material.dat", argc, argv);
-
- //Do I need to define the element type?
- UInt spatial_dimension = 2;
- UInt max_steps = 3000;
-
- Mesh mesh(spatial_dimension);
- mesh.read("square.msh");
- mesh.createGroupsFromMeshData<std::string>("physical_names");
-
- SolidMechanicsModel model(mesh);
-
- /// model initialization
- model.initFull();
-
- std::cout << model.getMaterial(0) << std::endl;
- model.assembleMassLumped();
-
- /// Dirichlet boundary conditions
- model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x");
- model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y");
-
- model.updateResidual();
-
- model.setBaseName("plate");
- model.addDumpFieldVector("displacement");
- model.addDumpField("blocked_dofs");
- model.addDumpField("force" );
- model.addDumpField("residual" );
- model.dump();
-
- Real time_step = model.getStableTimeStep() * .8;
- model.setTimeStep(time_step);
-
- Vector<Real> traction(2);
- for(UInt s = 1; s <= max_steps; ++s) {
- if(s % 100 == 0)
- std::cout << "passing step " << s << "/" << max_steps << std::endl;
-
- // Neumann boundary condition
- traction(0) = s*0.1;
- traction(1) = 0.0;
- model.applyBC(BC::Neumann::FromTraction(traction), "Traction");
-
- model.explicitPred();
- model.updateResidual();
- model.updateAcceleration();
- model.explicitCorr();
-
- if(s % 10 == 0)
- model.dump();
- }
-
- finalize();
- return EXIT_SUCCESS;
-}
diff --git a/examples/boundary_conditions/predefined_bc/CMakeLists.txt b/examples/boundary_conditions/predefined_bc/CMakeLists.txt
new file mode 100644
index 000000000..8d7036691
--- /dev/null
+++ b/examples/boundary_conditions/predefined_bc/CMakeLists.txt
@@ -0,0 +1,37 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+#
+# @date creation: Wed Dec 16 2015
+# @date last modification: Mon Jan 18 2016
+#
+# @brief boundary condition example configuration
+#
+# @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
+#
+#===============================================================================
+
+add_mesh(predefined_bc_mesh square.geo 2 1)
+
+register_example(predefined_bc SOURCES predefined_bc.cc
+ DEPENDS predefined_bc_mesh
+ FILES_TO_COPY material.dat)
diff --git a/examples/boundary_conditions/material.dat b/examples/boundary_conditions/predefined_bc/material.dat
similarity index 100%
copy from examples/boundary_conditions/material.dat
copy to examples/boundary_conditions/predefined_bc/material.dat
diff --git a/examples/boundary_conditions/predefined_bc/predefined_bc.cc b/examples/boundary_conditions/predefined_bc/predefined_bc.cc
new file mode 100644
index 000000000..c59eeb2ef
--- /dev/null
+++ b/examples/boundary_conditions/predefined_bc/predefined_bc.cc
@@ -0,0 +1,63 @@
+/**
+ * @file predefined_bc.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Wed Dec 16 2015
+ * @date last modification: Mon Jan 18 2016
+ *
+ * @brief boundary condition example
+ *
+ * @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 <iostream>
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+ initialize("material.dat", argc, argv);
+
+ Mesh mesh(2);
+ mesh.read("square.msh");
+ mesh.createGroupsFromMeshData<std::string>("physical_names");
+
+ // model initialization
+ SolidMechanicsModel model(mesh);
+ model.initFull();
+
+ // Dirichlet boundary conditions
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x");
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y");
+
+ // output in a paraview file
+ model.setBaseName("plate");
+ model.addDumpFieldVector("displacement");
+ model.addDumpField("blocked_dofs");
+ model.addDumpField("force" );
+ model.dump();
+
+ finalize();
+ return EXIT_SUCCESS;
+}
diff --git a/examples/boundary_conditions/square.geo b/examples/boundary_conditions/predefined_bc/square.geo
similarity index 100%
rename from examples/boundary_conditions/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
new file mode 100644
index 000000000..920781217
--- /dev/null
+++ b/examples/boundary_conditions/user_defined_bc/CMakeLists.txt
@@ -0,0 +1,39 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+#
+# @date creation: Wed Dec 16 2015
+# @date last modification: Mon Jan 18 2016
+#
+# @brief boundary condition example configuration
+#
+# @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
+#
+#===============================================================================
+
+add_mesh(user_defined_bc_mesh fine_mesh.geo 2 1)
+
+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
new file mode 100644
index 000000000..b22399597
--- /dev/null
+++ b/examples/boundary_conditions/user_defined_bc/fine_mesh.geo
@@ -0,0 +1,29 @@
+// Mesh size
+h = 0.1;
+
+// Dimensions of the square
+Lx = 2;
+Ly = 2;
+
+// ------------------------------------------
+// Geometry
+// ------------------------------------------
+Point(1) = { 0.0, 0.0, 0.0, h};
+Point(2) = { Lx, 0.0, 0.0, h};
+Point(3) = { Lx, Ly, 0.0, h};
+Point(4) = { 0.0, Ly, 0.0, h};
+
+Line(1) = {1, 2};
+Line(2) = {2, 3};
+Line(3) = {3, 4};
+Line(4) = {4, 1};
+
+Line Loop(1) = {1:4};
+
+Plane Surface(1) = {1};
+
+Physical Surface(1) = {1};
+Physical Line("Fixed_y") = {1};
+Physical Line("Fixed_x") = {4};
+Physical Line("Traction") = {2};
+Physical Line("Free") = {3};
diff --git a/examples/boundary_conditions/material.dat b/examples/boundary_conditions/user_defined_bc/material.dat
similarity index 100%
rename from examples/boundary_conditions/material.dat
rename to examples/boundary_conditions/user_defined_bc/material.dat
diff --git a/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc b/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc
new file mode 100644
index 000000000..32e1e048d
--- /dev/null
+++ b/examples/boundary_conditions/user_defined_bc/user_defined_bc.cc
@@ -0,0 +1,89 @@
+/**
+ * @file user_defined_bc.cc
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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 <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()(__attribute__((unused)) UInt node,
+ Vector<bool> & flags,
+ Vector<Real> & primal,
+ const Vector<Real> & coord) const {
+ DIRICHLET_SANITY_CHECK;
+ flags(axis) = true;
+ 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();
+
+ /// 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();
+
+ 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/CMakeLists.txt b/examples/cohesive_element/cohesive_extrinsic_IG_TG/CMakeLists.txt
deleted file mode 100644
index 3028fbb46..000000000
--- a/examples/cohesive_element/cohesive_extrinsic_IG_TG/CMakeLists.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-#===============================================================================
-# @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
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
-#
-# @section DESCRIPTION
-#
-#===============================================================================
-
-register_example(cohesive_extrinsic_IG_TG
- cohesive_extrinsic_IG_TG.cc)
-
- #===============================================================================
-file(COPY material.dat DESTINATION .)
-file(COPY square.msh DESTINATION .)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
-
-
diff --git a/examples/cohesive_element/cohesive_extrinsic_IG_TG/cohesive_extrinsic_IG_TG.cc b/examples/cohesive_element/cohesive_extrinsic_IG_TG/cohesive_extrinsic_IG_TG.cc
deleted file mode 100644
index ded0af86b..000000000
--- a/examples/cohesive_element/cohesive_extrinsic_IG_TG/cohesive_extrinsic_IG_TG.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#include <limits>
-#include <fstream>
-#include <iostream>
-
-
-/* -------------------------------------------------------------------------- */
-#include "solid_mechanics_model_cohesive.hh"
-
-/* -------------------------------------------------------------------------- */
-
-using namespace akantu;
-
-class MultiGrainMaterialSelector : public DefaultMaterialCohesiveSelector {
-public:
- MultiGrainMaterialSelector(const SolidMechanicsModelCohesive & model, const ID & transgranular_id, const ID & intergranular_id) :
- DefaultMaterialCohesiveSelector(model),
- transgranular_id(transgranular_id),
- intergranular_id(intergranular_id),
- model(model),
- mesh(model.getMesh()),
- mesh_facets(model.getMeshFacets()),
- spatial_dimension(model.getSpatialDimension()),
- nb_IG(0), nb_TG(0) {
- }
-
- UInt operator()(const Element & element) {
- if(mesh_facets.getSpatialDimension(element.type) == (spatial_dimension - 1)) {
- const std::vector<Element> & element_to_subelement = mesh_facets.getElementToSubelement(element.type, element.ghost_type)(element.element);
-
- const Element & el1 = element_to_subelement[0];
- const Element & el2 = element_to_subelement[1];
-
- UInt grain_id1 = mesh.getData<UInt>("tag_0", el1.type, el1.ghost_type)(el1.element);
- if(el2 != ElementNull) {
- UInt grain_id2 = mesh.getData<UInt>("tag_0", el2.type, el2.ghost_type)(el2.element);
- if (grain_id1 == grain_id2){
- //transgranular = 0 indicator
- nb_TG++;
- return model.getMaterialIndex(transgranular_id);
- } else {
- //intergranular = 1 indicator
- nb_IG++;
- return model.getMaterialIndex(intergranular_id);
- }
- } else {
- //transgranular = 0 indicator
- nb_TG++;
- return model.getMaterialIndex(transgranular_id);
- }
- } else {
- return DefaultMaterialCohesiveSelector::operator()(element);
- }
- }
-
-private:
- ID transgranular_id, intergranular_id;
- const SolidMechanicsModelCohesive & model;
- const Mesh & mesh;
- const Mesh & mesh_facets;
- UInt spatial_dimension;
-
- UInt nb_IG;
- UInt nb_TG;
-};
-
-
-/* -------------------------------------------------------------------------- */
-int main(int argc, char *argv[]) {
- initialize("material.dat", argc, argv);
-
- const UInt spatial_dimension = 2;
- const UInt max_steps = 1000;
-
- Mesh mesh(spatial_dimension);
- mesh.read("square.msh");
-
- SolidMechanicsModelCohesive model(mesh);
-
- /// model initialization
- MultiGrainMaterialSelector material_selector(model, "TG_cohesive", "IG_cohesive");
- model.setMaterialSelector(material_selector);
- model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true, false));
-
- Real time_step = model.getStableTimeStep()*0.05;
- model.setTimeStep(time_step);
- std::cout << "Time step: " << time_step << std::endl;
-
- model.assembleMassLumped();
-
- Array<Real> & position = mesh.getNodes();
- Array<Real> & velocity = model.getVelocity();
- Array<bool> & boundary = model.getBlockedDOFs();
- Array<Real> & displacement = model.getDisplacement();
-
- UInt nb_nodes = mesh.getNbNodes();
-
- /// boundary conditions
- for (UInt n = 0; n < nb_nodes; ++n) {
- if (position(n, 1) > 0.99|| position(n, 1) < -0.99)
- boundary(n, 1) = true;
-
- if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
- boundary(n, 0) = true;
- }
-
- model.updateResidual();
-
- model.setBaseName("extrinsic");
- model.addDumpFieldVector("displacement");
- model.addDumpField("velocity" );
- model.addDumpField("acceleration");
- model.addDumpField("residual" );
- model.addDumpField("stress");
- model.addDumpField("grad_u");
- model.dump();
-
- /// initial conditions
- Real loading_rate = 0.1;
- // bar_height = 2
- Real VI = loading_rate * 2* 0.5;
- for (UInt n = 0; n < nb_nodes; ++n) {
- velocity(n, 1) = loading_rate * position(n, 1);
- velocity(n, 0) = loading_rate * position(n, 0);
- }
-
- model.dump();
-
- Real dispy = 0;
-
- /// Main loop
- for (UInt s = 1; s <= max_steps; ++s) {
- dispy += VI * time_step;
- /// update displacement on extreme nodes
- for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
- if (position(n, 1) > 0.99){
- displacement(n, 1) = dispy;
- velocity(n,1) = VI;}
- if (position(n, 1) < -0.99){
- displacement(n, 1) = -dispy;
- velocity(n,1) = -VI;}
- if (position(n, 0) > 0.99){
- displacement(n, 0) = dispy;
- velocity(n,0) = VI;}
- if (position(n, 0) < -0.99){
- displacement(n, 0) = -dispy;
- velocity(n,0) = -VI;}
- }
-
- model.checkCohesiveStress();
-
- model.explicitPred();
- model.updateResidual();
- model.updateAcceleration();
- model.explicitCorr();
-
- model.dump();
- if(s % 10 == 0) {
- std::cout << "passing step " << s << "/" << max_steps << std::endl;
- }
- }
-
- Real Ed = model.getEnergy("dissipated");
-
- Real Edt = 40;
-
- std::cout << Ed << " " << Edt << std::endl;
-
- if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
- std::cout << "The dissipated energy is incorrect" << std::endl;
- finalize();
- return EXIT_FAILURE;
- }
-
- finalize();
-
- std::cout << "OK: test_cohesive_extrinsic_IG_TG was passed!" << std::endl;
- return EXIT_SUCCESS;
-}
diff --git a/examples/cohesive_element/cohesive_extrinsic_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
new file mode 100644
index 000000000..d48b8babb
--- /dev/null
+++ b/examples/cohesive_element/cohesive_extrinsic_ig_tg/CMakeLists.txt
@@ -0,0 +1,38 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
+#
+# @date creation: Mon Jan 18 2016
+#
+# @brief Configuration for cohesive_extrinsic_IG_TG
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+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
new file mode 100644
index 000000000..ac2246f35
--- /dev/null
+++ b/examples/cohesive_element/cohesive_extrinsic_ig_tg/cohesive_extrinsic_ig_tg.cc
@@ -0,0 +1,197 @@
+/**
+ * @file cohesive_extrinsic_ig_tg.cc
+ *
+ * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @date creation: Mon Jan 18 2016
+ *
+ * @brief Test for considering different cohesive properties for intergranular
+ * (IG) and
+ * transgranular (TG) fractures in extrinsic cohesive elements
+ *
+ * @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;
+
+class MultiGrainMaterialSelector : public DefaultMaterialCohesiveSelector {
+public:
+ MultiGrainMaterialSelector(const SolidMechanicsModelCohesive & model,
+ const ID & transgranular_id,
+ const ID & intergranular_id)
+ : DefaultMaterialCohesiveSelector(model),
+ transgranular_id(transgranular_id), intergranular_id(intergranular_id),
+ model(model), mesh(model.getMesh()), mesh_facets(model.getMeshFacets()),
+ spatial_dimension(model.getSpatialDimension()), nb_IG(0), nb_TG(0) {}
+
+ UInt operator()(const Element & element) {
+ if (mesh_facets.getSpatialDimension(element.type) ==
+ (spatial_dimension - 1)) {
+ const std::vector<Element> & element_to_subelement =
+ mesh_facets.getElementToSubelement(element.type, element.ghost_type)(
+ element.element);
+
+ const Element & el1 = element_to_subelement[0];
+ const Element & el2 = element_to_subelement[1];
+
+ UInt grain_id1 =
+ mesh.getData<UInt>("tag_0", el1.type, el1.ghost_type)(el1.element);
+ if (el2 != ElementNull) {
+ UInt grain_id2 =
+ mesh.getData<UInt>("tag_0", el2.type, el2.ghost_type)(el2.element);
+ if (grain_id1 == grain_id2) {
+ // transgranular = 0 indicator
+ nb_TG++;
+ return model.getMaterialIndex(transgranular_id);
+ } else {
+ // intergranular = 1 indicator
+ nb_IG++;
+ return model.getMaterialIndex(intergranular_id);
+ }
+ } else {
+ // transgranular = 0 indicator
+ nb_TG++;
+ return model.getMaterialIndex(transgranular_id);
+ }
+ } else {
+ return DefaultMaterialCohesiveSelector::operator()(element);
+ }
+ }
+
+private:
+ ID transgranular_id, intergranular_id;
+ const SolidMechanicsModelCohesive & model;
+ const Mesh & mesh;
+ const Mesh & mesh_facets;
+ UInt spatial_dimension;
+
+ UInt nb_IG;
+ UInt nb_TG;
+};
+
+/* -------------------------------------------------------------------------- */
+int main(int argc, char * argv[]) {
+ initialize("material.dat", argc, argv);
+
+ const UInt spatial_dimension = 2;
+ const UInt max_steps = 1000;
+
+ Mesh mesh(spatial_dimension);
+ mesh.read("square.msh");
+
+ SolidMechanicsModelCohesive model(mesh);
+
+ /// model initialization
+ MultiGrainMaterialSelector material_selector(model,
+ "tg_cohesive",
+ "ig_cohesive");
+ model.setMaterialSelector(material_selector);
+ model.initFull(
+ SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true, false));
+
+ Real time_step = model.getStableTimeStep() * 0.05;
+ model.setTimeStep(time_step);
+ std::cout << "Time step: " << time_step << std::endl;
+
+ model.assembleMassLumped();
+
+ Array<Real> & position = mesh.getNodes();
+ Array<Real> & velocity = model.getVelocity();
+ Array<bool> & boundary = model.getBlockedDOFs();
+ Array<Real> & displacement = model.getDisplacement();
+
+ UInt nb_nodes = mesh.getNbNodes();
+
+ /// boundary conditions
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ if (position(n, 1) > 0.99 || position(n, 1) < -0.99)
+ boundary(n, 1) = true;
+
+ if (position(n, 0) > 0.99 || position(n, 0) < -0.99)
+ boundary(n, 0) = true;
+ }
+
+ model.updateResidual();
+
+ model.setBaseName("extrinsic");
+ model.addDumpFieldVector("displacement");
+ model.addDumpField("velocity");
+ model.addDumpField("acceleration");
+ model.addDumpField("residual");
+ model.addDumpField("stress");
+ model.addDumpField("grad_u");
+ model.dump();
+
+ /// initial conditions
+ Real loading_rate = 0.1;
+ // bar_height = 2
+ Real VI = loading_rate * 2 * 0.5;
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ velocity(n, 1) = loading_rate * position(n, 1);
+ velocity(n, 0) = loading_rate * position(n, 0);
+ }
+
+ model.dump();
+
+ Real dispy = 0;
+
+ /// Main loop
+ for (UInt s = 1; s <= max_steps; ++s) {
+ dispy += VI * time_step;
+ /// update displacement on extreme nodes
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (position(n, 1) > 0.99) {
+ displacement(n, 1) = dispy;
+ velocity(n, 1) = VI;
+ }
+ if (position(n, 1) < -0.99) {
+ displacement(n, 1) = -dispy;
+ velocity(n, 1) = -VI;
+ }
+ if (position(n, 0) > 0.99) {
+ displacement(n, 0) = dispy;
+ velocity(n, 0) = VI;
+ }
+ if (position(n, 0) < -0.99) {
+ displacement(n, 0) = -dispy;
+ velocity(n, 0) = -VI;
+ }
+ }
+
+ model.checkCohesiveStress();
+
+ model.solveStep();
+
+ if (s % 10 == 0) {
+ model.dump();
+ std::cout << "passing step " << s << "/" << max_steps << std::endl;
+ }
+ }
+
+ finalize();
+ 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/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt b/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt
new file mode 100644
index 000000000..9f1038539
--- /dev/null
+++ b/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt
@@ -0,0 +1,39 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Mauro Corrado <mauro.corrado@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/>.
+#
+# @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)
+
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
new file mode 100644
index 000000000..bf38b4695
--- /dev/null
+++ b/examples/embedded/CMakeLists.txt
@@ -0,0 +1,40 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Lucas Frerot <lucas.frerot@epfl.ch>
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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(concrete_mesh concrete.geo 2 1)
+add_mesh(reinforcement_mesh reinforcement.geo 1 1)
+
+register_example(embedded embedded.cc
+ DEPENDS concrete_mesh reinforcement_mesh
+ USE_PACKAGES CGAL
+ FILES_TO_COPY material.dat)
+
diff --git a/examples/embedded/concrete.geo b/examples/embedded/concrete.geo
new file mode 100644
index 000000000..f4ad04aee
--- /dev/null
+++ b/examples/embedded/concrete.geo
@@ -0,0 +1,24 @@
+// Concrete geometry
+
+// Target mesh size
+lc = 0.3;
+
+Point(1) = {0, 0, 0, lc};
+Point(2) = {10, 0, 0, lc};
+Point(3) = {10, 1, 0, lc};
+Point(4) = {0, 1, 0, lc};
+
+Line(1) = {4, 1};
+Line(2) = {1, 2};
+Line(3) = {2, 3};
+Line(4) = {3, 4};
+
+Line Loop(1) = {4, 1, 2, 3};
+Plane Surface(1) = {1};
+
+// Boundary conditions
+Physical Line("XBlocked") = {3};
+Physical Point("YBlocked") = {1};
+Physical Line("Force") = {4};
+
+Physical Surface("concrete") = {1};
diff --git a/examples/embedded/embedded.cc b/examples/embedded/embedded.cc
new file mode 100644
index 000000000..92aee950a
--- /dev/null
+++ b/examples/embedded/embedded.cc
@@ -0,0 +1,112 @@
+/**
+ * @file embedded.cc
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @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
+ *
+ * @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 "embedded_interface_model.hh"
+/* -------------------------------------------------------------------------- */
+#include <iostream>
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char * argv[]) {
+ initialize("material.dat", argc, argv);
+
+ const UInt dim = 2;
+
+ // Loading the concrete mesh
+ Mesh mesh(dim);
+ mesh.read("concrete.msh");
+
+ // Necessary to define physical names
+ mesh.createGroupsFromMeshData<std::string>("physical_names");
+
+ // Loading the reinforcement mesh
+ Mesh reinforcement_mesh(dim, "reinforcement_mesh");
+
+ // Exception is raised because reinforcement
+ // mesh contains only segments, i.e. 1D elements
+ try {
+ reinforcement_mesh.read("reinforcement.msh");
+ } catch (debug::Exception & e) {
+ }
+
+ // Necessary to define physical names as well
+ reinforcement_mesh.createGroupsFromMeshData<std::string>("physical_names");
+
+ // Model creation
+ EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
+ model.initFull(EmbeddedInterfaceModelOptions(_static));
+
+ // Boundary conditions
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "XBlocked");
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "YBlocked");
+
+ Vector<Real> force(dim);
+ force(0) = 0.0;
+ force(1) = -1.0;
+
+ model.applyBC(BC::Neumann::FromTraction(force), "Force");
+
+ // Dumping the concrete
+ model.setBaseName("concrete");
+ model.addDumpFieldVector("displacement");
+ model.addDumpFieldVector("force");
+ model.addDumpFieldVector("residual");
+ model.addDumpFieldTensor("stress");
+
+ // Dumping the reinforcement
+ model.setBaseNameToDumper("reinforcement", "reinforcement");
+ model.addDumpFieldTensorToDumper(
+ "reinforcement", "stress_embedded"); // dumping stress in reinforcement
+
+ // Assemble global stiffness matrix
+ model.assembleStiffnessMatrix();
+
+ // Update residual
+ model.updateResidual();
+
+ // Solve
+ Real error;
+ bool converged =
+ model.solveStep<_scm_newton_raphson_tangent_not_computed, _scc_residual>(
+ 1e-6, error, 1);
+
+ if (!converged) {
+ std::cerr << "Model did not converge, error = " << error << std::endl;
+ }
+
+ // Dumping model
+ model.dump();
+ model.dump("reinforcement");
+
+ finalize();
+ return EXIT_SUCCESS;
+}
diff --git a/examples/embedded/material.dat b/examples/embedded/material.dat
new file mode 100644
index 000000000..6e8b975f2
--- /dev/null
+++ b/examples/embedded/material.dat
@@ -0,0 +1,12 @@
+material reinforcement elastic [
+ name = reinforcement
+ E = 210e9
+ area = 1e-4
+ pre_stress = 10e6
+]
+
+material elastic [
+ name = concrete
+ E = 30e9
+ nu = 0.1
+]
diff --git a/examples/embedded/reinforcement.geo b/examples/embedded/reinforcement.geo
new file mode 100644
index 000000000..914bde0fe
--- /dev/null
+++ b/examples/embedded/reinforcement.geo
@@ -0,0 +1,11 @@
+// Reinforcement geometry
+
+// Target mesh size
+lc = 1;
+
+Point(1) = {0, 0.25, 0, lc};
+Point(2) = {10, 0.25, 0, lc};
+
+Line(1) = {1, 2};
+
+Physical Line("reinforcement") = {1};
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 9ab6d1d8b..1128600c0 100644
--- a/examples/io/CMakeLists.txt
+++ b/examples/io/CMakeLists.txt
@@ -1,29 +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 a88f56a37..bfed4045a 100644
--- a/examples/io/dumper/dumpable_interface.cc
+++ b/examples/io/dumper/dumpable_interface.cc
@@ -1,179 +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);
- mesh.addDumpFieldExternal("color", colour);
+
+ 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
new file mode 100644
index 000000000..88655648e
--- /dev/null
+++ b/examples/io/parser/CMakeLists.txt
@@ -0,0 +1,40 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Fabian Barras <fabian.barras@epfl.ch>
+#
+# @date creation: Fri Sep 03 2010
+# @date last modification: Mon Jan 18 2016
+#
+# @brief Tests insertion of cohesive elements
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+add_mesh(swiss_cheese_mesh swiss_cheese.geo 2 2)
+
+register_example(example_parser
+ example_parser.cc
+ 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
new file mode 100644
index 000000000..e0ab62c1e
--- /dev/null
+++ b/examples/io/parser/example_parser.cc
@@ -0,0 +1,84 @@
+/**
+ * @file example_parser.cc
+ *
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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[]) {
+
+ // Precise in initialize the name of the text input file to parse.
+ initialize("input_file.dat", argc, argv);
+
+ // Get the user ParserSection.
+ const ParserSection & usersect = getUserParser();
+
+ // getParameterValue() allows to extract data associated to a given parameter
+ // name
+ // and cast it in the desired type set as template paramter.
+ Mesh mesh(usersect.getParameterValue<UInt>("spatial_dimension"));
+ mesh.read(usersect.getParameterValue<std::string>("mesh_file"));
+
+ // getParameter() can be used with variable declaration (destination type is
+ // explicitly known).
+ UInt max_iter = usersect.getParameter("max_nb_iterations");
+ Real precision = usersect.getParameter("precision");
+
+ // Following NumPy convention, data can be interpreted as Vector or Matrix
+ // structures.
+ Matrix<Real> eigen_stress = usersect.getParameter("stress");
+
+ SolidMechanicsModel model(mesh);
+ mesh.createGroupsFromMeshData<std::string>("physical_names");
+ model.initFull(SolidMechanicsModelOptions(_static));
+
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _x),
+ usersect.getParameterValue<std::string>("outter_crust"));
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _y),
+ usersect.getParameterValue<std::string>("outter_crust"));
+ model.applyBC(BC::Neumann::FromStress(eigen_stress),
+ usersect.getParameterValue<std::string>("inner_holes"));
+
+ model.setDirectory("./paraview");
+ model.setBaseName("swiss_cheese");
+ model.addDumpFieldVector("displacement");
+
+ model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(precision,
+ max_iter);
+
+ model.dump();
+
+ finalize();
+
+ return EXIT_SUCCESS;
+}
diff --git a/examples/io/parser/input_file.dat b/examples/io/parser/input_file.dat
new file mode 100644
index 000000000..15c8fd6fc
--- /dev/null
+++ b/examples/io/parser/input_file.dat
@@ -0,0 +1,17 @@
+material elastic [
+ name = cheese
+ rho = 1100
+ nu = 0.45
+ E = 1e5
+]
+
+user parameters [
+ spatial_dimension = 2
+ mesh_file = swiss_cheese.msh
+ inner_holes = holes
+ outter_crust = crust
+ lactostatic_p = 30e3
+ stress = [[lactostatic_p,0],[0,lactostatic_p]]
+ max_nb_iterations = 100
+ precision = 1e-9
+]
diff --git a/examples/io/parser/swiss_cheese.geo b/examples/io/parser/swiss_cheese.geo
new file mode 100644
index 000000000..a6ca2dcd3
--- /dev/null
+++ b/examples/io/parser/swiss_cheese.geo
@@ -0,0 +1,76 @@
+dx = 0.01;
+w = 0.2;
+radius = 0.015;
+
+Point(1) = {0,0,0,dx};
+Point(2) = {0,.03,0,dx};
+Point(3) = {0,-.03,0,dx};
+Point(4) = {w,0,0,dx};
+Point(5) = {w,.03,0,dx};
+Point(6) = {w,-.03,0,dx};
+Point(7) = {0,w,0,dx};
+Point(8) = {0,w,0.3,dx};
+Point(9) = {0,w,-.03,dx};
+Point(10) = {w,w,0,dx};
+Point(11) = {w,w,.03,dx};
+Point(12) = {w,w,-.03,dx};
+Point(13) = {0.5*w,0.5*w,0,dx};
+Point(14) = {0.5*w+radius,0.5*w+radius,0,dx};
+Point(15) = {0.5*w-radius,0.5*w+radius,0,dx};
+Point(16) = {0.5*w+radius,0.5*w-radius,0,dx};
+Point(17) = {0.5*w-radius,0.5*w-radius,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(8) = {8, 11};
+Line(9) = {7, 10};
+Line(10) = {9, 12};
+Line(11) = {8, 7};
+Line(12) = {11, 10};
+Line(13) = {10, 12};
+Line(14) = {7, 9};
+Line(15) = {2, 8};
+Line(16) = {1, 7};
+Line(17) = {3, 9};
+Line(18) = {5, 11};
+Line(19) = {4, 10};
+Line(20) = {6, 12};
+Circle(41) = {16, 13, 14};
+Circle(42) = {14, 13, 15};
+Circle(43) = {15, 13, 17};
+Circle(44) = {17, 13, 16};
+Translate {0.05, 0.05, 0} {
+ Duplicata { Line{44, 43, 42, 41}; }
+}
+Translate {-0.05, 0.05, 0} {
+ Duplicata { Line{44, 43, 42, 41}; }
+}
+Translate {0.05, -0.05,0} {
+ Duplicata { Line{44, 43, 42, 41}; }
+}
+Translate {-0.05,-0.05,0} {
+ Duplicata { Line{44, 43, 42, 41}; }
+}
+Delete {
+ Line{2, 15, 1, 3, 18, 8, 7, 5, 17, 14, 10, 13, 12, 20};
+}
+Delete {
+ Line{11, 6};
+}
+Delete {
+ Point{2, 3, 9, 12, 11, 5, 8, 6};
+}
+Line Loop(61) = {4, 19, -9, -16};
+Line Loop(62) = {60, 59, 58, 57};
+Line Loop(63) = {44, 41, 42, 43};
+Line Loop(64) = {55, 54, 53, 56};
+Line Loop(65) = {52, 51, 50, 49};
+Line Loop(66) = {46, 45, 48, 47};
+Plane Surface(67) = {61, 62, 63, 64, 65, 66};
+Physical Surface("cheese") = {67};
+Physical Line("holes") = {60, 57, 58, 59, 56, 53, 54, 55, 41, 44, 43, 42, 52, 51, 50, 49, 45, 48, 47, 46};
+Physical Line("crust") = {4, 19, 9, 16};
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.cc
deleted file mode 100644
index 3bddbbd03..000000000
--- a/examples/new_material/local_material_damage_inline_impl.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @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>
- *
- * @date creation: Fri Nov 26 2010
- * @date last modification: Fri May 16 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-
-/* -------------------------------------------------------------------------- */
-inline void LocalMaterialDamage::computeStressOnQuad(Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- Real & dam) {
-
- Real trace = grad_u.trace();
-
- /// \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla u_{ij} + \nabla u_{ji})
- for (UInt i = 0; i < spatial_dimension; ++i) {
- for (UInt j = 0; j < spatial_dimension; ++j) {
- sigma(i, j) = (i == j)*lambda*trace + mu*(grad_u(i, j) + grad_u(j, i));
- }
- }
-
- Real Y = 0;
- for (UInt i = 0; i < spatial_dimension; ++i) {
- for (UInt j = 0; j < spatial_dimension; ++j) {
- Y += sigma(i,j) * grad_u(i,j);
- }
- }
- Y *= 0.5;
-
- Real Fd = Y - Yd - Sd*dam;
-
- if (Fd > 0) dam = (Y - Yd) / Sd;
- dam = std::min(dam,1.);
-
- sigma *= 1-dam;
-}
-
-/* -------------------------------------------------------------------------- */
-inline void LocalMaterialDamage::computePotentialEnergyOnQuad(Matrix<Real> & grad_u,
- Matrix<Real> & sigma,
- Real & epot) {
- epot = 0.;
- for (UInt i = 0, t = 0; i < spatial_dimension; ++i)
- for (UInt j = 0; j < spatial_dimension; ++j, ++t)
- epot += sigma(i, j) * (grad_u(i, j) - (i == j));
- epot *= .5;
-}
-
-/* -------------------------------------------------------------------------- */
-inline Real LocalMaterialDamage::getCelerity(__attribute__ ((unused)) const Element & element) const {
- // Here the fastest celerity is the push wave speed
- return (std::sqrt((2*mu+lambda)/rho));
-}
diff --git a/examples/new_material/local_material_damage_inline_impl.hh b/examples/new_material/local_material_damage_inline_impl.hh
new file mode 100644
index 000000000..cc7b15170
--- /dev/null
+++ b/examples/new_material/local_material_damage_inline_impl.hh
@@ -0,0 +1,83 @@
+/**
+ * @file local_material_damage_inline_impl.cc
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------------- */
+inline void LocalMaterialDamage::computeStressOnQuad(Matrix<Real> & grad_u,
+ Matrix<Real> & sigma,
+ Real & dam) {
+
+ Real trace = grad_u.trace();
+
+ /// \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla
+ /// u_{ij} + \nabla u_{ji})
+ for (UInt i = 0; i < spatial_dimension; ++i) {
+ for (UInt j = 0; j < spatial_dimension; ++j) {
+ sigma(i, j) =
+ (i == j) * lambda * trace + mu * (grad_u(i, j) + grad_u(j, i));
+ }
+ }
+
+ Real Y = 0;
+ for (UInt i = 0; i < spatial_dimension; ++i) {
+ for (UInt j = 0; j < spatial_dimension; ++j) {
+ Y += sigma(i, j) * grad_u(i, j);
+ }
+ }
+ Y *= 0.5;
+
+ Real Fd = Y - Yd - Sd * dam;
+
+ if (Fd > 0)
+ dam = (Y - Yd) / Sd;
+ dam = std::min(dam, 1.);
+
+ sigma *= 1 - dam;
+}
+
+/* -------------------------------------------------------------------------- */
+inline void LocalMaterialDamage::computePotentialEnergyOnQuad(
+ Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & epot) {
+ epot = 0.;
+ for (UInt i = 0, t = 0; i < spatial_dimension; ++i)
+ for (UInt j = 0; j < spatial_dimension; ++j, ++t)
+ epot += sigma(i, j) * (grad_u(i, j) - (i == j));
+ epot *= .5;
+}
+
+/* -------------------------------------------------------------------------- */
+inline Real LocalMaterialDamage::getCelerity(__attribute__((unused))
+ const Element & element) const {
+ // Here the fastest celerity is the push wave speed
+ return (std::sqrt((2 * mu + lambda) / rho));
+}
diff --git a/examples/new_material/new_local_material.cc b/examples/new_material/new_local_material.cc
index 9b9bebf22..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/CMakeLists.txt b/examples/optimization/CMakeLists.txt
deleted file mode 100644
index 49241bdcf..000000000
--- a/examples/optimization/CMakeLists.txt
+++ /dev/null
@@ -1,32 +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(fn_optimize fn_optimize.cc)
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/CMakeLists.txt b/examples/parallel/CMakeLists.txt
new file mode 100644
index 000000000..4a597eb76
--- /dev/null
+++ b/examples/parallel/CMakeLists.txt
@@ -0,0 +1,39 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Jan 18 2016
+#
+# @brief configuration for a parallel example
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+#===============================================================================
+add_mesh(parallel_2d_mesh square_2d.geo 2 1)
+
+register_example(parallel_2d
+ 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/parallel_2d.cc b/examples/parallel/parallel_2d.cc
new file mode 100644
index 000000000..b9bb12eea
--- /dev/null
+++ b/examples/parallel/parallel_2d.cc
@@ -0,0 +1,118 @@
+/**
+ * @file parallel_2d.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Mon Jan 18 2016
+ *
+ * @brief Parallel example
+ *
+ * @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"
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char * argv[]) {
+ initialize("material.dat", argc, argv);
+
+ UInt spatial_dimension = 2;
+ UInt max_steps = 10000;
+ Real time_factor = 0.8;
+ Real max_disp = 1e-6;
+
+ Mesh mesh(spatial_dimension);
+
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+ Int psize = comm.getNbProc();
+ Int prank = comm.whoAmI();
+
+ akantu::MeshPartition * partition = NULL;
+ if (prank == 0) {
+ // Read the mesh
+ mesh.read("square_2d.msh");
+ partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ partition->partitionate(psize);
+ }
+
+ SolidMechanicsModel model(mesh);
+
+ /// model initialization
+ model.initParallel(partition);
+ delete partition;
+
+ model.initFull();
+
+ if (prank == 0)
+ std::cout << model.getMaterial(0) << std::endl;
+
+ model.setBaseName("multi");
+ model.addDumpFieldVector("displacement");
+ model.addDumpFieldVector("velocity");
+ model.addDumpFieldVector("acceleration");
+ model.addDumpFieldTensor("stress");
+ model.addDumpFieldTensor("grad_u");
+
+ /// boundary conditions
+ Real eps = 1e-16;
+ const Array<Real> & pos = mesh.getNodes();
+ Array<Real> & disp = model.getDisplacement();
+ Array<bool> & boun = model.getBlockedDOFs();
+
+ mesh.computeBoundingBox();
+ Real left_side = mesh.getLowerBounds()(0);
+ Real right_side = mesh.getUpperBounds()(0);
+
+ for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
+ if (std::abs(pos(i, 0) - left_side) < eps) {
+ disp(i, 0) = max_disp;
+ boun(i, 0) = true;
+ }
+
+ if (std::abs(pos(i, 0) - right_side) < eps) {
+ disp(i, 0) = -max_disp;
+ boun(i, 0) = true;
+ }
+ }
+
+ Real time_step = model.getStableTimeStep() * time_factor;
+ std::cout << "Time Step = " << time_step << "s" << std::endl;
+ model.setTimeStep(time_step);
+
+ model.dump();
+ for (UInt s = 1; s <= max_steps; ++s) {
+ model.explicitPred();
+ model.updateResidual();
+ model.updateAcceleration();
+ model.explicitCorr();
+
+ if (s % 200 == 0)
+ model.dump();
+
+ if (prank == 0 && s % 100 == 0)
+ std::cout << "passing step " << s << "/" << max_steps << std::endl;
+ }
+
+ finalize();
+ return EXIT_SUCCESS;
+}
diff --git a/examples/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/parallel_2d/CMakeLists.txt b/examples/parallel_2d/CMakeLists.txt
deleted file mode 100644
index 71460593a..000000000
--- a/examples/parallel_2d/CMakeLists.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-#===============================================================================
-# @file CMakeLists.txt
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Fri Oct 22 2010
-# @date last modification: Thu Nov 01 2012
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
-#
-# @section DESCRIPTION
-#
-#===============================================================================
-
-#===============================================================================
-add_mesh(parallel_2d_mesh square_2d.geo 2 1)
-
-register_example(parallel_2d
- parallel_2d.cc)
-add_dependencies(parallel_2d
- parallel_2d_mesh)
-
-#===============================================================================
-file(COPY material.dat DESTINATION .)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
\ No newline at end of file
diff --git a/examples/parallel_2d/parallel_2d.cc b/examples/parallel_2d/parallel_2d.cc
deleted file mode 100644
index 592196195..000000000
--- a/examples/parallel_2d/parallel_2d.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * @file parallel_2d.cc
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Fri Oct 22 2010
- * @date last modification: Tue Jun 24 2014
- *
- * @brief Parallel example
- *
- * @section LICENSE
- *
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-/* -------------------------------------------------------------------------- */
-#include <limits>
-#include <fstream>
-
-/* -------------------------------------------------------------------------- */
-#include "mesh_io.hh"
-#include "solid_mechanics_model.hh"
-/* -------------------------------------------------------------------------- */
-using namespace akantu;
-
-int main(int argc, char *argv[])
-{
- initialize("material.dat", argc, argv);
- debug::setDebugLevel(dblError);
-
- UInt spatial_dimension = 2;
- UInt max_steps = 10000;
- Real time_factor = 0.8;
- Real max_disp = 1e-6;
-
- Mesh mesh(spatial_dimension);
-
- StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- Int psize = comm.getNbProc();
- Int prank = comm.whoAmI();
-
- akantu::MeshPartition * partition = NULL;
- if(prank == 0) {
- // Read the mesh
- mesh.read("square_2d.msh");
- partition = new MeshPartitionScotch(mesh, spatial_dimension);
- partition->partitionate(psize);
- }
-
- SolidMechanicsModel model(mesh);
-
- /// model initialization
- model.initParallel(partition);
- delete partition;
-
- model.initFull();
-
- if(prank == 0) std::cout << model.getMaterial(0) << std::endl;
-
- model.setBaseName("multi");
- model.addDumpFieldVector("displacement");
- model.addDumpFieldVector("velocity");
- model.addDumpFieldVector("acceleration");
- model.addDumpFieldTensor("stress");
- model.addDumpFieldTensor("grad_u");
-
- /// boundary conditions
- Real eps = 1e-16;
- const Array<Real> & pos = mesh.getNodes();
- Array<Real> & disp = model.getDisplacement();
- Array<bool> & boun = model.getBlockedDOFs();
-
- mesh.computeBoundingBox();
- Real left_side = mesh.getLowerBounds()(0);
- Real right_side = mesh.getUpperBounds()(0);
-
- for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
- if(std::abs(pos(i,0) - left_side) < eps) {
- disp(i, 0) = max_disp;
- boun(i, 0) = true;
- }
-
- if(std::abs(pos(i,0) - right_side) < eps) {
- disp(i, 0) = -max_disp;
- boun(i, 0) = true;
- }
- }
-
- Real time_step = model.getStableTimeStep() * time_factor;
- std::cout << "Time Step = " << time_step << "s" << std::endl;
- model.setTimeStep(time_step);
-
- model.dump();
- for(UInt s = 1; s <= max_steps; ++s) {
- model.explicitPred();
- model.updateResidual();
- model.updateAcceleration();
- model.explicitCorr();
-
- if(s % 200 == 0) model.dump();
-
- if(prank == 0 && s % 100 == 0)
- std::cout << "passing step " << s << "/" << max_steps << std::endl;
- }
-
- finalize();
- return EXIT_SUCCESS;
-}
diff --git a/examples/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/examples/python/plate-hole/material.dat b/examples/python/plate-hole/material.dat
new file mode 100644
index 000000000..8f20aa1e1
--- /dev/null
+++ b/examples/python/plate-hole/material.dat
@@ -0,0 +1,6 @@
+material elastic [
+ name = steel
+ rho = 7800 # density
+ E = 2.1e11 # young's modulus
+ nu = 0.3 # poisson's 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 23fc7544d..413cd3016 160000
--- a/extra_packages/extra-materials
+++ b/extra_packages/extra-materials
@@ -1 +1 @@
-Subproject commit 23fc7544d4c021ab12dd9e2185dcf55b2101a3fb
+Subproject commit 413cd301657897dbf57f36e0250da810fd81eb7a
diff --git a/extra_packages/parallel-cohesive-element b/extra_packages/parallel-cohesive-element
index 37d232414..4e4270f3c 160000
--- a/extra_packages/parallel-cohesive-element
+++ b/extra_packages/parallel-cohesive-element
@@ -1 +1 @@
-Subproject commit 37d2324147b5740afaa65468b09631bd0561c7cd
+Subproject commit 4e4270f3c06f17adf40f0d6d27f9fcdff1ce5c03
diff --git a/extra_packages/phase-field b/extra_packages/phase-field
new file mode 160000
index 000000000..0ec10337f
--- /dev/null
+++ b/extra_packages/phase-field
@@ -0,0 +1 @@
+Subproject commit 0ec10337f210ea87aac26436b463e96c7cfd30c5
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/extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh
new file mode 100644
index 000000000..fe4298a23
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/boundary_conditions/inclined_flat_dirichlet.hh
@@ -0,0 +1,89 @@
+/**
+ * @file inclined_flat_dirichlet.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief inclined dirichlet
+ *
+ * @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_INCLINED_FLAT_DIRICHLET_HH__
+#define __AST_INCLINED_FLAT_DIRICHLET_HH__
+
+// akantu
+#include "aka_common.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class InclinedFlatDirichlet : public BC::Dirichlet::DirichletFunctor {
+
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+ 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:
+ inline void operator()(UInt node,
+ Vector<bool> & flags,
+ Vector<Real> & primal,
+ const Vector<Real> & coord) const {
+ AKANTU_DEBUG_IN();
+
+ Real dist = coord(incl_ax) - this->center_coord;
+ flags(axis) = true;
+ primal(axis) = this->value + this->tang * dist;
+
+ AKANTU_DEBUG_OUT();
+ }
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ Real value;
+ BC::Axis incl_ax;
+ Real center_coord;
+ Real tang;
+};
+
+__END_AKANTU__
+
+#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/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh
new file mode 100644
index 000000000..2528756be
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/common/parameter_reader.hh
@@ -0,0 +1,114 @@
+/**
+ * @file parameter_reader.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief for simulations to read parameters from an input file
+ *
+ * @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_PARAMETER_READER_HH__
+#define __AST_PARAMETER_READER_HH__
+
+/* -------------------------------------------------------------------------- */
+// std
+#include <set>
+#include <map>
+
+// akantu
+#include "aka_common.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class ParameterReader {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ ParameterReader();
+ virtual ~ParameterReader() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// read input file
+ void readInputFile(std::string file_name);
+
+ /// write input file
+ void writeInputFile(std::string file_name) const;
+
+ /// 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:
+ /// 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 "parameter_reader_inline_impl.cc"
+
+/// standard output stream operator
+inline std::ostream & operator <<(std::ostream & stream, const ParameterReader & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#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/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh
new file mode 100644
index 000000000..72d5842f9
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/functions/boundary_functions.hh
@@ -0,0 +1,46 @@
+/**
+ * @file boundary_functions.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief functions for boundaries
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+// akantu
+#include "aka_common.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__
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/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh
new file mode 100644
index 000000000..08ad84e41
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_coulomb.hh
@@ -0,0 +1,110 @@
+/**
+ * @file ntn_friclaw_coulomb.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief coulomb friction with \mu_s = \mu_k (constant)
+ *
+ * @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_FRICLAW_COULOMB_HH__
+#define __AST_NTN_FRICLAW_COULOMB_HH__
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_fricreg_no_regularisation.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation = NTNFricRegNoRegularisation>
+class NTNFricLawCoulomb : public Regularisation {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTNFricLawCoulomb(NTNBaseContact * contact,
+ const FrictionID & id = "coulomb",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawCoulomb() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// 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;
+
+protected:
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength();
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ // friction coefficient
+ SynchronizedArray<Real> mu;
+};
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+/// standard output stream operator
+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 /* __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/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh
new file mode 100644
index 000000000..8ba9f8643
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_cohesive.hh
@@ -0,0 +1,116 @@
+/**
+ * @file ntn_friclaw_linear_cohesive.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#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 Regularisation = NTNFricRegNoRegularisation>
+class NTNFricLawLinearCohesive : public Regularisation {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTNFricLawLinearCohesive(NTNBaseContact * contact,
+ const FrictionID & id = "linear_cohesive",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawLinearCohesive() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// 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;
+
+protected:
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength();
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ // fracture energy
+ SynchronizedArray<Real> G_c;
+
+ // peak value of cohesive law
+ SynchronizedArray<Real> tau_c;
+
+ // residual value of cohesive law (for slip > d_c)
+ SynchronizedArray<Real> tau_r;
+};
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+/// standard output stream operator
+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 /* __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/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh
new file mode 100644
index 000000000..4d1931d7b
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening.hh
@@ -0,0 +1,118 @@
+/**
+ * @file ntn_friclaw_linear_slip_weakening.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#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 Regularisation = NTNFricRegNoRegularisation>
+class NTNFricLawLinearSlipWeakening : public NTNFricLawCoulomb<Regularisation> {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTNFricLawLinearSlipWeakening(NTNBaseContact * contact,
+ const FrictionID & id = "linear_slip_weakening",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawLinearSlipWeakening() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// 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;
+
+protected:
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength();
+ /// computes the friction coefficient as a function of slip
+ virtual void computeFrictionCoefficient();
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ // static coefficient of friction
+ SynchronizedArray<Real> mu_s;
+
+ // kinetic coefficient of friction
+ SynchronizedArray<Real> mu_k;
+
+ // Dc the length over which slip weakening happens
+ SynchronizedArray<Real> d_c;
+};
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+/// standard output stream operator
+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 /* __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh
new file mode 100644
index 000000000..ce633b0be
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_laws/ntn_friclaw_linear_slip_weakening_no_healing.hh
@@ -0,0 +1,96 @@
+/**
+ * @file ntn_friclaw_linear_slip_weakening_no_healing.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#ifndef __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_NO_HEALING_HH__
+#define __AST_NTN_FRICLAW_LINEAR_SLIP_WEAKENING_NO_HEALING_HH__
+
+/* -------------------------------------------------------------------------- */
+#include "ntn_friclaw_linear_slip_weakening.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <class Regularisation = NTNFricRegNoRegularisation>
+class NTNFricLawLinearSlipWeakeningNoHealing : public NTNFricLawLinearSlipWeakening<Regularisation> {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTNFricLawLinearSlipWeakeningNoHealing(NTNBaseContact * contact,
+ const FrictionID & id = "linear_slip_weakening_no_healing",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricLawLinearSlipWeakeningNoHealing() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// 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();
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+
+};
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+/// standard output stream operator
+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 /* __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/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh
new file mode 100644
index 000000000..001f543f5
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_no_regularisation.hh
@@ -0,0 +1,140 @@
+/**
+ * @file ntn_fricreg_no_regularisation.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief regularisation that does nothing
+ *
+ * @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_FRICREG_NO_REGULARISATION_HH__
+#define __AST_NTN_FRICREG_NO_REGULARISATION_HH__
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_base_friction.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class NTNFricRegNoRegularisation : public NTNBaseFriction {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTNFricRegNoRegularisation(NTNBaseContact * contact,
+ const FrictionID & id = "no_regularisation",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricRegNoRegularisation() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// 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;
+
+protected:
+ virtual void computeFrictionalContactPressure();
+
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+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 */
+ /* ------------------------------------------------------------------------ */
+protected:
+ // contact pressure (absolut value) for computation of friction
+ SynchronizedArray<Real> frictional_contact_pressure;
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+//#include "ntn_fricreg_no_regularisation_inline_impl.cc"
+
+/// standard output stream operator
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricRegNoRegularisation & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#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/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh
new file mode 100644
index 000000000..740ac2a4e
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_rubin_ampuero.hh
@@ -0,0 +1,106 @@
+/**
+ * @file ntn_fricreg_rubin_ampuero.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief regularisation that regularizes the contact pressure
+ *
+ * @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_FRICREG_RUBIN_AMPUERO_HH__
+#define __AST_NTN_FRICREG_RUBIN_AMPUERO_HH__
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_fricreg_no_regularisation.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class NTNFricRegRubinAmpuero : public NTNFricRegNoRegularisation {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ 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);
+
+ virtual void setToSteadyState();
+
+ /// 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:
+ SynchronizedArray<Real> t_star;
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+//#include "ntn_fricreg_rubin_ampuero_inline_impl.cc"
+
+/// standard output stream operator
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricRegRubinAmpuero & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#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/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh
new file mode 100644
index 000000000..a08448822
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/friction_regularisations/ntn_fricreg_simplified_prakash_clifton.hh
@@ -0,0 +1,115 @@
+/**
+ * @file ntn_fricreg_simplified_prakash_clifton.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief regularisation that regularizes the frictional strength 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#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__
+
+/* -------------------------------------------------------------------------- */
+class NTNFricRegSimplifiedPrakashClifton : public NTNFricRegNoRegularisation {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTNFricRegSimplifiedPrakashClifton(NTNBaseContact * contact,
+ const FrictionID & id = "simplified_prakash_clifton",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFricRegSimplifiedPrakashClifton() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ 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;
+
+protected:
+ /// compute frictional strength according to friction law
+ virtual void computeFrictionalStrength();
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+protected:
+ /// get the frictional strength array
+ virtual SynchronizedArray<Real> & internalGetFrictionalStrength() {
+ return this->spc_internal;
+ };
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+private:
+ SynchronizedArray<Real> t_star;
+
+ // to get the incremental frictional strength
+ SynchronizedArray<Real> spc_internal;
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+//#include "ntn_fricreg_simplified_prakash_clifton_inline_impl.cc"
+
+/// standard output stream operator
+inline std::ostream & operator <<(std::ostream & stream,
+ const NTNFricRegSimplifiedPrakashClifton & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#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/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh
new file mode 100644
index 000000000..c7bc3a3a7
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_friction.hh
@@ -0,0 +1,106 @@
+/**
+ * @file ntn_friction.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 friction for node to 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AST_NTN_FRICTION_HH__
+#define __AST_NTN_FRICTION_HH__
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_base_friction.hh"
+#include "ntn_friclaw_coulomb.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <template<class> class FrictionLaw = NTNFricLawCoulomb,
+ class Regularisation = NTNFricRegNoRegularisation>
+class NTNFriction : public FrictionLaw<Regularisation> {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+ NTNFriction(NTNBaseContact * contact,
+ const FrictionID & id = "friction",
+ const MemoryID & memory_id = 0);
+ virtual ~NTNFriction() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// apply the friction force
+ virtual void applyFrictionTraction();
+
+ /// function to print the contain of the class
+ virtual void printself(std::ostream & stream, int indent = 0) const;
+
+protected:
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+ // virtual void addDumpFieldToDumper(const std::string & dumper_name,
+ // const std::string & field_id);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+/// standard output stream operator
+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 /* __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/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh
new file mode 100644
index 000000000..c28a1e9cd
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_initiation_function.hh
@@ -0,0 +1,48 @@
+/**
+ * @file ntn_initiation_function.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * 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 "parameter_reader.hh"
+#include "ntrf_contact.hh"
+#include "ntn_base_friction.hh"
+
+__BEGIN_AKANTU__
+
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact,
+ ParameterReader & data);
+
+NTNBaseFriction * initializeNTNFriction(NTNBaseContact * contact);
+
+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/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh
new file mode 100644
index 000000000..4f534e6e5
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_contact.hh
@@ -0,0 +1,128 @@
+/**
+ * @file ntrf_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 rigid flat 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 __AST_NTRF_CONTACT_HH__
+#define __AST_NTRF_CONTACT_HH__
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_base_contact.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+class NTRFContact : public NTNBaseContact {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NTRFContact(SolidMechanicsModel & model,
+ const ContactID & id = "contact",
+ const MemoryID & memory_id = 0);
+ virtual ~NTRFContact() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ 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;
+
+ /* ------------------------------------------------------------------------ */
+ /* 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:
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+private:
+ /// reference point for rigid flat surface
+ Vector<Real> reference_point;
+ /// outpointing normal of rigid flat surface
+ Vector<Real> normal;
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+//#include "ntrf_contact_inline_impl.cc"
+
+/// standard output stream operator
+inline std::ostream & operator <<(std::ostream & stream, const NTRFContact & _this)
+{
+ _this.printself(stream);
+ return stream;
+}
+
+__END_AKANTU__
+
+#endif /* __AST_NTRF_CONTACT_HH__ */
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh
new file mode 100644
index 000000000..31ee29506
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntrf_friction.hh
@@ -0,0 +1,100 @@
+/**
+ * @file ntrf_friction.hh
+ *
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Tue Dec 02 2014
+ * @date last modification: Fri Jan 22 2016
+ *
+ * @brief friction for node to rigid flat 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 __AST_NTRF_FRICTION_HH__
+#define __AST_NTRF_FRICTION_HH__
+
+/* -------------------------------------------------------------------------- */
+// simtools
+#include "ntn_friclaw_coulomb.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <template<class> class FrictionLaw = NTNFricLawCoulomb,
+ class Regularisation = NTNFricRegNoRegularisation>
+class NTRFFriction : public FrictionLaw<Regularisation> {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ 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;
+
+ /* ------------------------------------------------------------------------ */
+ /* Dumpable */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+
+};
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+/// 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__
+
+#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 5b973c202..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)
-
+ SYSTEM OFF third-party/cmake/blackdynamite.cmake
+ EXTRA_PACKAGE_OPTIONS FOUND BlackDynamite_FOUND)
-set(_version 1)
+set(_version master)
package_add_third_party_script_variable(BlackDynamite
BLACKDYNAMITE_VERSION "${_version}")
package_add_third_party_script_variable(BlackDynamite
- BLACKDYNAMITE_GIT "svn+ssh://lsmssrv1.epfl.ch/space/repositories/SimulPack/BlackDynamite")
+ BLACKDYNAMITE_GIT "git@lsmssrv1.epfl.ch:blackdynamite.git")
package_add_third_party_script_variable(BlackDynamite
- BLACKDYNAMITE_ARCHIVE "blackdynamite-${_version}.tar.gz")
\ No newline at end of file
+ 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 359a381d6..e43d83d33 100644
--- a/packages/blas.cmake
+++ b/packages/blas.cmake
@@ -1,72 +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)
+ EXTRA_PACKAGE_OPTIONS LANGUAGE Fortran
+ SYSTEM ON third-party/cmake/blas.cmake)
-set(AKANTU_USE_BLAS_VENDOR "Generic" CACHE STRING "Version of blas to use")
+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 af01b6668..ac61ea588 100644
--- a/packages/boost.cmake
+++ b/packages/boost.cmake
@@ -1,47 +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)
- add_flags(cxx -DBOOST_RESULT_OF_USE_TR1)
+ if(AKANTU_CORE_CXX11 AND _boost_version VERSION_LESS 1.58 AND _boost_version VERSION_GREATER 1.53)
+ package_set_compile_flags(Boost CXX -DBOOST_SPIRIT_USE_PHOENIX_V3)
else()
- remove_flags(cxx -DBOOST_RESULT_OF_USE_TR1)
+ 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 794d042f9..557f04c91 100644
--- a/packages/cgal.cmake
+++ b/packages/cgal.cmake
@@ -1,73 +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_abstract.cc
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 03ccbfc7a..334840d1d 100644
--- a/packages/cohesive_element.cmake
+++ b/packages/cohesive_element.cmake
@@ -1,122 +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
- model/solid_mechanics/materials/material_cohesive_includes.hh
-
- mesh_utils/cohesive_element_inserter.hh
- mesh_utils/cohesive_element_inserter.cc
-
fe_engine/cohesive_element.cc
- fe_engine/shape_cohesive.hh
fe_engine/cohesive_element.hh
fe_engine/fe_engine_template_cohesive.cc
-
+ fe_engine/shape_cohesive.hh
fe_engine/shape_cohesive_inline_impl.cc
-
- model/solid_mechanics/materials/material_cohesive/cohesive_internal_field_tmpl.hh
+ 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/material_cohesive_inline_impl.cc
-
- model/solid_mechanics/solid_mechanics_model_cohesive.cc
- model/solid_mechanics/solid_mechanics_model_cohesive_inline_impl.cc
- model/solid_mechanics/fragment_manager.cc
- model/solid_mechanics/materials/material_cohesive/material_cohesive.cc
- model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc
- model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc
- model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.cc
+ 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_exponential.cc
-
- model/solid_mechanics/solid_mechanics_model_cohesive.hh
- model/solid_mechanics/fragment_manager.hh
- model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
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_exponential.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_quadrature_points
- interpolate_on_quadrature_points
- compute_normals_on_control_points
+ 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 eea83e141..000000000
--- a/packages/contact.cmake
+++ /dev/null
@@ -1,82 +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
- model/model_manager.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
- model/model_manager.hh
- model/contact_manager0.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 98c369df4..cf509e7f0 100644
--- a/packages/core.cmake
+++ b/packages/core.cmake
@@ -1,485 +1,513 @@
#===============================================================================
-# @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/quadrature_point.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
- fe_engine/quadrature_point.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_type.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_pbc.cc
+ 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/dof_manager.cc
model/dof_manager.hh
model/dof_manager_inline_impl.cc
model/model_solver.cc
model/model_solver.hh
model/non_linear_solver.hh
model/non_linear_solver.cc
model/non_linear_solver_default.cc
model/non_linear_solver_default.hh
model/solver_callback.hh
model/time_step_solver.hh
model/time_step_solvers/time_step_solver.cc
model/time_step_solvers/time_step_solver_default.cc
model/time_step_solvers/time_step_solver_default.hh
model/time_step_solvers/time_step_solver_default_explicit.hh
model/non_linear_solver_callback.hh
model/time_step_solvers/time_step_solver_default_solver_callback.hh
model/integration_scheme/generalized_trapezoidal.hh
model/integration_scheme/generalized_trapezoidal.cc
model/integration_scheme/integration_scheme.hh
model/integration_scheme/integration_scheme.cc
model/integration_scheme/integration_scheme_1st_order.hh
model/integration_scheme/integration_scheme_1st_order.cc
model/integration_scheme/integration_scheme_2nd_order.hh
model/integration_scheme/integration_scheme_2nd_order.cc
model/integration_scheme/newmark-beta.hh
model/integration_scheme/newmark-beta.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/sparse_solver.cc
solver/sparse_solver.hh
solver/sparse_solver_inline_impl.cc
solver/sparse_matrix.cc
solver/sparse_matrix.hh
solver/sparse_matrix_inline_impl.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/mpi_type_wrapper.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_quadrature_points
- interpolate_on_quadrature_points
+ gradient_on_integration_points
+ interpolate_on_integration_points
interpolate
- compute_normals_on_control_points
+ 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 06b852bb6..9aaa78d18 100644
--- a/packages/core_cxx11.cmake
+++ b/packages/core_cxx11.cmake
@@ -1,82 +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/>.
#
#===============================================================================
-include(CheckCXXCompilerFlag)
-check_cxx_compiler_flag (-std=c++0x HAVE_CPP_0X)
-
-package_declare_sources(core_cxx11
- common/aka_point.hh
- common/aka_ball.cc
- common/aka_ci_string.hh
- 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
- )
-
-
-if(HAVE_CPP_0X)
- set(_cpp_11_flag "-std=c++0x")
-else()
- check_cxx_compiler_flag (-std=c++11 HAVE_CPP_11)
- if(HAVE_CPP_11)
- set(_cpp_11_flag "-std=c++11")
- else()
- set(_cpp_11_flag)
- endif()
-endif()
-
-if(_cpp_11_flag)
+if(AKANTU_CXX11_FLAGS)
package_declare(core_cxx11 ADVANCED
DESCRIPTION "C++ 11 additions for Akantu core" DEFAULT ON
- COMPILE_FLAGS "${_cpp_11_flag}")
+ 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_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 146d0a3a2..0e5058094 100644
--- a/packages/damage_non_local.cmake
+++ b/packages/damage_non_local.cmake
@@ -1,65 +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_function.cc
- model/solid_mechanics/materials/weight_function.hh
- model/solid_mechanics/materials/weight_function_tmpl.hh
+ 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
- synchronizer/grid_synchronizer.cc
- synchronizer/grid_synchronizer.hh
)
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/debug_tools.cmake b/packages/debug_tools.cmake
deleted file mode 100644
index 29f423b99..000000000
--- a/packages/debug_tools.cmake
+++ /dev/null
@@ -1,33 +0,0 @@
-#===============================================================================
-# @file debug_tools.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @brief some usefull tools to debug
-#
-# @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(debug_tools ADVANCED
- DESCRIPTION "Compiles akantu with the advanced debug tools activated (/!\ can slow down the code)")
-
-
-package_declare_sources(debug_tools
- common/aka_debug_tools.hh
- )
\ No newline at end of file
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 95f8057e3..b223dfbb5 100644
--- a/packages/embedded.cmake
+++ b/packages/embedded.cmake
@@ -1,60 +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/materials/material_embedded/material_embedded_includes.hh
-
- model/solid_mechanics/embedded_interface_intersector.hh
- model/solid_mechanics/embedded_interface_intersector.cc
- model/solid_mechanics/embedded_interface_model.hh
- model/solid_mechanics/embedded_interface_model.cc
-
+ 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_reinforcement.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 8e707a7b6..70f9e22bc 100644
--- a/packages/implicit.cmake
+++ b/packages/implicit.cmake
@@ -1,64 +1,65 @@
#===============================================================================
-# @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")
set(AKANTU_IMPLICIT_SOLVER "Mumps"
CACHE STRING "Solver activated in Akantu")
set_property(CACHE AKANTU_IMPLICIT_SOLVER PROPERTY STRINGS
Mumps
PETSc
Mumps+PETSc
)
if(AKANTU_IMPLICIT_SOLVER MATCHES "Mumps")
package_add_dependencies(implicit Mumps scotch)
else()
package_remove_dependencies(implicit Mumps scotch)
endif()
if(AKANTU_IMPLICIT_SOLVER MATCHES "PETSc")
package_add_dependencies(implicit PETSc)
else()
package_remove_dependency(implicit PETSc)
endif()
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}"
)
diff --git a/packages/iohelper.cmake b/packages/iohelper.cmake
index e38c2e638..b7f7afe67 100644
--- a/packages/iohelper.cmake
+++ b/packages/iohelper.cmake
@@ -1,71 +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_points_field.hh
+ io/dumper/dumper_quadrature_point_iterator.hh
io/dumper/dumper_variable.hh
- io/dumper/dumper_iterator_helper.hh
- io/dumper/dumper_connectivity_field.hh
io/dumper/dumper_padding_helper.hh
io/dumper/dumper_elemental_field.hh
io/dumper/dumper_element_iterator.hh
- io/dumper/dumper_material_internal_field.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 fedf0e63f..cf12e775e 100644
--- a/packages/mpi.cmake
+++ b/packages/mpi.cmake
@@ -1,61 +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")
+
+ #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})
+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 9be8caf0d..061f832b3 100644
--- a/packages/mumps.cmake
+++ b/packages/mumps.cmake
@@ -1,88 +1,106 @@
#===============================================================================
-# @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
model/dof_manager_default.hh
model/dof_manager_default.cc
model/dof_manager_default_inline_impl.cc
solver/solver_mumps.cc
solver/solver_mumps.hh
solver/sparse_matrix_aij.cc
solver/sparse_matrix_aij.hh
solver/sparse_matrix_aij_inline_impl.cc
)
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
new file mode 100644
index 000000000..158ac82cb
--- /dev/null
+++ b/packages/numpy.cmake
@@ -0,0 +1,48 @@
+#===============================================================================
+# @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, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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 c39165d30..aea47c2cf 100644
--- a/packages/petsc.cmake
+++ b/packages/petsc.cmake
@@ -1,46 +1,68 @@
#===============================================================================
# @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
model/dof_manager_petsc.hh
model/dof_manager_petsc.cc
solver/sparse_matrix_petsc.hh
solver/sparse_matrix_petsc.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
new file mode 100644
index 000000000..bb06880b2
--- /dev/null
+++ b/packages/python_interface.cmake
@@ -0,0 +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, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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 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
new file mode 100644
index 000000000..8ab88defe
--- /dev/null
+++ b/packages/pythonlibs.cmake
@@ -0,0 +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, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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_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 89b5b2b38..0ec04f04c 100644
--- a/packages/scotch.cmake
+++ b/packages/scotch.cmake
@@ -1,93 +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)
- set(CMAKE_EXTRA_INCLUDE_FILES stdio.h scotch.h)
- set(CMAKE_REQUIRED_INCLUDES ${_include_dir})
- check_type_size("SCOTCH_Num" SCOTCH_NUM)
+ 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(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}")
+ 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 9432b0094..04b727722 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -1,223 +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 ${AKA_DEFS})
+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 REQUIRED)
-find_package(PythonLibs)
+
+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
- ${PYTHON_INCLUDE_PATH}
${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 "Scannong dependencies for swig module ${_module_we}"
+ 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)
- cmake_parse_arguments(_swig_opt "" "OUTPUT_DIR" "EXTRA_FLAGS" ${ARGN})
+function(swig_generate_wrappers project _wrappers_cpp _wrappers_py)
+ 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}"
+ 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}"
- )
+ 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 in order to generate them")
+ 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 "${_wrapper}")
+ list(APPEND _swig_wrappers_py "${_extra_wrapper_bin}")
endif()
endif()
endforeach()
add_custom_target(${project}_generate_swig_wrappers DEPENDS ${_swig_wrappers})
- set(${_wrappers} ${_swig_wrappers} PARENT_SCOPE)
+ set(${_wrappers_cpp} ${_swig_wrappers} PARENT_SCOPE)
+ set(${_wrappers_py} ${_swig_wrappers_py} PARENT_SCOPE)
endfunction()
-swig_generate_wrappers(akantu AKANTU_SWIG_WRAPPERS
+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)
+ 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")
+
+ if(CMAKE_VERBOSE_MAKEFILE)
+ set(_quiet)
+ else()
+ set(_quiet --quiet)
+ endif()
-if(AKANTU_SWIG_WRAPPERS)
- add_library(_akantu MODULE ${AKANTU_SWIG_WRAPPERS})
- target_link_libraries(_akantu akantu ${PYTHON_LIBRARIES})
+ 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}'])],
+ )
+")
- set_target_properties(_akantu PROPERTIES PREFIX "")
-endif()
+ 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"
+ )
+
+ set_directory_properties(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/_akantu${CMAKE_SHARED_MODULE_SUFFIX})
+
+ # 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 6b06979c9..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] = {$1->getSize(), $1->getNbComponent()};
+ 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 a5dfeaff0..95984de36 100644
--- a/python/swig/aka_common.i
+++ b/python/swig/aka_common.i
@@ -1,71 +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;
+ int i = 0;
if (!PyList_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a list");
return NULL;
}
+
$1 = PyList_Size($input);
- $2 = (char **) malloc(($1+1)*sizeof(char *));
+ $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 ($2) free($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 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 {
- void initialize(const std::string & input_file) {
- int argc = 0;
- char ** argv = NULL;
- initialize(input_file, argc, argv);
- }
- void initialize() {
- int argc = 0;
- char ** argv = NULL;
- initialize(argc, argv);
- }
-
+#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 initializeWithArgv(input_file):
- _initializeWithArgv(input_file, _aka_sys.argv)
+ 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 596cb4bdb..7154152aa 100644
--- a/python/swig/aka_csr.i
+++ b/python/swig/aka_csr.i
@@ -1,70 +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{
+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") %{
+ %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 fb9bd0014..a6845b8da 100644
--- a/python/swig/akantu.i
+++ b/python/swig/akantu.i
@@ -1,47 +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;
- }
-}
+ 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 a6384cd75..f86a7c23d 100644
--- a/python/swig/mesh.i
+++ b/python/swig/mesh.i
@@ -1,127 +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::QuadraturePoint;
+
+using akantu::IntegrationPoint;
using akantu::Vector;
using akantu::ElementTypeMapArray;
using akantu::MatrixProxy;
using akantu::Matrix;
using akantu::UInt;
using akantu::Real;
using akantu::Array;
using akantu::SolidMechanicsModel;
%}
namespace akantu {
%ignore NewNodesEvent;
%ignore RemovedNodesEvent;
%ignore NewElementsEvent;
%ignore RemovedElementsEvent;
%ignore MeshEventHandler;
%ignore MeshEvent< UInt >;
%ignore MeshEvent< Element >;
%ignore Mesh::extractNodalCoordinatesFromPBCElement;
%ignore Mesh::getGroupDumer;
%ignore Mesh::getFacetLocalConnectivity;
%ignore Mesh::getAllFacetTypes;
}
print_self(Mesh)
%extend akantu::Mesh {
-
void resizeMesh(UInt nb_nodes, UInt nb_element, const ElementType & type) {
-
Array<Real> & nodes = const_cast<Array<Real> &>($self->getNodes());
nodes.resize(nb_nodes);
$self->addConnectivityType(type);
Array<UInt> & connectivity = const_cast<Array<UInt> &>($self->getConnectivity(type));
connectivity.resize(nb_element);
-
-
-
}
+#if defined(AKANTU_COHESIVE_ELEMENT)
+ Array<Real> & getCohesiveBarycenter(SpacialDirection dir) {
+ UInt spatial_dimension = $self->getSpatialDimension();
+ ElementTypeMapArray<Real> & barycenter =
+ $self->registerData<Real>("barycenter");
+ $self->initElementTypeMapArray(barycenter, 1, spatial_dimension, false,
+ akantu::_ek_cohesive, true);
+ akantu::ElementType type = *($self->firstType(
+ spatial_dimension, akantu::_not_ghost, akantu::_ek_cohesive));
+
+ Vector<Real> bary(spatial_dimension);
+ Array<Real> & bary_coh = barycenter(type);
+ for (UInt i = 0; i < $self->getNbElement(type); ++i) {
+ bary.clear();
+ $self->getBarycenter(i, type, bary.storage());
+ bary_coh(i) = bary(dir);
+ }
+ return bary_coh;
+ }
+#endif
}
%extend akantu::GroupManager {
void createGroupsFromStringMeshData(const std::string & dataset_name) {
$self->createGroupsFromMeshData<std::string>(dataset_name);
}
void createGroupsFromUIntMeshData(const std::string & dataset_name) {
$self->createGroupsFromMeshData<akantu::UInt>(dataset_name);
}
}
%extend akantu::NodeGroup {
-
- akantu::Array<akantu::Real> & getGroupedNodes(akantu::Array<akantu::Real, true> & surface_array, Mesh & mesh) {
-
+ akantu::Array<akantu::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 472805275..59ea5a929 100644
--- a/python/swig/model.i
+++ b/python/swig/model.i
@@ -1,41 +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 QuadraturePoint::operator=;
+ %ignore IntegrationPoint::operator=;
- %ignore FEEngine::getNbQuadraturePoints;
+ %ignore FEEngine::getNbIntegrationPoints;
%ignore FEEngine::getShapes;
%ignore FEEngine::getShapesDerivatives;
- %ignore FEEngine::getQuadraturePoints;
+ %ignore FEEngine::getIntegrationPoints;
%ignore FEEngine::getIGFEMElementTypes;
- %ignore FEEngine::interpolateOnQuadraturePoints(const Array<Real> &,ElementTypeMapArray<Real> &,const ElementTypeMapArray<UInt> *) const;
- %ignore FEEngine::interpolateOnQuadraturePoints(const Array<Real> &,ElementTypeMapArray<Real> &) const;
- %ignore FEEngine::interpolateOnQuadraturePoints(const Array<Real> &,Array<Real> &,UInt,const ElementType&,const GhostType &,const Array< UInt > &) const;
- %ignore FEEngine::interpolateOnQuadraturePoints(const Array<Real> &,Array<Real> &,UInt,const ElementType&,const GhostType &) const;
+ %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 47cf6c9d1..1c27b06f6 100644
--- a/python/swig/solid_mechanics_model.i
+++ b/python/swig/solid_mechanics_model.i
@@ -1,85 +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::initMaterials;
%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"
-%template(testConvergenceResidual) akantu::SolidMechanicsModel::testConvergence<akantu::SolveConvergenceCriteria::_scc_residual>;
-
%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) {
- $self->solveStatic<akantu::SolveConvergenceMethod::_scm_newton_raphson_tangent_not_computed, akantu::SolveConvergenceCriteria::_scc_residual>(tolerance, max_iteration);
+ 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 solveDisplCorr(bool need_factorize, bool has_profile_changed) {
+ /* ------------------------------------------------------------------------ */
+ void applyDirichletBC(PyObject * func_obj, const std::string & group_name) {
+ akantu::BC::PythonFunctorDirichlet functor(func_obj);
+ $self->applyBC(functor, group_name);
+ }
- akantu::Array<akantu::Real> & increment = $self->getIncrement();
+ /* ------------------------------------------------------------------------ */
+ void applyNeumannBC(PyObject * func_obj, const std::string & group_name) {
+ akantu::BC::PythonFunctorNeumann functor(func_obj);
+ $self->applyBC(functor, group_name);
+ }
- $self->solve<akantu::IntegrationScheme2ndOrder::_displacement_corrector>(increment, 1., need_factorize, has_profile_changed);
+ /* ------------------------------------------------------------------------ */
+ 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
new file mode 100644
index 000000000..236a756c3
--- /dev/null
+++ b/python/swig/solid_mechanics_model_cohesive.i
@@ -0,0 +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 293a8abde..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})
-add_extra_mpi_options()
-
#===========================================================================
# 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 2331d5abf..05e3d3d62 100644
--- a/src/common/aka_array.hh
+++ b/src/common/aka_array.hh
@@ -1,380 +1,390 @@
/**
* @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 scalar_iterator on the beginning of the Array considered of shape (new_size)
inline scalar_iterator begin_reinterpret(UInt new_size);
/// Get a scalar_iterator on the end of the Array considered of shape (new_size)
inline scalar_iterator end_reinterpret(UInt new_size);
/// Get a const_scalar_iterator on the beginning of the Array considered of shape (new_size)
inline const_scalar_iterator begin_reinterpret(UInt new_size) const;
/// Get a const_scalar_iterator on the end of the Array considered of shape (new_size)
inline const_scalar_iterator end_reinterpret(UInt new_size) const;
/* ------------------------------------------------------------------------ */
/// Get a vector_iterator on the beginning 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 beginning 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 beginning 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 beginning 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 beginning 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 beginning 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 beginning 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 beginning 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
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;
-
- /* ------------------------------------------------------------------------ */
- /* Accessors */
- /* ------------------------------------------------------------------------ */
-public:
- /// get the number of tuples contained in the array
- UInt getSize() const{ return this->size; };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// array of values
T * values; // /!\ very dangerous
-
};
+#include "aka_array_tmpl.hh"
+
__END_AKANTU__
#include "aka_types.hh"
__BEGIN_AKANTU__
-#include "aka_array_tmpl.hh"
-
/* -------------------------------------------------------------------------- */
/* 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 6a8495d37..cdc558fa4 100644
--- a/src/common/aka_array_tmpl.hh
+++ b/src/common/aka_array_tmpl.hh
@@ -1,1339 +1,1512 @@
/**
* @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
+ * append a tuple to the array with the value value for all components
+ * @param value the new last tuple or the array will contain nb_component copies
+ * of value
*/
template <class T, bool is_scal>
inline void Array<T, is_scal>::push_back(const T & value) {
UInt pos = size;
- resizeUnitialized(size+1);
+ 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),
+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),
+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;
+ 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 <<")");
+ << 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 size new number of tuples contained in the array */
-template <class T, bool is_scal>
-void Array<T, is_scal>::resize(UInt new_size) {
+ * @param new_size new number of tuples contained in the array */
+template <class T, bool is_scal> void Array<T, is_scal>::resize(UInt new_size) {
UInt old_size = size;
T * old_values = values;
- if(new_size < size) {
+ 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 << " | "
+ 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 << " | "
+ 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,
+ 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) {
+ 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 << ", ";
+ if (j != vect.getNbComponent() - 1)
+ stream << ", ";
}
stream << "}";
- if(i != vect.getSize() - 1) 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)) 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;
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<< ")");
+ << 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));
+ << 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<< ")");
+ << 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));
+ << 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,
+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<< ")");
+ << 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,
+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<< ")");
+ << 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,
+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<< ")");
+ << 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,
+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));
+ << 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 typename Array<T, is_scal>::scalar_iterator Array<T, is_scal>::begin() {
AKANTU_DEBUG_ASSERT(
nb_component == 1,
"this iterator cannot be used on a vector which has nb_component != 1");
return scalar_iterator(values);
}
/* -------------------------------------------------------------------------- */
/*! Get an iterator that behaves like a pointer T * that points *past* the
* last entry in the member array values
* @return a scalar_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::scalar_iterator Array<T, is_scal>::end() {
AKANTU_DEBUG_ASSERT(
nb_component == 1,
"this iterator cannot be used on a array which has nb_component != 1");
return scalar_iterator(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 typename Array<T, is_scal>::const_scalar_iterator
Array<T, is_scal>::begin() const {
AKANTU_DEBUG_ASSERT(
nb_component == 1,
"this iterator cannot be used on a array which has nb_component != 1");
return const_scalar_iterator(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 typename Array<T, is_scal>::const_scalar_iterator
Array<T, is_scal>::end() const {
AKANTU_DEBUG_ASSERT(
nb_component == 1,
"this iterator cannot be used on a array which has nb_component != 1");
return const_scalar_iterator(values + size);
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline typename Array<T, is_scal>::scalar_iterator
Array<T, is_scal>::begin_reinterpret(UInt new_size) {
AKANTU_DEBUG_ASSERT(new_size == this->nb_component * this->size,
"The new values for size ("
<< new_size
<< ") is not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return scalar_iterator(values);
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline typename Array<T, is_scal>::scalar_iterator
Array<T, is_scal>::end_reinterpret(UInt new_size) {
AKANTU_DEBUG_ASSERT(new_size == this->nb_component * this->size,
"The new values for size ("
<< new_size
<< ") is not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return scalar_iterator(values + size);
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_scalar_iterator
Array<T, is_scal>::begin_reinterpret(UInt new_size) const {
AKANTU_DEBUG_ASSERT(new_size == this->nb_component * this->size,
"The new values for size ("
<< new_size
<< ") is not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_scalar_iterator(values);
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_scalar_iterator
Array<T, is_scal>::end_reinterpret(UInt new_size) const {
AKANTU_DEBUG_ASSERT(new_size == this->nb_component * this->size,
"The new values for size ("
<< new_size
<< ") is not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_scalar_iterator(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 47aecc9c9..e6cece638 100644
--- a/src/common/aka_blas_lapack.hh
+++ b/src/common/aka_blas_lapack.hh
@@ -1,317 +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 4f78be2be..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_ci_string.hh b/src/common/aka_ci_string.hh
deleted file mode 100644
index e8ab8a528..000000000
--- a/src/common/aka_ci_string.hh
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * @file aka_ci_string.hh
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jan 04 2013
- *
- * @brief Case insensitive string
- *
- * @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_CI_STRING_HH__
-#define __AKANTU_CI_STRING_HH__
-
-__BEGIN_AKANTU__
-
-
-/// Traits class for a case insensitive string class
-struct ci_char_traits : public std::char_traits<char> {
-
- static bool eq( char c1, char c2 )
- { return toupper(c1) == toupper(c2); }
-
- static bool ne( char c1, char c2 )
- { return toupper(c1) != toupper(c2); }
-
- static bool lt( char c1, char c2 )
- { return toupper(c1) < toupper(c2); }
-
- static int compare(const char* s1, const char* s2, size_t n )
- { return memicmp( s1, s2, n ); }
-
-private:
- static int memicmp(const void *s1, const void *s2, size_t n) {
-
- if (n != 0) {
- const unsigned char *p1 = (const unsigned char *)s1, *p2 = (const unsigned char *)s2;
- do {
- if (toupper(*p1) != toupper(*p2))
- return (*p1 - *p2);
- p1++;
- p2++;
- } while (--n != 0);
- }
- return 0;
- }
-};
-
-/// case insensitive string type definition
-typedef std::basic_string<char, ci_char_traits> ci_string;
-
-
-/// provide standard output for case insensitive string
-template<typename char_type, typename traits_type, typename allocator_type>
-inline std::basic_ostream<char_type, traits_type>&
-operator<<(std::basic_ostream<char_type, traits_type>& os,
- const std::basic_string<char_type, ci_char_traits, allocator_type>& str) {
- return std::__ostream_insert(os, str.data(), str.size());
-}
-
-__END_AKANTU__
-
-#endif /* __AKANTU_CI_STRING_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 46064d603..e5a6614e4 100644
--- a/src/common/aka_common.cc
+++ b/src/common/aka_common.cc
@@ -1,137 +1,149 @@
/**
* @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 "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);
AKANTU_DEBUG_OUT();
-
}
/* -------------------------------------------------------------------------- */
void finalize() {
AKANTU_DEBUG_IN();
- if(StaticMemory::isInstantiated()) delete &(StaticMemory::getStaticMemory());
- if(StaticCommunicator::isInstantiated()) {
+ if (StaticCommunicator::isInstantiated()) {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- comm.barrier();
delete &comm;
}
+ if (StaticMemory::isInstantiated()) {
+ delete &(StaticMemory::getStaticMemory());
+ }
+
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 3451e72b7..6e8a86796 100644
--- a/src/common/aka_common.hh
+++ b/src/common/aka_common.hh
@@ -1,466 +1,521 @@
/**
* @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 DOFSupportType defines which kind of dof that can exists
enum DOFSupportType {
_dst_nodal,
_dst_generic
};
/// Type of non linear resolution available in akantu
enum NonLinearSolverType {
_nls_linear, ///< No non linear convergence loop
_nls_newton_raphson, ///< Regular Newton-Raphson
_nls_newton_raphson_modified, ///< Newton-Raphson with initial tangent
};
/// Type of time stepping solver
enum TimeStepSolverType {
_tsst_forward_euler, ///< GeneralizedTrapezoidal(0)
_tsst_forward_euler_lumped, ///< GeneralizedTrapezoidal(0) with lumped capacity
_tsst_trapezoidal_rule_1, ///< GeneralizedTrapezoidal(1/2)
_tsst_backward_euler, ///< GeneralizedTrapezoidal(1)
_tsst_central_difference, ///< NewmarkBeta(0, 1/2)
_tsst_central_difference_lumped, ///< NewmarkBeta(0, 1/2) with lumped mass
_tsst_fox_goodwin, ///< NewmarkBeta(1/6, 1/2)
_tsst_trapezoidal_rule_2, ///< NewmarkBeta(1/2, 1/2)
_tsst_linear_acceleration, ///< NewmarkBeta(1/3, 1/2)
_tsst_newmark_beta, ///< generic NewmarkBeta with user defined
/// alpha and beta
_tsst_generalized_trapezoidal, ///< generic GeneralizedTrapezoidal with user
///defined alpha
};
/// 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_solution, ///< Use solution 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
};
//! 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
};
/// 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 MatrixType {
_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_inserter, //< synchronization of global nodes id of newly inserted cohesive elements
_gst_ce_groups, //< synchronization of cohesive element insertion depending on facet groups
//--- GroupManager tags ---
_gst_gm_clusters, //< synchronization of clusters
//--- HeatTransfer tags ---
_gst_htm_capacity, //< synchronization of the nodal heat capacity
_gst_htm_temperature, //< synchronization of the nodal temperature
_gst_htm_gradient_temperature, //< synchronization of the element gradient temperature
//--- LevelSet tags ---
/// synchronization of the nodal level set value phi
_gst_htm_phi,
/// synchronization of the element gradient phi
_gst_htm_gradient_phi,
//--- Material non local ---
_gst_mnl_for_average, //< synchronization of data to average in non local material
_gst_mnl_weight, //< synchronization of data for the weight computations
+ //--- NeighborhoodSynchronization tags ---
+ _gst_nh_criterion,
//--- General tags ---
_gst_test, //< Test tag
_gst_user_1, //< tag for user simulations
_gst_user_2, //< tag for user simulations
_gst_material_id, //< synchronization of the material ids
_gst_for_dump, //< everything that needs to be synch before dump
//--- Contact & Friction ---
_gst_cf_nodal, //< synchronization of disp, velo, and current position
_gst_cf_incr, //< synchronization of increment
///--- Solver tags ---
_gst_solver_solution //< synchronization of the solution obained with the PETSc solver
};
/// standard output stream operator for SynchronizationTag
inline std::ostream & operator <<(std::ostream & stream, SynchronizationTag type);
/// @enum GhostType type of ghost
enum GhostType {
_not_ghost,
_ghost,
_casper // not used but a real cute ghost
};
/* -------------------------------------------------------------------------- */
struct GhostType_def {
typedef GhostType type;
static const type _begin_ = _not_ghost;
static const type _end_ = _casper;
};
typedef safe_enum<GhostType_def> ghost_type_t;
/// standard output stream operator for GhostType
inline std::ostream & operator <<(std::ostream & stream, GhostType type);
/// @enum SynchronizerOperation reduce operation that the synchronizer can perform
enum SynchronizerOperation {
_so_sum,
_so_min,
_so_max,
+ _so_prod,
+ _so_land,
+ _so_band,
+ _so_lor,
+ _so_bor,
+ _so_lxor,
+ _so_bxor,
+ _so_min_loc,
+ _so_max_loc,
_so_null
};
/* -------------------------------------------------------------------------- */
/* Global defines */
/* -------------------------------------------------------------------------- */
#define AKANTU_MIN_ALLOCATION 2000
#define AKANTU_INDENT " "
#define AKANTU_INCLUDE_INLINE_IMPL
/* -------------------------------------------------------------------------- */
// int 2 type construct
template <int d>
struct Int2Type {
enum { result = d };
};
// type 2 type construct
template <class T>
class Type2Type {
typedef T OriginalType;
};
/* -------------------------------------------------------------------------- */
template<class T>
struct is_scalar {
enum{ value = false };
};
#define AKANTU_SPECIFY_IS_SCALAR(type) \
template<> \
struct is_scalar<type> { \
enum { value = true }; \
}
AKANTU_SPECIFY_IS_SCALAR(Real);
AKANTU_SPECIFY_IS_SCALAR(UInt);
AKANTU_SPECIFY_IS_SCALAR(Int);
AKANTU_SPECIFY_IS_SCALAR(bool);
template < typename T1, typename T2 >
struct is_same {
enum { value = false }; // is_same represents a bool.
};
template < typename T >
struct is_same<T, T> {
enum { value = true };
};
/* -------------------------------------------------------------------------- */
#define AKANTU_SET_MACRO(name, variable, type) \
inline void set##name (type variable) { \
this->variable = variable; \
}
#define AKANTU_GET_MACRO(name, variable, type) \
inline type get##name () const { \
return variable; \
}
#define AKANTU_GET_MACRO_NOT_CONST(name, variable, type) \
inline type get##name () { \
return variable; \
}
#define AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, \
support, con) \
inline con Array<type> & \
get##name (const support & el_type, \
const GhostType & ghost_type = _not_ghost) con { \
return variable(el_type, ghost_type); \
}
#define AKANTU_GET_MACRO_BY_ELEMENT_TYPE(name, variable, type) \
AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType,)
#define AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(name, variable, type) \
AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType, const)
#define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE(name, variable, type) \
AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType,)
#define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE_CONST(name, variable, type) \
AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType, const)
/* -------------------------------------------------------------------------- */
/// initialize the static part of akantu
void initialize(int & argc, char ** & argv);
/// initialize the static part of akantu and read the global input_file
void initialize(const std::string & input_file, int & argc, char ** & argv);
/* -------------------------------------------------------------------------- */
/// finilize correctly akantu and clean the memory
void finalize ();
/* -------------------------------------------------------------------------- */
+/// Read an new input file
+void readInputFile(const std::string & input_file);
+/* -------------------------------------------------------------------------- */
+
/*
* For intel compiler annoying remark
*/
#if defined(__INTEL_COMPILER)
/// remark #981: operands are evaluated in unspecified order
#pragma warning ( disable : 981 )
/// remark #383: value copied to temporary, reference to temporary used
#pragma warning ( disable : 383 )
#endif //defined(__INTEL_COMPILER)
/* -------------------------------------------------------------------------- */
/* string manipulation */
/* -------------------------------------------------------------------------- */
inline std::string to_lower(const std::string & str);
/* -------------------------------------------------------------------------- */
inline std::string trim(const std::string & to_trim);
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/// give a string representation of the a human readable size in bit
template<typename T>
std::string printMemorySize(UInt size);
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include "aka_fwd.hh"
__BEGIN_AKANTU__
/// get access to the internal argument parser
cppargparse::ArgumentParser & getStaticArgumentParser();
/// get access to the internal input file parser
Parser & getStaticParser();
/// get access to the user part of the internal input file parser
const ParserSection & getUserParser();
__END_AKANTU__
#include "aka_common_inline_impl.cc"
+/* -------------------------------------------------------------------------- */
+
+#if defined(AKANTU_UNORDERED_MAP_IS_CXX11)
+
+__BEGIN_AKANTU_UNORDERED_MAP__
+
+#if AKANTU_INTEGER_SIZE == 4
+#define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b9
+#elif AKANTU_INTEGER_SIZE == 8
+#define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b97f4a7c13LL
+#endif
+
+/**
+ * Hashing function for pairs based on hash_combine from boost The magic number
+ * is coming from the golden number @f[\phi = \frac{1 + \sqrt5}{2}@f]
+ * @f[\frac{2^32}{\phi} = 0x9e3779b9@f]
+ * http://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine
+ * http://burtleburtle.net/bob/hash/doobs.html
+ */
+template <typename a, typename b> struct hash< std::pair<a, b> > {
+public:
+ hash() : ah(), bh() {}
+ size_t operator()(const std::pair<a, b> & p) const {
+ size_t seed = ah(p.first);
+ return bh(p.second) + AKANTU_HASH_COMBINE_MAGIC_NUMBER + (seed << 6) +
+ (seed >> 2);
+ }
+
+private:
+ const hash<a> ah;
+ const hash<b> bh;
+};
+
+__END_AKANTU_UNORDERED_MAP__
+
+#endif
+
+
#endif /* __AKANTU_COMMON_HH__ */
diff --git a/src/common/aka_common_inline_impl.cc b/src/common/aka_common_inline_impl.cc
index 309e5225e..315a2ab67 100644
--- a/src/common/aka_common_inline_impl.cc
+++ b/src/common/aka_common_inline_impl.cc
@@ -1,178 +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_ce_inserter : stream << "_gst_ce_inserter" ; 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_solution: 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 741755872..8a491ef1d 100644
--- a/src/common/aka_config.hh.in
+++ b/src/common/aka_config.hh.in
@@ -1,118 +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_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_debug_tools.hh b/src/common/aka_debug_tools.hh
deleted file mode 100644
index 487e3b943..000000000
--- a/src/common/aka_debug_tools.hh
+++ /dev/null
@@ -1,374 +0,0 @@
-/**
- * @file aka_debug_tools.hh
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date Mon Apr 8 16:33:02 2013
- *
- * @brief Different tool to help to debug (compiled only in AKANTU_DEBUG mode)
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-#if defined(AKANTU_CORE_CXX11)
-# include <functional>
-#endif
-#include <iostream>
-#include <fstream>
-
-/* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
-#include "mesh.hh"
-#include "static_communicator.hh"
-/* -------------------------------------------------------------------------- */
-#ifndef __AKANTU_AKA_DEBUG_TOOLS_HH__
-#define __AKANTU_AKA_DEBUG_TOOLS_HH__
-
-#if defined(AKANTU_DEBUG_TOOLS)
-
-#define AKANTU_DEBUG_DBT(info) AKANTU_DEBUG_("DBT", dblSecondary, info)
-
-namespace akantu {
- namespace debug {
- enum DebugModule {
- _dm_all,
- _dm_test,
- _dm_synch,
- _dm_material,
- _dm_material_non_local,
- _dm_material_damage,
- _dm_material_cohesive,
- _dm_model_cohesive,
- _dm_debug_tools,
- _dm_integrator,
- _dm_end
- };
-
- struct DebugModule_def {
- typedef DebugModule type;
- static const type _begin_ = _dm_all;
- static const type _end_ = _dm_end;
- };
-
- typedef safe_enum<DebugModule_def> debug_module_t;
-
-
- class DebugModulesHandler {
- public:
- void addModule(DebugModule mod) {
- if(mod == _dm_all)
- for(debug_module_t::iterator m(debug_module_t::begin()); m != debug_module_t::end(); ++m)
- modules.insert(*m);
- else
- modules.insert(mod);
- }
-
- void removeModule(DebugModule mod) {
- if(mod == _dm_all)
- modules.clear();
- else
- modules.erase(mod);
- }
-
- bool isActive(DebugModule mod) {
- return modules.find(mod) != modules.end();
- }
- private:
- std::set<DebugModule> modules;
- };
-
-
- /* ---------------------------------------------------------------------- */
- /* Debug Element Manager */
- /* ---------------------------------------------------------------------- */
- class DebugElementManager : public DebugModulesHandler, public MeshEventHandler {
- public:
- DebugElementManager() : barycenters("debug_element_manager", "debug_element_barycenters", 0), out(&std::cerr) {
- }
-
- void setOutStream(std::ostream & o) {
- out = &o;
- }
-
- void setMesh(const Mesh & imesh) {
- this->mesh = &imesh;
- UInt spatial_dimension = mesh->getSpatialDimension();
- mesh->initElementTypeMapArray(barycenters,
- spatial_dimension,
- _all_dimensions,
- false,
- _ek_not_defined);
-
- 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,
- _ek_not_defined);
-
- Mesh::type_iterator last_type = mesh->lastType(_all_dimensions,
- *gt,
- _ek_not_defined);
- for(; it != last_type; ++it) {
- UInt nb_element = mesh->getNbElement(*it, *gt);
- Array<Real> & barycenter = barycenters(*it, *gt);
- barycenter.resize(nb_element);
-
- Array<Real>::vector_iterator bary_it = barycenter.begin(spatial_dimension);
- for (UInt elem = 0; elem < nb_element; ++elem) {
- mesh->getBarycenter(elem, *it, bary_it->storage(), *gt);
- ++bary_it;
- }
- }
- }
- const_cast<Mesh *>(mesh)->registerEventHandler(*this);
- }
-
- public:
- void clear() { element_to_debug.clear(); }
-
- // Add element
- bool addElement(const Element & element) {
- element_to_debug.insert(element);
- if(isActive(_dm_debug_tools))
- AKANTU_DEBUG_DBT(element << ": registered in debugger");
- return true;
- }
-
- bool addElement(const Vector<Real> & pos, const ElementType & type,
- const GhostType & ghost_type, Real tolerance) {
- Array<Real> bary_arr = barycenters(type, ghost_type);
- Array<Real>::const_iterator<Vector<Real> > bary_begin = bary_arr.begin(bary_arr.getNbComponent());
- Array<Real>::const_iterator<Vector<Real> > bary_it = bary_begin;
- Array<Real>::const_iterator<Vector<Real> > bary_end = bary_arr.end(bary_arr.getNbComponent());
- bool found = false;
- for(; bary_it != bary_end && !found; ++bary_it) {
- found = pos.equal(*bary_it, tolerance);
- }
-
- if(!found) return false;
-
- UInt el_id = bary_it - bary_begin - 1;
- Element el(type, el_id, ghost_type, Mesh::getKind(type));
- return addElement(el);
- }
-
- bool addElement(const Vector<Real> & pos, Real tolerance) {
- bool finished = false;
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end() && ! finished; ++gt) {
- Mesh::type_iterator first = mesh->firstType(_all_dimensions, *gt, _ek_not_defined);
- Mesh::type_iterator last = mesh->lastType(_all_dimensions, *gt, _ek_not_defined);
- for (; first != last && !finished; ++first) {
- ElementType type = *first;
- finished = addElement(pos, type, *gt, tolerance);
- }
- }
-
- barycenters_of_elements_to_debug[pos] = tolerance;
- return finished;
- }
-
- inline void onElementsAdded(const Array<Element> & element_list,
- __attribute__((unused)) const NewElementsEvent & event) {
- Array<Element>::const_iterator<Element> it = element_list.begin();
- Array<Element>::const_iterator<Element> end = element_list.end();
-
- for (UInt el = 0; it != end; ++it, ++el) {
- const Element & elem = *it;
- Vector<Real> bary(mesh->getSpatialDimension(elem.type));
- mesh->getBarycenter(elem, bary);
- barycenters(elem.type, elem.ghost_type).push_back(bary);
- std::map<Vector<Real>, Real>::iterator bit = barycenters_of_elements_to_debug.begin();
- std::map<Vector<Real>, Real>::iterator bend = barycenters_of_elements_to_debug.end();
- for (;bit != bend; ++bit) {
- if(bary.equal(bit->first, bit->second)) addElement(elem);
- }
- }
- }
-
- inline void onElementsRemoved(const Array<Element> & element_list,
- const ElementTypeMapArray<UInt> & new_numbering,
- __attribute__((unused)) const RemovedElementsEvent & event) {
- barycenters.onElementsRemoved(new_numbering);
- Array<Element>::const_iterator<Element> it = element_list.begin();
- Array<Element>::const_iterator<Element> end = element_list.end();
-
- for (; it != end; ++it) {
- std::set<Element>::iterator el = element_to_debug.find(*it);
- if(el != element_to_debug.end()) {
- if(isActive(_dm_debug_tools))
- AKANTU_DEBUG_DBT(*it << ": unregistered from debuger");
- element_to_debug.erase(el);
- }
- }
- }
-
- public:
- // Actions
- template<typename T>
- void printData(DebugModule mod,
- const std::string & ctxt,
- const ElementTypeMapArray<T> & data) {
- if(!isActive(mod)) return;
- begin(ctxt);
- for(std::set<Element>::const_iterator it(element_to_debug.begin());
- it != element_to_debug.end(); ++it) {
- std::stringstream sout;
- try {
- const Array<T> & array = data(it->type, it->ghost_type);
- UInt nb_data_per_element
- = array.getSize() / mesh->getNbElement(it->type, it->ghost_type);
-
- sout << " -> " << *it << " " << data.getID() << "(" << nb_data_per_element << ")" << ":";
- typename Array<T>::template const_iterator< Vector<T> > data_it = array.begin(array.getNbComponent());
- data_it += it->element * nb_data_per_element;
- for (UInt d = 0; d < nb_data_per_element; ++d, ++data_it) {
- sout << std::setprecision(15) << " " << *data_it;
- }
- } catch (...) {
- sout << " -> " << *it << " has no data defined";
- }
-
- AKANTU_DEBUG_DBT(sout.str());
- }
- end(ctxt);
- }
-
- /* ---------------------------------------------------------------------- */
- template<typename T>
- void printData(DebugModule mod,
- const std::string & ctxt,
- const ElementTypeMapArray<T> & data,
- const ElementTypeMapArray<UInt> & filter) {
- if(!isActive(mod)) return;
-
- begin(ctxt);
- for(std::set<Element>::const_iterator it(element_to_debug.begin());
- it != element_to_debug.end(); ++it) {
- std::stringstream sout;
- sout << " -> " << *it << " " << data.getID() << ":";
- UInt pos = filter(it->type, it->ghost_type).find(it->element);
- if(pos == UInt(-1)) (*out) << " not in filter!";
- else {
- UInt nb_element = filter(it->type, it->ghost_type).getSize();
- const Array<T> & array = data(it->type, it->ghost_type);
- UInt nb_data_per_element = array.getSize() / nb_element;
- typename Array<T>::template const_iterator< Vector<T> > data_it = array.begin(array.getNbComponent());
- data_it += pos * nb_data_per_element;
- for (UInt d = 0; d < nb_data_per_element; ++d, ++data_it) {
- sout << " " << *data_it;
- }
- }
- AKANTU_DEBUG_DBT(sout.str());
- }
-
- end(ctxt);
- }
-
-#if defined(AKANTU_CORE_CXX11)
- void print(DebugModule mod,
- std::function< std::string(const Element &) > funct) {
- if(!isActive(mod)) return;
-
- for(std::set<Element>::const_iterator it(element_to_debug.begin());
- it != element_to_debug.end(); ++it) {
- std::string func_str = funct(*it);
- if(func_str != "")
- AKANTU_DEBUG_DBT(" -> " << *it << ": " << func_str);
- }
- }
-#endif
-
- // Actions
- void printElements(DebugModule mod, const std::string & ctxt) {
- if(!isActive(mod)) return;
-
- begin(ctxt);
- for(std::set<Element>::const_iterator it(element_to_debug.begin());
- it != element_to_debug.end(); ++it) {
- AKANTU_DEBUG_DBT(" -> " << *it);
- }
- end(ctxt);
- }
-
- void begin(const std::string & ctxt) {
- dbg_out = &debugger.getOutStream();
- debugger.setOutStream(*out);
- if(! element_to_debug.empty())
- AKANTU_DEBUG_DBT("Begin ("<< ctxt <<")");
- }
-
- void end(const std::string & ctxt) {
- if(! element_to_debug.empty())
- AKANTU_DEBUG_DBT("End ("<< ctxt <<")");
- debugger.setOutStream(*dbg_out);
- }
-
- protected:
- const Mesh * mesh;
- ElementTypeMapArray<Real> barycenters;
- std::set<Element> element_to_debug;
- std::map<Vector<Real>, Real> barycenters_of_elements_to_debug;
- std::ostream * out;
- std::ostream * dbg_out;
- };
-
- extern DebugElementManager element_manager;
- }
-
- /* ------------------------------------------------------------------------ */
- /* CSV Writer */
- /* ------------------------------------------------------------------------ */
- class csv_ofstream {
- public:
- csv_ofstream(char sep = ',') : sep(sep) {
- }
-
- ~csv_ofstream() {
- if(file.is_open()) file.close();
- }
-
- void open(std::string filename,
- std::ios_base::openmode mode = std::ios_base::out) {
- file.open(filename.c_str(), mode);
- }
-
- template<class T>
- csv_ofstream & operator<<(T t) {
- file << t << sep;
- return *this;
- }
-
- csv_ofstream & operator<<(std::ostream& ( *pf )(std::ostream&)) {
- long pos = file.tellp();
- file.seekp(pos-1);
- file << pf;
- return *this;
- }
-
- private:
- std::ofstream file;
- char sep;
- };
-
-}
-
-
-#endif
-#endif /* __AKANTU_AKA_DEBUG_TOOLS_HH__ */
diff --git a/src/common/aka_element_classes_info.hh.in b/src/common/aka_element_classes_info.hh.in
index 90623649e..91b46a765 100644
--- a/src/common/aka_element_classes_info.hh.in
+++ b/src/common/aka_element_classes_info.hh.in
@@ -1,185 +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 75651d53e..e4df6efa4 100644
--- a/src/common/aka_error.cc
+++ b/src/common/aka_error.cc
@@ -1,353 +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)) && \
+ (not defined(_WIN32))
#include <execinfo.h>
+#include <sys/wait.h>
+#endif
+
#include <cxxabi.h>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <cstring>
#include <map>
-#include <sys/wait.h>
#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
-#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 "-Wliteral-suffix"
-# endif
-#endif
-# include <mpi.h>
-#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
+#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))
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
+
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 04027e5fd..737b557b8 100644
--- a/src/common/aka_event_handler_manager.hh
+++ b/src/common/aka_event_handler_manager.hh
@@ -1,90 +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 0b4065d37..cfbfea4d6 100644
--- a/src/common/aka_extern.cc
+++ b/src/common/aka_extern.cc
@@ -1,95 +1,98 @@
/**
* @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 <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::parser_permissive = false;
+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
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/common/aka_fwd.hh b/src/common/aka_fwd.hh
index b98ace4d2..b32317956 100644
--- a/src/common/aka_fwd.hh
+++ b/src/common/aka_fwd.hh
@@ -1,73 +1,74 @@
/**
* @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;
class Mesh;
class SparseMatrix;
}
#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 65fecf371..000000000
--- a/src/common/aka_geometry.hh
+++ /dev/null
@@ -1,382 +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_floating_point<T>::value, bool>::type
-equal(T x, T y, T tol = 2*std::numeric_limits<T>::epsilon()) {
-
- T absTol = tol;
- T relTol = absTol;
-
- // here both tolerances are equal, but the code is written
- // like this so that tolerance values can be assigned indepently
- // in the future
- return std::abs(x - y) <= std::max(absTol, relTol * std::max(std::abs(x), std::abs(y)));
-}
-
-
-
-// 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 63e4abc96..c1758cf2f 100644
--- a/src/common/aka_grid_dynamic.hh
+++ b/src/common/aka_grid_dynamic.hh
@@ -1,459 +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 15bde5688..c27c7e8fb 100644
--- a/src/common/aka_math_tmpl.hh
+++ b/src/common/aka_math_tmpl.hh
@@ -1,774 +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 6127bb27f..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 */
/* -------------------------------------------------------------------------- */
-
-template<typename T>
-class Rand48Generator {
+#if not defined(_WIN32)
+template <typename T> class Rand48Generator {
/* ------------------------------------------------------------------------ */
public:
inline T operator()() { AKANTU_DEBUG_TO_IMPLEMENT(); }
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << "Rand48Generator [seed=" << seed << "]";
}
/* ------------------------------------------------------------------------ */
public:
- static void seed(long int s) { _seed = s; srand48(_seed); }
+ static 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 1767be826..7a7a48ce5 100644
--- a/src/common/aka_static_memory.cc
+++ b/src/common/aka_static_memory.cc
@@ -1,154 +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 be2a5ed80..2ad2430a5 100644
--- a/src/common/aka_types.hh
+++ b/src/common/aka_types.hh
@@ -1,1155 +1,1157 @@
/**
* @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 "aka_array.hh"
/* -------------------------------------------------------------------------- */
#include <iomanip>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_AKA_TYPES_HH__
#define __AKANTU_AKA_TYPES_HH__
__BEGIN_AKANTU__
enum NormType { L_1 = 1, L_2 = 2, L_inf = UInt(-1) };
/**
* DimHelper is a class to generalize the setup of a dim array from 3
* values. This gives a common interface in the TensorStorage class
* independently of its derived inheritance (Vector, Matrix, Tensor3)
* @tparam dim
*/
template <UInt dim> struct DimHelper {
static inline void setDims(UInt m, UInt n, UInt p, UInt dims[dim]);
};
/* -------------------------------------------------------------------------- */
template <> struct DimHelper<1> {
static inline void setDims(UInt m, __attribute__((unused)) UInt n,
__attribute__((unused)) UInt p, UInt dims[1]) {
dims[0] = m;
}
};
/* -------------------------------------------------------------------------- */
template <> struct DimHelper<2> {
static inline void setDims(UInt m, UInt n, __attribute__((unused)) UInt p,
UInt dims[2]) {
dims[0] = m;
dims[1] = n;
}
};
/* -------------------------------------------------------------------------- */
template <> struct DimHelper<3> {
static inline void setDims(UInt m, UInt n, UInt p, UInt dims[3]) {
dims[0] = m;
dims[1] = n;
dims[2] = p;
}
};
/* -------------------------------------------------------------------------- */
template <typename T, UInt ndim, class RetType> class TensorStorage;
/* -------------------------------------------------------------------------- */
/* Proxy classes */
/* -------------------------------------------------------------------------- */
/**
* @class TensorProxy aka_types.hh
* @desc 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
* @tparam T stored type
* @tparam ndim order of the tensor
* @tparam RetType real derived type
*/
template <typename T, UInt ndim, class RetType> class TensorProxy {
protected:
TensorProxy(T * data, UInt m, UInt n, UInt p) {
DimHelper<ndim>::setDims(m, n, p, this->n);
this->values = data;
}
TensorProxy(const TensorProxy & other) {
this->values = other.storage();
for (UInt i = 0; i < ndim; ++i)
this->n[i] = other.n[i];
}
inline TensorProxy(const TensorStorage<T, ndim, RetType> & other);
public:
UInt size(UInt i) const {
AKANTU_DEBUG_ASSERT(i < ndim, "This tensor has only " << ndim
<< " dimensions, not "
<< (i + 1));
return n[i];
}
inline UInt size() const {
UInt _size = 1;
for (UInt d = 0; d < ndim; ++d)
_size *= this->n[d];
return _size;
}
T * storage() const { return values; }
inline TensorProxy & operator=(const RetType & src) {
AKANTU_DEBUG_ASSERT(
src.size() == this->size(),
"You are trying to copy two tensors with different sizes");
memcpy(this->values, src.storage(), this->size() * sizeof(T));
return *this;
}
inline TensorProxy & operator=(const TensorProxy & src) {
AKANTU_DEBUG_ASSERT(
src.size() == this->size(),
"You are trying to copy two tensors with different sizes");
memcpy(this->values, src.storage(), this->size() * sizeof(T));
return *this;
}
protected:
T * values;
UInt n[ndim];
};
/* -------------------------------------------------------------------------- */
template <typename T> class VectorProxy : public TensorProxy<T, 1, Vector<T> > {
typedef TensorProxy<T, 1, Vector<T> > parent;
typedef Vector<T> type;
public:
VectorProxy(T * data, UInt n) : parent(data, n, 0, 0) {}
VectorProxy(const VectorProxy & src) : parent(src) {}
VectorProxy(const Vector<T> & src) : parent(src) {}
VectorProxy & operator=(const type & src) {
parent::operator=(src);
return *this;
}
VectorProxy & operator=(const VectorProxy & src) {
parent::operator=(src);
return *this;
}
T & operator()(UInt index) { return this->values[index]; };
const T & operator()(UInt index) const { return this->values[index]; };
};
template <typename T> class MatrixProxy : public TensorProxy<T, 2, Matrix<T> > {
typedef TensorProxy<T, 2, Matrix<T> > parent;
typedef Matrix<T> type;
public:
MatrixProxy(T * data, UInt m, UInt n) : parent(data, m, n, 0) {}
MatrixProxy(const MatrixProxy & src) : parent(src) {}
MatrixProxy(const type & src) : parent(src) {}
MatrixProxy & operator=(const type & src) {
parent::operator=(src);
return *this;
}
MatrixProxy & operator=(const MatrixProxy & src) {
parent::operator=(src);
return *this;
}
};
template <typename T>
class Tensor3Proxy : public TensorProxy<T, 3, Tensor3<T> > {
typedef TensorProxy<T, 3, Tensor3<T> > parent;
typedef Tensor3<T> type;
public:
Tensor3Proxy(T * data, UInt m, UInt n, UInt k) : parent(data, m, n, k) {}
Tensor3Proxy(const Tensor3Proxy & src) : parent(src) {}
Tensor3Proxy(const Tensor3<T> & src) : parent(src) {}
Tensor3Proxy & operator=(const type & src) {
parent::operator=(src);
return *this;
}
Tensor3Proxy & operator=(const Tensor3Proxy & src) {
parent::operator=(src);
return *this;
}
};
/* -------------------------------------------------------------------------- */
/* Tensor base class */
/* -------------------------------------------------------------------------- */
template <typename T, UInt ndim, class RetType> class TensorStorage {
public:
typedef T value_type;
protected:
template <class TensorType> void copySize(const TensorType & src) {
for (UInt d = 0; d < ndim; ++d)
this->n[d] = src.size(d);
this->_size = src.size();
}
TensorStorage() : values(NULL), wrapped(false) {
for (UInt d = 0; d < ndim; ++d)
this->n[d] = 0;
_size = 0;
}
TensorStorage(const TensorProxy<T, ndim, RetType> & proxy) {
this->copySize(proxy);
this->values = proxy.storage();
this->wrapped = true;
}
protected:
TensorStorage(const TensorStorage & src) {}
public:
TensorStorage(const TensorStorage & src, bool deep_copy)
: values(NULL), wrapped(false) {
if (deep_copy)
this->deepCopy(src);
else
this->shallowCopy(src);
}
protected:
TensorStorage(UInt m, UInt n, UInt p, const T & def) {
DimHelper<ndim>::setDims(m, n, p, this->n);
this->computeSize();
this->values = new T[this->_size];
this->set(def);
this->wrapped = false;
}
TensorStorage(T * data, UInt m, UInt n, UInt p) {
DimHelper<ndim>::setDims(m, n, p, this->n);
this->computeSize();
this->values = data;
this->wrapped = true;
}
public:
/* ------------------------------------------------------------------------ */
template <class TensorType> inline void shallowCopy(const TensorType & src) {
this->copySize(src);
if (!this->wrapped)
delete[] this->values;
this->values = src.storage();
this->wrapped = true;
}
/* ------------------------------------------------------------------------ */
template <class TensorType> inline void deepCopy(const TensorType & src) {
this->copySize(src);
if (!this->wrapped)
delete[] this->values;
this->values = new T[this->_size];
- memcpy(this->values, 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;
}
/* ------------------------------------------------------------------------ */
inline TensorStorage & operator=(const RetType & src) {
if (this != &src) {
if (this->wrapped) {
// this test is not sufficient for Tensor of order higher than 1
AKANTU_DEBUG_ASSERT(this->_size == src.size(),
"Tensors of different size");
- memcpy(this->values, src.storage(), this->_size * sizeof(T));
+ memcpy((void *)this->values, (void *)src.storage(),
+ this->_size * sizeof(T));
} else {
deepCopy(src);
}
}
return *this;
}
/* ------------------------------------------------------------------------ */
template <class R>
inline RetType & operator+=(const TensorStorage<T, ndim, R> & other) {
T * a = this->storage();
T * b = other.storage();
AKANTU_DEBUG_ASSERT(
_size == other.size(),
"The two tensors do not have the same size, they cannot be subtracted");
for (UInt i = 0; i < _size; ++i)
*(a++) += *(b++);
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
template <class R>
inline RetType & operator-=(const TensorStorage<T, ndim, R> & other) {
T * a = this->storage();
T * b = other.storage();
AKANTU_DEBUG_ASSERT(
_size == other.size(),
"The two tensors do not have the same size, they cannot be subtracted");
for (UInt i = 0; i < _size; ++i)
*(a++) -= *(b++);
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
inline RetType & operator+=(const T & x) {
T * a = this->values;
for (UInt i = 0; i < _size; ++i)
*(a++) += x;
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
inline RetType & operator-=(const T & x) {
T * a = this->values;
for (UInt i = 0; i < _size; ++i)
*(a++) -= x;
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
inline RetType & operator*=(const T & x) {
T * a = this->storage();
for (UInt i = 0; i < _size; ++i)
*(a++) *= x;
return *(static_cast<RetType *>(this));
}
/* ---------------------------------------------------------------------- */
inline RetType & operator/=(const T & x) {
T * a = this->values;
for (UInt i = 0; i < _size; ++i)
*(a++) /= x;
return *(static_cast<RetType *>(this));
}
/* ------------------------------------------------------------------------ */
T * storage() const { return values; }
UInt size() const { return _size; }
UInt size(UInt i) const {
AKANTU_DEBUG_ASSERT(i < ndim, "This tensor has only " << ndim
<< " dimensions, not "
<< (i + 1));
return n[i];
};
/* ------------------------------------------------------------------------ */
inline void clear() { memset(values, 0, _size * sizeof(T)); };
inline void set(const T & t) { std::fill_n(values, _size, t); };
template <class TensorType> inline void copy(const TensorType & other) {
AKANTU_DEBUG_ASSERT(
_size == other.size(),
"The two tensors do not have the same size, they cannot be copied");
memcpy(values, other.storage(), _size * sizeof(T));
}
bool isWrapped() const { return this->wrapped; }
protected:
friend class Array<T>;
inline void computeSize() {
_size = 1;
for (UInt d = 0; d < ndim; ++d)
_size *= this->n[d];
}
protected:
template <typename R, NormType norm_type> struct NormHelper {
template <class Ten> static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it)
_norm += std::pow(std::abs(*it), norm_type);
return std::pow(_norm, 1. / norm_type);
}
};
template <typename R> struct NormHelper<R, L_1> {
template <class Ten> static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it)
_norm += std::abs(*it);
return _norm;
}
};
template <typename R> struct NormHelper<R, L_2> {
template <class Ten> static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it)
_norm += *it * *it;
return sqrt(_norm);
}
};
template <typename R> struct NormHelper<R, L_inf> {
template <class Ten> static R norm(const Ten & ten) {
R _norm = 0.;
R * it = ten.storage();
R * end = ten.storage() + ten.size();
for (; it < end; ++it)
_norm = std::max(std::abs(*it), _norm);
return _norm;
}
};
public:
/*----------------------------------------------------------------------- */
/// "Entrywise" norm norm<L_p> @f[ \|\boldsymbol{T}\|_p = \left(
/// \sum_i^{n[0]}\sum_j^{n[1]}\sum_k^{n[2]} |T_{ijk}|^p \right)^{\frac{1}{p}}
/// @f]
template <NormType norm_type> inline T norm() const {
return NormHelper<T, norm_type>::norm(*this);
}
protected:
UInt n[ndim];
UInt _size;
T * values;
bool wrapped;
};
template <typename T, UInt ndim, class RetType>
inline TensorProxy<T, ndim, RetType>::TensorProxy(
const TensorStorage<T, ndim, RetType> & other) {
this->values = other.storage();
for (UInt i = 0; i < ndim; ++i)
this->n[i] = other.size(i);
}
/* -------------------------------------------------------------------------- */
/* Vector */
/* -------------------------------------------------------------------------- */
template <typename T> class Vector : public TensorStorage<T, 1, Vector<T> > {
typedef TensorStorage<T, 1, Vector<T> > parent;
public:
typedef typename parent::value_type value_type;
typedef VectorProxy<T> proxy;
public:
Vector() : parent() {}
Vector(UInt n, const T & def = T()) : parent(n, 0, 0, def) {}
Vector(T * data, UInt n) : parent(data, n, 0, 0) {}
Vector(const Vector & src, bool deep_copy = true) : parent(src, deep_copy) {}
Vector(const VectorProxy<T> & src) : parent(src) {}
public:
virtual ~Vector(){};
/* ------------------------------------------------------------------------ */
inline Vector & operator=(const Vector & src) {
parent::operator=(src);
return *this;
}
/* ------------------------------------------------------------------------ */
inline T & operator()(UInt i) {
AKANTU_DEBUG_ASSERT((i < this->n[0]),
"Access out of the vector! "
<< "Index (" << i
<< ") is out of the vector of size (" << this->n[0]
<< ")");
return *(this->values + i);
}
inline const T & operator()(UInt i) const {
AKANTU_DEBUG_ASSERT((i < this->n[0]),
"Access out of the vector! "
<< "Index (" << i
<< ") is out of the vector of size (" << this->n[0]
<< ")");
return *(this->values + i);
}
- inline T & operator[](UInt i) { return *(this->values + i); }
- inline const T & operator[](UInt i) const { return *(this->values + i); }
+ inline 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++);
return *this;
}
/* ------------------------------------------------------------------------ */
inline Real dot(const Vector<T> & vect) const {
return Math::vectorDot(this->values, vect.storage(), this->_size);
}
/* ------------------------------------------------------------------------ */
inline Real mean() const {
Real mean = 0;
T * a = this->storage();
for (UInt i = 0; i < this->_size; ++i)
mean += *(a++);
return mean / this->_size;
}
/* ------------------------------------------------------------------------ */
inline Vector & crossProduct(const Vector<T> & v1, const Vector<T> & v2) {
AKANTU_DEBUG_ASSERT(this->size() == 3,
"crossProduct is only defined in 3D (n=" << this->size()
<< ")");
AKANTU_DEBUG_ASSERT(
this->size() == v1.size() && this->size() == v2.size(),
"crossProduct is not a valid operation non matching size vectors");
Math::vectorProduct3(v1.storage(), v2.storage(), this->values);
return *this;
}
/* ------------------------------------------------------------------------ */
inline void solve(Matrix<T> & A, const Vector<T> & b) {
AKANTU_DEBUG_ASSERT(
this->size() == A.rows() && this->_size = A.cols(),
"The size of the solution vector mismatches the size of the matrix");
AKANTU_DEBUG_ASSERT(
this->_size == b._size,
"The rhs vector has a mismatch in size with the matrix");
Math::solve(this->_size, A.storage(), this->values, b.storage());
}
/* ------------------------------------------------------------------------ */
template <bool tr_A>
inline void mul(const Matrix<T> & A, const Vector<T> & x, Real alpha = 1.0);
/* ------------------------------------------------------------------------ */
inline Real norm() const { return parent::template norm<L_2>(); }
template <NormType nt> inline Real norm() const {
return parent::template norm<nt>();
}
/* ------------------------------------------------------------------------ */
inline void normalize() {
Real n = norm();
operator/=(n);
}
/* ------------------------------------------------------------------------ */
/// norm of (*this - x)
inline Real distance(const Vector<T> & y) const {
Real * vx = this->values;
Real * vy = y.storage();
Real sum_2 = 0;
for (UInt i = 0; i < this->_size; ++i, ++vx, ++vy)
sum_2 += (*vx - *vy) * (*vx - *vy);
return sqrt(sum_2);
}
/* ------------------------------------------------------------------------ */
inline bool equal(const Vector<T> & v,
Real tolerance = Math::getTolerance()) const {
T * a = this->storage();
T * b = v.storage();
UInt i = 0;
while (i < this->_size && (std::abs(*(a++) - *(b++)) < tolerance))
++i;
return i == this->_size;
}
/* ------------------------------------------------------------------------ */
inline short compare(const Vector<T> & v,
Real tolerance = Math::getTolerance()) const {
T * a = this->storage();
T * b = v.storage();
for (UInt i(0); i < this->_size; ++i, ++a, ++b) {
if (std::abs(*a - *b) > tolerance)
return (((*a - *b) > tolerance) ? 1 : -1);
}
return 0;
}
/* ------------------------------------------------------------------------ */
inline bool operator==(const Vector<T> & v) const { return equal(v); }
inline bool operator<(const Vector<T> & v) const { return compare(v) == -1; }
inline bool operator>(const Vector<T> & v) const { return compare(v) == 1; }
/* ------------------------------------------------------------------------ */
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << "[";
for (UInt i = 0; i < this->_size; ++i) {
if (i != 0)
stream << ", ";
stream << this->values[i];
}
stream << "]";
}
friend class ::akantu::Array<T>;
};
typedef Vector<Real> RVector;
/* ------------------------------------------------------------------------ */
template <>
inline bool Vector<UInt>::equal(const Vector<UInt> & v,
__attribute__((unused)) Real tolerance) const {
UInt * a = this->storage();
UInt * b = v.storage();
UInt i = 0;
while (i < this->_size && (*(a++) == *(b++)))
++i;
return i == this->_size;
}
/* ------------------------------------------------------------------------ */
/* Matrix */
/* ------------------------------------------------------------------------ */
template <typename T> class Matrix : public TensorStorage<T, 2, Matrix<T> > {
typedef TensorStorage<T, 2, Matrix<T> > parent;
public:
typedef typename parent::value_type value_type;
typedef MatrixProxy<T> proxy;
public:
Matrix() : parent() {}
Matrix(UInt m, UInt n, const T & def = T()) : parent(m, n, 0, def) {}
Matrix(T * data, UInt m, UInt n) : parent(data, m, n, 0) {}
Matrix(const Matrix & src, bool deep_copy = true) : parent(src, deep_copy) {}
Matrix(const MatrixProxy<T> & src) : parent(src) {}
virtual ~Matrix() {}
/* ------------------------------------------------------------------------ */
inline Matrix & operator=(const Matrix & src) {
parent::operator=(src);
return *this;
}
public:
/* ---------------------------------------------------------------------- */
UInt rows() const { return this->n[0]; }
UInt cols() const { return this->n[1]; }
/* ---------------------------------------------------------------------- */
inline T & at(UInt i, UInt j) {
AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])),
"Access out of the matrix! "
<< "Index (" << i << ", " << j
<< ") is out of the matrix of size (" << this->n[0]
<< ", " << this->n[1] << ")");
return *(this->values + i + j * this->n[0]);
}
inline const T & at(UInt i, UInt j) const {
AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])),
"Access out of the matrix! "
<< "Index (" << i << ", " << j
<< ") is out of the matrix of size (" << this->n[0]
<< ", " << this->n[1] << ")");
return *(this->values + i + j * this->n[0]);
}
/* ---------------------------------------------------------------------- */
inline T & operator()(UInt i, UInt j) { return this->at(i, j); }
inline const T & operator()(UInt i, UInt j) const { return this->at(i, j); }
/// give a line vector wrapped on the column i
inline VectorProxy<T> operator()(UInt j) {
AKANTU_DEBUG_ASSERT(j < this->n[1],
"Access out of the matrix! "
<< "You are trying to access the column vector "
<< j << " in a matrix of size (" << this->n[0]
<< ", " << this->n[1] << ")");
return VectorProxy<T>(this->values + j * this->n[0], this->n[0]);
}
inline const VectorProxy<T> operator()(UInt j) const {
AKANTU_DEBUG_ASSERT(j < this->n[1],
"Access out of the matrix! "
<< "You are trying to access the column vector "
<< j << " in a matrix of size (" << this->n[0]
<< ", " << this->n[1] << ")");
return VectorProxy<T>(this->values + j * this->n[0], this->n[0]);
}
inline T & operator[](UInt idx) { return *(this->values + idx); };
inline const T & operator[](UInt idx) const { return *(this->values + idx); };
/* ---------------------------------------------------------------------- */
inline Matrix operator*(const Matrix & B) {
Matrix C(this->rows(), B.cols());
C.mul<false, false>(*this, B);
return C;
}
/* ----------------------------------------------------------------------- */
inline Matrix & operator*=(const T & x) { return parent::operator*=(x); }
inline Matrix & operator*=(const Matrix & B) {
Matrix C(*this);
this->mul<false, false>(C, B);
return *this;
}
/* ---------------------------------------------------------------------- */
template <bool tr_A, bool tr_B>
inline void mul(const Matrix & A, const Matrix & B, T alpha = 1.0) {
UInt k = A.cols();
if (tr_A)
k = A.rows();
#ifndef AKANTU_NDEBUG
if (tr_B) {
AKANTU_DEBUG_ASSERT(k == B.cols(),
"matrices to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->cols() == B.rows(),
"matrices to multiply have no fit dimensions");
} else {
AKANTU_DEBUG_ASSERT(k == B.rows(),
"matrices to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->cols() == B.cols(),
"matrices to multiply have no fit dimensions");
}
if (tr_A) {
AKANTU_DEBUG_ASSERT(this->rows() == A.cols(),
"matrices to multiply have no fit dimensions");
} else {
AKANTU_DEBUG_ASSERT(this->rows() == A.rows(),
"matrices to multiply have no fit dimensions");
}
#endif // AKANTU_NDEBUG
Math::matMul<tr_A, tr_B>(this->rows(), this->cols(), k, alpha, A.storage(),
B.storage(), 0., this->storage());
}
/* ---------------------------------------------------------------------- */
inline void outerProduct(const Vector<T> & A, const Vector<T> & B) {
AKANTU_DEBUG_ASSERT(
A.size() == this->rows() && B.size() == this->cols(),
"A and B are not compatible with the size of the matrix");
for (UInt i = 0; i < this->rows(); ++i) {
for (UInt j = 0; j < this->cols(); ++j) {
this->values[i + j * this->rows()] += A[i] * B[j];
}
}
}
private:
class EigenSorter {
public:
EigenSorter(const Vector<T> & eigs) : eigs(eigs) {}
bool operator()(const UInt & a, const UInt & b) const {
return (eigs(a) > eigs(b));
}
private:
const Vector<T> & eigs;
};
public:
/* ---------------------------------------------------------------------- */
inline void eig(Vector<T> & eigenvalues, Matrix<T> & eigenvectors) const {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"eig is not a valid operation on a rectangular matrix");
AKANTU_DEBUG_ASSERT(eigenvalues.size() == this->cols(),
"eigenvalues should be of size " << this->cols()
<< ".");
#ifndef AKANTU_NDEBUG
if (eigenvectors.storage() != NULL)
AKANTU_DEBUG_ASSERT((eigenvectors.rows() == eigenvectors.cols()) &&
(eigenvectors.rows() == this->cols()),
"Eigenvectors needs to be a square matrix of size "
<< this->cols() << " x " << this->cols() << ".");
#endif
Matrix<T> tmp = *this;
Vector<T> tmp_eigs(eigenvalues.size());
Matrix<T> tmp_eig_vects(eigenvectors.rows(), eigenvectors.cols());
if (tmp_eig_vects.rows() == 0 || tmp_eig_vects.cols() == 0)
Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage());
else
Math::matrixEig(tmp.cols(), tmp.storage(), tmp_eigs.storage(),
tmp_eig_vects.storage());
Vector<UInt> perm(eigenvalues.size());
for (UInt i = 0; i < perm.size(); ++i)
perm(i) = i;
std::sort(perm.storage(), perm.storage() + perm.size(),
EigenSorter(tmp_eigs));
for (UInt i = 0; i < perm.size(); ++i)
eigenvalues(i) = tmp_eigs(perm(i));
if (tmp_eig_vects.rows() != 0 && tmp_eig_vects.cols() != 0)
for (UInt i = 0; i < perm.size(); ++i) {
for (UInt j = 0; j < eigenvectors.rows(); ++j) {
eigenvectors(j, i) = tmp_eig_vects(j, perm(i));
}
}
}
/* ---------------------------------------------------------------------- */
inline void eig(Vector<T> & eigenvalues) const {
Matrix<T> empty;
eig(eigenvalues, empty);
}
/* ---------------------------------------------------------------------- */
inline void eye(T alpha = 1.) {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"eye is not a valid operation on a rectangular matrix");
this->clear();
for (UInt i = 0; i < this->cols(); ++i) {
this->values[i + i * this->rows()] = alpha;
}
}
/* ---------------------------------------------------------------------- */
static inline Matrix<T> eye(UInt m, T alpha = 1.) {
Matrix<T> tmp(m, m);
tmp.eye(alpha);
return tmp;
}
/* ---------------------------------------------------------------------- */
inline T trace() const {
AKANTU_DEBUG_ASSERT(
this->cols() == this->rows(),
"trace is not a valid operation on a rectangular matrix");
T trace = 0.;
for (UInt i = 0; i < this->rows(); ++i) {
trace += this->values[i + i * this->rows()];
}
return trace;
}
/* ---------------------------------------------------------------------- */
inline Matrix transpose() const {
Matrix tmp(this->cols(), this->rows());
for (UInt i = 0; i < this->rows(); ++i) {
for (UInt j = 0; j < this->cols(); ++j) {
tmp(j, i) = operator()(i, j);
}
}
return tmp;
}
/* ---------------------------------------------------------------------- */
inline void inverse(const Matrix & A) {
AKANTU_DEBUG_ASSERT(A.cols() == A.rows(),
"inv is not a valid operation on a rectangular matrix");
AKANTU_DEBUG_ASSERT(this->cols() == A.cols(),
"the matrix should have the same size as its inverse");
if (this->cols() == 1)
*this->values = 1. / *A.storage();
else if (this->cols() == 2)
Math::inv2(A.storage(), this->values);
else if (this->cols() == 3)
Math::inv3(A.storage(), this->values);
else
Math::inv(this->cols(), A.storage(), this->values);
}
/* --------------------------------------------------------------------- */
inline T det() const {
AKANTU_DEBUG_ASSERT(this->cols() == this->rows(),
"inv is not a valid operation on a rectangular matrix");
if (this->cols() == 1)
return *(this->values);
else if (this->cols() == 2)
return Math::det2(this->values);
else if (this->cols() == 3)
return Math::det3(this->values);
else
return Math::det(this->cols(), this->values);
}
/* --------------------------------------------------------------------- */
inline T doubleDot(const Matrix<T> & other) const {
AKANTU_DEBUG_ASSERT(
this->cols() == this->rows(),
"doubleDot is not a valid operation on a rectangular matrix");
if (this->cols() == 1)
return *(this->values) * *(other.storage());
else if (this->cols() == 2)
return Math::matrixDoubleDot22(this->values, other.storage());
else if (this->cols() == 3)
return Math::matrixDoubleDot33(this->values, other.storage());
else
AKANTU_DEBUG_ERROR("doubleDot is not defined for other spatial dimensions"
<< " than 1, 2 or 3.");
return T();
}
/* ---------------------------------------------------------------------- */
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << "[";
for (UInt i = 0; i < this->n[0]; ++i) {
if (i != 0)
stream << ", ";
stream << "[";
for (UInt j = 0; j < this->n[1]; ++j) {
if (j != 0)
stream << ", ";
stream << operator()(i, j);
}
stream << "]";
}
stream << "]";
};
};
/* ------------------------------------------------------------------------ */
template <typename T>
template <bool tr_A>
inline void Vector<T>::mul(const Matrix<T> & A, const Vector<T> & x,
Real alpha) {
#ifndef AKANTU_NDEBUG
UInt n = x.size();
if (tr_A) {
AKANTU_DEBUG_ASSERT(n == A.rows(),
"matrix and vector to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->size() == A.cols(),
"matrix and vector to multiply have no fit dimensions");
} else {
AKANTU_DEBUG_ASSERT(n == A.cols(),
"matrix and vector to multiply have no fit dimensions");
AKANTU_DEBUG_ASSERT(this->size() == A.rows(),
"matrix and vector to multiply have no fit dimensions");
}
#endif
Math::matVectMul<tr_A>(A.rows(), A.cols(), alpha, A.storage(), x.storage(),
0., this->storage());
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline std::ostream & operator<<(std::ostream & stream,
const Matrix<T> & _this) {
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
template <typename T>
inline std::ostream & operator<<(std::ostream & stream,
const Vector<T> & _this) {
_this.printself(stream);
return stream;
}
/* ------------------------------------------------------------------------ */
/* Tensor3 */
/* ------------------------------------------------------------------------ */
template <typename T> class Tensor3 : public TensorStorage<T, 3, Tensor3<T> > {
typedef TensorStorage<T, 3, Tensor3<T> > parent;
public:
typedef typename parent::value_type value_type;
typedef Tensor3Proxy<T> proxy;
public:
Tensor3() : parent(){};
Tensor3(UInt m, UInt n, UInt p, const T & def = T()) : parent(m, n, p, def) {}
Tensor3(T * data, UInt m, UInt n, UInt p) : parent(data, m, n, p) {}
Tensor3(const Tensor3 & src, bool deep_copy = true)
: parent(src, deep_copy) {}
public:
/* ------------------------------------------------------------------------ */
inline Tensor3 & operator=(const Tensor3 & src) {
parent::operator=(src);
return *this;
}
/* ---------------------------------------------------------------------- */
inline T & operator()(UInt i, UInt j, UInt k) {
AKANTU_DEBUG_ASSERT(
(i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the element "
<< "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
<< this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
return *(this->values + (k * this->n[0] + i) * this->n[1] + j);
}
inline const T & operator()(UInt i, UInt j, UInt k) const {
AKANTU_DEBUG_ASSERT(
(i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the element "
<< "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
<< this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
return *(this->values + (k * this->n[0] + i) * this->n[1] + j);
}
inline MatrixProxy<T> operator()(UInt k) {
AKANTU_DEBUG_ASSERT((k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the slice " << k
<< " in a tensor3 of size (" << this->n[0] << ", "
<< this->n[1] << ", " << this->n[2] << ")");
return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
this->n[0], this->n[1]);
}
inline const MatrixProxy<T> operator()(UInt k) const {
AKANTU_DEBUG_ASSERT((k < this->n[2]),
"Access out of the tensor3! "
<< "You are trying to access the slice " << k
<< " in a tensor3 of size (" << this->n[0] << ", "
<< this->n[1] << ", " << this->n[2] << ")");
return MatrixProxy<T>(this->values + k * this->n[0] * this->n[1],
this->n[0], this->n[1]);
}
inline MatrixProxy<T> operator[](UInt k) {
- return Matrix<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]);
}
};
/* -------------------------------------------------------------------------- */
// support operations for the creation of other vectors
/* -------------------------------------------------------------------------- */
template <typename T>
Vector<T> operator*(const T & scalar, const Vector<T> & a) {
Vector<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Vector<T> operator*(const Vector<T> & a, const T & scalar) {
Vector<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Vector<T> operator/(const Vector<T> & a, const T & scalar) {
Vector<T> r(a);
r /= scalar;
return r;
}
template <typename T>
Vector<T> operator+(const Vector<T> & a, const Vector<T> & b) {
Vector<T> r(a);
r += b;
return r;
}
template <typename T>
Vector<T> operator-(const Vector<T> & a, const Vector<T> & b) {
Vector<T> r(a);
r -= b;
return r;
}
/* -------------------------------------------------------------------------- */
template <typename T>
Matrix<T> operator*(const T & scalar, const Matrix<T> & a) {
Matrix<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Matrix<T> operator*(const Matrix<T> & a, const T & scalar) {
Matrix<T> r(a);
r *= scalar;
return r;
}
template <typename T>
Matrix<T> operator/(const Matrix<T> & a, const T & scalar) {
Matrix<T> r(a);
r /= scalar;
return r;
}
template <typename T>
Matrix<T> operator+(const Matrix<T> & a, const Matrix<T> & b) {
Matrix<T> r(a);
r += b;
return r;
}
template <typename T>
Matrix<T> operator-(const Matrix<T> & a, const Matrix<T> & b) {
Matrix<T> r(a);
r -= b;
return r;
}
__END_AKANTU__
#endif /* __AKANTU_AKA_TYPES_HH__ */
diff --git a/src/common/aka_visitor.hh b/src/common/aka_visitor.hh
index 2496bb850..cd72e500d 100644
--- a/src/common/aka_visitor.hh
+++ b/src/common/aka_visitor.hh
@@ -1,175 +1,175 @@
/**
* @file aka_visitor.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
- * @date last modification: Fri Jan 04 2013
+ * @date last modification: Sun Oct 19 2014
*
* @brief Objects that support the visitor design pattern
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_VISITOR_HH__
#define __AKANTU_VISITOR_HH__
#include "aka_typelist.hh"
__BEGIN_AKANTU__
///////////////////////////////////////////////////////////////////////////
// visitor class template, adapted from the Andrei Alexandrescu's
// "Modern C++ Design"
enum Visit_type { Mutable, Immutable };
template <class T, typename R = void, Visit_type = Mutable>
class StrictVisitor;
template <class T, typename R>
class StrictVisitor<T, R, Mutable>
{
public:
typedef R ReturnType;
typedef T ParamType;
virtual ~StrictVisitor() {}
virtual ReturnType Visit(ParamType&) = 0;
};
template <class T, typename R>
class StrictVisitor<T, R, Immutable>
{
public:
typedef R ReturnType;
typedef const T ParamType;
virtual ~StrictVisitor() {}
virtual ReturnType Visit(ParamType&) = 0;
};
/// class template StrictVisitor (specialization)
template <class Head, class Tail, typename R>
class StrictVisitor<Typelist<Head, Tail>, R, Mutable>
: public StrictVisitor<Head, R, Mutable>, public StrictVisitor<Tail, R, Mutable>
{
public:
typedef R ReturnType;
typedef Head ParamType;
// using StrictVisitor<Head, R>::Visit;
// using StrictVisitor<Tail, R>::Visit;
};
template <class Head, typename R>
class StrictVisitor<Typelist<Head, Null_type>, R, Mutable> : public StrictVisitor<Head, R, Mutable>
{
public:
typedef R ReturnType;
typedef Head ParamType;
using StrictVisitor<Head, R, Mutable>::Visit;
};
template <class Head, class Tail, typename R>
class StrictVisitor<Typelist<Head, Tail>, R, Immutable>
: public StrictVisitor<Head, R, Immutable>, public StrictVisitor<Tail, R, Immutable>
{
public:
typedef R ReturnType;
typedef Head ParamType;
// using StrictVisitor<Head, R>::Visit;
// using StrictVisitor<Tail, R>::Visit;
};
template <class Head, typename R>
class StrictVisitor<Typelist<Head, Null_type>, R, Immutable> : public StrictVisitor<Head, R, Immutable>
{
public:
typedef R ReturnType;
typedef Head ParamType;
using StrictVisitor<Head, R, Immutable>::Visit;
};
////////////////////////////////////////////////////////////////////////////////
// class template NonStrictVisitor
// Implements non-strict visitation (you can implement only part of the Visit
// functions)
//
template <class R>
struct DefaultFunctor {
template <class T>
R operator()(T&) { return R(); }
};
template <class T, typename R = void, Visit_type V = Mutable, class F = DefaultFunctor<R> > class BaseVisitorImpl;
template <class Head, class Tail, typename R, Visit_type V, class F>
class BaseVisitorImpl<Typelist<Head, Tail>, R, V, F>
: public StrictVisitor<Head, R, V>, public BaseVisitorImpl<Tail, R, V, F> {
public:
typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
virtual R Visit(ParamType& h)
{ return F()(h); }
};
template <class Head, typename R, Visit_type V, class F >
class BaseVisitorImpl<Typelist<Head, Null_type>, R, V, F> : public StrictVisitor<Head, R, V>
{
public:
typedef typename StrictVisitor<Head, R, V>::ParamType ParamType;
virtual R Visit(ParamType& h)
{ return F()(h); }
};
/// Visitor
template <class R>
struct Strict {};
template <typename R, class TList, Visit_type V = Mutable, template <class> class FunctorPolicy = DefaultFunctor>
class Visitor : public BaseVisitorImpl<TList, R, V, FunctorPolicy<R> > {
public:
typedef R ReturnType;
template <class Visited>
ReturnType GenericVisit(Visited& host) {
StrictVisitor<Visited, ReturnType, V>& subObj = *this;
return subObj.Visit(host);
}
};
template <typename R, class TList, Visit_type V>
class Visitor<R, TList, V, Strict> : public StrictVisitor<TList, R, V> {
public:
typedef R ReturnType;
template <class Visited>
ReturnType GenericVisit(Visited& host) {
StrictVisitor<Visited, ReturnType, V>& subObj = *this;
return subObj.Visit(host);
}
};
__END_AKANTU__
#endif /* __AKANTU_VISITOR_HH__ */
diff --git a/src/common/aka_voigthelper.cc b/src/common/aka_voigthelper.cc
index 3905a4118..0bdc01fe3 100644
--- a/src/common/aka_voigthelper.cc
+++ b/src/common/aka_voigthelper.cc
@@ -1,67 +1,67 @@
/**
* @file aka_voigthelper.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Till Junge <till.junge@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Dec 20 2013
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Voigt indices
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "aka_common.hh"
#include "aka_voigthelper.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <> const UInt VoigtHelper<1>::mat[][1] = {{0}};
template <> const UInt VoigtHelper<2>::mat[][2] = {{0, 2},
{3, 1}};
template <> const UInt VoigtHelper<3>::mat[][3] = {{0, 5, 4},
{8, 1, 3},
{7, 6, 2}};
template <> const UInt VoigtHelper<1>::vec[][2] = {{0, 0}};
template <> const UInt VoigtHelper<2>::vec[][2] = {{0, 0},
{1, 1},
{0, 1},
{1, 0}};
template <> const UInt VoigtHelper<3>::vec[][2] = {{0, 0},
{1, 1},
{2, 2},
{1, 2},
{0, 2},
{0, 1},
{2, 1},
{2, 0},
{1, 0}};
template <> const Real VoigtHelper<1>::factors[] = {1.};
template <> const Real VoigtHelper<2>::factors[] = {1., 1., 1., 2.};
template <> const Real VoigtHelper<3>::factors[] = {1., 1., 1.,
2., 2., 2.};
__END_AKANTU__
diff --git a/src/common/aka_voigthelper.hh b/src/common/aka_voigthelper.hh
index f1bcf9405..728daa182 100644
--- a/src/common/aka_voigthelper.hh
+++ b/src/common/aka_voigthelper.hh
@@ -1,204 +1,206 @@
/**
* @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>
+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/scheme.hh b/src/contact/scheme.hh
deleted file mode 100644
index bcae584f1..000000000
--- a/src/contact/scheme.hh
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * @file scheme.hh
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date creation: Fri Jan 04 2013
- * @date last modification: Mon Sep 15 2014
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#ifndef __AKANTU_SCHEME_HH__
-#define __AKANTU_SCHEME_HH__
-
-#include "aka_common.hh"
-#include "contact_common.hh"
-#include "discretization.hh"
-#include "friction.hh"
-
-__BEGIN_AKANTU__
-
-
-
-
-__END_AKANTU__
-
-#endif /* __AKANTU_SCHEME_HH__ */
diff --git a/src/contact/search.cc b/src/contact/search.cc
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 2033731cb..36d207212 100644
--- a/src/fe_engine/cohesive_element.cc
+++ b/src/fe_engine/cohesive_element.cc
@@ -1,111 +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[] = { 3 };
+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 e545b7a8f..1219a2319 100644
--- a/src/fe_engine/cohesive_element.hh
+++ b/src/fe_engine/cohesive_element.hh
@@ -1,65 +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 Cohesive element class
+ * @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 a270726fd..4910d16e9 100644
--- a/src/fe_engine/element_class.hh
+++ b/src/fe_engine/element_class.hh
@@ -1,360 +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__
/* -------------------------------------------------------------------------- */
-template<ElementType element_type>
-struct ElementClassProperty {
+/// default element class structure
+template <ElementType element_type> struct ElementClassProperty {
static const GeometricalType geometrical_type = _gt_not_defined;
static const InterpolationType interpolation_type = _itp_not_defined;
static const ElementKind element_kind = _ek_regular;
static const UInt spatial_dimension = 0;
static const GaussIntergrationType gauss_integration_type = _git_not_defined;
static const UInt minimal_integration_order = 0;
};
-#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; \
+/// Macro to generate the element class structures for different element types
+#define AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(elem_type, geom_type, \
+ interp_type, elem_kind, sp, \
+ gauss_int_type, min_int_order) \
+ template <> struct ElementClassProperty<elem_type> { \
+ static const GeometricalType geometrical_type = geom_type; \
+ static const InterpolationType interpolation_type = interp_type; \
+ static const ElementKind element_kind = elem_kind; \
+ static const UInt spatial_dimension = sp; \
+ static const GaussIntergrationType gauss_integration_type = \
+ gauss_int_type; \
+ static const UInt minimal_integration_order = min_int_order; \
}
/* -------------------------------------------------------------------------- */
/* Geometry */
/* -------------------------------------------------------------------------- */
-template<GeometricalType geometrical_type>
-struct GeometricalShape {
+/// Default GeometricalShape structure
+template <GeometricalType geometrical_type> struct GeometricalShape {
static const GeometricalShapeType shape = _gst_point;
};
-template<GeometricalShapeType shape>
-struct GeometricalShapeContains {
+/// Templated GeometricalShape with function contains
+template <GeometricalShapeType shape> struct GeometricalShapeContains {
+ /// Check if the point (vector in 2 and 3D) at natural coordinate coor
template <class vector_type>
static inline bool contains(const vector_type & coord);
};
-#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; \
}
-
/* -------------------------------------------------------------------------- */
-template< GeometricalType geometrical_type,
- GeometricalShapeType shape = GeometricalShape<geometrical_type>::shape >
+/// Templated GeometricalElement with function getInradius
+template <GeometricalType geometrical_type,
+ GeometricalShapeType shape =
+ GeometricalShape<geometrical_type>::shape>
class GeometricalElement {
public:
/// compute the in-radius
- static inline Real getInradius(__attribute__((unused)) const Matrix<Real> & coord) {
+ 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 */
/* -------------------------------------------------------------------------- */
-template<InterpolationType interpolation_type>
-struct InterpolationPorperty {
+/// default InterpolationPorperty structure
+template <InterpolationType interpolation_type> struct InterpolationPorperty {
static const InterpolationKind kind = _itk_not_defined;
static const UInt nb_nodes_per_element = 0;
static const UInt natural_space_dimension = 0;
};
-#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"
/* -------------------------------------------------------------------------- */
-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 e0518061e..555e922f2 100644
--- a/src/fe_engine/element_class_structural.hh
+++ b/src/fe_engine/element_class_structural.hh
@@ -1,239 +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 for structural elements
+ * @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
/* -------------------------------------------------------------------------- */
-#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; \
}
-
/* -------------------------------------------------------------------------- */
-template<ElementType element_type>
-class ElementClass<element_type, _ek_structural> :
- public GeometricalElement<ElementClassProperty<element_type>::geometrical_type>,
- public InterpolationElement<ElementClassProperty<element_type>::interpolation_type> {
+/* ElementClass for structural elements */
+/* -------------------------------------------------------------------------- */
+template <ElementType element_type>
+class ElementClass<element_type, _ek_structural>
+ : public GeometricalElement<
+ ElementClassProperty<element_type>::geometrical_type>,
+ public InterpolationElement<
+ ElementClassProperty<element_type>::interpolation_type> {
protected:
- typedef GeometricalElement<ElementClassProperty<element_type>::geometrical_type> geometrical_element;
- typedef InterpolationElement<ElementClassProperty<element_type>::interpolation_type> interpolation_element;
- typedef ElementClass<ElementClassProperty<element_type>::parent_element_type> parent_element;
+ 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) {
- /// TO BE CONTINUED
+ 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 540cfafc6..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 segement [-1, 1]
+ 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 ad9beb4db..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)
- 8---|------7
+ 7---|------6
/| | /|
/ | | / |
- (-1,-1,1) 5----------6 | (1,-1,1)
+ (-1,-1,1) 4----------5 | (1,-1,1)
| | | | |
| | | | |
| | +---|-------> \xi
| | / | |
- (-1,1,-1) | 4-/-----|--3 (1,1,-1)
+ (-1,1,-1) | 3-/-----|--2 (1,1,-1)
| / / | /
|/ / |/
- 1-/--------2
+ 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 9d7fe3b15..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 3878a6662..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,196 +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
- \zeta
- ^
- (-1,1,1) | (1,1,1)
- 8---|------7
- /| | /|
- / | | / |
- (-1,-1,1) 5----------6 | (1,-1,1)
- | | | | |
- | | | | |
- | | +---|-------> \xi
- | | / | |
- (-1,1,-1) | 4-/-----|--3 (1,1,-1)
- | / / | /
- |/ / |/
- 1-/--------2
- (-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 \\
- * N43 = (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}
+ /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(0)*(1-c(2)); // N1(q)
- N(1) = 0.5*c(1)*(1-c(2)); // N2(q)
- N(2) = 0.5*(1-c(0)-c(1))*(1-c(2)); // N3(q)
- N(3) = 0.5*c(0)*(c(2)+1); // N4(q)
- N(4) = 0.5*c(1)*(c(2)+1); // N5(q)
- N(5) = 0.5*(1-c(0)-c(1))*(c(2)+1); // N6(q)
+ 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) {
- /**
- * @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) = 0.5*(1-c(2));
- dnds(0, 1) = 0 ;
- dnds(0, 2) = -0.5*(1-c(2));
- dnds(0, 3) = 0.5*(c(2)+1);
- dnds(0, 4) = 0.;
- dnds(0, 5) = -0.5*(1+c(2));
+ 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. ;
- dnds(1, 1) = 0.5*(1-c(2));
- dnds(1, 2) = -0.5*(1-c(2));
- dnds(1, 3) = 0.;
- dnds(1, 4) = 0.5*(c(2)+1);
- dnds(1, 5) = -0.5*(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.5*c(0);
- dnds(2, 1) = -0.5*c(1);
- dnds(2, 2) = -0.5*(1-c(0)-c(1));
- dnds(2, 3) = 0.5*c(0);
- dnds(2, 4) = 0.5*c(1);
- dnds(2, 5) = 0.5*(1-c(0)-c(1));
+ 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 4faceeb8e..ced8191ab 100644
--- a/src/fe_engine/fe_engine.cc
+++ b/src/fe_engine/fe_engine.cc
@@ -1,80 +1,81 @@
/**
* @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"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
FEEngine::FEEngine(Mesh & mesh, UInt element_dimension, ID id, MemoryID memory_id) :
- Memory(id, memory_id), mesh(mesh), normals_on_quad_points("normals_on_quad_points", id) {
+ Memory(id, memory_id), mesh(mesh), normals_on_integration_points("normals_on_quad_points", id) {
AKANTU_DEBUG_IN();
this->element_dimension = (element_dimension != _all_dimensions) ?
element_dimension : mesh.getSpatialDimension();
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FEEngine::init() {
}
/* -------------------------------------------------------------------------- */
FEEngine::~FEEngine() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FEEngine::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 ff64042ec..7d5bd363c 100644
--- a/src/fe_engine/fe_engine.hh
+++ b/src/fe_engine/fe_engine.hh
@@ -1,352 +1,398 @@
/**
* @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_memory.hh"
#include "mesh.hh"
#include "element_class.hh"
-#include "quadrature_point.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 on all elements of type "type"
+ /// 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 quadrature points of type "type" but don't sum over all quadrature points
- virtual void integrateOnQuadraturePoints(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 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 quadrature points
- virtual UInt getNbQuadraturePoints(const ElementType & type,
- const GhostType & ghost_type = _not_ghost) const = 0;
+ /// 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 quadrature points
- const virtual Matrix<Real> & getQuadraturePoints(const ElementType & type,
- const GhostType & ghost_type = _not_ghost) 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 gradientOnQuadraturePoints(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;
+ 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 interpolateOnQuadraturePoints(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;
+ 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 interpolateOnQuadraturePoints(const Array<Real> & u,
- ElementTypeMapArray<Real> & uq,
- const ElementTypeMapArray<UInt> * filter_elements = NULL) const = 0;
+ 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;
- virtual
- void interpolate(const Vector<Real> & real_coords,
+ /// 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 control points
- virtual void computeNormalsOnControlPoints(const GhostType & ghost_type = _not_ghost) = 0;
+ /// pre-compute normals on integration points
+ virtual void computeNormalsOnIntegrationPoints(const GhostType & ghost_type = _not_ghost) = 0;
- /// pre-compute normals on control points
- virtual void computeNormalsOnControlPoints(__attribute__((unused)) const Array<Real> & field,
+ /// 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 control points
- virtual void computeNormalsOnControlPoints(__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 {
+ /// 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
// 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,
__attribute__ ((unused)) Array<Real> & lumped,
__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 quadrature points
- AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NormalsOnQuadPoints, normals_on_quad_points, Real);
+ /// 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 quadrature points
- ElementTypeMapArray<Real> normals_on_quad_points;
+ /// 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 QuadraturePoint & _this)
+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 c52d9780a..0e2bad4fa 100644
--- a/src/fe_engine/fe_engine_inline_impl.cc
+++ b/src/fe_engine/fe_engine_inline_impl.cc
@@ -1,192 +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 0b183ed7e..8f04c13ca 100644
--- a/src/fe_engine/fe_engine_template.hh
+++ b/src/fe_engine/fe_engine_template.hh
@@ -1,292 +1,356 @@
/**
* @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 Jul 07 2014
+ * @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"
/* -------------------------------------------------------------------------- */
namespace akantu {
class DOFManager;
}
__BEGIN_AKANTU__
-template <ElementKind k> class AssembleLumpedTemplateHelper;
-template <ElementKind k> class AssembleFieldMatrixHelper;
+template <ElementKind k> struct AssembleLumpedTemplateHelper;
+template <ElementKind k> struct AssembleFieldMatrixHelper;
/* -------------------------------------------------------------------------- */
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind = _ek_regular>
class FEEngineTemplate : public FEEngine {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef I<kind> Integ;
typedef S<kind> Shape;
FEEngineTemplate(Mesh & mesh, UInt spatial_dimension = _all_dimensions,
ID id = "fem", MemoryID memory_id = 0);
virtual ~FEEngineTemplate();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// pre-compute all the shape functions, their derivatives and the jacobians
void initShapeFunctions(const GhostType & ghost_type = _not_ghost);
void initShapeFunctions(const Array<Real> & nodes,
const GhostType & ghost_type = _not_ghost);
/* ------------------------------------------------------------------------ */
/* Integration method bridges */
/* ------------------------------------------------------------------------ */
/// integrate f for all elements of type "type"
void integrate(const Array<Real> & f, Array<Real> & intf,
UInt nb_degree_of_freedom, const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// integrate a scalar value on all elements of type "type"
Real integrate(const Array<Real> & f, const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// integrate one element scalar value on all elements of type "type"
virtual Real integrate(const Vector<Real> & f, const ElementType & type,
UInt index,
const GhostType & ghost_type = _not_ghost) const;
- /// integrate partially around a quadrature point (@f$ intf_q = f_q * J_q *
+ /// integrate partially around an integration point (@f$ intf_q = f_q * J_q *
/// w_q @f$)
- void integrateOnQuadraturePoints(
+ void integrateOnIntegrationPoints(
const Array<Real> & f, Array<Real> & intf, UInt nb_degree_of_freedom,
const ElementType & type, const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// interpolate on a phyiscal point inside an element
void interpolate(const Vector<Real> & real_coords,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated, const Element & element) const;
- /// get the number of quadrature points
- UInt getNbQuadraturePoints(const ElementType & type,
- const GhostType & ghost_type = _not_ghost) const;
+ /// get the number of integration points
+ UInt getNbIntegrationPoints(const ElementType & type,
+ const GhostType & ghost_type = _not_ghost) const;
/// get shapes precomputed
const Array<Real> & getShapes(const ElementType & type,
const GhostType & ghost_type = _not_ghost,
UInt id = 0) const;
/// get the derivatives of shapes
const Array<Real> &
getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type = _not_ghost,
UInt id = 0) const;
- /// get quadrature points
+ /// get integration points
const inline Matrix<Real> &
- getQuadraturePoints(const ElementType & type,
- const GhostType & ghost_type = _not_ghost) const;
+ getIntegrationPoints(const ElementType & type,
+ const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Shape method bridges */
/* ------------------------------------------------------------------------ */
- /// compute the gradient of a nodal field on the quadrature points
- void gradientOnQuadraturePoints(
+ /// compute the gradient of a nodal field on the integration points
+ void gradientOnIntegrationPoints(
const Array<Real> & u, Array<Real> & nablauq,
const UInt nb_degree_of_freedom, const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
- /// interpolate a nodal field on the quadrature points
- void interpolateOnQuadraturePoints(
+ /// 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 quadrature points given a by_element_type
- void interpolateOnQuadraturePoints(
+ /// interpolate a nodal field on the integration points given a
+ /// by_element_type
+ void interpolateOnIntegrationPoints(
const Array<Real> & u, ElementTypeMapArray<Real> & uq,
const ElementTypeMapArray<UInt> * filter_elements = NULL) const;
+ /// compute the position of integration points given by an element_type_map
+ /// from nodes position
+ inline void computeIntegrationPointsCoordinates(
+ ElementTypeMapArray<Real> & quadrature_points_coordinates,
+ const ElementTypeMapArray<UInt> * filter_elements = NULL) const;
+
+ /// compute the position of integration points from nodes position
+ inline void computeIntegrationPointsCoordinates(
+ Array<Real> & quadrature_points_coordinates, const ElementType & type,
+ const GhostType & ghost_type = _not_ghost,
+ const Array<UInt> & filter_elements = empty_filter) const;
+
+ /// interpolate field at given position (interpolation_points) from given
+ /// values of this field at integration points (field)
+ inline void interpolateElementalFieldFromIntegrationPoints(
+ const ElementTypeMapArray<Real> & field,
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates,
+ ElementTypeMapArray<Real> & result, const GhostType ghost_type,
+ const ElementTypeMapArray<UInt> * element_filter) const;
+
+ /// Interpolate field at given position from given values of this field at
+ /// integration points (field)
+ /// using matrices precomputed with
+ /// initElementalFieldInterplationFromIntegrationPoints
+ inline void interpolateElementalFieldFromIntegrationPoints(
+ const ElementTypeMapArray<Real> & field,
+ const ElementTypeMapArray<Real> &
+ interpolation_points_coordinates_matrices,
+ const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
+ ElementTypeMapArray<Real> & result, const GhostType ghost_type,
+ const ElementTypeMapArray<UInt> * element_filter) const;
+
+ /// Build pre-computed matrices for interpolation of field form integration
+ /// points at other given positions (interpolation_points)
+ inline void initElementalFieldInterpolationFromIntegrationPoints(
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates,
+ ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
+ ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
+ const ElementTypeMapArray<UInt> * element_filter = NULL) const;
+
/// find natural coords from real coords provided an element
void inverseMap(const Vector<Real> & real_coords, UInt element,
const ElementType & type, Vector<Real> & natural_coords,
const GhostType & ghost_type = _not_ghost) const;
/// return true if the coordinates provided are inside the element, false
/// otherwise
inline bool contains(const Vector<Real> & real_coords, UInt element,
const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
/// compute the shape on a provided point
inline void computeShapes(const Vector<Real> & real_coords, UInt element,
const ElementType & type, Vector<Real> & shapes,
const GhostType & ghost_type = _not_ghost) const;
/// compute the shape derivatives on a provided point
inline void
computeShapeDerivatives(const Vector<Real> & real__coords, UInt element,
const ElementType & type,
Matrix<Real> & shape_derivatives,
const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Other methods */
/* ------------------------------------------------------------------------ */
- /// pre-compute normals on control points
- void computeNormalsOnControlPoints(const GhostType & ghost_type = _not_ghost);
- void computeNormalsOnControlPoints(const Array<Real> & field,
- const GhostType & ghost_type = _not_ghost);
- void computeNormalsOnControlPoints(
+ /// 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 computeNormalsOnControlPoints(const Array<Real> & field,
- Array<Real> & normal,
- const GhostType & ghost_type) const;
+ void computeNormalsOnIntegrationPoints(const Array<Real> & field,
+ Array<Real> & normal,
+ const GhostType & ghost_type) const;
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
+ /// assemble a field as a lumped matrix (ex. rho in lumped mass)
void assembleFieldLumped(const Array<Real> & field, Array<Real> & lumped,
DOFManager & dof_manager, 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, const ID & matrix_id,
const ID & dof_id, DOFManager & dof_manager,
ElementType type,
- const GhostType & ghost_type = _not_ghost) const;
+ const GhostType & ghost_type) 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;
- 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,
+ /// compute shapes function in a matrix for structural elements
+ 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 class AssembleLumpedTemplateHelper<kind>;
- friend class AssembleFieldMatrixHelper<kind>;
+ 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, Array<Real> & lumped,
DOFManager & dof_manager,
const GhostType & ghost_type) const;
/// @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j
/// dV = \int \rho \varphi_i dV @f$
template <ElementType type>
void assembleLumpedRowSum(const Array<Real> & field, Array<Real> & lumped,
DOFManager & dof_manager,
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,
Array<Real> & lumped,
DOFManager & dof_manager,
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, const ID & matrix_id,
const ID & dof_id, DOFManager & dof_manager,
const GhostType & ghost_type) const;
#ifdef AKANTU_STRUCTURAL_MECHANICS
+
+ /// assemble a field as a matrix for structural elements (ex. rho to mass
+ /// matrix)
template <ElementType type>
void assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom, SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
+ __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;
};
+ /// get the shape class
const Shape & getShapeFunctions() const { return shape_functions; };
+ /// get the integrator class (probably useless: see getIntegrator)
const Integrator & getIntegratorInterface() const { return integrator; };
+ /// get the integrator class
const Integ & getIntegrator() const { return integrator; };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
Integ integrator;
Shape shape_functions;
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "fe_engine_template_tmpl.hh"
/* -------------------------------------------------------------------------- */
/* Shape Linked specialization */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_STRUCTURAL_MECHANICS)
#include "fe_engine_template_tmpl_struct.hh"
#endif
/* -------------------------------------------------------------------------- */
/* Shape IGFEM specialization */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_IGFEM)
#include "fe_engine_template_tmpl_igfem.hh"
#endif
#endif /* __AKANTU_FE_ENGINE_TEMPLATE_HH__ */
diff --git a/src/fe_engine/fe_engine_template_cohesive.cc b/src/fe_engine/fe_engine_template_cohesive.cc
index 0292a78fc..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 = getNbQuadraturePoints(type);
+ 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 = getNbQuadraturePoints(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.");
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>::
-gradientOnQuadraturePoints(__attribute__((unused)) const Array<Real> &u,
+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>::
-computeNormalsOnControlPoints<_cohesive_1d_2>(__attribute__((unused)) const Array<Real> & field,
+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 27520b172..4c1c21910 100644
--- a/src/fe_engine/fe_engine_template_tmpl.hh
+++ b/src/fe_engine/fe_engine_template_tmpl.hh
@@ -1,1481 +1,1605 @@
/**
* @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"
#include "dof_manager.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
FEEngineTemplate<I, S, kind>::FEEngineTemplate(Mesh & mesh,
UInt spatial_dimension, ID id,
MemoryID memory_id)
: FEEngine(mesh, spatial_dimension, id, memory_id),
integrator(mesh, id, memory_id), shape_functions(mesh, id, memory_id) {}
/* -------------------------------------------------------------------------- */
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
FEEngineTemplate<I, S, kind>::~FEEngineTemplate() {}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
-template <ElementKind kind> struct GradientOnQuadraturePointsHelper {
+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 gradientOnControlPoints<type>( \
+ shape_functions.template gradientOnIntegrationPoints<type>( \
u, nablauq, nb_degree_of_freedom, ghost_type, filter_elements);
-#define AKANTU_SPECIALIZE_GRADIENT_ON_QUADRATURE_POINTS_HELPER(kind) \
- template <> struct GradientOnQuadraturePointsHelper<kind> { \
+#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_QUADRATURE_POINTS_HELPER,
- AKANTU_FE_ENGINE_LIST_GRADIENT_ON_QUADRATURE_POINTS)
+ AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER,
+ AKANTU_FE_ENGINE_LIST_GRADIENT_ON_INTEGRATION_POINTS)
-#undef AKANTU_SPECIALIZE_GRADIENT_ON_QUADRATURE_POINTS_HELPER
+#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>::gradientOnQuadraturePoints(
+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.getControlPoints(type, ghost_type).cols();
+ UInt nb_points =
+ shape_functions.getIntegrationPoints(type, ghost_type).cols();
#ifndef AKANTU_NDEBUG
UInt element_dimension = mesh.getSpatialDimension(type);
AKANTU_DEBUG_ASSERT(u.getSize() == mesh.getNbNodes(),
"The vector u(" << u.getID()
<< ") has not the good size.");
AKANTU_DEBUG_ASSERT(u.getNbComponent() == nb_degree_of_freedom,
"The vector u("
<< u.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(
nablauq.getNbComponent() == nb_degree_of_freedom * element_dimension,
"The vector nablauq(" << nablauq.getID()
<< ") has not the good number of component.");
// AKANTU_DEBUG_ASSERT(nablauq.getSize() == nb_element * nb_points,
// "The vector nablauq(" << nablauq.getID()
// << ") has not the good size.");
#endif
nablauq.resize(nb_element * nb_points);
- GradientOnQuadraturePointsHelper<kind>::call(
+ 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) {
+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) {
+void FEEngineTemplate<I, S, kind>::initShapeFunctions(
+ const Array<Real> & nodes, const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = mesh.firstType(element_dimension, ghost_type, kind);
Mesh::type_iterator end = mesh.lastType(element_dimension, ghost_type, kind);
for (; it != end; ++it) {
ElementType type = *it;
integrator.initIntegrator(nodes, type, ghost_type);
- const Matrix<Real> & control_points = getQuadraturePoints(type, ghost_type);
+ const Matrix<Real> & control_points =
+ getIntegrationPoints(type, ghost_type);
shape_functions.initShapeFunctions(nodes, control_points, type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct IntegrateHelper {};
#define INTEGRATE(type) \
integrator.template integrate<type>(f, intf, nb_degree_of_freedom, \
ghost_type, filter_elements);
#define AKANTU_SPECIALIZE_INTEGRATE_HELPER(kind) \
template <> struct IntegrateHelper<kind> { \
template <class I> \
static void call(const I & integrator, const Array<Real> & f, \
Array<Real> & intf, UInt nb_degree_of_freedom, \
const ElementType & type, const GhostType & ghost_type, \
const Array<UInt> & filter_elements) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind); \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_HELPER)
#undef AKANTU_SPECIALIZE_INTEGRATE_HELPER
#undef INTEGRATE
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::integrate(
const Array<Real> & f, Array<Real> & intf, UInt nb_degree_of_freedom,
const ElementType & type, const GhostType & ghost_type,
const Array<UInt> & filter_elements) const {
UInt nb_element = mesh.getNbElement(type, ghost_type);
if (filter_elements != empty_filter)
nb_element = filter_elements.getSize();
#ifndef AKANTU_NDEBUG
- UInt nb_quadrature_points = getNbQuadraturePoints(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.");
AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
"The vector intf("
<< intf.getID()
<< ") has not the good number of component.");
#endif
intf.resize(nb_element);
IntegrateHelper<kind>::call(integrator, f, intf, nb_degree_of_freedom, type,
ghost_type, filter_elements);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct IntegrateScalarHelper {};
#define INTEGRATE(type) \
integral = \
integrator.template integrate<type>(f, ghost_type, filter_elements);
#define AKANTU_SPECIALIZE_INTEGRATE_SCALAR_HELPER(kind) \
template <> struct IntegrateScalarHelper<kind> { \
template <class I> \
static Real call(const I & integrator, const Array<Real> & f, \
const ElementType & type, const GhostType & ghost_type, \
const Array<UInt> & filter_elements) { \
Real integral = 0.; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind); \
return integral; \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_SCALAR_HELPER)
#undef AKANTU_SPECIALIZE_INTEGRATE_SCALAR_HELPER
#undef INTEGRATE
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
Real FEEngineTemplate<I, S, kind>::integrate(
const Array<Real> & f, const ElementType & type,
const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
#ifndef AKANTU_NDEBUG
// std::stringstream sstr; sstr << ghost_type;
// AKANTU_DEBUG_ASSERT(sstr.str() == nablauq.getTag(),
// "The vector " << nablauq.getID() << " is not taged " <<
// ghost_type);
UInt nb_element = mesh.getNbElement(type, ghost_type);
if (filter_elements != empty_filter)
nb_element = filter_elements.getSize();
- UInt nb_quadrature_points = getNbQuadraturePoints(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 << ")");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == 1,
"The vector f("
<< f.getID()
<< ") has not the good number of component.");
#endif
Real integral = IntegrateScalarHelper<kind>::call(
integrator, f, type, ghost_type, filter_elements);
AKANTU_DEBUG_OUT();
return integral;
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct IntegrateScalarOnOneElementHelper {};
#define INTEGRATE(type) \
res = integrator.template integrate<type>(f, index, ghost_type);
#define AKANTU_SPECIALIZE_INTEGRATE_SCALAR_ON_ONE_ELEMENT_HELPER(kind) \
template <> struct IntegrateScalarOnOneElementHelper<kind> { \
template <class I> \
static Real call(const I & integrator, const Vector<Real> & f, \
const ElementType & type, UInt index, \
const GhostType & ghost_type) { \
Real res = 0.; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind); \
return res; \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_SCALAR_ON_ONE_ELEMENT_HELPER)
#undef AKANTU_SPECIALIZE_INTEGRATE_SCALAR_ON_ONE_ELEMENT_HELPER
#undef INTEGRATE
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
-Real
-FEEngineTemplate<I, S, kind>::integrate(const Vector<Real> & f,
- const ElementType & type, UInt index,
- const GhostType & ghost_type) const {
+Real FEEngineTemplate<I, S, kind>::integrate(
+ const Vector<Real> & f, const ElementType & type, UInt index,
+ const GhostType & ghost_type) const {
Real res = IntegrateScalarOnOneElementHelper<kind>::call(integrator, f, type,
index, ghost_type);
return res;
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
-template <ElementKind kind> struct IntegrateOnQuadraturePointsHelper {};
+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_QUADRATURE_POINTS_HELPER(kind) \
- template <> struct IntegrateOnQuadraturePointsHelper<kind> { \
+#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_QUADRATURE_POINTS_HELPER)
+AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_INTEGRATE_ON_INTEGRATION_POINTS_HELPER)
-#undef AKANTU_SPECIALIZE_INTEGRATE_ON_QUADRATURE_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>::integrateOnQuadraturePoints(
+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 = getNbQuadraturePoints(type);
+ UInt nb_quadrature_points = getNbIntegrationPoints(type);
#ifndef AKANTU_NDEBUG
// std::stringstream sstr; sstr << ghost_type;
// AKANTU_DEBUG_ASSERT(sstr.str() == nablauq.getTag(),
// "The vector " << nablauq.getID() << " is not taged " <<
// ghost_type);
AKANTU_DEBUG_ASSERT(f.getSize() == nb_element * nb_quadrature_points,
"The vector f(" << f.getID() << " size " << f.getSize()
<< ") has not the good size ("
<< nb_element << ").");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
"The vector f("
<< f.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
"The vector intf("
<< intf.getID()
<< ") has not the good number of component.");
#endif
intf.resize(nb_element * nb_quadrature_points);
- IntegrateOnQuadraturePointsHelper<kind>::call(integrator, f, intf,
- nb_degree_of_freedom, type,
- ghost_type, filter_elements);
+ 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 InterpolateOnQuadraturePointsHelper {
+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 interpolateOnControlPoints<type>( \
+ shape_functions.template interpolateOnIntegrationPoints<type>( \
u, uq, nb_degree_of_freedom, ghost_type, filter_elements);
-#define AKANTU_SPECIALIZE_INTERPOLATE_ON_QUADRATURE_POINTS_HELPER(kind) \
- template <> struct InterpolateOnQuadraturePointsHelper<kind> { \
+#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_QUADRATURE_POINTS_HELPER,
- AKANTU_FE_ENGINE_LIST_INTERPOLATE_ON_QUADRATURE_POINTS)
+ AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER,
+ AKANTU_FE_ENGINE_LIST_INTERPOLATE_ON_INTEGRATION_POINTS)
-#undef AKANTU_SPECIALIZE_INTERPOLATE_ON_QUADRATURE_POINTS_HELPER
+#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>::interpolateOnQuadraturePoints(
+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.getControlPoints(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();
#ifndef AKANTU_NDEBUG
AKANTU_DEBUG_ASSERT(u.getSize() == mesh.getNbNodes(),
"The vector u(" << u.getID()
<< ") has not the good size.");
AKANTU_DEBUG_ASSERT(u.getNbComponent() == nb_degree_of_freedom,
"The vector u("
<< u.getID()
<< ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(uq.getNbComponent() == nb_degree_of_freedom,
"The vector uq("
<< uq.getID()
<< ") has not the good number of component.");
#endif
uq.resize(nb_element * nb_points);
- InterpolateOnQuadraturePointsHelper<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>::interpolateOnQuadraturePoints(
+void FEEngineTemplate<I, S, kind>::interpolateOnIntegrationPoints(
const Array<Real> & u, ElementTypeMapArray<Real> & uq,
const ElementTypeMapArray<UInt> * filter_elements) const {
AKANTU_DEBUG_IN();
const Array<UInt> * filter = NULL;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
ElementTypeMapArray<Real>::type_iterator it =
uq.firstType(_all_dimensions, ghost_type, kind);
ElementTypeMapArray<Real>::type_iterator last =
uq.lastType(_all_dimensions, ghost_type, kind);
for (; it != last; ++it) {
ElementType type = *it;
- UInt nb_quad_per_element = getNbQuadraturePoints(type, ghost_type);
+ UInt nb_quad_per_element = getNbIntegrationPoints(type, ghost_type);
UInt nb_element = 0;
if (filter_elements) {
filter = &((*filter_elements)(type, ghost_type));
nb_element = filter->getSize();
} else {
filter = &empty_filter;
nb_element = mesh.getNbElement(type, ghost_type);
}
UInt nb_tot_quad = nb_quad_per_element * nb_element;
Array<Real> & quad = uq(type, ghost_type);
quad.resize(nb_tot_quad);
- interpolateOnQuadraturePoints(u, quad, mesh.getSpatialDimension(), 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 {
+
+ const Array<Real> & nodes_coordinates = mesh.getNodes();
+
+ interpolateOnIntegrationPoints(
+ nodes_coordinates, quadrature_points_coordinates, filter_elements);
+}
+
+/* -------------------------------------------------------------------------- */
+template <template <ElementKind> class I, template <ElementKind> class S,
+ ElementKind kind>
+inline void FEEngineTemplate<I, S, kind>::computeIntegrationPointsCoordinates(
+ Array<Real> & quadrature_points_coordinates, const ElementType & type,
+ const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
+
+ const Array<Real> & nodes_coordinates = mesh.getNodes();
+
+ UInt spatial_dimension = mesh.getSpatialDimension();
+
+ interpolateOnIntegrationPoints(
+ nodes_coordinates, quadrature_points_coordinates, spatial_dimension, type,
+ ghost_type, filter_elements);
+}
+
+/* -------------------------------------------------------------------------- */
+template <template <ElementKind> class I, template <ElementKind> class S,
+ ElementKind kind>
+inline void FEEngineTemplate<I, S, kind>::
+ initElementalFieldInterpolationFromIntegrationPoints(
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates,
+ ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
+ ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
+ const ElementTypeMapArray<UInt> * element_filter) const {
+
+ AKANTU_DEBUG_IN();
+
+ UInt spatial_dimension = this->mesh.getSpatialDimension();
+
+ ElementTypeMapArray<Real> quadrature_points_coordinates(
+ "quadrature_points_coordinates_for_interpolation", getID());
+ mesh.initElementTypeMapArray(quadrature_points_coordinates, spatial_dimension,
+ spatial_dimension);
+ computeIntegrationPointsCoordinates(quadrature_points_coordinates,
+ element_filter);
+ shape_functions.initElementalFieldInterpolationFromIntegrationPoints(
+ interpolation_points_coordinates,
+ interpolation_points_coordinates_matrices,
+ quad_points_coordinates_inv_matrices, quadrature_points_coordinates,
+ element_filter);
+}
+/* -------------------------------------------------------------------------- */
+template <template <ElementKind> class I, template <ElementKind> class S,
+ ElementKind kind>
+inline void
+FEEngineTemplate<I, S, kind>::interpolateElementalFieldFromIntegrationPoints(
+ const ElementTypeMapArray<Real> & field,
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates,
+ ElementTypeMapArray<Real> & result, const GhostType ghost_type,
+ const ElementTypeMapArray<UInt> * element_filter) const {
+
+ ElementTypeMapArray<Real> interpolation_points_coordinates_matrices(
+ "interpolation_points_coordinates_matrices");
+ ElementTypeMapArray<Real> quad_points_coordinates_inv_matrices(
+ "quad_points_coordinates_inv_matrices");
+
+ initElementalFieldInterpolationFromIntegrationPoints(
+ interpolation_points_coordinates,
+ interpolation_points_coordinates_matrices,
+ quad_points_coordinates_inv_matrices, element_filter);
+
+ interpolateElementalFieldFromIntegrationPoints(
+ field, interpolation_points_coordinates_matrices,
+ quad_points_coordinates_inv_matrices, result, ghost_type, element_filter);
+}
+
+/* -------------------------------------------------------------------------- */
+template <template <ElementKind> class I, template <ElementKind> class S,
+ ElementKind kind>
+inline void
+FEEngineTemplate<I, S, kind>::interpolateElementalFieldFromIntegrationPoints(
+ const ElementTypeMapArray<Real> & field,
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
+ const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
+ ElementTypeMapArray<Real> & result, const GhostType ghost_type,
+ const ElementTypeMapArray<UInt> * element_filter) const {
+
+ shape_functions.interpolateElementalFieldFromIntegrationPoints(
+ field, interpolation_points_coordinates_matrices,
+ quad_points_coordinates_inv_matrices, result, ghost_type, element_filter);
+}
+
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct InterpolateHelper {
template <class S>
- static void call(const S & shape_functions, const Vector<Real> & real_coords,
- UInt elem, const Matrix<Real> & nodal_values,
- Vector<Real> & interpolated, const ElementType & type,
- const GhostType & ghost_type) {
+ 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); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INTERPOLATE_HELPER,
AKANTU_FE_ENGINE_LIST_INTERPOLATE)
#undef AKANTU_SPECIALIZE_INTERPOLATE_HELPER
#undef INTERPOLATE
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::interpolate(
const Vector<Real> & real_coords, const Matrix<Real> & nodal_values,
Vector<Real> & interpolated, const Element & element) const {
AKANTU_DEBUG_IN();
InterpolateHelper<kind>::call(shape_functions, real_coords, element.element,
nodal_values, interpolated, element.type,
element.ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
-void FEEngineTemplate<I, S, kind>::computeNormalsOnControlPoints(
+void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
- computeNormalsOnControlPoints(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>::computeNormalsOnControlPoints(
+void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(
const Array<Real> & field, const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
// Real * coord = mesh.getNodes().storage();
UInt spatial_dimension = mesh.getSpatialDimension();
// allocate the normal arrays
Mesh::type_iterator it = mesh.firstType(element_dimension, ghost_type, kind);
Mesh::type_iterator end = mesh.lastType(element_dimension, ghost_type, kind);
for (; it != end; ++it) {
ElementType type = *it;
UInt size = mesh.getNbElement(type, ghost_type);
- if (normals_on_quad_points.exists(type, ghost_type)) {
- normals_on_quad_points(type, ghost_type).resize(size);
+ if (normals_on_integration_points.exists(type, ghost_type)) {
+ normals_on_integration_points(type, ghost_type).resize(size);
} else {
- normals_on_quad_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_quad_points(*it, ghost_type);
- computeNormalsOnControlPoints(field, normals_on_quad, *it, ghost_type);
+ 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 ComputeNormalsOnControlPoints {
+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_QUAD(type) \
- fem.template computeNormalsOnControlPoints<type>(field, normal, ghost_type);
+#define COMPUTE_NORMALS_ON_INTEGRATION_POINTS(type) \
+ fem.template computeNormalsOnIntegrationPoints<type>(field, normal, \
+ ghost_type);
-#define AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_CONTROL_POINTS(kind) \
- template <> struct ComputeNormalsOnControlPoints<kind> { \
+#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_QUAD, kind); \
+ AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_NORMALS_ON_INTEGRATION_POINTS, \
+ kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(
- AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_CONTROL_POINTS,
- AKANTU_FE_ENGINE_LIST_COMPUTE_NORMALS_ON_CONTROL_POINTS)
+ AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS,
+ AKANTU_FE_ENGINE_LIST_COMPUTE_NORMALS_ON_INTEGRATION_POINTS)
-#undef AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_CONTROL_POINTS
-#undef COMPUTE_NORMALS_ON_QUAD
+#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>::computeNormalsOnControlPoints(
+void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(
const Array<Real> & field, Array<Real> & normal, const ElementType & type,
const GhostType & ghost_type) const {
- ComputeNormalsOnControlPoints<kind>::call(*this, field, normal, type,
- ghost_type);
+ 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>::computeNormalsOnControlPoints(
+void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(
const Array<Real> & field, Array<Real> & normal,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt nb_points = getNbQuadraturePoints(type, ghost_type);
+ UInt nb_points = getNbIntegrationPoints(type, ghost_type);
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
normal.resize(nb_element * nb_points);
Array<Real>::matrix_iterator normals_on_quad =
normal.begin_reinterpret(spatial_dimension, nb_points, nb_element);
Array<Real> f_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, field, f_el, type, ghost_type);
const Matrix<Real> & quads =
integrator.template getQuadraturePoints<type>(ghost_type);
Array<Real>::matrix_iterator f_it =
f_el.begin(spatial_dimension, nb_nodes_per_element);
for (UInt elem = 0; elem < nb_element; ++elem) {
ElementClass<type>::computeNormalsOnNaturalCoordinates(quads, *f_it,
*normals_on_quad);
++normals_on_quad;
++f_it;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* Matrix lumping functions */
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct AssembleLumpedTemplateHelper {};
#define ASSEMBLE_LUMPED(type) \
fem.template assembleLumpedTemplate<type>( \
- field_1, nb_degree_of_freedom, lumped, equation_number, ghost_type)
+ 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, Array<Real> & lumped, DOFManager & dof_manager,
ElementType type, const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AssembleLumpedTemplateHelper<kind>::call(*this, field, lumped, dof_manager,
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, matrix_id, dof_id, \
dof_manager, 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, const ID & matrix_id, \
const ID & dof_id, DOFManager & dof_manager, \
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, const ID & matrix_id, const ID & dof_id,
DOFManager & dof_manager, ElementType type,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AssembleFieldMatrixHelper<kind>::call(*this, field, matrix_id, dof_id,
dof_manager, type, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleLumpedTemplate(
const Array<Real> & field, Array<Real> & lumped, DOFManager & dof_manager,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
this->template assembleLumpedRowSum<type>(field, lumped, dof_manager,
ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV =
* \int \rho \varphi_i dV @f$
*/
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleLumpedRowSum(
const Array<Real> & field, Array<Real> & lumped, DOFManager & dof_manager,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt shapes_size = ElementClass<type>::getShapeSize();
UInt nb_degree_of_freedom = field.getNbComponent();
Array<Real> * field_times_shapes =
new Array<Real>(0, shapes_size * nb_degree_of_freedom);
shape_functions.template fieldTimesShapes<type>(field, *field_times_shapes,
ghost_type);
delete field;
UInt nb_element = mesh.getNbElement(type, ghost_type);
Array<Real> * int_field_times_shapes = new Array<Real>(
nb_element, shapes_size * nb_degree_of_freedom, "inte_rho_x_shapes");
integrator.template integrate<type>(
*field_times_shapes, *int_field_times_shapes,
nb_degree_of_freedom * shapes_size, ghost_type, empty_filter);
delete field_times_shapes;
dof_manager.assembleElementalArrayLocalArray(*int_field_times_shapes, lumped,
type, ghost_type);
delete int_field_times_shapes;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* @f$ \tilde{M}_{i} = c * M_{ii} = \int_{V_e} \rho dV @f$
*/
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleLumpedDiagonalScaling(
const Array<Real> & field, Array<Real> & lumped, DOFManager & dof_manager,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
const ElementType & type_p1 = ElementClass<type>::getP1ElementType();
UInt nb_nodes_per_element_p1 = Mesh::getNbNodesPerElement(type_p1);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points =
integrator.template getQuadraturePoints<type>(ghost_type).cols();
UInt nb_degree_of_freedom = field.getNbComponent();
UInt nb_element = field.getSize() / nb_quadrature_points;
Vector<Real> nodal_factor(nb_nodes_per_element);
#define ASSIGN_WEIGHT_TO_NODES(corner, mid) \
{ \
for (UInt n = 0; n < nb_nodes_per_element_p1; n++) \
nodal_factor(n) = corner; \
for (UInt n = nb_nodes_per_element_p1; n < nb_nodes_per_element; n++) \
nodal_factor(n) = mid; \
}
if (type == _triangle_6)
ASSIGN_WEIGHT_TO_NODES(1. / 12., 1. / 4.);
if (type == _tetrahedron_10)
ASSIGN_WEIGHT_TO_NODES(1. / 32., 7. / 48.);
if (type == _quadrangle_8)
- ASSIGN_WEIGHT_TO_NODES(
- 3. / 76., 16. / 76.); /** coeff. derived by scaling the diagonal terms
- * of the corresponding
- * consistent mass computed with 3x3 gauss points;
- * coeff. are (1./36., 8./36.) for 2x2 gauss
- * points */
+ 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;
+ * the diagonal terms of the corresponding
+ * consistent mass computed with 3x3x3 gauss points;
* coeff. are (1./40.,
- * 1./15.) for 2x2x2 gauss
- * points */
+ * 1./15.) for 2x2x2 gauss points */
if (type == _pentahedron_15) {
// coefficients derived by scaling the diagonal terms of the corresponding
// consistent mass computed with 8 gauss points;
for (UInt n = 0; n < nb_nodes_per_element_p1; n++)
nodal_factor(n) = 51. / 2358.;
Real mid_triangle = 192. / 2358.;
Real mid_quadrangle = 300. / 2358.;
nodal_factor(6) = mid_triangle;
nodal_factor(7) = mid_triangle;
nodal_factor(8) = mid_triangle;
nodal_factor(9) = mid_quadrangle;
nodal_factor(10) = mid_quadrangle;
nodal_factor(11) = mid_quadrangle;
nodal_factor(12) = mid_triangle;
nodal_factor(13) = mid_triangle;
nodal_factor(14) = mid_triangle;
}
if (nb_element == 0) {
AKANTU_DEBUG_OUT();
return;
}
#undef ASSIGN_WEIGHT_TO_NODES
/// compute @f$ \int \rho dV = \rho V @f$ for each element
Array<Real> * int_field =
new Array<Real>(field.getSize(), nb_degree_of_freedom, "inte_rho_x");
integrator.template integrate<type>(field, *int_field, nb_degree_of_freedom,
ghost_type, empty_filter);
/// distribute the mass of the element to the nodes
Array<Real> * lumped_per_node = new Array<Real>(
nb_element, nb_degree_of_freedom * nb_nodes_per_element, "mass_per_node");
Array<Real>::const_vector_iterator int_field_it =
int_field->begin(nb_degree_of_freedom);
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) {
Vector<Real> l = (*lumped_per_node_it)(n);
l = *int_field_it;
l *= nodal_factor(n);
}
++int_field_it;
++lumped_per_node_it;
}
delete int_field;
dof_manager.assembleElementalArrayLocalArray(*lumped_per_node, lumped, type,
ghost_type);
delete lumped_per_node;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV =
* \int \rho \varphi_i dV @f$
*/
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleFieldMatrix(
const Array<Real> & field, const ID & matrix_id, const ID & dof_id,
DOFManager & dof_manager, const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt vect_size = field.getSize();
UInt shapes_size = ElementClass<type>::getShapeSize();
UInt nb_degree_of_freedom = field.getNbComponent();
UInt lmat_size = nb_degree_of_freedom * shapes_size;
const Array<Real> & shapes = shape_functions.getShapes(type, ghost_type);
Array<Real> * modified_shapes =
new Array<Real>(vect_size, lmat_size * nb_degree_of_freedom);
modified_shapes->clear();
Array<Real> * local_mat = new Array<Real>(vect_size, lmat_size * lmat_size);
Array<Real>::matrix_iterator mshapes_it =
modified_shapes->begin(lmat_size, nb_degree_of_freedom);
Array<Real>::const_vector_iterator shapes_it = shapes.begin(shapes_size);
for (UInt q = 0; q < vect_size; ++q, ++mshapes_it, ++shapes_it) {
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
for (UInt s = 0; s < shapes_size; ++s) {
(*mshapes_it)(s * nb_degree_of_freedom + d, d) = (*shapes_it)(s);
}
}
}
mshapes_it = modified_shapes->begin(lmat_size, nb_degree_of_freedom);
Array<Real>::matrix_iterator lmat = local_mat->begin(lmat_size, lmat_size);
Array<Real>::const_matrix_iterator field_it =
field.begin_reinterpret(nb_degree_of_freedom, 1, field.getSize());
for (UInt q = 0; q < vect_size; ++q, ++lmat, ++mshapes_it, ++field_it) {
Matrix<Real> & mat = *lmat;
const Matrix<Real> & f_mat = *field_it;
Matrix<Real> f_times_mat(lmat_size, nb_degree_of_freedom);
f_times_mat.mul<false, true>(f_mat, *mshapes_it);
mat.mul<false, true>(*mshapes_it, f_times_mat);
}
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");
this->integrator.template integrate<type>(*local_mat, *int_field_times_shapes,
lmat_size * lmat_size, ghost_type,
empty_filter);
delete local_mat;
dof_manager.assembleElementalMatricesToMatrix(
matrix_id, dof_id, *int_field_times_shapes, type, ghost_type);
delete int_field_times_shapes;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct InverseMapHelper {
template <class S>
- static void call(const S & shape_functions, const Vector<Real> & real_coords,
- UInt element, const ElementType & type,
- Vector<Real> & natural_coords,
- const GhostType & ghost_type) {
+ 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); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INVERSE_MAP_HELPER,
AKANTU_FE_ENGINE_LIST_INVERSE_MAP)
#undef AKANTU_SPECIALIZE_INVERSE_MAP_HELPER
#undef INVERSE_MAP
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::inverseMap(
const Vector<Real> & real_coords, UInt element, const ElementType & type,
Vector<Real> & natural_coords, const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
InverseMapHelper<kind>::call(shape_functions, real_coords, element, type,
natural_coords, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct ContainsHelper {
template <class S>
- static void call(const S & shape_functions, const Vector<Real> & real_coords,
- UInt element, const ElementType & type,
- const GhostType & ghost_type) {
+ 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; \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_CONTAINS_HELPER,
AKANTU_FE_ENGINE_LIST_CONTAINS)
#undef AKANTU_SPECIALIZE_CONTAINS_HELPER
#undef CONTAINS
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
inline bool
FEEngineTemplate<I, S, kind>::contains(const Vector<Real> & real_coords,
UInt element, const ElementType & type,
const GhostType & ghost_type) const {
return ContainsHelper<kind>::call(shape_functions, real_coords, element, type,
ghost_type);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct ComputeShapesHelper {
template <class S>
- static void call(const S & shape_functions, const Vector<Real> & real_coords,
- UInt element, const ElementType type, Vector<Real> & shapes,
- const GhostType & ghost_type) {
+ 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, \
ghost_type);
#define AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER(kind) \
template <> struct ComputeShapesHelper<kind> { \
template <class S> \
static void call(const S & shape_functions, \
const Vector<Real> & real_coords, UInt element, \
const ElementType type, Vector<Real> & shapes, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_SHAPES, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER,
AKANTU_FE_ENGINE_LIST_COMPUTE_SHAPES)
#undef AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER
#undef COMPUTE_SHAPES
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::computeShapes(
const Vector<Real> & real_coords, UInt element, const ElementType & type,
Vector<Real> & shapes, const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
ComputeShapesHelper<kind>::call(shape_functions, real_coords, element, type,
shapes, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct ComputeShapeDerivativesHelper {
template <class S>
- static void call(const S & shape_functions, const Vector<Real> & real_coords,
- UInt element, const ElementType type,
- Matrix<Real> & shape_derivatives,
- const GhostType & ghost_type) {
+ 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) \
Matrix<Real> coords_mat(real_coords.storage(), shape_derivatives.rows(), 1); \
Tensor3<Real> shapesd_tensor(shape_derivatives.storage(), \
shape_derivatives.rows(), \
shape_derivatives.cols(), 1); \
shape_functions.template computeShapeDerivatives<type>( \
coords_mat, element, shapesd_tensor, ghost_type);
#define AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER(kind) \
template <> struct ComputeShapeDerivativesHelper<kind> { \
template <class S> \
static void call(const S & shape_functions, \
const Vector<Real> & real_coords, UInt element, \
const ElementType type, Matrix<Real> & shape_derivatives, \
const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_SHAPE_DERIVATIVES, kind); \
} \
};
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER,
AKANTU_FE_ENGINE_LIST_COMPUTE_SHAPES_DERIVATIVES)
#undef AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER
#undef COMPUTE_SHAPE_DERIVATIVES
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::computeShapeDerivatives(
const Vector<Real> & real_coords, UInt element, const ElementType & type,
Matrix<Real> & shape_derivatives, const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
ComputeShapeDerivativesHelper<kind>::call(shape_functions, real_coords,
element, type, shape_derivatives,
ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
-template <ElementKind kind> struct GetNbQuadraturePointsHelper {};
+template <ElementKind kind> struct GetNbIntegrationPointsHelper {};
-#define GET_NB_QUAD(type) \
+#define GET_NB_INTEGRATION_POINTS(type) \
nb_quad_points = \
integrator.template getQuadraturePoints<type>(ghost_type).cols();
-#define AKANTU_SPECIALIZE_GET_NB_QUADRATURE_POINTS_HELPER(kind) \
- template <> struct GetNbQuadraturePointsHelper<kind> { \
+#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_QUAD, kind); \
+ AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_NB_INTEGRATION_POINTS, kind); \
return nb_quad_points; \
} \
};
-AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_NB_QUADRATURE_POINTS_HELPER)
+AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_NB_INTEGRATION_POINTS_HELPER)
-#undef AKANTU_SPECIALIZE_GET_NB_QUADRATURE_POINTS_HELPER
-#undef GET_NB_QUAD
+#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>::getNbQuadraturePoints(
+inline UInt FEEngineTemplate<I, S, kind>::getNbIntegrationPoints(
const ElementType & type, const GhostType & ghost_type) const {
- return GetNbQuadraturePointsHelper<kind>::call(integrator, type, ghost_type);
+ return GetNbIntegrationPointsHelper<kind>::call(integrator, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct GetShapesHelper {};
#define GET_SHAPES(type) ret = &(shape_functions.getShapes(type, ghost_type));
#define AKANTU_SPECIALIZE_GET_SHAPES_HELPER(kind) \
template <> struct GetShapesHelper<kind> { \
template <class S> \
static const Array<Real> & call(const S & shape_functions, \
const ElementType type, \
const GhostType & ghost_type) { \
const Array<Real> * ret = NULL; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_SHAPES, kind); \
return *ret; \
} \
};
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_SHAPES_HELPER)
#undef AKANTU_SPECIALIZE_GET_SHAPES_HELPER
#undef GET_SHAPES
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
inline const Array<Real> &
FEEngineTemplate<I, S, kind>::getShapes(const ElementType & type,
const GhostType & ghost_type,
__attribute__((unused)) UInt id) const {
return GetShapesHelper<kind>::call(shape_functions, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template <ElementKind kind> struct GetShapesDerivativesHelper {
template <template <ElementKind> class S, ElementKind k>
- static const Array<Real> & call(const S<k> & shape_functions,
- const ElementType & type,
- const GhostType & ghost_type, UInt id) {
+ 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) \
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) { \
+ 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_FE_ENGINE_LIST_GET_SHAPES_DERIVATIVES)
#undef AKANTU_SPECIALIZE_GET_SHAPE_DERIVATIVES_HELPER
#undef GET_SHAPES_DERIVATIVES
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
inline const Array<Real> & FEEngineTemplate<I, S, kind>::getShapesDerivatives(
const ElementType & type, const GhostType & ghost_type,
__attribute__((unused)) UInt id) const {
return GetShapesDerivativesHelper<kind>::call(shape_functions, type,
ghost_type, id);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
-template <ElementKind kind> struct GetQuadraturePointsHelper {};
+template <ElementKind kind> struct GetIntegrationPointsHelper {};
-#define GET_QUADS(type) \
+#define GET_INTEGRATION_POINTS(type) \
ret = &(integrator.template getQuadraturePoints<type>(ghost_type));
-#define AKANTU_SPECIALIZE_GET_QUADRATURE_POINTS_HELPER(kind) \
- template <> struct GetQuadraturePointsHelper<kind> { \
+#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_QUADS, kind); \
+ AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_INTEGRATION_POINTS, kind); \
return *ret; \
} \
};
-AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_QUADRATURE_POINTS_HELPER)
+AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_INTEGRATION_POINTS_HELPER)
-#undef AKANTU_SPECIALIZE_GET_QUADRATURE_POINTS_HELPER
-#undef GET_QUADS
+#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>::getQuadraturePoints(
+inline const Matrix<Real> & FEEngineTemplate<I, S, kind>::getIntegrationPoints(
const ElementType & type, const GhostType & ghost_type) const {
- return GetQuadraturePointsHelper<kind>::call(integrator, type, ghost_type);
+ return GetIntegrationPointsHelper<kind>::call(integrator, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <template <ElementKind> class I, template <ElementKind> class S,
ElementKind kind>
void FEEngineTemplate<I, S, kind>::printself(std::ostream & stream,
int indent) const {
std::string space;
for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
;
stream << space << "FEEngineTemplate [" << std::endl;
stream << space << " + parent [" << std::endl;
FEEngine::printself(stream, indent + 3);
stream << space << " ]" << std::endl;
stream << space << " + shape functions [" << std::endl;
shape_functions.printself(stream, indent + 3);
stream << space << " ]" << std::endl;
stream << space << " + integrator [" << std::endl;
integrator.printself(stream, indent + 3);
stream << space << " ]" << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include "shape_lagrange.hh"
#include "integrator_gauss.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_triangle_6>(const Array<Real> & field,
Array<Real> & lumped,
DOFManager & dof_manager,
const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_triangle_6>(field, lumped, dof_manager,
ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_tetrahedron_10>(
const Array<Real> & field, Array<Real> & lumped,
DOFManager & dof_manager, const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_tetrahedron_10>(field, lumped, dof_manager,
ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_quadrangle_8>(const Array<Real> & field,
Array<Real> & lumped,
DOFManager & dof_manager,
const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_quadrangle_8>(field, lumped, dof_manager,
ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_hexahedron_20>(const Array<Real> & field,
Array<Real> & lumped,
DOFManager & dof_manager,
const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_hexahedron_20>(field, lumped, dof_manager,
ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_pentahedron_15>(
const Array<Real> & field, Array<Real> & lumped,
DOFManager & dof_manager, const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_pentahedron_15>(field, lumped, dof_manager,
ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
- computeNormalsOnControlPoints<_point_1>(
+ computeNormalsOnIntegrationPoints<_point_1>(
__attribute__((unused)) const Array<Real> & field, Array<Real> & normal,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == 1,
"Mesh dimension must be 1 to compute normals on points!");
const ElementType type = _point_1;
UInt spatial_dimension = mesh.getSpatialDimension();
// UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt nb_points = getNbQuadraturePoints(type, ghost_type);
+ UInt nb_points = getNbIntegrationPoints(type, ghost_type);
UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
normal.resize(nb_element * nb_points);
Array<Real>::matrix_iterator normals_on_quad =
normal.begin_reinterpret(spatial_dimension, nb_points, nb_element);
Array<std::vector<Element> > segments =
mesh.getElementToSubelement(type, ghost_type);
Array<Real> coords = mesh.getNodes();
const Mesh * mesh_segment;
if (mesh.isMeshFacets())
mesh_segment = &(mesh.getMeshParent());
else
mesh_segment = &mesh;
for (UInt elem = 0; elem < nb_element; ++elem) {
UInt nb_segment = segments(elem).size();
AKANTU_DEBUG_ASSERT(
nb_segment > 0,
"Impossible to compute a normal on a point connected to 0 segments");
Real normal_value = 1;
if (nb_segment == 1) {
Element segment = segments(elem)[0];
const Array<UInt> & segment_connectivity =
mesh_segment->getConnectivity(segment.type, segment.ghost_type);
// const Vector<UInt> & segment_points =
// segment_connectivity.begin(Mesh::getNbNodesPerElement(segment.type))[segment.element];
Real difference;
if (segment_connectivity(0) == elem) {
difference = coords(elem) - coords(segment_connectivity(1));
} else {
difference = coords(elem) - coords(segment_connectivity(0));
}
normal_value = difference / std::abs(difference);
}
for (UInt n(0); n < nb_points; ++n) {
(*normals_on_quad)(0, n) = normal_value;
}
++normals_on_quad;
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/fe_engine/fe_engine_template_tmpl_struct.hh b/src/fe_engine/fe_engine_template_tmpl_struct.hh
index 3802e9126..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 = getNbQuadraturePoints(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 = getNbQuadraturePoints(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 f28fe1017..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,
- 1, 1, 2, 3, 0, 5,
- 2, 5, 6, 7, 4, 6,
- 3, 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, 3, 3, 0, 3, 5,
+ 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,
- 1, 4,
- 2, 5,
+ 2, 4,
+ 1, 5,
// second type
0, 0, 1,
- 3, 2, 4,
+ 1, 3, 2,
4, 5, 5,
- 1, 3, 2};
+ 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 0c759486e..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 intagration constants
+ * @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<> 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,};
+ 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
new file mode 100644
index 000000000..eb9677fe0
--- /dev/null
+++ b/src/fe_engine/integration_point.hh
@@ -0,0 +1,157 @@
+/**
+ * @file integration_point.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Wed Jun 17 2015
+ * @date last modification: Sun Nov 15 2015
+ *
+ * @brief definition of the class IntegrationPoint
+ *
+ * @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_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 bd2f1129c..26c606e9d 100644
--- a/src/fe_engine/integrator.hh
+++ b/src/fe_engine/integrator.hh
@@ -1,129 +1,135 @@
/**
* @file integrator.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Feb 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 22 2015
*
* @brief interface for integrator classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_INTEGRATOR_HH__
#define __AKANTU_INTEGRATOR_HH__
/* -------------------------------------------------------------------------- */
#include "aka_memory.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class Integrator : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Integrator(const Mesh & mesh,
const ID & id="integrator",
const MemoryID & memory_id = 0) :
Memory(id, memory_id),
mesh(mesh),
jacobians("jacobians", id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
};
virtual ~Integrator(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
+ /// empty method
template <ElementType type>
inline void precomputeJacobiansOnQuadraturePoints(__attribute__ ((unused))
GhostType ghost_type){}
+ /// empty method
void integrateOnElement(__attribute__ ((unused)) const Array<Real> & f,
__attribute__ ((unused)) Real * intf,
__attribute__ ((unused)) UInt nb_degree_of_freedom,
__attribute__ ((unused)) const Element & elem,
__attribute__ ((unused)) GhostType ghost_type) const {};
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Integrator [" << std::endl;
jacobians.printself(stream, indent + 1);
stream << space << "]" << std::endl;
};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// access to the jacobians
Array<Real> & getJacobians(const ElementType & type,
const GhostType & ghost_type = _not_ghost) {
return jacobians(type, ghost_type);
};
+ /// access to the jacobians const
const Array<Real> & getJacobians(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
return jacobians(type, ghost_type);
};
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
+ /// mesh associated to the integrator
const Mesh & mesh;
/// jacobians for all elements
ElementTypeMapArray<Real> jacobians;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
//#include "integrator_inline_impl.cc"
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const Integrator & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_INTEGRATOR_HH__ */
diff --git a/src/fe_engine/integrator_gauss.hh b/src/fe_engine/integrator_gauss.hh
index 0b82c68e7..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 fa11ede17..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: " << jacobians_it[el.element];
+ 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/quadrature_point.hh b/src/fe_engine/quadrature_point.hh
deleted file mode 100644
index 0408a9787..000000000
--- a/src/fe_engine/quadrature_point.hh
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef AKANTU_QUADRATURE_POINT_H
-#define AKANTU_QUADRATURE_POINT_H
-/* -------------------------------------------------------------------------- */
-__BEGIN_AKANTU__
-/* -------------------------------------------------------------------------- */
-
-class QuadraturePoint : public Element {
-
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
-
-public:
- typedef Vector<Real> position_type;
-
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-
-public:
- QuadraturePoint(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) { };
-
- QuadraturePoint(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) { };
-
- QuadraturePoint(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); };
-
- QuadraturePoint(const QuadraturePoint & quad) :
- Element(quad), num_point(quad.num_point), global_num(quad.global_num), position((Real *) NULL, 0) {
- position.shallowCopy(quad.position);
- };
-
- /* ------------------------------------------------------------------------ */
- /* Methods */
- /* ------------------------------------------------------------------------ */
-
- inline QuadraturePoint & operator=(const QuadraturePoint & 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;
- }
-
- AKANTU_GET_MACRO(Position, position, const position_type &);
-
- void setPosition(const position_type & position) {
- this->position.shallowCopy(position);
- }
-
- 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 << "QuadraturePoint [";
- 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/shape_cohesive.hh b/src/fe_engine/shape_cohesive.hh
index 2aea47f6e..e6beca1bc 100644
--- a/src/fe_engine/shape_cohesive.hh
+++ b/src/fe_engine/shape_cohesive.hh
@@ -1,200 +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> & control_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 control points from natural coordinates
+ /// pre compute all shapes on the element integration points from natural
+ /// coordinates
template <ElementType type>
- void precomputeShapesOnControlPoints(const Array<Real> & nodes,
- GhostType ghost_type);
+ void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
+ GhostType ghost_type);
- /// pre compute all shape derivatives on the element control points from natural coordinates
+ /// pre compute all shape derivatives on the element integration points from
+ /// natural coordinates
template <ElementType type>
- void precomputeShapeDerivativesOnControlPoints(const Array<Real> & nodes,
- GhostType ghost_type);
+ void precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
+ GhostType ghost_type);
- /// interpolate nodal values on the control points
+ /// interpolate nodal values on the integration points
template <ElementType type, class ReduceFunction>
- void interpolateOnControlPoints(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 interpolateOnControlPoints(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 {
- interpolateOnControlPoints<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 control points in the natural coordinates
+ /// compute the gradient of u on the integration points in the natural
+ /// coordinates
template <ElementType type>
- void gradientOnControlPoints(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 {
- variationOnControlPoints<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 control points
+ /// compute the gradient of u on the integration points
template <ElementType type, class ReduceFunction>
- void variationOnControlPoints(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 computeNormalsOnControlPoints(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 b8054e602..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) \
- setControlPointsByType<type>(control_points, ghost_type); \
- precomputeShapesOnControlPoints<type>(nodes, ghost_type); \
- precomputeShapeDerivativesOnControlPoints<type>(nodes, ghost_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> & control_points,
+ 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>::precomputeShapesOnControlPoints(__attribute__((unused)) const Array<Real> & nodes,
+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 = control_points(type, ghost_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>::precomputeShapeDerivativesOnControlPoints(__attribute__((unused)) const Array<Real> & nodes,
+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->control_points(type, ghost_type);
+ 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>::interpolateOnControlPoints(const Array<Real> &in_u,
+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 interpolateElementalFieldOnControlPoints<type>(u_el, out_uq, ghost_type,
+ 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>::variationOnControlPoints(const Array<Real> &in_u,
+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 gradientElementalFieldOnControlPoints<type>(u_el, nablauq, ghost_type,
+ 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>::computeNormalsOnControlPoints(const Array<Real> &u,
+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->control_points(type, ghost_type).cols();
+ 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 variationOnControlPoints<type, ReduceFunction>(u,
+ 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 5a79ba207..b8d935e57 100644
--- a/src/fe_engine/shape_functions.hh
+++ b/src/fe_engine/shape_functions.hh
@@ -1,138 +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;
- control_points.printself(stream, indent + 1);
+ integration_points.printself(stream, indent + 1);
stream << space << "]" << std::endl;
};
- /// set the control points for a given element
+ /// set the integration points for a given element
template <ElementType type>
- void setControlPointsByType(const Matrix<Real> & control_points,
+ 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 control points
+
+ /// interpolate nodal values stored by element on the integration points
template <ElementType type>
- void interpolateElementalFieldOnControlPoints(const Array<Real> &u_el,
+ 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 gradientElementalFieldOnControlPoints(const Array<Real> &u_el,
+ 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> & getControlPoints(const ElementType & type,
+ inline const Matrix<Real> & getIntegrationPoints(const ElementType & type,
const GhostType & ghost_type) const {
- return control_points(type, ghost_type);
+ return integration_points(type, ghost_type);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
+ /// associated mesh
const Mesh & mesh;
/// shape functions for all elements
- ElementTypeMap< Matrix<Real> > control_points;
+ 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 5c9c37fa9..1964c10e2 100644
--- a/src/fe_engine/shape_functions_inline_impl.cc
+++ b/src/fe_engine/shape_functions_inline_impl.cc
@@ -1,173 +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::setControlPointsByType(const Matrix<Real> & points,
+void ShapeFunctions::setIntegrationPointsByType(const Matrix<Real> & points,
const GhostType & ghost_type) {
- control_points(type, ghost_type).shallowCopy(points);
+ 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>
-void ShapeFunctions::interpolateElementalFieldOnControlPoints(const Array<Real> &u_el,
- Array<Real> &uq,
- GhostType ghost_type,
- const Array<Real> & shapes,
- const Array<UInt> & filter_elements) const {
+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 = control_points(type, ghost_type).cols();
+ 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::gradientElementalFieldOnControlPoints(const Array<Real> &u_el,
+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 = control_points(type, ghost_type).cols();
+ 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 7ce67a9b8..41061d22b 100644
--- a/src/fe_engine/shape_lagrange.hh
+++ b/src/fe_engine/shape_lagrange.hh
@@ -1,174 +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{
+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> & control_points,
+ const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type);
- /// pre compute all shapes on the element control points from natural coordinates
+ /// pre compute all shapes on the element integration points from natural coordinates
template<ElementType type>
- void precomputeShapesOnControlPoints(const Array<Real> & nodes,
+ void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
GhostType ghost_type);
- /// pre compute all shape derivatives on the element control points from natural coordinates
+ /// pre compute all shape derivatives on the element integration points from natural coordinates
template <ElementType type>
- void precomputeShapeDerivativesOnControlPoints(const Array<Real> & nodes,
+ void precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
GhostType ghost_type);
- /// interpolate nodal values on the control points
+ /// interpolate nodal values on the integration points
template <ElementType type>
- void interpolateOnControlPoints(const Array<Real> &u,
+ 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 control points
+ /// compute the gradient of u on the integration points
template <ElementType type>
- void gradientOnControlPoints(const Array<Real> &u,
+ 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 control points for a given element
+ /// 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 58e982521..6229d0552 100644
--- a/src/fe_engine/shape_lagrange_inline_impl.cc
+++ b/src/fe_engine/shape_lagrange_inline_impl.cc
@@ -1,410 +1,411 @@
/**
* @file shape_lagrange_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Feb 15 2011
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Wed Oct 27 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief ShapeLagrange inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
__END_AKANTU__
#include "fe_engine.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
inline const Array<Real> & ShapeLagrange<kind>::getShapes(const ElementType & el_type,
const GhostType & ghost_type) const {
return shapes(FEEngine::getInterpolationType(el_type), ghost_type);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
inline const Array<Real> & ShapeLagrange<kind>::getShapesDerivatives(const ElementType & el_type,
const GhostType & ghost_type) const {
return shapes_derivatives(FEEngine::getInterpolationType(el_type), ghost_type);
}
/* -------------------------------------------------------------------------- */
#define INIT_SHAPE_FUNCTIONS(type) \
- setControlPointsByType<type>(control_points, ghost_type); \
- precomputeShapesOnControlPoints<type>(nodes, ghost_type); \
+ setIntegrationPointsByType<type>(integration_points, ghost_type); \
+ precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type); \
if (ElementClass<type>::getNaturalSpaceDimension() == \
mesh.getSpatialDimension() || kind != _ek_regular) \
- precomputeShapeDerivativesOnControlPoints<type>(nodes, ghost_type);
+ precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
template <ElementKind kind>
inline void
ShapeLagrange<kind>::initShapeFunctions(const Array<Real> & nodes,
- const Matrix<Real> & control_points,
+ 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> & control_points,
+ __attribute__((unused)) const Matrix<Real> & integration_points,
__attribute__((unused)) const ElementType & type,
__attribute__((unused)) const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
#endif
#undef INIT_SHAPE_FUNCTIONS
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
inline void ShapeLagrange<kind>::
computeShapeDerivativesOnCPointsByElement(const Matrix<Real> & node_coords,
const Matrix<Real> & natural_coords,
Tensor3<Real> & shapesd) const {
AKANTU_DEBUG_IN();
// compute dnds
Tensor3<Real> dnds(node_coords.rows(), node_coords.cols(), natural_coords.cols());
ElementClass<type>::computeDNDS(natural_coords, dnds);
// compute dxds
Tensor3<Real> J(node_coords.rows(), natural_coords.rows(), natural_coords.cols());
ElementClass<type>::computeJMat(dnds, node_coords, J);
// compute shape derivatives
ElementClass<type>::computeShapeDerivatives(J, dnds, shapesd);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::inverseMap(const Vector<Real> & real_coords,
UInt elem,
Vector<Real> & natural_coords,
const GhostType & ghost_type) const{
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
mesh.extractNodalValuesFromElement(mesh.getNodes(),
nodes_coord.storage(),
elem_val + elem*nb_nodes_per_element,
nb_nodes_per_element,
spatial_dimension);
ElementClass<type>::inverseMap(real_coords,
nodes_coord,
natural_coords);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
bool ShapeLagrange<kind>::contains(const Vector<Real> & real_coords,
UInt elem,
const GhostType & ghost_type) const{
UInt spatial_dimension = mesh.getSpatialDimension();
Vector<Real> natural_coords(spatial_dimension);
inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
return ElementClass<type>::contains(natural_coords);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::interpolate(const Vector <Real> & real_coords,
UInt elem,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated,
const GhostType & ghost_type) const {
UInt nb_shapes = ElementClass<type>::getShapeSize();
Vector<Real> shapes(nb_shapes);
computeShapes<type>(real_coords, elem, shapes, ghost_type);
ElementClass<type>::interpolate(nodal_values, shapes, interpolated);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::computeShapes(const Vector<Real> & real_coords,
UInt elem,
Vector<Real> & shapes,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
Vector<Real> natural_coords(spatial_dimension);
inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
ElementClass<type>::computeShapes(natural_coords, shapes);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLagrange<kind>::computeShapeDerivatives(const Matrix<Real> & real_coords,
UInt elem,
Tensor3<Real> & shapesd,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_points = real_coords.cols();
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement();
AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == shapesd.size(0) && nb_nodes_per_element == shapesd.size(1),
"Shape size doesn't match");
AKANTU_DEBUG_ASSERT(nb_points == shapesd.size(2),
"Number of points doesn't match shapes size");
Matrix<Real> natural_coords(spatial_dimension, nb_points);
// Creates the matrix of natural coordinates
for (UInt i = 0 ; i < nb_points ; i++) {
Vector<Real> real_point = real_coords(i);
Vector<Real> natural_point = natural_coords(i);
inverseMap<type>(real_point, elem, natural_point, ghost_type);
}
UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
mesh.extractNodalValuesFromElement(mesh.getNodes(),
nodes_coord.storage(),
elem_val + elem*nb_nodes_per_element,
nb_nodes_per_element,
spatial_dimension);
computeShapeDerivativesOnCPointsByElement<type>(nodes_coord, natural_coords, shapesd);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
ShapeLagrange<kind>::ShapeLagrange(const Mesh & mesh,
const ID & id,
const MemoryID & memory_id) :
ShapeFunctions(mesh, id, memory_id),
shapes("shapes_generic", id),
shapes_derivatives("shapes_derivatives_generic", id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
-void ShapeLagrange<kind>::precomputeShapesOnControlPoints(__attribute__((unused)) const Array<Real> & nodes,
+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 = control_points(type, ghost_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>::precomputeShapeDerivativesOnControlPoints(const Array<Real> & nodes, GhostType ghost_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 = control_points(type, ghost_type);
+ 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>::interpolateOnControlPoints(const Array<Real> &in_u,
+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->interpolateElementalFieldOnControlPoints<type>(u_el, out_uq, ghost_type,
+ 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>::gradientOnControlPoints(const Array<Real> &in_u,
+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->gradientElementalFieldOnControlPoints<type>(u_el, out_nablauq, ghost_type,
+ 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 23b3f2217..48dc59731 100644
--- a/src/fe_engine/shape_linked.hh
+++ b/src/fe_engine/shape_linked.hh
@@ -1,158 +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> & control_points,
+ const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type);
- /// pre compute all shapes on the element control points from natural coordinates
+ /// pre compute all shapes on the element integration points from natural coordinates
template <ElementType type>
- void precomputeShapesOnControlPoints(const Array<Real> & nodes,
+ void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type);
- /// pre compute all shapes on the element control points from natural coordinates
+ /// pre compute all shapes on the element integration points from natural coordinates
template <ElementType type>
- void precomputeShapeDerivativesOnControlPoints(const Array<Real> & nodes,
+ void precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type);
- /// interpolate nodal values on the control points
+ /// interpolate nodal values on the integration points
template <ElementType type>
- void interpolateOnControlPoints(const Array<Real> &u,
+ 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 control points
+ /// compute the gradient of u on the integration points
template <ElementType type>
- void gradientOnControlPoints(const Array<Real> &u,
+ 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 a91ddcc10..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> & control_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) \
- setControlPointsByType<type>(control_points, ghost_type); \
- precomputeShapesOnControlPoints<type>(nodes, ghost_type); \
- precomputeShapeDerivativesOnControlPoints<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> & control_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>::precomputeShapesOnControlPoints(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 = control_points(type, ghost_type);
- UInt nb_points = control_points(type, ghost_type).cols();
+ 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>::precomputeShapeDerivativesOnControlPoints(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();
- Matrix<Real> & natural_coords = control_points(type, ghost_type);
+ UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
+ Matrix<Real> & natural_coords = integration_points(type, ghost_type);
UInt nb_points = natural_coords.cols();
UInt nb_element = mesh.getNbElement(type, ghost_type);
std::string ghost = "";
- if(ghost_type == _ghost) {
+ 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>::interpolateOnControlPoints(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 = control_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 interpolateElementalFieldOnControlPoints<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>::gradientOnControlPoints(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 = control_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 gradientElementalFieldOnControlPoints<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 17060ee9c..ea54bba64 100644
--- a/src/geometry/mesh_abstract_intersector.hh
+++ b/src/geometry/mesh_abstract_intersector.hh
@@ -1,78 +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 list of queries
+ /// 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 whatever result is needed from the user
+ /// 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 3d809e776..9782cee04 100644
--- a/src/geometry/mesh_abstract_intersector_tmpl.hh
+++ b/src/geometry/mesh_abstract_intersector_tmpl.hh
@@ -1,68 +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)
+ 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.cc b/src/geometry/mesh_geom_abstract.cc
deleted file mode 100644
index 0031a815d..000000000
--- a/src/geometry/mesh_geom_abstract.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * @file mesh_geom_abstract.cc
- *
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
- *
- * @date creation: Thu Feb 26 2015
- * @date last modification: Mon Mar 2 2015
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_abstract.hh"
-
-/* -------------------------------------------------------------------------- */
-
-__BEGIN_AKANTU__
-
-MeshGeomAbstract::MeshGeomAbstract(Mesh & mesh) :
- mesh(mesh)
-{}
-
-MeshGeomAbstract::~MeshGeomAbstract()
-{}
-
-__END_AKANTU__
diff --git a/src/geometry/mesh_geom_abstract.hh b/src/geometry/mesh_geom_abstract.hh
index 2309fdd07..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);
+ explicit MeshGeomAbstract(Mesh & mesh) : mesh(mesh) {};
/// Destructor
- virtual ~MeshGeomAbstract();
+ virtual ~MeshGeomAbstract() {};
public:
/// Construct geometric data for computational geometry algorithms
- virtual void constructData() = 0;
+ 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 8933f7aaa..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();
+ 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 7cc23fa9d..9f2450e3b 100644
--- a/src/geometry/mesh_geom_factory_tmpl.hh
+++ b/src/geometry/mesh_geom_factory_tmpl.hh
@@ -1,239 +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() {
+void MeshGeomFactory<dim, type, Primitive, Kernel>::constructData(GhostType ghost_type) {
AKANTU_DEBUG_IN();
- const GhostType ghost_type = _not_ghost;
-
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();
- Array<UInt>::const_vector_iterator begin = connectivity.begin(nb_nodes_per_element);
- Array<UInt>::const_vector_iterator it = connectivity.begin(nb_nodes_per_element);
- Array<UInt>::const_vector_iterator end = connectivity.end(nb_nodes_per_element);
+ 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) {
+ for (; it != end ; ++it, ++el_index) {
const Vector<UInt> & el_connectivity = *it;
- 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);
+ node_coordinates(j, i) = nodes(el_connectivity(i), j);
- addPrimitive(node_coordinates, it - begin);
+ // 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(1);
- s2.setId(id); s2.setSegId(2);
- s3.setId(id); s3.setSegId(3);
+ 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(1);
- s2.setId(id); s2.setSegId(2);
- s3.setId(id); s3.setSegId(3);
+ 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(1);
- s2.setId(id); s2.setSegId(2);
- s3.setId(id); s3.setSegId(3);
+ 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 53745a00d..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();
+ 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 875aa366c..ec2454717 100644
--- a/src/geometry/mesh_geom_intersector_tmpl.hh
+++ b/src/geometry/mesh_geom_intersector_tmpl.hh
@@ -1,59 +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)
+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() {
- factory.constructData();
+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 2ecfe0f54..940a8105a 100644
--- a/src/geometry/mesh_segment_intersector.hh
+++ b/src/geometry/mesh_segment_intersector.hh
@@ -1,98 +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 7989a25f7..37fe10631 100644
--- a/src/geometry/mesh_segment_intersector_tmpl.hh
+++ b/src/geometry/mesh_segment_intersector_tmpl.hh
@@ -1,261 +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 55bd08ab7..cc0b5335d 100644
--- a/src/geometry/mesh_sphere_intersector.hh
+++ b/src/geometry/mesh_sphere_intersector.hh
@@ -1,119 +1,105 @@
/**
- * @file mesh_segment_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__
-/* -------------------------------------------------------------------------- */
-/* class for new igfem elements mesh events */
-/* -------------------------------------------------------------------------- */
-#if defined(AKANTU_IGFEM)
-class NewIGFEMElementsEvent : public NewElementsEvent {
-public:
- AKANTU_GET_MACRO_NOT_CONST(OldElementsList, old_elements, Array<Element> &);
- AKANTU_GET_MACRO(OldElementsList, old_elements, const Array<Element> &);
-protected:
- Array<Element> old_elements;
-};
-#endif
-
-
/// 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();
- /* ------------------------------------------------------------------------ */
- /* Accessors */
- /* ------------------------------------------------------------------------ */
-public:
- /// get the new_node_per_elem array
- AKANTU_GET_MACRO(NewNodePerElem, new_node_per_elem, const Array<UInt>)
-
public:
/// Construct the primitive tree object
- virtual void constructData();
+ 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);
+ 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);
+ 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");
+ }
- /// Remove the additionnal nodes
- void removeAdditionnalNodes();
+ /// Set the tolerance
+ void setToleranceIntersectionOnNode(UInt tol) {
+ this->tol_intersection_on_node = tol;
+ }
protected:
- /// new node per element (column 0: number of new nodes, then odd is the intersection node number and even the ID of the sintersected segment)
- Array<UInt> new_node_per_elem;
-
- /// number of fem nodes in the initial mesh
- const UInt nb_nodes_fem;
-
- /// number of primitive in an element of the template type
- UInt nb_prim_by_el;
+ /// 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 1110e4e56..44a5120e0 100644
--- a/src/geometry/mesh_sphere_intersector_tmpl.hh
+++ b/src/geometry/mesh_sphere_intersector_tmpl.hh
@@ -1,414 +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),
- new_node_per_elem(0, 1 + 4*(dim-1)),
- nb_nodes_fem(mesh.getNodes().getSize()),
- nb_prim_by_el(0)
+ tol_intersection_on_node(1e-10)
{
- this->constructData();
-
- for(Mesh::type_iterator it = mesh.firstType(dim); it != mesh.lastType(dim); ++it){
#if defined(AKANTU_IGFEM)
- if(*it == _triangle_3){
- // Addition of the igfem types in the mesh
- this->mesh.addConnectivityType(_igfem_triangle_4, _not_ghost);
- this->mesh.addConnectivityType(_igfem_triangle_4, _ghost);
- this->mesh.addConnectivityType(_igfem_triangle_5, _not_ghost);
- this->mesh.addConnectivityType(_igfem_triangle_5, _ghost);
- }
-
- else if( (*it != _triangle_3) && (*it != _igfem_triangle_4) && (*it != _igfem_triangle_5) ) {
- AKANTU_DEBUG_ERROR("Not ready for mesh type " << *it);
- }
-
- if( (type == _triangle_3) || (type == _igfem_triangle_4) || (type == _igfem_triangle_5) ){
- this->nb_prim_by_el = 3;
- } else {
- AKANTU_DEBUG_ERROR("Not ready for mesh type " << type);
- }
+ 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( (*it != _triangle_3) )
- AKANTU_DEBUG_ERROR("Not ready for mesh type " << *it);
+ 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()
-{}
+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() {
+void MeshSphereIntersector<dim, type>::constructData(GhostType ghost_type) {
- this->new_node_per_elem.resize(this->mesh.getConnectivity(type).getSize());
- this->new_node_per_elem.clear();
+ 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();
+ MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK>::constructData(ghost_type);
}
template<UInt dim, ElementType type>
-void MeshSphereIntersector<dim, type>::computeIntersectionQuery(const SK::Sphere_3 & query) {
+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() ;
+ UInt nb_node = nodes.getSize() + this->intersection_points->getSize();
// Tolerance for proximity checks should be defined by user
- Math::setTolerance(1e-10);
+ 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();
- NewNodesEvent new_nodes;
- for (; it != end ; ++it) {
+ 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
- // Addition of the new node
+ // 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];
}
- bool is_on_mesh = false, is_new = true;
- // check if we already compute this intersection for a neighboor element
- UInt n = nb_nodes_fem-1;
- for (; n < nb_node ; ++n) {
- Array<Real>::vector_iterator existing_node = nodes.begin(dim) + n;
- if (Math::are_vector_equal(dim, new_node.storage(), existing_node->storage())) {
- is_new = false;
- break;
- }
- }
-
- 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 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) {
- nodes.push_back(new_node);
- new_nodes.getList().push_back(nb_node);
- nb_node++;
- }
-
- if (!is_on_mesh) {
- new_node_per_elem(it->id(), 0) += 1;
- new_node_per_elem(it->id(), (2 * new_node_per_elem(it->id(), 0)) - 1) = n;
- new_node_per_elem(it->id(), 2 * new_node_per_elem(it->id(), 0)) = it->segId();
- }
-
- else {
- // if intersection is at a node, write node number (in el) in pennultimate position
- if (Math::are_vector_equal(dim, source.storage(), new_node.storage())) {
- new_node_per_elem(it->id(), (new_node_per_elem.getNbComponent() - 2)) = it->segId() - 1;
- } else {
- new_node_per_elem(it->id(), (new_node_per_elem.getNbComponent() - 2)) =
- it->segId() % this->nb_prim_by_el;
- }
- }
- }
- }
- }
- }
-
- if(new_nodes.getList().getSize())
- this->mesh.sendEvent(new_nodes);
-
- AKANTU_DEBUG_OUT();
-}
-
-template<UInt dim, ElementType type>
-void MeshSphereIntersector<dim, type>::removeAdditionnalNodes() {
- AKANTU_DEBUG_IN();
-
- RemovedNodesEvent remove_nodes(this->mesh);
- Array<UInt> & nodes_removed = remove_nodes.getList();
- Array<UInt> & new_numbering = remove_nodes.getNewNumbering();
-
- for(UInt i = 0 ; i < nb_nodes_fem ; ++i){
- new_numbering(i) = i;
- }
-
- for(UInt i = nb_nodes_fem ; i < this->mesh.getNodes().getSize(); ++i){
- new_numbering(i) = UInt(-1) ;
- nodes_removed.push_back(i);
- }
-
- this->mesh.sendEvent(remove_nodes);
- AKANTU_DEBUG_OUT();
-}
-
-
-#if defined(AKANTU_IGFEM)
-
-template<UInt dim, ElementType type>
-void MeshSphereIntersector<dim, type>::buildResultFromQueryList(const std::list<SK::Sphere_3> & query_list) {
- AKANTU_DEBUG_IN();
-
- this->computeIntersectionQueryList(query_list);
-
- Array<UInt> & connec_type_tmpl = this->mesh.getConnectivity(type);
-
- Array<UInt>
- & connec_igfem_tri4 = this->mesh.getConnectivity(_igfem_triangle_4),
- & connec_igfem_tri5 = this->mesh.getConnectivity(_igfem_triangle_5),
- & connec_tri3 = this->mesh.getConnectivity(_triangle_3);
-
- Element element_tri3(_triangle_3, 0, _not_ghost, _ek_regular);
- Element element_tri4(_igfem_triangle_4, 0, _not_ghost, _ek_igfem);
- Element element_tri5(_igfem_triangle_5, 0, _not_ghost, _ek_igfem);
-
- NewIGFEMElementsEvent new_elements;
- UInt n_new_el = 0;
- Array<Element> & new_elements_list = new_elements.getList();
- Array<Element> & old_elements_list = new_elements.getOldElementsList();
-
- RemovedElementsEvent remove_elem(this->mesh);
- remove_elem.getNewNumbering().alloc(connec_type_tmpl.getSize(), 1, type, _not_ghost);
- Array<UInt> & new_numbering = remove_elem.getNewNumbering(type, _not_ghost);
- UInt new_nb_type_tmpl = 0; // Meter of the number of element (type) will we loop on elements
-
- for (UInt nel = 0 ; nel != new_node_per_elem.getSize(); ++nel) {
- if( (type != _triangle_3)
- && ( (new_node_per_elem(nel,0)==0)
- || ( (new_node_per_elem(nel,0) == 1)
- && ( ( (new_node_per_elem(nel,2)+1) % this->nb_prim_by_el )
- != new_node_per_elem(nel, new_node_per_elem.getNbComponent() - 2) ) ) ) ){
- Element element_type_tmpl(type, 0, _not_ghost, Mesh::getKind(type));
- new_elements_list.resize(n_new_el+1);
- old_elements_list.resize(n_new_el+1);
- Vector<UInt> ctri3(3);
- ctri3(0) = connec_type_tmpl(nel,0);
- ctri3(1) = connec_type_tmpl(nel,1);
- ctri3(2) = connec_type_tmpl(nel,2);
- /// add the new element in the mesh
- UInt nb_tri3 = connec_tri3.getSize();
- connec_tri3.push_back(ctri3);
- element_tri3.element = nb_tri3;
- new_elements_list(n_new_el) = element_tri3;
- /// the number of the old element in the mesh
- element_type_tmpl.element = nel;
- old_elements_list(n_new_el) = element_type_tmpl;
- new_numbering(nel) = UInt(-1);
- ++n_new_el;
-
- remove_elem.getList().push_back(element_type_tmpl);
-
- }
- else if( (new_node_per_elem(nel,0)!=0)
- && !( (new_node_per_elem(nel,0) == 1)
- && ( ( (new_node_per_elem(nel,2)+1) % this->nb_prim_by_el )
- != new_node_per_elem(nel, new_node_per_elem.getNbComponent() - 2) ) ) ){
- Element element_type_tmpl(type, 0, _not_ghost);
- element_type_tmpl.kind = Mesh::getKind(type);
- new_elements_list.resize(n_new_el+1);
- old_elements_list.resize(n_new_el+1);
- switch(new_node_per_elem(nel,0)){
- case 1 :{
- Vector<UInt> ctri4(4);
- switch(new_node_per_elem(nel,2)){
- case 1 :
- ctri4(0) = connec_type_tmpl(nel,2);
- ctri4(1) = connec_type_tmpl(nel,0);
- ctri4(2) = connec_type_tmpl(nel,1);
- break;
- case 2 :
- ctri4(0) = connec_type_tmpl(nel,0);
- ctri4(1) = connec_type_tmpl(nel,1);
- ctri4(2) = connec_type_tmpl(nel,2);
- break;
- case 3 :
- ctri4(0) = connec_type_tmpl(nel,1);
- ctri4(1) = connec_type_tmpl(nel,2);
- ctri4(2) = connec_type_tmpl(nel,0);
- break;
- default :
- AKANTU_DEBUG_ERROR("A triangle have only 3 segments not "<< new_node_per_elem(nel,2));
- break;
+ /// 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();
+ }
}
- ctri4(3) = new_node_per_elem(nel,1);
- UInt nb_tri4 = connec_igfem_tri4.getSize();
- connec_igfem_tri4.push_back(ctri4);
- element_tri4.element = nb_tri4;
- //new_elements.getList().push_back(element_tri4);
- new_elements_list(n_new_el) = element_tri4;
- if(type == _igfem_triangle_4)
- new_numbering.push_back(connec_igfem_tri4.getSize()-2);
- break;
}
- case 2 :{
- Vector<UInt> ctri5(5);
- if( (new_node_per_elem(nel,2)==1) && (new_node_per_elem(nel,4)==2) ){
- ctri5(0) = connec_type_tmpl(nel,1);
- ctri5(1) = connec_type_tmpl(nel,2);
- ctri5(2) = connec_type_tmpl(nel,0);
- ctri5(3) = new_node_per_elem(nel,3);
- ctri5(4) = new_node_per_elem(nel,1);
- }
- else if((new_node_per_elem(nel,2)==1) && (new_node_per_elem(nel,4)==3)){
- ctri5(0) = connec_type_tmpl(nel,0);
- ctri5(1) = connec_type_tmpl(nel,1);
- ctri5(2) = connec_type_tmpl(nel,2);
- ctri5(3) = new_node_per_elem(nel,1);
- ctri5(4) = new_node_per_elem(nel,3);
- }
- else if((new_node_per_elem(nel,2)==2) && (new_node_per_elem(nel,4)==3)){
- ctri5(0) = connec_type_tmpl(nel,2);
- ctri5(1) = connec_type_tmpl(nel,0);
- ctri5(2) = connec_type_tmpl(nel,1);
- ctri5(3) = new_node_per_elem(nel,3);
- ctri5(4) = new_node_per_elem(nel,1);
- }
- else if((new_node_per_elem(nel,2)==2) && (new_node_per_elem(nel,4)==1)){
- ctri5(0) = connec_type_tmpl(nel,1);
- ctri5(1) = connec_type_tmpl(nel,2);
- ctri5(2) = connec_type_tmpl(nel,0);
- ctri5(3) = new_node_per_elem(nel,1);
- ctri5(4) = new_node_per_elem(nel,3);
- }
- else if((new_node_per_elem(nel,2)==3) && (new_node_per_elem(nel,4)==1)){
- ctri5(0) = connec_type_tmpl(nel,0);
- ctri5(1) = connec_type_tmpl(nel,1);
- ctri5(2) = connec_type_tmpl(nel,2);
- ctri5(3) = new_node_per_elem(nel,3);
- ctri5(4) = new_node_per_elem(nel,1);
- }
- else if((new_node_per_elem(nel,2)==3) && (new_node_per_elem(nel,4)==2)){
- ctri5(0) = connec_type_tmpl(nel,2);
- ctri5(1) = connec_type_tmpl(nel,0);
- ctri5(2) = connec_type_tmpl(nel,1);
- ctri5(3) = new_node_per_elem(nel,1);
- ctri5(4) = new_node_per_elem(nel,3);
- }
- else{
- AKANTU_DEBUG_ERROR("A triangle have only 3 segments not "<< new_node_per_elem(nel,2) << "and" << new_node_per_elem(nel,4));
- }
- UInt nb_tri5 = connec_igfem_tri5.getSize();
- connec_igfem_tri5.push_back(ctri5);
- element_tri5.element = nb_tri5;
- //new_elements.getList().push_back(element_tri5);
- new_elements_list(n_new_el) = element_tri5;
- if(type == _igfem_triangle_5){
- new_numbering.push_back(new_nb_type_tmpl);
- ++new_nb_type_tmpl;
- }
- break;
- }
- default:
- AKANTU_DEBUG_ERROR("Igfem cannot add "<< new_node_per_elem(nel,0) << " nodes to triangles");
- break;
- }
- element_type_tmpl.element = nel;
- old_elements_list(n_new_el) = element_type_tmpl;
- remove_elem.getList().push_back(element_type_tmpl);
- new_numbering(nel) = UInt(-1);
- ++n_new_el;
- }
- else{
- new_numbering(nel) = new_nb_type_tmpl;
- ++new_nb_type_tmpl;
}
}
- // for(UInt nel=new_node_per_elem.getSize(); nel < this->mesh.getNbElement(type); ++nel) {
- // new_numbering(nel) = new_nb_type_tmpl;
- // ++new_nb_type_tmpl;
- // }
-
- UInt el_index = 0;
- for (UInt e = 0; e < this->mesh.getNbElement(type); ++e) {
- if (new_numbering(e) != UInt(-1)) {
- new_numbering(e) = el_index;
- ++el_index;
- }
- }
-
- if(n_new_el > 0){
- this->mesh.sendEvent(new_elements);
- this->mesh.sendEvent(remove_elem);
- }
+ Math::setTolerance(global_tolerance);
AKANTU_DEBUG_OUT();
}
-#else
-
-template<UInt dim, ElementType type>
-void MeshSphereIntersector<dim, type>::buildResultFromQueryList(const std::list<SK::Sphere_3> & query_list) {
- AKANTU_DEBUG_TO_IMPLEMENT();
-}
-
-
-#endif
-
__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 3aef9e96e..fceb2baee 100644
--- a/src/io/dumper/dumpable.cc
+++ b/src/io/dumper/dumpable.cc
@@ -1,307 +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>
+#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 1c93bf84e..24e641d36 100644
--- a/src/io/dumper/dumpable_inline_impl.hh
+++ b/src/io/dumper/dumpable_inline_impl.hh
@@ -1,137 +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) {
- dumper::Field * field_cont = new dumper::ElementalField<T>(field,
- spatial_dimension,
- ghost_type,
- element_kind);
+template <typename T>
+inline void Dumpable::addDumpFieldExternalToDumper(
+ const std::string & dumper_name, const std::string & field_id,
+ const ElementTypeMapArray<T> & field, UInt spatial_dimension,
+ const GhostType & ghost_type, const ElementKind & element_kind) {
+
+ dumper::Field * field_cont;
+#if defined(AKANTU_IGFEM)
+ if (element_kind == _ek_igfem) {
+ field_cont = new dumper::IGFEMElementalField<T>(field, spatial_dimension,
+ ghost_type, element_kind);
+ } else
+#endif
+ field_cont = new dumper::ElementalField<T>(field, spatial_dimension,
+ ghost_type, element_kind);
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerField(field_id, field_cont);
}
-
/* -------------------------------------------------------------------------- */
-template<class T>
+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 80f1ad5eb..3d7330154 100644
--- a/src/io/dumper/dumpable_iohelper.hh
+++ b/src/io/dumper/dumpable_iohelper.hh
@@ -1,196 +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 7f937ad14..b97c989dc 100644
--- a/src/io/dumper/dumper_compute.hh
+++ b/src/io/dumper/dumper_compute.hh
@@ -1,270 +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){
- return 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_connectivity_field.hh b/src/io/dumper/dumper_connectivity_field.hh
deleted file mode 100644
index 1bfce0a16..000000000
--- a/src/io/dumper/dumper_connectivity_field.hh
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * @file dumper_connectivity_field.hh
- *
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date creation: Tue Sep 02 2014
- * @date last modification: Thu Sep 04 2014
- *
- * @brief Connectivity field dumper
- *
- * @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/>.
- *
- */
-
-#if defined(AKANTU_COHESIVE_ELEMENT)
-
-/* -------------------------------------------------------------------------- */
-__BEGIN_AKANTU__
-__BEGIN_AKANTU_DUMPER__
-
-/* -------------------------------------------------------------------------- */
-template <class types>
-class cohesive_connectivity_field_iterator :
- public element_iterator<types, cohesive_connectivity_field_iterator> {
-
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
-public:
- typedef element_iterator<types, dumper::cohesive_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:
- cohesive_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) {
-
- write_order[_cohesive_3d_12].push_back(0);
- write_order[_cohesive_3d_12].push_back(1);
- write_order[_cohesive_3d_12].push_back(2);
- write_order[_cohesive_3d_12].push_back(6);
- write_order[_cohesive_3d_12].push_back(7);
- write_order[_cohesive_3d_12].push_back(8);
- write_order[_cohesive_3d_12].push_back(3);
- write_order[_cohesive_3d_12].push_back(4);
- write_order[_cohesive_3d_12].push_back(5);
- write_order[_cohesive_3d_12].push_back(9);
- write_order[_cohesive_3d_12].push_back(10);
- write_order[_cohesive_3d_12].push_back(11);
-
- write_order[_cohesive_3d_6].push_back(0);
- write_order[_cohesive_3d_6].push_back(1);
- write_order[_cohesive_3d_6].push_back(2);
- write_order[_cohesive_3d_6].push_back(3);
- write_order[_cohesive_3d_6].push_back(4);
- write_order[_cohesive_3d_6].push_back(5);
-
- write_order[_cohesive_2d_6].push_back(0);
- write_order[_cohesive_2d_6].push_back(2);
- write_order[_cohesive_2d_6].push_back(1);
- write_order[_cohesive_2d_6].push_back(4);
- write_order[_cohesive_2d_6].push_back(5);
- write_order[_cohesive_2d_6].push_back(3);
-
- write_order[_cohesive_2d_4].push_back(0);
- write_order[_cohesive_2d_4].push_back(1);
- write_order[_cohesive_2d_4].push_back(3);
- write_order[_cohesive_2d_4].push_back(2);
- }
-
- /* ------------------------------------------------------------------------ */
- /* Methods */
- /* ------------------------------------------------------------------------ */
-public
- return_type operator*() {
- const ElementType & type = *this->tit;
- const Vector<UInt> & conn = *this->array_it;
- Vector<UInt> new_conn(conn.size());
-
- for (UInt n = 0; n < conn.size(); ++n)
- new_conn(n) = conn(write_order[type][n]);
-
- return new_conn;
- }
-
- /* ------------------------------------------------------------------------ */
- /* Class Members */
- /* ------------------------------------------------------------------------ */
-protected:
- std::map<ElementType, std::vector<UInt> > write_order;
-};
-
-
-/* -------------------------------------------------------------------------- */
-class CohesiveConnectivityField :
- public GenericElementalField<SingleType<UInt,Vector,false>,
- cohesive_connectivity_field_iterator> {
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
-public:
- typedef SingleType<UInt,Vector,false> types;
- typedef cohesive_connectivity_field_iterator<types> iterator;
- typedef GenericElementalField<types,cohesive_connectivity_field_iterator> parent;
-
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-public:
- CohesiveConnectivityField(const field_type & field,
- UInt spatial_dimension = _all_dimensions,
- GhostType ghost_type = _not_ghost) :
- parent(field, spatial_dimension, ghost_type, _ek_cohesive) { }
-};
-
-/* -------------------------------------------------------------------------- */
-
-__END_AKANTU_DUMPER__
-__END_AKANTU__
-
-#endif
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_element_type.hh b/src/io/dumper/dumper_element_type.hh
deleted file mode 100644
index 4082fc373..000000000
--- a/src/io/dumper/dumper_element_type.hh
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @file dumper_element_type.hh
- *
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- *
- * @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
- *
- * @brief ElementType Field
- *
- * @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/>.
- *
- */
-
-__BEGIN_AKANTU__
-__BEGIN_AKANTU_DUMPER__
-/* -------------------------------------------------------------------------- */
-
-template <class types>
-class element_type_field_iterator
- : public element_iterator<types, element_type_field_iterator> {
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
-public:
- typedef element_iterator<types, dumper::element_type_field_iterator> parent;
-
- typedef typename types::data_type data_type;
- 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_type_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*() {
- data_type type = getIOHelperType(*this->tit);
- return return_type(1, type);
- }
-};
-
-/* -------------------------------------------------------------------------- */
-template <bool filtered = false>
-class ElementTypeField
- : public GenericElementalField<DualType<UInt,iohelper::ElemType,Vector,filtered>,
- element_type_field_iterator> {
-
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
-public:
- typedef DualType<UInt,iohelper::ElemType,Vector,filtered> types;
- typedef element_type_field_iterator<types> iterator;
- typedef typename types::field_type field_type;
- typedef GenericElementalField<types,element_type_field_iterator> parent;
-
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-public:
- ElementTypeField(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 */
- /* ------------------------------------------------------------------------ */
-public:
- 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 b3058ecb2..b36fcfae8 100644
--- a/src/io/dumper/dumper_field.hh
+++ b/src/io/dumper/dumper_field.hh
@@ -1,121 +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(){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 0cdf281d0..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 "dumper_iterator_helper.hh"
#include "element_type_map_filter.hh"
#include "dumper_element_iterator.hh"
#include "dumper_homogenizing_field.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <class _types, template <class> class iterator_type>
class GenericElementalField : public Field {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
public:
+ // check dumper_type_traits.hh for additional information over these types
typedef _types types;
typedef typename types::data_type data_type;
typedef typename types::it_type it_type;
typedef typename types::field_type field_type;
typedef typename types::array_type array_type;
typedef typename types::array_iterator array_iterator;
typedef typename field_type::type_iterator field_type_iterator;
typedef iterator_type<types> iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
GenericElementalField(const field_type & field,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind element_kind = _ek_not_defined)
: field(field), spatial_dimension(spatial_dimension),
ghost_type(ghost_type), element_kind(element_kind) {
this->checkHomogeneity();
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get the number of components of the hosted field
virtual ElementTypeMap<UInt>
getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined) {
return this->field.getNbComponents(dim, ghost_type, kind);
};
/// return the size of the contained data: i.e. the number of elements ?
virtual UInt size() {
checkHomogeneity();
return this->nb_total_element;
}
/// return the iohelper datatype to be dumped
iohelper::DataType getDataType() {
return iohelper::getDataType<data_type>();
}
protected:
/// return the number of entries per element
UInt getNbDataPerElem(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const {
if (!nb_data_per_elem.exists(type, ghost_type))
return field(type, ghost_type).getNbComponent();
return nb_data_per_elem(type, this->ghost_type);
}
/// check if the same quantity of data for all element types
virtual void checkHomogeneity();
public:
virtual void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) {
dumper.addElemDataField(id, *this);
};
/// for connection to a FieldCompute
inline virtual Field * connect(FieldComputeProxy & proxy) {
return proxy.connectToField(this);
}
/// for connection to a Homogenizer
inline virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy) {
return proxy.connectToField(this);
};
virtual iterator begin() {
field_type_iterator tit;
field_type_iterator end;
/// type iterators on the elemental field
tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
this->element_kind);
end = this->field.lastType(this->spatial_dimension, this->ghost_type,
this->element_kind);
/// skip all types without data
ElementType type = *tit;
for (; tit != end && this->field(*tit, this->ghost_type).getSize() == 0;
++tit) {
}
type = *tit;
if (tit == end)
return this->end();
/// getting information for the field of the given type
const array_type & vect = this->field(type, this->ghost_type);
UInt nb_data_per_elem = this->getNbDataPerElem(type);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.getSize() * nb_component) / nb_data_per_elem;
/// define element-wise iterator
array_iterator it = vect.begin_reinterpret(nb_data_per_elem, size);
array_iterator it_end = vect.end_reinterpret(nb_data_per_elem, size);
/// define data iterator
iterator rit =
iterator(this->field, tit, end, it, it_end, this->ghost_type);
rit.setNbDataPerElem(this->nb_data_per_elem);
return rit;
}
virtual iterator end() {
field_type_iterator tit;
field_type_iterator end;
tit = this->field.firstType(this->spatial_dimension, this->ghost_type,
this->element_kind);
end = this->field.lastType(this->spatial_dimension, this->ghost_type,
this->element_kind);
ElementType type = *tit;
for (; tit != end; ++tit)
type = *tit;
const array_type & vect = this->field(type, this->ghost_type);
UInt nb_data = this->getNbDataPerElem(type);
UInt nb_component = vect.getNbComponent();
UInt size = (vect.getSize() * nb_component) / nb_data;
array_iterator it = vect.end_reinterpret(nb_data, size);
iterator rit = iterator(this->field, end, end, it, it, this->ghost_type);
rit.setNbDataPerElem(this->nb_data_per_elem);
return rit;
}
virtual UInt getDim() {
if (this->homogeneous) {
field_type_iterator tit = this->field.firstType(
this->spatial_dimension, this->ghost_type, this->element_kind);
return this->getNbDataPerElem(*tit);
}
throw;
return 0;
}
void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data) {
nb_data_per_elem = nb_data;
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the ElementTypeMapArray embedded in the field
const field_type & field;
/// total number of elements
UInt nb_total_element;
/// the spatial dimension of the problem
UInt spatial_dimension;
/// whether this is a ghost field or not (for type selection)
GhostType ghost_type;
/// The element kind to operate on
ElementKind element_kind;
/// The number of data per element type
ElementTypeMap<UInt> nb_data_per_elem;
};
/* -------------------------------------------------------------------------- */
#include "dumper_generic_elemental_field_tmpl.hh"
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__ __END_AKANTU__
#endif /* __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_generic_elemental_field_tmpl.hh b/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
index 9ef53f79a..ee491bd10 100644
--- a/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
+++ b/src/io/dumper/dumper_generic_elemental_field_tmpl.hh
@@ -1,67 +1,67 @@
/**
* @file dumper_generic_elemental_field_tmpl.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
+ * @date last modification: Sun Oct 19 2014
*
* @brief Implementation of the template functions of the ElementalField
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
template<class types, template <class> class iterator>
void GenericElementalField<types,iterator>::checkHomogeneity() {
typedef typename field_type::type_iterator field_type_iterator;
typedef typename field_type::array_type array_type;
field_type_iterator tit;
field_type_iterator end;
tit = field.firstType(spatial_dimension, ghost_type, element_kind);
end = field.lastType(spatial_dimension, ghost_type, element_kind);
this->nb_total_element = 0;
UInt nb_comp = 0;
bool homogen = true;
if(tit != end) {
nb_comp = this->field(*tit, ghost_type).getNbComponent();
for(;tit != end; ++tit) {
const array_type & vect = this->field(*tit, ghost_type);
UInt nb_element = vect.getSize();
UInt nb_comp_cur = vect.getNbComponent();
if(homogen && nb_comp != nb_comp_cur) homogen = false;
this->nb_total_element += nb_element;
// this->nb_data_per_elem(*tit,this->ghost_type) = nb_comp_cur;
}
if(!homogen) nb_comp = 0;
}
this->homogeneous = homogen;
}
/* -------------------------------------------------------------------------- */
diff --git a/src/io/dumper/dumper_homogenizing_field.hh b/src/io/dumper/dumper_homogenizing_field.hh
index 9317030f0..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
new file mode 100644
index 000000000..84c68f24f
--- /dev/null
+++ b/src/io/dumper/dumper_internal_material_field.hh
@@ -0,0 +1,78 @@
+/**
+ * @file dumper_internal_material_field.hh
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Sep 17 2015
+ *
+ * @brief description of material internal field
+ *
+ * @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/>.
+ *
+ */
+
+#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 e8b67cbb9..7e431f426 100644
--- a/src/io/dumper/dumper_iohelper.cc
+++ b/src/io/dumper/dumper_iohelper.cc
@@ -1,310 +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_connectivity_field.hh"
-#include "dumper_element_type.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_COHESIVE_ELEMENT)
-// if (element_kind == _ek_cohesive) {
-// registerField("connectivities",
-// new dumper::CohesiveConnectivityField(mesh.getConnectivities(),
-// spatial_dimension,
-// ghost_type));
-// } else
-// #endif
#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("element_type",
- // new dumper::ElementTypeField<>(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("element_type",
- // new dumper::ElementTypeField<true>(*f_connectivities,
- // 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_iterator_helper.hh b/src/io/dumper/dumper_iterator_helper.hh
deleted file mode 100644
index a92e6a430..000000000
--- a/src/io/dumper/dumper_iterator_helper.hh
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * @file dumper_iterator_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
- *
- * @brief Helper to write field iterators
- *
- * @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_DUMPER_ITERATOR_HELPER_HH__
-#define __AKANTU_DUMPER_ITERATOR_HELPER_HH__
-/* -------------------------------------------------------------------------- */
-
-__BEGIN_AKANTU__
-__BEGIN_AKANTU_DUMPER__
-
-template<class T, class R>
-class iterator_helper {
-
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
-public:
-
-
- typedef typename Array<T>::template const_iterator< R > internal_iterator;
-
- /* ------------------------------------------------------------------------ */
- /* Methods */
- /* ------------------------------------------------------------------------ */
-
-public:
-
- static internal_iterator begin(const Array<T> & vect, UInt m, UInt n, UInt size) {
- return vect.begin_reinterpret(n*m, size);
- }
-
- static internal_iterator end(const Array<T> & vect, UInt m, UInt n, UInt size) {
- return vect.end_reinterpret(n*m, size);
- }
-};
-
-/* -------------------------------------------------------------------------- */
-
-template<class T>
-class iterator_helper<T, Matrix<T> > {
-
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
-
-public:
-
- typedef typename Array<T>::template const_iterator< Matrix<T> > internal_iterator;
-
-public:
-
- /* ------------------------------------------------------------------------ */
- /* Methods */
- /* ------------------------------------------------------------------------ */
-
-
- static internal_iterator begin(const Array<T> & vect, UInt m, UInt n, UInt size) {
- return vect.begin_reinterpret(m, n, size);
- }
-
- static internal_iterator end(const Array<T> & vect, UInt m, UInt n, UInt size) {
- return vect.end_reinterpret(m, n, size);
- }
-};
-
-
-/* -------------------------------------------------------------------------- */
-
-__END_AKANTU_DUMPER__
-__END_AKANTU__
-
-
-#endif /* __AKANTU_DUMPER_ITERATOR_HELPER_HH__ */
diff --git a/src/io/dumper/dumper_material_internal_field.hh b/src/io/dumper/dumper_material_internal_field.hh
deleted file mode 100644
index bcd0deba8..000000000
--- a/src/io/dumper/dumper_material_internal_field.hh
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * @file dumper_material_internal_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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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_INTERNAL_FIELD_HH__
-#define __AKANTU_DUMPER_MATERIAL_INTERNAL_FIELD_HH__
-/* -------------------------------------------------------------------------- */
-#include "dumper_quadrature_points_field.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_MATERIAL_INTERNAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_material_padders.hh b/src/io/dumper/dumper_material_padders.hh
index 1ffecd8da..386d8b42d 100644
--- a/src/io/dumper/dumper_material_padders.hh
+++ b/src/io/dumper/dumper_material_padders.hh
@@ -1,290 +1,295 @@
/**
* @file dumper_material_padders.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue Sep 02 2014
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Fri Mar 27 2015
*
* @brief Material padders for plane stress/ plane strain
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_DUMPER_MATERIAL_PADDERS_HH__
#define __AKANTU_DUMPER_MATERIAL_PADDERS_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_padding_helper.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
class MaterialFunctor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- MaterialFunctor(const SolidMechanicsModel & model) :
- model(model),
- material_index(model.getMaterialByElement()),
- spatial_dimension(model.getSpatialDimension()){}
+ MaterialFunctor(const SolidMechanicsModel & model)
+ : model(model), material_index(model.getMaterialByElement()),
+ spatial_dimension(model.getSpatialDimension()) {}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
/// return the material from the global element index
- const Material & getMaterialFromGlobalIndex(Element global_index){
+ 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
new file mode 100644
index 000000000..7c740aa4e
--- /dev/null
+++ b/src/io/dumper/dumper_quadrature_point_iterator.hh
@@ -0,0 +1,77 @@
+/**
+ * @file dumper_quadrature_point_iterator.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Tue Sep 02 2014
+ * @date last modification: Thu Sep 17 2015
+ *
+ * @brief Description of quadrature point iterator
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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_quadrature_points_field.hh b/src/io/dumper/dumper_quadrature_points_field.hh
deleted file mode 100644
index 7fa4f0c9d..000000000
--- a/src/io/dumper/dumper_quadrature_points_field.hh
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * @file dumper_quadrature_points_field.hh
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Tue Sep 02 2014
- * @date last modification: Tue Sep 02 2014
- *
- * @brief Description of quadrature points fields
- *
- * @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_DUMPER_IOHELPER_TMPL_QUADRATURE_POINTS_FIELD_HH__
-#define __AKANTU_DUMPER_IOHELPER_TMPL_QUADRATURE_POINTS_FIELD_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;
- }
-};
-
- /* -------------------------------------------------------------------------- */
- /* Fields type description */
- /* -------------------------------------------------------------------------- */
- template<class types, template <class> class iterator_type>
- class GenericQuadraturePointsField :
- public GenericElementalField<types,iterator_type> {
-
- public:
-
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
-
-
- typedef iterator_type<types> iterator;
- typedef typename types::field_type field_type;
- typedef typename iterator::it_type T;
- typedef GenericElementalField<types,iterator_type> parent;
-
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-
- GenericQuadraturePointsField(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) { }
-
- /* ------------------------------------------------------------------------ */
- /* Methods */
- /* ------------------------------------------------------------------------ */
-
- virtual iterator begin() {
- iterator it = parent::begin();
- return it;
- }
-
- virtual iterator end () {
- iterator it = parent::end();
- return it;
- }
-
- };
-
-/* -------------------------------------------------------------------------- */
-
-__END_AKANTU_DUMPER__
-__END_AKANTU__
-
-#endif /* __AKANTU_DUMPER_IOHELPER_TMPL_QUADRATURE_POINTS_FIELD_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 e168afd34..be7ce42ce 100644
--- a/src/io/dumper/dumper_type_traits.hh
+++ b/src/io/dumper/dumper_type_traits.hh
@@ -1,92 +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 1b02585ce..0e01e4be9 100644
--- a/src/io/mesh_io/mesh_io_abaqus.cc
+++ b/src/io/mesh_io/mesh_io_abaqus.cc
@@ -1,544 +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_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/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,
- 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() << ".");
+ template <class EG, class ID, class Map>
+ void operator()(EG * el_grp, const ID & element,
+ const Map & elements_mapping) const {
+ typename Map::const_iterator eit = elements_mapping.find(element);
+ AKANTU_DEBUG_ASSERT(eit != elements_mapping.end(),
+ "There is an unknown element ("
+ << element << ") in the in the ELSET "
+ << el_grp->getName() << ".");
- el_grp->add(eit->second, true, false);
- }
- };
+ 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
- )
+ (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
- )
+ >> *( (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)
- )
+ >> 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
- )
+ >> *( (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_(',') >> 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) ]
+ ^ *(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_(',')
+ >> 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::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) ]
+ 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;
+ >> 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");
+ 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");
+ 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::back_inserter(storage));
+ 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);
-
- 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;
- }
+ Array<std::string> & abaqus_material =
+ this->getData<std::string>(mesh, "abaqus_material", *tit);
+
+ ElementGroup::const_element_iterator eit = eg.element_begin(*tit);
+ ElementGroup::const_element_iterator eend = eg.element_end(*tit);
+ for (; eit != eend; ++eit) {
+ abaqus_material(*eit) = *mnit;
+ }
}
}
}
this->setNbGlobalNodes(mesh, mesh.getNodes().getSize());
MeshUtils::fillElementToSubElementsData(mesh);
}
-
-
__END_AKANTU__
diff --git a/src/io/mesh_io/mesh_io_abaqus.hh b/src/io/mesh_io/mesh_io_abaqus.hh
index 4ed265243..3cd861fec 100644
--- a/src/io/mesh_io/mesh_io_abaqus.hh
+++ b/src/io/mesh_io/mesh_io_abaqus.hh
@@ -1,59 +1,60 @@
/**
* @file mesh_io_abaqus.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Jan 16 2013
- * @date last modification: Fri Jun 13 2014
+ * @date creation: Sun Sep 26 2010
+ * @date last modification: Tue Jun 30 2015
*
* @brief read a mesh from an abaqus input file
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_io.hh"
#include "mesh_accessor.hh"
#ifndef __AKANTU_MESH_IO_ABAQUS_HH__
#define __AKANTU_MESH_IO_ABAQUS_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class MeshIOAbaqus : public MeshIO, private MeshAccessor {
public:
MeshIOAbaqus();
virtual ~MeshIOAbaqus();
/// read a mesh from the file
virtual void read(const std::string & filename, Mesh & mesh);
/// write a mesh to a file
// virtual void write(const std::string & filename, const Mesh & mesh);
private:
/// correspondence between msh element types and akantu element types
std::map<std::string, ElementType> _abaqus_to_akantu_element_types;
};
__END_AKANTU__
#endif /* __AKANTU_MESH_IO_ABAQUS_HH__ */
diff --git a/src/io/mesh_io/mesh_io_diana.cc b/src/io/mesh_io/mesh_io_diana.cc
index cdc1abc28..42ea07a41 100644
--- a/src/io/mesh_io/mesh_io_diana.cc
+++ b/src/io/mesh_io/mesh_io_diana.cc
@@ -1,774 +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;
+ 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";
-}
-/* -------------------------------------------------------------------------- */
-MeshIODiana::~MeshIODiana() {
- std::map<std::string, Array<UInt> *>::iterator ng_it;
- std::map<std::string, std::vector<Element> *>::iterator eg_it;
+ 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);
- for (ng_it = node_groups.begin(); ng_it != node_groups.end(); ++ng_it) {
- delete ng_it->second;
- }
+ UInt * tmp = new UInt[nb_nodes];
+ for (UInt i = 0; i < nb_nodes; ++i) {
+ tmp[i] = i;
+ }
- for (eg_it = element_groups.begin(); eg_it != element_groups.end(); ++eg_it) {
- delete eg_it->second;
+ 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
+ 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);
- }
+ if (!infile.good()) { AKANTU_DEBUG_ERROR("Cannot open file " << filename); }
- while(infile.good()) {
+ while (infile.good()) {
my_getline(infile, line);
/// read all nodes
- if(line == "'COORDINATES'") {
+ 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);
- }
+ if (line == "'MATERIALS'") { line = readMaterial(infile, filename); }
/// read the material properties and write a .dat file
if (line == "'GROUPS'") {
- line = readGroups(infile, first_node_number);
+ 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) {
+ __attribute__((unused)) const Mesh & mesh) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
-std::string MeshIODiana::readCoordinates(std::ifstream & infile, Mesh & mesh, UInt & first_node_number) {
+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;
- //end = true;
- //else {
- /// for each node, read the coordinates
+ if ("'ELEMENTS'" == line) break;
std::stringstream sstr_node(line);
-
sstr_node >> index >> coord[0] >> coord[1] >> coord[2];
- //if (!sstr_node.fail())
- //break;
-
first_node_number = first_node_number < index ? first_node_number : index;
nodes.push_back(coord);
- // }
- } while(true);//!end);
+ } while (true);
AKANTU_DEBUG_OUT();
return line;
}
/* -------------------------------------------------------------------------- */
UInt MeshIODiana::readInterval(std::stringstream & line,
- std::set<UInt> & interval) {
-
- int space;
- space = line.get();
- while (space == ' '){
- space = line.get();
- if(line.fail()) {
- line.clear(std::ios::eofbit);
- return 0;
- }
- }
- if(!line.fail()) line.unget();
- else {
- line.clear(std::ios::eofbit);
- return 0;
- }
-
+ std::set<UInt> & interval) {
UInt first;
line >> first;
- if(line.fail()) { return 0; }
+ if (line.fail()) { return 0; }
interval.insert(first);
- // std::cerr << "first: " << first << std::endl;
-
UInt second;
int dash;
dash = line.get();
- if(dash == '-') {
+ if (dash == '-') {
line >> second;
interval.insert(second);
-
- // std::cerr << "second: " << second << std::endl;
-
- int bracket;
- UInt unknown_stuff;
- bracket = line.get();
- if(bracket == '('){
- line >> unknown_stuff;
- bracket = line.get();
- }
- else{
- if(line.fail()) line.clear(std::ios::eofbit);
- else line.unget();
- }
return 2;
}
- if(line.fail())
- line.clear(std::ios::eofbit); // in case of get at end of the line
- else line.unget();
+ 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,
- UInt first_node_number) {
+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;
+ while (line != "'SUPPORTS'") {
+ if (line == "NODES") {
+ reading_nodes_group = true;
my_getline(infile, line);
}
- if(line == "ELEMEN") {
- reading_nodes_group = false;
+ if (line == "ELEMEN") {
+ reading_nodes_group = false;
my_getline(infile, line);
}
- // std::cerr << line << std::endl;
- std::stringstream *str = new std::stringstream(line);
+ std::stringstream * str = new std::stringstream(line);
UInt id;
std::string name;
char c;
*str >> id >> name >> c;
- // std::cerr << "AAAA " << id << " " << name << " " << c << std::endl;
-
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);
- }
- }
+ 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;
+ if (str->fail())
+ end = true;
else {
- my_getline(infile, line);
- delete str;
- str = new std::stringstream(line);
- s = 1;
+ my_getline(infile, line);
+ delete str;
+ str = new std::stringstream(line);
}
}
delete str;
- if(reading_nodes_group) {
-
- // reading a node group
-
+ if (reading_nodes_group) {
+ NodeGroup & ng = mesh.createNodeGroup(name);
for (UInt i = 0; i < list_ids->getSize(); ++i) {
- (*list_ids)(i) -= first_node_number;
+ UInt node = (*list_ids)(i) - first_node_number;
+ ng.add(node, false);
}
- node_groups[name] = list_ids;
- } else {
-
- // reading an element group
+ delete list_ids;
- std::vector<Element> * elem = new std::vector<Element>;
- elem->reserve(list_ids->getSize());
+ } else {
+ ElementGroup & eg = mesh.createElementGroup(name);
for (UInt i = 0; i < list_ids->getSize(); ++i) {
- Element & e = diana_element_number_to_elements[(*list_ids)(i)];
- if(e.type != _not_defined)
- elem->push_back(e);
+ Element & elem = diana_element_number_to_elements[ (*list_ids)(i)];
+ if (elem.type != _not_defined) eg.add(elem, false, false);
}
- element_groups[name] = elem;
+ 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) {
+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) {
+ if ("CONNECTIVITY" == line) {
line = readConnectivity(infile, mesh, first_node_number);
}
/// read the line corresponding to the materials
- if ("MATERIALS" == line) {
- line = readMaterialElement(infile, mesh);
- }
+ 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) {
+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;
+ 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;
+ 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) {
+ if (akantu_type == _not_defined) continue;
+
+ if (akantu_type != akantu_type_old) {
connectivity = mesh.getConnectivityPointer(akantu_type);
-
+
node_per_element = connectivity->getNbComponent();
akantu_type_old = akantu_type;
+ read_order = _read_order[akantu_type];
}
-
- UInt local_connect[node_per_element];
-
- //used if element is written on two lines
- UInt j_last = 0;
-
- for(UInt j = 0; j < node_per_element; ++j) {
+
+ 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;
+ sstr_elem.clear();
+ sstr_elem.ignore();
+ break;
}
-
+
node_index -= first_node_number;
- local_connect[j] = node_index;
+ 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
-
+ 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[j] = node_index;
- }
- }
-
- // Exceptions
- UInt local_connect_non_modified[node_per_element];
-
- // Create a new unmodified vector
- for(UInt k = 0; k < node_per_element; ++k) {
- local_connect_non_modified[k] = local_connect[k];
- }
-
- switch(akantu_type){
-
- case _triangle_6:
- local_connect[0] = local_connect_non_modified[0];
- local_connect[1] = local_connect_non_modified[2];
- local_connect[2] = local_connect_non_modified[4];
- local_connect[3] = local_connect_non_modified[1];
- local_connect[4] = local_connect_non_modified[3];
- local_connect[5] = local_connect_non_modified[5];
- break;
- case _quadrangle_8:
- local_connect[0] = local_connect_non_modified[0];
- local_connect[1] = local_connect_non_modified[2];
- local_connect[2] = local_connect_non_modified[4];
- local_connect[3] = local_connect_non_modified[6];
- local_connect[4] = local_connect_non_modified[1];
- local_connect[5] = local_connect_non_modified[3];
- local_connect[6] = local_connect_non_modified[5];
- local_connect[7] = local_connect_non_modified[7];
- break;
-
- case _pentahedron_15:
- local_connect[0] = local_connect_non_modified[2];
- local_connect[1] = local_connect_non_modified[4];
- local_connect[2] = local_connect_non_modified[0];
- local_connect[3] = local_connect_non_modified[11];
- local_connect[4] = local_connect_non_modified[13];
- local_connect[5] = local_connect_non_modified[9];
- local_connect[6] = local_connect_non_modified[3];
- local_connect[7] = local_connect_non_modified[5];
- local_connect[8] = local_connect_non_modified[1];
- local_connect[9] = local_connect_non_modified[7];
- local_connect[10] =local_connect_non_modified[8];
- local_connect[11] =local_connect_non_modified[6];
- local_connect[12] =local_connect_non_modified[12];
- local_connect[13] =local_connect_non_modified[14];
- local_connect[14] =local_connect_non_modified[10];
- break;
-
- case _hexahedron_20:
- local_connect[0] = local_connect_non_modified[14];
- local_connect[8] = local_connect_non_modified[13];
- local_connect[1] = local_connect_non_modified[12];
- local_connect[9] = local_connect_non_modified[19];
- local_connect[2] = local_connect_non_modified[18];
- local_connect[10] = local_connect_non_modified[17];
- local_connect[3] = local_connect_non_modified[16];
- local_connect[11] = local_connect_non_modified[15];
- local_connect[12] = local_connect_non_modified[9];
- local_connect[13] = local_connect_non_modified[8];
- local_connect[14] = local_connect_non_modified[11];
- local_connect[15] = local_connect_non_modified[10];
- local_connect[4] = local_connect_non_modified[2];
- local_connect[16] = local_connect_non_modified[1];
- local_connect[5] = local_connect_non_modified[0];
- local_connect[17] = local_connect_non_modified[7];
- local_connect[6] = local_connect_non_modified[6];
- local_connect[18] = local_connect_non_modified[5];
- local_connect[7] = local_connect_non_modified[4];
- local_connect[19] = local_connect_non_modified[3];
- break;
+ for (UInt j = (j_last + 1); j < node_per_element; ++j) {
- default:
- //nothing to change
- break;
+ 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) {
+ Mesh & mesh) {
AKANTU_DEBUG_IN();
-
std::string line;
- std::stringstream sstr_tag_name; sstr_tag_name << "tag_" << 0;
+ std::stringstream sstr_tag_name;
+ sstr_tag_name << "tag_" << 0;
- Mesh::type_iterator it = mesh.firstType();
+ Mesh::type_iterator it = mesh.firstType();
Mesh::type_iterator end = mesh.lastType();
- for(; it != end; ++it) {
+ for (; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it);
- mesh.getDataPointer<UInt>("material", *it, _not_ghost, 1)->resize(nb_element);
+ 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
+ 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);
+ AKANTU_DEBUG_WARNING("reading line " << line);
Array<UInt> temp_id(0, 2);
UInt mat;
- while(true){
+ 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);
+ 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;
+ 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;
+ 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) {
+ 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());
+ 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{
+ 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();
+ 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 {
+ } 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();
- }
+ 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;
+ 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");
+ AKANTU_DEBUG_INFO("In material reader, property " << prop_name
+ << "not recognized");
}
}
} while (!end);
AKANTU_DEBUG_OUT();
return line;
}
/* -------------------------------------------------------------------------- */
-void MeshIODiana::createElementGroupInMesh(Mesh & mesh, const std::string & group_name) {
-
- std::map<std::string, std::vector<Element> *>::iterator git
- = element_groups.find(group_name);
-
- if (git == element_groups.end()) {
- AKANTU_EXCEPTION("group '" << group_name
- << "' not found in data loaded from Diana");
- }
-
- std::vector<Element> & element_group = *git->second;
-
- if (element_group.size() == 0) return;
-
- // std::cerr << "adding group " << group_name << std::endl;
- Element & first_element = element_group[0];
-
- UInt group_dim = mesh.getSpatialDimension(first_element.type);
- mesh.createElementGroup(group_name, group_dim);
- ElementGroup & group = mesh.getElementGroup(git->first);
-
- std::vector<Element>::iterator it = element_group.begin();
- std::vector<Element>::iterator end = element_group.end();
-
- for(; it != end; ++it){
- group.add(*it,true,false);
- }
-
-}
-
-/* -------------------------------------------------------------------------- */
-
-void MeshIODiana::createNodeGroupInMesh(Mesh & mesh, const std::string & group_name) {
-
- std::map<std::string, Array<UInt> *>::iterator git
- = node_groups.find(group_name);
-
- if (git == node_groups.end()) {
- AKANTU_EXCEPTION("group '" << group_name
- << "' not found in data loaded from Diana");
- }
-
- Array<UInt> & node_group = *git->second;
-
- mesh.createNodeGroup(group_name);
- NodeGroup & group = mesh.getNodeGroup(git->first);
-
- Array<UInt>::iterator<UInt> it = node_group.begin();
- Array<UInt>::iterator<UInt> end = node_group.end();
-
- for(; it != end; ++it){
- group.add(*it);
- }
-
-}
-
-
-
-
-/* -------------------------------------------------------------------------- */
-
-void MeshIODiana::printself(std::ostream & stream,int indent) const {
-
- MeshIO::printself(stream,indent);
-
- std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
- if (node_groups.size()){
- stream << space << "Read node groups: ";
- std::map<std::string, Array<UInt> *>::const_iterator it = node_groups.begin();
- std::map<std::string, Array<UInt> *>::const_iterator end = node_groups.end();
-
- for (;it != end; ++it) {
- stream << "'" << it->first << "' ";
- }
- stream << std::endl;
- }
-
- if (element_groups.size()){
- stream << space << "Read element groups: ";
- std::map<std::string, std::vector<Element> *>::const_iterator it = element_groups.begin();
- std::map<std::string, std::vector<Element> *>::const_iterator end = element_groups.end();
-
- for (;it != end; ++it) {
- stream << "'" << it->first << "' ";
- }
- stream << std::endl;
- }
-}
-
-/* -------------------------------------------------------------------------- */
-
-void MeshIODiana::onNodesRemoved(const Array<UInt> & element_list,
- const Array<UInt> & new_numbering,
- const RemovedNodesEvent & event) {
- std::map<std::string, Array<UInt> *>::iterator it = node_groups.begin();
- std::map<std::string, Array<UInt> *>::iterator end = node_groups.end();
- for (; it != end; ++it) {
- Array<UInt> & group = *(it->second);
- Array<UInt>::iterator<> git = group.begin();
- Array<UInt>::iterator<> gend = group.end();
- for (; git != gend; ++git) {
- UInt new_id = new_numbering(*git);
- AKANTU_DEBUG_ASSERT(new_id != UInt(-1), "Argh " << *git << " was suppressed!");
- *git = new_id;
- }
- }
-}
-
-
-
__END_AKANTU__
diff --git a/src/io/mesh_io/mesh_io_diana.hh b/src/io/mesh_io/mesh_io_diana.hh
index 05ac755d5..737c4de68 100644
--- a/src/io/mesh_io/mesh_io_diana.hh
+++ b/src/io/mesh_io/mesh_io_diana.hh
@@ -1,160 +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 , public MeshEventHandler{
+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);
+ 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);
- /// request creation of an element group from data read from Diana file
- void createElementGroupInMesh(Mesh & mesh, const std::string & group_name);
- /// request creation of a nodal group from data read from Diana file
- void createNodeGroupInMesh(Mesh & mesh, const std::string & group_name);
-
private:
- std::string readCoordinates(std::ifstream & infile,
- Mesh & mesh,
- UInt & first_node_number);
+ 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 readElements(std::ifstream & infile, Mesh & mesh,
+ UInt first_node_number);
- std::string readGroups(std::ifstream & infile,
- 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 readConnectivity(std::ifstream & infile, Mesh & mesh,
+ UInt first_node_number);
- std::string readMaterialElement(std::ifstream & infile,
- Mesh & mesh);
+ std::string readMaterialElement(std::ifstream & infile, Mesh & mesh);
std::string readMaterial(std::ifstream & infile,
- const std::string & filename);
+ const std::string & filename);
- UInt readInterval(std::stringstream & line,
- std::set<UInt> & interval);
-
- virtual void printself(std::ostream & stream, int indent = 0) const;
+ UInt readInterval(std::stringstream & line, std::set<UInt> & interval);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
- const Array<UInt> & getNodeGroup(const std::string & group_name) const {
- std::map<std::string, Array<UInt> *>::const_iterator it = node_groups.find(group_name);
- AKANTU_DEBUG_ASSERT(it != node_groups.end(), "There is no nodes group named : " << group_name);
- return *it->second;
- }
-
- const std::vector<Element> & getElementGroup(const std::string & group_name) const {
- std::map<std::string, std::vector<Element> *>::const_iterator it = element_groups.find(group_name);
- AKANTU_DEBUG_ASSERT(it != element_groups.end(), "There is no elements group named : " << group_name);
- return *it->second;
- }
-
- std::vector<std::string> getNodeGroupsNames() const {
- std::vector<std::string> names;
- std::map<std::string, Array<UInt> *>::const_iterator it;
- for(it = node_groups.begin(); it != node_groups.end(); ++it)
- names.push_back(it->first);
-
- return names;
- }
-
- std::vector<std::string> getElementGroupsNames() const {
- std::vector<std::string> names;
- std::map<std::string, std::vector<Element> *>::const_iterator it;
- for(it = element_groups.begin(); it != element_groups.end(); ++it)
- names.push_back(it->first);
-
- return names;
- }
-
- /* ------------------------------------------------------------------------ */
- /* Mesh Event Handler inherited members */
- /* ------------------------------------------------------------------------ */
-protected:
- virtual void onNodesRemoved(const Array<UInt> & element_list,
- const Array<UInt> & new_numbering,
- const RemovedNodesEvent & event);
-
/* ------------------------------------------------------------------------ */
/* 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<std::string, Array<UInt> *> node_groups;
- std::map<std::string, std::vector<Element> *> element_groups;
-
- std::map<UInt,Element> diana_element_number_to_elements;
- std::map<Element,UInt> akantu_number_to_diana_number;
+ 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 4f53866ed..5326adf68 100644
--- a/src/io/mesh_io/mesh_io_msh.cc
+++ b/src/io/mesh_io/mesh_io_msh.cc
@@ -1,555 +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;
+ 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_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_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_prism_18 ] = _not_defined;
- _msh_to_akantu_element_types[_msh_hexahedron_20 ] = _hexahedron_20;
- _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;
+ _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) {
+ 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];
- UInt * tmp = new UInt[nb_nodes];
+ std::vector<UInt> tmp(nb_nodes);
for (UInt i = 0; i < nb_nodes; ++i) {
tmp[i] = i;
}
- switch(it->first) {
+ 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[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[9] = 11;
tmp[10] = 12;
- tmp[11] = 9;
+ tmp[11] = 9;
tmp[12] = 13;
tmp[13] = 10;
tmp[17] = 19;
tmp[18] = 17;
tmp[19] = 18;
break;
default:
- //nothing to change
+ // nothing to change
break;
}
_read_order[it->first] = tmp;
}
}
/* -------------------------------------------------------------------------- */
-MeshIOMSH::~MeshIOMSH() {
- std::map<ElementType, MSHElementType>::iterator it;
- for(it = _akantu_to_msh_element_types.begin();
- it != _akantu_to_msh_element_types.end(); ++it) {
- delete [] _read_order[it->first];
- }
+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;
+ UInt first_node_number = std::numeric_limits<UInt>::max(),
+ last_node_number = 0, file_format = 1, current_line = 0;
-
- if(!infile.good()) {
+ if (!infile.good()) {
AKANTU_DEBUG_ERROR("Cannot open file " << filename);
}
- while(infile.good()) {
- std::getline(infile, line);
+ while (infile.good()) {
+ my_getline(infile, line);
current_line++;
/// read the header
- if(line == "$MeshFormat") {
- std::getline(infile, line); /// the format line
+ 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.");
- std::getline(infile, line); /// the end of block 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") {
- std::getline(infile, line); /// the format line
+ 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++) {
- std::getline(infile, line);
+ 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);
+ 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") {
+ if (line == "$Nodes" || line == "$NOD") {
UInt nb_nodes;
- std::getline(infile, line);
+ 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) {
+ for (UInt i = 0; i < nb_nodes; ++i) {
UInt offset = i * spatial_dimension;
- std::getline(infile, line);
+ 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);
+ 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)
+ for (UInt j = 0; j < spatial_dimension; ++j)
nodes.storage()[offset + j] = coord[j];
}
- std::getline(infile, line); /// the end of block line
+ my_getline(infile, line); /// the end of block line
}
-
/// read all elements
- if(line == "$Elements" || line == "$ELM") {
+ if (line == "$Elements" || line == "$ELM") {
UInt nb_elements;
- UInt * read_order = NULL;
+ std::vector<UInt> read_order;
- std::getline(infile, line);
+ 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;
+ Array<UInt> * connectivity = NULL;
UInt node_per_element = 0;
- for(UInt i = 0; i < nb_elements; ++i) {
- std::getline(infile, line);
+ 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 = _msh_to_akantu_element_types[(MSHElementType) msh_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);
+ if (akantu_type == _not_defined) {
+ AKANTU_DEBUG_WARNING("Unsuported element kind "
+ << msh_type << " at line " << current_line);
continue;
}
- if(akantu_type != akantu_type_old) {
+ if (akantu_type != akantu_type_old) {
connectivity = mesh.getConnectivityPointer(akantu_type);
-// connectivity->resize(0);
+ // connectivity->resize(0);
node_per_element = connectivity->getNbComponent();
akantu_type_old = akantu_type;
- read_order = _read_order[akantu_type];
+ read_order = this->_read_order[akantu_type];
}
/// read tags informations
- if(file_format == 2) {
+ if (file_format == 2) {
UInt nb_tags;
sstr_elem >> nb_tags;
- for(UInt j = 0; j < nb_tags; ++j) {
+ 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);
+ 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
+ sstr_elem >> tag; // reg-phys
std::string tag_name = "tag_0";
- Array<UInt> * data = mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
+ Array<UInt> * data =
+ mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
data->push_back(tag);
- sstr_elem >> tag; //reg-elem
+ 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
+ sstr_elem >> tag; // number-of-nodes
}
- UInt local_connect[node_per_element];
- for(UInt j = 0; j < node_per_element; ++j) {
+ 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 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;
}
- std::getline(infile, line); /// the end of block line
+ 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);
+ 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);
+ 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 << "2.1 0 8" << std::endl;
+ outfile << "$EndMeshFormat" << std::endl;
outfile << std::setprecision(std::numeric_limits<Real>::digits10);
- outfile << "$Nodes" << std::endl;;
+ outfile << "$Nodes" << std::endl;
+
outfile << nodes.getSize() << std::endl;
outfile << std::uppercase;
- for(UInt i = 0; i < nodes.getSize(); ++i) {
+ 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 << 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::endl;
+ ;
}
outfile << std::nouppercase;
- outfile << "$EndNodes" << std::endl;;
-
+ outfile << "$EndNodes" << std::endl;
+ ;
- outfile << "$Elements" << 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);
+ 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) {
+ 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) {
+ 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);
+ const Array<UInt> & data_tag_0 =
+ mesh.getData<UInt>("tag_0", type, _not_ghost);
tag[0] = data_tag_0.storage();
- } catch(...) { tag[0] = NULL; }
+ } catch (...) {
+ tag[0] = NULL;
+ }
try {
- const Array<UInt> & data_tag_1 = mesh.getData<UInt>("tag_1", type, _not_ghost);
+ const Array<UInt> & data_tag_1 =
+ mesh.getData<UInt>("tag_1", type, _not_ghost);
tag[1] = data_tag_1.storage();
- } catch(...) { tag[1] = NULL; }
+ } catch (...) {
+ tag[1] = NULL;
+ }
- for(UInt i = 0; i < connectivity.getSize(); ++i) {
+ for (UInt i = 0; i < connectivity.getSize(); ++i) {
UInt offset = i * connectivity.getNbComponent();
- outfile << element_idx << " " << _akantu_to_msh_element_types[type] << " 2";
+ 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";
+ if (tag[t])
+ outfile << " " << tag[t][i];
+ else
+ outfile << " 0";
- for(UInt j = 0; j < connectivity.getNbComponent(); ++j) {
+ for (UInt j = 0; j < connectivity.getNbComponent(); ++j) {
outfile << " " << connectivity.storage()[offset + j] + 1;
}
outfile << std::endl;
element_idx++;
}
}
- outfile << "$EndElements" << std::endl;;
+ 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 6f766701f..f36eed4e4 100644
--- a/src/io/mesh_io/mesh_io_msh.hh
+++ b/src/io/mesh_io/mesh_io_msh.hh
@@ -1,115 +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_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, UInt*> _read_order;
+ 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 a186f0b97..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];
- UInt * tmp = new UInt[nb_nodes];
+ 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 d2e4b845d..24af4ebee 100644
--- a/src/io/parser/algebraic_parser.hh
+++ b/src/io/parser/algebraic_parser.hh
@@ -1,561 +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
+ Iterator err_pos,
+ Iterator last) const
{
- AKANTU_EXCEPTION("Error! Expecting "
- << what // what failed?
- << " here: \""
- << std::string(err_pos, last) // iterators to error-pos, end
- << "\"");
+ 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); }
- template<class Iterator>
- struct Skipper {
- typedef qi::rule<Iterator, void()> type;
- };
-
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);
+ 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);
+ 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);
+ 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);
+ __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
- ;
-
- 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 )
+ "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 )
+ ("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 )
+ ;
+
+ 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 )
+ ("hypot", &std::hypot )
#endif
- ;
+ ;
- qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
+ 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");
+ 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");
+ 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);
- }
+ 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;
+ 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;
};
- std::ostream& operator<<(std::ostream& stream, const parsable_vector& pv) {
+ 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 << *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;
+ 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;
};
- std::ostream& operator<<(std::ostream& stream, const parsable_matrix& pm) {
+ 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 << *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);
+ 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");
+ "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);
- }
+ 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);
+ 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");
+ "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);
- }
+ 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) {}
+ 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;
};
- std::ostream& operator<<(std::ostream& stream, const ParsableRandomGenerator& prg) {
+ 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 ]
- ;
+ "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)))
+ (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);
+ 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));
+ 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");
+ 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);
- }
+ 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 9109096b7..cb3b13ed6 100644
--- a/src/io/parser/cppargparse/cppargparse.cc
+++ b/src/io/parser/cppargparse/cppargparse.cc
@@ -1,515 +1,526 @@
/**
* @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();
}
this->argc = &argc;
this->argv = &argv;
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 57b0c33e1..6c3ba4aca 100644
--- a/src/io/parser/cppargparse/cppargparse.hh
+++ b/src/io/parser/cppargparse/cppargparse.hh
@@ -1,182 +1,201 @@
/**
* @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,
- _stop_on_not_parsed = 0x1,
- _remove_parsed = 0x2
+ _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);
/// get the last argc parsed
- int & getARGC() { return *argc; }
+ int & getArgC() { return *(this->argc); }
/// get the last argv parsed
- char** & getARGV() { return *argv; }
+ char** & getArgV() { return *(this->argv); }
/// 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;
/// is the argument present
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
class _Argument;
- template <class T> class ArgumentStorage;
+ /// 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:
- typedef std::map<std::string, _Argument *> _Arguments;
+ /// 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 view of arguments
+ /// 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 to parse
+ /// positional arguments
PositionalArgument pos_args;
- /// Success fully parsed arguments
- Arguments success_parsed;
-
/// program name
std::string program_name;
/// exit function to use
void (*external_exit)(int);
/// Parallel context, rank and size of communicator
int prank, psize;
/// The last argc parsed (those are the modified version after parse)
int * argc;
/// The last argv parsed (those are the modified version after parse)
char *** argv;
};
}
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 061052bba..92a662404 100644
--- a/src/io/parser/cppargparse/cppargparse_tmpl.hh
+++ b/src/io/parser/cppargparse/cppargparse_tmpl.hh
@@ -1,266 +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
+ * @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) {}
+ _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) {
+ 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) {
+ if (has_default) {
stream << " (default: ";
this->_printDefault(stream);
stream << ")";
}
- if(has_const) {
+ 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;
};
/* -------------------------------------------------------------------------- */
-template<class T>
+/// 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) {
+ 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) {
+template <>
+inline void
+ArgumentParser::ArgumentStorage<std::string>::addValue(std::string & value) {
values.push_back(value);
}
-template<class T>
-struct is_vector {
+template <class T> struct is_vector {
enum { value = false };
};
-
-template<class T>
-struct is_vector< std::vector<T> > {
+template <class T> struct is_vector<std::vector<T> > {
enum { value = true };
};
/* -------------------------------------------------------------------------- */
-template<class T, bool is_vector = cppargparse::is_vector<T>::value>
+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) {
+ 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);
+ 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> {
+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);
+ dynamic_cast<const ArgumentParser::ArgumentStorage<T> &>(arg);
return _arg.values;
}
};
/* -------------------------------------------------------------------------- */
-template<class T>
-ArgumentParser::Argument::operator T() const{
+template <class T> ArgumentParser::Argument::operator T() const {
return cast_helper<T>::cast(*this);
}
-template<>
-inline ArgumentParser::Argument::operator const char*() const{
+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{
+template <> inline ArgumentParser::Argument::operator unsigned int() const {
return cast_helper<int>::cast(*this);
}
-template<class T>
+template <class T>
void ArgumentParser::addArgument(const std::string & name_or_flag,
- const std::string & help,
- int nargs,
- ArgumentType type,
- T def) {
+ 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>
+template <class T>
void ArgumentParser::addArgument(const std::string & name_or_flag,
- const std::string & help,
- int nargs,
- ArgumentType type,
- T def,
- T cons) {
+ 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) {
+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) {
+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<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);
+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 c8b5c34e4..726986f0a 100644
--- a/src/io/parser/parsable.cc
+++ b/src/io/parser/parsable.cc
@@ -1,196 +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::parser_permissive) {
+ 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::parser_permissive) {
+ } 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 6c9a284aa..ecd981471 100644
--- a/src/io/parser/parsable.hh
+++ b/src/io/parser/parsable.hh
@@ -1,185 +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 ef41eb103..e166b1b53 100644
--- a/src/io/parser/parser.cc
+++ b/src/io/parser/parser.cc
@@ -1,231 +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"
-#include "static_communicator.hh"
-/* -------------------------------------------------------------------------- */
-//#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>
-/* -------------------------------------------------------------------------- */
-#include "algebraic_parser.hh"
-#include "input_file_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);
-}
-
-/* -------------------------------------------------------------------------- */
-std::string Parser::getLastParsedFile() const {
- return last_parsed_file;
+ return ((sub_sections_by_type.insert(std::pair<SectionType, ParserSection>(
+ section.getType(), section)))->second);
}
-
/* -------------------------------------------------------------------------- */
-void Parser::parse(const std::string& filename) {
- std::ifstream input(filename.c_str());
-
- if(!input.good()) {
- AKANTU_EXCEPTION("Could not open file " << filename << "!");
- }
-
- input.unsetf(std::ios::skipws);
-
- // wrap istream into iterator
- spirit::istream_iterator fwd_begin(input);
- spirit::istream_iterator fwd_end;
-
- // wrap forward iterator with position iterator, to record the position
- typedef spirit::classic::position_iterator2<spirit::istream_iterator> pos_iterator_type;
- pos_iterator_type position_begin(fwd_begin, fwd_end, filename);
- pos_iterator_type position_end;
-
- // parse
- parser::InputFileGrammar<pos_iterator_type> ag(this);
-
- bool result = qi::phrase_parse(position_begin,
- position_end,
- ag,
- ag.skipper);
-
- if(!result || position_begin != position_end) {
- spirit::classic::file_position pos = position_begin.get_position();
-
- AKANTU_EXCEPTION("Parse error [ " << ag.getErrorMessage() << " ]"
- << " in file " << filename
- << " line " << pos.line
- << " column " << pos.column << std::endl
- << "'" << position_begin.get_currentline() << "'" << std::endl
- << std::setw(pos.column) << " " << "^- here");
- }
-
-
- try {
- DebugLevel dbl = debug::getDebugLevel();
- debug::setDebugLevel(dblError);
- bool permissive = getParameter("parser_permissive", _ppsc_current_scope);
- debug::setDebugLevel(dbl);
-
- parser_permissive = permissive;
- AKANTU_DEBUG_INFO("Parser switched permissive mode to " << std::boolalpha << parser_permissive);
- } catch (debug::Exception & e) {
- }
-
- last_parsed_file = filename;
- input.close();
-}
-
-/* -------------------------------------------------------------------------- */
-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;
-}
-
-
-/* -------------------------------------------------------------------------- */
-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);
-}
-
-/* -------------------------------------------------------------------------- */
-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);
-}
-
-/* -------------------------------------------------------------------------- */
-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");
- }
-}
+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 6baa0ebc3..2f567c148 100644
--- a/src/io/parser/parser.hh
+++ b/src/io/parser/parser.hh
@@ -1,407 +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) \
- (non_local) \
- (user) \
- (solver) \
+#define AKANTU_SECTION_TYPES \
+ (global)(material)(model)(mesh)(heat)(contact)(friction) \
+ (embedded_interface)(rules)(non_local)(user)(solver)(neighborhood) \
(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
+/// 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; }
- void setDebugInfo(const std::string & filename,
- UInt line, UInt column) {
+ /// Set info for debug output
+ 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;
-
- void printself(std::ostream & stream, unsigned int indent = 0) const {
- stream << name << ": " << value
- << " (" << dbg_filename << ":" << dbg_line << ":" << dbg_column << ")";
+ /// Print parameter info in stream
+ 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 = sub_sections_by_type;
+ sub_sections_by_type = other.sub_sections_by_type;
setChldrenPointers();
}
return *this;
}
virtual ~ParserSection();
virtual void printself(std::ostream & stream, unsigned int indent = 0) const;
/* ---------------------------------------------------------------------- */
/* Creation functions */
/* ---------------------------------------------------------------------- */
public:
ParserParameter & addParameter(const ParserParameter & param);
ParserSection & addSubSection(const ParserSection & section);
+protected:
+ /// Clean ParserSection content
+ void clean() {
+ parameters.clear();
+ sub_sections_by_type.clear();
+ }
+
private:
void setChldrenPointers() {
Parameters::iterator pit = this->parameters.begin();
- for(;pit != this->parameters.end(); ++pit) pit->second.setParent(*this);
+ 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());
}
/* ---------------------------------------------------------------------- */
- const ParserParameter & getParameter(const std::string & name,
- ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
+ /// Get parameter within specified context
+ const ParserParameter & getParameter(
+ const std::string & name,
+ ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
Parameters::const_iterator it;
- if(search_ctx & _ppsc_current_scope) it = parameters.find(name);
+ if (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;
}
/* ------------------------------------------------------------------------ */
- bool hasParameter(const std::string & name,
- ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
+ /// Check if parameter exists within specified context
+ bool hasParameter(
+ const std::string & name,
+ ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
Parameters::const_iterator it;
- if(search_ctx & _ppsc_current_scope) it = parameters.find(name);
+ if (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;
}
- /* -------------------------------------------------------------------------- */
- template<class T>
- T getParameterValue(const std::string & name,
- ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
+ /* --------------------------------------------------------------------------
+ */
+ /// Get value of given parameter in context
+ template <class T>
+ T getParameterValue(
+ const std::string & name,
+ ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const {
const ParserParameter & tmp_param = getParameter(name, search_ctx);
T t = tmp_param;
return t;
}
- /* -------------------------------------------------------------------------- */
- const std::string & getName() const { return name; }
- const SectionType & getType() const { return type; }
+ /* --------------------------------------------------------------------------
+ */
+ /// Get section name
+ const std::string & getName() const { return name; }
+ /// Get section type
+ const SectionType & getType() const { return type; }
+ /// Get section option
const std::string & getOption() const { return option; }
protected:
- void setParent(const ParserSection & sect) {
- parent_section = &sect;
- }
+ 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 parser_permissive; }
+ static bool isPermissive() { return permissive_parser; }
+
public:
+ /// Parse real scalar
+ static Real parseReal(const std::string & value,
+ const ParserSection & section);
+ /// Parse real vector
+ static Vector<Real> parseVector(const std::string & value,
+ const ParserSection & section);
+ /// Parse real matrix
+ static Matrix<Real> parseMatrix(const std::string & value,
+ const ParserSection & section);
+ /// Parse real random parameter
+ static RandomParameter<Real>
+ parseRandomParameter(const std::string & value,
+ const ParserSection & section);
- static Real parseReal (const std::string & value, const ParserSection & section);
- static Vector<Real> parseVector(const std::string & value, const ParserSection & section);
- static Matrix<Real> parseMatrix(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 parser_permissive;
+ // 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
new file mode 100644
index 000000000..fd2aefc0c
--- /dev/null
+++ b/src/io/parser/parser_grammar_tmpl.hh
@@ -0,0 +1,81 @@
+/**
+ * @file parser_grammar_tmpl.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Wed Nov 11 2015
+ *
+ * @brief implementation of the templated part of ParsableParam Parsable and
+ * ParsableParamTyped
+ *
+ * @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 <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
new file mode 100644
index 000000000..aaf08d3cd
--- /dev/null
+++ b/src/io/parser/parser_input_files.cc
@@ -0,0 +1,97 @@
+/**
+ * @file parser_input_files.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Wed Nov 11 2015
+ * @date last modification: Wed Jan 13 2016
+ *
+ * @brief implementation of the parser
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "parser.hh"
+#include "parser_grammar_tmpl.hh"
+/* -------------------------------------------------------------------------- */
+#include "input_file_parser.hh"
+/* -------------------------------------------------------------------------- */
+#include <fstream>
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+void Parser::parse(const std::string & filename) {
+ this->clean();
+ std::ifstream input(filename.c_str());
+
+ if (!input.good()) {
+ AKANTU_EXCEPTION("Could not open file " << filename << "!");
+ }
+
+ input.unsetf(std::ios::skipws);
+
+ // wrap istream into iterator
+ spirit::istream_iterator fwd_begin(input);
+ spirit::istream_iterator fwd_end;
+
+ // wrap forward iterator with position iterator, to record the position
+ typedef spirit::classic::position_iterator2<spirit::istream_iterator>
+ pos_iterator_type;
+ pos_iterator_type position_begin(fwd_begin, fwd_end, filename);
+ pos_iterator_type position_end;
+
+ // parse
+ parser::InputFileGrammar<pos_iterator_type> ag(this);
+
+ bool result = qi::phrase_parse(position_begin, position_end, ag, ag.skipper);
+
+ if (!result || position_begin != position_end) {
+ spirit::classic::file_position pos = position_begin.get_position();
+
+ AKANTU_EXCEPTION("Parse error [ "
+ << ag.getErrorMessage() << " ]"
+ << " in file " << filename << " line " << pos.line
+ << " column " << pos.column << std::endl
+ << "'" << position_begin.get_currentline() << "'"
+ << std::endl
+ << std::setw(pos.column) << " "
+ << "^- here");
+ }
+
+ try {
+ DebugLevel dbl = debug::getDebugLevel();
+ debug::setDebugLevel(dblError);
+ bool permissive = getParameter("permissive_parser", _ppsc_current_scope);
+ debug::setDebugLevel(dbl);
+
+ permissive_parser = permissive;
+ AKANTU_DEBUG_INFO("Parser switched permissive mode to "
+ << std::boolalpha << permissive_parser);
+ } catch (debug::Exception & e) {
+ }
+
+ last_parsed_file = filename;
+ input.close();
+}
+
+__END_AKANTU__
diff --git a/src/io/parser/parser_random.cc b/src/io/parser/parser_random.cc
new file mode 100644
index 000000000..7f281cdea
--- /dev/null
+++ b/src/io/parser/parser_random.cc
@@ -0,0 +1,58 @@
+/**
+ * @file parser_random.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Mon Dec 07 2015
+ *
+ * @brief implementation of the parser
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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
new file mode 100644
index 000000000..666d8f0ce
--- /dev/null
+++ b/src/io/parser/parser_real.cc
@@ -0,0 +1,48 @@
+/**
+ * @file parser_real.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Wed Nov 11 2015
+ *
+ * @brief implementation of the parser
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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
new file mode 100644
index 000000000..f829f7279
--- /dev/null
+++ b/src/io/parser/parser_types.cc
@@ -0,0 +1,58 @@
+/**
+ * @file parser_types.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Wed Nov 11 2015
+ *
+ * @brief implementation of the parser
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "parser.hh"
+#include "parser_grammar_tmpl.hh"
+/* -------------------------------------------------------------------------- */
+#include "algebraic_parser.hh"
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+Vector<Real> Parser::parseVector(const std::string & value, const ParserSection & section) {
+ using boost::spirit::ascii::space_type;
+ parser::VectorGrammar<std::string::const_iterator, space_type> grammar(section);
+ grammar.name("vector_grammar");
+ return Parser::parseType<parser::parsable_vector>(value, grammar);
+}
+
+/* -------------------------------------------------------------------------- */
+Matrix<Real> Parser::parseMatrix(const std::string & value, const ParserSection & section) {
+ using boost::spirit::ascii::space_type;
+ parser::MatrixGrammar<std::string::const_iterator, space_type> grammar(section);
+ grammar.name("matrix_grammar");
+ return Parser::parseType<parser::parsable_matrix>(value, grammar);
+}
+
+/* -------------------------------------------------------------------------- */
+
+__END_AKANTU__
\ No newline at end of file
diff --git a/src/mesh/element_group.cc b/src/mesh/element_group.cc
index e6241ec00..24bf91037 100644
--- a/src/mesh/element_group.cc
+++ b/src/mesh/element_group.cc
@@ -1,200 +1,201 @@
/**
* @file element_group.cc
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Tue Aug 18 2015
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <sstream>
#include <algorithm>
#include <iterator>
#include "mesh.hh"
#include "group_manager.hh"
#include "group_manager_inline_impl.cc"
#include "dumpable.hh"
#include "dumpable_inline_impl.hh"
#include "aka_csr.hh"
#include "mesh_utils.hh"
#include "element_group.hh"
#if defined(AKANTU_USE_IOHELPER)
# include "dumper_paraview.hh"
#endif
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
ElementGroup::ElementGroup(const std::string & group_name,
const Mesh & mesh,
NodeGroup & node_group,
UInt dimension,
const std::string & id,
const MemoryID & mem_id) :
Memory(id, mem_id),
mesh(mesh),
name(group_name),
elements("elements", id, mem_id),
node_group(node_group),
dimension(dimension) {
AKANTU_DEBUG_IN();
#if defined(AKANTU_USE_IOHELPER)
this->registerDumper<DumperParaview>("paraview_" + group_name, group_name, true);
this->addDumpFilteredMesh(mesh, elements, node_group.getNodes(), dimension);
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::empty() {
elements.free();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::append(const ElementGroup & other_group) {
AKANTU_DEBUG_IN();
node_group.append(other_group.node_group);
/// loop on all element types in all dimensions
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
type_iterator it = other_group.firstType(_all_dimensions,
ghost_type,
_ek_not_defined);
type_iterator last = other_group.lastType(_all_dimensions,
ghost_type,
_ek_not_defined);
for (; it != last; ++it) {
ElementType type = *it;
const Array<UInt> & other_elem_list = other_group.elements(type, ghost_type);
UInt nb_other_elem = other_elem_list.getSize();
Array<UInt> * elem_list;
UInt nb_elem = 0;
/// create current type if doesn't exists, otherwise get information
if (elements.exists(type, ghost_type)) {
elem_list = &elements(type, ghost_type);
nb_elem = elem_list->getSize();
}
else {
elem_list = &(elements.alloc(0, 1, type, ghost_type));
}
/// append new elements to current list
elem_list->resize(nb_elem + nb_other_elem);
std::copy(other_elem_list.begin(),
other_elem_list.end(),
elem_list->begin() + nb_elem);
/// remove duplicates
std::sort(elem_list->begin(), elem_list->end());
Array<UInt>::iterator<> end = std::unique(elem_list->begin(), elem_list->end());
elem_list->resize(end - elem_list->begin());
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "ElementGroup [" << std::endl;
stream << space << " + name: " << name << std::endl;
stream << space << " + dimension: " << dimension << std::endl;
elements.printself(stream, indent + 1);
node_group.printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
void ElementGroup::optimize() {
// increasing the locality of data when iterating on the element of a group
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
ElementList::type_iterator it = elements.firstType(_all_dimensions, ghost_type);
ElementList::type_iterator last = elements.lastType(_all_dimensions, ghost_type);
for (; it != last; ++it) {
Array<UInt> & els = elements(*it, ghost_type);
std::sort(els.begin(), els.end());
Array<UInt>::iterator<> end = std::unique(els.begin(), els.end());
els.resize(end - els.begin());
}
}
node_group.optimize();
}
/* -------------------------------------------------------------------------- */
void ElementGroup::fillFromNodeGroup() {
CSR<Element> node_to_elem;
MeshUtils::buildNode2Elements(this->mesh, node_to_elem, this->dimension);
std::set<Element> seen;
Array<UInt>::const_iterator<> itn = this->node_group.begin();
Array<UInt>::const_iterator<> endn = this->node_group.end();
for (;itn != endn; ++itn) {
CSR<Element>::iterator ite = node_to_elem.begin(*itn);
CSR<Element>::iterator ende = node_to_elem.end(*itn);
for (;ite != ende; ++ite) {
const Element & elem = *ite;
if(this->dimension != _all_dimensions && this->dimension != Mesh::getSpatialDimension(elem.type)) continue;
if(seen.find(elem) != seen.end()) continue;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(elem.type);
Array<UInt>::const_iterator< Vector<UInt> > conn_it =
this->mesh.getConnectivity(elem.type, elem.ghost_type).begin(nb_nodes_per_element);
const Vector<UInt> & conn = conn_it[elem.element];
UInt count = 0;
for (UInt n = 0; n < conn.size(); ++n) {
count += (this->node_group.getNodes().find(conn(n)) != -1 ? 1 : 0);
}
if(count == nb_nodes_per_element) this->add(elem);
seen.insert(elem);
}
}
this->optimize();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/mesh/element_group.hh b/src/mesh/element_group.hh
index 38ec48f84..7dcc766e1 100644
--- a/src/mesh/element_group.hh
+++ b/src/mesh/element_group.hh
@@ -1,179 +1,179 @@
/**
* @file element_group.hh
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 03 2013
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Tue Aug 18 2015
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_GROUP_HH__
#define __AKANTU_ELEMENT_GROUP_HH__
#include <set>
#include "aka_common.hh"
#include "aka_memory.hh"
#include "element_type_map.hh"
#include "node_group.hh"
#include "dumpable.hh"
__BEGIN_AKANTU__
class Mesh;
class Element;
/* -------------------------------------------------------------------------- */
class ElementGroup : private Memory, public Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ElementGroup(const std::string & name,
const Mesh & mesh,
NodeGroup & node_group,
UInt dimension = _all_dimensions,
const std::string & id = "element_group",
const MemoryID & memory_id = 0);
/* ------------------------------------------------------------------------ */
/* Type definitions */
/* ------------------------------------------------------------------------ */
public:
typedef ElementTypeMapArray<UInt> ElementList;
typedef Array<UInt> NodeList;
/* ------------------------------------------------------------------------ */
/* Node iterator */
/* ------------------------------------------------------------------------ */
typedef NodeGroup::const_node_iterator const_node_iterator;
inline const_node_iterator node_begin() const;
inline const_node_iterator node_end() const;
/* ------------------------------------------------------------------------ */
/* Element iterator */
/* ------------------------------------------------------------------------ */
typedef ElementList::type_iterator type_iterator;
inline type_iterator firstType(UInt dim = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & kind = _ek_regular) const;
inline type_iterator lastType(UInt dim = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & kind = _ek_regular) const;
typedef Array<UInt>::const_iterator<UInt> const_element_iterator;
inline const_element_iterator element_begin(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
inline const_element_iterator element_end(const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// empty the element group
void empty();
/// append another group to this group
/// BE CAREFUL: it doesn't conserve the element order
void append(const ElementGroup & other_group);
/// add an element to the group. By default the it does not add the nodes to the group
inline void add(const Element & el, bool add_nodes = false, bool check_for_duplicate = true);
/// \todo fix the default for add_nodes : make it coherent with the other method
inline void add(const ElementType & type, UInt element,
const GhostType & ghost_type = _not_ghost,
bool add_nodes = true, bool check_for_duplicate = true);
inline void addNode(UInt node_id, bool check_for_duplicate = true);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/// fill the elements based on the underlying node group.
virtual void fillFromNodeGroup();
// sort and remove duplicated values
void optimize();
private:
inline void addElement(const ElementType & elem_type,
UInt elem_id,
const GhostType & ghost_type);
friend class GroupManager;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Elements, elements, UInt);
AKANTU_GET_MACRO(Elements, elements, const ElementTypeMapArray<UInt> &);
AKANTU_GET_MACRO(Nodes, node_group.getNodes(), const Array<UInt> &);
AKANTU_GET_MACRO(NodeGroup, node_group, const NodeGroup &);
AKANTU_GET_MACRO_NOT_CONST(NodeGroup, node_group, NodeGroup &);
AKANTU_GET_MACRO(Dimension, dimension, UInt);
AKANTU_GET_MACRO(Name, name, std::string);
inline UInt getNbNodes() const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// Mesh to which this group belongs
const Mesh & mesh;
/// name of the group
std::string name;
/// list of elements composing the group
ElementList elements;
/// sub list of nodes which are composing the elements
NodeGroup & node_group;
/// group dimension
UInt dimension;
/// empty arry for the iterator to work when an element type not present
Array<UInt> empty_elements;
};
/// standard output stream operator
inline std::ostream & operator << (std::ostream & stream, const ElementGroup &_this) {
_this.printself(stream);
return stream;
}
__END_AKANTU__
#include "element.hh"
#include "element_group_inline_impl.cc"
#endif /* __AKANTU_ELEMENT_GROUP_HH__ */
diff --git a/src/mesh/element_group_inline_impl.cc b/src/mesh/element_group_inline_impl.cc
index e9effa1b3..e7475c19e 100644
--- a/src/mesh/element_group_inline_impl.cc
+++ b/src/mesh/element_group_inline_impl.cc
@@ -1,127 +1,127 @@
/**
* @file element_group_inline_impl.cc
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Tue Aug 18 2015
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline void ElementGroup::add(const Element & el, bool add_nodes,
bool check_for_duplicate) {
this->add(el.type,el.element,el.ghost_type,add_nodes,check_for_duplicate);
}
/* -------------------------------------------------------------------------- */
inline void ElementGroup::add(const ElementType & type, UInt element,
const GhostType & ghost_type,bool add_nodes,
bool check_for_duplicate) {
addElement(type, element, ghost_type);
if(add_nodes) {
Array<UInt>::const_vector_iterator it =
mesh.getConnectivity(type, ghost_type).begin(mesh.getNbNodesPerElement(type)) + element;
const Vector<UInt> & conn = *it;
for (UInt i = 0; i < conn.size(); ++i) addNode(conn[i], check_for_duplicate);
}
}
/* -------------------------------------------------------------------------- */
inline void ElementGroup::addNode(UInt node_id, bool check_for_duplicate) {
node_group.add(node_id, check_for_duplicate);
}
/* -------------------------------------------------------------------------- */
inline void ElementGroup::addElement(const ElementType & elem_type,
UInt elem_id,
const GhostType & ghost_type) {
if(!(elements.exists(elem_type, ghost_type))) {
elements.alloc(0, 1, elem_type, ghost_type);
}
elements(elem_type, ghost_type).push_back(elem_id);
this->dimension = UInt(std::max(Int(this->dimension), Int(mesh.getSpatialDimension(elem_type))));
}
/* -------------------------------------------------------------------------- */
inline UInt ElementGroup::getNbNodes() const {
return node_group.getSize();
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::const_node_iterator ElementGroup::node_begin() const {
return node_group.begin();
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::const_node_iterator ElementGroup::node_end() const {
return node_group.end();
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::type_iterator ElementGroup::firstType(UInt dim,
const GhostType & ghost_type,
const ElementKind & kind) const {
return elements.firstType(dim, ghost_type, kind);
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::type_iterator ElementGroup::lastType(UInt dim,
const GhostType & ghost_type,
const ElementKind & kind) const {
return elements.lastType(dim, ghost_type, kind);
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::const_element_iterator ElementGroup::element_begin(const ElementType & type,
const GhostType & ghost_type) const {
if(elements.exists(type, ghost_type)) {
return elements(type, ghost_type).begin();
} else {
return empty_elements.begin();
}
}
/* -------------------------------------------------------------------------- */
inline ElementGroup::const_element_iterator ElementGroup::element_end(const ElementType & type,
const GhostType & ghost_type) const {
if(elements.exists(type, ghost_type)) {
return elements(type, ghost_type).end();
} else {
return empty_elements.end();
}
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/mesh/element_type_map.hh b/src/mesh/element_type_map.hh
index 7976baa1d..bcac63471 100644
--- a/src/mesh/element_type_map.hh
+++ b/src/mesh/element_type_map.hh
@@ -1,318 +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) {};
+ 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 aba92d351..02c978670 100644
--- a/src/mesh/element_type_map_filter.hh
+++ b/src/mesh/element_type_map_filter.hh
@@ -1,332 +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>>
+ 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 e7f1aa30e..18e9a09a5 100644
--- a/src/mesh/element_type_map_tmpl.hh
+++ b/src/mesh/element_type_map_tmpl.hh
@@ -1,442 +1,458 @@
/**
* @file element_type_map_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 31 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Fri Oct 02 2015
*
* @brief implementation of template functions of the ElementTypeMap and
* ElementTypeMapArray classes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__
#define __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* ElementTypeMap */
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline std::string ElementTypeMap<Stored, SupportType>::printType(const SupportType & type,
const GhostType & ghost_type) {
std::stringstream sstr; sstr << "(" << ghost_type << ":" << type << ")";
return sstr.str();
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline bool ElementTypeMap<Stored, SupportType>::exists(const SupportType & type, const GhostType & ghost_type) const {
return this->getData(ghost_type).find(type) != this->getData(ghost_type).end();
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline const Stored & ElementTypeMap<Stored, SupportType>::operator()(const SupportType & type,
const GhostType & ghost_type) const {
typename DataMap::const_iterator it =
this->getData(ghost_type).find(type);
if(it == this->getData(ghost_type).end())
AKANTU_EXCEPTION("No element of type "
<< ElementTypeMap::printType(type, ghost_type)
<< " in this ElementTypeMap<"
<< debug::demangle(typeid(Stored).name()) << "> class");
return it->second;
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline Stored & ElementTypeMap<Stored, SupportType>::operator()(const SupportType & type,
const GhostType & ghost_type) {
return this->getData(ghost_type)[type];
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline Stored & ElementTypeMap<Stored, SupportType>::operator()(const Stored & insert,
const SupportType & type,
const GhostType & ghost_type) {
typename DataMap::iterator it =
this->getData(ghost_type).find(type);
if(it != this->getData(ghost_type).end()) {
AKANTU_EXCEPTION("Element of type "
<< ElementTypeMap::printType(type, ghost_type)
<< " already in this ElementTypeMap<"
<< debug::demangle(typeid(Stored).name()) << "> class");
} else {
DataMap & data = this->getData(ghost_type);
const std::pair<typename DataMap::iterator, bool> & res =
data.insert(std::pair<ElementType, Stored>(type, insert));
it = res.first;
}
return it->second;
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::DataMap &
ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) {
if(ghost_type == _not_ghost) return data;
else return ghost_data;
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
inline const typename ElementTypeMap<Stored, SupportType>::DataMap &
ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) const {
if(ghost_type == _not_ghost) return data;
else return ghost_data;
}
/* -------------------------------------------------------------------------- */
/// Works only if stored is a pointer to a class with a printself method
template<class Stored, typename SupportType>
void ElementTypeMap<Stored, SupportType>::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "ElementTypeMap<" << debug::demangle(typeid(Stored).name()) << "> [" << std::endl;
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
const DataMap & data = getData(gt);
typename DataMap::const_iterator it;
for(it = data.begin(); it != data.end(); ++it) {
stream << space << space << ElementTypeMap::printType(it->first, gt) << std::endl;
}
}
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
ElementTypeMap<Stored, SupportType>::ElementTypeMap() {
AKANTU_DEBUG_IN();
// std::stringstream sstr;
// if(parent_id != "") sstr << parent_id << ":";
// sstr << id;
// this->id = sstr.str();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class Stored, typename SupportType>
ElementTypeMap<Stored, SupportType>::~ElementTypeMap() {
}
/* -------------------------------------------------------------------------- */
/* ElementTypeMapArray */
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline Array<T> & ElementTypeMapArray<T, SupportType>::alloc(UInt size,
UInt nb_component,
const SupportType & type,
const GhostType & ghost_type,
const T & default_value) {
std::string ghost_id = "";
if (ghost_type == _ghost) ghost_id = ":ghost";
Array<T> * tmp;
typename ElementTypeMapArray<T, SupportType>::DataMap::iterator it =
this->getData(ghost_type).find(type);
if(it == this->getData(ghost_type).end()) {
std::stringstream sstr; sstr << this->id << ":" << type << ghost_id;
tmp = &(Memory::alloc<T>(sstr.str(), size,
nb_component, default_value));
std::stringstream sstrg; sstrg << ghost_type;
//tmp->setTag(sstrg.str());
this->getData(ghost_type)[type] = tmp;
} else {
AKANTU_DEBUG_INFO("The vector " << this->id << this->printType(type, ghost_type)
<< " already exists, it is resized instead of allocated.");
tmp = it->second;
it->second->resize(size);
}
return *tmp;
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline void ElementTypeMapArray<T, SupportType>::alloc(UInt size,
UInt nb_component,
const SupportType & type,
const T & default_value) {
this->alloc(size, nb_component, type, _not_ghost, default_value);
this->alloc(size, nb_component, type, _ghost, default_value);
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline void ElementTypeMapArray<T, SupportType>::free() {
AKANTU_DEBUG_IN();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
DataMap & data = this->getData(gt);
typename DataMap::const_iterator it;
for(it = data.begin(); it != data.end(); ++it) {
dealloc(it->second->getID());
}
data.clear();
}
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
+template <typename T, typename SupportType>
+inline void ElementTypeMapArray<T, SupportType>::clear() {
+ for(UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType gt = (GhostType) g;
+
+ DataMap & data = this->getData(gt);
+ typename DataMap::const_iterator it;
+ for(it = data.begin(); it != data.end(); ++it) {
+ it->second->clear();
+ }
+ }
+}
+
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline const Array<T> & ElementTypeMapArray<T, SupportType>::operator()(const SupportType & type,
const GhostType & ghost_type) const {
typename ElementTypeMapArray<T, SupportType>::DataMap::const_iterator it =
this->getData(ghost_type).find(type);
if(it == this->getData(ghost_type).end())
AKANTU_EXCEPTION("No element of type "
<< ElementTypeMapArray::printType(type, ghost_type)
<< " in this const ElementTypeMapArray<"
<< debug::demangle(typeid(T).name()) << "> class(\""
<< this->id << "\")");
return *(it->second);
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline Array<T> & ElementTypeMapArray<T, SupportType>::operator()(const SupportType & type,
const GhostType & ghost_type) {
typename ElementTypeMapArray<T, SupportType>::DataMap::iterator it =
this->getData(ghost_type).find(type);
if(it == this->getData(ghost_type).end())
AKANTU_EXCEPTION("No element of type "
<< ElementTypeMapArray::printType(type, ghost_type)
<< " in this ElementTypeMapArray<"
<< debug::demangle(typeid(T).name()) << "> class (\""
<< this->id << "\")");
return *(it->second);
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline void ElementTypeMapArray<T, SupportType>::setArray(const SupportType & type,
const GhostType & ghost_type,
const Array<T> & vect) {
typename ElementTypeMapArray<T, SupportType>::DataMap::iterator it =
this->getData(ghost_type).find(type);
if(AKANTU_DEBUG_TEST(dblWarning) && it != this->getData(ghost_type).end() && it->second != &vect) {
AKANTU_DEBUG_WARNING("The Array " << this->printType(type, ghost_type)
<< " is already registred, this call can lead to a memory leak.");
}
this->getData(ghost_type)[type] = &(const_cast<Array<T> &>(vect));
}
/* -------------------------------------------------------------------------- */
template <typename T, typename SupportType>
inline void ElementTypeMapArray<T, SupportType>::onElementsRemoved(const ElementTypeMapArray<UInt> & new_numbering) {
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
ElementTypeMapArray<UInt>::type_iterator it = new_numbering.firstType(_all_dimensions, gt, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end = new_numbering.lastType(_all_dimensions, gt, _ek_not_defined);
for (; it != end; ++it) {
SupportType type = *it;
if(this->exists(type, gt)){
const Array<UInt> & renumbering = new_numbering(type, gt);
+ if (renumbering.getSize() == 0) continue;
Array<T> & vect = this->operator()(type, gt);
UInt nb_component = vect.getNbComponent();
Array<T> tmp(renumbering.getSize(), nb_component);
UInt new_size = 0;
for (UInt i = 0; i < vect.getSize(); ++i) {
UInt new_i = renumbering(i);
if(new_i != UInt(-1)) {
memcpy(tmp.storage() + new_i * nb_component,
vect.storage() + i *nb_component,
nb_component * sizeof(T));
++new_size;
}
}
tmp.resize(new_size);
vect.copy(tmp);
}
}
}
}
/* -------------------------------------------------------------------------- */
template<typename T, typename SupportType>
void ElementTypeMapArray<T, SupportType>::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "ElementTypeMapArray<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
const DataMap & data = this->getData(gt);
typename DataMap::const_iterator it;
for(it = data.begin(); it != data.end(); ++it) {
stream << space << space << ElementTypeMapArray::printType(it->first, gt) << " [" << std::endl;
it->second->printself(stream, indent + 3);
stream << space << space << " ]" << std::endl;
}
}
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
/* SupportType Iterator */
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(DataMapIterator & list_begin,
DataMapIterator & list_end,
UInt dim, ElementKind ek) :
list_begin(list_begin), list_end(list_end), dim(dim), kind(ek) {
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(const type_iterator & it) :
list_begin(it.list_begin), list_end(it.list_end), dim(it.dim), kind(it.kind) {
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
typename ElementTypeMap<Stored, SupportType>::type_iterator & ElementTypeMap<Stored, SupportType>::type_iterator::operator=(const type_iterator & it) {
if(this != &it) {
list_begin = it.list_begin;
list_end = it.list_end;
dim = it.dim;
kind = it.kind;
}
return *this;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
ElementTypeMap<Stored, SupportType>::type_iterator::operator*() {
return list_begin->first;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
ElementTypeMap<Stored, SupportType>::type_iterator::operator*() const {
return list_begin->first;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator &
ElementTypeMap<Stored, SupportType>::type_iterator::operator++() {
++list_begin;
while((list_begin != list_end) &&
(((dim != _all_dimensions) && (dim != Mesh::getSpatialDimension(list_begin->first))) ||
((kind != _ek_not_defined) && (kind != Mesh::getKind(list_begin->first)))
)
)
++list_begin;
return *this;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
typename ElementTypeMap<Stored, SupportType>::type_iterator ElementTypeMap<Stored, SupportType>::type_iterator::operator++(int) {
type_iterator tmp(*this);
operator++();
return tmp;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline bool ElementTypeMap<Stored, SupportType>::type_iterator::operator==(const type_iterator & other) const {
return this->list_begin == other.list_begin;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline bool ElementTypeMap<Stored, SupportType>::type_iterator::operator!=(const type_iterator & other) const {
return this->list_begin != other.list_begin;
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator
ElementTypeMap<Stored, SupportType>::firstType(UInt dim, GhostType ghost_type, ElementKind kind) const {
typename DataMap::const_iterator b,e;
b = getData(ghost_type).begin();
e = getData(ghost_type).end();
// loop until the first valid type
while((b != e) &&
(((dim != _all_dimensions) && (dim != Mesh::getSpatialDimension(b->first))) ||
((kind != _ek_not_defined) && (kind != Mesh::getKind(b->first)))))
++b;
return typename ElementTypeMap<Stored, SupportType>::type_iterator(b, e, dim, kind);
}
/* -------------------------------------------------------------------------- */
template <class Stored, typename SupportType>
inline typename ElementTypeMap<Stored, SupportType>::type_iterator
ElementTypeMap<Stored, SupportType>::lastType(UInt dim, GhostType ghost_type, ElementKind kind) const {
typename DataMap::const_iterator e;
e = getData(ghost_type).end();
return typename ElementTypeMap<Stored, SupportType>::type_iterator(e, e, dim, kind);
}
/* -------------------------------------------------------------------------- */
/// standard output stream operator
template <class Stored, typename SupportType>
inline std::ostream & operator <<(std::ostream & stream, const ElementTypeMap<Stored, SupportType> & _this)
{
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__ */
diff --git a/src/mesh/group_manager.cc b/src/mesh/group_manager.cc
index a2e872046..3f992471c 100644
--- a/src/mesh/group_manager.cc
+++ b/src/mesh/group_manager.cc
@@ -1,1014 +1,1015 @@
/**
* @file group_manager.cc
*
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@gmail.com>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Fri May 03 2013
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Mon Aug 17 2015
*
* @brief Stores information about ElementGroup and NodeGroup
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "group_manager.hh"
#include "mesh.hh"
#include "aka_csr.hh"
#include "mesh_utils.hh"
#include "element_group.hh"
#include "node_group.hh"
#include "data_accessor.hh"
#include "distributed_synchronizer.hh"
/* -------------------------------------------------------------------------- */
#include <sstream>
#include <algorithm>
#include <iterator>
#include <list>
#include <queue>
#include <numeric>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
GroupManager::GroupManager(const Mesh & mesh,
const ID & id,
const MemoryID & mem_id) : id(id),
memory_id(mem_id),
mesh(mesh) {
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
GroupManager::~GroupManager() {
ElementGroups::iterator eit = element_groups.begin();
ElementGroups::iterator eend = element_groups.end();
for(; eit != eend ; ++eit) delete (eit->second);
NodeGroups::iterator nit = node_groups.begin();
NodeGroups::iterator nend = node_groups.end();
for(; nit != nend ; ++nit) delete (nit->second);
}
/* -------------------------------------------------------------------------- */
NodeGroup & GroupManager::createNodeGroup(const std::string & group_name,
bool replace_group) {
AKANTU_DEBUG_IN();
NodeGroups::iterator it = node_groups.find(group_name);
if(it != node_groups.end()) {
if (replace_group) {
it->second->empty();
AKANTU_DEBUG_OUT();
return *(it->second);
}
else
AKANTU_EXCEPTION("Trying to create a node group that already exists:" << group_name);
}
std::stringstream sstr;
sstr << this->id << ":" << group_name << "_node_group";
NodeGroup * node_group = new NodeGroup(group_name,
mesh,
sstr.str(),
memory_id);
node_groups[group_name] = node_group;
AKANTU_DEBUG_OUT();
return *node_group;
}
/* -------------------------------------------------------------------------- */
template<typename T>
NodeGroup & GroupManager::createFilteredNodeGroup(const std::string & group_name,
const NodeGroup & source_node_group,
T & filter) {
AKANTU_DEBUG_IN();
NodeGroup & node_group = this->createNodeGroup(group_name);
node_group.append(source_node_group);
if (T::type == FilterFunctor::_node_filter_functor) {
node_group.applyNodeFilter(filter);
}
else {
AKANTU_DEBUG_ERROR("ElementFilter cannot be applied to NodeGroup yet."
<< " Needs to be implemented.");
}
AKANTU_DEBUG_OUT();
return node_group;
}
/* -------------------------------------------------------------------------- */
void GroupManager::destroyNodeGroup(const std::string & group_name) {
AKANTU_DEBUG_IN();
NodeGroups::iterator nit = node_groups.find(group_name);
NodeGroups::iterator nend = node_groups.end();
if (nit != nend) {
delete (nit->second);
node_groups.erase(nit);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
UInt dimension,
bool replace_group) {
AKANTU_DEBUG_IN();
NodeGroup & new_node_group = createNodeGroup(group_name + "_nodes", replace_group);
ElementGroups::iterator it = element_groups.find(group_name);
if(it != element_groups.end()) {
if (replace_group) {
it->second->empty();
AKANTU_DEBUG_OUT();
return *(it->second);
}
else
AKANTU_EXCEPTION("Trying to create a element group that already exists:" << group_name);
}
std::stringstream sstr;
sstr << this->id << ":" << group_name << "_element_group";
ElementGroup * element_group = new ElementGroup(group_name, mesh, new_node_group,
dimension,
sstr.str(),
memory_id);
std::stringstream sstr_nodes;
sstr_nodes << group_name << "_nodes";
node_groups[sstr_nodes.str()] = &new_node_group;
element_groups[group_name] = element_group;
AKANTU_DEBUG_OUT();
return *element_group;
}
/* -------------------------------------------------------------------------- */
void GroupManager::destroyElementGroup(const std::string & group_name,
bool destroy_node_group) {
AKANTU_DEBUG_IN();
ElementGroups::iterator eit = element_groups.find(group_name);
ElementGroups::iterator eend = element_groups.end();
if (eit != eend) {
if (destroy_node_group)
destroyNodeGroup(eit->second->getNodeGroup().getName());
delete (eit->second);
element_groups.erase(eit);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GroupManager::destroyAllElementGroups(bool destroy_node_groups) {
AKANTU_DEBUG_IN();
ElementGroups::iterator eit = element_groups.begin();
ElementGroups::iterator eend = element_groups.end();
for(; eit != eend ; ++eit) {
if (destroy_node_groups)
destroyNodeGroup(eit->second->getNodeGroup().getName());
delete (eit->second);
}
element_groups.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
UInt dimension,
NodeGroup & node_group) {
AKANTU_DEBUG_IN();
if(element_groups.find(group_name) != element_groups.end())
AKANTU_EXCEPTION("Trying to create a element group that already exists:" << group_name);
ElementGroup * element_group = new ElementGroup(group_name, mesh, node_group,
dimension,
id + ":" + group_name + "_element_group",
memory_id);
element_groups[group_name] = element_group;
AKANTU_DEBUG_OUT();
return *element_group;
}
/* -------------------------------------------------------------------------- */
template <typename T>
ElementGroup & GroupManager::createFilteredElementGroup(const std::string & group_name,
UInt dimension,
const NodeGroup & node_group,
T & filter) {
AKANTU_DEBUG_IN();
ElementGroup * element_group = NULL;
if (T::type == FilterFunctor::_node_filter_functor) {
NodeGroup & filtered_node_group = this->createFilteredNodeGroup(group_name + "_nodes",
node_group,
filter);
element_group = &(this->createElementGroup(group_name,
dimension,
filtered_node_group));
}
else if (T::type == FilterFunctor::_element_filter_functor) {
AKANTU_DEBUG_ERROR("Cannot handle an ElementFilter yet. Needs to be implemented.");
}
AKANTU_DEBUG_OUT();
return *element_group;
}
/* -------------------------------------------------------------------------- */
class ClusterSynchronizer : public DataAccessor {
typedef std::set< std::pair<UInt, UInt> > DistantIDs;
public:
ClusterSynchronizer(GroupManager & group_manager,
UInt element_dimension,
std::string cluster_name_prefix,
ElementTypeMapArray<UInt> & element_to_fragment,
DistributedSynchronizer & distributed_synchronizer,
UInt nb_cluster) :
group_manager(group_manager),
element_dimension(element_dimension),
cluster_name_prefix(cluster_name_prefix),
element_to_fragment(element_to_fragment),
distributed_synchronizer(distributed_synchronizer),
nb_cluster(nb_cluster) { }
UInt synchronize() {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt rank = comm.whoAmI();
UInt nb_proc = comm.getNbProc();
/// find starting index to renumber local clusters
Array<UInt> nb_cluster_per_proc(nb_proc);
nb_cluster_per_proc(rank) = nb_cluster;
comm.allGather(nb_cluster_per_proc.storage(), 1);
starting_index = std::accumulate(nb_cluster_per_proc.begin(),
nb_cluster_per_proc.begin() + rank,
0);
UInt global_nb_fragment = std::accumulate(nb_cluster_per_proc.begin() + rank,
nb_cluster_per_proc.end(),
starting_index);
/// create the local to distant cluster pairs with neighbors
distributed_synchronizer.computeBufferSize(*this, _gst_gm_clusters);
distributed_synchronizer.asynchronousSynchronize(*this, _gst_gm_clusters);
distributed_synchronizer.waitEndSynchronize(*this, _gst_gm_clusters);
/// count total number of pairs
Array<int> nb_pairs(nb_proc); // This is potentially a bug for more than
// 2**31 pairs, but due to a all gatherv after
// it must be int to match MPI interfaces
nb_pairs(rank) = distant_ids.size();
comm.allGather(nb_pairs.storage(), 1);
UInt total_nb_pairs = std::accumulate(nb_pairs.begin(), nb_pairs.end(), 0);
/// generate pairs global array
UInt local_pair_index = std::accumulate(nb_pairs.storage(),
nb_pairs.storage() + rank, 0);
Array<UInt> total_pairs(total_nb_pairs, 2);
DistantIDs::iterator ids_it = distant_ids.begin();
DistantIDs::iterator ids_end = distant_ids.end();
for (; ids_it != ids_end; ++ids_it, ++local_pair_index) {
total_pairs(local_pair_index, 0) = ids_it->first;
total_pairs(local_pair_index, 1) = ids_it->second;
}
/// communicate pairs to all processors
nb_pairs *= 2;
comm.allGatherV(total_pairs.storage(), nb_pairs.storage());
/// renumber clusters
/// generate fragment list
std::vector< std::set<UInt> > global_clusters;
UInt total_nb_cluster = 0;
Array<bool> is_fragment_in_cluster(global_nb_fragment, 1, false);
std::queue<UInt> fragment_check_list;
while (total_pairs.getSize() != 0) {
/// create a new cluster
++total_nb_cluster;
global_clusters.resize(total_nb_cluster);
std::set<UInt> & current_cluster = global_clusters[total_nb_cluster - 1];
UInt first_fragment = total_pairs(0, 0);
UInt second_fragment = total_pairs(0, 1);
total_pairs.erase(0);
fragment_check_list.push(first_fragment);
fragment_check_list.push(second_fragment);
while (!fragment_check_list.empty()) {
UInt current_fragment = fragment_check_list.front();
UInt * total_pairs_end = total_pairs.storage() + total_pairs.getSize() * 2;
UInt * fragment_found = std::find(total_pairs.storage(),
total_pairs_end,
current_fragment);
if (fragment_found != total_pairs_end) {
UInt position = fragment_found - total_pairs.storage();
UInt pair = position / 2;
UInt other_index = (position + 1) % 2;
fragment_check_list.push(total_pairs(pair, other_index));
total_pairs.erase(pair);
}
else {
fragment_check_list.pop();
current_cluster.insert(current_fragment);
is_fragment_in_cluster(current_fragment) = true;
}
}
}
/// add to FragmentToCluster all local fragments
for (UInt c = 0; c < global_nb_fragment; ++c) {
if (!is_fragment_in_cluster(c)) {
++total_nb_cluster;
global_clusters.resize(total_nb_cluster);
std::set<UInt> & current_cluster = global_clusters[total_nb_cluster - 1];
current_cluster.insert(c);
}
}
/// reorganize element groups to match global clusters
for (UInt c = 0; c < global_clusters.size(); ++c) {
/// create new element group corresponding to current cluster
std::stringstream sstr;
sstr << cluster_name_prefix << "_" << c;
ElementGroup & cluster = group_manager.createElementGroup(sstr.str(),
element_dimension,
true);
std::set<UInt>::iterator it = global_clusters[c].begin();
std::set<UInt>::iterator end = global_clusters[c].end();
/// append to current element group all fragments that belong to
/// the same cluster if they exist
for (; it != end; ++it) {
Int local_index = *it - starting_index;
if (local_index < 0 || local_index >= Int(nb_cluster)) continue;
std::stringstream tmp_sstr;
tmp_sstr << "tmp_" << cluster_name_prefix << "_" << local_index;
GroupManager::element_group_iterator eg_it
= group_manager.element_group_find(tmp_sstr.str());
AKANTU_DEBUG_ASSERT(eg_it != group_manager.element_group_end(),
"Temporary fragment \""<< tmp_sstr.str() << "\" not found");
cluster.append(*(eg_it->second));
group_manager.destroyElementGroup(tmp_sstr.str(), true);
}
}
return total_nb_cluster;
}
private:
/// functions for parallel communications
inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const {
if (tag == _gst_gm_clusters)
return elements.getSize() * sizeof(UInt);
return 0;
}
inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
if (tag != _gst_gm_clusters) return;
Array<Element>::const_iterator<> el_it = elements.begin();
Array<Element>::const_iterator<> el_end = elements.end();
for (; el_it != el_end; ++el_it) {
const Element & el = *el_it;
/// for each element pack its global cluster index
buffer << element_to_fragment(el.type, el.ghost_type)(el.element) + starting_index;
}
}
inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
if (tag != _gst_gm_clusters) return;
Array<Element>::const_iterator<> el_it = elements.begin();
Array<Element>::const_iterator<> el_end = elements.end();
for (; el_it != el_end; ++el_it) {
UInt distant_cluster;
buffer >> distant_cluster;
const Element & el = *el_it;
UInt local_cluster = element_to_fragment(el.type, el.ghost_type)(el.element) + starting_index;
distant_ids.insert(std::make_pair(local_cluster, distant_cluster));
}
}
private:
GroupManager & group_manager;
UInt element_dimension;
std::string cluster_name_prefix;
ElementTypeMapArray<UInt> & element_to_fragment;
DistributedSynchronizer & distributed_synchronizer;
UInt nb_cluster;
DistantIDs distant_ids;
UInt starting_index;
};
/* -------------------------------------------------------------------------- */
/// \todo this function doesn't work in 1D
UInt GroupManager::createBoundaryGroupFromGeometry() {
UInt spatial_dimension = mesh.getSpatialDimension();
return createClusters(spatial_dimension - 1, "boundary");
}
/* -------------------------------------------------------------------------- */
//// \todo if needed element list construction can be optimized by
//// templating the filter class
UInt GroupManager::createClusters(UInt element_dimension,
std::string cluster_name_prefix,
const GroupManager::ClusteringFilter & filter,
DistributedSynchronizer * distributed_synchronizer,
Mesh * mesh_facets) {
AKANTU_DEBUG_IN();
UInt nb_proc = StaticCommunicator::getStaticCommunicator().getNbProc();
std::string tmp_cluster_name_prefix = cluster_name_prefix;
ElementTypeMapArray<UInt> * element_to_fragment = NULL;
if (nb_proc > 1 && distributed_synchronizer) {
element_to_fragment = new ElementTypeMapArray<UInt>;
mesh.initElementTypeMapArray(*element_to_fragment, 1, element_dimension,
false, _ek_not_defined, true);
tmp_cluster_name_prefix = "tmp_" + tmp_cluster_name_prefix;
}
/// Get facets
bool mesh_facets_created = false;
if (!mesh_facets && element_dimension > 0) {
mesh_facets = new Mesh(mesh.getSpatialDimension(),
mesh.getNodes().getID(),
"mesh_facets_for_clusters");
mesh_facets->defineMeshParent(mesh);
MeshUtils::buildAllFacets(mesh, *mesh_facets,
element_dimension,
element_dimension - 1,
distributed_synchronizer);
}
ElementTypeMapArray<bool> seen_elements("seen_elements");
mesh.initElementTypeMapArray(seen_elements, 1, element_dimension,
false, _ek_not_defined, true);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Element el;
el.ghost_type = ghost_type;
Mesh::type_iterator type_it = mesh.firstType(element_dimension,
ghost_type, _ek_not_defined);
Mesh::type_iterator type_end = mesh.lastType (element_dimension,
ghost_type, _ek_not_defined);
for (; type_it != type_end; ++type_it) {
el.type = *type_it;
el.kind = Mesh::getKind(*type_it);
UInt nb_element = mesh.getNbElement(*type_it, ghost_type);
Array<bool> & seen_elements_array = seen_elements(el.type, ghost_type);
for (UInt e = 0; e < nb_element; ++e) {
el.element = e;
if (!filter(el))
seen_elements_array(e) = true;
}
}
}
Array<bool> checked_node(mesh.getNbNodes(), 1, false);
UInt nb_cluster = 0;
/// keep looping until all elements are seen
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
Element uns_el;
uns_el.ghost_type = ghost_type;
Mesh::type_iterator type_it = mesh.firstType(element_dimension,
ghost_type,
_ek_not_defined);
Mesh::type_iterator type_end = mesh.lastType(element_dimension,
ghost_type,
_ek_not_defined);
for (; type_it != type_end; ++type_it) {
uns_el.type = *type_it;
Array<bool> & seen_elements_vec = seen_elements(uns_el.type, uns_el.ghost_type);
for (UInt e = 0; e < seen_elements_vec.getSize(); ++e) {
// skip elements that have been already seen
if (seen_elements_vec(e) == true) continue;
// set current element
uns_el.element = e;
seen_elements_vec(e) = true;
/// create a new cluster
std::stringstream sstr;
sstr << tmp_cluster_name_prefix << "_" << nb_cluster;
ElementGroup & cluster = createElementGroup(sstr.str(),
element_dimension,
true);
++nb_cluster;
// point element are cluster by themself
if(element_dimension == 0) {
cluster.add(uns_el);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(uns_el.type);
Vector<UInt> connect =
mesh.getConnectivity(uns_el.type, uns_el.ghost_type).begin(nb_nodes_per_element)[uns_el.element];
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
/// add element's nodes to the cluster
UInt node = connect[n];
if (!checked_node(node)) {
cluster.addNode(node);
checked_node(node) = true;
}
}
continue;
}
std::queue<Element> element_to_add;
element_to_add.push(uns_el);
/// keep looping until current cluster is complete (no more
/// connected elements)
while(!element_to_add.empty()) {
/// take first element and erase it in the queue
Element el = element_to_add.front();
element_to_add.pop();
/// if parallel, store cluster index per element
if (nb_proc > 1 && distributed_synchronizer)
(*element_to_fragment)(el.type, el.ghost_type)(el.element) = nb_cluster - 1;
/// add current element to the cluster
cluster.add(el);
const Array<Element> & element_to_facet
= mesh_facets->getSubelementToElement(el.type, el.ghost_type);
UInt nb_facet_per_element = element_to_facet.getNbComponent();
for (UInt f = 0; f < nb_facet_per_element; ++f) {
const Element & facet = element_to_facet(el.element, f);
if (facet == ElementNull) continue;
const std::vector<Element> & connected_elements
= mesh_facets->getElementToSubelement(facet.type, facet.ghost_type)(facet.element);
for (UInt elem = 0; elem < connected_elements.size(); ++elem) {
const Element & check_el = connected_elements[elem];
// check if this element has to be skipped
if (check_el == ElementNull || check_el == el) continue;
Array<bool> & seen_elements_vec_current
= seen_elements(check_el.type, check_el.ghost_type);
if (seen_elements_vec_current(check_el.element) == false) {
seen_elements_vec_current(check_el.element) = true;
element_to_add.push(check_el);
}
}
}
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
Vector<UInt> connect =
mesh.getConnectivity(el.type, el.ghost_type).begin(nb_nodes_per_element)[el.element];
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
/// add element's nodes to the cluster
UInt node = connect[n];
if (!checked_node(node)) {
cluster.addNode(node, false);
checked_node(node) = true;
}
}
}
}
}
}
if (nb_proc > 1 && distributed_synchronizer) {
ClusterSynchronizer cluster_synchronizer(*this, element_dimension,
cluster_name_prefix,
*element_to_fragment,
*distributed_synchronizer,
nb_cluster);
nb_cluster = cluster_synchronizer.synchronize();
delete element_to_fragment;
}
if (mesh_facets_created)
delete mesh_facets;
if(mesh.isDistributed())
this->synchronizeGroupNames();
AKANTU_DEBUG_OUT();
return nb_cluster;
}
/* -------------------------------------------------------------------------- */
template<typename T>
void GroupManager::createGroupsFromMeshData(const std::string & dataset_name) {
std::set<std::string> group_names;
const ElementTypeMapArray<T> & datas = mesh.getData<T>(dataset_name);
typedef typename ElementTypeMapArray<T>::type_iterator type_iterator;
std::map<std::string, UInt> group_dim;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
type_iterator type_it = datas.firstType(_all_dimensions, *gt);
type_iterator type_end = datas.lastType(_all_dimensions, *gt);
for (; type_it != type_end; ++type_it) {
const Array<T> & dataset = datas(*type_it, *gt);
UInt nb_element = mesh.getNbElement(*type_it, *gt);
AKANTU_DEBUG_ASSERT(dataset.getSize() == nb_element,
"Not the same number of elements ("<< *type_it << ":" << *gt <<
") in the map from MeshData (" << dataset.getSize() << ") "
<< dataset_name <<" and in the mesh (" << nb_element << ")!");
for(UInt e(0); e < nb_element; ++e) {
std::stringstream sstr; sstr << dataset(e);
std::string gname = sstr.str();
group_names.insert(gname);
std::map<std::string, UInt>::iterator it = group_dim.find(gname);
if(it == group_dim.end()) {
group_dim[gname] = mesh.getSpatialDimension(*type_it);
} else {
it->second = std::max(it->second, mesh.getSpatialDimension(*type_it));
}
}
}
}
std::set<std::string>::iterator git = group_names.begin();
std::set<std::string>::iterator gend = group_names.end();
for (;git != gend; ++git) createElementGroup(*git, group_dim[*git]);
if(mesh.isDistributed())
this->synchronizeGroupNames();
Element el;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
el.ghost_type = *gt;
type_iterator type_it = datas.firstType(_all_dimensions, *gt);
type_iterator type_end = datas.lastType(_all_dimensions, *gt);
for (; type_it != type_end; ++type_it) {
el.type = *type_it;
const Array<T> & dataset = datas(*type_it, *gt);
UInt nb_element = mesh.getNbElement(*type_it, *gt);
AKANTU_DEBUG_ASSERT(dataset.getSize() == nb_element,
"Not the same number of elements in the map from MeshData and in the mesh!");
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(el.type);
Array<UInt>::const_iterator< Vector<UInt> > cit =
mesh.getConnectivity(*type_it, *gt).begin(nb_nodes_per_element);
for(UInt e(0); e < nb_element; ++e, ++cit) {
el.element = e;
std::stringstream sstr; sstr << dataset(e);
ElementGroup & group = getElementGroup(sstr.str());
group.add(el, false, false);
const Vector<UInt> & connect = *cit;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = connect[n];
group.addNode(node, false);
}
}
}
}
git = group_names.begin();
for (;git != gend; ++git) {
getElementGroup(*git).optimize();
}
}
template void GroupManager::createGroupsFromMeshData<std::string>(const std::string & dataset_name);
template void GroupManager::createGroupsFromMeshData<UInt>(const std::string & dataset_name);
/* -------------------------------------------------------------------------- */
void GroupManager::createElementGroupFromNodeGroup(const std::string & name,
const std::string & node_group_name,
UInt dimension) {
NodeGroup & node_group = getNodeGroup(node_group_name);
ElementGroup & group = createElementGroup(name, dimension, node_group);
group.fillFromNodeGroup();
}
/* -------------------------------------------------------------------------- */
void GroupManager::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "GroupManager [" << std::endl;
std::set<std::string> node_group_seen;
for(const_element_group_iterator it(element_group_begin()); it != element_group_end(); ++it) {
it->second->printself(stream, indent + 1);
node_group_seen.insert(it->second->getNodeGroup().getName());
}
for(const_node_group_iterator it(node_group_begin()); it != node_group_end(); ++it) {
if(node_group_seen.find(it->second->getName()) == node_group_seen.end())
it->second->printself(stream, indent + 1);
}
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
UInt GroupManager::getNbElementGroups(UInt dimension) const {
if(dimension == _all_dimensions) return element_groups.size();
ElementGroups::const_iterator it = element_groups.begin();
ElementGroups::const_iterator end = element_groups.end();
UInt count = 0;
for(;it != end; ++it) count += (it->second->getDimension() == dimension);
return count;
}
/* -------------------------------------------------------------------------- */
void GroupManager::checkAndAddGroups(CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
UInt nb_node_group; buffer >> nb_node_group;
AKANTU_DEBUG_INFO("Received " << nb_node_group << " node group names");
for (UInt ng = 0; ng < nb_node_group; ++ng) {
std::string node_group_name;
buffer >> node_group_name;
if(node_groups.find(node_group_name) == node_groups.end()) {
this->createNodeGroup(node_group_name);
}
AKANTU_DEBUG_INFO("Received node goup name: " << node_group_name);
}
UInt nb_element_group; buffer >> nb_element_group;
AKANTU_DEBUG_INFO("Received " << nb_element_group << " element group names");
for (UInt eg = 0; eg < nb_element_group; ++eg) {
std::string element_group_name; buffer >> element_group_name;
std::string node_group_name; buffer >> node_group_name;
UInt dim; buffer >> dim;
AKANTU_DEBUG_INFO("Received element group name: " << element_group_name
<< " corresponding to a "
<< Int(dim) << "D group with node group "
<< node_group_name);
NodeGroup & node_group = *node_groups[node_group_name];
if(element_groups.find(element_group_name) == element_groups.end()) {
this->createElementGroup(element_group_name, dim, node_group);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GroupManager::fillBufferWithGroupNames(DynamicCommunicationBuffer & comm_buffer) const {
AKANTU_DEBUG_IN();
// packing node group names;
UInt nb_groups = this->node_groups.size();
comm_buffer << nb_groups;
AKANTU_DEBUG_INFO("Sending " << nb_groups << " node group names");
NodeGroups::const_iterator nnames_it = node_groups.begin();
NodeGroups::const_iterator nnames_end = node_groups.end();
for (; nnames_it != nnames_end; ++nnames_it) {
std::string node_group_name = nnames_it->first;
comm_buffer << node_group_name;
AKANTU_DEBUG_INFO("Sending node goupe name: " << node_group_name);
}
// packing element group names with there associated node group name
nb_groups = this->element_groups.size();
comm_buffer << nb_groups;
AKANTU_DEBUG_INFO("Sending " << nb_groups << " element group names");
ElementGroups::const_iterator gnames_it = this->element_groups.begin();
ElementGroups::const_iterator gnames_end = this->element_groups.end();
for (; gnames_it != gnames_end; ++gnames_it) {
ElementGroup & element_group = *(gnames_it->second);
std::string element_group_name = gnames_it->first;
std::string node_group_name = element_group.getNodeGroup().getName();
UInt dim = element_group.getDimension();
comm_buffer << element_group_name;
comm_buffer << node_group_name;
comm_buffer << dim;
AKANTU_DEBUG_INFO("Sending element group name: " << element_group_name
<< " corresponding to a "
<< Int(dim) << "D group with the node group "
<< node_group_name);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void GroupManager::synchronizeGroupNames() {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
if(nb_proc == 1) return;
if(my_rank == 0) {
for (UInt p = 1; p < nb_proc; ++p) {
CommunicationStatus status;
comm.probe<char>(p, p, status);
AKANTU_DEBUG_INFO("Got " << printMemorySize<char>(status.getSize()) << " from proc " << p);
CommunicationBuffer recv_buffer(status.getSize());
comm.receive(recv_buffer.storage(), recv_buffer.getSize(), p, p);
this->checkAndAddGroups(recv_buffer);
}
DynamicCommunicationBuffer comm_buffer;
this->fillBufferWithGroupNames(comm_buffer);
UInt buffer_size = comm_buffer.getSize();
comm.broadcast(&buffer_size, 1, 0);
AKANTU_DEBUG_INFO("Initiating broadcast with " << printMemorySize<char>(comm_buffer.getSize()));
comm.broadcast(comm_buffer.storage(), buffer_size, 0);
} else {
DynamicCommunicationBuffer comm_buffer;
this->fillBufferWithGroupNames(comm_buffer);
AKANTU_DEBUG_INFO("Sending " << printMemorySize<char>(comm_buffer.getSize()) << " to proc " << 0);
comm.send(comm_buffer.storage(), comm_buffer.getSize(), 0, my_rank);
UInt buffer_size = 0;
comm.broadcast(&buffer_size, 1, 0);
AKANTU_DEBUG_INFO("Receiving broadcast with " << printMemorySize<char>(comm_buffer.getSize()));
CommunicationBuffer recv_buffer(buffer_size);
comm.broadcast(recv_buffer.storage(), recv_buffer.getSize(), 0);
this->checkAndAddGroups(recv_buffer);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
const ElementGroup & GroupManager::getElementGroup(const std::string & name) const {
const_element_group_iterator it = element_group_find(name);
if(it == element_group_end()) {
AKANTU_EXCEPTION("There are no element groups named " << name
<< " associated to the group manager: " << id);
}
return *(it->second);
}
/* -------------------------------------------------------------------------- */
ElementGroup & GroupManager::getElementGroup(const std::string & name) {
element_group_iterator it = element_group_find(name);
if(it == element_group_end()) {
AKANTU_EXCEPTION("There are no element groups named " << name
<< " associated to the group manager: " << id);
}
return *(it->second);
}
/* -------------------------------------------------------------------------- */
const NodeGroup & GroupManager::getNodeGroup(const std::string & name) const {
const_node_group_iterator it = node_group_find(name);
if(it == node_group_end()) {
AKANTU_EXCEPTION("There are no node groups named " << name
<< " associated to the group manager: " << id);
}
return *(it->second);
}
/* -------------------------------------------------------------------------- */
NodeGroup & GroupManager::getNodeGroup(const std::string & name) {
node_group_iterator it = node_group_find(name);
if(it == node_group_end()) {
AKANTU_EXCEPTION("There are no node groups named " << name
<< " associated to the group manager: " << id);
}
return *(it->second);
}
__END_AKANTU__
diff --git a/src/mesh/group_manager.hh b/src/mesh/group_manager.hh
index 912ae8f18..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 T, bool filtered> class dump_type>
+ 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 939a04505..6a55937a2 100644
--- a/src/mesh/group_manager_inline_impl.cc
+++ b/src/mesh/group_manager_inline_impl.cc
@@ -1,215 +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){
- if (&field == NULL) return NULL;
+ 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){
- if (&field == NULL) return NULL;
+ 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 T, bool filtered> class dump_type> ///< type of InternalMaterialField
+ 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) {
- if (&field == NULL) return NULL;
+ 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) {
- if (&field == NULL) return NULL;
+ 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) {
- if (&field == NULL) return NULL;
+
+ 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 c28a6db5e..370c81e91 100644
--- a/src/mesh/mesh.cc
+++ b/src/mesh/mesh.cc
@@ -1,509 +1,467 @@
/**
* @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_material_internal_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),
- normals("normals", id),
- spatial_dimension(spatial_dimension),
- types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
- ghost_types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
- lower_bounds(spatial_dimension,0.),
- upper_bounds(spatial_dimension,0.),
- size(spatial_dimension, 0.),
- local_lower_bounds(spatial_dimension,0.),
- local_upper_bounds(spatial_dimension,0.),
- mesh_data("mesh_data", id, memory_id),
- mesh_facets(NULL) {
+Mesh::Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id)
+ : Memory(id, memory_id),
+ GroupManager(*this, id + ":group_manager", memory_id),
+ nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
+ created_nodes(true), connectivities("connectivities", id),
+ normals("normals", id), spatial_dimension(spatial_dimension),
+ types_offsets(Array<UInt>((UInt)_max_element_type + 1, 1)),
+ ghost_types_offsets(Array<UInt>((UInt)_max_element_type + 1, 1)),
+ lower_bounds(spatial_dimension, 0.), upper_bounds(spatial_dimension, 0.),
+ size(spatial_dimension, 0.), local_lower_bounds(spatial_dimension, 0.),
+ local_upper_bounds(spatial_dimension, 0.),
+ mesh_data("mesh_data", id, memory_id), mesh_facets(NULL) {
AKANTU_DEBUG_IN();
this->nodes = &(alloc<Real>(id + ":coordinates", 0, this->spatial_dimension));
nb_global_nodes = 0;
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-Mesh::Mesh(UInt spatial_dimension,
- const ID & nodes_id,
- const ID & id,
- const MemoryID & memory_id) :
- Memory(id, memory_id),
- GroupManager(*this, id + ":group_manager", memory_id),
- nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
- created_nodes(false),
- connectivities("connectivities", id),
- normals("normals", id),
- spatial_dimension(spatial_dimension),
- types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
- ghost_types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
- lower_bounds(spatial_dimension,0.),
- upper_bounds(spatial_dimension,0.),
- size(spatial_dimension, 0.),
- local_lower_bounds(spatial_dimension,0.),
- local_upper_bounds(spatial_dimension,0.),
- mesh_data("mesh_data", id, memory_id),
- mesh_facets(NULL) {
+Mesh::Mesh(UInt spatial_dimension, const ID & nodes_id, const ID & id,
+ const MemoryID & memory_id)
+ : Memory(id, memory_id),
+ GroupManager(*this, id + ":group_manager", memory_id),
+ nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
+ created_nodes(false), connectivities("connectivities", id),
+ normals("normals", id), spatial_dimension(spatial_dimension),
+ types_offsets(Array<UInt>((UInt)_max_element_type + 1, 1)),
+ ghost_types_offsets(Array<UInt>((UInt)_max_element_type + 1, 1)),
+ lower_bounds(spatial_dimension, 0.), upper_bounds(spatial_dimension, 0.),
+ size(spatial_dimension, 0.), local_lower_bounds(spatial_dimension, 0.),
+ local_upper_bounds(spatial_dimension, 0.),
+ mesh_data("mesh_data", id, memory_id), mesh_facets(NULL) {
AKANTU_DEBUG_IN();
this->nodes = &(getArray<Real>(nodes_id));
nb_global_nodes = nodes->getSize();
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-Mesh::Mesh(UInt spatial_dimension,
- Array<Real> & nodes,
- const ID & id,
- const MemoryID & memory_id) :
- Memory(id, memory_id),
- GroupManager(*this, id + ":group_manager", memory_id),
- nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
- created_nodes(false),
- connectivities("connectivities", id),
- normals("normals", id),
- spatial_dimension(spatial_dimension),
- types_offsets(Array<UInt>(_max_element_type + 1, 1)),
- ghost_types_offsets(Array<UInt>(_max_element_type + 1, 1)),
- lower_bounds(spatial_dimension,0.),
- upper_bounds(spatial_dimension,0.),
- size(spatial_dimension, 0.),
- local_lower_bounds(spatial_dimension,0.),
- local_upper_bounds(spatial_dimension,0.),
- mesh_data("mesh_data", id, memory_id),
- mesh_facets(NULL) {
+Mesh::Mesh(UInt spatial_dimension, Array<Real> & nodes, const ID & id,
+ const MemoryID & memory_id)
+ : Memory(id, memory_id),
+ GroupManager(*this, id + ":group_manager", memory_id),
+ nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
+ created_nodes(false), connectivities("connectivities", id),
+ normals("normals", id), spatial_dimension(spatial_dimension),
+ types_offsets(Array<UInt>(_max_element_type + 1, 1)),
+ ghost_types_offsets(Array<UInt>(_max_element_type + 1, 1)),
+ lower_bounds(spatial_dimension, 0.), upper_bounds(spatial_dimension, 0.),
+ size(spatial_dimension, 0.), local_lower_bounds(spatial_dimension, 0.),
+ local_upper_bounds(spatial_dimension, 0.),
+ mesh_data("mesh_data", id, memory_id), mesh_facets(NULL) {
AKANTU_DEBUG_IN();
this->nodes = &(nodes);
nb_global_nodes = nodes.getSize();
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh & Mesh::initMeshFacets(const ID & id) {
AKANTU_DEBUG_IN();
if (!mesh_facets) {
- mesh_facets = new Mesh(spatial_dimension,
- *(this->nodes),
- getID()+":"+id,
- getMemoryID());
+ mesh_facets = 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 4047cafbf..4b7d02ab6 100644
--- a/src/mesh/mesh.hh
+++ b/src/mesh/mesh.hh
@@ -1,566 +1,575 @@
/**
* @file mesh.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Dana Christen <dana.christen@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Jun 18 2010
- * @date last modification: Fri Sep 05 2014
+ * @date last modification: Thu Jan 14 2016
*
* @brief the class representing the meshes
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MESH_HH__
#define __AKANTU_MESH_HH__
/* -------------------------------------------------------------------------- */
#include "aka_config.hh"
#include "aka_common.hh"
#include "aka_memory.hh"
#include "aka_array.hh"
#include "element_class.hh"
#include "element_type_map.hh"
#include "aka_event_handler_manager.hh"
#include "group_manager.hh"
#include "element.hh"
/* -------------------------------------------------------------------------- */
#include <set>
/* -------------------------------------------------------------------------- */
#include "mesh_data.hh"
#include "dumpable.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Mesh modifications events */
/* -------------------------------------------------------------------------- */
#include "mesh_events.hh"
/* -------------------------------------------------------------------------- */
/* Mesh */
/* -------------------------------------------------------------------------- */
/**
* @class Mesh this contain the coordinates of the nodes in the Mesh.nodes
* Array, and the connectivity. The connectivity are stored in by element
* types.
*
* To know all the element types present in a mesh you can get the
* Mesh::ConnectivityTypeList
*
* In order to loop on all element you have to loop on all types like this :
* @code{.cpp}
Mesh::type_iterator it = mesh.firstType(dim, ghost_type);
Mesh::type_iterator end = mesh.lastType(dim, ghost_type);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it);
const Array<UInt> & conn = mesh.getConnectivity(*it);
for(UInt e = 0; e < nb_element; ++e) {
...
}
}
@endcode
*/
class Mesh : protected Memory,
public EventHandlerManager<MeshEventHandler>,
public GroupManager,
- public Dumpable {
+ 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
+ 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);
+ UInt dimension,
+ GhostType ghost_type);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the id of the mesh
AKANTU_GET_MACRO(ID, Memory::id, const ID &);
/// get the spatial dimension of the mesh = number of component of the coordinates
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// get the nodes Array aka coordinates
AKANTU_GET_MACRO(Nodes, *nodes, const Array<Real> &);
AKANTU_GET_MACRO_NOT_CONST(Nodes, *nodes, Array<Real> &);
/// get the normals for the elements
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Normals, normals, Real);
/// get the number of nodes
AKANTU_GET_MACRO(NbNodes, nodes->getSize(), UInt);
/// get the Array of global ids of the nodes (only used in parallel)
AKANTU_GET_MACRO(GlobalNodesIds, *nodes_global_ids, const Array<UInt> &);
+ AKANTU_GET_MACRO_NOT_CONST(GlobalNodesIds, *nodes_global_ids, Array<UInt> &);
/// get the global id of a node
inline UInt getNodeGlobalId(UInt local_id) const;
/// get the global number of nodes
inline UInt getNbGlobalNodes() const;
/// get the nodes type Array
AKANTU_GET_MACRO(NodesType, nodes_type, const Array<Int> &);
protected:
AKANTU_GET_MACRO_NOT_CONST(NodesType, nodes_type, Array<Int> &);
public:
inline Int getNodeType(UInt local_id) const;
/// say if a node is a pure ghost node
inline bool isPureGhostNode(UInt n) const;
/// say if a node is pur local or master node
inline bool isLocalOrMasterNode(UInt n) const;
inline bool isLocalNode(UInt n) const;
inline bool isMasterNode(UInt n) const;
inline bool isSlaveNode(UInt n) const;
AKANTU_GET_MACRO(LowerBounds, lower_bounds, const Vector<Real> &);
AKANTU_GET_MACRO(UpperBounds, upper_bounds, const Vector<Real> &);
AKANTU_GET_MACRO(LocalLowerBounds, local_lower_bounds, const Vector<Real> &);
AKANTU_GET_MACRO(LocalUpperBounds, local_upper_bounds, const Vector<Real> &);
/// get the connectivity Array for a given type
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Connectivity, connectivities, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Connectivity, connectivities, UInt);
AKANTU_GET_MACRO(Connectivities, connectivities, const ElementTypeMapArray<UInt> &);
/// get the number of element of a type in the mesh
inline UInt getNbElement(const ElementType & type, const GhostType & ghost_type = _not_ghost) const;
/// get the number of element for a given ghost_type and a given dimension
inline UInt getNbElement(const UInt spatial_dimension = _all_dimensions,
- const GhostType & ghost_type = _not_ghost,
- const ElementKind & kind = _ek_not_defined) const;
+ 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 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 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);
+ const ElementKind & element_kind);
template <typename T>
dumper::Field * createFieldFromAttachedData(const std::string & field_id,
- const std::string & group_name,
- const ElementKind & element_kind);
+ 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 ElementType & el_type,
const GhostType & ghost_type = _not_ghost,
UInt nb_component = 1,
- bool size_to_nb_element = true,
- bool resize_with_parent = false);
+ 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);
+ 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 42beadb81..c9b515eed 100644
--- a/src/mesh/mesh_data.hh
+++ b/src/mesh/mesh_data.hh
@@ -1,138 +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 & type, const GhostType & ghost_type) const;
+ 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);
- template<typename T>
- TypeCode getTypeCode() const;
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 0ca1e62ab..27343db0f 100644
--- a/src/mesh/mesh_data_tmpl.hh
+++ b/src/mesh/mesh_data_tmpl.hh
@@ -1,212 +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) : { \
+#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; \
- } \
+ 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 eede33fa1..b3d7036f1 100644
--- a/src/mesh/mesh_events.hh
+++ b/src/mesh/mesh_events.hh
@@ -1,120 +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__
-template<class Entity>
-class MeshEvent {
+/// 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() {};
+ virtual ~NewNodesEvent(){};
};
+
+/// akantu::MeshEvent related to nodes removed from the mesh
class RemovedNodesEvent : public MeshEvent<UInt> {
public:
- virtual ~RemovedNodesEvent() {};
+ 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() {};
+ virtual ~NewElementsEvent(){};
};
+/// akantu::MeshEvent related to elements removed from the mesh
class RemovedElementsEvent : public MeshEvent<Element> {
public:
- virtual ~RemovedElementsEvent() {};
- inline RemovedElementsEvent(const Mesh & mesh);
- AKANTU_GET_MACRO(NewNumbering, new_numbering, const ElementTypeMapArray<UInt> &);
- AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, ElementTypeMapArray<UInt> &);
+ 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() {};
+ virtual ~MeshEventHandler(){};
/* ------------------------------------------------------------------------ */
/* Internal code */
/* ------------------------------------------------------------------------ */
private:
- inline void sendEvent(const NewNodesEvent & event) { onNodesAdded (event.getList(),
- event); }
- inline void sendEvent(const RemovedNodesEvent & event) { onNodesRemoved(event.getList(),
- event.getNewNumbering(),
- event); }
-
- inline void sendEvent(const NewElementsEvent & event) { onElementsAdded (event.getList(),
- event); }
- inline void sendEvent(const RemovedElementsEvent & event) { onElementsRemoved(event.getList(),
- event.getNewNumbering(),
- event); }
-
- template<class EventHandler>
- friend class EventHandlerManager;
+ /// 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:
- 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 (__attribute__((unused)) const Array<Element> & elements_list,
- __attribute__((unused)) const NewElementsEvent & event) { }
- virtual void onElementsRemoved(__attribute__((unused)) const Array<Element> & elements_list,
- __attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
- __attribute__((unused)) const RemovedElementsEvent & event) { }
+ /// 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 2562c5484..fcd25618d 100644
--- a/src/mesh/mesh_filter.hh
+++ b/src/mesh/mesh_filter.hh
@@ -1,71 +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 Fonctors */
+/* 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 b5e90aee9..85351300b 100644
--- a/src/mesh/mesh_inline_impl.cc
+++ b/src/mesh/mesh_inline_impl.cc
@@ -1,587 +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) :
- new_numbering("new_numbering", mesh.getID()) {
-}
+inline RemovedElementsEvent::RemovedElementsEvent(const Mesh & mesh,
+ ID new_numbering_id)
+ : new_numbering(new_numbering_id, mesh.getID()) {}
/* -------------------------------------------------------------------------- */
template <>
-inline void Mesh::sendEvent<RemovedElementsEvent>(RemovedElementsEvent & event) {
+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 {
- AKANTU_DEBUG_IN();
-
+ const GhostType & ghost_type) const {
try {
const Array<UInt> & conn = connectivities(type, ghost_type);
- AKANTU_DEBUG_OUT();
return conn.getSize();
} catch (...) {
- AKANTU_DEBUG_OUT();
return 0;
}
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbElement(const UInt spatial_dimension,
- const GhostType & ghost_type,
- const ElementKind & kind) const {
- AKANTU_DEBUG_IN();
+ 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);
- AKANTU_DEBUG_OUT();
return nb_element;
}
-
/* -------------------------------------------------------------------------- */
inline void Mesh::getBarycenter(UInt element, const ElementType & type,
- Real * barycenter,
- GhostType ghost_type) const {
- AKANTU_DEBUG_IN();
-
+ 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);
- AKANTU_DEBUG_OUT();
+ 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;
-__END_AKANTU__
+ Array<Element>::const_iterator<Element> el_it = elements.begin();
+ Array<Element>::const_iterator<Element> el_end = elements.end();
+
+ for (; el_it != el_end; ++el_it) {
+ const Element & el = *el_it;
+ if (el.type != current_element_type) {
+ current_element_type = el.type;
+ nb_nodes_per_element = Mesh::getNbNodesPerElement(current_element_type);
+ }
+
+ nb_nodes += nb_nodes_per_element;
+ }
+
+ return nb_nodes;
+}
+/* -------------------------------------------------------------------------- */
+
+__END_AKANTU__
#endif /* __AKANTU_MESH_INLINE_IMPL_CC__ */
diff --git a/src/mesh/node_group.cc b/src/mesh/node_group.cc
index 29d4a31bd..5bb93cec5 100644
--- a/src/mesh/node_group.cc
+++ b/src/mesh/node_group.cc
@@ -1,109 +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){
+ 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 bc19c23d2..9143bb820 100644
--- a/src/mesh/node_group.hh
+++ b/src/mesh/node_group.hh
@@ -1,133 +1,134 @@
/**
* @file node_group.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Mon Jun 09 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Node group definition
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
#include "aka_memory.hh"
#include "mesh_filter.hh"
#include "dumpable.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_NODE_GROUP_HH__
#define __AKANTU_NODE_GROUP_HH__
__BEGIN_AKANTU__
class NodeGroup : public Memory, public Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NodeGroup(const std::string & name,
const Mesh & mesh,
const std::string & id = "node_group",
const MemoryID & memory_id = 0);
virtual ~NodeGroup();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
typedef Array<UInt>::const_iterator<UInt> const_node_iterator;
/// empty the node group
void empty();
/// iterator to the beginning of the node group
inline const_node_iterator begin() const;
/// iterator to the end of the node group
inline const_node_iterator end() const;
/// add a node and give the local position through an iterator
inline const_node_iterator add(UInt node, bool check_for_duplicate = true);
/// remove duplicated nodes
void optimize();
/// append a group to current one
void append(const NodeGroup & other_group);
/// apply a filter on current node group
template <typename T>
void applyNodeFilter(T & filter);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO_NOT_CONST(Nodes, node_group, Array<UInt> &);
AKANTU_GET_MACRO(Nodes, node_group, const Array<UInt> &);
AKANTU_GET_MACRO(Name, name, const std::string &);
/// give the number of nodes in the current group
inline UInt getSize() const;
UInt * storage(){return node_group.storage();};
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// name of the group
std::string name;
/// list of nodes in the group
Array<UInt> & node_group;
/// reference to the mesh in question
- const Mesh & mesh;
+ //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 040dfb403..d0d676123 100644
--- a/src/mesh/node_group_inline_impl.cc
+++ b/src/mesh/node_group_inline_impl.cc
@@ -1,88 +1,89 @@
/**
* @file node_group_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Wed Nov 13 2013
- * @date last modification: Tue Sep 02 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Dec 08 2015
*
* @brief Node group inline function definitions
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline NodeGroup::const_node_iterator NodeGroup::begin() const {
return node_group.begin();
}
/* -------------------------------------------------------------------------- */
inline NodeGroup::const_node_iterator NodeGroup::end() const {
return node_group.end();
}
/* -------------------------------------------------------------------------- */
inline NodeGroup::const_node_iterator NodeGroup::add(UInt node, bool check_for_duplicate) {
if(check_for_duplicate) {
const_node_iterator it = std::find(begin(), end(), node);
if(it == node_group.end()) {
node_group.push_back(node);
return (node_group.end() - 1);
}
return it;
} else {
node_group.push_back(node);
return (node_group.end() - 1);
}
}
/* -------------------------------------------------------------------------- */
inline UInt NodeGroup::getSize() const {
return node_group.getSize();
}
/* -------------------------------------------------------------------------- */
-class FilterFunctor;
+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 e70d8d5a6..e20861cc5 100644
--- a/src/mesh_utils/cohesive_element_inserter.cc
+++ b/src/mesh_utils/cohesive_element_inserter.cc
@@ -1,429 +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 distributed_synchronizer;
+ 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;
- distributed_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.nb_global_nodes += nb_new_nodes;
- mesh_facets.nb_global_nodes += nb_new_nodes;
+ 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 842f26a6c..6fcea2724 100644
--- a/src/mesh_utils/cohesive_element_inserter.hh
+++ b/src/mesh_utils/cohesive_element_inserter.hh
@@ -1,202 +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);
+ 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;
- /// distributed synchronizer
- DistributedSynchronizer * distributed_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
new file mode 100644
index 000000000..00dfc0699
--- /dev/null
+++ b/src/mesh_utils/global_ids_updater.cc
@@ -0,0 +1,48 @@
+/**
+ * @file global_ids_updater.cc
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Fri Oct 02 2015
+ *
+ * @brief Functions of the GlobalIdsUpdater
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "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
new file mode 100644
index 000000000..254b4c8dd
--- /dev/null
+++ b/src/mesh_utils/global_ids_updater.hh
@@ -0,0 +1,85 @@
+/**
+ * @file global_ids_updater.hh
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..867a4eb24
--- /dev/null
+++ b/src/mesh_utils/global_ids_updater_inline_impl.cc
@@ -0,0 +1,123 @@
+/**
+ * @file global_ids_updater_inline_impl.cc
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @date creation: Fri Oct 02 2015
+ * @date last modification: Sun Oct 04 2015
+ *
+ * @brief Implementation of the inline functions of GlobalIdsUpdater
+ *
+ * @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__
+
+/* -------------------------------------------------------------------------- */
+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 7036e31e3..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:
- /// defini a partition of the mesh
+ /// 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 002083485..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(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_pbc.cc b/src/mesh_utils/mesh_pbc.cc
deleted file mode 100644
index b9dd6aa44..000000000
--- a/src/mesh_utils/mesh_pbc.cc
+++ /dev/null
@@ -1,373 +0,0 @@
-/**
- * @file mesh_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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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::tweakConnectivityForPBC(Mesh & mesh,
-// bool flag_x,
-// bool flag_y,
-// bool flag_z){
-// std::map<UInt,UInt> pbc_pair;
-// mesh.computeBoundingBox();
-// mesh.pbc_directions[0] = flag_x;
-// mesh.pbc_directions[1] = flag_y;
-// mesh.pbc_directions[2] = flag_z;
-
-// if (flag_x) computePBCMap(mesh,0,pbc_pair);
-// if (flag_y) computePBCMap(mesh,1,pbc_pair);
-// if (flag_z) computePBCMap(mesh,2,pbc_pair);
-
-// {
-// std::map<UInt,UInt>::iterator it = pbc_pair.begin();
-// std::map<UInt,UInt>::iterator end = pbc_pair.end();
-
-// Real * coords = mesh.nodes->values;
-// UInt dim = mesh.getSpatialDimension();
-// while(it != end){
-// UInt i1 = (*it).first;
-// UInt i2 = (*it).second;
-
-// AKANTU_DEBUG_INFO("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]
-// << ")");
-// ++it;
-// }
-// }
-
-// //allocate and initialize list of reversed elements
-// mesh.initElementTypeMapArray<UInt>Array(mesh.reversed_elements_pbc,1,0,mesh.id,"reversed");
-// // now loop over the elements to change the connectivity of some elements
-// const Mesh::ConnectivityTypeList & type_list = mesh.getConnectivityTypeList();
-// Mesh::ConnectivityTypeList::const_iterator it;
-// for(it = type_list.begin(); it != type_list.end(); ++it) {
-// ElementType type = *it;
-// UInt nb_elem = mesh.getNbElement(type);
-// UInt nb_nodes_per_elem = mesh.getNbNodesPerElement(type);
-// UInt * conn = mesh.getConnectivityPointer(type)->values;
-// UInt index = 0;
-// Array<UInt> & list = *(mesh.reversed_elements_pbc[type]);
-// for (UInt el = 0; el < nb_elem; el++) {
-// UInt flag_should_register_elem = false;
-// for (UInt k = 0; k < nb_nodes_per_elem; ++k,++index){
-// if (pbc_pair.count(conn[index])){
-// flag_should_register_elem = true;
-// AKANTU_DEBUG_INFO("elem list size " << list.getSize());
-// AKANTU_DEBUG_INFO("node " << conn[index] +1
-// << " switch to "
-// << pbc_pair[conn[index]]+1);
-// // for (UInt toto = 0; toto < 3; ++toto) {
-// // AKANTU_DEBUG_INFO("dir " << toto << " coords "
-// // << mesh.nodes->values[conn[index]*3+toto]
-// // << " switch to "
-// // << mesh.nodes->values[pbc_pair[conn[index]]*3+toto]);
-// // }
-// std::stringstream str_temp;
-// str_temp << "initial elem(" << el << ") is ";
-// for (UInt l = 0 ; l < nb_nodes_per_elem ; ++ l){
-// str_temp << conn[el*nb_nodes_per_elem+l]+1 << " ";
-// }
-// AKANTU_DEBUG_INFO(str_temp.str());
-// conn[index] = pbc_pair[conn[index]];
-// }
-// }
-// if (flag_should_register_elem) list.push_back(el);
-// }
-// }
-// }
-
-/* -------------------------------------------------------------------------- */
-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/mesh_utils/mesh_utils.cc b/src/mesh_utils/mesh_utils.cc
index 6795a344e..3aee622be 100644
--- a/src/mesh_utils/mesh_utils.cc
+++ b/src/mesh_utils/mesh_utils.cc
@@ -1,2058 +1,2241 @@
/**
* @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];
-
- UInt * conn_val[nb_types];
- UInt nb_element[nb_types];
-
+ Vector<UInt> nb_nodes_per_element(nb_types);
+ UInt ** conn_val = new UInt *[nb_types];
+ Vector<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;
- ElementType facet_type = mesh.getFacetType(type);
mesh_facets.getSubelementToElementPointer(type, ghost_type);
- mesh_facets.getElementToSubelementPointer(facet_type, ghost_type);
- mesh_facets.getConnectivityPointer(facet_type, ghost_type);
+
+ Vector<ElementType> facet_types = mesh.getAllFacetTypes(type);
+
+ for (UInt ft = 0; ft < facet_types.size(); ++ft) {
+ ElementType facet_type = facet_types(ft);
+ mesh_facets.getElementToSubelementPointer(facet_type, ghost_type);
+ mesh_facets.getConnectivityPointer(facet_type, ghost_type);
+ }
}
}
Element current_element;
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ 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(type, loc_el.ghost_type);
-
- for (UInt f_in = 0; f_in < nb_facet_per_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;
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.initElementTypeMapArray(barycenters,
- spatial_dimension,
- _all_dimensions);
+ 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) {
+ buildAllFacets(mesh, mesh_facets, 1, synchronizer);
+ UInt spatial_dimension = mesh.getSpatialDimension();
+ const ElementTypeMapArray<UInt> & element_to_rank =
+ synchronizer->getPrankToElement();
+ Int local_rank = StaticCommunicator::getStaticCommunicator().whoAmI();
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+ GhostType ghost_type = *gt;
+ Mesh::type_iterator it = mesh_facets.firstType(1, ghost_type);
+ Mesh::type_iterator end = mesh_facets.lastType(1, ghost_type);
+ for (; it != end; ++it) {
+ ElementType type = *it;
+ UInt nb_segments = mesh_facets.getNbElement(type, ghost_type);
+
+ // allocate the data
+ Array<Int> & segment_to_nodetype = *(mesh_facets.getDataPointer<Int>(
+ "segment_to_nodetype", type, ghost_type));
+
+ std::set<Element> connected_elements;
+ const Array<std::vector<Element> > & segment_to_2Delement =
+ mesh_facets.getElementToSubelement(type, ghost_type);
+
+ // loop over segments
+ for (UInt s = 0; s < nb_segments; ++s) {
+
+ // determine the elements connected to the segment
+ connected_elements.clear();
+ const std::vector<Element> & twoD_elements = segment_to_2Delement(s);
+
+ if (spatial_dimension == 2) {
+ // if 2D just take the elements connected to the segments
+ connected_elements.insert(twoD_elements.begin(), twoD_elements.end());
+ } else if (spatial_dimension == 3) {
+ // if 3D a second loop is needed to get to the 3D elements
+ std::vector<Element>::const_iterator facet = twoD_elements.begin();
+
+ for (; facet != twoD_elements.end(); ++facet) {
+ const std::vector<Element> & threeD_elements =
+ mesh_facets.getElementToSubelement(
+ facet->type, facet->ghost_type)(facet->element);
+ connected_elements.insert(threeD_elements.begin(),
+ threeD_elements.end());
+ }
+ }
+
+ // get the minimum processor rank associated to the connected
+ // elements and verify if ghost and not ghost elements are
+ // found
+ Int minimum_rank = std::numeric_limits<Int>::max();
+
+ // two booleans saying if not ghost and ghost elements are found in the
+ // loop
+ bool ghost_found[2];
+ ghost_found[0] = false;
+ ghost_found[1] = false;
+
+ std::set<Element>::iterator connected_elements_it =
+ connected_elements.begin();
+
+ for (; connected_elements_it != connected_elements.end();
+ ++connected_elements_it) {
+ if (*connected_elements_it == ElementNull)
+ continue;
+ ghost_found[connected_elements_it->ghost_type] = true;
+ const Array<UInt> & el_to_rank_array = element_to_rank(
+ connected_elements_it->type, connected_elements_it->ghost_type);
+ minimum_rank =
+ std::min(minimum_rank,
+ Int(el_to_rank_array(connected_elements_it->element)));
+ }
+
+ // if no ghost elements are found the segment is local
+ if (!ghost_found[1])
+ segment_to_nodetype(s) = -1;
+ // if no not ghost elements are found the segment is pure ghost
+ else if (!ghost_found[0])
+ segment_to_nodetype(s) = -3;
+ // if the minimum rank is equal to the local rank, the segment is master
+ else if (local_rank == minimum_rank)
+ segment_to_nodetype(s) = -2;
+ // if the minimum rank is less than the local rank, the segment is slave
+ else if (local_rank > minimum_rank)
+ segment_to_nodetype(s) = minimum_rank;
+ else
+ AKANTU_DEBUG_ERROR("The local rank cannot be smaller than the "
+ "minimum rank if both ghost and not ghost "
+ "elements are found");
+ }
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+UInt MeshUtils::updateLocalMasterGlobalConnectivity(Mesh & mesh,
+ UInt local_nb_new_nodes) {
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+ Int rank = comm.whoAmI();
+ Int nb_proc = comm.getNbProc();
+ if (nb_proc == 1)
+ return local_nb_new_nodes;
+
+ /// resize global ids array
+ Array<UInt> & nodes_global_ids = mesh.getGlobalNodesIds();
+ UInt old_nb_nodes = mesh.getNbNodes() - local_nb_new_nodes;
+
+ nodes_global_ids.resize(mesh.getNbNodes());
+
+ /// compute the number of global nodes based on the number of old nodes
+ Vector<UInt> old_local_master_nodes(nb_proc);
+ for (UInt n = 0; n < old_nb_nodes; ++n)
+ if (mesh.isLocalOrMasterNode(n))
+ ++old_local_master_nodes(rank);
+ comm.allGather(old_local_master_nodes.storage(), 1);
+ UInt old_global_nodes =
+ std::accumulate(old_local_master_nodes.storage(),
+ old_local_master_nodes.storage() + nb_proc, 0);
+
+ /// compute amount of local or master doubled nodes
+ Vector<UInt> local_master_nodes(nb_proc);
+ for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n)
+ if (mesh.isLocalOrMasterNode(n))
+ ++local_master_nodes(rank);
+
+ comm.allGather(local_master_nodes.storage(), 1);
+
+ /// update global number of nodes
+ UInt total_nb_new_nodes = std::accumulate(
+ local_master_nodes.storage(), local_master_nodes.storage() + nb_proc, 0);
+
+ if (total_nb_new_nodes == 0)
+ return 0;
+
+ /// set global ids of local and master nodes
+ UInt starting_index =
+ std::accumulate(local_master_nodes.storage(),
+ local_master_nodes.storage() + rank, old_global_nodes);
+
+ for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n) {
+ if (mesh.isLocalOrMasterNode(n)) {
+ nodes_global_ids(n) = starting_index;
+ ++starting_index;
+ }
+ }
+
+ mesh.nb_global_nodes = old_global_nodes + total_nb_new_nodes;
+ return total_nb_new_nodes;
+}
+
+/* -------------------------------------------------------------------------- */
+
__END_AKANTU__
// LocalWords: ElementType
diff --git a/src/mesh_utils/mesh_utils.hh b/src/mesh_utils/mesh_utils.hh
index ab73adabf..88b5a8385 100644
--- a/src/mesh_utils/mesh_utils.hh
+++ b/src/mesh_utils/mesh_utils.hh
@@ -1,270 +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 ofr a given spatial dimension
+ /// 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
+ /// 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 on given a direction
+ /// 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
new file mode 100644
index 000000000..592361bc4
--- /dev/null
+++ b/src/mesh_utils/mesh_utils_pbc.cc
@@ -0,0 +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: Tue Sep 15 2015
+ *
+ * @brief periodic boundary condition connectivity tweak
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <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 7e8518bc6..26543509c 100644
--- a/src/model/boundary_condition.hh
+++ b/src/model/boundary_condition.hh
@@ -1,104 +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 45c9a037e..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 QuadraturePoint & 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 QuadraturePoint & 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 QuadraturePoint & 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 QuadraturePoint & 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 c5026d236..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 QuadraturePoint & 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 QuadraturePoint & 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 QuadraturePoint & 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
new file mode 100644
index 000000000..cae69819a
--- /dev/null
+++ b/src/model/boundary_condition_python_functor.cc
@@ -0,0 +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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100644
index 000000000..ff93856d5
--- /dev/null
+++ b/src/model/boundary_condition_python_functor.hh
@@ -0,0 +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, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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 f339ec171..bce9e98c2 100644
--- a/src/model/boundary_condition_tmpl.hh
+++ b/src/model/boundary_condition_tmpl.hh
@@ -1,263 +1,263 @@
/**
* @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();
- QuadraturePoint quad_point;
+ 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.getNbQuadraturePoints(*type_it, ghost_type);
+ 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.getNormalsOnQuadPoints(*type_it, ghost_type);
+ fem_boundary.getNormalsOnIntegrationPoints(*type_it, ghost_type);
- fem_boundary.interpolateOnQuadraturePoints(nodes_coords, *quad_coords,
+ 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
model.getDOFManager().assembleElementalArrayLocalArray(*dual_by_shapes_integ,
dual,
*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
new file mode 100644
index 000000000..81f852d64
--- /dev/null
+++ b/src/model/common/neighborhood_base.cc
@@ -0,0 +1,296 @@
+/**
+ * @file neighborhood_base.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
+ *
+ * @brief Implementation of generic neighborhood base
+ *
+ * @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 "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
new file mode 100644
index 000000000..91c308632
--- /dev/null
+++ b/src/model/common/neighborhood_base.hh
@@ -0,0 +1,152 @@
+/**
+ * @file neighborhood_base.hh
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
+ *
+ * @brief Generic neighborhood of quadrature points
+ *
+ * @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_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
new file mode 100644
index 000000000..5509f163e
--- /dev/null
+++ b/src/model/common/neighborhood_base_inline_impl.cc
@@ -0,0 +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 creation: Thu Feb 21 2013
+ * @date last modification: Wed Nov 25 2015
+ *
+ * @brief Inline implementation of neighborhood base functions
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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
new file mode 100644
index 000000000..55c7a296c
--- /dev/null
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
@@ -0,0 +1,314 @@
+/**
+ * @file neighborhood_max_criterion.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Thu Oct 15 2015
+ * @date last modification: Tue Nov 24 2015
+ *
+ * @brief Implementation of class NeighborhoodMaxCriterion
+ *
+ * @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 "neighborhood_max_criterion.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+NeighborhoodMaxCriterion::NeighborhoodMaxCriterion(const SolidMechanicsModel & model,
+ const ElementTypeMapReal & quad_coordinates,
+ const ID & criterion_id,
+ const ID & id,
+ const MemoryID & memory_id) :
+ NeighborhoodBase(model, quad_coordinates, id, memory_id),
+ Parsable(_st_non_local, id),
+ is_highest("is_highest", id),
+ criterion(criterion_id, id)
+ {
+
+ AKANTU_DEBUG_IN();
+
+ this->registerParam("radius" , neighborhood_radius , 100.,
+ _pat_parsable | _pat_readable , "Non local radius");
+
+ Mesh & mesh = this->model.getMesh();
+ /// allocate the element type map arrays for _not_ghosts: One entry per quad
+ GhostType ghost_type = _not_ghost;
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
+ Mesh::type_iterator last_type = mesh.lastType (spatial_dimension, ghost_type);
+
+ for(; it != last_type; ++it) {
+ UInt new_size = this->quad_coordinates(*it, ghost_type).getSize();
+ this->is_highest.alloc(new_size, 1, *it, ghost_type, true);
+ this->criterion.alloc(new_size, 1, *it, ghost_type, true);
+ }
+
+ /// criterion needs allocation also for ghost
+ ghost_type = _ghost;
+ it = mesh.firstType(spatial_dimension, ghost_type);
+ last_type = mesh.lastType(spatial_dimension, ghost_type);
+ for(; it != last_type; ++it) {
+ UInt new_size = this->quad_coordinates(*it, ghost_type).getSize();
+ this->criterion.alloc(new_size, 1, *it, ghost_type, true);
+ }
+
+ AKANTU_DEBUG_OUT();
+
+}
+
+/* -------------------------------------------------------------------------- */
+NeighborhoodMaxCriterion::~NeighborhoodMaxCriterion() {
+ AKANTU_DEBUG_IN();
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NeighborhoodMaxCriterion::initNeighborhood() {
+ AKANTU_DEBUG_IN();
+
+ /// parse the input parameter
+ const Parser & parser = getStaticParser();
+ const ParserSection & section_neighborhood = *(parser.getSubSections(_st_neighborhood).first);
+ this->parseSection(section_neighborhood);
+
+ AKANTU_DEBUG_INFO("Creating the grid");
+ this->createGrid();
+
+ /// insert the non-ghost quads into the grid
+ this->insertAllQuads(_not_ghost);
+
+ /// store the number of current ghost elements for each type in the mesh
+ ElementTypeMap<UInt> nb_ghost_protected;
+ Mesh & mesh = this->model.getMesh();
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
+ Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
+ for(; it != last_type; ++it)
+ nb_ghost_protected(mesh.getNbElement(*it, _ghost), *it, _ghost);
+
+ /// create the grid synchronizer
+ this->createGridSynchronizer();
+
+ /// insert the ghost quads into the grid
+ this->insertAllQuads(_ghost);
+
+ /// create the pair lists
+ this->updatePairList();
+
+ /// remove the unneccessary ghosts
+ this->cleanupExtraGhostElements(nb_ghost_protected);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NeighborhoodMaxCriterion::createGridSynchronizer() {
+ this->is_creating_grid = true;
+ std::set<SynchronizationTag> tags;
+ tags.insert(_gst_nh_criterion);
+
+ std::stringstream sstr; sstr << getID() << ":grid_synchronizer";
+ this->grid_synchronizer = GridSynchronizer::createGridSynchronizer(this->model.getMesh(),
+ *spatial_grid,
+ sstr.str(),
+ synch_registry,
+ tags, 0, false);
+ this->is_creating_grid = false;
+}
+
+/* -------------------------------------------------------------------------- */
+void NeighborhoodMaxCriterion::insertAllQuads(const GhostType & ghost_type) {
+ IntegrationPoint q;
+ q.ghost_type = ghost_type;
+ Mesh & mesh = this->model.getMesh();
+
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
+ Mesh::type_iterator last_type = mesh.lastType (spatial_dimension, ghost_type);
+ for(; it != last_type; ++it) {
+ UInt nb_element = mesh.getNbElement(*it, ghost_type);
+ UInt nb_quad = this->model.getFEEngine().getNbIntegrationPoints(*it, ghost_type);
+
+ const Array<Real> & quads = this->quad_coordinates(*it, ghost_type);
+ q.type = *it;
+
+ Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
+
+ for (UInt e = 0; e < nb_element; ++e) {
+ q.element = e;
+ for (UInt nq = 0; nq < nb_quad; ++nq) {
+ q.num_point = nq;
+ q.global_num = q.element * nb_quad + nq;
+ spatial_grid->insert(q, *quad);
+ ++quad;
+ }
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NeighborhoodMaxCriterion::findMaxQuads(std::vector<IntegrationPoint> & max_quads) {
+ AKANTU_DEBUG_IN();
+
+ /// clear the element type maps
+ this->is_highest.clear();
+ this->criterion.clear();
+ /// update the values of the criterion
+ const ID field_name = criterion.getName();
+ for (UInt m = 0; m < this->model.getNbMaterials(); ++m) {
+ const Material & material = this->model.getMaterial(m);
+ if (material.isInternal<Real>(field_name, _ek_regular))
+ for(UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType ghost_type = (GhostType) g;
+ material.flattenInternal(field_name, criterion, ghost_type, _ek_regular);
+ }
+ }
+
+ /// start the exchange the value of the criterion on the ghost elements
+ SynchronizerRegistry & synch_registry = this->model.getSynchronizerRegistry();
+ synch_registry.asynchronousSynchronize(_gst_nh_criterion);
+
+ /// compare to not-ghost neighbors
+ checkNeighbors(_not_ghost);
+
+ /// finish the exchange
+ synch_registry.waitEndSynchronize(_gst_nh_criterion);
+
+ /// compare to ghost neighbors
+ checkNeighbors(_ghost);
+
+
+ /// extract the quads with highest criterion in their neighborhood
+ IntegrationPoint quad;
+ quad.ghost_type = _not_ghost;
+ Mesh & mesh = this->model.getMesh();
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost);
+ Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost);
+ for(; it != last_type; ++it) {
+ quad.type = *it;
+ Array<bool>::const_scalar_iterator is_highest_it = is_highest(*it, _not_ghost).begin();
+ Array<bool>::const_scalar_iterator is_highest_end = is_highest(*it, _not_ghost).end();
+
+ UInt nb_quadrature_points = this->model.getFEEngine().getNbIntegrationPoints(*it, _not_ghost);
+ UInt q = 0;
+
+ /// loop over is_highest for the current element type
+ for (;is_highest_it != is_highest_end; ++is_highest_it, ++q) {
+ if (*is_highest_it) {
+ /// gauss point has the highest stress in his neighbourhood
+ quad.element = q / nb_quadrature_points;
+ quad.global_num = q;
+ quad.num_point = q % nb_quadrature_points;
+ max_quads.push_back(quad);
+ }
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NeighborhoodMaxCriterion::checkNeighbors(const GhostType & ghost_type2) {
+ AKANTU_DEBUG_IN();
+
+ PairList::const_iterator first_pair = pair_list[ghost_type2].begin();
+ PairList::const_iterator last_pair = pair_list[ghost_type2].end();
+
+ // Compute the weights
+ for(;first_pair != last_pair; ++first_pair) {
+ const IntegrationPoint & lq1 = first_pair->first;
+ const IntegrationPoint & lq2 = first_pair->second;
+
+ Array<bool> & has_highest_eq_stress_1 = is_highest(lq1.type, lq1.ghost_type);
+
+ const Array<Real> & criterion_1 = this->criterion(lq1.type, lq1.ghost_type);
+ const Array<Real> & criterion_2 = this->criterion(lq2.type, lq2.ghost_type);
+
+ if(criterion_1(lq1.global_num) < criterion_2(lq2.global_num))
+ has_highest_eq_stress_1(lq1.global_num) = false;
+ else if (ghost_type2 != _ghost) {
+ Array<bool> & has_highest_eq_stress_2 = is_highest(lq2.type, lq2.ghost_type);
+ has_highest_eq_stress_2(lq2.global_num) = false;
+ }
+ }
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void NeighborhoodMaxCriterion::cleanupExtraGhostElements(const ElementTypeMap<UInt> & nb_ghost_protected) {
+
+ Mesh & mesh = this->model.getMesh();
+ /// create remove elements event
+ RemovedElementsEvent remove_elem(mesh);
+ /// create set of ghosts to keep
+ std::set<Element> relevant_ghost_elements;
+ PairList::const_iterator first_pair = pair_list[_ghost].begin();
+ PairList::const_iterator last_pair = pair_list[_ghost].end();
+ for(;first_pair != last_pair; ++first_pair) {
+ const IntegrationPoint & q2 = first_pair->second;
+ relevant_ghost_elements.insert(q2);
+ }
+
+ Array<Element> ghosts_to_erase(0);
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
+ Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
+
+ Element element;
+ element.ghost_type = _ghost;
+
+ std::set<Element>::const_iterator end = relevant_ghost_elements.end();
+ for(; it != last_type; ++it) {
+ element.type = *it;
+ UInt nb_ghost_elem = mesh.getNbElement(*it, _ghost);
+ UInt nb_ghost_elem_protected = 0;
+ try {
+ nb_ghost_elem_protected = nb_ghost_protected(*it, _ghost);
+ } catch (...) {}
+
+ if(!remove_elem.getNewNumbering().exists(*it, _ghost))
+ remove_elem.getNewNumbering().alloc(nb_ghost_elem, 1, *it, _ghost);
+ else remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem);
+ Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
+ for (UInt g = 0; g < nb_ghost_elem; ++g) {
+ element.element = g;
+ if (element.element >= nb_ghost_elem_protected && relevant_ghost_elements.find(element) == end) {
+ ghosts_to_erase.push_back(element);
+ new_numbering(element.element) = UInt(-1);
+ }
+ }
+ /// renumber remaining ghosts
+ UInt ng = 0;
+ for (UInt g = 0; g < nb_ghost_elem; ++g) {
+ if (new_numbering(g) != UInt(-1)) {
+ new_numbering(g) = ng;
+ ++ng;
+ }
+ }
+ }
+
+ mesh.sendEvent(remove_elem);
+ this->onElementsRemoved(ghosts_to_erase, remove_elem.getNewNumbering(), remove_elem);
+
+}
+
+
+__END_AKANTU__
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
new file mode 100644
index 000000000..a3fabc793
--- /dev/null
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
@@ -0,0 +1,124 @@
+/**
+ * @file neighborhood_max_criterion.hh
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..9b039428c
--- /dev/null
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
@@ -0,0 +1,80 @@
+/**
+ * @file neighborhood_max_criterion_inline_impl.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Thu Oct 15 2015
+ *
+ * @brief Implementation of inline functions for class NeighborhoodMaxCriterion
+ *
+ * @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_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
new file mode 100644
index 000000000..8690b24a8
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_manager.cc
@@ -0,0 +1,623 @@
+/**
+ * @file non_local_manager.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Wed Dec 16 2015
+ *
+ * @brief Implementation of non-local manager
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "non_local_manager.hh"
+#include "non_local_neighborhood.hh"
+#include "material_non_local.hh"
+#include "base_weight_function.hh"
+/* -------------------------------------------------------------------------- */
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+NonLocalManager::NonLocalManager(SolidMechanicsModel & model,
+ const ID & id,
+ const MemoryID & memory_id) :
+ Memory(id, memory_id),
+ Parsable(_st_neighborhoods, id),
+ model(model),
+ quad_positions("quad_positions", id),
+ volumes("volumes", id),
+ spatial_dimension(this->model.getSpatialDimension()),
+ compute_stress_calls(0),
+ dummy_registry(NULL),
+ dummy_grid(NULL) {
+ Mesh & mesh = this->model.getMesh();
+ mesh.registerEventHandler(*this);
+
+ /// initialize the element type map array
+ /// it will be resized to nb_quad * nb_element during the computation of coords
+ mesh.initElementTypeMapArray(quad_positions, spatial_dimension, spatial_dimension, false, _ek_regular, true);
+ this->initElementTypeMap(1, volumes, this->model.getFEEngine());
+
+ /// parse the neighborhood information from the input file
+ const Parser & parser = getStaticParser();
+
+ /// iterate over all the non-local sections and store them in a map
+ std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
+ weight_sect = parser.getSubSections(_st_non_local);
+ Parser::const_section_iterator it = weight_sect.first;
+ for (; it != weight_sect.second; ++it) {
+ const ParserSection & section = *it;
+ ID name = section.getName();
+ this->weight_function_types[name] = section;
+ }
+
+ this->dummy_registry = new SynchronizerRegistry(this->dummy_accessor);
+}
+
+/* -------------------------------------------------------------------------- */
+NonLocalManager::~NonLocalManager() {
+
+ /// delete neighborhoods
+ NeighborhoodMap::iterator it;
+ for (it = neighborhoods.begin(); it != neighborhoods.end(); ++it) {
+ if(it->second) delete it->second;
+ }
+
+ /// delete non-local variables
+ std::map<ID, NonLocalVariable *>::iterator it_variables;
+ for (it_variables = non_local_variables.begin(); it_variables != non_local_variables.end(); ++it_variables) {
+ if(it_variables->second) delete it_variables->second;
+ }
+
+ std::map<ID, ElementTypeMapReal *>::iterator it_internals;
+ for (it_internals = weight_function_internals.begin(); it_internals != weight_function_internals.end(); ++it_internals) {
+ if(it_internals->second) delete it_internals->second;
+ }
+
+ std::map<ID, GridSynchronizer * >::iterator grid_synch_it;
+ for (grid_synch_it = dummy_synchronizers.begin(); grid_synch_it != dummy_synchronizers.end(); ++grid_synch_it) {
+ if(grid_synch_it->second) delete grid_synch_it->second;
+ }
+ /// delete all objects related to the dummy synchronizers
+ delete dummy_registry;
+ delete dummy_grid;
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::setJacobians(const FEEngine & fe_engine, const ElementKind & kind) {
+ Mesh & mesh = this->model.getMesh();
+ for(UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType gt = (GhostType) g;
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, kind);
+ Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt, kind);
+ for(; it != last_type; ++it) {
+ jacobians(*it, gt) = &fe_engine.getIntegratorInterface().getJacobians(*it, gt);
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::createNeighborhood(const ID & weight_func, const ID & neighborhood_id) {
+
+ AKANTU_DEBUG_IN();
+
+
+ const ParserSection & section = this->weight_function_types[weight_func];
+ const ID weight_func_type = section.getOption();
+ /// create new neighborhood for given ID
+ std::stringstream sstr; sstr << id << ":neighborhood:" << neighborhood_id;
+
+ if (weight_func_type == "base_wf")
+ neighborhoods[neighborhood_id] = new NonLocalNeighborhood<BaseWeightFunction>(*this, this->quad_positions, sstr.str());
+ else if (weight_func_type == "remove_wf")
+ neighborhoods[neighborhood_id] = new NonLocalNeighborhood<RemoveDamagedWeightFunction>(*this, this->quad_positions, sstr.str());
+ else if (weight_func_type == "stress_wf")
+ neighborhoods[neighborhood_id] = new NonLocalNeighborhood<StressBasedWeightFunction>(*this, this->quad_positions, sstr.str());
+ else if (weight_func_type == "damage_wf")
+ neighborhoods[neighborhood_id] = new NonLocalNeighborhood<DamagedWeightFunction>(*this, this->quad_positions, sstr.str());
+ else
+ AKANTU_EXCEPTION("error in weight function type provided in material file");
+
+ neighborhoods[neighborhood_id]->parseSection(section);
+ neighborhoods[neighborhood_id]->initNeighborhood();
+
+ AKANTU_DEBUG_OUT();
+
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::createNeighborhoodSynchronizers() {
+ /// exchange all the neighborhood IDs, so that every proc knows how many neighborhoods exist globally
+ /// First: Compute locally the maximum ID size
+ UInt max_id_size = 0;
+ UInt current_size = 0;
+ NeighborhoodMap::const_iterator it;
+ for (it = neighborhoods.begin(); it != neighborhoods.end(); ++it) {
+ current_size = it->first.size();
+ if (current_size > max_id_size)
+ max_id_size = current_size;
+ }
+
+ /// get the global maximum ID size on each proc
+ StaticCommunicator & static_communicator = akantu::StaticCommunicator::getStaticCommunicator();
+ static_communicator.allReduce(&max_id_size, 1, _so_max);
+
+ /// get the rank for this proc and the total nb proc
+ UInt prank = static_communicator.whoAmI();
+ UInt psize = static_communicator.getNbProc();
+
+ /// exchange the number of neighborhoods on each proc
+ Array<Int> nb_neighborhoods_per_proc(psize);
+ nb_neighborhoods_per_proc(prank) = neighborhoods.size();
+ static_communicator.allGather(nb_neighborhoods_per_proc.storage(), 1);
+
+ /// compute the total number of neighborhoods
+ UInt nb_neighborhoods_global = std::accumulate(nb_neighborhoods_per_proc.begin(),
+ nb_neighborhoods_per_proc.end(), 0);
+
+ /// allocate an array of chars to store the names of all neighborhoods
+ Array<char> buffer(nb_neighborhoods_global, max_id_size);
+
+ /// starting index on this proc
+ UInt starting_index = std::accumulate(nb_neighborhoods_per_proc.begin(),
+ nb_neighborhoods_per_proc.begin() + prank, 0);
+
+
+ it = neighborhoods.begin();
+ /// store the names of local neighborhoods in the buffer
+ for (UInt i = 0; i < neighborhoods.size(); ++i, ++it) {
+ UInt c = 0;
+ for (; c < it->first.size(); ++c)
+ buffer(i + starting_index, c) = it->first[c];
+
+ for (; c < max_id_size; ++c)
+ buffer(i + starting_index, c) = char( 0 );
+ }
+
+ /// store the nb of data to send in the all gather
+ Array<Int> buffer_size(nb_neighborhoods_per_proc);
+ buffer_size *= max_id_size;
+ /// exchange the names of all the neighborhoods with all procs
+ static_communicator.allGatherV(buffer.storage(), buffer_size.storage());
+
+
+
+ for (UInt i = 0; i < nb_neighborhoods_global; ++i) {
+ std::stringstream neighborhood_id;
+ for(UInt c = 0; c < max_id_size; ++c) {
+ if (buffer(i,c) == char( 0 )) break;
+ neighborhood_id << buffer(i,c);
+ }
+ global_neighborhoods.insert(neighborhood_id.str());
+ }
+
+
+
+ /// this proc does not know all the neighborhoods -> create dummy
+ /// grid so that this proc can participate in the all gather for
+ /// detecting the overlap of neighborhoods this proc doesn't know
+ Vector<Real> grid_center(this->spatial_dimension);
+ for(UInt s = 0; s < this->spatial_dimension; ++s)
+ grid_center(s) = std::numeric_limits<Real>::max();
+ dummy_grid = new SpatialGrid<IntegrationPoint>(spatial_dimension, 0., grid_center);
+ std::set<SynchronizationTag> tags;
+ tags.insert(_gst_mnl_for_average);
+ tags.insert(_gst_mnl_weight);
+
+
+ std::set<ID>::const_iterator global_neighborhoods_it = global_neighborhoods.begin();
+ for (; global_neighborhoods_it != global_neighborhoods.end(); ++global_neighborhoods_it) {
+ it = neighborhoods.find(*global_neighborhoods_it);
+ if (it != neighborhoods.end()) {
+ it->second->createGridSynchronizer();
+ }
+ else {
+ ID neighborhood_name = *global_neighborhoods_it;
+ std::stringstream sstr; sstr << getID() << ":" << neighborhood_name << ":grid_synchronizer";
+ dummy_synchronizers[neighborhood_name] = GridSynchronizer::createGridSynchronizer(this->model.getMesh(),
+ *dummy_grid,
+ sstr.str(),
+ dummy_registry,
+ tags, 0, false);
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::flattenInternal(ElementTypeMapReal & internal_flat,
+ const GhostType & ghost_type,
+ const ElementKind & kind) {
+
+ const ID field_name = internal_flat.getName();
+ for (UInt m = 0; m < this->non_local_materials.size(); ++m) {
+ Material & material = *(this->non_local_materials[m]);
+ if (material.isInternal<Real>(field_name, kind))
+ material.flattenInternal(field_name, internal_flat, ghost_type, kind);
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::averageInternals(const GhostType & ghost_type) {
+ /// update the weights of the weight function
+ if (ghost_type == _not_ghost)
+ this->computeWeights();
+
+ /// loop over all neighborhoods and compute the non-local variables
+ NeighborhoodMap::iterator neighborhood_it = neighborhoods.begin();
+ NeighborhoodMap::iterator neighborhood_end = neighborhoods.end();
+ for (; neighborhood_it != neighborhood_end; ++neighborhood_it) {
+ /// loop over all the non-local variables of the given neighborhood
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.begin();
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_end = non_local_variables.end();
+ for(; non_local_variable_it != non_local_variable_end; ++non_local_variable_it) {
+ NonLocalVariable * non_local_var = non_local_variable_it->second;
+ neighborhood_it->second->weightedAverageOnNeighbours(non_local_var->local, non_local_var->non_local, non_local_var->nb_component, ghost_type);
+
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::init(){
+
+ /// store the number of current ghost elements for each type in the mesh
+ ElementTypeMap<UInt> nb_ghost_protected;
+ Mesh & mesh = this->model.getMesh();
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
+ Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
+ for(; it != last_type; ++it)
+ nb_ghost_protected(mesh.getNbElement(*it, _ghost), *it, _ghost);
+
+ /// exchange the missing ghosts for the non-local neighborhoods
+ this->createNeighborhoodSynchronizers();
+
+ /// insert the ghost quadrature points of the non-local materials into the non-local neighborhoods
+ for(UInt m = 0; m < this->non_local_materials.size(); ++m) {
+ switch (spatial_dimension) {
+ case 1:
+ dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m])).insertQuadsInNeighborhoods(_ghost);
+ break;
+ case 2:
+ dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m])).insertQuadsInNeighborhoods(_ghost);
+ break;
+ case 3:
+ dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m])).insertQuadsInNeighborhoods(_ghost);
+ break;
+ }
+
+ }
+
+ FEEngine & fee = this->model.getFEEngine();
+ this->updatePairLists();
+ /// cleanup the unneccessary ghost elements
+ this->cleanupExtraGhostElements(nb_ghost_protected);
+ this->setJacobians(fee, _ek_regular);
+ this->initNonLocalVariables();
+ this->computeWeights();
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::initNonLocalVariables(){
+ /// loop over all the non-local variables
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.begin();
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_end = non_local_variables.end();
+
+ for(; non_local_variable_it != non_local_variable_end; ++non_local_variable_it) {
+ NonLocalVariable & variable = *(non_local_variable_it->second);
+ this->initElementTypeMap(variable.nb_component, variable.non_local, this->model.getFEEngine());
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::initElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
+ const FEEngine & fee, const ElementKind el_kind) {
+ Mesh & mesh = this->model.getMesh();
+ /// need to resize the arrays
+ for(UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType gt = (GhostType) g;
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, el_kind);
+ Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt, el_kind);
+ for(; it != end; ++it) {
+ ElementType el_type = *it;
+ UInt nb_element = mesh.getNbElement(*it, gt);
+ UInt nb_quads = fee.getNbIntegrationPoints(*it, gt);
+ if (!element_map.exists(el_type, gt)) {
+ element_map.alloc(nb_element * nb_quads,
+ nb_component,
+ el_type,
+ gt);
+ }
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::distributeInternals(ElementKind kind) {
+
+ /// loop over all the non-local variables and copy back their values into the materials
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.begin();
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_end = non_local_variables.end();
+ for(; non_local_variable_it != non_local_variable_end; ++non_local_variable_it) {
+ NonLocalVariable * non_local_var = non_local_variable_it->second;
+ const ID field_name = non_local_var->non_local.getName();
+ /// loop over all the materials
+ for (UInt m = 0; m < this->non_local_materials.size(); ++m) {
+ if (this->non_local_materials[m]->isInternal<Real>(field_name, kind))
+
+ switch (spatial_dimension) {
+ case 1:
+ dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m])).updateNonLocalInternals(non_local_var->non_local, field_name, non_local_var->nb_component);
+ break;
+ case 2:
+ dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m])).updateNonLocalInternals(non_local_var->non_local, field_name, non_local_var->nb_component);
+ break;
+ case 3:
+ dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m])).updateNonLocalInternals(non_local_var->non_local, field_name, non_local_var->nb_component);
+ break;
+ }
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::computeAllNonLocalStresses() {
+
+ /// update the flattened version of the internals
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.begin();
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_end = non_local_variables.end();
+
+ for(; non_local_variable_it != non_local_variable_end; ++non_local_variable_it) {
+ non_local_variable_it->second->local.clear();
+ non_local_variable_it->second->non_local.clear();
+ for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
+ GhostType ghost_type = (GhostType) gt;
+ this->flattenInternal(non_local_variable_it->second->local, ghost_type, _ek_regular);
+ }
+ }
+
+ this->volumes.clear();
+ ///loop over all the neighborhoods and compute intiate the
+ /// exchange of the non-local_variables
+ // std::set<ID>::const_iterator global_neighborhood_it = global_neighborhoods.begin();
+ // NeighborhoodMap::iterator it;
+ // for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
+ // it = neighborhoods.find(*global_neighborhood_it);
+ // if (it != neighborhoods.end())
+ // it->second->getSynchronizerRegistry().asynchronousSynchronize(_gst_mnl_for_average);
+ // else
+ // dummy_synchronizers[*global_neighborhood_it]->asynchronousSynchronize(dummy_accessor, _gst_mnl_for_average);
+ // }
+
+ NeighborhoodMap::iterator neighborhood_it = neighborhoods.begin();
+ //NeighborhoodMap::iterator neighborhood_end = neighborhoods.end();
+
+ for(; neighborhood_it != neighborhoods.end(); ++neighborhood_it) {
+ neighborhood_it->second->getSynchronizerRegistry().asynchronousSynchronize(_gst_mnl_for_average);
+ }
+
+ this->averageInternals(_not_ghost);
+
+ AKANTU_DEBUG_INFO("Wait distant non local stresses");
+
+ /// loop over all the neighborhoods and block until all non-local
+ /// variables have been exchanged
+ // global_neighborhood_it = global_neighborhoods.begin();
+ // for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
+ // it = neighborhoods.find(*global_neighborhood_it);
+ // if (it != neighborhoods.end())
+ // it->second->getSynchronizerRegistry().waitEndSynchronize(_gst_mnl_for_average);
+ // else
+ // dummy_synchronizers[*global_neighborhood_it]->waitEndSynchronize(dummy_accessor, _gst_mnl_for_average);
+ // }
+
+ neighborhood_it = neighborhoods.begin();
+ for(; neighborhood_it != neighborhoods.end(); ++neighborhood_it) {
+ neighborhood_it->second->getSynchronizerRegistry().waitEndSynchronize(_gst_mnl_for_average);
+ }
+
+
+ this->averageInternals(_ghost);
+
+ /// copy the results in the materials
+ this->distributeInternals(_ek_regular);
+ /// loop over all the materials and update the weights
+ for (UInt m = 0; m < this->non_local_materials.size(); ++m) {
+ switch (spatial_dimension) {
+ case 1:
+ dynamic_cast<MaterialNonLocal<1> &>(*(this->non_local_materials[m])).computeNonLocalStresses(_not_ghost); break;
+ case 2:
+ dynamic_cast<MaterialNonLocal<2> &>(*(this->non_local_materials[m])).computeNonLocalStresses(_not_ghost); break;
+ case 3:
+ dynamic_cast<MaterialNonLocal<3> &>(*(this->non_local_materials[m])).computeNonLocalStresses(_not_ghost); break;
+ }
+ }
+
+ ++this->compute_stress_calls;
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::cleanupExtraGhostElements(ElementTypeMap<UInt> & nb_ghost_protected) {
+
+ typedef std::set<Element> ElementSet;
+ ElementSet relevant_ghost_elements;
+ ElementSet to_keep_per_neighborhood;
+ /// loop over all the neighborhoods and get their protected ghosts
+ NeighborhoodMap::iterator neighborhood_it = neighborhoods.begin();
+ NeighborhoodMap::iterator neighborhood_end = neighborhoods.end();
+ for (; neighborhood_it != neighborhood_end; ++neighborhood_it) {
+ neighborhood_it->second->cleanupExtraGhostElements(to_keep_per_neighborhood);
+ ElementSet::const_iterator it = to_keep_per_neighborhood.begin();
+ for(; it != to_keep_per_neighborhood.end(); ++it)
+ relevant_ghost_elements.insert(*it);
+ to_keep_per_neighborhood.clear();
+ }
+
+ /// remove all unneccessary ghosts from the mesh
+ /// Create list of element to remove and new numbering for element to keep
+ Mesh & mesh = this->model.getMesh();
+ ElementSet ghost_to_erase;
+
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
+ Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
+
+ RemovedElementsEvent remove_elem(mesh);
+ Element element;
+ element.ghost_type = _ghost;
+
+ for(; it != last_type; ++it) {
+ element.type = *it;
+ UInt nb_ghost_elem = mesh.getNbElement(*it, _ghost);
+ UInt nb_ghost_elem_protected = 0;
+ try {
+ nb_ghost_elem_protected = nb_ghost_protected(*it, _ghost);
+ } catch (...) {}
+
+ if(!remove_elem.getNewNumbering().exists(*it, _ghost))
+ remove_elem.getNewNumbering().alloc(nb_ghost_elem, 1, *it, _ghost);
+ else remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem);
+ Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
+ for (UInt g = 0; g < nb_ghost_elem; ++g) {
+ element.element = g;
+ if (element.element >= nb_ghost_elem_protected &&
+ relevant_ghost_elements.find(element) == relevant_ghost_elements.end()) {
+ remove_elem.getList().push_back(element);
+ new_numbering(element.element) = UInt(-1);
+ }
+ }
+ /// renumber remaining ghosts
+ UInt ng = 0;
+ for (UInt g = 0; g < nb_ghost_elem; ++g) {
+ if (new_numbering(g) != UInt(-1)) {
+ new_numbering(g) = ng;
+ ++ng;
+ }
+ }
+ }
+
+
+ it = mesh.firstType(spatial_dimension, _not_ghost);
+ last_type = mesh.lastType(spatial_dimension, _not_ghost);
+ for(; it != last_type; ++it) {
+ UInt nb_elem = mesh.getNbElement(*it, _not_ghost);
+ if(!remove_elem.getNewNumbering().exists(*it, _not_ghost))
+ remove_elem.getNewNumbering().alloc(nb_elem, 1, *it, _not_ghost);
+ Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _not_ghost);
+ for (UInt e = 0; e < nb_elem; ++e) {
+ new_numbering(e) = e;
+ }
+ }
+ mesh.sendEvent(remove_elem);
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::onElementsRemoved(const Array<Element> & element_list,
+ const ElementTypeMapArray<UInt> & new_numbering,
+ __attribute__((unused)) const RemovedElementsEvent & event) {
+
+ FEEngine & fee = this->model.getFEEngine();
+ this->removeIntegrationPointsFromMap(event.getNewNumbering(), spatial_dimension, quad_positions, fee, _ek_regular);
+ this->removeIntegrationPointsFromMap(event.getNewNumbering(), 1, volumes, fee, _ek_regular);
+
+ /// loop over all the neighborhoods and call onElementsRemoved
+ std::set<ID>::const_iterator global_neighborhood_it = global_neighborhoods.begin();
+ NeighborhoodMap::iterator it;
+ for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
+ it = neighborhoods.find(*global_neighborhood_it);
+ if (it != neighborhoods.end())
+ it->second->onElementsRemoved(element_list, new_numbering, event);
+ else
+ dummy_synchronizers[*global_neighborhood_it]->onElementsRemoved(element_list, new_numbering, event);
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::onElementsAdded(__attribute__((unused)) const Array<Element> & element_list,
+ __attribute__((unused)) const NewElementsEvent & event) {
+ this->resizeElementTypeMap(1, volumes, model.getFEEngine());
+ this->resizeElementTypeMap(spatial_dimension, quad_positions, model.getFEEngine());
+
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::resizeElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
+ const FEEngine & fee, const ElementKind el_kind) {
+ Mesh & mesh = this->model.getMesh();
+ for(UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType gt = (GhostType) g;
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, el_kind);
+ Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt, el_kind);
+ for(; it != end; ++it) {
+ UInt nb_element = mesh.getNbElement(*it, gt);
+ UInt nb_quads = fee.getNbIntegrationPoints(*it, gt);
+ if(!element_map.exists(*it, gt))
+ element_map.alloc(nb_element * nb_quads, nb_component, *it, gt);
+ else
+ element_map(*it, gt).resize(nb_element * nb_quads);
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void NonLocalManager::removeIntegrationPointsFromMap(const ElementTypeMapArray<UInt> & new_numbering,
+ UInt nb_component, ElementTypeMapReal & element_map,
+ const FEEngine & fee, const ElementKind el_kind) {
+
+ for(UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType gt = (GhostType) g;
+ ElementTypeMapArray<UInt>::type_iterator it = new_numbering.firstType(_all_dimensions, gt, el_kind);
+ ElementTypeMapArray<UInt>::type_iterator end = new_numbering.lastType(_all_dimensions, gt, el_kind);
+ for (; it != end; ++it) {
+ ElementType type = *it;
+ if(element_map.exists(type, gt)){
+ const Array<UInt> & renumbering = new_numbering(type, gt);
+
+ Array<Real> & vect = element_map(type, gt);
+
+ UInt nb_quad_per_elem = fee.getNbIntegrationPoints(type, gt);
+
+ Array<Real> tmp(renumbering.getSize()*nb_quad_per_elem, nb_component);
+
+ AKANTU_DEBUG_ASSERT(tmp.getSize() == vect.getSize(), "Something strange append some mater was created from nowhere!!");
+
+ AKANTU_DEBUG_ASSERT(tmp.getSize() == vect.getSize(), "Something strange append some mater was created or disappeared in "<< vect.getID() << "("<< vect.getSize() <<"!=" << tmp.getSize() <<") ""!!");
+
+ UInt new_size = 0;
+ for (UInt i = 0; i < renumbering.getSize(); ++i) {
+ UInt new_i = renumbering(i);
+ if(new_i != UInt(-1)) {
+ memcpy(tmp.storage() + new_i * nb_component * nb_quad_per_elem,
+ vect.storage() + i * nb_component * nb_quad_per_elem,
+ nb_component * nb_quad_per_elem * sizeof(Real));
+ ++new_size;
+ }
+ }
+ tmp.resize(new_size * nb_quad_per_elem);
+ vect.copy(tmp);
+ }
+ }
+ }
+}
+
+
+__END_AKANTU__
diff --git a/src/model/common/non_local_toolbox/non_local_manager.hh b/src/model/common/non_local_toolbox/non_local_manager.hh
new file mode 100644
index 000000000..0761cdd44
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_manager.hh
@@ -0,0 +1,288 @@
+/**
+ * @file non_local_manager.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: Tue Dec 08 2015
+ *
+ * @brief Classes that manages all the non-local neighborhoods
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#ifndef __AKANTU_NON_LOCAL_MANAGER_HH__
+#define __AKANTU_NON_LOCAL_MANAGER_HH__
+/* -------------------------------------------------------------------------- */
+#include "aka_memory.hh"
+#include "solid_mechanics_model.hh"
+#include "non_local_neighborhood_base.hh"
+#include "mesh_events.hh"
+#include "parsable.hh"
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+class NonLocalManager : public Memory,
+ public Parsable,
+ public MeshEventHandler {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+ NonLocalManager(SolidMechanicsModel & model,
+ const ID & id = "non_local_manager",
+ const MemoryID & memory_id = 0);
+ virtual ~NonLocalManager();
+ typedef std::map<ID, NonLocalNeighborhoodBase *> NeighborhoodMap;
+ typedef std::pair<ID, ID> KeyCOO;
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ----------------------------------------------------------------------- */
+public:
+ /// initialize the non-local manager: compute pair lists and weights for all
+ /// neighborhoods
+ virtual void init();
+
+ /// insert new quadrature point in the grid
+ inline void insertQuad(const IntegrationPoint & quad,
+ const Vector<Real> & coords, const ID & neighborhood);
+
+ /// register non-local neighborhood
+ inline void registerNeighborhood(const ID & neighborhood,
+ const ID & weight_func_id);
+
+ /// associate a non-local variable to a neighborhood
+ void nonLocalVariableToNeighborhood(const ID & id, const ID & neighborhood);
+
+ /// return the fem object associated with a provided name
+ inline NonLocalNeighborhoodBase & getNeighborhood(const ID & name) const;
+
+ /// create the grid synchronizers for each neighborhood
+ void createNeighborhoodSynchronizers();
+
+ /// compute the weights in each neighborhood for non-local averaging
+ inline void computeWeights();
+
+ /// compute the weights in each neighborhood for non-local averaging
+ inline void updatePairLists();
+
+ /// register a new non-local material
+ inline void registerNonLocalMaterial(Material & new_mat);
+
+ /// register a non-local variable
+ inline void registerNonLocalVariable(const ID & variable_name,
+ const ID & nl_variable_name,
+ UInt nb_component);
+
+ /// average the non-local variables
+ void averageInternals(const GhostType & ghost_type = _not_ghost);
+
+ /// average the internals and compute the non-local stresses
+ virtual void computeAllNonLocalStresses();
+
+ /// register a new internal needed for the weight computations
+ inline ElementTypeMapReal &
+ registerWeightFunctionInternal(const ID & field_name);
+
+ /// update the flattened version of the weight function internals
+ inline void updateWeightFunctionInternals();
+
+ /// get Nb data for synchronization in parallel
+ inline UInt getNbDataForElements(const Array<Element> & elements,
+ const ID & id) const;
+
+ /// pack data for synchronization in parallel
+ inline void packElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag, const ID & id) const;
+
+ /// unpack data for synchronization in parallel
+ inline void unpackElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag, const ID & id) const;
+
+protected:
+ /// create a new neighborhood for a given domain ID
+ void createNeighborhood(const ID & weight_func, const ID & neighborhood);
+
+ /// flatten the material internal fields needed for the non-local computations
+ void flattenInternal(ElementTypeMapReal & internal_flat,
+ const GhostType & ghost_type, const ElementKind & kind);
+
+ /// set the values of the jacobians
+ void setJacobians(const FEEngine & fe_engine, const ElementKind & kind);
+
+ /// allocation of eelment type maps
+ void initElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
+ const FEEngine & fe_engine,
+ const ElementKind el_kind = _ek_regular);
+
+ /// resizing of element type maps
+ void resizeElementTypeMap(UInt nb_component, ElementTypeMapReal & element_map,
+ const FEEngine & fee,
+ const ElementKind el_kind = _ek_regular);
+
+ /// remove integration points from element type maps
+ void removeIntegrationPointsFromMap(
+ const ElementTypeMapArray<UInt> & new_numbering, UInt nb_component,
+ ElementTypeMapReal & element_map, const FEEngine & fee,
+ const ElementKind el_kind = _ek_regular);
+
+ /// allocate the non-local variables
+ void initNonLocalVariables();
+
+ /// copy the results of the averaging in the materials
+ void distributeInternals(ElementKind kind);
+
+ /// cleanup unneccessary ghosts
+ void cleanupExtraGhostElements(ElementTypeMap<UInt> & nb_ghost_protected);
+
+ /* ------------------------------------------------------------------------ */
+ /* MeshEventHandler inherited members */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void onElementsRemoved(const Array<Element> & element_list,
+ const ElementTypeMapArray<UInt> & new_numbering,
+ const RemovedElementsEvent & event);
+
+ virtual void onElementsAdded(const Array<Element> & element_list,
+ const NewElementsEvent & event);
+
+ virtual void onElementsChanged(__attribute__((unused)) const Array<Element> & old_elements_list,
+ __attribute__((unused)) const Array<Element> & new_elements_list,
+ __attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
+ __attribute__((unused)) const ChangedElementsEvent & event) {};
+
+ virtual void onNodesAdded(__attribute__((unused)) const Array<UInt> & nodes_list,
+ __attribute__((unused)) const NewNodesEvent & event) {};
+ virtual void onNodesRemoved(__attribute__((unused)) const Array<UInt> & nodes_list,
+ __attribute__((unused)) const Array<UInt> & new_numbering,
+ __attribute__((unused)) const RemovedNodesEvent & event) {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+ AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
+ AKANTU_GET_MACRO(Model, model, const SolidMechanicsModel &);
+ AKANTU_GET_MACRO_NOT_CONST(Volumes, volumes, ElementTypeMapReal &)
+ AKANTU_GET_MACRO(NbStressCalls, compute_stress_calls, UInt);
+
+ inline const Array<Real> & getJacobians(const ElementType & type,
+ const GhostType & ghost_type) {
+ return *jacobians(type, ghost_type);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ /// the non-local neighborhoods present
+ NeighborhoodMap neighborhoods;
+
+ /// list of all the non-local materials in the model
+ std::vector<Material *> non_local_materials;
+
+ struct NonLocalVariable {
+ NonLocalVariable(const ID & variable_name, const ID & nl_variable_name,
+ const ID & id, UInt nb_component)
+ : local(variable_name, id), non_local(nl_variable_name, id),
+ nb_component(nb_component) {}
+ ElementTypeMapReal local;
+ ElementTypeMapReal non_local;
+ UInt nb_component;
+ };
+
+ /// the non-local variables associated to a certain neighborhood
+ std::map<ID, NonLocalVariable *> non_local_variables;
+
+ /// reference to the model
+ SolidMechanicsModel & model;
+
+ /// jacobians for all the elements in the mesh
+ ElementTypeMap<const Array<Real> *> jacobians;
+
+ /// store the position of the quadrature points
+ ElementTypeMapReal quad_positions;
+
+ /// store the volume of each quadrature point for the non-local weight
+ /// normalization
+ ElementTypeMapReal volumes;
+
+ /// the spatial dimension
+ const UInt spatial_dimension;
+
+ /// counter for computeStress calls
+ UInt compute_stress_calls;
+
+ /// map to store weight function types from input file
+ std::map<ID, ParserSection> weight_function_types;
+
+ /// map to store the internals needed by the weight functions
+ std::map<ID, ElementTypeMapReal *> weight_function_internals;
+ /* --------------------------------------------------------------------------
+ */
+ /// the following are members needed to make this processor participate in the
+ /// grid creation of neighborhoods he doesn't own as a member. For details see
+ /// createGridSynchronizers function
+
+ /// synchronizer registry for dummy grid synchronizers
+ SynchronizerRegistry * dummy_registry;
+
+ /// map of dummy synchronizers
+ std::map<ID, GridSynchronizer *> dummy_synchronizers;
+
+ /// dummy spatial grid
+ SpatialGrid<IntegrationPoint> * dummy_grid;
+
+ /// create a set of all neighborhoods present in the simulation
+ std::set<ID> global_neighborhoods;
+
+ class DummyDataAccessor : public DataAccessor {
+ public:
+ virtual inline UInt getNbDataForElements(__attribute__((unused)) const Array<Element> & elements,
+ __attribute__((unused)) SynchronizationTag tag) const { return 0; };
+
+ virtual inline void packElementData(__attribute__((unused)) CommunicationBuffer & buffer,
+ __attribute__((unused)) const Array<Element> & element,
+ __attribute__((unused)) SynchronizationTag tag) const {};
+
+ virtual inline void unpackElementData(__attribute__((unused)) CommunicationBuffer & buffer,
+ __attribute__((unused)) const Array<Element> & element,
+ __attribute__((unused)) SynchronizationTag tag) {};
+ };
+
+ DummyDataAccessor dummy_accessor;
+};
+
+__END_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+#include "non_local_manager_inline_impl.cc"
+
+#endif /* __AKANTU_NON_LOCAL_MANAGER_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc b/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc
new file mode 100644
index 000000000..10fe2a3e6
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc
@@ -0,0 +1,249 @@
+/**
+ * @file non_local_manager_inline_impl.cc
+ *
+ * @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: Wed Nov 25 2015
+ *
+ * @brief inline implementation of non-local manager functions
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "grid_synchronizer.hh"
+#include "synchronizer_registry.hh"
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__
+#define __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::insertQuad(const IntegrationPoint & quad,
+ const Vector<Real> & coords,
+ const ID & neighborhood) {
+
+ AKANTU_DEBUG_ASSERT(neighborhoods[neighborhood] != NULL,
+ "The neighborhood " << neighborhood
+ << "has not been created");
+
+ neighborhoods[neighborhood]->insertQuad(quad, coords);
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::registerNeighborhood(const ID & neighborhood,
+ const ID & weight_func_id) {
+
+ /// check if neighborhood has already been created
+ NeighborhoodMap::const_iterator it = neighborhoods.find(neighborhood);
+ if (it == neighborhoods.end()) {
+ this->createNeighborhood(weight_func_id, neighborhood);
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+inline NonLocalNeighborhoodBase &
+NonLocalManager::getNeighborhood(const ID & name) const {
+ AKANTU_DEBUG_IN();
+
+ NeighborhoodMap::const_iterator it = neighborhoods.find(name);
+
+ AKANTU_DEBUG_ASSERT(it != neighborhoods.end(),
+ "The neighborhood " << name << " is not registered");
+
+ AKANTU_DEBUG_OUT();
+ return *(it->second);
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::computeWeights() {
+ AKANTU_DEBUG_IN();
+
+ this->updateWeightFunctionInternals();
+ this->volumes.clear();
+
+ // NeighborhoodMap::iterator it = neighborhoods.begin();
+ // NeighborhoodMap::iterator end = neighborhoods.end();
+
+ // for (; it != end; ++it)
+ // it->second->updateWeights();
+
+ /// loop over all the neighborhoods and call onElementsRemoved
+ std::set<ID>::const_iterator global_neighborhood_it =
+ global_neighborhoods.begin();
+ NeighborhoodMap::iterator it;
+ for (; global_neighborhood_it != global_neighborhoods.end();
+ ++global_neighborhood_it) {
+ it = neighborhoods.find(*global_neighborhood_it);
+ if (it != neighborhoods.end())
+ it->second->updateWeights();
+ else {
+ dummy_synchronizers[*global_neighborhood_it]->asynchronousSynchronize(
+ dummy_accessor, _gst_mnl_weight);
+ dummy_synchronizers[*global_neighborhood_it]->waitEndSynchronize(
+ dummy_accessor, _gst_mnl_weight);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::updatePairLists() {
+ AKANTU_DEBUG_IN();
+
+ /// compute the position of the quadrature points
+ this->model.getFEEngine().computeIntegrationPointsCoordinates(quad_positions);
+
+ NeighborhoodMap::iterator it = neighborhoods.begin();
+ NeighborhoodMap::iterator end = neighborhoods.end();
+
+ for (; it != end; ++it)
+ it->second->updatePairList();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::registerNonLocalVariable(
+ const ID & variable_name, const ID & nl_variable_name, UInt nb_component) {
+
+ AKANTU_DEBUG_IN();
+
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_it =
+ non_local_variables.find(variable_name);
+
+ if (non_local_variable_it == non_local_variables.end())
+ non_local_variables[nl_variable_name] = new NonLocalVariable(
+ variable_name, nl_variable_name, this->id, nb_component);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::registerNonLocalMaterial(Material & new_mat) {
+ non_local_materials.push_back(&new_mat);
+}
+
+/* -------------------------------------------------------------------------- */
+inline ElementTypeMapReal &
+NonLocalManager::registerWeightFunctionInternal(const ID & field_name) {
+
+ AKANTU_DEBUG_IN();
+
+ std::map<ID, ElementTypeMapReal *>::const_iterator it =
+ this->weight_function_internals.find(field_name);
+ if (it == weight_function_internals.end()) {
+ weight_function_internals[field_name] =
+ new ElementTypeMapReal(field_name, id);
+ }
+
+ return *(weight_function_internals[field_name]);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::updateWeightFunctionInternals() {
+
+ std::map<ID, ElementTypeMapReal *>::const_iterator it =
+ this->weight_function_internals.begin();
+ std::map<ID, ElementTypeMapReal *>::const_iterator end =
+ this->weight_function_internals.end();
+ for (; it != end; ++it) {
+ it->second->clear();
+ for (UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType ghost_type = (GhostType)g;
+ this->flattenInternal(*(it->second), ghost_type, _ek_regular);
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+inline void
+NonLocalManager::nonLocalVariableToNeighborhood(const ID & variable_name,
+ const ID & neighborhood) {
+
+ NeighborhoodMap::const_iterator it = neighborhoods.find(neighborhood);
+
+ AKANTU_DEBUG_ASSERT(it != neighborhoods.end(), "The neighborhood "
+ << neighborhood
+ << " is not registered");
+ it->second->registerNonLocalVariable(variable_name);
+}
+
+/* -------------------------------------------------------------------------- */
+inline UInt
+NonLocalManager::getNbDataForElements(const Array<Element> & elements,
+ const ID & id) const {
+ UInt size = 0;
+ UInt nb_quadrature_points = this->getModel().getNbIntegrationPoints(elements);
+ std::map<ID, NonLocalVariable *>::const_iterator it =
+ non_local_variables.find(id);
+
+ AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
+ "The non-local variable " << id << " is not registered");
+
+ size += it->second->nb_component * sizeof(Real) * nb_quadrature_points;
+ return size;
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::packElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ __attribute__((unused))
+ SynchronizationTag tag,
+ const ID & id) const {
+
+ std::map<ID, NonLocalVariable *>::const_iterator it =
+ non_local_variables.find(id);
+
+ AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
+ "The non-local variable " << id << " is not registered");
+
+ DataAccessor::packElementalDataHelper<Real>(
+ it->second->local, buffer, elements, true, this->model.getFEEngine());
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::unpackElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ __attribute__((unused))
+ SynchronizationTag tag,
+ const ID & id) const {
+
+ std::map<ID, NonLocalVariable *>::const_iterator it =
+ non_local_variables.find(id);
+
+ AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
+ "The non-local variable " << id << " is not registered");
+
+ DataAccessor::unpackElementalDataHelper<Real>(
+ it->second->local, buffer, elements, true, this->model.getFEEngine());
+}
+
+__END_AKANTU__
+
+#endif /* __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood.hh b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
new file mode 100644
index 000000000..401b24f97
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
@@ -0,0 +1,136 @@
+/**
+ * @file non_local_neighborhood.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: Wed Nov 25 2015
+ *
+ * @brief Non-local neighborhood for non-local averaging based on
+ * weight function
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#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
new file mode 100644
index 000000000..ec6d58a8d
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
@@ -0,0 +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 creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
+ *
+ * @brief Implementation of non-local neighborhood base
+ *
+ * @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 "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
new file mode 100644
index 000000000..c00a8b6a8
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
@@ -0,0 +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 creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
+ *
+ * @brief Non-local neighborhood base class
+ *
+ * @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_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
+#define __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
+/* -------------------------------------------------------------------------- */
+#include "neighborhood_base.hh"
+#include "parsable.hh"
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+class NonLocalNeighborhoodBase : public NeighborhoodBase, public Parsable {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+ NonLocalNeighborhoodBase(const SolidMechanicsModel & model,
+ const ElementTypeMapReal & quad_coordinates,
+ const ID & id = "non_local_neighborhood",
+ const MemoryID & memory_id = 0);
+ virtual ~NonLocalNeighborhoodBase();
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+
+public:
+ /// create grid synchronizer and exchange ghost cells
+ virtual void createGridSynchronizer();
+
+ /// compute weights, for instance needed for non-local damage computation
+ virtual void computeWeights(){};
+
+ /// compute the non-local counter part for a given element type map
+ virtual void weightedAverageOnNeighbours(
+ __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(){};
+
+ /// register a new non-local variable in the neighborhood
+ 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 */
+ /* --------------------------------------------------------------------------
+ */
+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> & 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> &);
+
+ /* ------------------------------------------------------------------------ */
+ /* 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
new file mode 100644
index 000000000..636c2bcea
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
@@ -0,0 +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 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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..39af89d5d
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
@@ -0,0 +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 creation: Mon Sep 28 2015
+ * @date last modification: Wed Nov 25 2015
+ *
+ * @brief Implementation of class non-local neighborhood
+ *
+ * @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 "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/contact_manager0.hh b/src/model/contact_manager0.hh
deleted file mode 100644
index 828103d13..000000000
--- a/src/model/contact_manager0.hh
+++ /dev/null
@@ -1,1159 +0,0 @@
-/**
- * @file contact_manager0.hh
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date creation: Tue May 13 2014
- * @date last modification: Tue May 13 2014
- *
- * @brief zeroth level of contact (simplest implementation)
- *
- * @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_MANAGER_0_HH__
-#define __AKANTU_CONTACT_MANAGER_0_HH__
-
-#include <unordered_set>
-
-
-//#include "aka_common.hh"
-#include "model_manager.hh"
-
-#define DEBUG_MANAGER 1
-
-
-__BEGIN_AKANTU__
-
-
-template <class pair_type>
-class PairComp {
-
-public:
- bool operator()(pair_type const &a, pair_type const &b) {
- return a.first->first < b.first->first
- || (!(b.first->first < a.first->first) && a.second->first < b.second->first);
- }
-};
-
-
-
-
-
-
-
-template <class Bounding_policy, Discretization_type DT, Consider_acceleration accel = Consider_t, template <class> class Cost_policy = Cost_functor>
-class Contact0_model_manager : public Model_manager<SolidMechanicsModel>, public Kinematic_traits<accel> {
-
-
- using Kinematic_traits<accel>::resolve_time;
-
- typedef Real time_type;
- typedef ctimer chronograph_type;
-
- // model type
- typedef SolidMechanicsModel model_type;
- typedef model_type* model_pointer;
- typedef model_type& model_reference;
-
- // geometric types
- typedef Bounding_policy volume_type;
- typedef typename volume_type::point_type point_type;
- typedef typename point_type::value_type value_type;
- typedef typename volume_type::aabb_type aabb_type;
-
- // element type
- typedef ModelElement<model_type> element_type;
-
- // Bounding volume hierarchy related types
- typedef Cost_policy<volume_type> cost_functor;
- typedef DataTree<volume_type, element_type, Cost_policy > tree_type;
- typedef typename tree_type::leaves_data_iterator leaves_data_iterator;
- typedef typename tree_type::leaf_iterator tree_leaf_iterator;
- typedef typename tree_type::iterator tree_iterator;
- typedef typename tree_type::const_iterator const_tree_iterator;
- typedef std::list<tree_type*> forest_container;
- typedef typename forest_container::iterator forest_iterator;
- typedef typename forest_container::const_iterator const_forest_iterator;
-
- // data structure for detailed check
- typedef std::pair<leaves_data_iterator, leaves_data_iterator> check_type;
-
-
- // typedef std::unordered_set<check_type, PairComp2<check_type> > check_container;
- typedef std::set<check_type, PairComp<check_type> > check_container;
- typedef typename check_container::iterator check_iterator;
-
- // kinematic types
- typedef point_type velocity_type;
- typedef std::list<velocity_type> velocity_container;
- typedef typename velocity_container::iterator velocity_iterator;
-
- typedef unsigned long mask_size;
-
- // timer type
- typedef std::priority_queue<time_type, std::vector<time_type>, std::greater<time_type> > timer_type;
-
- // tuple type
- typedef std::tuple<time_type, tree_iterator, tree_iterator> tuple_type;
-
- struct Tuple_compare {
- bool operator()(const tuple_type& t1, const tuple_type& t2) const
- { return std::get<0>(t1) > std::get<0>(t2); }
- };
-
- typedef typename std::priority_queue<tuple_type, std::vector<tuple_type>, Tuple_compare> hierarchy_timer;
-
-
- //! Structure used to do a postorder update of tree hierarchies
- struct Updater {
-
- tree_type &t_; //!< Reference to hierarchy
-
- Updater(tree_type& t) : t_(t) {}
-
- void operator()(tree_iterator it) {
- if (!it.is_leaf()) {
- volume_type& v = *it;
- volume_type& lv = *it.left();
- volume_type& rv = *it.right();
- v = lv + rv;
- assert(lv.last_time_ == rv.last_time_);
- v.last_time_ = lv.last_time_;
- v.velocity_ = 0.5 * (lv.velocity_ + rv.velocity_);
- v.acceleration_ = 0.5 * (lv.acceleration_ + rv.acceleration_);
- }
- }
- };
-
- struct Printer {
- void operator()(tree_iterator it)
- { cout<<*it<<", "; }
- };
-
- class Time_exception : public std::exception {
- virtual const char* what() const throw()
- { return "*** EXCEPTION *** Zero time increment."; }
- };
-
- struct Continuator : public std::exception {
-
- tuple_type best_;
-
- Continuator(const tuple_type& b) : best_(b) {}
-
- virtual const char* what() const throw()
- { return "*** EXCEPTION *** Continue."; }
- };
-
- template <bool flag>
- struct Bool2Type {
- enum { value = flag };
- };
-
-private:
-
- forest_container forest_; //!< Bounding volume hierarchies
- hierarchy_timer timer_; //!< Priority queue of times
- mask_size masks_; //!< Variable used for static objects
- tree_iterator null_;
- time_type last_; //!< Keep time of last detection engine reset
- check_container detailed_;
- bool detect_;
-
- //! Data structure that holds contact data
- struct ContactData {
-
- typedef SolidMechanicsModel model_type;
- typedef ModelElement<model_type> element_type;
-
- typedef std::set<UInt> node_set;
-
- struct Comparator {
- template <class iterator>
- bool operator()(iterator const &a, iterator const &b)
- { return a->first < b->first; }
- };
-
- typedef std::set<leaves_data_iterator, Comparator> elem_set;
-
- leaves_data_iterator left_;
- leaves_data_iterator right_;
-
- mutable elem_set ssurface_;
- mutable elem_set msurface_;
- mutable node_set slaves_;
-
- mutable tree_type *stree_;
- mutable tree_type *mtree_;
-
- ContactData(leaves_data_iterator l, leaves_data_iterator r) : left_(l), right_(r), ssurface_(), msurface_(), slaves_(), stree_(nullptr), mtree_(nullptr) {}
-
- template <class neighbor_type>
- void initialize(neighbor_type& ln, neighbor_type& rn) const {
-
- stree_ = ln.tree_;
- mtree_ = rn.tree_;
-
- // insert slave and master elements
- for (auto it = ln.elems_.begin(); it != ln.elems_.end(); ++it)
- ssurface_.insert(*it);
- for (auto it = rn.elems_.begin(); it != rn.elems_.end(); ++it)
- msurface_.insert(*it);
- }
-
-
-
- bool operator<(const ContactData& cd) const {
-
- return this->left_->first < cd.left_->first
- || (!(cd.left_->first < this->left_->first) && this->right_->first < cd.right_->first);
- }
-
-
- friend std::ostream& operator<<(std::ostream& os, const ContactData& cd) {
-
- os<<"Contact data info:"<<endl;
- os<<" "<<cd.slaves_.size()<<" slave nodes";
- // for (std::set<UInt>::const_iterator it = cd.slaves_.begin(); it!=cd.slaves_.end(); ++it)
- // os<<" "<<*it<<endl;
- // os<<" "<<*it;
- return os;
- }
-
- };
-
- std::set<ContactData> contact_;
- typedef typename std::set<ContactData>::iterator contact_iterator;
-
-public:
-
- //! Default constructor
- Contact0_model_manager()
- : Model_manager(), forest_(), timer_(), masks_(), null_(tree_iterator(nullptr)), last_(), detect_(true) {}
-
- //! Destructor
- ~Contact0_model_manager() {
-
- // delete trees
- for (forest_iterator it = forest_.begin(); it != forest_.end(); ++it)
- delete *it;
- }
-
- virtual void add_model(model_pointer m, Kinematic_type k = dynamic_object_t) {
-
- m->initializeUpdateResidualData();
- models_.push_back(m);
-
- if (models_.size() > 8*sizeof(mask_size)) {
- cout<<"*** ERROR *** Type used for masks is too small to handle all models."<<endl;
- cout<<"Aborting..."<<endl;
- exit(1);
- }
-
- // create tree
- tree_type* tp = construct_tree_bottom_up<tree_type, model_type, element_type>(*m);
- forest_.push_back(tp);
-
-
-#ifdef DEBUG_MANAGER
- // cout<<"tree "<<*tp<<endl;
- // print_mathematica(*tp);
-#endif
-
- // mask model as dynamic or static
- masks_ |= (k << (models_.size()-1));
- }
-
-
- void update_forest(time_type t) {
-
- int k = 0;
- for (forest_iterator fit = forest_.begin(); fit != forest_.end(); ++fit) {
-
- // check if the object is dynamic to update
- if (!(masks_ & (1 << k++)))
- continue;
-
- // loop over leaves
- for (leaves_data_iterator lit = (*fit)->leaves_data_begin();
- lit != (*fit)->leaves_data_end(); ++lit) {
-
- Real t_old = lit->first->last_time_;
-
- std::vector<const Real*> c = lit->second.coordinates();
- volume_type v = Volume_creator<volume_type>::create(c);
-
- // get positions
- const point_type& p0 = lit->first->center();
- const point_type& p1 = v.center();
-
- // get velocities
- const point_type& v0 = lit->first->velocity_;
- const point_type& v1 = v.velocity_;
-
- // new velocity and acceleration
- v.velocity_ = 1/(t - t_old) * (p1-p0);
- v.acceleration_ = 1/(t - t_old) * (v1-v0);
-
- v.last_time_ = t;
-
- // set new volume
- *lit->first = v;
- }
-
- tree_type &t = **fit;
- Updater u(t);
- postorder(t.root(),u);
- }
- }
-
-
- void reset() {
-
- // clear queue
- while (!timer_.empty())
- timer_.pop();
-
- timer_.push(std::make_tuple(last_, null_, null_));
- timer_.push(std::make_tuple(inf, null_, null_));
- }
-
-
- template <class queue_type>
- void print_queue(queue_type copy) {
-
- cout<<"Printing queue values:";
- while (!copy.empty()) {
- const tuple_type& tuple = copy.top();
- cout<<" "<<std::get<0>(tuple);
- copy.pop();
- }
- cout<<endl;
- }
-
-
-
- /*! \param t - Current elapsed time
- * \param Dt - Time step
- */
- void intersect(time_type t, time_type Dt) {
-
-#ifdef DEBUG_MANAGER
- cout<<"t = "<<t<<endl;
-// cout<<"t = "<<t<<", Dt = "<<Dt<<", timer:";
-
-// hierarchy_timer copy = timer_;
-// while (!copy.empty()) {
-// const tuple_type& tuple = copy.top();
-// cout<<" "<<std::get<0>(tuple);
-// copy.pop();
-// }
-// cout<<endl;
-
-#endif
-
- static time_type Dt1 = Dt;
-
- // reset if first enter the function
- if (t == last_ || t == Dt1) {
- Dt = Dt1;
- reset();
- }
-
- const tuple_type& tuple = timer_.top();
- time_type top = std::get<0>(tuple);
-
- // update hierarchies and get positions
- // note that the updating starts before the next intetersection check
- if (models_.size() > 1 && top <= t + 3*Dt1) {
- update_forest(t);
-//#ifdef DEBUG_MANAGER
-// cout<<"Updating forest"<<endl;
-//#endif
- }
-
- // check if detection is shut off
- if (t + Dt < top)
- return;
-
- if (detect_) {
-
- // get iterators from priority element
- tree_iterator it1 = std::get<1>(tuple);
- tree_iterator it2 = std::get<2>(tuple);
-
- // remove time from timer
- timer_.pop();
-
- // check for intersection becase:
- // 1. there are enough models
- // 2. intersection happens before the next increment
- if (models_.size() > 1 && top <= t + Dt1) {
-
- // if first step, add next time to timer and return because there
- // is not enough information for the computation of intersection times
- if (t <= last_ + (accel == Consider_t ? 2 : 1)*Dt) {
- // remove time from timer
- timer_.push(std::make_tuple(t, null_, null_));
-#ifdef DEBUG_MANAGER
- cout<<"Early out"<<endl;
-#endif
- return;
- }
-
- // check if iterators are null to compute O(n^2) collision times
- if (it1 == null_ || it2 == null_) {
-
- // do O(n^2) operation to obtain next time of intersections
- for (forest_iterator it1 = forest_.begin(); it1 != --forest_.end(); ++it1) {
-
- forest_iterator it2 = it1;
- for (++it2; it2 != forest_.end(); ++it2) {
-
- // get collision time
-#ifdef DEBUG_MANAGER
- cout<<"Calling check_collision in O(n^2) branch"<<endl;
-#endif
- time_type tstar = resolve_time((*it1)->root(), (*it2)->root());
- if (tstar != inf)
- timer_.push(std::make_tuple(t+tstar, (*it1)->root(), (*it2)->root()));
-#ifdef DEBUG_MANAGER
- else
- cout<<"*** INFO *** Objects do not intersect:\n "<<*(*it1)->root()<<"\n "<<*(*it2)->root()<<endl;
-#endif
- } // inner hierarchy loop
- } // outer hierarchy loop
-
- }
-
- // else use collision information previously computed (avoids O(n^2) operation above)
- else {
-
-#ifdef DEBUG_MANAGER
- cout<<"Calling check_collision in non-O(n^2) branch"<<endl;
-#endif
-
- // temporary queue for tree traversal
- hierarchy_timer pq;
- pq.push(std::make_tuple(top, it1, it2));
-
- try {
-
- // enter infinite loop
- while (!pq.empty()) {
-
-#ifdef DEBUG_MANAGER
- cout<<"______________________________________________"<<endl;
- cout<<"queue empty? -> "<<pq.empty()<<endl;
- if (!pq.empty())
- print_queue(pq);
-#endif
-
- const tuple_type& tuple = pq.top();
-
- time_type tstar = std::get<0>(tuple);
- tree_iterator left = std::get<1>(tuple);
- tree_iterator right = std::get<2>(tuple);
-
-#ifdef DEBUG_MANAGER
- cout<<"Queue time "<<tstar<<", items: "<<*left<<", "<<*right<<endl;
-#endif
-
- pq.pop();
-
- check_collision(t, left, right, pq);
-
- } // infinite loop
-
- }
- catch (Continuator& e) {
-
- cout<<"In continuator"<<endl;
-
- tuple_type& best = e.best_;
- time_type& best_time = std::get<0>(best);
- best_time += t;
-
- // clean hierarchy timer until best time
- while (std::get<0>(timer_.top()) <= best_time)
- timer_.pop();
-
- timer_.push(best);
- timer_.push(best);
-
- }
-
- }
-
- } // if statement on enough models
- // else do nothing as there are not enough models to carry out intersection
- // or the check engine is shut down until the next time in timer
- }
-
- // detailed check
- detailed_check(t, Dt);
- }
-
-
- struct Neighbor_finder {
-
- int count_;
- element_type *el_;
- tree_type *tree_;
-
- class Comparator {
-
- public:
- template <class iterator>
- bool operator()(iterator const &a, iterator const &b) {
- return a->first < b->first;
- }
- };
-
- std::set<leaves_data_iterator, Comparator > elems_;
-
- Neighbor_finder() : count_(), el_(nullptr), tree_(nullptr) {}
-
- UInt size() const
- { return elems_.size(); }
-
- template <class container>
- void add_slaves(container& c) {
-
- for (auto it = elems_.begin(); it != elems_.end(); ++it) {
- auto elem = (*it)->second;
- for (size_t i=0; i<elem.numNodes(); ++i)
- c.insert(elem.node(i));
- }
- }
-
- template <class container>
- void add_masters(container& c) {
-
- for (auto it = elems_.begin(); it != elems_.end(); ++it)
- c.insert(&(*it)->second);
- }
-
- bool operator()() { assert(el_ != nullptr); return elems_.size() == el_->numNodes()+1; }
-
- void operator()(tree_iterator it) {
-
- assert(tree_ != nullptr);
- assert(el_ != nullptr);
- auto eit = tree_->find_data(it);
- if (eit != tree_->leaves_data_end())
- if (el_->shareNodes(eit->second))
- elems_.insert(eit);
- ++count_;
- }
-
- friend std::ostream& operator<<(std::ostream& os, const Neighbor_finder& nf) {
-
- os<<"Neighbor finder info:"<<endl;
- os<<" found neighbors in "<<nf.count_<<" evaluations"<<endl;
-
- if (nf.el_)
- os<<" reference element "<<*nf.el_<<endl;
-
- cout<<" neighbors: "<<nf.size()<<endl;
- for (auto n:nf.elems_)
- os<<'\t'<<n->second<<'\n';
- return os;
- }
-
- };
-
-
- void detailed_check(time_type t, time_type Dt) {
-
- constexpr int dim = point_type::dim();
-
- if (contact_.size() > 0) {
-
- // loop over contact structures
- for (contact_iterator cit = contact_.begin(); cit != contact_.end(); ++cit) {
-
- ContactData& c = const_cast<ContactData&>(*cit);
-
- typedef std::set<element_type> elem_list;
- typedef std::pair<point_type, vector_type> closest_type;
- typedef std::tuple<UInt, Real, element_type, closest_type, elem_list> test_type;
-
- std::map<UInt, test_type > map;
- std::set<UInt> checked;
-
- typename ContactData::elem_set snew, mnew;
-
- // loop over slave elements to determine slave nodes
- for (auto sit:c.ssurface_) {
-
- // get slave element
- auto sel = sit->second;
- auto sbb = sel.template boundingBox<dim>();
-
- // loop over master elements
- for (auto mit:c.msurface_) {
-
- auto mel = mit->second;
-
- // tighter check with AABBs
- auto mbb = mel.template boundingBox<dim>();
- if (!(sbb & mbb))
- continue;
-
- // loop over slave nodes
- for (UInt i=0; i<sel.numNodes(); ++i) {
-
- UInt s = sel.node(i);
-
- // treat first element as slave
- auto coord = sel.coordinates();
-
- // create point
- point_type p(coord[i]);
-
- if (!penetrates(p,mel)) {
- continue;
- } else {
-
- // find node in contact data structure
- auto fslave = c.slaves_.find(s);
- // if not found, add it to container and search for new contact elements
- if (fslave == c.slaves_.end()) {
-
- c.slaves_.insert(s);
-
- Neighbor_finder sc, mc;
- sc.tree_ = c.stree_;
- mc.tree_ = c.mtree_;
- sc.el_ = &sit->second;
- mc.el_ = &mit->second;
- c.stree_->collect_neighbors(sit->first, sc);
- c.mtree_->collect_neighbors(mit->first, mc);
-
- for (auto i:sc.elems_)
- snew.insert(i);
- for (auto i:mc.elems_)
- mnew.insert(i);
- }
-
- // compute closest point
- closest_type r = closest_point_to_element(p, mel);
-
- Real nd = (p-r.first).sq_norm();
-
- auto elit = map.find(s);
- if (elit == map.end()) {
- map[s] = test_type(i, nd, sel, r, elem_list());
-
- test_type &tuple = map[s];
- std::get<4>(tuple).insert(mel);
- }
- else {
-
- auto tuple = map[s];
- Real dist = std::get<1>(tuple);
- element_type sel = std::get<2>(tuple);
-
- if (std::abs(nd - dist) < 1.0e-6) {
-
- test_type &tuple = map[s];
-
- // edit closest point
- elem_list &els = std::get<4>(tuple);
- els.insert(mel);
-
- if (els.size() == 2) {
-
- closest_type &p = std::get<3>(tuple);
-
- p = commonPonit<point_type>(els);
- }
-
-
- } else if (nd < dist) {
-
- map[s] = test_type(i, nd, sel, r, elem_list());
-
- test_type &tuple = map[s];
- std::get<4>(tuple).insert(mel);
-
- }
-
- }
-
- }
-
- } // loop over master elements
-
-
- } // loop over slave nodes
- } // loop over slave elements to determine slave nodes
-
- // add new elements if found
- if (!snew.empty() || !mnew.empty()) {
- for (auto s:snew)
- c.ssurface_.insert(s);
- for (auto m:mnew)
- c.msurface_.insert(m);
- }
-
-
- // loop over map to balance slave nodes with closest element
- for (auto it = map.begin(); it != map.end(); ++it) {
-
- UInt id = std::get<0>(it->second);
- element_type sel = std::get<2>(it->second);
- auto cp = std::get<3>(it->second);
- auto mel = std::get<4>(it->second);
-
-
- // process slave
- auto el = *mel.begin();
- balance<point_type>(Dt, id, cp, sel, const_cast<element_type&>(el));
-
- }
- } // loop over contact structures
- } // contact_ > 0
-
- // WORKING CODE FOR SINGLE PASS
- // if (contact_.size() > 0) {
- //
- // // loop over contact structures
- // for (auto c: contact_) {
- //
- // typedef std::tuple<UInt, Real, element_type, element_type> test_type;
- //
- // std::map<UInt, test_type > map;
- // std::set<UInt> checked;
- //
- // typename ContactData::elem_set snew, mnew;
- //
- // cout<<"------------------------------------------------------------------"<<endl;
- // cout<<"slaves -> "<<c.ssurface_.size()<<endl;
- // cout<<"masters -> "<<c.msurface_.size()<<endl;
- //
- // // loop over slave elements to determine slave nodes
- // for (auto sit:c.ssurface_) {
- //
- // // get slave element
- // auto sel = sit->second;
- // auto sbb = sel.template boundingBox<dim>();
- //
- // cout<<"sel -> "<<sel<<endl;
- //
- // // loop over master elements
- // for (auto mit:c.msurface_) {
- //
- // auto mel = mit->second;
- // cout<<"mel -> "<<mel<<endl;
- //
- // // tighter check with AABBs
- // auto mbb = mel.template boundingBox<dim>();
- // if (!(sbb & mbb)) {
- // cout<<"AABBS"<<endl;
- // continue;
- // }
- //
- // // loop over slave nodes
- // for (UInt i=0; i<sel.numNodes(); ++i) {
- //
- // UInt s = sel.node(i);
- //
- // cout<<"***NODE "<<s<<endl;
- // cout<<"***MBB -> "<<mbb<<endl;
- // cout<<"***MN -> "<<mel.normal()<<endl;
- //
- // // treat first element as slave
- // auto coord = sel.coordinates();
- //
- // // create point
- // point_type p(coord[i]);
- //
- // if (!penetrates(p,mel)) {
- // cout<<">SLAVE GETOUT"<<endl;
- // continue;
- // } else {
- //
- //
- // // find node in contact data structure
- // auto fslave = c.slaves_.find(s);
- // // if not found, add it to container and search for new contact elements
- // if (fslave == c.slaves_.end()) {
- // c.slaves_.insert(s);
- //
- // cout<<"type of sit -> "<<typeid(sit).name()<<endl;
- //
- // Neighbor_finder sc, mc;
- // sc.tree_ = c.stree_;
- // mc.tree_ = c.mtree_;
- // sc.el_ = &sit->second;
- // mc.el_ = &mit->second;
- // c.stree_->collect_neighbors(sit->first, sc);
- // c.mtree_->collect_neighbors(mit->first, mc);
- //
- // for (auto i:sc.elems_)
- // snew.insert(i);
- // for (auto i:mc.elems_)
- // mnew.insert(i);
- //
- // for (auto i:sc.elems_)
- // cout<<i->second;
- // for (auto i:mc.elems_)
- // cout<<i->second;
- // }
- //
- // cout<<">SLAVE "<<s<<": "<<p<<", with id "<<i<<", belonging to "<<sel<<" PENETRATES"<<endl;
- // cout<<"master element "<<mel<<", master bb -> "<<mbb<<endl;
- //
- // // compute closest point
- // std::pair<point_type, vector_type> r = closest_point_to_element(p, mel);
- //
- // cout<<"r -> "<<r.first<<endl;
- //
- // Real nd = (p-r.first).sq_norm();
- //
- // auto elit = map.find(s);
- // if (elit == map.end()) {
- // cout<<"NO ELEMENT IN MAP"<<endl;
- // map[s] = test_type(i, nd, sel, mel);
- // }
- // else {
- // cout<<"ELEMENT IN MAP"<<endl;
- // cout<<"stored info in map: ";
- //
- // auto tuple = map[s];
- // UInt id = std::get<0>(tuple);
- // Real dist = std::get<1>(tuple);
- // element_type sel = std::get<2>(tuple);
- // element_type mel = std::get<3>(tuple);
- //
- // cout<<"id "<<id<<", dist "<<dist<<"slave element "<<sel<<", master el "<<mel<<endl;
- //
- // cout<<"comparing new distance "<<nd<<" with stored value "<<dist<<endl;
- // if (nd < dist) {
- // cout<<"new distance smaller, inserting new element"<<endl;
- // map[s] = test_type(i, nd, sel, mel);
- // } else
- // cout<<"new distance is bigger!"<<endl;
- // }
- //
- // }
- //
- // } // loop over master elements
- //
- //
- // } // loop over slave nodes
- // } // loop over slave elements to determine slave nodes
- //
- // // add new elements if found
- // if (!snew.empty() || !mnew.empty()) {
- // for (auto s:snew)
- // c.ssurface_.insert(s);
- // for (auto m:mnew)
- // c.msurface_.insert(m);
- // }
- //
- //
- // // loop over map to balance slave nodes with closest element
- // for (auto it = map.begin(); it != map.end(); ++it) {
- //
- // UInt id = std::get<0>(it->second);
- // element_type sel = std::get<2>(it->second);
- // element_type mel = std::get<3>(it->second);
- //
- // cout<<"balance node with id -> "<<id<<" in slave element "<<sel<<endl;
- // cout<<"master el -> "<<mel<<endl;
- //
- // // process slave
- // balance<point_type>(Dt, id, sel, mel);
- //
- // }
- // } // loop over contact structures
- // } // contact_ > 0
- }
-
-
- template <class contact_type, class bbox_type, class slave_container>
- void solve_contact(time_type Dt, contact_type& c1, contact_type& c2, const bbox_type& bb, slave_container& slaves) {
-
- // treat first element as slave
- auto coord = c1.coordinates();
-
- int slave = 0;
- for (const double* c:coord) {
-
- // create point
- point_type p(c);
-
- // if point lies outside of collision zone, continue
- if (!(bb & p)) {
- ++slave;
- continue;
- }
-
- UInt id = c1.node(slave);
- auto it = slaves.find(id);
- if (it != slaves.end())
- continue;
- slaves.insert(id);
-
- // else find closest distance from p to contacting element c2
- std::pair<point_type, vector_type> r = closest_point_to_element(p, c2);
- 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 = c1.getMass(slave)[0];
-
- // compute force at slave node
- vector_type N = 2 * delta * mass / pow(Dt,2.) * n;
-
- // compute forces in master element balancing linear and angular momenta
- balance(Dt, slave, r, N, c1, c2);
-
- ++slave;
- }
-
- }
-
-
-private:
-
-
-
- template <class iterator>
- void traverse_right(iterator it1, iterator it2, hierarchy_timer& pq) {
-
-#ifdef DEBUG_MANAGER
- cout<<" traversing right hierarchy"<<endl;
-#endif
-
- iterator lit = it2.left();
- iterator rit = it2.right();
- assert(lit != null_);
- assert(rit != null_);
-
- time_type tstar1 = resolve_time(it1, lit);
- if (tstar1 != inf) {
-#ifdef DEBUG_MANAGER
- cout<<" Adding queue time "<<tstar1<<endl;
-#endif
- pq.push(std::make_tuple(tstar1, it1, lit));
- }
- time_type tstar2 = resolve_time(it1, rit);
- if (tstar2 != inf) {
-#ifdef DEBUG_MANAGER
- cout<<" Adding queue time "<<tstar2<<endl;
-#endif
- pq.push(std::make_tuple(tstar2, it1, rit));
- }
- }
-
- template <class iterator>
- void traverse_left(iterator it1, iterator it2, hierarchy_timer& pq) {
-
-#ifdef DEBUG_MANAGER
- cout<<" traversing left hierarchy"<<endl;
-#endif
-
- iterator lit = it1.left();
- iterator rit = it1.right();
- assert(lit != null_);
- assert(rit != null_);
-
- time_type tstar1 = resolve_time(lit, it2);
- if (tstar1 != inf) {
-#ifdef DEBUG_MANAGER
- cout<<" Adding queue time "<<tstar1<<endl;
-#endif
- pq.push(std::make_tuple(tstar1, lit, it2));
- }
- time_type tstar2 = resolve_time(rit, it2);
- if (tstar2 != inf) {
-#ifdef DEBUG_MANAGER
- cout<<" Adding queue time "<<tstar2<<endl;
-#endif
- pq.push(std::make_tuple(tstar2, rit, it2));
- }
- }
-
-
- template <class iterator>
- void check_collision(time_type t, iterator it1, iterator it2, hierarchy_timer& pq) {
-
- // if volumes are leaves, change the timer and time step
- if (it1.is_leaf() && it2.is_leaf()) {
-
- cout<<"*** FOUND LEAVES ***"<<endl;
-
- // case where objects intersect
- if (*it1 & *it2) {
-
- cout<<"*** BOUNDING SPHERE INTERSECTION ***"<<endl;
-
- // add leaves to carry out penetration tests
- leaves_data_iterator lit1(nullptr), lit2(nullptr);
-
- Neighbor_finder lc, rc;
-
- for (forest_iterator it = forest_.begin(); it != forest_.end(); ++it) {
-
- leaves_data_iterator lit = (*it)->find_data(it1);
- if (lit != (*it)->leaves_data_end()) {
- lit1 = lit;
-
- lc.tree_ = *it;
- lc.el_ = &lit->second;
- (*it)->collect_neighbors(lit->first, lc);
- }
-
- lit = (*it)->find_data(it2);
- if (lit != (*it)->leaves_data_end()) {
- lit2 = lit;
-
- rc.tree_ = *it;
- rc.el_ = &lit->second;
- (*it)->collect_neighbors(lit->first, rc);
- }
- }
-
- assert (lit1 != leaves_data_iterator(nullptr));
- assert (lit2 != leaves_data_iterator(nullptr));
-
- // check for new ContactData
- auto ins = contact_.insert(ContactData(lit1, lit2));
-
- if (ins.second) {
- auto cd = ins.first;
- cd->initialize(lc,rc);
- cout<<"*** INFO *** Adding contact data."<<endl;
- } else {
- cout<<"*** WARNING *** Contact data not inserted."<<endl;
- }
-
- // add to data structure for detailed check
- detailed_.insert(std::make_pair(lit1, lit2));
-
- detect_ = false;
-
- cout<<"***DETAILED SIZE -> "<<detailed_.size()<<endl;
-
- }
- else
- cout<<"*** NO INTERSECTION BETWEEN BOUNDING SPHERES ***"<<endl;
-
-
- time_type tstar = resolve_time(it1, it2);
-
-#ifdef DEBUG_MANAGER
-
- if (tstar == inf)
- cout<<" Leaves found that DO NOT collide"<<endl;
- else {
- cout<<" Leaves found that collide at time "<<(tstar)<<endl;
- }
-#endif
-
- if (tstar == inf) {
- cout<<" Leaves found that DO NOT collide"<<endl;
- }
-
- throw Continuator(std::make_tuple(tstar, it1, it2));
- }
-
- // found left leaf, traverse right hierarchy
- else if (it1.is_leaf() && !it2.is_leaf()) {
-
-#ifdef DEBUG_MANAGER
- cout<<" s1 is leaf"<<endl;
-#endif
- traverse_right(it1, it2, pq);
- }
-
- // found right leaf, traverse left hierarchy
- else if (!it1.is_leaf() && it2.is_leaf()) {
-
-#ifdef DEBUG_MANAGER
- cout<<" s2 is leaf"<<endl;
-#endif
- traverse_left(it1, it2, pq);
- }
-
- // else non-leaf case found, check volume sizes
- else {
-
- value_type m1 = it1->measure();
- value_type m2 = it2->measure();
-
- // volumes are equal to numerical error, traverse both hierarchies
- if (equal(m1, m2)) {
-
-#ifdef DEBUG_MANAGER
- cout<<" "<<m1<<" == "<<m2<<endl;
-#endif
- traverse_right(it1, it2, pq);
- traverse_left(it1, it2, pq);
- }
- // left volume is bigger, traverse right hierarchy
- else if (m1 > m2) {
-
-#ifdef DEBUG_MANAGER
- cout<<" "<<m1<<" > "<<m2<<endl;
-#endif
- traverse_left(it1, it2, pq);
- }
- // right volume is bigger, traverse left hierarchy
- else if (m1 < m2) {
-
-#ifdef DEBUG_MANAGER
- cout<<" "<<m1<<" < "<<m2<<endl;
-#endif
- traverse_right(it1, it2, pq);
- }
- } // non-leaf case
-
- }
-
-
- friend std::ostream& operator<<(std::ostream& os, const Contact0_model_manager& mm) {
-
- os<<"Contact model manager info:"<<endl;
- os<<" models: "<<mm.models_.size()<<endl;
- size_t i=0;
- const_forest_iterator tit = mm.forest_.begin();
- for (const_model_iterator it = mm.models_.begin(); it != mm.models_.end(); ++it) {
- os<<"\tmodel "<<++i<<" memory address: "<<*it<<endl;
- os<<"\tmodel: "<<**it<<endl;
- os<<"\ttree: ";
- print_mathematica(**tit++);
- }
- return os;
- }
-};
-
-__END_AKANTU__
-
-#endif /* __AKANTU_CONTACT_MANAGER_0_HH__ */
diff --git a/src/model/dof_manager_petsc.cc b/src/model/dof_manager_petsc.cc
index 7f5f2e780..671cb05ba 100644
--- a/src/model/dof_manager_petsc.cc
+++ b/src/model/dof_manager_petsc.cc
@@ -1,396 +1,396 @@
/**
* @file dof_manager_petsc.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Oct 5 21:19:58 2015
*
* @brief DOFManaterPETSc is the PETSc implementation of the DOFManager
*
* @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 "dof_manager_petsc.hh"
#include "cppargparse.hh"
#if defined(AKANTU_USE_MPI)
#include "static_communicator.hh"
#include "mpi_type_wrapper.hh"
#endif
/* -------------------------------------------------------------------------- */
#include <petscsys.h>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
#if not defined(PETSC_CLANGUAGE_CXX)
/// small hack to use the c binding of petsc when the cxx binding does notation
/// exists
int aka_PETScError(int ierr) {
CHKERRQ(ierr);
return 0;
}
#endif
UInt DOFManagerPETSc::petsc_dof_manager_instances = 0;
/// Error handler to make PETSc errors caught by Akantu
#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
static PetscErrorCode PETScErrorHandler(MPI_Comm, int line, const char * dir,
const char * file,
PetscErrorCode number,
PetscErrorType type,
const char * message, void *) {
AKANTU_DEBUG_ERROR("An error occured in PETSc in file \""
<< file << ":" << line << "\" - PetscErrorCode " << number
<< " - \"" << message << "\"");
}
#else
static PetscErrorCode PETScErrorHandler(MPI_Comm, int line, const char * func,
const char * dir, const char * file,
PetscErrorCode number,
PetscErrorType type,
const char * message, void *) {
AKANTU_DEBUG_ERROR("An error occured in PETSc in file \""
<< file << ":" << line << "\" - PetscErrorCode " << number
<< " - \"" << message << "\"");
}
#endif
/* -------------------------------------------------------------------------- */
DOFManagerPETSc::DOFManagerPETSc(const Mesh & mesh, const ID & id,
const MemoryID & memory_id)
: DOFManager(mesh, id, memory_id) {
// check if the akantu types and PETSc one are consistant
#if __cplusplus > 199711L
static_assert(sizeof(Int) == sizeof(PetscInt),
"The integer type of Akantu does not match the one from PETSc");
static_assert(sizeof(Real) == sizeof(PetscReal),
"The integer type of Akantu does not match the one from PETSc");
#else
AKANTU_DEBUG_ASSERT(
sizeof(Int) == sizeof(PetscInt),
"The integer type of Akantu does not match the one from PETSc");
AKANTU_DEBUG_ASSERT(
sizeof(Real) == sizeof(PetscReal),
"The integer type of Akantu does not match the one from PETSc");
#endif
if (this->petsc_dof_manager_instances == 0) {
#if defined(AKANTU_USE_MPI)
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
const StaticCommunicatorMPI & mpi_st_comm =
dynamic_cast<const StaticCommunicatorMPI &>(
comm.getRealStaticCommunicator());
this->communicator = mpi_st_comm.getMPITypeWrapper().getMPICommunicator();
#else
this->communicator = PETSC_COMM_SELF;
#endif
cppargparse::ArgumentParser & argparser = getStaticArgumentParser();
- int & argc = argparser.getARGC();
- char **& argv = argparser.getARGV();
+ int & argc = argparser.getArgC();
+ char **& argv = argparser.getArgV();
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);
this->petsc_dof_manager_instances++;
}
VecCreate(PETSC_COMM_WORLD, &this->residual);
VecCreate(PETSC_COMM_WORLD, &this->solution);
}
/* -------------------------------------------------------------------------- */
DOFManagerPETSc::~DOFManagerPETSc() {
PetscErrorCode ierr;
ierr = VecDestroy(&(this->residual));
CHKERRXX(ierr);
ierr = VecDestroy(&(this->solution));
CHKERRXX(ierr);
this->petsc_dof_manager_instances--;
if (this->petsc_dof_manager_instances == 0) {
PetscFinalize();
}
}
/* -------------------------------------------------------------------------- */
void DOFManagerPETSc::registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
DOFSupportType & support_type) {
DOFManager::registerDOFs(dof_id, dofs_array, support_type);
PetscErrorCode ierr;
PetscInt current_size;
ierr = VecGetSize(this->residual, &current_size);
CHKERRXX(ierr);
if (current_size == 0) { // first time vector is set
PetscInt local_size = this->pure_local_system_size;
ierr = VecSetSizes(this->residual, local_size, PETSC_DECIDE);
CHKERRXX(ierr);
ierr = VecSetFromOptions(this->residual);
CHKERRXX(ierr);
#ifndef AKANTU_NDEBUG
PetscInt global_size;
ierr = VecGetSize(this->residual, &global_size);
CHKERRXX(ierr);
AKANTU_DEBUG_ASSERT(this->system_size == UInt(global_size),
"The local value of the system size does not match the "
"one determined by PETSc");
#endif
PetscInt start_dof, end_dof;
VecGetOwnershipRange(this->residual, &start_dof, &end_dof);
PetscInt * global_indices = new PetscInt[local_size];
global_indices[0] = start_dof;
for (PetscInt d = 0; d < local_size; d++)
global_indices[d + 1] = global_indices[d] + 1;
// To be change if we switch to a block definition
#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
ISLocalToGlobalMappingCreate(this->communicator, 1, local_size,
global_indices, PETSC_COPY_VALUES,
&this->is_ltog);
#else
ISLocalToGlobalMappingCreate(this->communicator, local_size, global_indices,
PETSC_COPY_VALUES, &this->is_ltog);
#endif
VecSetLocalToGlobalMapping(this->residual, this->is_ltog);
delete[] global_indices;
ierr = VecDuplicate(this->residual, &this->solution);
CHKERRXX(ierr);
} else { // this is an update of the object already created
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// set the solution to zero
// ierr = VecZeroEntries(this->solution);
// CHKERRXX(ierr);
}
/* -------------------------------------------------------------------------- */
/**
* 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 SparseMatrixPETSc::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();
// }
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/heat_transfer/heat_transfer_model.cc b/src/model/heat_transfer/heat_transfer_model.cc
index 0cca5c502..0fb2fadd0 100644
--- a/src/model/heat_transfer/heat_transfer_model.cc
+++ b/src/model/heat_transfer/heat_transfer_model.cc
@@ -1,1251 +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_material_internal_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) {
+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();
- PBCSynchronizer * synch = new PBCSynchronizer(pbc_pair);
+ pbc_synch = new PBCSynchronizer(pbc_pair);
- synch_registry->registerSynchronizer(*synch, _gst_htm_capacity);
- synch_registry->registerSynchronizer(*synch, _gst_htm_temperature);
- changeLocalEquationNumberForPBC(pbc_pair,1);
+ synch_registry->registerSynchronizer(*pbc_synch, _gst_htm_capacity);
+ synch_registry->registerSynchronizer(*pbc_synch, _gst_htm_temperature);
+ changeLocalEquationNumberForPBC(pbc_pair, 1);
- // as long as there are ones on the diagonal of the matrix, we can put boudandary true for slaves
+ // 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().getNbQuadraturePoints(*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().getNbQuadraturePoints(*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().getNbQuadraturePoints(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().interpolateOnQuadraturePoints(*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().gradientOnQuadraturePoints(*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_quadrature_points = fem.getNbQuadraturePoints(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.computeNormalsOnControlPoints();
+ 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().getNbQuadraturePoints(type);
+ 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().getNbQuadraturePoints(*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 17dc4ebcb..c32e85634 100644
--- a/src/model/heat_transfer/heat_transfer_model.hh
+++ b/src/model/heat_transfer/heat_transfer_model.hh
@@ -1,452 +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(std::string name = "");
+ 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 990351f2b..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(std::string name) {
+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 += getNbQuadraturePoints(elements) * spatial_dimension * sizeof(Real); // temperature gradient
+ 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 0f647ae29..654e66219 100644
--- a/src/model/integration_scheme/generalized_trapezoidal.hh
+++ b/src/model/integration_scheme/generalized_trapezoidal.hh
@@ -1,155 +1,156 @@
/**
* @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(DOFManager & dof_manager, Real alpha) : IntegrationScheme1stOrder(dof_manager), alpha(alpha){};
virtual ~GeneralizedTrapezoidal(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
const Array<bool> & blocked_dofs) const;
virtual void corrector(const SolutionType & type, Real delta_t,
Array<Real> & u, Array<Real> & u_dot,
const Array<bool> & blocked_dofs,
const Array<Real> & delta) const;
virtual void assembleJacobian(const SolutionType & type,
Real time_step);
public:
/// the coeffichent @f{b@f} in the description
Real getTemperatureCoefficient(const SolutionType & type, Real delta_t) const;
/// the coeffichent @f{a@f} in the description
Real getTemperatureRateCoefficient(const SolutionType & type,
Real delta_t) const;
private:
template <SolutionType type>
void allCorrector(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
const Array<bool> & blocked_dofs,
const Array<Real> & delta) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Alpha, alpha, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// the @f$\alpha@f$ parameter
const Real alpha;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* Forward Euler (explicit) -> condition on delta_t
*/
class ForwardEuler : public GeneralizedTrapezoidal {
public:
ForwardEuler(DOFManager & dof_manager) : GeneralizedTrapezoidal(dof_manager, 0.){};
};
/**
* Trapezoidal rule (implicit), midpoint rule or Crank-Nicolson
*/
class TrapezoidalRule1 : public GeneralizedTrapezoidal {
public:
TrapezoidalRule1(DOFManager & dof_manager) : GeneralizedTrapezoidal(dof_manager, .5){};
};
/**
* Backward Euler (implicit)
*/
class BackwardEuler : public GeneralizedTrapezoidal {
public:
BackwardEuler(DOFManager & dof_manager) : GeneralizedTrapezoidal(dof_manager, 1.){};
};
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__ */
diff --git a/src/model/integration_scheme/integration_scheme_1st_order.hh b/src/model/integration_scheme/integration_scheme_1st_order.hh
index a3d6635d6..df10ff646 100644
--- a/src/model/integration_scheme/integration_scheme_1st_order.hh
+++ b/src/model/integration_scheme/integration_scheme_1st_order.hh
@@ -1,87 +1,88 @@
/**
* @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"
#include "integration_scheme.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__
#define __AKANTU_INTEGRATION_SCHEME_1ST_ORDER_HH__
__BEGIN_AKANTU__
class IntegrationScheme1stOrder : public IntegrationScheme {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
IntegrationScheme1stOrder(DOFManager & dof_manager)
: IntegrationScheme(dof_manager, 1){};
virtual ~IntegrationScheme1stOrder(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void predictor(const ID & dof_id, Real delta_t);
virtual void corrector(const SolutionType & type, const ID & dof_id, Real delta_t);
/// generic interface of a predictor of 1st order
virtual void predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
const Array<bool> & boundary) const = 0;
/// generic interface of a corrector of 1st order
virtual void corrector(const SolutionType & type, Real delta_t,
Array<Real> & u, Array<Real> & u_dot,
const Array<bool> & boundary,
const Array<Real> & delta) const = 0;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
protected:
virtual Real getTemperatureCoefficient(const SolutionType & type,
Real delta_t) const = 0;
virtual Real getTemperatureRateCoefficient(const SolutionType & type,
Real delta_t) const = 0;
/* ------------------------------------------------------------------------ */
/* 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 766ee1c8a..1b94437d9 100644
--- a/src/model/integration_scheme/integration_scheme_2nd_order.hh
+++ b/src/model/integration_scheme/integration_scheme_2nd_order.hh
@@ -1,103 +1,104 @@
/**
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "integration_scheme.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_INTEGRATION_SCHEME_2ND_ORDER_HH__
#define __AKANTU_INTEGRATION_SCHEME_2ND_ORDER_HH__
namespace akantu {
class SparseMatrix;
}
__BEGIN_AKANTU__
class IntegrationScheme2ndOrder : public IntegrationScheme {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
IntegrationScheme2ndOrder(DOFManager & dof_manager) : IntegrationScheme(dof_manager, 2){};
virtual ~IntegrationScheme2ndOrder(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// generic interface of a predictor
virtual void predictor(const ID & dof_id, Real delta_t);
/// generic interface of a corrector
virtual void corrector(const SolutionType & type, const ID & dof_id,
Real delta_t);
/// generic interface of a predictor of 2nd order
virtual void predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
Array<Real> & u_dot_dot,
const Array<bool> & blocked_dofs) const = 0;
/// generic interface of a corrector of 2nd order
virtual void corrector(const SolutionType & type,
Real delta_t, Array<Real> & u, Array<Real> & u_dot,
Array<Real> & u_dot_dot,
const Array<bool> & blocked_dofs,
const Array<Real> & delta) const = 0;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
protected:
virtual Real
getAccelerationCoefficient(const SolutionType & type,
Real delta_t) const;
virtual Real
getVelocityCoefficient(const SolutionType & type,
Real delta_t) const;
virtual Real
getDisplacementCoefficient(const SolutionType & type,
Real delta_t) const;
/* ------------------------------------------------------------------------ */
/* 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 8d4771a87..e0e760f67 100644
--- a/src/model/integration_scheme/newmark-beta.hh
+++ b/src/model/integration_scheme/newmark-beta.hh
@@ -1,186 +1,187 @@
/**
* @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(DOFManager & dof_manager, Real alpha, Real beta)
: IntegrationScheme2ndOrder(dof_manager), beta(beta), alpha(alpha), k(0.),
h(0.){};
~NewmarkBeta(){};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
void predictor(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
Array<Real> & u_dot_dot,
const Array<bool> & blocked_dofs) const;
void corrector(const SolutionType & type, Real delta_t, Array<Real> & u,
Array<Real> & u_dot, Array<Real> & u_dot_dot,
const Array<bool> & blocked_dofs,
const Array<Real> & delta) const;
void assembleJacobian(const SolutionType & type, Real delta_t);
public:
Real getAccelerationCoefficient(const SolutionType & type,
Real delta_t) const;
Real getVelocityCoefficient(const SolutionType & type, Real delta_t) const;
Real getDisplacementCoefficient(const SolutionType & type,
Real delta_t) const;
private:
template <SolutionType type>
void allCorrector(Real delta_t, Array<Real> & u, Array<Real> & u_dot,
Array<Real> & u_dot_dot, const Array<bool> & blocked_dofs,
const 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;
};
/**
* 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(DOFManager & dof_manager)
: NewmarkBeta(dof_manager, 0., 1. / 2.){};
};
//#include "integration_scheme/central_difference.hh"
/// undamped trapezoidal rule (implicit)
class TrapezoidalRule2 : public NewmarkBeta {
public:
TrapezoidalRule2(DOFManager & dof_manager)
: NewmarkBeta(dof_manager, 1. / 2., 1. / 2.){};
};
/// Fox-Goodwin rule (implicit)
class FoxGoodwin : public NewmarkBeta {
public:
FoxGoodwin(DOFManager & dof_manager)
: NewmarkBeta(dof_manager, 1. / 6., 1. / 2.){};
};
/// Linear acceleration (implicit)
class LinearAceleration : public NewmarkBeta {
public:
LinearAceleration(DOFManager & dof_manager)
: NewmarkBeta(dof_manager, 1. / 3., 1. / 2.){};
};
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif /* __AKANTU_NEWMARK_BETA_HH__ */
diff --git a/src/model/model.cc b/src/model/model.cc
index 075feff51..a8cce3918 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -1,394 +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& mesh, UInt dim, const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id), ModelSolver(mesh, id, memory_id),
mesh(mesh),
spatial_dimension(dim == _all_dimensions ? mesh.getSpatialDimension() : dim),
synch_registry(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;
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
- Real * coords = mesh.getNodes().storage();
- UInt dim = mesh.getSpatialDimension();
+ Array<Real>::const_vector_iterator coord_it =
+ 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;
- AKANTU_DEBUG_INFO("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]
- << ")");
+ UInt slave = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i1) : i1;
+ UInt master = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i2) : i2;
+
+ AKANTU_DEBUG_INFO("pairing " << slave << " (" << Vector<Real>(coord_it[i1])
+ << ") with " << master << " ("
+ << Vector<Real>(coord_it[i2]) << ")");
#endif
++it;
}
}
/* -------------------------------------------------------------------------- */
-DistributedSynchronizer & Model::createParallelSynch(MeshPartition * partition,
- __attribute__((unused)) DataAccessor * data_accessor){
+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) {
- this->addDumpGroupFieldToDumper(dumper_name,field_id,"all",_ek_regular,3);
+ 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 f5e30bca1..eb59391ed 100644
--- a/src/model/model.hh
+++ b/src/model/model.hh
@@ -1,316 +1,327 @@
/**
* @file model.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Tue Jul 27 2010
- * @date last modification: Fri Sep 05 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Oct 16 2015
*
* @brief Interface of a model
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MODEL_HH__
#define __AKANTU_MODEL_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_memory.hh"
#include "mesh.hh"
#include "fe_engine.hh"
#include "mesh_utils.hh"
#include "synchronizer_registry.hh"
#include "distributed_synchronizer.hh"
#include "static_communicator.hh"
#include "mesh_partition.hh"
#include "dof_synchronizer.hh"
#include "pbc_synchronizer.hh"
#include "parser.hh"
#include "model_solver.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
struct ModelOptions {
virtual ~ModelOptions() {}
};
class DumperIOHelper;
class Model : public Memory, public ModelSolver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Model(Mesh& mesh, UInt spatial_dimension = _all_dimensions,
const ID & id = "model",
const MemoryID & memory_id = 0);
virtual ~Model();
typedef std::map<std::string, FEEngine *> FEEngineMap;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void initFull(const ModelOptions & options);
virtual void initModel() = 0;
/// create the synchronizer registry object
void createSynchronizerRegistry(DataAccessor * data_accessor);
/// create a parallel synchronizer and distribute the mesh
DistributedSynchronizer & createParallelSynch(MeshPartition * partition,
DataAccessor * data_accessor);
/// change local equation number so that PBC is assembled properly
- void changeLocalEquationNumberForPBC(std::map<UInt,UInt> & pbc_pair,UInt dimension);
+ 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);
/// Dump the data for all boundaries
void dumpGroup();
/// Set the directory for a given group
void setGroupDirectory(const std::string & directory,
const std::string & group_name);
/// Set the directory for all boundaries
void setGroupDirectory(const std::string & directory);
/// Set the base name for a given group
void setGroupBaseName(const std::string & basename,
const std::string & group_name);
/// Get the internal dumper of a given group
DumperIOHelper & getGroupDumper(const std::string & group_name);
/* ------------------------------------------------------------------------ */
- /* Accessors */
+ /* 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 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;
+ inline bool isPBCSlaveNode(const UInt node) const { throw; }
/// 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 getNbQuadraturePoints(const Array<Element> & elements,
- const ID & fem_id = ID()) const;
+ inline UInt getNbIntegrationPoints(const Array<Element> & elements,
+ const ID & fem_id = ID()) const;
/* ------------------------------------------------------------------------ */
/* Dumpable interface (kept for convenience) and dumper relative functions */
/* ------------------------------------------------------------------------ */
void setTextModeToDumper();
virtual void addDumpGroupFieldToDumper(const std::string & field_id,
dumper::Field * field,
DumperIOHelper & dumper);
virtual void addDumpField(const std::string & field_id);
virtual void addDumpFieldVector(const std::string & field_id);
virtual void addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldTensorToDumper(const std::string & dumper_name,
const std::string & field_id);
virtual void addDumpFieldTensor(const std::string & field_id);
virtual void setBaseName(const std::string & basename);
virtual void setBaseNameToDumper(const std::string & dumper_name,
- const std::string & basename);
-
+ const std::string & basename);
virtual void addDumpGroupField(const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag);
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & element_kind,
bool padding_flag);
virtual void removeDumpGroupField(const std::string & field_id,
const std::string & group_name);
virtual void removeDumpGroupFieldFromDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldVector(const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name);
- virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag){return NULL;}
-
- virtual dumper::Field * createNodalFieldUInt(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag){return NULL;}
-
- virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag){return NULL;}
-
-
- virtual dumper::Field * createElementalField(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag,
- const UInt & spatial_dimension,
- const ElementKind & kind){return NULL;}
-
+ 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);
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;
/// 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 b16dbf432..5ed55bccb 100644
--- a/src/model/model_inline_impl.cc
+++ b/src/model/model_inline_impl.cc
@@ -1,197 +1,199 @@
/**
* @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 ?");
+ << " 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);
+ 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");
+ << 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){
+ 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");
+ << name << " was already created");
#endif
std::stringstream sstr; sstr << id << ":fem:" << name;
fems[name] = new FEEngineClass(mesh, spatial_dimension, sstr.str(), memory_id);
// MeshUtils::buildFacets(fems[name]->getMesh());
// std::stringstream sstr2; sstr2 << id << ":fem_boundary:" << name;
// fems_boundary[name] = new FEEngineClass(mesh, spatial_dimension-1, sstr2.str(), memory_id);
}
/* -------------------------------------------------------------------------- */
inline FEEngine & Model::getFEEngine(const ID & name) const{
AKANTU_DEBUG_IN();
ID tmp_name = name;
if (name == "") tmp_name = default_fem;
FEEngineMap::const_iterator it = fems.find(tmp_name);
AKANTU_DEBUG_ASSERT(it != fems.end(),
- "The FEEngine " << tmp_name << " is not registered");
+ "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");
+ "The FEEngine boundary " << tmp_name << " is not registered");
AKANTU_DEBUG_ASSERT(it->second != NULL,
- "The FEEngine boundary " << tmp_name << " was not created");
+ "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){
// 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) {
// (*dof_synchronizer->getLocalDOFEquationNumbersPointer())
// (node_slave*dimension+i) = dimension*node_master+i;
// (*dof_synchronizer->getGlobalDOFEquationNumbersPointer())
// (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::getNbQuadraturePoints(const Array<Element> & elements,
- const ID & fem_id) const {
+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).getNbQuadraturePoints(el.type,
- el.ghost_type);
+ nb_quad += getFEEngine(fem_id).getNbIntegrationPoints(el.type,
+ el.ghost_type);
}
return nb_quad;
}
/* -------------------------------------------------------------------------- */
diff --git a/src/model/model_manager.cc b/src/model/model_manager.cc
deleted file mode 100644
index 15b3c3578..000000000
--- a/src/model/model_manager.cc
+++ /dev/null
@@ -1,407 +0,0 @@
-/**
- * @file model_manager.cc
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date creation: Mon Jan 07 2013
- * @date last modification: Tue May 07 2013
- *
- * @brief higher order object that deals with collections of 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/>.
- *
- */
-
-// akantu header files
-#include "model_manager.hh"
-
-__BEGIN_AKANTU__
-
-
-#define SWAPD(a,b) do { double tmp = b ; b = a ; a = tmp ; } while(0)
-
-
-uint32_t solve_quadratic(Real a, Real b, Real c,
- Real *x0, Real *x1 )
-{
-#ifdef DEBUG_POLYSOLVER
- std::cout << "solve_quadratic( "
- << a << ", "
- << b << ", "
- << c << " )\n";
-#endif
-
- // Handle linear case
- if( a == 0.0 ) {
- if( b == 0.0 ) {
-#ifdef DEBUG_POLYSOLVER
- std::cout << "linear with no roots\n";
-#endif
- return( 0 );
- } else {
- *x0 = -c / b;
-#ifdef DEBUG_POLYSOLVER
- std::cout << "linear with one root at x = " << *x0 << "\n";
-#endif
- return( 1 );
- }
- }
-
- Real disc = b*b - 4.0*a*c;
- if( disc > 0 ) {
- if( b == 0 ) {
- Real r = fabs( 0.5 * sqrt (disc) / a );
- *x0 = -r;
- *x1 = r;
- } else {
- Real sgnb = (b > 0 ? 1 : -1);
- Real temp = -0.5 * (b + sgnb * sqrt (disc));
- Real r1 = temp / a ;
- Real r2 = c / temp ;
-
- if( r1 < r2 ) {
- *x0 = r1 ;
- *x1 = r2 ;
- } else {
- *x0 = r2 ;
- *x1 = r1 ;
- }
- }
- return 2;
- } else if( disc == 0 ) {
- *x0 = -0.5 * b / a ;
- *x1 = -0.5 * b / a ;
- return 2;
- } else
- return 0;
-}
-
-
-/* Finds the real roots of x^4 + a x^3 + b x^2 + c x + d = 0
- */
-
-
-//template<>
-uint32_t Kinematic_traits<Consider_t>::solve_quartic(Real a, Real b, Real c, Real d,
- Real *x0, Real *x1, Real *x2, Real *x3) {
- Real u[3];
- Real aa, pp, qq, rr, rc, sc, tc, mt;
- Real w1r, w1i, w2r, w2i, w3r;
- Real v[3], v1, v2, arg, theta;
- Real disc, h;
- int k1 = 0, k2 = 0;
- Real zarr[4];
-
- /* Deal easily with the cases where the quartic is degenerate. The
- * ordering of solutions is done explicitly. */
- if (0 == b && 0 == c)
- {
- if (0 == d)
- {
- if (a > 0)
- {
- *x0 = -a;
- *x1 = 0.0;
- *x2 = 0.0;
- *x3 = 0.0;
- }
- else
- {
- *x0 = 0.0;
- *x1 = 0.0;
- *x2 = 0.0;
- *x3 = -a;
- }
- return 4;
- }
- else if (0 == a)
- {
- if (d > 0)
- {
- return 0;
- }
- else
- {
- *x1 = sqrt (sqrt (-d));
- *x0 = -(*x1);
- return 2;
- }
- }
- }
-
- if (0.0 == c && 0.0 == d)
- {
- *x0=0.0;
- *x1=0.0;
- if( solve_quadratic( 1.0, a, b, x2, x3 ) == 0 ) {
- mt=3;
- } else {
- mt=1;
- }
- }
- else
- {
- /* For non-degenerate solutions, proceed by constructing and
- * solving the resolvent cubic */
- aa = a * a;
- pp = b - (3.0/8.0) * aa;
- qq = c - (1.0/2.0) * a * (b - (1.0/4.0) * aa);
- rr = d - (1.0/4.0) * (a * c - (1.0/4.0) * aa * (b - (3.0/16.0) * aa));
- rc = (1.0/2.0) * pp;
- sc = (1.0/4.0) * ((1.0/4.0) * pp * pp - rr);
- tc = -((1.0/8.0) * qq * (1.0/8.0) * qq);
-
- /* This code solves the resolvent cubic in a convenient fashion
- * for this implementation of the quartic. If there are three real
- * roots, then they are placed directly into u[]. If two are
- * complex, then the real root is put into u[0] and the real
- * and imaginary part of the complex roots are placed into
- * u[1] and u[2], respectively. Additionally, this
- * calculates the discriminant of the cubic and puts it into the
- * variable disc. */
- {
- Real qcub = (rc * rc - 3 * sc);
- Real rcub = (2 * rc * rc * rc - 9 * rc * sc + 27 * tc);
-
- Real Q = qcub / 9;
- Real R = rcub / 54;
-
- Real Q3 = Q * Q * Q;
- Real R2 = R * R;
-
- Real CR2 = 729 * rcub * rcub;
- Real CQ3 = 2916 * qcub * qcub * qcub;
-
- disc = (CR2 - CQ3) / 2125764.0;
-
- if (0 == R && 0 == Q)
- {
- u[0] = -rc / 3;
- u[1] = -rc / 3;
- u[2] = -rc / 3;
- }
- else if (CR2 == CQ3)
- {
- Real sqrtQ = sqrt (Q);
- if (R > 0)
- {
- u[0] = -2 * sqrtQ - rc / 3;
- u[1] = sqrtQ - rc / 3;
- u[2] = sqrtQ - rc / 3;
- }
- else
- {
- u[0] = -sqrtQ - rc / 3;
- u[1] = -sqrtQ - rc / 3;
- u[2] = 2 * sqrtQ - rc / 3;
- }
- }
- else if (CR2 < CQ3)
- {
- Real sqrtQ = sqrt (Q);
- Real sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
- Real theta = acos (R / sqrtQ3);
- if (R / sqrtQ3 >= 1.0) theta = 0.0;
- {
- Real norm = -2 * sqrtQ;
-
- u[0] = norm * cos (theta / 3) - rc / 3;
- u[1] = norm * cos ((theta + 2.0 * M_PI) / 3) - rc / 3;
- u[2] = norm * cos ((theta - 2.0 * M_PI) / 3) - rc / 3;
- }
- }
- else
- {
- Real sgnR = (R >= 0 ? 1 : -1);
- Real modR = fabs (R);
- Real sqrt_disc = sqrt (R2 - Q3);
- Real A = -sgnR * pow (modR + sqrt_disc, 1.0 / 3.0);
- Real B = Q / A;
- Real mod_diffAB = fabs (A - B);
-
- u[0] = A + B - rc / 3;
- u[1] = -0.5 * (A + B) - rc / 3;
- u[2] = -(sqrt (3.0) / 2.0) * mod_diffAB;
- }
- }
- /* End of solution to resolvent cubic */
-
- /* Combine the square roots of the roots of the cubic
- * resolvent appropriately. Also, calculate 'mt' which
- * designates the nature of the roots:
- * mt=1 : 4 real roots (disc == 0)
- * mt=2 : 0 real roots (disc < 0)
- * mt=3 : 2 real roots (disc > 0)
- */
-
- if (0.0 == disc)
- u[2] = u[1];
-
- if (0 >= disc)
- {
- mt = 2;
-
- /* One would think that we could return 0 here and exit,
- * since mt=2. However, this assignment is temporary and
- * changes to mt=1 under certain conditions below.
- */
-
- v[0] = fabs (u[0]);
- v[1] = fabs (u[1]);
- v[2] = fabs (u[2]);
-
- v1 = std::max(std::max(v[0], v[1] ), v[2] );
- /* Work out which two roots have the largest moduli */
- k1 = 0, k2 = 0;
- if (v1 == v[0])
- {
- k1 = 0;
- v2 = std::max( v[1], v[2] );
- }
- else if (v1 == v[1])
- {
- k1 = 1;
- v2 = std::max( v[0], v[2] );
- }
- else
- {
- k1 = 2;
- v2 = std::max( v[0], v[1] );
- }
-
- if (v2 == v[0])
- {
- k2 = 0;
- }
- else if (v2 == v[1])
- {
- k2 = 1;
- }
- else
- {
- k2 = 2;
- }
-
- if (0.0 <= u[k1])
- {
- w1r=sqrt(u[k1]);
- w1i=0.0;
- }
- else
- {
- w1r=0.0;
- w1i=sqrt(-u[k1]);
- }
- if (0.0 <= u[k2])
- {
- w2r=sqrt(u[k2]);
- w2i=0.0;
- }
- else
- {
- w2r=0.0;
- w2i=sqrt(-u[k2]);
- }
- }
- else
- {
- mt = 3;
-
- if (0.0 == u[1] && 0.0 == u[2])
- {
- arg = 0.0;
- }
- else
- {
- arg = sqrt(sqrt(u[1] * u[1] + u[2] * u[2]));
- }
- theta = atan2(u[2], u[1]);
-
- w1r = arg * cos(theta / 2.0);
- w1i = arg * sin(theta / 2.0);
- w2r = w1r;
- w2i = -w1i;
- }
-
- /* Solve the quadratic to obtain the roots to the quartic */
- w3r = qq / 8.0 * (w1i * w2i - w1r * w2r) /
- (w1i * w1i + w1r * w1r) / (w2i * w2i + w2r * w2r);
- h = a / 4.0;
-
- zarr[0] = w1r + w2r + w3r - h;
- zarr[1] = -w1r - w2r + w3r - h;
- zarr[2] = -w1r + w2r - w3r - h;
- zarr[3] = w1r - w2r - w3r - h;
-
- /* Arrange the roots into the variables z0, z1, z2, z3 */
- if (2 == mt)
- {
- if (u[k1] >= 0 && u[k2] >= 0)
- {
- mt = 1;
- *x0 = zarr[0];
- *x1 = zarr[1];
- *x2 = zarr[2];
- *x3 = zarr[3];
- }
- else
- {
- return 0;
- }
- }
- else
- {
- *x0 = zarr[0];
- *x1 = zarr[1];
- }
- }
-
- /* Sort the roots as usual */
- if (1 == mt)
- {
- /* Roots are all real, sort them by the real part */
- if (*x0 > *x1)
- SWAPD (*x0, *x1);
- if (*x0 > *x2)
- SWAPD (*x0, *x2);
- if (*x0 > *x3)
- SWAPD (*x0, *x3);
-
- if (*x1 > *x2)
- SWAPD (*x1, *x2);
- if (*x2 > *x3) {
- SWAPD (*x2, *x3);
- if (*x1 > *x2)
- SWAPD (*x1, *x2);
- }
- return 4;
- }
- else
- {
- /* 2 real roots */
- if (*x0 > *x1)
- SWAPD (*x0, *x1);
- }
-
- return 2;
-}
-
-
-__END_AKANTU__
-
diff --git a/src/model/model_manager.hh b/src/model/model_manager.hh
deleted file mode 100644
index 130a796df..000000000
--- a/src/model/model_manager.hh
+++ /dev/null
@@ -1,1346 +0,0 @@
-/**
- * @file model_manager.hh
- *
- * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date creation: Mon Jan 07 2013
- * @date last modification: Fri Sep 05 2014
- *
- * @brief higher order object that deals with collections of 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_MODEL_MANAGER_HH__
-#define __AKANTU_MODEL_MANAGER_HH__
-
-#include "aka_common.hh"
-#include "mesh.hh"
-#include "model.hh"
-#include "aka_tree.hh"
-#include "solid_mechanics_model.hh"
-#include "aka_plane.hh"
-#include "aka_geometry.hh"
-#include "solid_mechanics_model_element.hh"
-#include "aka_timer.hh"
-
-#include <cstring>
-#include <queue>
-#include <unordered_set>
-#include <array/expr.hpp>
-
-
-
-#define DEBUG_MANAGER 1
-
-
-__BEGIN_AKANTU__
-
-
-typedef array::vector_type<Real> vector_type;
-typedef array::matrix_type<Real> matrix_type;
-using array::transpose;
-
-
-enum Discretization_type { Node_to_node, Node_to_segment };
-
-
-template <class Model_policy>
-class Model_manager {
-
-public:
-
- typedef Model_policy model_type;
- typedef model_type* model_pointer;
- typedef model_type& model_reference;
-
- typedef std::list<model_type*> model_container;
- typedef typename model_container::iterator model_iterator;
- typedef typename model_container::const_iterator const_model_iterator;
-
-protected:
-
- model_container models_; //!< Models
-
-
-public:
-
- //! Default constructor
- Model_manager() : models_() {}
-
- virtual void add_model(model_reference m)
- { models_.push_back(&m); }
-
- virtual void add_model(model_pointer m)
- { models_.push_back(m); }
-
- model_iterator models_begin()
- { return models_.begin(); }
-
- model_iterator models_end()
- { return models_.end(); }
-
- friend std::ostream& operator<<(std::ostream& os, const Model_manager& mm) {
-
- os<<"Model manager info:"<<endl;
- os<<" models: "<<mm.models_.size()<<endl;
- size_t i=0;
- for (const_model_iterator it = mm.models_.begin(); it != mm.models_.end(); ++it) {
- os<<"\tmodel "<<++i<<" memory address: "<<*it<<endl;
- os<<"\tmodel "<<**it<<endl;
- }
-
- return os;
- }
-
-};
-
-
-
-enum Kinematic_type { static_object_t, dynamic_object_t};
-enum Consider_acceleration { Consider_t, Neglect_t };
-
-
-template <Consider_acceleration>
-class Kinematic_traits;
-
-
-
-template<>
-class Kinematic_traits<Consider_t> {
-
-protected:
-
- typedef Real time_type;
-
- // check collision considering acceleration
- // the equation to solve is
- //
- // alpha t^4 + beta t^3 + gamma t^2 + delta t + epsilon = 0
- //
- // where alpha = (a.a)/4, beta = (a.v), gamma = a.s + v.v, delta = 2(s.v),
- // epsilon = s.s - r^2, a = a1-a2, v = v1-v2, s = c1-c2, r = r1-r2
- //
- template <class iterator>
- time_type resolve_time(iterator it1, iterator it2) {
-
- typedef typename iterator::value_type volume_type;
- typedef typename volume_type::point_type point_type;
-
- const point_type& v1 = it1->velocity_;
- const point_type& v2 = it2->velocity_;
-
- point_type a1 = it1->acceleration_;
- point_type a2 = it2->acceleration_;
-
- Real r = it1->radius() + it2->radius();
- point_type s = it2->center() - it1->center();
- point_type v = v2 - v1;
- point_type a = a2 - a1;
-
- // get coefficients
- Real alpha = (a*a)/4;
- Real beta = a*v;
- Real gamma = a*s + v*v;
- Real delta = 2*(s*v);
- Real epsilon = s*s - r*r;
-
- // obtain roots from quartic equation by calling the function such that
- // the coefficient for the quartic term is equal to one
- std::vector<Real> x(4, inf);
-
-
- uint32_t roots = solve_quartic(beta/alpha, gamma/alpha, delta/alpha, epsilon/alpha,
- &x[0], &x[1], &x[2], &x[3]);
-
- Real tmin = inf;
-
- // if there are roots, take the first one as an indication of the collision
- if (roots > 0) {
-
- for (size_t i=0; i<x.size(); ++i)
- tmin = std::min(tmin, x[i]);
-
- if (tmin > 0) {
-#ifdef DEBUG_MANAGER
- cout<<" Solve quartic with coefficients ";
- cout<<(beta/alpha)<<", "<<(gamma/alpha)<<", "<<(delta/alpha)<<", "<<(epsilon/alpha)<<endl;
- cout<<" Approximate collision time -> tmin = "<<tmin<<" = "<<(tmin)<<endl;
- cout<<" Roots:";
- for (size_t i=0; i<x.size(); ++i)
- cout<<" "<<x[i];
- cout<<endl;
-#endif
- for (size_t i=0; i<x.size(); ++i)
- tmin = std::min(tmin, x[i]);
-
- }
- } // if roots
- return tmin > 0 ? tmin : inf;
- }
-
-private:
-
- /*! \brief Solve quartic equation x^4 + a*x^3 + b*x^2 + c*x + d = 0.
- *
- * Solves the quartic equation. Returns the number of roots
- * found. Roots are filled in ascending order.
- * Code taken from the Ion Beam Simulator, which is distrubuted under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
- uint32_t solve_quartic(Real a, Real b, Real c, Real d,
- Real *x0, Real *x1, Real *x2, Real *x3 );
-
-};
-
-
-
-template<>
-class Kinematic_traits<Neglect_t> {
-
-protected:
-
- typedef Real time_type;
-
- // check collision neglecting acceleration
- template <class iterator>
- time_type resolve_time(iterator it1, iterator it2) {
-
- typedef typename iterator::value_type volume_type;
- typedef typename volume_type::point_type point_type;
- typedef typename point_type::value_type value_type;
-
- const volume_type& s1 = *it1;
- const volume_type& s2 = *it2;
-
- const point_type& v1 = s1.velocity_;
- const point_type& v2 = s2.velocity_;
-
- // vector between spheress
- point_type s = s2.center() - s1.center();
- // relative motion of s1 with respect to stationary s0
- point_type v = v2 - v1;
- // sum of radii
- value_type r = s1.radius() + s2.radius();
- value_type c = s*s - r*r;
-
-#ifdef DEBUG_MANAGER
- cout<<"Checking collisiong between:"<<endl;
- cout<<" "<<s1<<", velocity: "<<v1<<endl;
- cout<<" "<<s2<<", velocity: "<<v2<<endl;
- cout<<" Relative velocity: "<<v<<endl;
-#endif
-
- value_type epsilon = 1e-8;
-
- // already intersecting
- if (c < -epsilon) {
-
-#ifdef DEBUG_MANAGER
- cout<<" Intersecting bounding volumes"<<endl;
-#endif
- // should not get to this point
- return time_type();
- }
-
- value_type a = v*v;
- // if spheres not moving relative to each other
- if (a < epsilon) {
-#ifdef DEBUG_MANAGER
- cout<<" Objects not moving relative to each other"<<endl;
- cout<<" a: "<<a<<endl;
-#endif
- return inf;
- }
-
- value_type b = v*s;
- // if spheres not moving towards each other
- if (b >= 0.) {
-#ifdef DEBUG_MANAGER
- cout<<" Objects not moving towards each other"<<endl;
- cout<<" b: "<<b<<endl;
-#endif
- return inf;
- }
-
- value_type d = b*b - a*c;
- // if no real-valued root (d < 0), spheres do not intersect
- // otherwise add time to timer
- if (d >= 0.) {
- time_type ts = (-b - sqrt(d))/a;
- if (ts > -epsilon) {
-#ifdef DEBUG_MANAGER
- cout<<" Objects intersects at time "<<(ts)<<endl;
-#endif
- return ts;
- }
-#ifdef DEBUG_MANAGER
- else {
- cout<<" ts negative: "<<ts<<endl;
- }
-#endif
-
- }
-#ifdef DEBUG_MANAGER
- else {
- cout<<" Objects do not intersect"<<endl;
- cout<<" discriminant: "<<d<<endl;
- }
-#endif
-
- return inf;
- }
-};
-
-
-
-template <class VolumeType, class DataPolicy, template <class> class CostPolicy = Cost_functor>
-class DataTree :
-public Tree<VolumeType, CostPolicy> {
-
-public:
-
- typedef DataPolicy data_type;
- typedef VolumeType volume_type;
- typedef CostPolicy<volume_type> cost_functor;
- typedef Tree<volume_type, CostPolicy> tree_type;
- typedef typename tree_type::iterator tree_iterator;
- typedef typename tree_type::const_iterator const_tree_iterator;
-
- // leaf information
- typedef std::map<tree_iterator, data_type> leaves_data;
- typedef typename leaves_data::iterator leaves_data_iterator;
-
- bool add_data(tree_iterator it, data_type& data) {
- auto i = data_.insert(std::make_pair(it, data));
- return i.second;
- }
-
- leaves_data_iterator leaves_data_begin()
- { return data_.begin(); }
-
- leaves_data_iterator leaves_data_end()
- { return data_.end(); }
-
- leaves_data_iterator find_data(tree_iterator it)
- { return data_.find(it); }
-
-private:
-
- leaves_data data_;
-
-};
-
-template <class U, class T>
-std::pair<U, T> minmax(const U& u, const T& t) {
- return u < t ? std::make_pair(u,t) : std::make_pair(t,u);
-}
-
-template <Discretization_type, class, class>
-class ContactElement;
-
-
-template <class point_type, class element_type>
-class ContactElement<Node_to_node, point_type, element_type> {
-
-public:
-
- typedef Real time_type;
- typedef typename vector_type::value_type value_type;
- typedef std::tuple<time_type, point_type> impact_tuple;
- typedef typename element_type::model_type model_type;
-
- struct Comparator {
-
- bool operator()(const ContactElement *c1, const ContactElement *c2) const {
-
- auto p1 = minmax(c1->el1_, c1->el2_);
- auto p2 = minmax(c2->el1_, c2->el2_);
-
- if (p1.first < p2.first || p1.second < p2.second)
- return true;
-
- auto i1 = minmax(c1->id1_, c1->id2_);
- auto i2 = minmax(c2->id1_, c2->id2_);
-
- if (i1.first < i2.first || i1.second < i2.second)
- return true;
-
- return false;
- }
- };
-
- typedef Comparator comparator_type;
-
- //! Parameter constructor
- template <class parameter_type>
- ContactElement(const parameter_type& p) :
- id1_(std::get<0>(p)), id2_(std::get<1>(p)),
- el1_(std::get<2>(p)), el2_(std::get<3>(p)),
- impact_(std::get<4>(p)), m1_(), m2_(), linked_(), release_(true) {}
-
-
- //! Resolve impact
- /*! At the moment of impact, obtain velocities after impact from
- * contacting nodes, and join masses (nodes behave as one)
- */
- void resolve_impact(time_type t, time_type Dt) {
-
- // if at moment of impact
- if (equal(t, std::get<0>(impact_)) && !linked_) {
-
-
-#ifdef DEBUG_MANAGER
- cout<<"Linking nodes"<<endl;
-#endif
-
- // get models
- model_type &model1 = el1_->model();
- model_type &model2 = el2_->model();
-
- // get global node ids
- UInt n1 = el1_->node(id1_);
- UInt n2 = el2_->node(id2_);
-
- // get references to mass and velocity vectors
- Array<Real> &mass1 = model1.getMass();
- Array<Real> &mass2 = model2.getMass();
- Array<Real> &velocity1 = model1.getVelocity();
- Array<Real> &velocity2 = model2.getVelocity();
-
- // get references to masses and velocities involved in the collision
- Real &m1 = mass1(n1);
- Real &m2 = mass2(n2);
- value_type &v1 = velocity1(n1);
- value_type &v2 = velocity2(n2);
-
- // set correct velocity
- Real vc = (m1*v1 + m2*v2) / (m1+m2);
- velocity1(n1) = vc;
- velocity2(n2) = vc;
-
- // save mass values and add masses to treat them as a single node
- m1_ = m1;
- m2_ = m2;
- mass1(n1) += m2_;
- mass2(n2) += m1_;
-
- // set link flag
- linked_ = true;
- }
- }
-
- //! Treat linked nodes
- /*! During the time that the nodes are in contact, treat them as a single
- * node of joint mass and synchronize residual values
- */
- bool resolve(time_type t, time_type Dt) {
-
- // get models
- model_type &model1 = el1_->model();
- model_type &model2 = el2_->model();
-
- // get global node ids
- UInt n1 = el1_->node(id1_);
- UInt n2 = el2_->node(id2_);
-
- // get references to residual vectors
- Array<Real> & r1 = model1.getResidual();
- Array<Real> & r2 = model2.getResidual();
-
- // check condition for delinking of nodes
- vector_type vec = el2_->barycenter() - el1_->barycenter();
-
- if (std::signbit(vec[0]) != std::signbit(r1(n1))) {
-
-#ifdef DEBUG_MANAGER
- cout<<"Unlinking nodes"<<endl;
-#endif
-
- if (release_) {
-
- // get masses
- Array<Real> &mass1 = model1.getMass();
- Array<Real> &mass2 = model2.getMass();
-
- mass1(id1_) = m1_;
- mass2(id2_) = m2_;
-
- release_ = false;
- return true;
- }
- }
-
- // synchronize if necessary
- if (linked_ && release_) {
- Real tmp = r1(n1);
-
- r1(n1) += r2(n2);
- r2(n2) += tmp;
- }
- return false;
- }
-
- friend std::ostream& operator<<(std::ostream& os, const ContactElement& ce) {
- cout<<"Contact element info:\n linking elements ("<<ce.el1_<<" - "<<ce.el2_<<")"<<endl;
- cout<<" colliding nodes ("<<ce.id1_<<" - "<<ce.id2_<<")"<<endl;
- cout<<" first impact at location "<<std::get<1>(ce.impact_)<<" at time "<<std::get<0>(ce.impact_)<<endl;
- if (ce.m1_ > 0. && ce.m2_ > 0)
- cout<<" saved masses: ("<<ce.m1_<<","<<ce.m2_<<")"<<endl;
- if (ce.linked_)
- cout<<" linked state (treating contacting nodes as a single node)"<<endl;
-
- return os;
- }
-
-private:
- size_t id1_, id2_; //!< Ids of element nodes involved in the collision
- element_type *el1_, *el2_; //!< Pointers to elements involved in teh collision
- impact_tuple impact_; //!< Impact information, tuple containing the time and point of contact
-
- value_type m1_, m2_; //!< Mass values stored after linking of the nodes
- bool linked_, release_; //!< Flags used to specify the state of the linking
-};
-
-
-template <class Bounding_policy, Discretization_type DT, Consider_acceleration accel = Consider_t, template <class> class Cost_policy = Cost_functor>
-class Contact_model_manager : public Model_manager<SolidMechanicsModel>, public Kinematic_traits<accel> {
-
-
- using Kinematic_traits<accel>::resolve_time;
-
- typedef ctimer chronograph_type;
-
- // model type
- typedef SolidMechanicsModel model_type;
- typedef model_type* model_pointer;
- typedef model_type& model_reference;
-
- // geometric types
- typedef Bounding_policy volume_type;
- typedef typename volume_type::point_type point_type;
- typedef typename point_type::value_type value_type;
- typedef typename volume_type::aabb_type aabb_type;
-
- // element type
- typedef ModelElement<model_type> element_type;
- typedef ContactElement<DT, point_type, element_type> contact_element_type;
- typedef std::set<contact_element_type*, typename contact_element_type::comparator_type > contact_element_container;
- typedef typename contact_element_container::iterator contact_element_iterator;
- typedef typename contact_element_type::time_type time_type;
- typedef typename contact_element_type::impact_tuple impact_tuple;
-
- // Bounding volume hierarchy related types
- typedef Cost_policy<volume_type> cost_functor;
- typedef DataTree<volume_type, element_type, Cost_policy > tree_type;
- typedef typename tree_type::leaves_data_iterator leaves_data_iterator;
- typedef typename tree_type::leaf_iterator tree_leaf_iterator;
- typedef typename tree_type::iterator tree_iterator;
- typedef typename tree_type::const_iterator const_tree_iterator;
- typedef std::list<tree_type*> forest_container;
- typedef typename forest_container::iterator forest_iterator;
- typedef typename forest_container::const_iterator const_forest_iterator;
-
- // kinematic types
- typedef point_type velocity_type;
- typedef std::list<velocity_type> velocity_container;
- typedef typename velocity_container::iterator velocity_iterator;
-
- typedef unsigned long mask_size;
-
- // timer type
- typedef std::priority_queue<time_type, std::vector<time_type>, std::greater<time_type> > timer_type;
-
- // tuple type
- typedef std::tuple<time_type, tree_iterator, tree_iterator> tuple_type;
-
- struct Tuple_compare {
- bool operator()(const tuple_type& t1, const tuple_type& t2) const
- { return std::get<0>(t1) > std::get<0>(t2); }
- };
-
- typedef typename std::priority_queue<tuple_type, std::vector<tuple_type>, Tuple_compare> hierarchy_timer;
-
-
- //! Structure used to do a postorder update of tree hierarchies
- struct Updater {
-
- tree_type &t_; //!< Reference to hierarchy
-
- Updater(tree_type& t) : t_(t) {}
-
- void operator()(tree_iterator it) {
- if (!it.is_leaf()) {
- volume_type& v = *it;
- volume_type& lv = *it.left();
- volume_type& rv = *it.right();
- v = lv + rv;
- assert(lv.last_time_ == rv.last_time_);
- v.last_time_ = lv.last_time_;
- v.velocity_ = 0.5 * (lv.velocity_ + rv.velocity_);
- v.acceleration_ = 0.5 * (lv.acceleration_ + rv.acceleration_);
- }
- }
- };
-
- struct Printer {
- void operator()(tree_iterator it)
- { cout<<*it<<", "; }
- };
-
- class Time_exception : public std::exception {
- virtual const char* what() const throw()
- { return "*** EXCEPTION *** Zero time increment."; }
- };
-
- struct Continuator : public std::exception {
-
- tuple_type best_;
-
- Continuator(const tuple_type& b) : best_(b) {}
-
- virtual const char* what() const throw()
- { return "*** EXCEPTION *** Continue."; }
- };
-
- struct Contactor : public std::exception {
-
- impact_tuple data_;
-
- Contactor(const impact_tuple& c) : data_(c) {}
-
- virtual const char* what() const throw()
- { return "*** EXCEPTION *** Contact."; }
- };
-
- template <bool flag>
- struct Bool2Type {
- enum { value = flag };
- };
-
-private:
-
- forest_container forest_; //!< Bounding volume hierarchies
- hierarchy_timer timer_; //!< Priority queue of times
- mask_size masks_; //!< Variable used for static objects
- tree_iterator null_;
- time_type last_; //!< Keep time of last detection engine reset
- contact_element_container celems_; //!< Contact elements
-
-public:
-
- //! Default constructor
- Contact_model_manager()
- : Model_manager(), forest_(), timer_(), masks_(), null_(tree_iterator(nullptr)), last_() {}
-
- //! Destructor
- ~Contact_model_manager() {
-
- // delete trees
- for (forest_iterator it = forest_.begin(); it != forest_.end(); ++it)
- delete *it;
-
- // delete contact element
- for (contact_element_iterator it = celems_.begin(); it != celems_.end(); ++it)
- delete *it;
- }
-
- virtual void add_model(model_pointer m, Kinematic_type k = dynamic_object_t) {
-
- m->initializeUpdateResidualData();
- models_.push_back(m);
-
- if (models_.size() > 8*sizeof(mask_size)) {
- cout<<"*** ERROR *** Type used for masks is too small to handle all models."<<endl;
- cout<<"Aborting..."<<endl;
- exit(1);
- }
-
- // create tree
- tree_type* tp = construct_tree_bottom_up<tree_type, model_type, element_type>(*m);
- forest_.push_back(tp);
-
-
-#ifdef DEBUG_MANAGER
- cout<<"tree "<<*tp<<endl;
-// print_mathematica(*tp);
-#endif
-
- // mask model as dynamic or static
- masks_ |= (k << (models_.size()-1));
- }
-
-
- void update_forest(time_type t) {
-
- int k = 0;
- for (forest_iterator fit = forest_.begin(); fit != forest_.end(); ++fit) {
-
- // check if the object is dynamic to update
- if (!(masks_ & (1 << k++)))
- continue;
-
- // loop over leaves
- for (leaves_data_iterator lit = (*fit)->leaves_data_begin();
- lit != (*fit)->leaves_data_end(); ++lit) {
-
- Real t_old = lit->first->last_time_;
-
- std::vector<const Real*> c = lit->second.coordinates();
- volume_type v = Volume_creator<volume_type>::create(c);
-
- // get positions
- const point_type& p0 = lit->first->center();
- const point_type& p1 = v.center();
-
- // get velocities
- const point_type& v0 = lit->first->velocity_;
- const point_type& v1 = v.velocity_;
-
- // new velocity and acceleration
- v.velocity_ = 1/(t - t_old) * (p1-p0);
- v.acceleration_ = 1/(t - t_old) * (v1-v0);
-
- v.last_time_ = t;
-
- // set new volume
- *lit->first = v;
- }
-
- tree_type &t = **fit;
- Updater u(t);
- postorder(t.root(),u);
- }
- }
-
-
- void reset() {
-
- // clear queue
- while (!timer_.empty())
- timer_.pop();
-
- timer_.push(std::make_tuple(last_, null_, null_));
- timer_.push(std::make_tuple(inf, null_, null_));
- }
-
- void resolve(time_type t, time_type Dt) {
-
- // loop over contact elements
- contact_element_iterator elit = celems_.begin();
- while (elit != celems_.end()) {
-
- cout<<**elit<<endl;
- if ((*elit)->resolve(t, Dt)) {
- celems_.erase(elit++);
-
- last_ = t + Dt;
-
- } else
- ++elit;
- }
- }
-
-
- template <class queue_type>
- void print_queue(queue_type copy) {
-
- cout<<"Printing queue values:";
- while (!copy.empty()) {
- const tuple_type& tuple = copy.top();
- cout<<" "<<std::get<0>(tuple);
- copy.pop();
- }
- cout<<endl;
- }
-
-
-
- /*! \param t - Current elapsed time
- * \param Dt - Time step
- */
- void intersect(time_type t, time_type& Dt) {
-
-#ifdef DEBUG_MANAGER
- cout<<"t = "<<t<<", Dt = "<<Dt<<", timer:";
-
- hierarchy_timer copy = timer_;
- while (!copy.empty()) {
- const tuple_type& tuple = copy.top();
- cout<<" "<<std::get<0>(tuple);
- copy.pop();
- }
- cout<<endl;
-
-#endif
-
- static time_type Dt1 = Dt;
-
- // reset if first enter the function
- if (t == last_ || t == Dt1) {
- Dt = Dt1;
- reset();
- }
-
- const tuple_type& tuple = timer_.top();
- time_type top = std::get<0>(tuple);
-
- // update hierarchies and get positions
- // note that the updating starts before the next intetersection check
- if (models_.size() > 1 && top <= t + 3*Dt1) {
- update_forest(t);
-#ifdef DEBUG_MANAGER
- cout<<"Updating forest"<<endl;
-#endif
- }
-
- // check if detection is shut off
- if (t + Dt < top)
- return;
-
- // get iterators from priority element
- tree_iterator it1 = std::get<1>(tuple);
- tree_iterator it2 = std::get<2>(tuple);
-
- // remove time from timer
- timer_.pop();
-
- // check for intersection becase:
- // 1. there are enough models
- // 2. intersection happens before the next increment
- if (models_.size() > 1 && top <= t + Dt1) {
-
- // if first step, add next time to timer and return because there
- // is not enough information for the computation of intersection times
- if (t <= last_ + (accel == Consider_t ? 2 : 1)*Dt) {
- // remove time from timer
- timer_.push(std::make_tuple(t, null_, null_));
-#ifdef DEBUG_MANAGER
- cout<<"Early out"<<endl;
-#endif
- return;
- }
-
- // check if iterators are null to compute O(n^2) collision times
- if (it1 == null_ || it2 == null_) {
-
- // do O(n^2) operation to obtain next time of intersections
- for (forest_iterator it1 = forest_.begin(); it1 != --forest_.end(); ++it1) {
-
- forest_iterator it2 = it1;
- for (++it2; it2 != forest_.end(); ++it2) {
-
- // get collision time
-#ifdef DEBUG_MANAGER
- cout<<"Calling check_collision in O(n^2) branch"<<endl;
-#endif
- time_type tstar = resolve_time((*it1)->root(), (*it2)->root());
- if (tstar != inf)
- timer_.push(std::make_tuple(t+tstar, (*it1)->root(), (*it2)->root()));
-#ifdef DEBUG_MANAGER
- else
- cout<<"*** INFO *** Objects do not intersect:\n "<<*(*it1)->root()<<"\n "<<*(*it2)->root()<<endl;
-#endif
- } // inner hierarchy loop
- } // outer hierarchy loop
-
- }
-
- // else use collision information previously computed (avoids O(n^2) operation above)
- else {
-
-#ifdef DEBUG_MANAGER
- cout<<"Calling check_collision in non-O(n^2) branch"<<endl;
-#endif
-
- // temporary queue for tree traversal
- hierarchy_timer pq;
- pq.push(std::make_tuple(top, it1, it2));
-
- try {
-
- // enter infinite loop
- while (true) {
-
-#ifdef DEBUG_MANAGER
- cout<<"______________________________________________"<<endl;
- print_queue(pq);
-#endif
-
- const tuple_type& tuple = pq.top();
-
- time_type tstar = std::get<0>(tuple);
- tree_iterator left = std::get<1>(tuple);
- tree_iterator right = std::get<2>(tuple);
-
-#ifdef DEBUG_MANAGER
- cout<<"Queue time "<<tstar<<", items: "<<*left<<", "<<*right<<endl;
-#endif
-
- pq.pop();
-
- check_collision(t, left, right, pq);
-
- } // infinite loop
-
- }
- catch (Continuator& e) {
-
- tuple_type& best = e.best_;
- time_type& best_time = std::get<0>(best);
- Dt = best_time;
- best_time += t;
-
- // clean hierarchy timer until best time
- while (std::get<0>(timer_.top()) <= best_time)
- timer_.pop();
-
- timer_.push(best);
- timer_.push(best);
-
- try {
- // set time step if required
- cout<<"calling set_time_set in Continuator"<<endl;
-
- set_time_step(t, Dt, Dt1);
- } catch (Time_exception& e) {
- cout<<"catching inner Time_exception"<<endl;
-
- }
-
-
- }
- catch (Contactor& c) {
-
- // get collision impact
- Dt = std::get<0>(c.data_);
-
- try {
-
- cout<<"calling set_time_set in Contactor"<<endl;
-
- // set time step if required
- set_time_step(t, Dt, Dt1);
- // last_ = t + Dt;
-
- } catch (Time_exception& e) {
- // if too small a time step, do nothing, next time step
- // will carry out DCR
-
- cout<<"catching outter Time_exception"<<endl;
-
- // last_ = t + Dt;
-
- Dt = Dt1;
- }
- cout<<"last -> "<<last_<<endl;
- }
- }
-
- } // if statement on enough models
- // else do nothing as there are not enough models to carry out intersection
- // or the check engine is shut down until the next time in timer
-
-
- // resolve collision if necessary
- for (contact_element_iterator elit = celems_.begin(); elit != celems_.end(); ++elit)
- (*elit)->resolve_impact(t, Dt);
-
-
- }
-
-
-private:
-
- void set_time_step(time_type t, time_type& Dt, time_type Dt1) {
-
- if (Dt > Dt1)
- Dt = Dt1;
-
- if (Dt < 1e-10) {
- cout<<"*** INFO *** New time step is too small. Throwing exception..."<<endl;
- throw Time_exception();
- }
-#ifdef DEBUG_MANAGER
- cout<<" Leaves found that collide at time "<<(t + Dt)<<endl;
- cout<<" Setting new time step: "<<Dt<<endl;
-#endif
- for (model_iterator mit = models_.begin(); mit != models_.end(); ++mit)
- (*mit)->setTimeStep(Dt);
- }
-
- // check time of collision between points
- impact_tuple check_points(time_type t, leaves_data_iterator it1, leaves_data_iterator it2) {
-
- const volume_type& v1 = *it1->first;
- const volume_type& v2 = *it2->first;
-
- std::vector<const Real*> c1 = it1->second.coordinates();
- std::vector<const Real*> c2 = it2->second.coordinates();
-
- // compute intersection
- volume_type vint = v1 && v2;
-
- // get indices of colliding nodes
- size_t ii=0, jj=0;
- for (size_t i=1; i<c1.size(); ++i) {
-
- if (vint & point_type(c1[i]))
- ii = i;
- if (vint & point_type(c2[i]))
- jj = i;
- }
-
- impact_tuple impact =
- moving_point_against_point(point_type(c1[ii]), point_type(c2[jj]), it1->first->velocity_, it2->first->velocity_);
-
- time_type &timpact = std::get<0>(impact);
- timpact += t;
-
- celems_.insert(new contact_element_type(std::make_tuple(ii, jj, &it1->second, &it2->second, impact)));
-
- return impact;
-
- }
-
- // check time of collision between 2D segments
- impact_tuple check_2D_sides(time_type t, leaves_data_iterator it1, leaves_data_iterator it2) {
-
- typedef Point<3> test_point;
-
-
- const volume_type& v1 = *it1->first;
- const volume_type& v2 = *it2->first;
-
- std::vector<const Real*> c1 = it1->second.coordinates();
- std::vector<const Real*> c2 = it2->second.coordinates();
-
- // create plane from second container node
- // THIS WON'T WORK, SIDES HAVE ONLY TWO NODES, CONTINUE DEVELOPING FROM HERE
- assert(c2.size() == 3);
-
- // form plane from three points
- test_point o,p,q;
-
- for (size_t j=0; j<point_type::dim(); ++j) {
- o[j] = c2[0][j];
- p[j] = c2[1][j];
- q[j] = c2[2][j];
- }
-
-// point_type o(c2[0]);
-// point_type p(c2[1]);
-// point_type q(c2[2]);
-
- Plane pi(o,p,q);
-
- // loop over the nodes of the container
- for (size_t i=0; i<c1.size(); ++i) {
-
- test_point v;
- point_type v2d = v1.velocity_ - v2.velocity_;
-
- // create 3D point, used to check for plane intersection
- test_point x;
- for (size_t j=0; j<point_type::dim(); ++j) {
- x[j] = c1[i][j];
- v[j] = v2d[j];
- }
-
- cout<<"x -> "<<x<<endl;
-
- cout<<"v -> "<<v<<endl;
-
-
- std::tuple<time_type, test_point> impact =
- moving_point_against_plane(x, v, pi);
-
-
-
- }
-
- exit(1);
-
-//// impact_tuple impact =
-//// moving_point_against_point(point_type(c1[ii]), point_type(c2[jj]), it1->first->velocity_, it2->first->velocity_);
-////
-//// time_type &timpact = std::get<0>(impact);
-//// timpact += t;
-////
-//// celems_.insert(new contact_element_type(std::make_tuple(ii, jj, &it1->second, &it2->second, impact)));
-////
-// return impact;
-
- }
-
-
- // check time of collision between triangles
- impact_tuple check_triangles(leaves_data_iterator it1, leaves_data_iterator it2) {
-
- std::vector<const Real*> c1 = it1->second.coordinates();
- std::vector<const Real*> c2 = it2->second.coordinates();
-
- assert(c1.size() == 3);
- assert(c1.size() == c2.size());
- impact_tuple min = std::make_tuple(inf,point_type());
-
- for (size_t i=0; i<c1.size(); ++i) {
-
- point_type r(c1[i]);
-
- // form plane from three points
- point_type o(c2[0]);
- point_type p(c2[1]);
- point_type q(c2[2]);
-
- Plane pi(o,p,q);
-
- // relative velocity
- point_type v = it1->first->velocity_ - it2->first->velocity_;
-
- // intersect point r with velocity v with plane pi
- // the function returns collision time and point of contact
- impact_tuple impact = moving_point_against_plane(r, v, pi);
-
- // make sure intersection point lies within the triangle
- if (is_point_in_triangle(std::get<1>(impact), o, p, q))
- if (std::get<0>(impact) < std::get<0>(min))
- min = impact;
- }
- return min;
- }
-
- impact_tuple fine_collision_time(time_type t, leaves_data_iterator it1, leaves_data_iterator it2, Int2Type<1>) {
-
- // check nodes of first segment against second segment
- return check_points(t, it1, it2);
- }
-
- impact_tuple fine_collision_time(time_type t, leaves_data_iterator it1, leaves_data_iterator it2, Int2Type<2>) {
-
- // check sides of the colliding elements
- return check_2D_sides(t, it1, it2);
- }
-
- impact_tuple fine_collision_time(time_type t, leaves_data_iterator it1, leaves_data_iterator it2, Int2Type<3>) {
-
- // check nodes of first triangle against second triangle
- impact_tuple impact1 = check_triangles(it1, it2);
- impact_tuple impact2 = check_triangles(it2, it1);
-
- // check nodes of second triangle against first triangle
- return std::get<0>(impact1) < std::get<0>(impact2) ? impact1 : impact2;
- }
-
- template <class iterator>
- void traverse_right(iterator it1, iterator it2, hierarchy_timer& pq) {
-
-#ifdef DEBUG_MANAGER
- cout<<" traversing right hierarchy"<<endl;
-#endif
-
- iterator lit = it2.left();
- iterator rit = it2.right();
- assert(lit != null_);
- assert(rit != null_);
-
- time_type tstar1 = resolve_time(it1, lit);
- if (tstar1 != inf) {
-#ifdef DEBUG_MANAGER
- cout<<" Adding queue time "<<tstar1<<endl;
-#endif
- pq.push(std::make_tuple(tstar1, it1, lit));
- }
- time_type tstar2 = resolve_time(it1, rit);
- if (tstar2 != inf) {
-#ifdef DEBUG_MANAGER
- cout<<" Adding queue time "<<tstar2<<endl;
-#endif
- pq.push(std::make_tuple(tstar2, it1, rit));
- }
- }
-
- template <class iterator>
- void traverse_left(iterator it1, iterator it2, hierarchy_timer& pq) {
-
-#ifdef DEBUG_MANAGER
- cout<<" traversing left hierarchy"<<endl;
-#endif
-
- iterator lit = it1.left();
- iterator rit = it1.right();
- assert(lit != null_);
- assert(rit != null_);
-
- time_type tstar1 = resolve_time(lit, it2);
- if (tstar1 != inf) {
-#ifdef DEBUG_MANAGER
- cout<<" Adding queue time "<<tstar1<<endl;
-#endif
- pq.push(std::make_tuple(tstar1, lit, it2));
- }
- time_type tstar2 = resolve_time(rit, it2);
- if (tstar2 != inf) {
-#ifdef DEBUG_MANAGER
- cout<<" Adding queue time "<<tstar2<<endl;
-#endif
- pq.push(std::make_tuple(tstar2, rit, it2));
- }
- }
-
-
- template <class iterator>
- void check_collision(time_type t, iterator it1, iterator it2, hierarchy_timer& pq) {
-
- // if volumes are leaves, change the timer and time step
- if (it1.is_leaf() && it2.is_leaf()) {
-
- cout<<"*** FOUND LEAVES ***"<<endl;
-
- // case where objects intersect
- if (*it1 & *it2) {
-
- cout<<"*** BOUNDING SPHERE INTERSECTION ***"<<endl;
-
- // add leaves to carry out penetration tests
- leaves_data_iterator lit1(nullptr), lit2(nullptr);
-
- for (forest_iterator it = forest_.begin(); it != forest_.end(); ++it) {
-
- leaves_data_iterator lit = (*it)->find_data(it1);
- if (lit != (*it)->leaves_data_end())
- lit1 = lit;
-
- lit = (*it)->find_data(it2);
- if (lit != (*it)->leaves_data_end())
- lit2 = lit;
-
- }
-
- assert (lit1 != leaves_data_iterator(nullptr));
- assert (lit2 != leaves_data_iterator(nullptr));
-
- // determine collision time at the lowest level of detection
- impact_tuple impact = fine_collision_time(t, lit1, lit2, Int2Type<volume_type::dim()>());
-
-#ifdef DEBUG_MANAGER
- cout<<" Fine intersection time: "<<std::get<0>(impact)<<endl;
-#endif
- throw Contactor(impact);
- }
- else
- cout<<"*** NO INTERSECTION BETWEEN BOUNDING SPHERES ***"<<endl;
-
-
- time_type tstar = resolve_time(it1, it2);
-
-#ifdef DEBUG_MANAGER
-
- if (tstar == inf)
- cout<<" Leaves found that DO NOT collide"<<endl;
- else {
- cout<<" Leaves found that collide at time "<<(tstar)<<endl;
- cout<<" Modifying timer and time step..."<<endl;
- }
-#endif
-
- if (tstar == inf) {
- cout<<" Leaves found that DO NOT collide"<<endl;
- return;
- }
- throw Continuator(std::make_tuple(tstar, it1, it2));
- }
-
- // found left leaf, traverse right hierarchy
- else if (it1.is_leaf() && !it2.is_leaf()) {
-
-#ifdef DEBUG_MANAGER
- cout<<" s1 is leaf"<<endl;
-#endif
- traverse_right(it1, it2, pq);
- }
-
- // found right leaf, traverse left hierarchy
- else if (!it1.is_leaf() && it2.is_leaf()) {
-
-#ifdef DEBUG_MANAGER
- cout<<" s2 is leaf"<<endl;
-#endif
- traverse_left(it1, it2, pq);
- }
-
- // else non-leaf case found, check volume sizes
- else {
-
- value_type m1 = it1->measure();
- value_type m2 = it2->measure();
-
- // volumes are equal to numerical error, traverse both hierarchies
- if (equal(m1, m2)) {
-
-#ifdef DEBUG_MANAGER
- cout<<" "<<m1<<" == "<<m2<<endl;
-#endif
- traverse_right(it1, it2, pq);
- traverse_left(it1, it2, pq);
- }
- // left volume is bigger, traverse right hierarchy
- else if (m1 > m2) {
-
-#ifdef DEBUG_MANAGER
- cout<<" "<<m1<<" > "<<m2<<endl;
-#endif
- traverse_left(it1, it2, pq);
- }
- // right volume is bigger, traverse left hierarchy
- else if (m1 < m2) {
-
-#ifdef DEBUG_MANAGER
- cout<<" "<<m1<<" < "<<m2<<endl;
-#endif
- traverse_right(it1, it2, pq);
- }
- } // non-leaf case
- }
-
-
- friend std::ostream& operator<<(std::ostream& os, const Contact_model_manager& mm) {
-
- os<<"Contact model manager info:"<<endl;
- os<<" models: "<<mm.models_.size()<<endl;
- size_t i=0;
- const_forest_iterator tit = mm.forest_.begin();
- for (const_model_iterator it = mm.models_.begin(); it != mm.models_.end(); ++it) {
- os<<"\tmodel "<<++i<<" memory address: "<<*it<<endl;
- os<<"\tmodel: "<<**it<<endl;
- os<<"\ttree: ";
- print_mathematica(**tit++);
- }
- return os;
- }
-};
-
-__END_AKANTU__
-
-#endif /* __AKANTU_MODEL_MANAGER_HH__ */
diff --git a/src/model/solid_mechanics/embedded_interface_intersector.cc b/src/model/solid_mechanics/embedded_interface_intersector.cc
deleted file mode 100644
index 39328d243..000000000
--- a/src/model/solid_mechanics/embedded_interface_intersector.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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() {
- 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));
- 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/embedded_interface_intersector.hh b/src/model/solid_mechanics/embedded_interface_intersector.hh
deleted file mode 100644
index 4917f90ff..000000000
--- a/src/model/solid_mechanics/embedded_interface_intersector.hh
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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();
-
- /// 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/embedded_interface_model.cc b/src/model/solid_mechanics/embedded_interface_model.cc
deleted file mode 100644
index 3a69618b7..000000000
--- a/src/model/solid_mechanics/embedded_interface_model.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-/**
- * @file embedded_interface_model.cc
- *
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
- *
- * @date creation: Mon Mar 9 2015
- * @date last modification: Mon Mar 9 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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(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(field_name,kind);
- else if (mat != NULL && field_name == "stress_embedded")
- return mat->getInternalDataPerElem(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/embedded_interface_model.hh b/src/model/solid_mechanics/embedded_interface_model.hh
deleted file mode 100644
index 9dc01fc75..000000000
--- a/src/model/solid_mechanics/embedded_interface_model.hh
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * @file embedded_interface_model.hh
- *
- * @author Lucas Frérot <lucas.frerot@epfl.ch>
- *
- * @date creation: Mon Mar 9 2015
- * @date last modification: Mon Mar 9 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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/fragment_manager.cc b/src/model/solid_mechanics/fragment_manager.cc
deleted file mode 100644
index fbd92a446..000000000
--- a/src/model/solid_mechanics/fragment_manager.cc
+++ /dev/null
@@ -1,650 +0,0 @@
-/**
- * @file fragment_manager.cc
- *
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date creation: Thu Jan 23 2014
- * @date last modification: Tue Aug 19 2014
- *
- * @brief Group manager to handle fragments
- *
- * @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 "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().interpolateOnQuadraturePoints(model.getMesh().getNodes(),
- quad_coordinates);
-
- /// store mass density per quadrature point
- mesh.initElementTypeMapArray(mass_density,
- 1,
- spatial_dimension,
- _not_ghost);
-
- storeMassDensityPerQuadraturePoint();
-
- 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").getNbQuadraturePoints(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().getNbQuadraturePoints(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().interpolateOnQuadraturePoints(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().getNbQuadraturePoints(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().getNbQuadraturePoints(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::storeMassDensityPerQuadraturePoint() {
- 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().getNbQuadraturePoints(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().getNbQuadraturePoints(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/fragment_manager.hh b/src/model/solid_mechanics/fragment_manager.hh
deleted file mode 100644
index 58f5256b7..000000000
--- a/src/model/solid_mechanics/fragment_manager.hh
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * @file fragment_manager.hh
- *
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date creation: Thu Jan 23 2014
- * @date last modification: Tue Aug 19 2014
- *
- * @brief Group manager to handle fragments
- *
- * @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_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 quadrature point
- void storeMassDensityPerQuadraturePoint();
-
- /// 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/material.cc b/src/model/solid_mechanics/material.cc
index 98848b0c0..8238b8452 100644
--- a/src/model/solid_mechanics/material.cc
+++ b/src/model/solid_mechanics/material.cc
@@ -1,1867 +1,1671 @@
/**
* @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_vector(false),
- 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> & internal_force = const_cast<Array<Real> &>(model->getInternalForce());
- Mesh & mesh = this->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 & mesh = fem->getMesh();
+ Mesh::type_iterator it =
+ element_filter.firstType(spatial_dimension, ghost_type);
+ Mesh::type_iterator last_type =
+ element_filter.lastType(spatial_dimension, ghost_type);
+ for (; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if (nb_element) {
- const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(*it, ghost_type);
+ 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->getNbQuadraturePoints(*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");
- this->fem->integrate(*sigma_dphi_dx, *int_sigma_dphi_dx,
- size_of_shapes_derivatives,
- *it, ghost_type,
+ fem->integrate(*sigma_dphi_dx, *int_sigma_dphi_dx,
+ size_of_shapes_derivatives, *it, ghost_type,
elem_filter);
delete sigma_dphi_dx;
-
/// assemble
model->getDOFManager().assembleElementalArrayLocalArray(*int_sigma_dphi_dx, internal_force,
*it, ghost_type, -1, elem_filter);
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->gradientOnQuadraturePoints(model->getDisplacement(), gradu_vect,
- spatial_dimension,
- *it, ghost_type, elem_filter);
+ fem->gradientOnIntegrationPoints(model->getDisplacement(), gradu_vect,
+ spatial_dimension, *it, ghost_type,
+ elem_filter);
gradu_vect -= eigengradu(*it, ghost_type);
/// compute @f$\mathbf{\sigma}_q@f$ from @f$\nabla u@f$
computeStress(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computeAllCauchyStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
- AKANTU_DEBUG_ASSERT(finite_deformation,"The Cauchy stress can only be computed if you are working in finite deformation.");
+ 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->gradientOnQuadraturePoints(displacement, gradu_vect,
- spatial_dimension,
- *it, ghost_type, elem_filter);
+ fem->gradientOnIntegrationPoints(displacement, gradu_vect,
+ spatial_dimension, *it, ghost_type,
+ elem_filter);
setToSteadyState(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
/**
* Compute the stiffness matrix by assembling @f$\int_{\omega} B^t \times D
* \times B d\omega @f$
*
* @param[in] current_position nodes postition + displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void Material::assembleStiffnessMatrix(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model->getSpatialDimension();
- Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension, ghost_type);
- for(; it != last_type; ++it) {
- if(finite_deformation){
+ 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()) {
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->getNbQuadraturePoints(type,
- ghost_type);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(type, ghost_type);
gradu_vect.resize(nb_quadrature_points * nb_element);
- fem->gradientOnQuadraturePoints(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;
model->getDOFManager().assembleElementalMatricesToMatrix("stiffness", "displacements", *K_e,
type, ghost_type, _symmetric,
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();
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->getNbQuadraturePoints(type, ghost_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->gradientOnQuadraturePoints(model->getIncrement(), gradu_vect,
+ // 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");
fem->integrate(*bt_s_b, *K_e,
bt_s_b_size * bt_s_b_size,
type, ghost_type,
elem_filter);
delete bt_s_b;
model->getDOFManager().assembleElementalMatricesToMatrix("stiffness", "displacements", *K_e,
type, ghost_type, _symmetric,
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();
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->getNbQuadraturePoints(type, ghost_type);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(type, ghost_type);
gradu_vect.resize(nb_quadrature_points * nb_element);
- fem->gradientOnQuadraturePoints(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;
model->getDOFManager().assembleElementalMatricesToMatrix("stiffness", "displacements", *K_e,
type, ghost_type, _symmetric,
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> & internal_force = model->getInternalForce();
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->getNbQuadraturePoints(*it, ghost_type);
+ 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;
model->getDOFManager().assembleElementalArrayLocalArray(*r_e, internal_force,
*it, ghost_type, -1, elem_filter);
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->getNbQuadraturePoints(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->gradientOnQuadraturePoints(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();
- if(!potential_energy.exists(el_type, ghost_type)) {
- UInt nb_element = element_filter(el_type, ghost_type).getSize();
- UInt nb_quadrature_points = fem->getNbQuadraturePoints(el_type, _not_ghost);
-
- potential_energy.alloc(nb_element * nb_quadrature_points, 1,
- el_type, ghost_type);
- }
-
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->getNbQuadraturePoints(type));
+ 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::computeQuadraturePointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates,
- const GhostType & ghost_type) const {
- AKANTU_DEBUG_IN();
-
- const Mesh & mesh = this->model->getMesh();
-
- Array<Real> nodes_coordinates(mesh.getNodes(), true);
- nodes_coordinates += this->model->getDisplacement();
-
- Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type);
- for(; it != last_type; ++it) {
- const Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
-
- UInt nb_element = elem_filter.getSize();
- if (nb_element == 0) continue;
- UInt nb_tot_quad = this->fem->getNbQuadraturePoints(*it, ghost_type) * nb_element;
-
- Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
- quads.resize(nb_tot_quad);
-
- this->fem->interpolateOnQuadraturePoints(nodes_coordinates,
- quads, spatial_dimension,
- *it, ghost_type, elem_filter);
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void Material::initElementalFieldInterpolation(const ElementTypeMapArray<Real> & interpolation_points_coordinates) {
- AKANTU_DEBUG_IN();
- const Mesh & mesh = fem->getMesh();
-
- ElementTypeMapArray<Real> quadrature_points_coordinates("quadrature_points_coordinates_for_interpolation", getID());
- mesh.initElementTypeMapArray(quadrature_points_coordinates, spatial_dimension, spatial_dimension);
-
- for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end(); ++gt) {
-
- GhostType ghost_type = *gt;
-
- computeQuadraturePointsCoordinates(quadrature_points_coordinates, ghost_type);
-
- Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last = element_filter.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<Real> & interp_points_coord = interpolation_points_coordinates(type, ghost_type);
- UInt nb_interpolation_points_per_elem = interp_points_coord.getSize() / nb_element;
-
- AKANTU_DEBUG_ASSERT(interp_points_coord.getSize() % nb_element == 0,
- "Number of interpolation points is wrong");
-
-#define AKANTU_INIT_INTERPOLATE_ELEMENTAL_FIELD(type) \
- initElementalFieldInterpolation<type>(quadrature_points_coordinates(type, ghost_type), \
- interp_points_coord, \
- nb_interpolation_points_per_elem, \
- ghost_type) \
-
- AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(AKANTU_INIT_INTERPOLATE_ELEMENTAL_FIELD);
-#undef AKANTU_INIT_INTERPOLATE_ELEMENTAL_FIELD
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template <ElementType type>
-void Material::initElementalFieldInterpolation(const Array<Real> & quad_coordinates,
- const Array<Real> & interpolation_points_coordinates,
- const UInt nb_interpolation_points_per_elem,
- const GhostType ghost_type) {
+void Material::initElementalFieldInterpolation(
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates) {
AKANTU_DEBUG_IN();
- Array<UInt> & elem_fil = element_filter(type, ghost_type);
- UInt nb_element = elem_fil.getSize();
- UInt nb_quad_per_element = fem->getNbQuadraturePoints(type, ghost_type);
-
- if(!interpolation_inverse_coordinates.exists(type, ghost_type))
- interpolation_inverse_coordinates.alloc(nb_element,
- nb_quad_per_element*nb_quad_per_element,
- type, ghost_type);
- else
- interpolation_inverse_coordinates(type, ghost_type).resize(nb_element);
-
- if(!interpolation_points_matrices.exists(type, ghost_type))
- interpolation_points_matrices.alloc(nb_element,
- nb_interpolation_points_per_elem * nb_quad_per_element,
- type, ghost_type);
- else
- interpolation_points_matrices(type, ghost_type).resize(nb_element);
-
- Array<Real> & interp_inv_coord = interpolation_inverse_coordinates(type, ghost_type);
- Array<Real> & interp_points_mat = interpolation_points_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 =
- quad_coordinates.begin_reinterpret(spatial_dimension,
- nb_quad_per_element,
- nb_element);
-
- Array<Real>::const_matrix_iterator points_coords_begin =
- interpolation_points_coordinates.begin_reinterpret(spatial_dimension,
- nb_interpolation_points_per_elem,
- interpolation_points_coordinates.getSize() / nb_interpolation_points_per_elem);
-
- Array<Real>::matrix_iterator inv_quad_coord_it =
- interp_inv_coord.begin(nb_quad_per_element, nb_quad_per_element);
-
- Array<Real>::matrix_iterator inv_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; ++el, ++inv_quad_coord_it,
- ++inv_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
- buildElementalFieldInterpolationCoodinates<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[elem_fil(el)];
- /// matrix to store the interpolation points coordinates
- /// compatible with these functions
- Matrix<Real> & inv_points_coord_matrix = *inv_points_mat_it;
-
- /// insert the quad coordinates in a matrix compatible with the interpolation
- buildElementalFieldInterpolationCoodinates<type>(points_coords,
- inv_points_coord_matrix);
- }
+ 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) {
- interpolateElementalField(stress, result, ghost_type);
-}
-/* -------------------------------------------------------------------------- */
-void Material::interpolateElementalField(const ElementTypeMapArray<Real> & field,
- ElementTypeMapArray<Real> & result,
- const GhostType ghost_type) {
- AKANTU_DEBUG_IN();
-
- Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last = element_filter.lastType(spatial_dimension, ghost_type);
- for (; it != last; ++it) {
- ElementType type = *it;
-
- Array<UInt> & elem_fil = element_filter(type, ghost_type);
- UInt nb_element = elem_fil.getSize();
- UInt nb_quad_per_element = fem->getNbQuadraturePoints(type, ghost_type);
-
- const Array<Real> & field_vec = field(type, ghost_type);
- Array<Real> & result_vec = result(type, ghost_type);
-
- Matrix<Real> coefficients(nb_quad_per_element, field_vec.getNbComponent());
-
- const Array<Real> & interp_inv_coord = interpolation_inverse_coordinates(type, ghost_type);
- const Array<Real> & interp_points_coord = interpolation_points_matrices(type, ghost_type);
-
- UInt nb_interpolation_points_per_elem
- = interp_points_coord.getNbComponent() / nb_quad_per_element;
-
- Array<Real>::const_matrix_iterator field_it
- = field_vec.begin_reinterpret(field_vec.getNbComponent(),
- nb_quad_per_element,
- nb_element);
-
- Array<Real>::const_matrix_iterator interpolation_points_coordinates_it =
- interp_points_coord.begin(nb_interpolation_points_per_elem, nb_quad_per_element);
-
- Array<Real>::matrix_iterator result_begin
- = result_vec.begin_reinterpret(field_vec.getNbComponent(),
- nb_interpolation_points_per_elem,
- result_vec.getSize() / nb_interpolation_points_per_elem);
-
- Array<Real>::const_matrix_iterator inv_quad_coord_it =
- interp_inv_coord.begin(nb_quad_per_element, nb_quad_per_element);
-
- /// loop over the elements of the current material 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[elem_fil(el)]);
- res.mul<true, true>(coefficients, coord);
- }
- }
-
- AKANTU_DEBUG_OUT();
+ 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,
- const GhostType ghost_type) {
- interpolateElementalFieldOnFacets(stress, result, ghost_type);
-}
+void Material::interpolateStressOnFacets(
+ ElementTypeMapArray<Real> & result,
+ ElementTypeMapArray<Real> & by_elem_result, const GhostType ghost_type) {
-/* -------------------------------------------------------------------------- */
-void Material::interpolateElementalFieldOnFacets(const ElementTypeMapArray<Real> & field,
- ElementTypeMapArray<Real> & result,
- const GhostType ghost_type) {
- AKANTU_DEBUG_IN();
+ interpolateStress(by_elem_result, ghost_type);
- UInt sp2 = spatial_dimension * spatial_dimension;
+ UInt stress_size = this->stress.getNbComponent();
const Mesh & mesh = this->model->getMesh();
const Mesh & mesh_facets = mesh.getMeshFacets();
- Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last = 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;
+ 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_quad_per_element = fem->getNbQuadraturePoints(type, ghost_type);
-
- const Array<Real> & field_vec = field(type, ghost_type);
-
- Matrix<Real> coefficients(nb_quad_per_element, field_vec.getNbComponent());
-
- const Array<Real> & interp_inv_coord = interpolation_inverse_coordinates(type, ghost_type);
- const Array<Real> & interp_points_coord = interpolation_points_matrices(type, ghost_type);
-
- UInt nb_interpolation_points_per_elem
- = interp_points_coord.getNbComponent() / nb_quad_per_element;
-
- Array<Real>::const_matrix_iterator field_it
- = field_vec.begin_reinterpret(field_vec.getNbComponent(),
- nb_quad_per_element,
- nb_element);
-
- Array<Real>::const_matrix_iterator interpolation_points_coordinates_it =
- interp_points_coord.begin(nb_interpolation_points_per_elem, nb_quad_per_element);
-
- Array<Real>::const_matrix_iterator inv_quad_coord_it =
- interp_inv_coord.begin(nb_quad_per_element, nb_quad_per_element);
-
- Matrix<Real> result_tmp(sp2, nb_interpolation_points_per_elem);
+ 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;
- /// loop over the elements of the current material 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
- result_tmp.mul<true, true>(coefficients, coord);
+ Array<Real>::const_matrix_iterator result_it =
+ by_elem_res.begin_reinterpret(
+ stress_size, nb_interpolation_points_per_elem, nb_element_full);
+ for (UInt el = 0; el < nb_element; ++el) {
UInt global_el = elem_fil(el);
element_for_comparison.element = global_el;
for (UInt f = 0; f < nb_facet_per_elem; ++f) {
+
Element facet_elem = facet_to_element(global_el, f);
UInt global_facet = facet_elem.element;
if (facet_elem.ghost_type != current_ghost_type) {
current_ghost_type = facet_elem.ghost_type;
- element_to_facet = &mesh_facets.getElementToSubelement(type_facet,
- current_ghost_type);
+ 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;
+ 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 * sp2,
- sp2);
+ 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);
}
}
}
}
-
- AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-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 {
+ std::stringstream sstr;
+ std::string ghost_id = "";
+ if (ghost_type == _ghost)
+ ghost_id = ":ghost";
+ sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
+
+ ID fvect_id = sstr.str();
+ try {
+ return Memory::getArray<UInt>(fvect_id);
+ } catch (debug::Exception & e) {
+ AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
+ << ") does not contain a vector "
+ << vect_id << "(" << fvect_id
+ << ") [" << e << "]");
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+Array<UInt> & Material::getArray(const ID & vect_id, const ElementType & type,
+ const GhostType & ghost_type) {
+ std::stringstream sstr;
+ std::string ghost_id = "";
+ if (ghost_type == _ghost)
+ ghost_id = ":ghost";
+ sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
+
+ ID fvect_id = sstr.str();
+ try {
+ return Memory::getArray<UInt>(fvect_id);
+ } catch (debug::Exception & e) {
+ AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
+ << ") does not contain a vector "
+ << vect_id << "(" << fvect_id
+ << ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-const InternalField<T> & Material::getInternal(const ID & int_id) const {
+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());
+ ElementTypeMapArray<UInt> material_local_new_numbering(
+ "remove mat filter elem", getID());
Element element;
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ 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->removeQuadraturePoints(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->removeQuadraturePoints(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->removeQuadraturePoints(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());
+ ElementTypeMapArray<UInt> material_local_new_numbering(
+ "remove mat filter elem", getID());
Array<Element>::const_iterator<Element> el_begin = element_list.begin();
- Array<Element>::const_iterator<Element> el_end = element_list.end();
+ 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->removeQuadraturePoints(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->removeQuadraturePoints(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->removeQuadraturePoints(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);
-
- for(; it != end; ++it) {
+ 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);
- if(!this->potential_energy.exists(*it, _not_ghost)) {
- UInt nb_element = this->element_filter(*it, _not_ghost).getSize();
- UInt nb_quadrature_points = this->fem->getNbQuadraturePoints(*it, _not_ghost);
-
- this->potential_energy.alloc(nb_element * nb_quadrature_points, 1,
- *it, _not_ghost);
- }
+ 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;
}
-/* -------------------------------------------------------------------------- */
-inline ElementTypeMap<UInt> Material::getInternalDataPerElem(const ID & id,
- const ElementKind & element_kind,
- const ID & fe_engine_id) 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)
- AKANTU_EXCEPTION("Cannot find internal field " << id << " in material " << this->name);
-
- InternalField<Real> & internal = *internal_array->second;
- InternalField<Real>::type_iterator it = internal.firstType(internal.getSpatialDimension(),
- _not_ghost, element_kind);
- InternalField<Real>::type_iterator last_type = internal.lastType(internal.getSpatialDimension(),
- _not_ghost, element_kind);
-
- ElementTypeMap<UInt> res;
- for(; it != last_type; ++it) {
- UInt nb_quadrature_points = 0;
- nb_quadrature_points = model->getFEEngine(fe_engine_id).getNbQuadraturePoints(*it);
-
- res(*it) = internal.getNbComponent() * nb_quadrature_points;
- }
- return res;
-}
-
-/* -------------------------------------------------------------------------- */
-void Material::flattenInternal(const std::string & field_id,
- ElementTypeMapArray<Real> & internal_flat,
- const GhostType ghost_type,
- ElementKind element_kind) const {
- this->flattenInternalIntern(field_id, internal_flat,
- this->spatial_dimension,
- ghost_type, element_kind);
-}
-
-/* -------------------------------------------------------------------------- */
-void Material::flattenInternalIntern(const std::string & field_id,
- ElementTypeMapArray<Real> & internal_flat,
- UInt spatial_dimension,
- const GhostType ghost_type,
- ElementKind element_kind,
- const ElementTypeMapArray<UInt> * element_filter,
- const Mesh * mesh) const {
- typedef ElementTypeMapArray<UInt>::type_iterator iterator;
-
- if(element_filter == NULL) element_filter = &(this->element_filter);
- if(mesh == NULL) mesh = &(this->model->mesh);
-
- iterator tit = element_filter->firstType(spatial_dimension,
- ghost_type,
- element_kind);
- iterator end = element_filter->lastType(spatial_dimension,
- ghost_type,
- element_kind);
-
- for (; tit != end; ++tit) {
- ElementType type = *tit;
-
- try {
- __attribute__((unused)) const Array<Real> & src_vect
- = this->getArray<Real>(field_id, type, ghost_type);
- } catch(debug::Exception & e) {
- continue;
- }
-
- const Array<Real> & src_vect = this->getArray<Real>(field_id, type, ghost_type);
- const Array<UInt> & filter = (*element_filter)(type, ghost_type);
-
- // total number of elements for a given type
- UInt nb_element = mesh->getNbElement(type,ghost_type);
- // number of filtered elements
- UInt nb_element_src = filter.getSize();
- // number of quadrature points per elem
- UInt nb_quad_per_elem = 0;
- // number of data per quadrature point
- UInt nb_data_per_quad = src_vect.getNbComponent();
-
- if (!internal_flat.exists(type,ghost_type)) {
- internal_flat.alloc(nb_element * nb_quad_per_elem,
- nb_data_per_quad,
- type,
- ghost_type);
- }
-
- if (nb_element_src == 0) continue;
- nb_quad_per_elem = (src_vect.getSize() / nb_element_src);
-
- // number of data per element
- UInt nb_data = nb_quad_per_elem * src_vect.getNbComponent();
-
- Array<Real> & dst_vect = internal_flat(type,ghost_type);
- dst_vect.resize(nb_element*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);
-
- for (; it != end ; ++it,++it_src) {
- it_dst[*it] = *it_src;
- }
- }
-};
/* -------------------------------------------------------------------------- */
/// extrapolate internal values
-void Material::extrapolateInternal(const ID & id, const Element & element, const Matrix<Real> & point, Matrix<Real> & extrapolated) {
- if (this->isInternal(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().getNbQuadraturePoints(element.type, element.ghost_type);
- const Array<Real> & internal = this->getArray<Real>(id, element.type, element.ghost_type);
+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_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) {
+ if (tmp.norm() > 0) {
index = j;
- continue;
+ 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) {
+
+ ElementTypeMapArray<UInt>::type_iterator it = this->element_filter.firstType(
+ _all_dimensions, _not_ghost, _ek_not_defined);
+ ElementTypeMapArray<UInt>::type_iterator end =
+ element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
+
+ for (; it != end; ++it) {
+ ElementType type = *it;
+ if (!element_filter(type, ghost_type).getSize())
+ continue;
+ Array<Real>::matrix_iterator eigen_it =
+ this->eigengradu(type, ghost_type)
+ .begin(spatial_dimension, spatial_dimension);
+ Array<Real>::matrix_iterator eigen_end =
+ this->eigengradu(type, ghost_type)
+ .end(spatial_dimension, spatial_dimension);
+ for (; eigen_it != eigen_end; ++eigen_it) {
+ Matrix<Real> & current_eigengradu = *eigen_it;
+ current_eigengradu = prescribed_eigen_grad_u;
+ }
+ }
+}
+
__END_AKANTU__
diff --git a/src/model/solid_mechanics/material.hh b/src/model/solid_mechanics/material.hh
index a416b88f3..3d310fa49 100644
--- a/src/model/solid_mechanics/material.hh
+++ b/src/model/solid_mechanics/material.hh
@@ -1,649 +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);
- /// Operations before and after solveStep in implicit
- virtual void beforeSolveStep() {}
- virtual void afterSolveStep() {}
-
/// 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 computeAllNonLocalStresses(__attribute__((unused)) 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,
- 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;
- /// assemble the residual
- template<UInt dim>
- void assembleResidual(GhostType ghost_type);
+ /// compute the potential energy by element
+ void computePotentialEnergyByElements();
- /// Computation of Cauchy stress tensor in the case of finite deformation
- template<UInt dim>
- void computeCauchyStress(__attribute__((unused)) ElementType el_type,
- __attribute__((unused)) GhostType ghost_type = _not_ghost);
+ /// resize the intenals arrays
+ virtual void resizeInternals();
- template<UInt dim >
- inline void computeCauchyStressOnQuad(const Matrix<Real> & F, const Matrix<Real> & S,
- Matrix<Real> & cauchy,
- const Real & C33 = 1.0 ) const;
+ /* ------------------------------------------------------------------------ */
+ /* 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>
+ /// Computation of Cauchy stress tensor in the case of finite deformation from
+ /// the 2nd Piola-Kirchhoff for a given element type
+ template <UInt dim>
+ void computeCauchyStress(__attribute__((unused)) ElementType el_type,
+ __attribute__((unused))
+ GhostType ghost_type = _not_ghost);
+
+ /// Computation the Cauchy stress the 2nd Piola-Kirchhoff and the deformation
+ /// gradient
+ template <UInt dim>
+ inline void computeCauchyStressOnQuad(const Matrix<Real> & F,
+ const Matrix<Real> & S,
+ Matrix<Real> & cauchy,
+ const Real & C33 = 1.0) const;
+
+ template <UInt dim>
void computeAllStressesFromTangentModuli(const ElementType & type,
- GhostType ghost_type);
+ 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);
- /// write the stress tensor in the Voigt notation.
- template<UInt dim>
- inline void SetCauchyStressArray(const Matrix<Real> & S_t, Matrix<Real> & Stress_vect);
-
- inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const;
-
- /// Size of the Stress matrix for the case of finite deformation see: Bathe et al, IJNME, Vol 9, 353-386, 1975
+ /// 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> & Stress_matrix);
-
- /// compute the potential energy by element
- void computePotentialEnergyByElements();
-
- /// resize the intenals arrays
- virtual void resizeInternals();
+ Matrix<Real> & sigma);
-public:
- /// compute the coordinates of the quadrature points
- virtual void computeQuadraturePointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates,
- const GhostType & ghost_type) const;
-
-protected:
- /// interpolate an elemental field on given points for each element
- void interpolateElementalField(const ElementTypeMapArray<Real> & field,
- ElementTypeMapArray<Real> & result,
- const GhostType ghost_type);
-
- /// interpolate an elemental field and store the results per facet
- void interpolateElementalFieldOnFacets(const ElementTypeMapArray<Real> & field,
- ElementTypeMapArray<Real> & result,
- const GhostType ghost_type);
-
- /// template function to initialize the elemental field interpolation
- template <ElementType type>
- void initElementalFieldInterpolation(const Array<Real> & quad_coordinates,
- const Array<Real> & interpolation_points_coordinates,
- const UInt nb_interpolation_points_per_elem,
- const GhostType ghost_type);
-
- /// build the coordinate matrix for the interpolation on elemental field
- template <ElementType type>
- inline void buildElementalFieldInterpolationCoodinates(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix);
-
- /// build interpolation coordinates for basic linear elements
- inline void buildElementalFieldInterpolationCoodinatesLinear(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix);
-
- /// build interpolation coordinates for basic quadratic elements
- inline void buildElementalFieldInterpolationCoodinatesQuadratic(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix);
+ /// write the stress tensor in the Voigt notation.
+ template <UInt dim>
+ inline void setCauchyStressArray(const Matrix<Real> & S_t,
+ Matrix<Real> & sigma_voight);
-public:
/* ------------------------------------------------------------------------ */
/* Conversion functions */
/* ------------------------------------------------------------------------ */
- 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);
+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>
+ template <UInt dim>
static inline void gradUToEpsilon(const Matrix<Real> & grad_u,
- Matrix<Real> & epsilon);
- template<UInt dim>
+ Matrix<Real> & epsilon);
+ template <UInt dim>
static inline void gradUToGreenStrain(const Matrix<Real> & grad_u,
- Matrix<Real> & epsilon);
+ 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 QuadraturePoint convertToLocalPoint(const QuadraturePoint & global_point) const;
+ inline IntegrationPoint
+ convertToLocalPoint(const IntegrationPoint & global_point) const;
/// converts local quadrature point to global quadrature point
- inline QuadraturePoint convertToGlobalPoint(const QuadraturePoint & 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 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){};
/* ------------------------------------------------------------------------ */
/* 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>
inline bool isInternal(const ID & id, const ElementKind & element_kind) const;
- virtual ElementTypeMap<UInt> getInternalDataPerElem(const ID & id,
- const ElementKind & element_kind,
- const ID & fe_engine_id = "") const;
+
+ template <typename T>
+ ElementTypeMap<UInt>
+ getInternalDataPerElem(const ID & id, const ElementKind & element_kind) const;
bool isFiniteDeformation() const { return finite_deformation; }
bool isInelasticDeformation() const { return inelastic_deformation; }
- template <typename T>
- inline void setParam(const ID & param, T value);
+ template <typename T> inline 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;
+ void flattenInternal(const std::string & field_id,
+ ElementTypeMapArray<T> & internal_flat,
+ const GhostType ghost_type = _not_ghost,
+ ElementKind element_kind = _ek_not_defined) const;
- 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:
- /// internal variation of the flatten function that is more flexible and can
- /// be used by inherited materials to change some behavior
- virtual void flattenInternalIntern(const std::string & field_id,
- ElementTypeMapArray<Real> & internal_flat,
- UInt spatial_dimension,
- const GhostType ghost_type,
- ElementKind element_kind,
- const ElementTypeMapArray<UInt> * element_filter = NULL,
- const Mesh * mesh = NULL) const;
+ /// apply a constant eigengrad_u everywhere in the material
+ virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
+ const GhostType = _not_ghost);
protected:
-
bool isInit() const { return is_init; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// boolean to know if the material has been initialized
bool is_init;
std::map<ID, InternalField<Real> *> internal_vectors_real;
std::map<ID, InternalField<UInt> *> internal_vectors_uint;
std::map<ID, InternalField<bool> *> internal_vectors_bool;
protected:
/// Link to the fem object in the model
FEEngine * fem;
/// Finite deformation
bool finite_deformation;
/// Finite deformation
bool inelastic_deformation;
/// material name
std::string name;
/// The model to witch the material belong
SolidMechanicsModel * model;
/// density : rho
Real rho;
/// spatial dimension
UInt spatial_dimension;
/// list of element handled by the material
ElementTypeMapArray<UInt> element_filter;
/// stresses arrays ordered by element types
InternalField<Real> stress;
/// eigengrad_u arrays ordered by element types
InternalField<Real> eigengradu;
/// grad_u arrays ordered by element types
InternalField<Real> gradu;
/// Green Lagrange strain (Finite deformation)
InternalField<Real> green_strain;
- /// Second Piola-Kirchhoff stress tensor arrays ordered by element types (Finite deformation)
+ /// 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;
};
-/* -------------------------------------------------------------------------- */
-/* inline functions */
-/* -------------------------------------------------------------------------- */
-
-#include "material_inline_impl.cc"
-
/// 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 */
/* -------------------------------------------------------------------------- */
-
-#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_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 \
- } \
+/// This can be used to automatically write the loop on quadrature points in
+/// functions such as computeStress. This macro in addition to write the loop
+/// provides two tensors (matrices) sigma and grad_u
+#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type) \
+ Array<Real>::matrix_iterator gradu_it = \
+ this->gradu(el_type, ghost_type) \
+ .begin(this->spatial_dimension, this->spatial_dimension); \
+ Array<Real>::matrix_iterator gradu_end = \
+ this->gradu(el_type, ghost_type) \
+ .end(this->spatial_dimension, this->spatial_dimension); \
+ \
+ this->stress(el_type, ghost_type) \
+ .resize(this->gradu(el_type, ghost_type).getSize()); \
+ \
+ Array<Real>::iterator<Matrix<Real> > stress_it = \
+ this->stress(el_type, ghost_type) \
+ .begin(this->spatial_dimension, this->spatial_dimension); \
+ \
+ if (this->isFiniteDeformation()) { \
+ this->piola_kirchhoff_2(el_type, ghost_type) \
+ .resize(this->gradu(el_type, ghost_type).getSize()); \
+ stress_it = this->piola_kirchhoff_2(el_type, ghost_type) \
+ .begin(this->spatial_dimension, this->spatial_dimension); \
+ } \
+ \
+ for (; gradu_it != gradu_end; ++gradu_it, ++stress_it) { \
+ Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it; \
+ Matrix<Real> & __attribute__((unused)) sigma = *stress_it
+
+#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END }
+
+/// This can be used to automatically write the loop on quadrature points in
+/// functions such as computeTangentModuli. This macro in addition to write the
+/// loop provides two tensors (matrices) sigma_tensor, grad_u, and a matrix
+/// where the elemental tangent moduli should be stored in Voigt Notation
+#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_mat) \
+ Array<Real>::matrix_iterator gradu_it = \
+ this->gradu(el_type, ghost_type) \
+ .begin(this->spatial_dimension, this->spatial_dimension); \
+ Array<Real>::matrix_iterator gradu_end = \
+ this->gradu(el_type, ghost_type) \
+ .end(this->spatial_dimension, this->spatial_dimension); \
+ Array<Real>::matrix_iterator sigma_it = \
+ this->stress(el_type, ghost_type) \
+ .begin(this->spatial_dimension, this->spatial_dimension); \
+ \
+ tangent_mat.resize(this->gradu(el_type, ghost_type).getSize()); \
+ \
+ UInt tangent_size = \
+ this->getTangentStiffnessVoigtSize(this->spatial_dimension); \
+ Array<Real>::matrix_iterator tangent_it = \
+ tangent_mat.begin(tangent_size, tangent_size); \
+ \
+ for (; gradu_it != gradu_end; ++gradu_it, ++sigma_it, ++tangent_it) { \
+ Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it; \
+ Matrix<Real> & __attribute__((unused)) sigma_tensor = *sigma_it; \
+ Matrix<Real> & tangent = *tangent_it
+
+#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END }
/* -------------------------------------------------------------------------- */
-#define INSTANTIATE_MATERIAL(mat_name) \
- template class mat_name<1>; \
- template class mat_name<2>; \
+#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 7a7e99dd4..319b01603 100644
--- a/src/model/solid_mechanics/material_inline_impl.cc
+++ b/src/model/solid_mechanics/material_inline_impl.cc
@@ -1,471 +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/>.
*
*/
-__END_AKANTU__
-
+/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
-#include <iostream>
+/* -------------------------------------------------------------------------- */
-__BEGIN_AKANTU__
+#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 = element_filter(type, ghost_type);
+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;
+ 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.");
+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 >
+template <UInt dim>
inline void Material::computeCauchyStressOnQuad(const Matrix<Real> & F,
- const Matrix<Real> & piola,
- Matrix<Real> & sigma,
- const Real & C33 ) const {
+ 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;
+ 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) {
+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) {
+inline void Material::leftCauchy(const Matrix<Real> & F, Matrix<Real> & B) {
B.mul<false, true>(F, F);
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
+template <UInt dim>
inline void Material::gradUToEpsilon(const Matrix<Real> & grad_u,
- Matrix<Real> & epsilon) {
+ 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));
+ epsilon(i, j) = 0.5 * (grad_u(i, j) + grad_u(j, i));
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
+template <UInt dim>
inline void Material::gradUToGreenStrain(const Matrix<Real> & grad_u,
- Matrix<Real> & epsilon) {
+ 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.);
+ 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);
+ 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> & Stress_vect) {
-
- AKANTU_DEBUG_IN();
-
- Stress_vect.clear();
-
- //UInt cauchy_matrix_size = getCauchyStressArraySize(dim);
+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
- //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);
- /*
- * 1d: [ s11 ]'
- * 2d: [ s11 s22 s12 ]'
- * 3d: [ s11 s22 s33 s23 s13 s12 ]
- */
- for (UInt i = 0; i < dim; ++i)//diagonal terms
- Stress_vect(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 = 1; i < dim; ++i)// term s12 in 2D and terms s23 s13 in 3D
- Stress_vect(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);
- for (UInt i = 2; i < dim; ++i)//term s13 in 3D
- Stress_vect(dim+i, 0) = S_t(0, 1);
-
- AKANTU_DEBUG_OUT();
+ AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-inline void Material::setCauchyStressMatrix(const Matrix<Real> & S_t, Matrix<Real> & Stress_matrix) {
-
- AKANTU_DEBUG_IN();
+template <UInt dim>
+inline void Material::setCauchyStressMatrix(const Matrix<Real> & S_t,
+ Matrix<Real> & sigma) {
+ AKANTU_DEBUG_IN();
- Stress_matrix.clear();
+ 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) {
- Stress_matrix(i * dim + m, i * dim + n) = S_t(m, n);
- }
- }
+ /// 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);
+ }
}
+ }
- //other terms from the diagonal
- /*for (UInt i = 0; i < 3 - dim; ++i) {
- Stress_matrix(dim * dim + i, dim * dim + i) = S_t(dim + i, dim + i);
- }*/
-
-
- AKANTU_DEBUG_OUT();
+ AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-inline Element Material::convertToLocalElement(const Element & global_element) const {
+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 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);
+ "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);
+ 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);
+ 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 {
+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);
+ 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);
+ Element tmp_quad(local_element.type, ge, local_element.ghost_type,
+ local_element.kind);
return tmp_quad;
}
/* -------------------------------------------------------------------------- */
-inline QuadraturePoint Material::convertToLocalPoint(const QuadraturePoint & global_point) const {
+inline IntegrationPoint
+Material::convertToLocalPoint(const IntegrationPoint & global_point) const {
const FEEngine & fem = this->model->getFEEngine();
- UInt nb_quad = fem.getNbQuadraturePoints(global_point.type);
- Element el = this->convertToLocalElement(static_cast<const Element &>(global_point));
- QuadraturePoint tmp_quad(el, global_point.num_point, nb_quad);
+ 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 QuadraturePoint Material::convertToGlobalPoint(const QuadraturePoint & local_point) const {
+inline IntegrationPoint
+Material::convertToGlobalPoint(const IntegrationPoint & local_point) const {
const FEEngine & fem = this->model->getFEEngine();
- UInt nb_quad = fem.getNbQuadraturePoints(local_point.type);
- Element el = this->convertToGlobalElement(static_cast<const Element &>(local_point));
- QuadraturePoint tmp_quad(el, local_point.num_point, nb_quad);
+ 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;
}
-/* -------------------------------------------------------------------------- */
-template<ElementType type>
-inline void Material::buildElementalFieldInterpolationCoodinates(__attribute__((unused)) const Matrix<Real> & coordinates,
- __attribute__((unused)) Matrix<Real> & coordMatrix) {
- AKANTU_DEBUG_TO_IMPLEMENT();
-}
-
-/* -------------------------------------------------------------------------- */
-inline void Material::buildElementalFieldInterpolationCoodinatesLinear(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
-
- for (UInt i = 0; i < coordinates.cols(); ++i)
- coordMatrix(i, 0) = 1;
-}
-
-/* -------------------------------------------------------------------------- */
-inline void Material::buildElementalFieldInterpolationCoodinatesQuadratic(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
-
- 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);
- }
-}
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_segment_2>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
- buildElementalFieldInterpolationCoodinatesLinear(coordinates, coordMatrix);
-}
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_segment_3>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
-
- buildElementalFieldInterpolationCoodinatesQuadratic(coordinates, coordMatrix);
-}
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_triangle_3>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
- buildElementalFieldInterpolationCoodinatesLinear(coordinates, coordMatrix);
-}
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_triangle_6>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
-
- buildElementalFieldInterpolationCoodinatesQuadratic(coordinates, coordMatrix);
-}
-
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_tetrahedron_4>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
- buildElementalFieldInterpolationCoodinatesLinear(coordinates, coordMatrix);
-}
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_tetrahedron_10>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
-
- buildElementalFieldInterpolationCoodinatesQuadratic(coordinates, coordMatrix);
-}
-
-/**
- * @todo Write a more efficient interpolation for quadrangles by
- * dropping unnecessary quadrature points
- *
- */
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_quadrangle_4>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
-
- 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 Material::buildElementalFieldInterpolationCoodinates<_quadrangle_8>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
-
- 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;
- }
- }
-
- }
-}
-
/* -------------------------------------------------------------------------- */
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().getNbQuadraturePoints(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()) {
+ 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()) {
+ 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());
+ 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());
+ } 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 {
+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));
+ 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 <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) {
+template <>
+inline void Material::registerInternal<Real>(InternalField<Real> & vect) {
internal_vectors_real[vect.getID()] = &vect;
}
-template<> inline void Material::registerInternal<UInt>(InternalField<UInt> & 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) {
+template <>
+inline void Material::registerInternal<bool>(InternalField<bool> & vect) {
internal_vectors_bool[vect.getID()] = &vect;
}
/* -------------------------------------------------------------------------- */
-template<> inline void Material::unregisterInternal<Real>(InternalField<Real> & 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) {
+template <>
+inline void Material::unregisterInternal<UInt>(InternalField<UInt> & vect) {
internal_vectors_uint.erase(vect.getID());
}
-template<> inline void Material::unregisterInternal<bool>(InternalField<bool> & vect) {
+template <>
+inline void Material::unregisterInternal<bool>(InternalField<bool> & vect) {
internal_vectors_bool.erase(vect.getID());
}
/* -------------------------------------------------------------------------- */
-inline bool Material::isInternal(const ID & id, const ElementKind & element_kind) const {
+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);
+ internal_vectors_real.find(this->getID() + ":" + id);
if (internal_array == internal_vectors_real.end() ||
- internal_array->second->getElementKind() != element_kind) return false;
+ 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 c2449bedb..9f55a061f 100644
--- a/src/model/solid_mechanics/material_selector.hh
+++ b/src/model/solid_mechanics/material_selector.hh
@@ -1,126 +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;
};
/* -------------------------------------------------------------------------- */
-template<typename T>
+/**
+ * Use elemental data to assign materials
+ */
+template <typename T>
class ElementDataMaterialSelector : public MaterialSelector {
public:
ElementDataMaterialSelector(const ElementTypeMapArray<T> & element_data,
const SolidMechanicsModel & model,
- UInt first_index = 1):
- element_data(element_data),
- model(model),
- first_index(first_index)
- {}
+ 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);
}
-private:
+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;
};
/* -------------------------------------------------------------------------- */
-template<typename T>
+/**
+ * class to use mesh data information to assign different materials
+ * where name is the tag value: tag_0, tag_1
+ */
+template <typename T>
class MeshDataMaterialSelector : public ElementDataMaterialSelector<T> {
public:
- MeshDataMaterialSelector(const std::string & name, const SolidMechanicsModel & model, UInt first_index = 1);
+ 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 52de6e0ca..ef2c3ecc2 100644
--- a/src/model/solid_mechanics/materials/internal_field.hh
+++ b/src/model/solid_mechanics/materials/internal_field.hh
@@ -1,217 +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;
-template<typename T>
-class InternalField : public ElementTypeMapArray<T> {
+/**
+ * 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);
+ 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, 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) {};
+ 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 removeQuadraturePoints(const ElementTypeMapArray<UInt> & new_numbering);
+ virtual void
+ removeIntegrationPoints(const ElementTypeMapArray<UInt> & new_numbering);
/// print the content
- virtual void printself(std::ostream & stream, UInt indent = 0) const;
+ virtual void printself(std::ostream & stream, int indent = 0) const;
/// get the default value
inline operator T() const;
- virtual FEEngine & getFEEngine() {
- return *fem;}
- ///AKANTU_GET_MACRO(FEEngine, *fem, FEEngine &);
+ 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) {
+ 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 {
+ 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) {
+ 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");
+ "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 {
+ 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");
+ "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");
+ "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");
+ "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
+ /// 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)
-{
+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 3ed933479..9488faa58 100644
--- a/src/model/solid_mechanics/materials/internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/internal_field_tmpl.hh
@@ -1,338 +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)
+ : 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, 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, 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");
+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) {
+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) {
+template <typename T> void InternalField<T>::setFEEngine(FEEngine & fe_engine) {
this->fem = &fe_engine;
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+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) {
+template <typename T> void InternalField<T>::initialize(UInt nb_component) {
internalInitialize(nb_component);
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-void InternalField<T>::initializeHistory() {
- if(!previous_values)
+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;
+template <typename T> void InternalField<T>::resize() {
+ if (!this->is_init)
+ return;
- for(UInt g = _not_ghost; g <= _ghost; ++g) {
- GhostType gt = (GhostType) g;
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
- typename ElementTypeMapArray<UInt>::type_iterator it
- = element_filter.firstType(spatial_dimension, gt, element_kind);
- typename ElementTypeMapArray<UInt>::type_iterator end
- = element_filter.lastType(spatial_dimension, gt, element_kind);
- for(; it != end; ++it) {
- UInt nb_element = element_filter(*it, gt).getSize();
+ filter_type_iterator it = this->filterFirstType(*gt);
+ filter_type_iterator end = this->filterLastType(*gt);
- UInt nb_quadrature_points = fem->getNbQuadraturePoints(*it, 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);
+ 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));
+ 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());
+ vect->storage() + new_size * vect->getNbComponent());
}
}
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-void InternalField<T>::setDefaultValue(const T & value) {
+template <typename T> void InternalField<T>::setDefaultValue(const T & value) {
this->default_value = value;
this->reset();
}
-
/* -------------------------------------------------------------------------- */
-template<typename T>
-void InternalField<T>::reset() {
- for(UInt g = _not_ghost; g <= _ghost; ++g) {
- GhostType gt = (GhostType) g;
-
- typename ElementTypeMapArray<T>::type_iterator it = this->firstType(spatial_dimension, gt, element_kind);
- typename ElementTypeMapArray<T>::type_iterator end = this->lastType(spatial_dimension, gt, element_kind);
- for(; it != end; ++it) {
- Array<T> & vect = this->operator()(*it, gt);
+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());
+ vect.storage() +
+ vect.getSize() * vect.getNbComponent());
}
}
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+template <typename T>
void InternalField<T>::internalInitialize(UInt nb_component) {
- if(!this->is_init) {
+ if (!this->is_init) {
this->nb_component = nb_component;
- for(UInt g = _not_ghost; g <= _ghost; ++g) {
- GhostType gt = (GhostType) g;
- typename ElementTypeMapArray<UInt>::type_iterator it
- = element_filter.firstType(spatial_dimension, gt, element_kind);
- typename ElementTypeMapArray<UInt>::type_iterator end
- = element_filter.lastType(spatial_dimension, gt, element_kind);
-
- for(; it != end; ++it) {
- UInt nb_element = element_filter(*it, gt).getSize();
- UInt nb_quadrature_points = fem->getNbQuadraturePoints(*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);
+
+ 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(previous_values) previous_values->internalInitialize(nb_component);
+ if (this->previous_values)
+ this->previous_values->internalInitialize(nb_component);
}
/* -------------------------------------------------------------------------- */
-template<typename T>
+template <typename T>
void InternalField<T>::setArrayValues(T * begin, T * end) {
- for(; begin < end; ++begin) *begin = default_value;
+ for (; begin < end; ++begin)
+ *begin = this->default_value;
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-void InternalField<T>::saveCurrentValues() {
- AKANTU_DEBUG_ASSERT(previous_values != NULL,
- "The history of the internal " << this->getID()
- << " has not been activated");
-
- if(!is_init) return;
-
- for(UInt g = _not_ghost; g <= _ghost; ++g) {
- GhostType gt = (GhostType) g;
- typename ElementTypeMapArray<T>::type_iterator it = this->firstType(spatial_dimension, gt, element_kind);
- typename ElementTypeMapArray<T>::type_iterator end = this->lastType(spatial_dimension, gt, element_kind);
- for(; it != end; ++it) {
- this->previous_values->operator()(*it, gt).copy(this->operator()(*it, gt));
+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>::removeQuadraturePoints(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);
+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)){
- const Array<UInt> & renumbering = new_numbering(type, gt);
-
- Array<T> & vect = this->operator()(type, gt);
-
- UInt nb_quad_per_elem = fem->getNbQuadraturePoints(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);
+ 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, UInt indent) const {
+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)) {
+ if (AKANTU_DEBUG_TEST(dblDump)) {
stream << std::endl;
- InternalField<T>::printself(stream, indent + 3);
+ ElementTypeMapArray<T>::printself(stream, indent + 3);
} else {
#endif
- stream << " {"
- << this->getData(_not_ghost).size() << " types - "
- << this->getData(_ghost).size() << " ghost types"
- << "}";
+ 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) {
+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 {
+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 c173bbee0..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,64 +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 104bba1fe..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->getNbQuadraturePoints(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.getNbQuadraturePoints(elem->type);
+ 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 52b584a75..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,726 +1,716 @@
/**
* @file material_cohesive_linear.cc
*
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Tue May 08 2012
- * @date last modification: Thu Aug 07 2014
+ * @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) {
+ insertion_stress("insertion_stress", *this),
+ opening_prec("opening_prec", *this),
+ reduction_penalty("reduction_penalty", *this) {
AKANTU_DEBUG_IN();
- this->registerParam("beta" , beta , Real(0.) ,
+ this->registerParam("beta", beta, Real(0.),
_pat_parsable | _pat_readable,
- "Beta parameter" );
+ "Beta parameter");
- this->registerParam("G_c" , G_c , Real(0.) ,
+ this->registerParam("G_c", G_c, Real(0.),
_pat_parsable | _pat_readable,
- "Mode I fracture energy" );
+ "Mode I fracture energy");
- this->registerParam("penalty", penalty, Real(0.) ,
+ this->registerParam("penalty", penalty, Real(0.),
_pat_parsable | _pat_readable,
- "Penalty coefficient" );
+ "Penalty coefficient");
- this->registerParam("volume_s", volume_s, Real(0.) ,
+ 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.) ,
+ this->registerParam("m_s", m_s, Real(1.),
_pat_parsable | _pat_readable,
"Weibull exponent for sigma_c scaling");
- this->registerParam("kappa" , kappa , Real(1.) ,
+ 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");
- // if (!model->isExplicit())
- use_previous_delta_max = true;
+ this->registerParam("recompute", recompute, false,
+ _pat_parsable | _pat_modifiable,
+ "recompute solution");
+
+ 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);
+ 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();
+ 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.getNbQuadraturePoints(type_facet);
+ 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.getNbQuadraturePoints(elem->type);
+ UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(elem->type);
Vector<Real> unit_vector(nb_quadrature_points, 1);
volume += fe_engine.integrate(unit_vector, elem->type,
elem->element, elem->ghost_type);
}
// scale sigma_c
*sigma_c_iterator -= base_sigma_c;
*sigma_c_iterator *= std::pow(volume_s / volume, 1. / m_s);
*sigma_c_iterator += base_sigma_c;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::checkInsertion(bool check_only) {
AKANTU_DEBUG_IN();
const Mesh & mesh_facets = model->getMeshFacets();
CohesiveElementInserter & inserter = model->getElementInserter();
Real tolerance = Math::getTolerance();
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1);
Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1);
for (; it != last; ++it) {
ElementType type_facet = *it;
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
const Array<bool> & facets_check = inserter.getCheckFacets(type_facet);
Array<bool> & f_insertion = inserter.getInsertionFacets(type_facet);
Array<UInt> & f_filter = facet_filter(type_facet);
Array<Real> & sig_c_eff = sigma_c_eff(type_cohesive);
Array<Real> & del_c = delta_c_eff(type_cohesive);
Array<Real> & ins_stress = insertion_stress(type_cohesive);
Array<Real> & trac_old = tractions_old(type_cohesive);
+ Array<Real> & open_prec = opening_prec(type_cohesive);
+ Array<bool> & red_penalty = reduction_penalty(type_cohesive);
const Array<Real> & f_stress = model->getStressOnFacets(type_facet);
const Array<Real> & sigma_lim = sigma_c(type_facet);
Real max_ratio = 0.;
UInt index_f = 0;
UInt index_filter = 0;
UInt nn = 0;
-
- UInt nb_quad_facet = model->getFEEngine("FacetsFEEngine").getNbQuadraturePoints(type_facet);
+ UInt nb_quad_facet = model->getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
UInt nb_facet = f_filter.getSize();
- if (nb_facet == 0) continue;
+ // 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").getNormalsOnQuadPoints(type_facet);
+ = 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){
- std::cout << "ratio = " << ratio << std::endl;
++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.
+ /// Insertion of only 1 cohesive element in case of implicit approach. The one subjected to the highest stress.
if (!model->isExplicit()){
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Array<Real> abs_max(comm.getNbProc());
abs_max(comm.whoAmI()) = max_ratio;
comm.allGather(abs_max.storage(), 1);
Array<Real>::scalar_iterator it = std::max_element(abs_max.begin(), abs_max.end());
Int pos = it - abs_max.begin();
if (pos != comm.whoAmI()) {
AKANTU_DEBUG_OUT();
return;
}
if (nn) {
f_insertion(index_filter) = true;
if (!check_only) {
// Array<Real>::iterator<Matrix<Real> > normal_traction_it =
// normal_traction.begin_reinterpret(nb_quad_facet, spatial_dimension, nb_facet);
Array<Real>::const_iterator<Real> sigma_lim_it = sigma_lim.begin();
for (UInt q = 0; q < nb_quad_facet; ++q) {
// Vector<Real> ins_s(normal_traction_it[index_f].storage() + q * spatial_dimension,
// spatial_dimension);
Real new_sigma = (sigma_lim_it[index_f]);
Vector<Real> normal_traction_vec(spatial_dimension, 0.0);
new_sigmas.push_back(new_sigma);
new_normal_traction.push_back(normal_traction_vec);
Real new_delta;
//set delta_c in function of G_c or a given delta_c value
if (!Math::are_float_equal(delta_c, 0.))
new_delta = delta_c;
else
new_delta = 2 * G_c / (new_sigma);
new_delta_c.push_back(new_delta);
}
}
}
}
// update material data for the new elements
UInt old_nb_quad_points = sig_c_eff.getSize();
UInt new_nb_quad_points = new_sigmas.size();
sig_c_eff.resize(old_nb_quad_points + new_nb_quad_points);
ins_stress.resize(old_nb_quad_points + new_nb_quad_points);
trac_old.resize(old_nb_quad_points + new_nb_quad_points);
del_c.resize(old_nb_quad_points + new_nb_quad_points);
+ open_prec.resize(old_nb_quad_points + new_nb_quad_points);
+ red_penalty.resize(old_nb_quad_points + new_nb_quad_points);
for (UInt q = 0; q < new_nb_quad_points; ++q) {
sig_c_eff(old_nb_quad_points + q) = new_sigmas[q];
del_c(old_nb_quad_points + q) = new_delta_c[q];
+ red_penalty(old_nb_quad_points + q) = false;
for (UInt dim = 0; dim < spatial_dimension; ++dim) {
ins_stress(old_nb_quad_points + q, dim) = new_normal_traction[q](dim);
trac_old(old_nb_quad_points + q, dim) = new_normal_traction[q](dim);
+ open_prec(old_nb_quad_points + q, dim) = 0.;
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
- Array<Real>::iterator< Vector<Real> > traction_it =
+ Array<Real>::vector_iterator traction_it =
tractions(el_type, ghost_type).begin(spatial_dimension);
- Array<Real>::iterator< Vector<Real> > opening_it =
+ Array<Real>::vector_iterator opening_it =
opening(el_type, ghost_type).begin(spatial_dimension);
- Array<Real>::iterator< Vector<Real> > contact_traction_it =
+ /// 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 contact_traction_it =
contact_tractions(el_type, ghost_type).begin(spatial_dimension);
- 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>::const_iterator< Vector<Real> > normal_it =
+ Array<Real>::const_vector_iterator normal_it =
normal.begin(spatial_dimension);
- Array<Real>::iterator< Vector<Real> >traction_end =
+ 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>::iterator<Vector<Real> > insertion_stress_it =
+ Array<Real>::vector_iterator insertion_stress_it =
insertion_stress(el_type, ghost_type).begin(spatial_dimension);
+ 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> 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, ++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) {
-
- if (!model->isExplicit())
- *delta_max_it = *delta_max_prev_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 (penetration) {
- /// use penalty coefficient in case of penetration
- *contact_traction_it = normal_opening;
- *contact_traction_it *= 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);
-
- /// 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);
-
- }
+ ++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.
+
+ /**
+ * This function set a predefined value to the parameter
+ * delta_max_prev of the elements that have been inserted in the
+ * last loading step for which convergence has not been
+ * reached. This is done before reducing the loading and re-doing
+ * the step. Otherwise, the updating of delta_max_prev would be
+ * done with reference to the non-convergent solution. In this
+ * function also other variables related to the contact and
+ * friction behavior are correctly set.
+ */
Mesh & mesh = fem_cohesive->getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type, _ek_cohesive);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
ghost_type, _ek_cohesive);
+ /**
+ * the variable "recompute" is set to true to activate the
+ * procedure that reduce the penalty parameter for
+ * compression. This procedure is set true only during the phase of
+ * load_reduction, that has to be set in the maiin file. The
+ * penalty parameter will be reduced only for the elements having
+ * reduction_penalty = true.
+ */
+ recompute = true;
+
for(; it != last_type; ++it) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
UInt nb_element = elem_filter.getSize();
if (nb_element == 0) continue;
ElementType el_type = *it;
/// define iterators
- Array<Real>::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);
/// loop on each quadrature point
for (; delta_max_it != delta_max_end;
- ++delta_max_it, ++delta_max_prev_it, ++delta_c_it) {
+ ++delta_max_it, ++delta_max_prev_it, ++delta_c_it,
+ ++opening_prec_it, ++opening_prec_prev_it) {
if (*delta_max_prev_it == 0)
- /// elements inserted in the last step, that has not converged
+ /// elements inserted in the last incremental step, that did
+ /// not converge
*delta_max_it = *delta_c_it / 1000;
else
- /// elements introduced in previous steps, for which a correct
- /// value of delta_max_prev already exists
+ /// 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;
+
}
}
}
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialCohesiveLinear<spatial_dimension>::resetVariables(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ /**
+ * This function set the variables "recompute" and
+ * "reduction_penalty" to false. It is called by solveStepCohesive
+ * when convergence is reached. Such variables, in fact, have to be
+ * false at the beginning of a new incremental step.
+ */
+
+ Mesh & mesh = fem_cohesive->getMesh();
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension,
+ ghost_type, _ek_cohesive);
+ Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
+ ghost_type, _ek_cohesive);
+
+ recompute = false;
+
+ for(; it != last_type; ++it) {
+ Array<UInt> & elem_filter = element_filter(*it, ghost_type);
+
+ UInt nb_element = elem_filter.getSize();
+ if (nb_element == 0) continue;
+
+ ElementType el_type = *it;
+
+ Array<bool>::scalar_iterator reduction_penalty_it =
+ reduction_penalty(el_type, ghost_type).begin();
+
+ Array<bool>::scalar_iterator reduction_penalty_end =
+ reduction_penalty(el_type, ghost_type).end();
+
+ /// loop on each quadrature point
+ for (; reduction_penalty_it != reduction_penalty_end;
+ ++reduction_penalty_it) {
+
+ *reduction_penalty_it = false;
+ }
+ }
+}
+
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
Array<Real>::matrix_iterator tangent_it =
tangent_matrix.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator tangent_end =
tangent_matrix.end(spatial_dimension, spatial_dimension);
Array<Real>::const_vector_iterator normal_it =
normal.begin(spatial_dimension);
Array<Real>::vector_iterator opening_it =
opening(el_type, ghost_type).begin(spatial_dimension);
- Array<Real>::iterator<Real>delta_max_it =
+ /// NB: delta_max_it points on delta_max_previous, i.e. the
+ /// delta_max related to the solution of the previous incremental
+ /// step
+ Array<Real>::scalar_iterator delta_max_it =
delta_max.previous(el_type, ghost_type).begin();
- Array<Real>::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<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);
- Array<Real> tang_output(spatial_dimension,spatial_dimension);
-
for (; tangent_it != tangent_end;
- ++tangent_it, ++normal_it, ++opening_it, ++ delta_max_it,
- ++sigma_c_it, ++delta_c_it, ++damage_it, ++contact_opening_it) {
-
- /// compute normal and tangential opening vectors
- *opening_it += *contact_opening_it;
- 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;
- 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){
- /// don't consider penetration contribution for delta
- *opening_it = tangential_opening;
- normal_opening_norm = opening_it->dot(*normal_it);
- normal_opening = (*normal_it);
- normal_opening *= normal_opening_norm;
- // std::cout << "normal opening in case of penetration = " << normal_opening << std::endl;
-
- /// stiffness in compression given by the penalty parameter
- *tangent_it += n_outer_n;
- *tangent_it *= penalty;
- }
- 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 (!penetration){
- if (delta >= *delta_max_it){
- derivative = -*sigma_c_it/(delta * delta);
- t = *sigma_c_it * (1 - delta / *delta_c_it);
- } 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;
- *tangent_it += prov;
-
- /// 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-13){
- std::cout << "non symmetric cohesive matrix" << std::endl;
- std::cout << "error " << error << std::endl;
- }
- }
- }
- }
- }
+ ++tangent_it, ++normal_it, ++opening_it,
+ ++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
+ ++contact_opening_it, ++reduction_penalty_it) {
+
+ Real normal_opening_norm, tangential_opening_norm;
+ bool penetration;
+ Real current_penalty = 0.;
+ this->computeTangentTractionOnQuad(*tangent_it,
+ *delta_max_it,
+ *delta_c_it,
+ *sigma_c_it,
+ *opening_it,
+ *normal_it,
+ normal_opening,
+ tangential_opening,
+ normal_opening_norm,
+ tangential_opening_norm,
+ *damage_it,
+ penetration,
+ *reduction_penalty_it,
+ current_penalty,
+ *contact_opening_it);
+
+ // check if the tangential stiffness matrix is symmetric
+ // for (UInt h = 0; h < spatial_dimension; ++h){
+ // for (UInt l = h; l < spatial_dimension; ++l){
+ // if (l > h){
+ // Real k_ls = (*tangent_it)[spatial_dimension*h+l];
+ // Real k_us = (*tangent_it)[spatial_dimension*l+h];
+ // // std::cout << "k_ls = " << k_ls << std::endl;
+ // // std::cout << "k_us = " << k_us << std::endl;
+ // if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
+ // Real error = std::abs((k_ls - k_us) / k_us);
+ // if (error > 1e-10){
+ // std::cout << "non symmetric cohesive matrix" << std::endl;
+ // // std::cout << "error " << error << std::endl;
+ // }
+ // }
+ // }
+ // }
+ // }
}
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialCohesiveLinear);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh
index d3b3dc3f8..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,176 +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;
+ /// 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;
+
+ /**
+ * 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;
+
};
/* -------------------------------------------------------------------------- */
/* 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 b416455f5..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;
+ // 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);
+ // 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_linear_friction.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
new file mode 100644
index 000000000..841913221
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
@@ -0,0 +1,112 @@
+/**
+ * @file material_cohesive_linear_friction.hh
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Jan 12 2016
+ *
+ * @brief Linear irreversible cohesive law of mixed mode loading with
+ * random stress definition for extrinsic type
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#include "material_cohesive_linear.hh"
+
+/* -------------------------------------------------------------------------- */
+#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
+#define __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/**
+ * Cohesive material linear with friction force
+ *
+ * parameters in the material files :
+ * - mu : friction coefficient
+ * - penalty_for_friction : Penalty parameter for the friction behavior
+ */
+template<UInt spatial_dimension>
+class MaterialCohesiveLinearFriction : public MaterialCohesiveLinear<spatial_dimension> {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+ typedef MaterialCohesiveLinear<spatial_dimension> MaterialParent;
+public:
+
+ MaterialCohesiveLinearFriction(SolidMechanicsModel & model, const ID & id = "");
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ /// initialize the material parameters
+ virtual void initMaterial();
+
+protected:
+ /// constitutive law
+ virtual void computeTraction(const Array<Real> & normal,
+ ElementType el_type,
+ GhostType ghost_type = _not_ghost);
+
+ /// check delta_max for cohesive elements in case of no convergence
+ /// in the solveStep (only for extrinsic-implicit)
+ virtual void checkDeltaMax(GhostType ghost_type = _not_ghost);
+
+
+ /// compute tangent stiffness matrix
+ virtual void computeTangentTraction(const ElementType & el_type,
+ Array<Real> & tangent_matrix,
+ const Array<Real> & normal,
+ GhostType ghost_type);
+
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ /// maximum value of the friction coefficient
+ Real mu_max;
+
+ /// penalty parameter for the friction law
+ Real friction_penalty;
+
+ /// history parameter for the friction law
+ CohesiveInternalField<Real> residual_sliding;
+
+ /// friction force
+ CohesiveInternalField<Real> friction_force;
+};
+
+__END_AKANTU__
+
+#endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc
index 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 9c2cae430..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,630 +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();
-
- 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 (model->getIsExtrinsic()) this->sigma_c.initialize(1);
- if (use_previous_delta_max) delta_max.initializeHistory();
-
+ 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->getNbQuadraturePoints(*it, ghost_type);
+ 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->getNbQuadraturePoints(*it, ghost_type);
+ 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
- computeTraction(ghost_type);
+ /// 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->getNbQuadraturePoints(*it, ghost_type);
+ 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->computeNormalsOnControlPoints(position,
+ fem_cohesive->computeNormalsOnIntegrationPoints(position,
normal,
type, ghost_type);
else {
#define COMPUTE_NORMAL(type) \
fem_cohesive->getShapeFunctions(). \
- computeNormalsOnControlPoints<type, CohesiveReduceFunctionMean>(position, \
+ 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(). \
- interpolateOnControlPoints<type, CohesiveReduceFunctionOpening>(displacement, \
+ 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->getNbQuadraturePoints(*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.;
}
-/* -------------------------------------------------------------------------- */
-inline ElementTypeMap<UInt> MaterialCohesive::getInternalDataPerElem(const ID & id,
- const ElementKind & element_kind,
- const ID & fe_engine_id) const {
- if (element_kind == _ek_cohesive) {
- return Material::getInternalDataPerElem(id, element_kind, "CohesiveFEEngine");
- } else {
- return Material::getInternalDataPerElem(id, element_kind, fe_engine_id);
- }
-}
-
/* -------------------------------------------------------------------------- */
__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 248520262..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,260 +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(__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){};
- virtual void computeAllStresses(__attribute__((unused)) GhostType ghost_type = _not_ghost) { };
+ /// compute the stresses
+ virtual void computeAllStresses(__attribute__((unused))
+ GhostType ghost_type = _not_ghost){};
// add the facet to be handled by the material
UInt addFacet(const Element & element);
protected:
- virtual void computeTangentTraction(__attribute__((unused)) const ElementType & el_type,
- __attribute__((unused)) Array<Real> & tangent_matrix,
- __attribute__((unused)) const Array<Real> & normal,
- __attribute__((unused)) GhostType ghost_type = _not_ghost) {
+ 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);
- virtual ElementTypeMap<UInt> getInternalDataPerElem(const ID & id,
- const ElementKind & element_kind,
- const ID & fe_engine_id) const;
-
- 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);
- 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);
+ template <ElementType type>
+ void computeNormal(const Array<Real> & position, Array<Real> & normal,
+ GhostType ghost_type);
/// assemble stiffness
void assembleStiffnessMatrix(GhostType ghost_type);
/// constitutive law
- virtual void computeTraction(const Array<Real> & normal,
- ElementType el_type,
- GhostType ghost_type = _not_ghost) = 0;
+ 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;
+ SynchronizationTag tag) const;
inline void packElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) const;
+ const Array<Element> & elements,
+ SynchronizationTag tag) const;
inline void unpackElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag);
+ 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 958271fd9..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().getNbQuadraturePoints(elements, "CohesiveFEEngine");
+ return 2 * spatial_dimension * sizeof(Real) * this->getModel().getNbIntegrationPoints(elements, "CohesiveFEEngine");
}
case _gst_smmc_damage: {
- return sizeof(Real) * this->getModel().getNbQuadraturePoints(elements, "CohesiveFEEngine");
+ 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 0470be6ea..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,102 +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,
- template <UInt> class WeightFunction = BaseWeightFunction>
+ class MaterialDamageLocal>
class MaterialDamageNonLocal : public MaterialDamageLocal,
- public MaterialNonLocal<spatial_dimension, WeightFunction> {
+ public MaterialNonLocal<spatial_dimension> {
public:
- typedef MaterialNonLocal<spatial_dimension, WeightFunction> MaterialNonLocalParent;
+ 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 c705df553..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,106 +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 e67baaa98..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().getNbQuadraturePoints(elements);
+ 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 8eb524408..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,97 +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, template <UInt> class WeightFunction = BaseWeightFunction>
-class MaterialMarigoNonLocal : public MaterialDamageNonLocal<spatial_dimension, MaterialMarigo<spatial_dimension>, WeightFunction> {
+template<UInt spatial_dimension>
+class MaterialMarigoNonLocal : public MaterialDamageNonLocal<spatial_dimension, MaterialMarigo<spatial_dimension> > {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef MaterialDamageNonLocal<spatial_dimension, MaterialMarigo<spatial_dimension>, WeightFunction> MaterialMarigoNonLocalParent;
+ 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 2948a9cbe..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,102 +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, template <UInt> class WeigthFunction>
-MaterialMarigoNonLocal<spatial_dimension, WeigthFunction>::MaterialMarigoNonLocal(SolidMechanicsModel & model, const ID & id) :
+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, template <UInt> class WeigthFunction>
-void MaterialMarigoNonLocal<spatial_dimension, WeigthFunction>::initMaterial() {
+template<UInt spatial_dimension>
+void MaterialMarigoNonLocal<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
- this->registerNonLocalVariable(Y, Ynl, 1);
MaterialMarigoNonLocalParent::initMaterial();
+ this->model->getNonLocalManager().nonLocalVariableToNeighborhood(Ynl.getName(), this->name);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeigthFunction>
-void MaterialMarigoNonLocal<spatial_dimension, WeigthFunction>::computeStress(ElementType el_type, GhostType ghost_type) {
+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, template <UInt> class WeigthFunction>
-void MaterialMarigoNonLocal<spatial_dimension, WeigthFunction>::computeNonLocalStress(ElementType type,
+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 e9032724e..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,145 +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);
- for(; it != last_type; ++it) {
- this->computeNonLocalStress(nl_var(*it, ghost_type), *it, ghost_type);
- }
+ // if(this->damage_in_compute_stress)
+ // this->weightedAvergageOnNeighbours(this->damage, nl_var, 1);
+ // else
+ // this->weightedAvergageOnNeighbours(this->Ehat, nl_var, 1);
+
+ // Mesh::type_iterator it =
+ // this->model->getFEEngine().getMesh().firstType(spatial_dimension,
+ // ghost_type);
+ // Mesh::type_iterator last_type =
+ // this->model->getFEEngine().getMesh().lastType(spatial_dimension,
+ // ghost_type);
+ // for(; it != last_type; ++it) {
+ // this->computeNonLocalStress(nl_var(*it, ghost_type), *it, ghost_type);
+ // }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void MaterialMazarsNonLocal<spatial_dimension>::computeNonLocalStress(Array<Real> & non_loc_var,
- ElementType el_type,
- GhostType ghost_type) {
+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() {}
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 8e2e0a44c..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,98 +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, BaseWeightFunction> {
+ public MaterialNonLocal<spatial_dimension> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- typedef MaterialNonLocal<spatial_dimension, BaseWeightFunction> MaterialNonLocalParent;
+ 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 e7d96ce74..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().getNbQuadraturePoints(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 9b0702649..90ba0261e 100644
--- a/src/model/solid_mechanics/materials/material_elastic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic.hh
@@ -1,148 +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 884bb54dd..137737be7 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
@@ -1,332 +1,332 @@
/**
* @file material_elastic_linear_anisotropic.cc
*
* @author Till Junge <till.junge@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Sep 25 2013
- * @date last modification: Fri Sep 19 2014
+ * @date last modification: Thu Oct 15 2015
*
* @brief Anisotropic elastic material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "material_elastic_linear_anisotropic.hh"
#include "solid_mechanics_model.hh"
#include <algorithm>
#include <sstream>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialElasticLinearAnisotropic<spatial_dimension>::
MaterialElasticLinearAnisotropic(SolidMechanicsModel & model,
const ID & id,
bool symmetric) :
Material(model, id),
rot_mat(spatial_dimension, spatial_dimension),
Cprime(spatial_dimension*spatial_dimension,
spatial_dimension*spatial_dimension),
C(this->voigt_h.size, this->voigt_h.size),
eigC(this->voigt_h.size),
symmetric(symmetric),
alpha(0) {
AKANTU_DEBUG_IN();
this->dir_vecs.push_back(new Vector<Real>(spatial_dimension));
(*this->dir_vecs.back())[0] = 1.;
this->registerParam("n1", *(this->dir_vecs.back()), _pat_parsmod,
"Direction of main material axis");
this->dir_vecs.push_back(new Vector<Real>(spatial_dimension));
(*this->dir_vecs.back())[1] = 1.;
this->registerParam("n2", *(this->dir_vecs.back()), _pat_parsmod,
"Direction of secondary material axis");
if (spatial_dimension > 2) {
this->dir_vecs.push_back(new Vector<Real>(spatial_dimension));
(*this->dir_vecs.back())[2] = 1.;
this->registerParam("n3", *(this->dir_vecs.back()), _pat_parsmod,
"Direction of tertiary material axis");
}
for (UInt i = 0 ; i < this->voigt_h.size ; ++i) {
UInt start = 0;
if (this->symmetric) {
start = i;
}
for (UInt j = start ; j < this->voigt_h.size ; ++j) {
std::stringstream param("C");
param << "C" << i+1 << j+1;
this->registerParam(param.str() , this->Cprime(i,j), Real(0.), _pat_parsmod,
"Coefficient " + param.str());
}
}
this->registerParam("alpha", this->alpha, _pat_parsmod,
"Proportion of viscous stress");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialElasticLinearAnisotropic<spatial_dimension>::~MaterialElasticLinearAnisotropic() {
for (UInt i = 0 ; i < spatial_dimension ; ++i) {
delete this->dir_vecs[i];
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticLinearAnisotropic<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticLinearAnisotropic<spatial_dimension>::updateInternalParameters() {
Material::updateInternalParameters();
if (this->symmetric) {
for (UInt i = 0 ; i < this->voigt_h.size ; ++i) {
for (UInt j = i+1 ; j < this->voigt_h.size ; ++j) {
this->Cprime(j, i) = this->Cprime(i, j);
}
}
}
this->rotateCprime();
this->C.eig(this->eigC);
}
/* -------------------------------------------------------------------------- */
template<UInt Dim>
void MaterialElasticLinearAnisotropic<Dim>::rotateCprime() {
// start by filling the empty parts fo Cprime
UInt diff = Dim*Dim - this->voigt_h.size;
for (UInt i = this->voigt_h.size ; i < Dim*Dim ; ++i) {
for (UInt j = 0 ; j < Dim*Dim ; ++j) {
this->Cprime(i, j) = this->Cprime(i-diff, j);
}
}
for (UInt i = 0 ; i < Dim*Dim ; ++i) {
for (UInt j = this->voigt_h.size ; j < Dim*Dim ; ++j) {
this->Cprime(i, j) = this->Cprime(i, j-diff);
}
}
// construction of rotator tensor
// normalise rotation matrix
for (UInt j = 0 ; j < Dim ; ++j) {
Vector<Real> rot_vec = this->rot_mat(j);
rot_vec = *this->dir_vecs[j];
rot_vec.normalize();
}
// make sure the vectors form a right-handed base
Vector<Real> test_axis(3);
Vector<Real> v1(3), v2(3), v3(3);
if (Dim == 2){
for (UInt i = 0; i < Dim; ++i) {
v1[i] = this->rot_mat(0, i);
v2[i] = this->rot_mat(1, i);
v3[i] = 0.;
}
v3[2] = 1.;
v1[2] = 0.;
v2[2] = 0.;
}
else if (Dim == 3){
v1 = this->rot_mat(0);
v2 = this->rot_mat(1);
v3 = this->rot_mat(2);
}
test_axis.crossProduct(v1,v2);
test_axis -= v3;
if (test_axis.norm() > 8*std::numeric_limits<Real>::epsilon()) {
AKANTU_DEBUG_ERROR("The axis vectors do not form a right-handed coordinate "
<< "system. I. e., ||n1 x n2 - n3|| should be zero, but "
<< "it is " << test_axis.norm() << ".");
}
// create the rotator and the reverse rotator
Matrix<Real> rotator(Dim * Dim, Dim * Dim);
Matrix<Real> revrotor(Dim * Dim, Dim * Dim);
for (UInt i = 0 ; i < Dim ; ++i) {
for (UInt j = 0 ; j < Dim ; ++j) {
for (UInt k = 0 ; k < Dim ; ++k) {
for (UInt l = 0 ; l < Dim ; ++l) {
UInt I = this->voigt_h.mat[i][j];
UInt J = this->voigt_h.mat[k][l];
rotator (I, J) = this->rot_mat(k, i) * this->rot_mat(l, j);
revrotor(I, J) = this->rot_mat(i, k) * this->rot_mat(j, l);
}
}
}
}
// create the full rotated matrix
Matrix<Real> Cfull(Dim*Dim, Dim*Dim);
Cfull = rotator*Cprime*revrotor;
for (UInt i = 0 ; i < this->voigt_h.size ; ++i) {
for (UInt j = 0 ; j < this->voigt_h.size ; ++j) {
this->C(i, j) = Cfull(i, j);
}
}
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticLinearAnisotropic<spatial_dimension>::computeStress(ElementType el_type,
GhostType ghost_type) {
// Wikipedia convention:
// 2*eps_ij (i!=j) = voigt_eps_I
// http://en.wikipedia.org/wiki/Voigt_notation
AKANTU_DEBUG_IN();
Array<Real>::iterator< Matrix<Real> > gradu_it =
this->gradu(el_type, ghost_type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::iterator< Matrix<Real> > gradu_end =
this->gradu(el_type, ghost_type).end(spatial_dimension,
spatial_dimension);
UInt nb_quad_pts = gradu_end - gradu_it;
// create array for strains and stresses of all dof of all gauss points
// for efficient computation of stress
Matrix<Real> voigt_strains(this->voigt_h.size, nb_quad_pts);
Matrix<Real> voigt_stresses(this->voigt_h.size, nb_quad_pts);
// copy strains
Matrix<Real> strain(spatial_dimension, spatial_dimension);
for (UInt q = 0; gradu_it != gradu_end ; ++gradu_it, ++q) {
Matrix<Real> & grad_u = *gradu_it;
for(UInt I = 0; I < this->voigt_h.size; ++I) {
Real voigt_factor = this->voigt_h.factors[I];
UInt i = this->voigt_h.vec[I][0];
UInt j = this->voigt_h.vec[I][1];
voigt_strains(I, q) = voigt_factor * (grad_u(i, j) + grad_u(j, i)) / 2.;
}
}
// compute the strain rate proportional part if needed
//bool viscous = this->alpha == 0.; // only works if default value
bool viscous = false;
if(viscous) {
Array<Real> strain_rate(0, spatial_dimension * spatial_dimension,
"strain_rate");
Array<Real> & velocity = this->model->getVelocity();
const Array<UInt> & elem_filter = this->element_filter(el_type, ghost_type);
- this->model->getFEEngine().gradientOnQuadraturePoints(velocity, strain_rate,
+ this->model->getFEEngine().gradientOnIntegrationPoints(velocity, strain_rate,
spatial_dimension, el_type,
ghost_type, elem_filter);
Array<Real>::matrix_iterator gradu_dot_it = strain_rate.begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator gradu_dot_end = strain_rate.end(spatial_dimension,
spatial_dimension);
Matrix<Real> strain_dot(spatial_dimension, spatial_dimension);
for (UInt q = 0; gradu_dot_it != gradu_dot_end ; ++gradu_dot_it, ++q) {
Matrix<Real> & grad_u_dot = *gradu_dot_it;
for(UInt I = 0; I < this->voigt_h.size; ++I) {
Real voigt_factor = this->voigt_h.factors[I];
UInt i = this->voigt_h.vec[I][0];
UInt j = this->voigt_h.vec[I][1];
voigt_strains(I, q) = this->alpha * voigt_factor * (grad_u_dot(i, j) + grad_u_dot(j, i)) / 2.;
}
}
}
// compute stresses
voigt_stresses = this->C * voigt_strains;
// copy stresses back
Array<Real>::iterator< Matrix<Real> > stress_it =
this->stress(el_type, ghost_type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::iterator< Matrix<Real> > stress_end =
this->stress(el_type, ghost_type).end(spatial_dimension,
spatial_dimension);
for (UInt q = 0 ; stress_it != stress_end; ++stress_it, ++q) {
Matrix<Real> & stress = *stress_it;
for(UInt I = 0; I < this->voigt_h.size; ++I) {
UInt i = this->voigt_h.vec[I][0];
UInt j = this->voigt_h.vec[I][1];
stress(i, j) = stress(j, i) = voigt_stresses(I, q);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticLinearAnisotropic<spatial_dimension>::computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
tangent.copy(this->C);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialElasticLinearAnisotropic<spatial_dimension>::getCelerity(__attribute__((unused)) const Element & element) const {
return std::sqrt( this->eigC(0) / rho);
}
/* -------------------------------------------------------------------------- */
INSTANTIATE_MATERIAL(MaterialElasticLinearAnisotropic);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
index 504e407f1..60321279a 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
@@ -1,120 +1,121 @@
/**
* @file material_elastic_linear_anisotropic.hh
*
* @author Till Junge <till.junge@epfl.ch>
*
- * @date creation: Wed Sep 25 2013
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Tue Aug 18 2015
*
* @brief Orthotropic elastic material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material.hh"
#include "material_elastic.hh"
#include <vector>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_HH__
#define __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_HH__
__BEGIN_AKANTU__
/**
* General linear anisotropic elastic material
* The only constraint on the elastic tensor is that it can be represented
* as a symmetric 6x6 matrix (3D) or 3x3 (2D).
*
* parameters in the material files :
* - rho : density (default: 0)
* - C_ij : entry on the stiffness
*/
template<UInt Dim>
class MaterialElasticLinearAnisotropic : public virtual Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialElasticLinearAnisotropic(SolidMechanicsModel & model, const ID & id = "",
bool symmetric = true);
~MaterialElasticLinearAnisotropic();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void initMaterial();
/// constitutive law for all element of a type
virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
/// compute the tangent stiffness matrix for an element type
void computeTangentModuli(const ElementType & el_type,
Array<Real> & tangent_matrix,
GhostType ghost_type = _not_ghost);
virtual void updateInternalParameters();
protected:
// compute C from Cprime
void rotateCprime();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// compute max wave celerity
virtual Real getCelerity(const Element & element) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
const static VoigtHelper<Dim> voigt_h;
/// direction matrix and vectors
std::vector<Vector<Real>*> dir_vecs;
Matrix<Real> rot_mat;
/// Elastic stiffness tensor in material frame and full vectorised notation
Matrix<Real> Cprime;
/// Elastic stiffness tensor in voigt notation
Matrix<Real> C;
/// eigenvalues of stiffness tensor
Vector<Real> eigC;
bool symmetric;
/// viscous proportion
Real alpha;
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
index 3c0316f20..e0a992e4e 100644
--- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
@@ -1,212 +1,213 @@
/**
* @file material_elastic_orthotropic.cc
*
* @author Till Junge <till.junge@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
*
- * @date creation: Tue May 08 2012
- * @date last modification: Fri Sep 19 2014
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
*
* @brief Orthotropic elastic material
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "material_elastic_orthotropic.hh"
#include "solid_mechanics_model.hh"
#include <algorithm>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt Dim>
MaterialElasticOrthotropic<Dim>::MaterialElasticOrthotropic(SolidMechanicsModel & model,
const ID & id) :
Material(model, id),
MaterialElasticLinearAnisotropic<Dim>(model, id) {
AKANTU_DEBUG_IN();
this->registerParam("E1", E1 , Real(0.), _pat_parsmod, "Young's modulus (n1)");
this->registerParam("E2", E2 , Real(0.), _pat_parsmod, "Young's modulus (n2)");
this->registerParam("nu12", nu12, Real(0.), _pat_parsmod, "Poisson's ratio (12)");
this->registerParam("G12", G12 , Real(0.), _pat_parsmod, "Shear modulus (12)");
if (Dim > 2) {
this->registerParam("E3" , E3 , Real(0.), _pat_parsmod, "Young's modulus (n3)");
this->registerParam("nu13", nu13, Real(0.), _pat_parsmod, "Poisson's ratio (13)");
this->registerParam("nu23", nu23, Real(0.), _pat_parsmod, "Poisson's ratio (23)");
this->registerParam("G13" , G13 , Real(0.), _pat_parsmod, "Shear modulus (13)");
this->registerParam("G23" , G23 , Real(0.), _pat_parsmod, "Shear modulus (23)");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt Dim>
MaterialElasticOrthotropic<Dim>::~MaterialElasticOrthotropic() {
}
/* -------------------------------------------------------------------------- */
template<UInt Dim>
void MaterialElasticOrthotropic<Dim>::initMaterial() {
AKANTU_DEBUG_IN();
Material::initMaterial();
updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline Real vector_norm(Vector<Real> & vec) {
Real norm = 0;
for (UInt i = 0 ; i < vec.size() ; ++i) {
norm += vec(i)*vec(i);
}
return std::sqrt(norm);
}
/* -------------------------------------------------------------------------- */
template<UInt Dim>
void MaterialElasticOrthotropic<Dim>::updateInternalParameters() {
/* 1) construction of temporary material frame stiffness tensor------------ */
// http://solidmechanics.org/Text/Chapter3_2/Chapter3_2.php#Sect3_2_13
Real nu21 = nu12 * E2 / E1;
Real nu31 = nu13 * E3 / E1;
Real nu32 = nu23 * E3 / E2;
// Full (i.e. dim^2 by dim^2) stiffness tensor in material frame
if (Dim == 1) {
AKANTU_DEBUG_ERROR("Dimensions 1 not implemented: makes no sense to have orthotropy for 1D");
}
Real Gamma;
if (Dim == 3)
Gamma = 1/(1 - nu12 * nu21 - nu23 * nu32 - nu31 * nu13 - 2 * nu21 * nu32 * nu13);
if (Dim == 2)
Gamma = 1/(1 - nu12 * nu21);
// Lamé's first parameters
this->Cprime(0, 0) = E1 * (1 - nu23 * nu32) * Gamma;
this->Cprime(1, 1) = E2 * (1 - nu13 * nu31) * Gamma;
if (Dim == 3)
this->Cprime(2, 2) = E3 * (1 - nu12 * nu21) * Gamma;
// normalised poisson's ratio's
this->Cprime(1, 0) = this->Cprime(0, 1) = E1 * (nu21 + nu31 * nu23) * Gamma;
if (Dim == 3) {
this->Cprime(2, 0) = this->Cprime(0, 2) = E1 * (nu31 + nu21 * nu32) * Gamma;
this->Cprime(2, 1) = this->Cprime(1, 2) = E2 * (nu32 + nu12 * nu31) * Gamma;
}
// Lamé's second parameters (shear moduli)
if (Dim == 3) {
this->Cprime(3, 3) = G23;
this->Cprime(4, 4) = G13;
this->Cprime(5, 5) = G12;
}
else
this->Cprime(2, 2) = G12;
/* 1) rotation of C into the global frame */
this->rotateCprime();
this->C.eig(this->eigC);
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
inline void MaterialElasticOrthotropic<dim>::computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
const Matrix<Real> & sigma,
Real & epot) {
epot = .5 * sigma.doubleDot(grad_u);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticOrthotropic<spatial_dimension>::computePotentialEnergy(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Material::computePotentialEnergy(el_type, ghost_type);
AKANTU_DEBUG_ASSERT(!this->finite_deformation,"finite deformation not possible in material orthotropic (TO BE IMPLEMENTED)");
if(ghost_type != _not_ghost) return;
Array<Real>::scalar_iterator epot = this->potential_energy(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computePotentialEnergyOnQuad(grad_u, sigma, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElasticOrthotropic<spatial_dimension>::computePotentialEnergyByElement(ElementType type, UInt index,
Vector<Real> & epot_on_quad_points) {
AKANTU_DEBUG_ASSERT(!this->finite_deformation,"finite deformation not possible in material orthotropic (TO BE IMPLEMENTED)");
Array<Real>::matrix_iterator gradu_it =
this->gradu(type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator gradu_end =
this->gradu(type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator stress_it =
this->stress(type).begin(spatial_dimension,
spatial_dimension);
- UInt nb_quadrature_points = this->model->getFEEngine().getNbQuadraturePoints(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;
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 2e26fd033..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,743 +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").getNbQuadraturePoints(int_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);
+ 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").getNbQuadraturePoints(type);
+ 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);
+ 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.getNbQuadraturePoints(interface_type, ghost_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").getNbQuadraturePoints(type, ghost_type);
+ 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.getNbQuadraturePoints(interface_type, ghost_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.getNbQuadraturePoints(*interface_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.interpolateOnQuadraturePoints(interface_mesh.getNodes(),
+ 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();
-}
+// /* -------------------------------------------------------------------------- */
+// 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 e6b5ffeb6..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;
+ // 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;
+ // /// 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 0d8f1a3f5..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").getNbQuadraturePoints(type);
+ 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 b558272a8..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,166 +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
new file mode 100644
index 000000000..22833e4d8
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_non_local.cc
@@ -0,0 +1,172 @@
+/**
+ * @file material_non_local.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "material_non_local.hh"
+/* -------------------------------------------------------------------------- */
+__BEGIN_AKANTU__
+/* -------------------------------------------------------------------------- */
+template <UInt DIM>
+MaterialNonLocal<DIM>::MaterialNonLocal(SolidMechanicsModel & model,
+ const ID & id)
+ : Material(model, id) {
+ AKANTU_DEBUG_IN();
+
+ NonLocalManager & manager = this->model->getNonLocalManager();
+ manager.registerNonLocalMaterial(*this);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <UInt spatial_dimension>
+MaterialNonLocal<spatial_dimension>::~MaterialNonLocal() {}
+
+/* -------------------------------------------------------------------------- */
+template <UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::initMaterial() {
+ this->registerNeighborhood();
+ this->insertQuadsInNeighborhoods(_not_ghost);
+}
+
+/* -------------------------------------------------------------------------- */
+template <UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::insertQuadsInNeighborhoods(
+ GhostType ghost_type) {
+
+ NonLocalManager & manager = this->model->getNonLocalManager();
+ UInt _spatial_dimension = this->model->getSpatialDimension();
+ AKANTU_DEBUG_ASSERT(_spatial_dimension == spatial_dimension,
+ "This assert was inserted because the current variable "
+ "shadows a template parameter: cannot know which to use");
+
+ InternalField<Real> quadrature_points_coordinates(
+ "quadrature_points_coordinates_tmp_nl", *this);
+ quadrature_points_coordinates.initialize(spatial_dimension);
+
+ /// intialize quadrature point object
+ IntegrationPoint q;
+ q.ghost_type = ghost_type;
+ q.kind = _ek_regular;
+
+ Mesh::type_iterator it = this->element_filter.firstType(
+ spatial_dimension, ghost_type, _ek_regular);
+ Mesh::type_iterator last_type =
+ this->element_filter.lastType(spatial_dimension, ghost_type, _ek_regular);
+ for (; it != last_type; ++it) {
+ q.type = *it;
+ const Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
+ UInt nb_element = elem_filter.getSize();
+ if (nb_element) {
+ UInt nb_quad = this->fem->getNbIntegrationPoints(*it, ghost_type);
+ UInt nb_tot_quad = nb_quad * nb_element;
+
+ Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
+ quads.resize(nb_tot_quad);
+
+ this->model->getFEEngine().computeIntegrationPointsCoordinates(
+ quads, *it, ghost_type, elem_filter);
+
+ Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
+ UInt * elem = elem_filter.storage();
+
+ for (UInt e = 0; e < nb_element; ++e) {
+ q.element = *elem;
+ for (UInt nq = 0; nq < nb_quad; ++nq) {
+ q.num_point = nq;
+ q.global_num = q.element * nb_quad + nq;
+ manager.insertQuad(q, *quad, this->name);
+ ++quad;
+ }
+ ++elem;
+ }
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+template <UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::updateNonLocalInternals(
+ ElementTypeMapReal & non_local_flattened, const ID & field_id,
+ const UInt nb_component) {
+
+ for (ghost_type_t::iterator g = ghost_type_t::begin();
+ g != ghost_type_t::end(); ++g) {
+ GhostType ghost_type = *g;
+ /// loop over all types in the material
+ typedef ElementTypeMapArray<UInt>::type_iterator iterator;
+ iterator it = this->element_filter.firstType(spatial_dimension, ghost_type,
+ _ek_regular);
+ iterator last_type = this->element_filter.lastType(spatial_dimension,
+ ghost_type, _ek_regular);
+ for (; it != last_type; ++it) {
+ ElementType el_type = *it;
+ Array<Real> & internal =
+ this->getInternal<Real>(field_id)(el_type, ghost_type);
+ Array<Real>::vector_iterator internal_it = internal.begin(nb_component);
+ Array<Real> & internal_flat = non_local_flattened(el_type, ghost_type);
+ Array<Real>::const_vector_iterator internal_flat_it =
+ internal_flat.begin(nb_component);
+ /// loop all elements for the given type
+ const Array<UInt> & filter = this->element_filter(el_type, ghost_type);
+ UInt nb_elements = filter.getSize();
+ UInt nb_quads =
+ this->getFEEngine().getNbIntegrationPoints(el_type, ghost_type);
+ for (UInt e = 0; e < nb_elements; ++e) {
+ UInt global_el = filter(e);
+ for (UInt q = 0; q < nb_quads; ++q, ++internal_it) {
+ UInt global_quad = global_el * nb_quads + q;
+ *internal_it = internal_flat_it[global_quad];
+ }
+ }
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+template <UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::updateResidual(__attribute__((unused))
+ GhostType ghost_type) {
+ AKANTU_EXCEPTION("this method has not been implemented");
+}
+
+/* -------------------------------------------------------------------------- */
+template <UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::registerNeighborhood() {
+ this->model->getNonLocalManager().registerNeighborhood(this->name,
+ this->name);
+}
+
+/* -------------------------------------------------------------------------- */
+
+INSTANTIATE_MATERIAL(MaterialNonLocal);
+
+__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_non_local.hh b/src/model/solid_mechanics/materials/material_non_local.hh
index 905d6f3ff..e7a9db227 100644
--- a/src/model/solid_mechanics/materials/material_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_non_local.hh
@@ -1,185 +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 "aka_grid_dynamic.hh"
#include "fe_engine.hh"
-
-#include "weight_function.hh"
-
-namespace akantu {
- class GridSynchronizer;
-}
+#include "non_local_manager.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_NON_LOCAL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-template<UInt dim, template <UInt> class WeightFunction = BaseWeightFunction>
-class MaterialNonLocal : public virtual Material {
+template <UInt dim> class MaterialNonLocal : public virtual Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
MaterialNonLocal(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialNonLocal();
- typedef std::vector< std::pair<QuadraturePoint, QuadraturePoint> > PairList;
-
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material computed parameter
virtual void initMaterial();
virtual void updateResidual(GhostType ghost_type);
- virtual void computeAllNonLocalStresses(GhostType ghost_type = _not_ghost);
-
- void savePairs(const std::string & filename) const;
- void neighbourhoodStatistics(const std::string & filename) const;
-
-protected:
- void updatePairList(const ElementTypeMapArray<Real> & quadrature_points_coordinates);
-
- void computeWeights(const ElementTypeMapArray<Real> & quadrature_points_coordinates);
-
- void createCellList(ElementTypeMapArray<Real> & quadrature_points_coordinates);
-
- void cleanupExtraGhostElement(const ElementTypeMap<UInt> & nb_ghost_protected);
-
- void fillCellList(const ElementTypeMapArray<Real> & quadrature_points_coordinates,
- const GhostType & ghost_type);
+ /// insert the quadrature points in the neighborhoods of the non-local manager
+ virtual void insertQuadsInNeighborhoods(GhostType ghost_type = _not_ghost);
+ /// update the values in the non-local internal fields
+ void updateNonLocalInternals(ElementTypeMapReal & non_local_flattened,
+ const ID & field_id, const UInt nb_component);
/// constitutive law
virtual void computeNonLocalStresses(GhostType ghost_type = _not_ghost) = 0;
- template<typename T>
- void weightedAvergageOnNeighbours(const InternalField<T> & to_accumulate,
- InternalField<T> & accumulated,
- UInt nb_degree_of_freedom,
- GhostType ghost_type2 = _not_ghost) const;
-
- 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);
-
- virtual inline void onElementsAdded(const Array<Element> & element_list);
- virtual inline void onElementsRemoved(const Array<Element> & element_list,
- const ElementTypeMapArray<UInt> & new_numbering,
- const RemovedElementsEvent & event);
-
- /* ------------------------------------------------------------------------ */
- /* Accessors */
- /* ------------------------------------------------------------------------ */
-public:
-
- void registerNonLocalVariable(InternalField<Real> & local,
- InternalField<Real> & non_local,
- UInt nb_degree_of_freedom) {
- ID id = local.getID();
- NonLocalVariable & non_local_variable = non_local_variables[id];
+ /// register the neighborhoods for the material
+ virtual void registerNeighborhood();
- non_local_variable.local = &local;
- non_local_variable.non_local = &non_local;
- non_local_variable.nb_component = nb_degree_of_freedom;
+protected:
+ 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!!!");
}
- AKANTU_GET_MACRO(PairList, pair_list, const PairList &)
- Real getRadius() const { return weight_func->getRadius(); }
- AKANTU_GET_MACRO(CellList, *spatial_grid, const SpatialGrid<QuadraturePoint> &)
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
-
- /// the weight function used
- WeightFunction<dim> * weight_func;
-
-private:
- /**
- * the pairs of quadrature points
- * 0: not ghost to not ghost
- * 1: not ghost to ghost
- */
- PairList pair_list[2];
-
- /// the weights associated to the pairs
- Array<Real> * pair_weight[2];
-
- /// the regular grid to construct/update the pair lists
- SpatialGrid<QuadraturePoint> * spatial_grid;
-
- /// the types of the existing pairs
- typedef std::set< std::pair<ElementType, ElementType> > pair_type;
- pair_type existing_pairs[2];
-
- /// count the number of calls of computeStress
- UInt compute_stress_calls;
-
- struct NonLocalVariable {
- InternalField<Real> * local;
- InternalField<Real> * non_local;
- UInt nb_component;
- };
-
- std::map<ID, NonLocalVariable> non_local_variables;
-
- bool is_creating_grid;
-
- GridSynchronizer * grid_synchronizer;
};
-
/* -------------------------------------------------------------------------- */
/* 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 6dd528ddf..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,46 +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_MATERIAL_WEIGHT_FUNCTION_TMPL_LIST \
- ((stress_wf, (StressBasedWeightFunction ))) \
- ((damage_wf, (DamagedWeightFunction ))) \
- ((remove_wf, (RemoveDamagedWeightFunction))) \
- ((base_wf, (BaseWeightFunction )))
-
#define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST \
- ((3, (marigo_non_local , MaterialMarigoNonLocal, \
- AKANTU_MATERIAL_WEIGHT_FUNCTION_TMPL_LIST))) \
- ((2, (mazars_non_local , MaterialMazarsNonLocal )))
+ ((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 12bc17a34..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,830 +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__
-/* -------------------------------------------------------------------------- */
-#include "aka_types.hh"
-#include "grid_synchronizer.hh"
-#include "synchronizer_registry.hh"
-#include "integrator.hh"
-#include "dumper_paraview.hh"
-/* -------------------------------------------------------------------------- */
-#include <fstream>
-/* -------------------------------------------------------------------------- */
-
-#if defined(AKANTU_DEBUG_TOOLS)
-# include "aka_debug_tools.hh"
-#endif
-
-
__BEGIN_AKANTU__
-
-/* -------------------------------------------------------------------------- */
-template<UInt DIM, template <UInt> class WeightFunction>
-MaterialNonLocal<DIM, WeightFunction>::MaterialNonLocal(SolidMechanicsModel & model,
- const ID & id) :
- Material(model, id), weight_func(NULL), spatial_grid(NULL),
- compute_stress_calls(0), is_creating_grid(false), grid_synchronizer(NULL) {
- AKANTU_DEBUG_IN();
-
-
- for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
- GhostType ghost_type = (GhostType) gt;
- pair_weight[ghost_type] = NULL;
- }
-
-
- this->is_non_local = true;
- this->weight_func = new WeightFunction<DIM>(*this);
-
- this->registerSubSection(_st_non_local, "weight_function", *weight_func);
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-MaterialNonLocal<spatial_dimension, WeightFunction>::~MaterialNonLocal() {
- AKANTU_DEBUG_IN();
-
- for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
- GhostType ghost_type = (GhostType) gt;
- delete pair_weight[ghost_type];
- }
-
- delete spatial_grid;
- delete weight_func;
- delete grid_synchronizer;
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::initMaterial() {
- AKANTU_DEBUG_IN();
- // Material::initMaterial();
- Mesh & mesh = this->model->getFEEngine().getMesh();
-
- InternalField<Real> quadrature_points_coordinates("quadrature_points_coordinates_tmp_nl", *this);
- quadrature_points_coordinates.initialize(spatial_dimension);
-
- ElementTypeMap<UInt> nb_ghost_protected;
- 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);
-
- AKANTU_DEBUG_INFO("Creating cell list");
- createCellList(quadrature_points_coordinates);
-
- AKANTU_DEBUG_INFO("Creating pairs");
- updatePairList(quadrature_points_coordinates);
-
-#if not defined(AKANTU_NDEBUG)
- if(AKANTU_DEBUG_TEST(dblDump))
- neighbourhoodStatistics("material_non_local.stats");
-#endif
-
- AKANTU_DEBUG_INFO("Cleaning extra ghosts");
- /// cleanupExtraGhostElement(nb_ghost_protected);
-
- AKANTU_DEBUG_INFO("Computing weights");
- weight_func->setRadius(weight_func->getRadius());
- weight_func->init();
-
- computeWeights(quadrature_points_coordinates);
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::cleanupExtraGhostElement(const ElementTypeMap<UInt> & nb_ghost_protected) {
- AKANTU_DEBUG_IN();
-
- // Create list of element to keep
- std::set<Element> relevant_ghost_element;
-
- 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 QuadraturePoint & q2 = first_pair->second;
- relevant_ghost_element.insert(q2);
- }
-
- // Create list of element to remove and new numbering for element to keep
- Mesh & mesh = this->model->getFEEngine().getMesh();
- std::set<Element> 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_local; // member element corresponds to global element number
- element_local.ghost_type = _ghost;
-
- for(; it != last_type; ++it) {
- element_local.type = *it;
- UInt nb_ghost_elem_global = 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_global, 1, *it, _ghost);
- else remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem_global);
- Array<UInt> & elem_filter = element_filter(*it, _ghost);
- UInt nb_ghost_elem_local = elem_filter.getSize();
- Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
- for (UInt g = 0; g < nb_ghost_elem_local; ++g) {
- element_local.element = g;
- Element element_global = this->convertToGlobalElement(element_local);
- if (element_global.element >= nb_ghost_elem_protected &&
- relevant_ghost_element.find(element_local) == relevant_ghost_element.end()) {
- // (std::find(relevant_ghost_element.begin(),
- // relevant_ghost_element.end(),
- // element_local) == relevant_ghost_element.end())) {
- std::cout<< "element removed" << std::endl;
- remove_elem.getList().push_back(element_global);
- new_numbering(element_global.element) = UInt(-1);
- }
- }
-
- UInt ng = 0;
- for (UInt g = 0; g < nb_ghost_elem_global; ++g) {
- if (new_numbering(g) != UInt(-1)) {
- new_numbering(g) = ng;
- ++ng;
- }
- }
- }
-
- mesh.sendEvent(remove_elem);
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::createCellList(ElementTypeMapArray<Real> & quadrature_points_coordinates) {
- AKANTU_DEBUG_IN();
-
- const Real safety_factor = 1.2; // for the cell grid spacing
- Mesh & mesh = this->model->getFEEngine().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, weight_func->getRadius() * safety_factor);
-
- spatial_grid = new SpatialGrid<QuadraturePoint>(spatial_dimension, spacing, center);
-
- this->computeQuadraturePointsCoordinates(quadrature_points_coordinates, _not_ghost);
- this->fillCellList(quadrature_points_coordinates, _not_ghost);
-
- is_creating_grid = true;
- std::set<SynchronizationTag> tags;
- tags.insert(_gst_mnl_for_average);
- tags.insert(_gst_mnl_weight);
- tags.insert(_gst_material_id);
-
- SynchronizerRegistry & synch_registry = this->model->getSynchronizerRegistry();
- std::stringstream sstr; sstr << getID() << ":grid_synchronizer";
- grid_synchronizer = GridSynchronizer::createGridSynchronizer(mesh,
- *spatial_grid,
- sstr.str(),
- &synch_registry,
- tags);
- is_creating_grid = false;
-
- this->computeQuadraturePointsCoordinates(quadrature_points_coordinates, _ghost);
- fillCellList(quadrature_points_coordinates, _ghost);
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::fillCellList(const ElementTypeMapArray<Real> & quadrature_points_coordinates,
- const GhostType & ghost_type) {
- QuadraturePoint q;
- q.ghost_type = ghost_type;
-
- Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = this->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();
- UInt nb_quad = this->model->getFEEngine().getNbQuadraturePoints(*it, ghost_type);
-
- const Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
- q.type = *it;
-
- 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;
- //q.setPosition(*quad);
- spatial_grid->insert(q, *quad);
- ++quad;
- }
- ++elem;
- }
- }
-}
-
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::updatePairList(const ElementTypeMapArray<Real> & quadrature_points_coordinates) {
- AKANTU_DEBUG_IN();
-
- GhostType ghost_type = _not_ghost;
- QuadraturePoint q1;
- q1.ghost_type = ghost_type;
-
- // generate the pair of neighbor depending of the cell_list
- Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type);
- for(; it != last_type; ++it) {
- // Preparing datas
- const Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
- Array<Real>::const_vector_iterator q1_coord_it = quads.begin(spatial_dimension);
- Array<Real>::const_vector_iterator last_quad = quads.end(spatial_dimension);
-
- q1.type = *it;
- q1.global_num = 0;
- // loop over quad points
- for(;q1_coord_it != last_quad; ++q1_coord_it, ++(q1.global_num)) {
- UInt nb_quad1 =
- this->model->getFEEngine().getNbQuadraturePoints(q1.type,
- q1.ghost_type);
- q1.element = q1.global_num / nb_quad1;
- q1.num_point = q1.global_num % nb_quad1;
- const Vector<Real> & q1_coord = *q1_coord_it;
-
- SpatialGrid<QuadraturePoint>::CellID cell_id = spatial_grid->getCellID(q1_coord);
- SpatialGrid<QuadraturePoint>::neighbor_cells_iterator first_neigh_cell =
- spatial_grid->beginNeighborCells(cell_id);
- SpatialGrid<QuadraturePoint>::neighbor_cells_iterator last_neigh_cell =
- spatial_grid->endNeighborCells(cell_id);
-
- // loop over neighbors cells of the one containing the current quadrature
- // point
- for (; first_neigh_cell != last_neigh_cell; ++first_neigh_cell) {
- SpatialGrid<QuadraturePoint>::Cell::iterator first_neigh_quad =
- spatial_grid->beginCell(*first_neigh_cell);
- SpatialGrid<QuadraturePoint>::Cell::iterator last_neigh_quad =
- spatial_grid->endCell(*first_neigh_cell);
-
- // loop over the quadrature point in the current cell of the cell list
- for (;first_neigh_quad != last_neigh_quad; ++first_neigh_quad){
- QuadraturePoint q2 = this->convertToLocalPoint(*first_neigh_quad);
-
- Array<Real>::const_vector_iterator q2_coord_it =
- quadrature_points_coordinates(q2.type,
- q2.ghost_type).begin(spatial_dimension);
-
- const Vector<Real> & q2_coord = q2_coord_it[q2.global_num];
-
- Real distance = q1_coord.distance(q2_coord);
-
- if(distance <= weight_func->getRadius() &&
- (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();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::computeWeights(const ElementTypeMapArray<Real> & quadrature_points_coordinates) {
- AKANTU_DEBUG_IN();
-
- InternalField<Real> quadrature_points_volumes("quadrature_points_volumes", *this);
- quadrature_points_volumes.initialize(1);
-
- const FEEngine & fem = this->model->getFEEngine();
-
- weight_func->updateInternals(quadrature_points_volumes);
-
- for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
- GhostType ghost_type2 = (GhostType) gt;
-
- if(!(pair_weight[ghost_type2])) {
- std::string ghost_id = "";
- if (ghost_type2 == _ghost) ghost_id = ":ghost";
- std::stringstream sstr; sstr << getID() << ":pair_weight:" << ghost_id;
- pair_weight[ghost_type2] = new Array<Real>(0, 2, sstr.str());
- }
-
- pair_weight[ghost_type2]->resize(pair_list[ghost_type2].size());
- pair_weight[ghost_type2]->clear();
-
- 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 QuadraturePoint & lq1 = first_pair->first;
- const QuadraturePoint & lq2 = first_pair->second;
-
- QuadraturePoint gq1 = this->convertToGlobalPoint(lq1);
- QuadraturePoint gq2 = this->convertToGlobalPoint(lq2);
-
- // const Real q2_wJ = fem.getIntegratorInterface().getJacobians(gq2.type, gq2.ghost_type)(gq2.global_num);
-
- Array<Real>::const_vector_iterator quad_coords_1 =
- quadrature_points_coordinates(lq1.type, lq1.ghost_type).begin(spatial_dimension);
- Array<Real>::const_vector_iterator quad_coords_2 =
- quadrature_points_coordinates(lq2.type, lq2.ghost_type).begin(spatial_dimension);
-
- Array<Real> & quad_volumes_1 = quadrature_points_volumes(lq1.type, lq1.ghost_type);
- const Array<Real> & jacobians_2 =
- fem.getIntegratorInterface().getJacobians(gq2.type, gq2.ghost_type);
- const Real & q2_wJ = jacobians_2(gq2.global_num);
- // Real & q1_volume = quad_volumes(lq1.global_num);
-
- const Vector<Real> & q1_coord = quad_coords_1[lq1.global_num];
- // quadrature_points_coordinates(lq1.type, lq1.ghost_type).begin(spatial_dimension)[lq1.global_num];
- const Vector<Real> & q2_coord = quad_coords_2[lq2.global_num];
- // quadrature_points_coordinates(lq1.type, lq1.ghost_type).begin(spatial_dimension)[lq2.global_num];
-
- this->weight_func->selectType(lq1.type, lq1.ghost_type, lq2.type, lq2.ghost_type);
-
- // Weight function
- Real r = q1_coord.distance(q2_coord);
- Real w1 = this->weight_func->operator()(r, lq1, lq2);
- weight(0) = q2_wJ * w1;
- // q1_volume += weight(0);
- quad_volumes_1(lq1.global_num) += weight(0);
-
- if(lq2.ghost_type != _ghost && lq1.global_num != lq2.global_num) {
- const Array<Real> & jacobians_1 =
- fem.getIntegratorInterface().getJacobians(gq1.type, gq1.ghost_type);
- Array<Real> & quad_volumes_2 =
- quadrature_points_volumes(lq2.type, lq2.ghost_type);
-
- const Real & q1_wJ = jacobians_1(gq1.global_num);
- //Real & q2_volume = quad_volumes_2(lq2.global_num);
-
- Real w2 = this->weight_func->operator()(r, lq2, lq1);
- weight(1) = q1_wJ * w2;
-
- quad_volumes_2(lq2.global_num) += weight(1);
- //q2_volume += 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(2);
-
- // Compute the weights
- for(;first_pair != last_pair; ++first_pair, ++weight_it) {
- Vector<Real> & weight = *weight_it;
-
- const QuadraturePoint & lq1 = first_pair->first;
- const QuadraturePoint & lq2 = first_pair->second;
-
- Array<Real> & quad_volumes_1 = quadrature_points_volumes(lq1.type, lq1.ghost_type);
- Array<Real> & quad_volumes_2 = quadrature_points_volumes(lq2.type, lq2.ghost_type);
-
- Real q1_volume = quad_volumes_1(lq1.global_num);
-
- weight(0) *= 1. / q1_volume;
- if(ghost_type2 != _ghost) {
- Real q2_volume = quad_volumes_2(lq2.global_num);
- weight(1) *= 1. / q2_volume;
- }
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-template<typename T>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::weightedAvergageOnNeighbours(const InternalField<T> & to_accumulate,
- InternalField<T> & accumulated,
- UInt nb_degree_of_freedom,
- GhostType ghost_type2) const {
- AKANTU_DEBUG_IN();
-
- if(ghost_type2 == _not_ghost) {
- accumulated.reset();
- }
-
- 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 QuadraturePoint & lq1 = first_pair->first;
- const QuadraturePoint & lq2 = first_pair->second;
-
- const Array<T> & to_acc_1 = to_accumulate(lq1.type, lq1.ghost_type);
- Array<T> & acc_1 = accumulated(lq1.type, lq1.ghost_type);
- const Array<T> & to_acc_2 = to_accumulate(lq2.type, lq2.ghost_type);
- Array<T> & acc_2 = accumulated(lq2.type, lq2.ghost_type);
-
- // const Vector<T> & q2_to_acc = to_acc_2[lq2.global_num];
- // Vector<T> & q1_acc = acc_1[lq1.global_num];
-
- //q1_acc += weight(0) * q2_to_acc;
- for(UInt d = 0; d < nb_degree_of_freedom; ++d) {
- acc_1(lq1.global_num, d) += weight(0) * to_acc_2(lq2.global_num, d);
- }
-
- if(ghost_type2 != _ghost) {
- for(UInt d = 0; d < nb_degree_of_freedom; ++d) {
- acc_2(lq2.global_num, d) += weight(1) * to_acc_1(lq1.global_num, d);
- }
- }
-
- // if(ghost_type2 != _ghost) {
- // const Vector<T> & q1_to_acc = to_acc_1[lq1.global_num];
- // Vector<T> & q2_acc = acc_2[lq2.global_num];
-
- // q2_acc += weight(1) * q1_to_acc;
- // }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::updateResidual(GhostType ghost_type) {
- AKANTU_DEBUG_IN();
-
- // Update the weights for the non local variable averaging
- if(ghost_type == _not_ghost &&
- this->weight_func->getUpdateRate() &&
- (this->compute_stress_calls % this->weight_func->getUpdateRate() == 0)) {
- ElementTypeMapArray<Real> quadrature_points_coordinates("quadrature_points_coordinates", getID());
- Mesh & mesh = this->model->getFEEngine().getMesh();
- mesh.initElementTypeMapArray(quadrature_points_coordinates, spatial_dimension, spatial_dimension);
- computeQuadraturePointsCoordinates(quadrature_points_coordinates, _not_ghost);
- computeQuadraturePointsCoordinates(quadrature_points_coordinates, _ghost);
- computeWeights(quadrature_points_coordinates);
- }
- if(ghost_type == _not_ghost) ++this->compute_stress_calls;
-
- computeAllStresses(ghost_type);
-
- computeNonLocalStresses(ghost_type);
- assembleResidual(ghost_type);
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::computeAllNonLocalStresses(GhostType ghost_type) {
- // Update the weights for the non local variable averaging
- if(ghost_type == _not_ghost) {
- if(this->weight_func->getUpdateRate() &&
- (this->compute_stress_calls % this->weight_func->getUpdateRate() == 0)) {
- this->model->getSynchronizerRegistry().asynchronousSynchronize(_gst_mnl_weight);
-
- ElementTypeMapArray<Real> quadrature_points_coordinates("quadrature_points_coordinates", getID());
- Mesh & mesh = this->model->getFEEngine().getMesh();
- mesh.initElementTypeMapArray(quadrature_points_coordinates, spatial_dimension, spatial_dimension);
- computeQuadraturePointsCoordinates(quadrature_points_coordinates, _not_ghost);
- computeQuadraturePointsCoordinates(quadrature_points_coordinates, _ghost);
-
- this->model->getSynchronizerRegistry().waitEndSynchronize(_gst_mnl_weight);
-
- computeWeights(quadrature_points_coordinates);
- }
-
- typename std::map<ID, NonLocalVariable>::iterator it = non_local_variables.begin();
- typename std::map<ID, NonLocalVariable>::iterator end = non_local_variables.end();
- for(;it != end; ++it) {
- NonLocalVariable & non_local_variable = it->second;
-
- non_local_variable.non_local->resize();
- this->weightedAvergageOnNeighbours(*non_local_variable.local, *non_local_variable.non_local,
- non_local_variable.nb_component, _not_ghost);
- }
-
- ++this->compute_stress_calls;
- } else {
- typename std::map<ID, NonLocalVariable>::iterator it = non_local_variables.begin();
- typename std::map<ID, NonLocalVariable>::iterator end = non_local_variables.end();
- for(;it != end; ++it) {
- NonLocalVariable & non_local_variable = it->second;
- this->weightedAvergageOnNeighbours(*non_local_variable.local, *non_local_variable.non_local,
- non_local_variable.nb_component, _ghost);
- }
- computeNonLocalStresses(_not_ghost);
- }
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::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();
-
- Array<Real>::vector_iterator weight_it = pair_weight[ghost_type2]->begin(2);
-
- for(;first_pair != last_pair; ++first_pair, ++weight_it) {
- Vector<Real> & weight = *weight_it;
-
- const QuadraturePoint & lq1 = first_pair->first;
- const QuadraturePoint & lq2 = first_pair->second;
- pout << lq1 << " " << lq2 << " " << weight << std::endl;
- }
- }
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::neighbourhoodStatistics(const std::string & filename) const {
- // std::ofstream pout;
- // pout.open(filename.c_str());
-
- // const Mesh & mesh = this->model->getFEEngine().getMesh();
-
- // GhostType ghost_type1;
- // ghost_type1 = _not_ghost;
-
- // StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- // Int prank = comm.whoAmI();
-
- // InternalField<UInt> nb_neighbors("nb_neighbours", *const_cast<MaterialNonLocal *>(this));
- // nb_neighbors.initialize(1);
-
- // for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
- // GhostType ghost_type2 = (GhostType) gt;
- // UInt existing_pairs_num = gt - _not_ghost;
-
- // pair_type::const_iterator first_pair_types = existing_pairs[existing_pairs_num].begin();
- // pair_type::const_iterator last_pair_types = existing_pairs[existing_pairs_num].end();
-
- // for (; first_pair_types != last_pair_types; ++first_pair_types) {
- // const Array<UInt> & pairs =
- // pair_list(first_pair_types->first, ghost_type1)(first_pair_types->second, ghost_type2);
- // if(prank == 0) {
- // pout << ghost_type2 << " ";
- // pout << "Types : " << first_pair_types->first << " " << first_pair_types->second << std::endl;
- // }
- // Array<UInt>::const_iterator< Vector<UInt> > first_pair = pairs.begin(2);
- // Array<UInt>::const_iterator< Vector<UInt> > last_pair = pairs.end(2);
- // Array<UInt> & nb_neigh_1 = nb_neighbors(first_pair_types->first, ghost_type1);
- // Array<UInt> & nb_neigh_2 = nb_neighbors(first_pair_types->second, ghost_type2);
- // for(;first_pair != last_pair; ++first_pair) {
- // UInt q1 = (*first_pair)(0);
- // UInt q2 = (*first_pair)(1);
- // ++(nb_neigh_1(q1));
- // if(q1 != q2) ++(nb_neigh_2(q2));
- // }
- // }
-
- // Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type1);
- // Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type1);
- // UInt nb_quads = 0;
- // Real sum_nb_neig = 0;
- // UInt max_nb_neig = 0;
- // UInt min_nb_neig = std::numeric_limits<UInt>::max();
- // for(; it != last_type; ++it) {
- // Array<UInt> & nb_neighor = nb_neighbors(*it, ghost_type1);
- // Array<UInt>::iterator<UInt> nb_neigh = nb_neighor.begin();
- // Array<UInt>::iterator<UInt> end_neigh = nb_neighor.end();
-
- // for (; nb_neigh != end_neigh; ++nb_neigh, ++nb_quads) {
- // UInt nb = *nb_neigh;
- // sum_nb_neig += nb;
- // max_nb_neig = std::max(max_nb_neig, nb);
- // min_nb_neig = std::min(min_nb_neig, nb);
- // }
- // }
-
-
- // comm.allReduce(&nb_quads, 1, _so_sum);
- // comm.allReduce(&sum_nb_neig, 1, _so_sum);
- // comm.allReduce(&max_nb_neig, 1, _so_max);
- // comm.allReduce(&min_nb_neig, 1, _so_min);
-
- // if(prank == 0) {
- // pout << ghost_type2 << " ";
- // pout << "Nb quadrature points: " << nb_quads << std::endl;
-
- // Real mean_nb_neig = sum_nb_neig / Real(nb_quads);
- // pout << ghost_type2 << " ";
- // pout << "Average nb neighbors: " << mean_nb_neig << "(" << sum_nb_neig << ")" << std::endl;
-
- // pout << ghost_type2 << " ";
- // pout << "Max nb neighbors: " << max_nb_neig << std::endl;
-
- // pout << ghost_type2 << " ";
- // pout << "Min nb neighbors: " << min_nb_neig << std::endl;
- // }
- // }
- // pout.close();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-inline UInt MaterialNonLocal<spatial_dimension, WeightFunction>::getNbDataForElements(const Array<Element> & elements,
- SynchronizationTag tag) const {
- UInt nb_quadrature_points = this->getModel().getNbQuadraturePoints(elements);
- UInt size = 0;
-
- if(tag == _gst_mnl_for_average) {
- typename std::map<ID, NonLocalVariable>::const_iterator it = non_local_variables.begin();
- typename std::map<ID, NonLocalVariable>::const_iterator end = non_local_variables.end();
-
- for(;it != end; ++it) {
- const NonLocalVariable & non_local_variable = it->second;
- size += non_local_variable.nb_component * sizeof(Real) * nb_quadrature_points;
- }
- }
-
- size += weight_func->getNbDataForElements(elements, tag);
-
- return size;
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-inline void MaterialNonLocal<spatial_dimension, WeightFunction>::packElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) const {
- if(tag == _gst_mnl_for_average) {
- typename std::map<ID, NonLocalVariable>::const_iterator it = non_local_variables.begin();
- typename std::map<ID, NonLocalVariable>::const_iterator end = non_local_variables.end();
-
- for(;it != end; ++it) {
- const NonLocalVariable & non_local_variable = it->second;
- this->packElementDataHelper(*non_local_variable.local,
- buffer, elements);
- }
- }
-
- weight_func->packElementData(buffer, elements, tag);
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-inline void MaterialNonLocal<spatial_dimension, WeightFunction>::unpackElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) {
- if(tag == _gst_mnl_for_average) {
- typename std::map<ID, NonLocalVariable>::iterator it = non_local_variables.begin();
- typename std::map<ID, NonLocalVariable>::iterator end = non_local_variables.end();
-
- for(;it != end; ++it) {
- NonLocalVariable & non_local_variable = it->second;
- this->unpackElementDataHelper(*non_local_variable.local,
- buffer, elements);
- }
- }
-
- weight_func->unpackElementData(buffer, elements, tag);
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-inline void MaterialNonLocal<spatial_dimension, WeightFunction>::onElementsAdded(const Array<Element> & element_list) {
- AKANTU_DEBUG_IN();
- AKANTU_DEBUG_ERROR("This is a case not taken into account!!!");
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-inline void MaterialNonLocal<spatial_dimension, WeightFunction>::onElementsRemoved(const Array<Element> & element_list,
- const ElementTypeMapArray<UInt> & new_numbering,
- __attribute__((unused)) const RemovedElementsEvent & event) {
- AKANTU_DEBUG_IN();
-
- // 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();
-
- // Array<Real>::vector_iterator weight_it = pair_weight[ghost_type2]->begin(2);
-
- for(;first_pair != last_pair; ++first_pair) {
- QuadraturePoint & q1 = first_pair->first;
- QuadraturePoint gq1 = this->convertToGlobalPoint(q1);
- q1 = gq1;
-
- if(new_numbering.exists(q1.type, q1.ghost_type)) {
- UInt q1_new_el = new_numbering(q1.type, q1.ghost_type)(gq1.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;
- }
-
-
- QuadraturePoint & q2 = first_pair->second;
- QuadraturePoint gq2 = this->convertToGlobalPoint(q2);
- q2 = gq2;
-
- if(new_numbering.exists(q2.type, q2.ghost_type)) {
- UInt q2_new_el = new_numbering(q2.type, q2.ghost_type)(gq2.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;
- }
- }
- }
-
- // Change the material numbering
- Material::onElementsRemoved(element_list, new_numbering, event);
-
- // Change back the pairs to the new material 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();
-
- // Array<Real>::vector_iterator weight_it = pair_weight[ghost_type2]->begin(2);
-
- for(;first_pair != last_pair; ++first_pair) {
- first_pair->first = this->convertToLocalPoint(first_pair->first );
- first_pair->second = this->convertToLocalPoint(first_pair->second);
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
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 dc06edb44..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,137 +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
new file mode 100644
index 000000000..1150170f1
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_python/material_python.cc
@@ -0,0 +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) {
+ AKANTU_DEBUG_IN();
+
+ this->registerInternals();
+
+ std::vector<std::string> param_names =
+ this->callFunctor<std::vector<std::string> >("registerParam");
+
+ this->local_params.resize(param_names.size());
+
+ for (UInt i = 0; i < param_names.size(); ++i) {
+ std::stringstream sstr;
+ sstr << "PythonParameter" << i;
+ this->registerParam(param_names[i], local_params[i], 0., _pat_parsable,
+ sstr.str());
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void MaterialPython::registerInternals() {
+
+ std::vector<std::string> internal_names =
+ this->callFunctor<std::vector<std::string> >("registerInternals");
+
+ this->internals.resize(internal_names.size());
+
+ for (UInt i = 0; i < internal_names.size(); ++i) {
+ std::stringstream sstr;
+ sstr << "PythonInternal" << i;
+ this->internals[i] = new InternalField<Real>(internal_names[i], *this);
+ this->internals[i]->initialize(1);
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void MaterialPython::initMaterial() {
+ AKANTU_DEBUG_IN();
+
+ Material::initMaterial();
+
+ // initInternalArray(this->damage, 1);
+ // resizeInternalArray(this->damage);
+
+ // lambda = nu * E / ((1 + nu) * (1 - 2*nu));
+ // mu = E / (2 * (1 + nu));
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void MaterialPython::computeStress(ElementType el_type, GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ typedef Array<Real>::iterator<Real> it_type;
+ std::vector<it_type> its;
+ for (auto i : this->internals) {
+ its.push_back((*i)(el_type, ghost_type).begin());
+ }
+
+ MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
+
+ computeStress(grad_u, sigma, its);
+
+ for (auto b : its)
+ ++(*b);
+
+ MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename it_type>
+void MaterialPython::computeStress(Matrix<Real> & grad_u, Matrix<Real> & sigma,
+ std::vector<it_type> & internal_iterators) {
+
+ std::vector<Real> inputs;
+ for (auto i : internal_iterators) {
+ inputs.push_back(*i);
+ }
+ this->callFunctor<void>("computeStress", grad_u, sigma, inputs);
+
+ for (UInt i = 0; i < inputs.size(); ++i) {
+ *internal_iterators[i] = inputs[i];
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void MaterialPython::computeTangentModuli(const ElementType & el_type,
+ Array<Real> & tangent_matrix,
+ GhostType ghost_type) {
+
+ this->callFunctor<void>("computeTangentModuli", el_type, tangent_matrix,
+ ghost_type);
+}
+
+/* -------------------------------------------------------------------------- */
+Real MaterialPython::getPushWaveSpeed(__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
new file mode 100644
index 000000000..84b43872c
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_python/material_python.hh
@@ -0,0 +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 6bedde1b6..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().getNbQuadraturePoints(type);
+ 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 0d2c25b91..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,132 +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 144e1dd77..595725b9a 100644
--- a/src/model/solid_mechanics/materials/random_internal_field.hh
+++ b/src/model/solid_mechanics/materials/random_internal_field.hh
@@ -1,100 +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);
- virtual void printself(std::ostream & stream, unsigned int indent = 0) const;
+ /// 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 4c4babf1e..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,129 +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(
+ 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>
+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) {
+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) {
+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) {
+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, unsigned int indent) const {
+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)) {
+ 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) {
+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>
+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) {
+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_function.cc b/src/model/solid_mechanics/materials/weight_function.cc
deleted file mode 100644
index bfe16c82c..000000000
--- a/src/model/solid_mechanics/materials/weight_function.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * @file weight_function.cc
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Fri Apr 13 2012
- * @date last modification: Tue Nov 06 2012
- *
- * @brief implementation of the 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-#include "weight_function.hh"
-
-__BEGIN_AKANTU__
-
-
-__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/weight_function.hh b/src/model/solid_mechanics/materials/weight_function.hh
deleted file mode 100644
index c66717f53..000000000
--- a/src/model/solid_mechanics/materials/weight_function.hh
+++ /dev/null
@@ -1,374 +0,0 @@
-/**
- * @file 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
- *
- * @brief Weight functions 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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 "solid_mechanics_model.hh"
-#include "parsable.hh"
-#include <cmath>
-#if defined(AKANTU_DEBUG_TOOLS)
-#include "aka_debug_tools.hh"
-#include <string>
-#endif
-
-#include "material_list.hh"
-
-/* -------------------------------------------------------------------------- */
-#include <vector>
-#include "material_damage.hh"
-
-#ifndef __AKANTU_WEIGHT_FUNCTION_HH__
-#define __AKANTU_WEIGHT_FUNCTION_HH__
-
-__BEGIN_AKANTU__
-
-/* -------------------------------------------------------------------------- */
-/* Normal weight function */
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-class BaseWeightFunction : public Parsable {
-public:
- BaseWeightFunction(Material & material, const std::string & type = "base") :
- Parsable(_st_non_local, "weight_function:" + type), material(material), type(type) {
- this->registerParam("radius" , R , 100.,
- _pat_parsable | _pat_readable , "Non local radius");
- this->registerParam("update_rate" , update_rate, 0U ,
- _pat_parsmod, "Update frequency");
- }
-
- virtual ~BaseWeightFunction() {}
-
- virtual void init() { R2 = R * R; };
-
- virtual void updateInternals(__attribute__((unused)) const ElementTypeMapArray<Real> & quadrature_points_coordinates) {};
-
- /* ------------------------------------------------------------------------ */
- inline void setRadius(Real radius) { R = radius; R2 = R * R; }
-
- /* ------------------------------------------------------------------------ */
- inline void selectType(__attribute__((unused)) ElementType type1,
- __attribute__((unused)) GhostType ghost_type1,
- __attribute__((unused)) ElementType type2,
- __attribute__((unused)) GhostType ghost_type2) {
- }
-
- /* ------------------------------------------------------------------------ */
- inline Real operator()(Real r,
- const __attribute__((unused)) QuadraturePoint & q1,
- const __attribute__((unused)) QuadraturePoint & q2) {
- Real w = 0;
- if(r <= R) {
- Real alpha = (1. - r*r / R2);
- w = alpha * alpha;
- // *weight = 1 - sqrt(r / radius);
- }
- return w;
- }
-
- void printself(std::ostream & stream, int indent) 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;
- }
-
-public:
- Real getRadius() { return R; }
- UInt getUpdateRate() { return update_rate; }
-
-public:
- 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) {}
-protected:
- Material & material;
-
- Real R;
- Real R2;
-
- UInt update_rate;
-
- const std::string type;
-};
-
-/* -------------------------------------------------------------------------- */
-/* Damage weight function */
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-class DamagedWeightFunction : public BaseWeightFunction<spatial_dimension> {
-public:
- DamagedWeightFunction(Material & material) : BaseWeightFunction<spatial_dimension>(material, "damaged") {
- //AKANTU_DEBUG_ASSERT(dynamic_cast<MaterialDamage<spatial_dimension> *>(&material) != NULL, "This weight function works only with damage materials!");
- }
-
- inline void selectType(__attribute__((unused)) ElementType type1,
- __attribute__((unused)) GhostType ghost_type1,
- ElementType type2,
- GhostType ghost_type2) {
- selected_damage = &(this->material.template getArray<Real>("damage", type2, ghost_type2));
- }
-
- inline Real operator()(Real r,
- const __attribute__((unused)) QuadraturePoint & q1,
- const QuadraturePoint & q2) {
- UInt quad = q2.global_num;
- Real D = (*selected_damage)(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;
- }
-
-private:
- const Array<Real> * selected_damage;
-};
-
-/* -------------------------------------------------------------------------- */
-/* Remove damaged weight function */
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-class RemoveDamagedWeightFunction : public BaseWeightFunction<spatial_dimension> {
-public:
- RemoveDamagedWeightFunction(Material & material) : BaseWeightFunction<spatial_dimension>(material, "remove_damaged") {
- this->registerParam("damage_limit", this->damage_limit, 1., _pat_parsable, "Damage Threshold");
- }
-
- inline void selectType(__attribute__((unused)) ElementType type1,
- __attribute__((unused)) GhostType ghost_type1,
- ElementType type2,
- GhostType ghost_type2) {
- selected_damage = &(this->material.template getArray<Real>("damage", type2, ghost_type2));
- // selected_damage = &mat.getDamage(type2, ghost_type2);
- }
-
- inline Real operator()(Real r,
- const __attribute__((unused)) QuadraturePoint & q1,
- const QuadraturePoint & q2) {
- UInt quad = q2.global_num;
-
- if(q1 == q2) return 1.;
-
- Real D = (*selected_damage)(quad);
- Real w = 0.;
- if(D < damage_limit) {
- Real alpha = std::max(0., 1. - r*r / this->R2);
- w = alpha * alpha;
- }
- return w;
- }
-
-
- virtual UInt getNbDataForElements(const Array<Element> & elements,
- SynchronizationTag tag) const {
- if(tag == _gst_mnl_weight)
- return this->material.getModel().getNbQuadraturePoints(elements) * sizeof(Real);
-
- return 0;
- }
-
- virtual inline void packElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) const {
- if(tag == _gst_mnl_weight) {
- ElementTypeMapArray<Real> & damage = this->material.template getInternal<Real>("damage");
- this->material.packElementDataHelper(damage,
- buffer,
- elements);
- }
- }
-
- virtual inline void unpackElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) {
- if(tag == _gst_mnl_weight) {
- ElementTypeMapArray<Real> & damage = this->material.template getInternal<Real>("damage");
- this->material.unpackElementDataHelper(damage,
- buffer,
- elements);
- }
- }
-
-
-private:
- /// limit at which a point is considered as complitely broken
- Real damage_limit;
-
- /// internal pointer to the current damage vector
- const Array<Real> * selected_damage;
-};
-/* -------------------------------------------------------------------------- */
-/* Remove damaged with damage rate weight function */
-/* -------------------------------------------------------------------------- */
-
-template<UInt spatial_dimension>
-class RemoveDamagedWithDamageRateWeightFunction : public BaseWeightFunction<spatial_dimension> {
-public:
- RemoveDamagedWithDamageRateWeightFunction(Material & material) : BaseWeightFunction<spatial_dimension>(material, "remove_damage_with_damage_rate") {
- this->registerParam("damage_limit", this->damage_limit_with_damage_rate, 1, _pat_parsable, "Damage Threshold");
- }
-
- inline void selectType(__attribute__((unused)) ElementType type1,
- __attribute__((unused)) GhostType ghost_type1,
- ElementType type2,
- GhostType ghost_type2) {
- selected_damage_with_damage_rate = &(this->material.template getArray<Real>("damage",type2, ghost_type2));
- selected_damage_rate_with_damage_rate = &(this->material.template getArray<Real>("damage-rate",type2, ghost_type2));
- }
-
- inline Real operator()(Real r,
- const __attribute__((unused)) QuadraturePoint & q1,
- const QuadraturePoint & q2) {
- UInt quad = q2.global_num;
-
- if(q1.global_num == quad) return 1.;
-
- Real D = (*selected_damage_with_damage_rate)(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;
- }
-
-private:
- /// limit at which a point is considered as complitely broken
- Real damage_limit_with_damage_rate;
-
- /// internal pointer to the current damage vector
- const Array<Real> * selected_damage_with_damage_rate;
-
- /// internal pointer to the current damage rate vector
- const Array<Real> * selected_damage_rate_with_damage_rate;
-};
-
-/* -------------------------------------------------------------------------- */
-/* Stress Based Weight */
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-class StressBasedWeightFunction : public BaseWeightFunction<spatial_dimension> {
-public:
- StressBasedWeightFunction(Material & material);
-
- void init();
-
- virtual void updateInternals(__attribute__((unused)) const ElementTypeMapArray<Real> & quadrature_points_coordinates) {
- updatePrincipalStress(_not_ghost);
- updatePrincipalStress(_ghost);
- };
-
- void updatePrincipalStress(GhostType ghost_type);
-
- inline void updateQuadraturePointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates);
-
- inline void selectType(ElementType type1, GhostType ghost_type1,
- ElementType type2, GhostType ghost_type2);
-
- inline Real operator()(Real r,
- const QuadraturePoint & q1,
- const QuadraturePoint & q2);
-
- inline Real computeRhoSquare(Real r,
- Vector<Real> & eigs,
- Matrix<Real> & eigenvects,
- Vector<Real> & x_s);
-
-private:
- Real ft;
-
- InternalField<Real> stress_diag;
- Array<Real> * selected_stress_diag;
- InternalField<Real> stress_base;
- Array<Real> * selected_stress_base;
-
-
- // InternalField<Real> quadrature_points_coordinates;
- Array<Real> * selected_position_1;
- Array<Real> * selected_position_2;
-
- InternalField<Real> characteristic_size;
- Array<Real> * selected_characteristic_size;
-};
-
-
-template<UInt spatial_dimension>
-inline std::ostream & operator <<(std::ostream & stream,
- const BaseWeightFunction<spatial_dimension> & _this)
-{
- _this.printself(stream);
- return stream;
-}
-
-
-#include "weight_function_tmpl.hh"
-
-__END_AKANTU__
-
-#endif /* __AKANTU_WEIGHT_FUNCTION_HH__ */
diff --git a/src/model/solid_mechanics/materials/weight_function_tmpl.hh b/src/model/solid_mechanics/materials/weight_function_tmpl.hh
deleted file mode 100644
index 92dc9dabd..000000000
--- a/src/model/solid_mechanics/materials/weight_function_tmpl.hh
+++ /dev/null
@@ -1,279 +0,0 @@
-/**
- * @file weight_function_tmpl.hh
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Fri Apr 13 2012
- * @date last modification: Thu Jun 05 2014
- *
- * @brief implementation of the 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-
-/* -------------------------------------------------------------------------- */
-/* Stress based weight function */
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-StressBasedWeightFunction<spatial_dimension>::StressBasedWeightFunction(Material & material) :
- BaseWeightFunction<spatial_dimension>(material, "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);
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void StressBasedWeightFunction<spatial_dimension>::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));
- }
- }
- }
-}
-
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-void StressBasedWeightFunction<spatial_dimension>::updatePrincipalStress(GhostType ghost_type) {
- AKANTU_DEBUG_IN();
-
- const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
-
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
- for(; it != last_type; ++it) {
- Array<Real>::const_matrix_iterator sigma =
- this->material.getStress(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
- Array<Real>::vector_iterator eigenvalues =
- stress_diag(*it, ghost_type).begin(spatial_dimension);
- Array<Real>::vector_iterator eigenvalues_end =
- stress_diag(*it, ghost_type).end(spatial_dimension);
- Array<Real>::matrix_iterator eigenvector =
- stress_base(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
-
-#ifndef __trick__
- Array<Real>::iterator<Real> cl = characteristic_size(*it, ghost_type).begin();
-#endif
- UInt q = 0;
- for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues, ++eigenvector, ++cl, ++q) {
- sigma->eig(*eigenvalues, *eigenvector);
- *eigenvalues /= ft;
-#ifndef __trick__
- // specify a lower bound for principal stress based on the size of the element
- for (UInt i = 0; i < spatial_dimension; ++i) {
- (*eigenvalues)(i) = std::max(*cl / this->R, (*eigenvalues)(i));
- }
-#endif
- }
- }
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline void StressBasedWeightFunction<spatial_dimension>::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);
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline Real StressBasedWeightFunction<spatial_dimension>::operator()(Real r,
- const QuadraturePoint & q1,
- const QuadraturePoint & q2) {
- Real zero = std::numeric_limits<Real>::epsilon();
-
- if(r < zero) return 1.; // means x and s are the same points
-
- const Vector<Real> & x = q1.getPosition();
- const Vector<Real> & s = q2.getPosition();
-
- Vector<Real> eigs =
- selected_stress_diag->begin(spatial_dimension)[q2.global_num];
-
- Matrix<Real> eigenvects =
- selected_stress_base->begin(spatial_dimension, spatial_dimension)[q2.global_num];
-
- Real min_rho_lc = selected_characteristic_size->begin()[q1.global_num];
-
- Vector<Real> x_s(spatial_dimension);
- x_s = x;
- x_s -= s;
-
- Real rho_2 = computeRhoSquare(r, eigs, eigenvects, x_s);
-
- Real rho_lc_2 = std::max(this->R2 * rho_2, min_rho_lc*min_rho_lc);
-
- // Real w = std::max(0., 1. - r*r / rho_lc_2);
- // w = w*w;
- Real w = exp(- 2*2*r*r / rho_lc_2);
- return w;
-}
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline Real StressBasedWeightFunction<1>::computeRhoSquare(__attribute__ ((unused)) Real r,
- Vector<Real> & eigs,
- __attribute__ ((unused)) Matrix<Real> & eigenvects,
- __attribute__ ((unused)) Vector<Real> & x_s) {
- return eigs[0];
-}
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline Real StressBasedWeightFunction<2>::computeRhoSquare(__attribute__ ((unused)) Real r,
- Vector<Real> & eigs,
- Matrix<Real> & eigenvects,
- Vector<Real> & x_s) {
- 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);
-}
-
-/* -------------------------------------------------------------------------- */
-template<>
-inline Real StressBasedWeightFunction<3>::computeRhoSquare(Real r,
- Vector<Real> & eigs,
- Matrix<Real> & eigenvects,
- Vector<Real> & x_s) {
- 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);
-}
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
new file mode 100644
index 000000000..a47b5c7d2
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/base_weight_function.hh
@@ -0,0 +1,183 @@
+/**
+ * @file base_weight_function.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Thu Oct 15 2015
+ *
+ * @brief Base weight function for non local materials
+ *
+ * @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_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
new file mode 100644
index 000000000..68d782e10
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/base_weight_function_inline_impl.cc
@@ -0,0 +1,58 @@
+/**
+ * @file base_weight_function_inline_impl.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @date creation: Thu Feb 21 2013
+ * @date last modification: Thu Oct 15 2015
+ *
+ * @brief Implementation of inline function of base weight function
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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
new file mode 100644
index 000000000..d0e3473c2
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
@@ -0,0 +1,83 @@
+/**
+ * @file damaged_weight_function.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
+ *
+ * @brief Damaged weight function for non local materials
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "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
new file mode 100644
index 000000000..0c81aecfa
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
@@ -0,0 +1,74 @@
+/**
+ * @file damaged_weight_function_inline_impl.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Thu Oct 15 2015
+ *
+ * @brief Implementation of inline function of damaged weight 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+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
new file mode 100644
index 000000000..f969ba02c
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
@@ -0,0 +1,99 @@
+/**
+ * @file remove_damaged_weight_function.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100644
index 000000000..6616daafc
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc
@@ -0,0 +1,86 @@
+/**
+ * @file remove_damaged_weight_function_inline_impl.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @date creation: Mon Aug 24 2015
+ * @date last modification: Wed Oct 21 2015
+ *
+ * @brief Implementation of inline function of remove damaged weight 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+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
new file mode 100644
index 000000000..a959aa1ab
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
@@ -0,0 +1,82 @@
+/**
+ * @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 Jun 18 2010
+ * @date last modification: Thu Oct 15 2015
+ *
+ * @brief Removed damaged weight function for non local materials
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "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
new file mode 100644
index 000000000..918813435
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
@@ -0,0 +1,60 @@
+/**
+ * @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: Mon Aug 24 2015
+ * @date last modification: Thu Oct 15 2015
+ *
+ * @brief Implementation of inline function of remove damaged with
+ * damage rate weight 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+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
new file mode 100644
index 000000000..d1fe4c526
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
@@ -0,0 +1,117 @@
+/**
+ * @file stress_based_weight_function.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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(__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
new file mode 100644
index 000000000..56593df10
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
@@ -0,0 +1,104 @@
+/**
+ * @file stress_based_weight_function.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100644
index 000000000..2990dd1d4
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
@@ -0,0 +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 Oct 15 2015
+ *
+ * @brief Implementation of inline function of remove damaged with
+ * damage rate weight function
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+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(
+ __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()(__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];
+
+ // 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 635e203e4..5f4920909 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model.cc
@@ -1,1366 +1,1445 @@
/**
* @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 "element_group.hh"
#include "static_communicator.hh"
#include "dumpable_inline_impl.hh"
#ifdef AKANTU_USE_IOHELPER
-# include "dumper_field.hh"
-# include "dumper_paraview.hh"
-# include "dumper_homogenizing_field.hh"
-# include "dumper_material_internal_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"
#endif
/* -------------------------------------------------------------------------- */
#include <cmath>
/* -------------------------------------------------------------------------- */
-
/* -------------------------------------------------------------------------- */
__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), displacement(NULL),
previous_displacement(NULL), increment(NULL), mass(NULL), velocity(NULL),
acceleration(NULL), increment_acceleration(NULL), external_force(NULL),
internal_force(NULL), blocked_dofs(NULL), current_position(NULL),
material_index("material index", id),
material_local_numbering("material local numbering", id), materials(0),
material_selector(new DefaultMaterialSelector(material_index)),
is_default_material_selector(true), increment_flag(false),
synch_parallel(NULL), are_materials_instantiated(false) {
AKANTU_DEBUG_IN();
this->createSynchronizerRegistry(this);
this->registerFEEngineObject<MyFEEngineType>("SolidMechanicsFEEngine", mesh,
spatial_dimension);
this->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 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
}
/* -------------------------------------------------------------------------- */
/* Initialization */
/* -------------------------------------------------------------------------- */
/**
* 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);
- method = smm_options.analysis_method;
+ this->method = smm_options.analysis_method;
// initialize the vectors
- initArrays();
+ this->initArrays();
// set the initial condition to 0
external_force->clear();
velocity->clear();
acceleration->clear();
displacement->clear();
// initialize pbc
- if(pbc_pair.size()!=0)
- initPBC();
+ if (this->pbc_pair.size() != 0)
+ this->initPBC();
// initialize the time integration schemes
- switch(method) {
+ switch (this->method) {
case _explicit_lumped_mass:
- initExplicit();
+ this->initExplicit();
break;
case _explicit_consistent_mass:
- initSolver();
- initExplicit();
+ this->initSolver();
+ this->initExplicit();
break;
case _implicit_dynamic:
- initImplicit(true);
+ this->initImplicit(true);
break;
case _static:
- initImplicit(false);
+ this->initImplicit(false);
+ this->initArraysPreviousDisplacment();
break;
default:
AKANTU_EXCEPTION("analysis method not recognised by SolidMechanicsModel");
break;
}
+#ifdef AKANTU_DAMAGE_NON_LOCAL
+ /// create the non-local manager object for non-local damage computations
+ this->non_local_manager = new NonLocalManager(*this);
+#endif
+
// initialize the materials
- if(this->parser->getLastParsedFile() != "") {
- instantiateMaterials();
+ if (this->parser->getLastParsedFile() != "") {
+ this->instantiateMaterials();
}
- if(!smm_options.no_init_materials) {
- initMaterials();
+ if (!smm_options.no_init_materials) {
+ this->initMaterials();
}
- if(increment_flag)
+ if (increment_flag)
this->initBC(*this, *displacement, *increment, *external_force);
else
this->initBC(*this, *displacement, *external_force);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initParallel(MeshPartition * partition,
DataAccessor * data_accessor) {
AKANTU_DEBUG_IN();
- if (data_accessor == NULL) data_accessor = this;
+ 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.computeNormalsOnControlPoints(_not_ghost);
- fem_boundary.computeNormalsOnControlPoints(_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;
// 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();
- SolidMechanicsModel::setIncrementFlagOn();
- UInt nb_nodes = mesh.getNbNodes();
- std::stringstream sstr_disp_t;
- sstr_disp_t << id << ":previous_displacement";
- previous_displacement = &(alloc<Real > (sstr_disp_t.str(), nb_nodes, spatial_dimension, 0.));
+ this->setIncrementFlagOn();
+ if (not this->previous_displacement) {
+ UInt nb_nodes = this->mesh.getNbNodes();
+ std::stringstream sstr_disp_t;
+ sstr_disp_t << this->id << ":previous_displacement";
+
+ this->previous_displacement = &(this->alloc<Real>(
+ sstr_disp_t.str(), nb_nodes, this->spatial_dimension, 0.));
+ }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Allocate all the needed vectors. By default their are not necessarily set to
* 0
*/
void SolidMechanicsModel::initArrays() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
- std::stringstream sstr_disp; sstr_disp << id << ":displacement";
- std::stringstream sstr_forc; sstr_forc << id << ":force";
- std::stringstream sstr_ifor; sstr_forc << id << ":internal_force";
- std::stringstream sstr_boun; sstr_boun << id << ":blocked_dofs";
+ std::stringstream sstr_disp;
+ sstr_disp << id << ":displacement";
+ std::stringstream sstr_forc;
+ sstr_forc << id << ":force";
+ std::stringstream sstr_ifor;
+ sstr_forc << id << ":internal_force";
+ std::stringstream sstr_boun;
+ sstr_boun << id << ":blocked_dofs";
/* ------------------------------------------------------------------------ */
- //for static
- this->displacement = &(alloc<Real>(sstr_disp.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
- this->internal_force = &(alloc<Real>(sstr_ifor.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
- this->external_force = &(alloc<Real>(sstr_forc.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
- this->blocked_dofs = &(alloc<bool>(sstr_boun.str(), nb_nodes, spatial_dimension, false));
-
- this->getDOFManager().registerDOFs("displacements", *this->displacement, _dst_nodal);
- this->getDOFManager().registerBlockedDOFs("displacements", *this->blocked_dofs);
-
- std::stringstream sstr_curp; sstr_curp << id << ":current_position";
- this->current_position = &(alloc<Real>(sstr_curp.str(), 0, spatial_dimension, REAL_INIT_VALUE));
+ // for static
+ this->displacement = &(alloc<Real>(sstr_disp.str(), nb_nodes,
+ spatial_dimension, REAL_INIT_VALUE));
+ this->internal_force = &(alloc<Real>(sstr_ifor.str(), nb_nodes,
+ spatial_dimension, REAL_INIT_VALUE));
+ this->external_force = &(alloc<Real>(sstr_forc.str(), nb_nodes,
+ spatial_dimension, REAL_INIT_VALUE));
+ this->blocked_dofs =
+ &(alloc<bool>(sstr_boun.str(), nb_nodes, spatial_dimension, false));
+
+ this->getDOFManager().registerDOFs("displacements", *this->displacement,
+ _dst_nodal);
+ this->getDOFManager().registerBlockedDOFs("displacements",
+ *this->blocked_dofs);
+
+ std::stringstream sstr_curp;
+ sstr_curp << id << ":current_position";
+ this->current_position =
+ &(alloc<Real>(sstr_curp.str(), 0, spatial_dimension, REAL_INIT_VALUE));
/* ------------------------------------------------------------------------ */
// for dynamic
- std::stringstream sstr_velo; sstr_velo << id << ":velocity";
- std::stringstream sstr_acce; sstr_acce << id << ":acceleration";
- this->velocity = &(alloc<Real>(sstr_velo.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
- this->acceleration = &(alloc<Real>(sstr_acce.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
-
- this->getDOFManager().registerDOFsDerivative("displacements", 1, *this->velocity);
- this->getDOFManager().registerDOFsDerivative("displacements", 2, *this->acceleration);
-
- 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";
+ this->velocity = &(alloc<Real>(sstr_velo.str(), nb_nodes, spatial_dimension,
+ REAL_INIT_VALUE));
+ this->acceleration = &(alloc<Real>(sstr_acce.str(), nb_nodes,
+ spatial_dimension, REAL_INIT_VALUE));
+
+ this->getDOFManager().registerDOFsDerivative("displacements", 1,
+ *this->velocity);
+ this->getDOFManager().registerDOFsDerivative("displacements", 2,
+ *this->acceleration);
+
+ 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);
this->material_index.alloc(nb_element, 1, *it, gt);
this->material_local_numbering.alloc(nb_element, 1, *it, gt);
}
}
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(){
- PBCSynchronizer * synch = new PBCSynchronizer(pbc_pair);
- synch_registry->registerSynchronizer(*synch, _gst_smm_uv);
- synch_registry->registerSynchronizer(*synch, _gst_smm_mass);
- synch_registry->registerSynchronizer(*synch, _gst_smm_res);
- synch_registry->registerSynchronizer(*synch, _gst_for_dump);
+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();
this->current_position->copy(this->mesh.getNodes());
- Array<Real>::vector_iterator cpos_it = this->current_position->begin(spatial_dimension);
- Array<Real>::vector_iterator cpos_end = this->current_position->end(spatial_dimension);
- Array<Real>::const_vector_iterator disp_it = this->displacement->begin(spatial_dimension);
+ Array<Real>::vector_iterator cpos_it =
+ this->current_position->begin(spatial_dimension);
+ Array<Real>::vector_iterator cpos_end =
+ this->current_position->end(spatial_dimension);
+ Array<Real>::const_vector_iterator disp_it =
+ this->displacement->begin(spatial_dimension);
for (; cpos_it != cpos_end; ++cpos_it, ++disp_it) {
*cpos_it += *disp_it;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initializeUpdateResidualData() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
internal_force->resize(nb_nodes);
/// copy the forces in residual for boundary conditions
- this->getDOFManager().assembleToResidual("displacements", *this->external_force);
+ this->getDOFManager().assembleToResidual("displacements",
+ *this->external_force);
// start synchronization
synch_registry->asynchronousSynchronize(_gst_smm_uv);
synch_registry->waitEndSynchronize(_gst_smm_uv);
this->updateCurrentPosition();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* 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 */
- synch_registry->asynchronousSynchronize(_gst_mnl_for_average);
- AKANTU_DEBUG_INFO("Compute non local stresses for local elements");
-
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
- Material & mat = **mat_it;
- mat.computeAllNonLocalStresses(_not_ghost);
- }
-
-
- AKANTU_DEBUG_INFO("Wait distant non local stresses");
- synch_registry->waitEndSynchronize(_gst_mnl_for_average);
-
- AKANTU_DEBUG_INFO("Compute non local stresses for ghosts elements");
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
- Material & mat = **mat_it;
- mat.computeAllNonLocalStresses(_ghost);
- }
+ 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);
}
- this->getDOFManager().assembleToResidual("displacements", *this->internal_force);
+ this->getDOFManager().assembleToResidual("displacements",
+ *this->internal_force);
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 */
- synch_registry->asynchronousSynchronize(_gst_mnl_for_average);
-
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
- Material & mat = **mat_it;
- mat.computeAllNonLocalStresses(_not_ghost);
- }
-
- synch_registry->waitEndSynchronize(_gst_mnl_for_average);
-
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
- Material & mat = **mat_it;
- mat.computeAllNonLocalStresses(_ghost);
- }
+ 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);
}
}
}
-
/* -------------------------------------------------------------------------- */
/* Implicit scheme */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// /**
// * Initialize the solver and create the sparse matrices needed.
// *
// */
// void SolidMechanicsModel::initSolver(__attribute__((unused))
// SolverOptions & options) {
// UInt nb_global_nodes = mesh.getNbGlobalNodes();
-// jacobian_matrix = &(this->getDOFManager().getNewMatrix("jacobian", _symmetric));
+// jacobian_matrix = &(this->getDOFManager().getNewMatrix("jacobian",
+// _symmetric));
-// // jacobian_matrix->buildProfile(mesh, *dof_synchronizer, spatial_dimension);
+// // jacobian_matrix->buildProfile(mesh, *dof_synchronizer,
+// spatial_dimension);
// if (!isExplicit()) {
// delete stiffness_matrix;
// std::stringstream sstr_sti;
// sstr_sti << id << ":stiffness_matrix";
-// stiffness_matrix = &(this->getDOFManager().getNewMatrix("stiffness", _symmetric));
+// stiffness_matrix = &(this->getDOFManager().getNewMatrix("stiffness",
+// _symmetric));
// }
-
// if (solver) solver->initialize(options);
// }
-// /* -------------------------------------------------------------------------- */
+// /* --------------------------------------------------------------------------
+// */
// void SolidMechanicsModel::initJacobianMatrix() {
-// // @todo make it more flexible: this is an ugly patch to treat the case of non
+// // @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;
-// jacobian_matrix = &(this->getDOFManager().getNewMatrix("jacobian", "stiffness"));
+// jacobian_matrix = &(this->getDOFManager().getNewMatrix("jacobian",
+// "stiffness"));
// std::stringstream sstr_solv; sstr_solv << id << ":solver";
// delete solver;
// solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
// if(solver)
// solver->initialize(_solver_no_options);
// }
/* -------------------------------------------------------------------------- */
/**
* Initialize the implicit solver, either for dynamic or static cases,
*
* @param dynamic
*/
void SolidMechanicsModel::initImplicit(bool dynamic) {
AKANTU_DEBUG_IN();
method = dynamic ? _implicit_dynamic : _static;
- if (!increment) setIncrementFlagOn();
+ if (!increment)
+ setIncrementFlagOn();
initSolver();
// if(method == _implicit_dynamic) {
// if(integrator) delete integrator;
// integrator = new TrapezoidalRule2();
// }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleStiffnessMatrix() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Assemble the new stiffness matrix.");
// 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() {
return this->getDOFManager().getNewMatrix("velocity_damping", "jacobian");
}
-// /* -------------------------------------------------------------------------- */
+// /* --------------------------------------------------------------------------
+// */
// void SolidMechanicsModel::implicitPred() {
// AKANTU_DEBUG_IN();
// if(previous_displacement) previous_displacement->copy(*displacement);
// if(method == _implicit_dynamic)
// integrator->integrationSchemePred(time_step,
// *displacement,
// *velocity,
// *acceleration,
// *blocked_dofs);
// AKANTU_DEBUG_OUT();
// }
-// /* -------------------------------------------------------------------------- */
+// /* --------------------------------------------------------------------------
+// */
// void SolidMechanicsModel::implicitCorr() {
// AKANTU_DEBUG_IN();
// if(method == _implicit_dynamic) {
// integrator->integrationSchemeCorrDispl(time_step,
// *displacement,
// *velocity,
// *acceleration,
// *blocked_dofs,
// *increment);
// } else {
// UInt nb_nodes = displacement->getSize();
// UInt nb_degree_of_freedom = displacement->getNbComponent() * nb_nodes;
// Real * incr_val = increment->storage();
// Real * disp_val = displacement->storage();
// bool * boun_val = blocked_dofs->storage();
-// for (UInt j = 0; j < nb_degree_of_freedom; ++j, ++disp_val, ++incr_val, ++boun_val){
+// 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);
- Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
- 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)
- AKANTU_DEBUG_ERROR("No function called to assemble the mass.");
+ 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;
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().getNbQuadraturePoints(type);
+ 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().interpolateOnQuadraturePoints(*velocity, vel_on_quad,
- spatial_dimension,
- type, _not_ghost,
- filter_element);
+ getFEEngine().interpolateOnIntegrationPoints(*velocity, vel_on_quad,
+ spatial_dimension, type,
+ _not_ghost, filter_element);
- Array<Real>::vector_iterator vit = vel_on_quad.begin(spatial_dimension);
- Array<Real>::vector_iterator vend = vel_on_quad.end(spatial_dimension);
+ 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 * velo = velocity->storage();
+ Real * incr_or_velo = NULL;
+ if (this->method == _static) {
+ incr_or_velo = this->increment->storage();
+ } else {
+ incr_or_velo = this->velocity->storage();
+ }
Real * forc = external_force->storage();
Real * resi = internal_force->storage();
bool * boun = blocked_dofs->storage();
Real work = 0.;
- UInt nb_nodes = mesh.getNbNodes();
+ UInt nb_nodes = this->mesh.getNbNodes();
for (UInt n = 0; n < nb_nodes; ++n) {
- bool is_local_node = mesh.isLocalOrMasterNode(n);
- bool is_not_pbc_slave_node = !isPBCSlaveNode(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 < spatial_dimension; ++i) {
+ for (UInt i = 0; i < this->spatial_dimension; ++i) {
if (count_node) {
- if(*boun)
- work -= *resi * *velo * time_step;
+ if (*boun)
+ work -= *resi * *incr_or_velo;
else
- work += *forc * *velo * time_step;
+ work += *forc * *incr_or_velo;
}
- ++velo;
+ ++incr_or_velo;
++forc;
++resi;
++boun;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&work, 1, _so_sum);
+ if (this->method != _static)
+ work *= this->time_step;
AKANTU_DEBUG_OUT();
return work;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getEnergy(const std::string & energy_id) {
AKANTU_DEBUG_IN();
if (energy_id == "kinetic") {
return getKineticEnergy();
- } else if (energy_id == "external work"){
+ } 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) {
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);
+ 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_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());
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->initSolver();
- }
+ 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(external_force) external_force->resize(nb_nodes);
- if(internal_force) internal_force->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 (external_force)
+ external_force->resize(nb_nodes);
+ if (internal_force)
+ internal_force->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);
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);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModel::onNodesRemoved(__attribute__((unused)) const Array<UInt> & element_list,
+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(internal_force) mesh.removeNodesFromArray(*internal_force, new_numbering);
- if(external_force) mesh.removeNodesFromArray(*external_force, 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);
+ __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 (internal_force)
+ mesh.removeNodesFromArray(*internal_force, new_numbering);
+ if (external_force)
+ mesh.removeNodesFromArray(*external_force, 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);
if (method != _explicit_lumped_mass) {
this->initSolver();
}
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::isInternal(const std::string & field_name,
- const ElementKind & element_kind){
+ 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(field_name, element_kind);
+ 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) {
-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);
+ 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(field_name, element_kind))
- return materials[m]->getInternalDataPerElem(field_name, element_kind);
+ for (UInt m = 0; m < materials.size(); ++m) {
+ if (materials[m]->isInternal<Real>(field_name, element_kind))
+ return materials[m]->getInternalDataPerElem<Real>(field_name,
+ element_kind);
}
return ElementTypeMap<UInt>();
}
-
/* -------------------------------------------------------------------------- */
-ElementTypeMapArray<Real> & SolidMechanicsModel::flattenInternal(const std::string & field_name,
- const ElementKind & kind,
- const GhostType ghost_type){
- std::pair<std::string,ElementKind> key(field_name,kind);
- if (this->registered_internals.count(key) == 0){
+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);
+ new ElementTypeMapArray<Real>(field_name, this->id);
}
ElementTypeMapArray<Real> * internal_flat = this->registered_internals[key];
typedef ElementTypeMapArray<Real>::type_iterator iterator;
- iterator tit = internal_flat->firstType(spatial_dimension,
- ghost_type,
- kind);
- iterator end = internal_flat->lastType(spatial_dimension,
- ghost_type,
- kind);
+ 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();
+ (*internal_flat)(type, ghost_type).clear();
}
for (UInt m = 0; m < materials.size(); ++m) {
- if (materials[m]->isInternal(field_name, kind))
- materials[m]->flattenInternal(field_name, *internal_flat, ghost_type, kind);
+ if (materials[m]->isInternal<Real>(field_name, kind))
+ materials[m]->flattenInternal(field_name, *internal_flat, ghost_type,
+ kind);
}
- return *internal_flat;
+ return *internal_flat;
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModel::flattenAllRegisteredInternals(const ElementKind & kind){
+void SolidMechanicsModel::flattenAllRegisteredInternals(
+ const ElementKind & kind) {
- std::map<std::pair<std::string, ElementKind>,
- ElementTypeMapArray<Real> *>::iterator it = this->registered_internals.begin();
- std::map<std::pair<std::string, ElementKind>,
- ElementTypeMapArray<Real> *>::iterator end = this->registered_internals.end();
+ 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){
+ 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 * field = NULL;
if (field_name == "partitions")
field = mesh.createElementalField<UInt, dumper::ElementPartitionField>(
mesh.getConnectivities(), group_name, spatial_dimension, kind);
else if (field_name == "material_index")
field = mesh.createElementalField<UInt, Vector, dumper::ElementalField>(
material_index, group_name, spatial_dimension, kind);
else {
// this copy of field_name is used to compute derivated data such as
// strain and von mises stress that are based on grad_u and stress
std::string field_name_copy(field_name);
if (field_name == "strain" || field_name == "Green strain" ||
field_name == "principal strain" ||
field_name == "principal Green strain")
field_name_copy = "grad_u";
else if (field_name == "Von Mises stress")
field_name_copy = "stress";
bool is_internal = this->isInternal(field_name_copy, kind);
if (is_internal) {
ElementTypeMap<UInt> nb_data_per_elem =
this->getInternalDataPerElem(field_name_copy, kind);
ElementTypeMapArray<Real> & internal_flat =
this->flattenInternal(field_name_copy, kind);
field = mesh.createElementalField<Real, dumper::InternalMaterialField>(
internal_flat, group_name, spatial_dimension, kind, nb_data_per_elem);
if (field_name == "strain") {
dumper::ComputeStrain<false> * foo =
new dumper::ComputeStrain<false>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
} else if (field_name == "Von Mises stress") {
dumper::ComputeVonMisesStress * foo =
new dumper::ComputeVonMisesStress(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
} else if (field_name == "Green strain") {
dumper::ComputeStrain<true> * foo =
new dumper::ComputeStrain<true>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
} else if (field_name == "principal strain") {
dumper::ComputePrincipalStrain<false> * foo =
new dumper::ComputePrincipalStrain<false>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
} else if (field_name == "principal Green strain") {
dumper::ComputePrincipalStrain<true> * foo =
new dumper::ComputePrincipalStrain<true>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
}
// treat the paddings
if (padding_flag) {
if (field_name == "stress") {
if (spatial_dimension == 2) {
dumper::StressPadder<2> * foo = new dumper::StressPadder<2>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
}
} else if (field_name == "strain" || field_name == "Green strain") {
if (spatial_dimension == 2) {
dumper::StrainPadder<2> * foo = new dumper::StrainPadder<2>(*this);
field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
}
}
}
// homogenize the field
dumper::ComputeFunctorInterface * foo =
dumper::HomogenizerProxy::createHomogenizer(*field);
field = dumper::FieldComputeProxy::createFieldCompute(field, *foo);
}
}
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field *
SolidMechanicsModel::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
std::map<std::string, Array<Real> *> real_nodal_fields;
real_nodal_fields["displacement"] = this->displacement;
real_nodal_fields["mass"] = this->mass;
real_nodal_fields["velocity"] = this->velocity;
real_nodal_fields["acceleration"] = this->acceleration;
real_nodal_fields["force"] = this->external_force;
real_nodal_fields["residual"] = this->internal_force;
real_nodal_fields["increment"] = this->increment;
dumper::Field * field = NULL;
if (padding_flag)
- field = this->mesh.createNodalField(real_nodal_fields[field_name], group_name, 3);
+ field = this->mesh.createNodalField(real_nodal_fields[field_name],
+ group_name, 3);
else
- field = this->mesh.createNodalField(real_nodal_fields[field_name], group_name);
+ field =
+ this->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,
+ 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(__attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) 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(__attribute__((unused)) const std::string & field_name,
+ __attribute__((unused)) const std::string & group_name,
+ __attribute__((unused)) 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);
external_force->printself(stream, indent + 2);
internal_force->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 2130d4c5d..3543536a9 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,712 +1,746 @@
/**
* @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 "material_selector.hh"
#include "solid_mechanics_model_event_handler.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class Material;
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,
+ 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
- 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;
/* ------------------------------------------------------------------------ */
/* 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
void updateIncrement();
+ /// Copy the actuel displacement into previous displacement
void updatePreviousDisplacement();
+ /// Save stress and strain through EventManager
void saveStressAndStrainBeforeDamage();
+ /// Update energies through EventManager
void updateEnergiesAfterDamage();
/// Solve the system @f[ A x = \alpha b @f] with A a lumped matrix
- void solveLumped(Array <Real> & x,
- const Array <Real> & A,
- const Array <Real> & b,
- const Array <bool> & blocked_dofs,
- Real alpha);
+ void solveLumped(Array<Real> & x, const Array<Real> & A,
+ const Array<Real> & b, const Array<bool> & blocked_dofs,
+ Real alpha);
/// explicit integration predictor
void explicitPred();
/// explicit integration corrector
void explicitCorr();
public:
void solveStep();
/* ------------------------------------------------------------------------ */
/* Implicit */
/* ------------------------------------------------------------------------ */
public:
/// initialize the solver and the jacobian_matrix (called by initImplicit)
void initSolver();
/// initialize the stuff for the implicit solver
void initImplicit(bool dynamic = false);
/// 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);
+ bool solveStep(Real tolerance, Real & error, UInt max_iteration = 100,
+ bool do_not_factorize = false);
public:
/**
* solve Ku = f using the the given convergence method (see
* akantu::SolveConvergenceMethod) and the given convergence
* criteria (see akantu::SolveConvergenceCriteria)
**/
template <SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool solveStatic(Real tolerance, UInt max_iteration,
bool do_not_factorize = false);
/// create and return the velocity damping matrix
SparseMatrix & initVelocityDampingMatrix();
/// implicit time integration predictor
void implicitPred();
/// implicit time integration corrector
void implicitCorr();
/// compute the Cauchy stress on user demand.
void computeCauchyStresses();
// /// compute A and solve @f[ A\delta u = f_ext - f_int @f]
// template <NewmarkBeta::IntegrationSchemeCorrectorType type>
// void solve(Array<Real> &increment, Real block_val = 1.,
// bool need_factorize = true, bool has_profile_changed = false);
protected:
/// finish the computation of residual to solve in increment
void updateResidualInternal();
/// compute the support reaction and store it in force
void updateSupportReaction();
private:
/// re-initialize the J matrix (to use if the profile of K changed)
void initJacobianMatrix();
/* ------------------------------------------------------------------------ */
/* Explicit/Implicit */
/* ------------------------------------------------------------------------ */
public:
/// Update the stresses for the computation of the residual of the Stiffness
/// matrix in the case of finite deformation
void computeStresses();
/// synchronize the ghost element boundaries values
void synchronizeBoundaries();
/* ------------------------------------------------------------------------ */
/* Materials (solid_mechanics_model_material.cc) */
/* ------------------------------------------------------------------------ */
public:
- /// registers all the custom materials of a given type present in the input file
- template <typename M>
- void registerNewCustomMaterials(const ID & mat_type);
+ /// registers all the custom materials of a given type present in the input
+ /// file
+ template <typename M> void registerNewCustomMaterials(const ID & mat_type);
/// register an empty material of a given type
template <typename M>
Material & registerNewEmptyMaterial(const std::string & name);
// /// Use a UIntData in the mesh to specify the material to use per element
// void setMaterialIDsFromIntData(const std::string & data_name);
/// reassigns materials depending on the material selector
virtual void reassignMaterial();
+ /// apply a constant eigen_grad_u on all quadrature points of a given material
+ virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
+ const ID & material_name,
+ const GhostType ghost_type = _not_ghost);
+
protected:
/// register a material in the dynamic database
template <typename M>
Material & registerNewMaterial(const ParserSection & mat_section);
/// read the material files to instantiate all the materials
void instantiateMaterials();
/// set the element_id_by_material and add the elements to the good materials
- void assignMaterialToElements(const ElementTypeMapArray<UInt> * filter = NULL);
+ 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,
+ 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,
+ virtual void onNodesAdded(const Array<UInt> & nodes_list,
const NewNodesEvent & event);
- virtual void onNodesRemoved(const Array <UInt> & element_list,
- const Array <UInt> & new_numbering,
+ virtual void onNodesRemoved(const Array<UInt> & element_list,
+ const Array<UInt> & new_numbering,
const RemovedNodesEvent & event);
- virtual void onElementsAdded(const Array <Element> & nodes_list,
+ 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
+ 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);
virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
-
virtual dumper::Field * createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
const UInt & spatial_dimension,
const ElementKind & kind);
virtual void dump(const std::string & dumper_name);
virtual void dump(const std::string & dumper_name, UInt step);
virtual void dump(const std::string & dumper_name, Real time, UInt step);
virtual void dump();
virtual void dump(UInt step);
virtual void dump(Real time, UInt step);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// return the dimension of the system space
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// get the current value of the time step
AKANTU_GET_MACRO(TimeStep, time_step, Real);
/// set the value of the time step
void setTimeStep(Real time_step);
/// return the of iterations done in the last solveStep
AKANTU_GET_MACRO(NumberIter, n_iter, UInt);
/// get the value of the conversion from forces/ mass to acceleration
AKANTU_GET_MACRO(F_M2A, f_m2a, Real);
/// set the value of the conversion from forces/ mass to acceleration
AKANTU_SET_MACRO(F_M2A, f_m2a, Real);
/// get the SolidMechanicsModel::displacement vector
- AKANTU_GET_MACRO(Displacement, *displacement, Array <Real> &);
+ 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 (external forces)
AKANTU_GET_MACRO(Force, *external_force, Array <Real> &);
/// get the SolidMechanicsModel::internal_force vector (internal forces)
AKANTU_GET_MACRO(InternalForce, *internal_force, 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 &);
// /// get the mass matrix
// AKANTU_GET_MACRO(MassMatrix, *mass_matrix, SparseMatrix &);
// /// get the velocity damping matrix
// AKANTU_GET_MACRO(VelocityDampingMatrix, *velocity_damping_matrix, SparseMatrix &);
/// get the FEEngine object to integrate or interpolate on the boundary
inline FEEngine & getFEEngineBoundary(const ID & name = "");
// /// get integrator
// AKANTU_GET_MACRO(Integrator, *integrator, const IntegrationScheme2ndOrder &);
/// get 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);
- template <int dim, class model_type>
- friend struct ContactData;
+ /// get the non-local manager
+ AKANTU_GET_MACRO(NonLocalManager, *non_local_manager, NonLocalManager &);
+
+ template <int dim, class model_type> friend struct ContactData;
template <int Dim, AnalysisMethod s, ContactResolutionMethod r>
friend class ContactResolution;
protected:
friend class Material;
protected:
/// compute the stable time step
Real getStableTimeStep(const GhostType & ghost_type);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// number of iterations
UInt n_iter;
/// time step
Real time_step;
/// conversion coefficient form force/mass to acceleration
Real f_m2a;
/// displacements array
- Array <Real> *displacement;
+ Array<Real> * displacement;
/// displacements array at the previous time step (used in finite deformation)
- Array <Real> *previous_displacement;
+ Array<Real> * previous_displacement;
/// increment of displacement
Array <Real> *increment;
/// 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;
/// external forces array
Array <Real> *external_force;
/// internal forces array
Array <Real> *internal_force;
/// 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;
+ /// mass matrix
+ SparseMatrix * mass_matrix;
- // /// velocity damping matrix
- // SparseMatrix *velocity_damping_matrix;
+ /// velocity damping matrix
+ SparseMatrix * velocity_damping_matrix;
- // /// stiffness matrix
- // SparseMatrix *stiffness_matrix;
+ /// stiffness matrix
+ SparseMatrix * stiffness_matrix;
- // /// jacobian matrix @f[A = cM + dD + K@f] with @f[c = \frac{1}{\beta \Delta
- // /// t^2}, d = \frac{\gamma}{\beta \Delta t} @f]
- // SparseMatrix *jacobian_matrix;
+ /// jacobian matrix @f[A = cM + dD + K@f] with @f[c = \frac{1}{\beta \Delta
+ /// t^2}, d = \frac{\gamma}{\beta \Delta t} @f]
+ SparseMatrix * jacobian_matrix;
/// Arrays containing the material index for each element
ElementTypeMapArray<UInt> material_index;
- /// Arrays containing the position in the element filter of the material (material's local numbering)
+ /// 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;
/// flag defining if the increment must be computed or not
bool increment_flag;
/// 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;
+ /// 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"
#include "solid_mechanics_model_inline_impl.cc"
/// 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.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive.cc
deleted file mode 100644
index 022e59333..000000000
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive.cc
+++ /dev/null
@@ -1,743 +0,0 @@
-/**
- * @file solid_mechanics_model_cohesive.cc
- *
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Tue May 08 2012
- * @date last modification: Fri Sep 05 2014
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-#include <algorithm>
-#include "shape_cohesive.hh"
-#include "solid_mechanics_model_cohesive.hh"
-#include "dumpable_inline_impl.hh"
-#include "material_cohesive.hh"
-
-#ifdef AKANTU_USE_IOHELPER
-# include "dumper_paraview.hh"
-#endif
-
-/* -------------------------------------------------------------------------- */
-
-__BEGIN_AKANTU__
-
-const SolidMechanicsModelCohesiveOptions default_solid_mechanics_model_cohesive_options(_explicit_lumped_mass,
- false,
- false);
-
-/* -------------------------------------------------------------------------- */
-
-SolidMechanicsModelCohesive::SolidMechanicsModelCohesive(Mesh & mesh,
- UInt dim,
- const ID & id,
- const MemoryID & memory_id) :
- SolidMechanicsModel(mesh, dim, id, memory_id),
- tangents("tangents", id),
- facet_stress("facet_stress", id),
- facet_material("facet_material", id) {
- AKANTU_DEBUG_IN();
-
- inserter = NULL;
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- facet_synchronizer = NULL;
- facet_stress_synchronizer = NULL;
- cohesive_distributed_synchronizer = NULL;
- global_connectivity = NULL;
-#endif
-
- delete material_selector;
- material_selector = new DefaultMaterialCohesiveSelector(*this);
-
- this->registerEventHandler(*this);
-
-#if defined(AKANTU_USE_IOHELPER)
- this->mesh.registerDumper<DumperParaview>("cohesive elements", id);
- this->mesh.addDumpMeshToDumper("cohesive elements",
- mesh, spatial_dimension, _not_ghost, _ek_cohesive);
-#endif
-
- AKANTU_DEBUG_OUT();
-}
-
-
-/* -------------------------------------------------------------------------- */
-SolidMechanicsModelCohesive::~SolidMechanicsModelCohesive() {
- AKANTU_DEBUG_IN();
-
- delete inserter;
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- delete cohesive_distributed_synchronizer;
- delete facet_synchronizer;
- delete facet_stress_synchronizer;
-#endif
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::setTimeStep(Real time_step) {
- SolidMechanicsModel::setTimeStep(time_step);
-
-#if defined(AKANTU_USE_IOHELPER)
- this->mesh.getDumper("cohesive elements").setTimeStep(time_step);
-#endif
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::initFull(const ModelOptions & options) {
- AKANTU_DEBUG_IN();
-
- const SolidMechanicsModelCohesiveOptions & smmc_options =
- dynamic_cast<const SolidMechanicsModelCohesiveOptions &>(options);
-
- this->is_extrinsic = smmc_options.extrinsic;
-
- if (!inserter)
- inserter = new CohesiveElementInserter(mesh, is_extrinsic, synch_parallel,
- id+":cohesive_element_inserter");
-
- SolidMechanicsModel::initFull(options);
-
- AKANTU_DEBUG_OUT();
-}
-
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::initMaterials() {
- AKANTU_DEBUG_IN();
-
- // make sure the material are instantiated
- if(!are_materials_instantiated) instantiateMaterials();
-
- /// find the first cohesive material
- UInt cohesive_index = 0;
-
- while ((dynamic_cast<MaterialCohesive *>(materials[cohesive_index]) == NULL)
- && cohesive_index <= materials.size())
- ++cohesive_index;
-
- AKANTU_DEBUG_ASSERT(cohesive_index != materials.size(),
- "No cohesive materials in the material input file");
-
- material_selector->setFallback(cohesive_index);
-
- // set the facet information in the material in case of dynamic insertion
- if (is_extrinsic) {
- const Mesh & mesh_facets = inserter->getMeshFacets();
- mesh_facets.initElementTypeMapArray(facet_material, 1, spatial_dimension - 1);
-
- Element element;
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
- element.ghost_type = *gt;
- Mesh::type_iterator first = mesh_facets.firstType(spatial_dimension - 1, *gt);
- Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1, *gt);
- for(;first != last; ++first) {
- element.type = *first;
- Array<UInt> & f_material = facet_material(*first, *gt);
- UInt nb_element = mesh_facets.getNbElement(*first, *gt);
- f_material.resize(nb_element);
- f_material.set(cohesive_index);
- for (UInt el = 0; el < nb_element; ++el) {
- element.element = el;
- UInt mat_index = (*material_selector)(element);
- f_material(el) = mat_index;
- MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(*materials[mat_index]);
- mat.addFacet(element);
- }
- }
- }
- SolidMechanicsModel::initMaterials();
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- if (facet_synchronizer != NULL)
- inserter->initParallel(facet_synchronizer);
-#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);
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(std::string cohesive_surfaces) {
-
- AKANTU_DEBUG_IN();
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- if (facet_synchronizer != NULL)
- inserter->initParallel(facet_synchronizer);
-#endif
- std::istringstream split(cohesive_surfaces);
- std::string physname;
- while(std::getline(split,physname,',')){
- AKANTU_DEBUG_INFO("Pre-inserting cohesive elements along facets from physical surface: "
- << physname);
- insertElementsFromMeshData(physname);
- }
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- if (facet_synchronizer != NULL){
- facet_synchronizer-> asynchronousSynchronize(*inserter, _gst_ce_groups);
- facet_synchronizer-> waitEndSynchronize(*inserter, _gst_ce_groups);
- }
-#endif
-
- SolidMechanicsModel::initMaterials();
-
- delete material_selector;
- material_selector = new MeshDataMaterialCohesiveSelector(*this);
- inserter->insertElements();
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(UInt cohesive_index) {
-
- AKANTU_DEBUG_IN();
-
- for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
- Mesh::type_iterator first = mesh.firstType(spatial_dimension, *gt, _ek_cohesive);
- Mesh::type_iterator last = mesh.lastType(spatial_dimension, *gt, _ek_cohesive);
-
- for(;first != last; ++first) {
- Array<UInt> & mat_indexes = this->material_index(*first, *gt);
- Array<UInt> & mat_loc_num = this->material_local_numbering(*first, *gt);
- mat_indexes.set(cohesive_index);
- mat_loc_num.clear();
- }
- }
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- if (facet_synchronizer != NULL)
- inserter->initParallel(facet_synchronizer);
-#endif
-
- SolidMechanicsModel::initMaterials();
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-/**
- * Initialize the model,basically it pre-compute the shapes, shapes derivatives
- * and jacobian
- *
- */
-void SolidMechanicsModelCohesive::initModel() {
- AKANTU_DEBUG_IN();
-
- SolidMechanicsModel::initModel();
-
- registerFEEngineObject<MyFEEngineCohesiveType>("CohesiveFEEngine", mesh, spatial_dimension);
-
- /// add cohesive type connectivity
- ElementType type = _not_defined;
-
- for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end(); ++gt) {
-
- GhostType type_ghost = *gt;
-
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, type_ghost);
- Mesh::type_iterator last = mesh.lastType(spatial_dimension, type_ghost);
-
- for (; it != last; ++it) {
- const Array<UInt> & connectivity = mesh.getConnectivity(*it, type_ghost);
- if (connectivity.getSize() != 0) {
- type = *it;
- ElementType type_facet = Mesh::getFacetType(type);
- ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
- mesh.addConnectivityType(type_cohesive, type_ghost);
- }
- }
- }
-
- AKANTU_DEBUG_ASSERT(type != _not_defined, "No elements in the mesh");
-
- getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
- getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
-
- registerFEEngineObject<MyFEEngineType>("FacetsFEEngine",
- mesh.getMeshFacets(),
- spatial_dimension - 1);
-
- if (is_extrinsic) {
- getFEEngine("FacetsFEEngine").initShapeFunctions(_not_ghost);
- getFEEngine("FacetsFEEngine").initShapeFunctions(_ghost);
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::limitInsertion(BC::Axis axis,
- Real first_limit,
- Real second_limit) {
- AKANTU_DEBUG_IN();
- inserter->setLimit(axis, first_limit, second_limit);
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::insertIntrinsicElements() {
- AKANTU_DEBUG_IN();
- inserter->insertIntrinsicElements();
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::insertElementsFromMeshData(std::string physname) {
- AKANTU_DEBUG_IN();
-
- UInt material_index = SolidMechanicsModel::getMaterialIndex(physname);
- inserter->insertIntrinsicElements(physname, material_index);
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::initAutomaticInsertion() {
- AKANTU_DEBUG_IN();
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- if (facet_stress_synchronizer != NULL) {
- DataAccessor * data_accessor = this;
- const ElementTypeMapArray<UInt> & rank_to_element = synch_parallel->getPrankToElement();
-
- facet_stress_synchronizer->updateFacetStressSynchronizer(*inserter,
- rank_to_element,
- *data_accessor);
- }
-#endif
-
- inserter->getMeshFacets().initElementTypeMapArray(facet_stress,
- 2 * spatial_dimension * spatial_dimension,
- spatial_dimension - 1);
-
- resizeFacetStress();
-
- /// compute normals on facets
- computeNormals();
-
- initStressInterpolation();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::updateAutomaticInsertion() {
- AKANTU_DEBUG_IN();
-
- inserter->limitCheckFacets();
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- if (facet_stress_synchronizer != NULL) {
- DataAccessor * data_accessor = this;
- const ElementTypeMapArray<UInt> & rank_to_element = synch_parallel->getPrankToElement();
-
- facet_stress_synchronizer->updateFacetStressSynchronizer(*inserter,
- rank_to_element,
- *data_accessor);
- }
-#endif
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::initStressInterpolation() {
- Mesh & mesh_facets = inserter->getMeshFacets();
-
- /// compute quadrature points coordinates on facets
- Array<Real> & position = mesh.getNodes();
-
- ElementTypeMapArray<Real> quad_facets("quad_facets", id);
- mesh_facets.initElementTypeMapArray(quad_facets,
- spatial_dimension, spatial_dimension - 1);
-
- getFEEngine("FacetsFEEngine").interpolateOnQuadraturePoints(position, quad_facets);
-
- /// compute elements quadrature point positions and build
- /// element-facet quadrature points data structure
- ElementTypeMapArray<Real> elements_quad_facets("elements_quad_facets", id);
-
- mesh.initElementTypeMapArray(elements_quad_facets,
- spatial_dimension,
- spatial_dimension);
-
- for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end(); ++gt) {
-
- GhostType elem_gt = *gt;
-
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, elem_gt);
- Mesh::type_iterator last = mesh.lastType(spatial_dimension, elem_gt);
-
- for (; it != last; ++it) {
- ElementType type = *it;
- UInt nb_element = mesh.getNbElement(type, elem_gt);
- if (nb_element == 0) continue;
-
- /// compute elements' quadrature points and list of facet
- /// quadrature points positions by element
- Array<Element> & facet_to_element = mesh_facets.getSubelementToElement(type,
- elem_gt);
- UInt nb_facet_per_elem = facet_to_element.getNbComponent();
-
- Array<Real> & el_q_facet = elements_quad_facets(type, elem_gt);
-
- ElementType facet_type = Mesh::getFacetType(type);
-
- UInt nb_quad_per_facet =
- getFEEngine("FacetsFEEngine").getNbQuadraturePoints(facet_type);
-
- el_q_facet.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet);
-
- for (UInt el = 0; el < nb_element; ++el) {
- for (UInt f = 0; f < nb_facet_per_elem; ++f) {
- Element global_facet_elem = facet_to_element(el, f);
- UInt global_facet = global_facet_elem.element;
- GhostType facet_gt = global_facet_elem.ghost_type;
- const Array<Real> & quad_f = quad_facets(facet_type, facet_gt);
-
- for (UInt q = 0; q < nb_quad_per_facet; ++q) {
- for (UInt s = 0; s < spatial_dimension; ++s) {
- el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet
- + f * nb_quad_per_facet + q, s)
- = quad_f(global_facet * nb_quad_per_facet + q, s);
- }
- }
- }
- }
- }
- }
-
- /// loop over non cohesive materials
- for (UInt m = 0; m < materials.size(); ++m) {
- try {
- MaterialCohesive & mat __attribute__((unused)) =
- dynamic_cast<MaterialCohesive &>(*materials[m]);
- } catch(std::bad_cast&) {
- /// initialize the interpolation function
- materials[m]->initElementalFieldInterpolation(elements_quad_facets);
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::updateResidual(bool need_initialize) {
- AKANTU_DEBUG_IN();
-
- if (need_initialize) initializeUpdateResidualData();
-
- // f -= fint
- std::vector<Material *>::iterator mat_it;
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
- try {
- MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(**mat_it);
- mat.computeTraction(_not_ghost);
- } catch (std::bad_cast & bce) { }
- }
-
- SolidMechanicsModel::updateResidual(false);
-
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
- try {
- MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(**mat_it);
- mat.computeEnergies();
- } catch (std::bad_cast & bce) { }
- }
-
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::computeNormals() {
- AKANTU_DEBUG_IN();
-
- Mesh & mesh_facets = this->inserter->getMeshFacets();
- this->getFEEngine("FacetsFEEngine").computeNormalsOnControlPoints(_not_ghost);
-
- /**
- * @todo store tangents while computing normals instead of
- * recomputing them as follows:
- */
- /* ------------------------------------------------------------------------ */
- UInt tangent_components = spatial_dimension * (spatial_dimension - 1);
-
- mesh_facets.initElementTypeMapArray(tangents,
- tangent_components,
- spatial_dimension - 1);
-
- Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1);
- Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1);
-
- for (; it != last; ++it) {
- ElementType facet_type = *it;
-
- const Array<Real> & normals =
- this->getFEEngine("FacetsFEEngine").getNormalsOnQuadPoints(facet_type);
-
- Array<Real> & tangents = this->tangents(facet_type);
-
- Math::compute_tangents(normals, tangents);
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::interpolateStress() {
- for (UInt m = 0; m < materials.size(); ++m) {
- try {
- MaterialCohesive & mat __attribute__((unused)) =
- dynamic_cast<MaterialCohesive &>(*materials[m]);
- } catch(std::bad_cast&) {
- /// interpolate stress on facet quadrature points positions
- materials[m]->interpolateStressOnFacets(facet_stress);
- }
- }
-
-#if defined(AKANTU_DEBUG_TOOLS)
- debug::element_manager.printData(debug::_dm_model_cohesive,
- "Interpolated stresses before",
- facet_stress);
-#endif
-
- synch_registry->synchronize(_gst_smmc_facets_stress);
-
-#if defined(AKANTU_DEBUG_TOOLS)
- debug::element_manager.printData(debug::_dm_model_cohesive,
- "Interpolated stresses",
- facet_stress);
-#endif
-}
-
-/* -------------------------------------------------------------------------- */
-UInt SolidMechanicsModelCohesive::checkCohesiveStress() {
- interpolateStress();
-
- for (UInt m = 0; m < materials.size(); ++m) {
- try {
- MaterialCohesive & mat_cohesive = dynamic_cast<MaterialCohesive &>(*materials[m]);
- /// check which not ghost cohesive elements are to be created
- mat_cohesive.checkInsertion();
- } catch(std::bad_cast&) { }
- }
-
- /* if(static and extrinsic) {
- check max mean stresses
- and change inserter.getInsertionFacets(type_facet);
- }
- */
-
- /// communicate data among processors
- synch_registry->synchronize(_gst_smmc_facets);
-
- /// insert cohesive elements
- return inserter->insertElements();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::onElementsAdded(const Array<Element> & element_list,
- const NewElementsEvent & event) {
- AKANTU_DEBUG_IN();
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- updateCohesiveSynchronizers();
-#endif
-
- SolidMechanicsModel::onElementsAdded(element_list, event);
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- if (cohesive_distributed_synchronizer != NULL)
- cohesive_distributed_synchronizer->computeAllBufferSizes(*this);
-#endif
-
- /// update shape functions
- getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
- getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
-
- if (is_extrinsic) resizeFacetStress();
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::onNodesAdded(const Array<UInt> & doubled_nodes,
- __attribute__((unused)) const NewNodesEvent & event) {
- AKANTU_DEBUG_IN();
-
- UInt nb_new_nodes = doubled_nodes.getSize();
- Array<UInt> nodes_list(nb_new_nodes);
-
- for (UInt n = 0; n < nb_new_nodes; ++n)
- nodes_list(n) = doubled_nodes(n, 1);
-
- SolidMechanicsModel::onNodesAdded(nodes_list, event);
-
- for (UInt n = 0; n < nb_new_nodes; ++n) {
-
- UInt old_node = doubled_nodes(n, 0);
- UInt new_node = doubled_nodes(n, 1);
-
- for (UInt dim = 0; dim < spatial_dimension; ++dim) {
- (*displacement)(new_node, dim) = (*displacement)(old_node, dim);
- (*velocity) (new_node, dim) = (*velocity) (old_node, dim);
- (*acceleration)(new_node, dim) = (*acceleration)(old_node, dim);
- (*blocked_dofs)(new_node, dim) = (*blocked_dofs)(old_node, dim);
-
- if (current_position)
- (*current_position)(new_node, dim) = (*current_position)(old_node, dim);
-
- if (increment_acceleration)
- (*increment_acceleration)(new_node, dim)
- = (*increment_acceleration)(old_node, dim);
-
- if (increment)
- (*increment)(new_node, dim) = (*increment)(old_node, dim);
-
- if (previous_displacement)
- (*previous_displacement)(new_node, dim)
- = (*previous_displacement)(old_node, dim);
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::onEndSolveStep(const AnalysisMethod & method) {
-
- AKANTU_DEBUG_IN();
-
- /******************************************************************************
- This is required because the Cauchy stress is the stress measure that is used
- to check the insertion of cohesive elements
- ******************************************************************************/
-
- std::vector<Material *>::iterator mat_it;
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
- Material & mat = **mat_it;
- if(mat.isFiniteDeformation())
- mat.computeAllCauchyStresses(_not_ghost);
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::printself(std::ostream & stream, int indent) const {
- std::string space;
- for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
-
- stream << space << "SolidMechanicsModelCohesive [" << std::endl;
-
- SolidMechanicsModel::printself(stream, indent + 1);
-
- stream << space << "]" << std::endl;
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::resizeFacetStress() {
- AKANTU_DEBUG_IN();
-
- Mesh & mesh_facets = inserter->getMeshFacets();
-
- for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end();
- ++gt) {
- GhostType ghost_type = *gt;
-
- Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
- Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
- for(; it != end; ++it) {
- ElementType type = *it;
-
- UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
-
- UInt nb_quadrature_points =
- getFEEngine("FacetsFEEngine").getNbQuadraturePoints(type, ghost_type);
-
- UInt new_size = nb_facet * nb_quadrature_points;
-
- facet_stress(type, ghost_type).resize(new_size);
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::addDumpGroupFieldToDumper(const std::string & dumper_name,
- const std::string & field_id,
- const std::string & group_name,
- const ElementKind & element_kind,
- bool padding_flag) {
- AKANTU_DEBUG_IN();
-
- UInt spatial_dimension = this->spatial_dimension;
- ElementKind _element_kind = element_kind;
- if (dumper_name == "cohesive elements") {
- _element_kind = _ek_cohesive;
- } else if (dumper_name == "facets") {
- spatial_dimension = this->spatial_dimension - 1;
- }
- SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name,
- field_id,
- group_name,
- spatial_dimension,
- _element_kind,
- padding_flag);
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-
-void SolidMechanicsModelCohesive::onDump(){
- this->flattenAllRegisteredInternals(_ek_cohesive);
- SolidMechanicsModel::onDump();
-}
-
-/* -------------------------------------------------------------------------- */
-
-
-
-__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive.hh
deleted file mode 100644
index 319266de2..000000000
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive.hh
+++ /dev/null
@@ -1,326 +0,0 @@
-/**
- * @file solid_mechanics_model_cohesive.hh
- *
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date creation: Tue May 08 2012
- * @date last modification: Tue Sep 02 2014
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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"
-#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,
- 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
-
-};
-
-
-/* -------------------------------------------------------------------------- */
-/* inline functions */
-/* -------------------------------------------------------------------------- */
-
-/* -------------------------------------------------------------------------- */
-class DefaultMaterialCohesiveSelector : public DefaultMaterialSelector {
-public:
- DefaultMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model) :
- DefaultMaterialSelector(model.getMaterialByElement()),
- facet_material(model.getFacetMaterial()),
- mesh(model.getMesh()) { }
-
- inline virtual UInt 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);
- }
- }
-
-private:
- const ElementTypeMapArray<UInt> & facet_material;
- const Mesh & mesh;
-};
-
-/* -------------------------------------------------------------------------- */
-/// To be used with intrinsic elements inserted along mesh physical surfaces
-class MeshDataMaterialCohesiveSelector : public DefaultMaterialSelector {
-public:
- MeshDataMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model):
- DefaultMaterialSelector(model.getMaterialByElement()),
- mesh_facets(model.getMeshFacets()),
- material_index(mesh_facets.getData<UInt>("physical_names")) {
- third_dimension = (model.getSpatialDimension()==3);}
- inline virtual UInt 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 DefaultMaterialSelector::operator()(element);
- }
-
-protected:
- const Mesh & mesh_facets;
- const ElementTypeMapArray<UInt> & material_index;
- bool third_dimension;
-
-};
-
-/* -------------------------------------------------------------------------- */
-/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const SolidMechanicsModelCohesive & _this)
-{
- _this.printself(stream);
- return stream;
-}
-
-
-__END_AKANTU__
-
-#if defined (AKANTU_INCLUDE_INLINE_IMPL)
-# include "solid_mechanics_model_cohesive_inline_impl.cc"
-#endif
-
-#endif /* __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_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
new file mode 100644
index 000000000..af86db504
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
@@ -0,0 +1,650 @@
+/**
+ * @file fragment_manager.cc
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @date creation: Thu Jan 23 2014
+ * @date last modification: Mon Dec 14 2015
+ *
+ * @brief Group manager to handle fragments
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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
new file mode 100644
index 000000000..2c04d8eb2
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
@@ -0,0 +1,174 @@
+/**
+ * @file fragment_manager.hh
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @date creation: Thu Jan 23 2014
+ * @date last modification: Mon Dec 14 2015
+ *
+ * @brief Group manager to handle fragments
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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
new file mode 100644
index 000000000..ee723cbe4
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
@@ -0,0 +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>
+ *
+ * @date creation: Fri Dec 11 2015
+ * @date last modification: Mon Dec 14 2015
+ *
+ * @brief Material selector for cohesive elements
+ *
+ * @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_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
new file mode 100644
index 000000000..8d423a4b9
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
@@ -0,0 +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>
+ *
+ * @date creation: Fri Dec 11 2015
+ * @date last modification: Mon Dec 14 2015
+ *
+ * @brief Material selectors for cohesive elements
+ *
+ * @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_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
new file mode 100644
index 000000000..9420540d4
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
@@ -0,0 +1,767 @@
+/**
+ * @file solid_mechanics_model_cohesive.cc
+ *
+ * @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: Wed Jan 13 2016
+ *
+ * @brief Solid mechanics model for cohesive elements
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <algorithm>
+#include "shape_cohesive.hh"
+#include "solid_mechanics_model_cohesive.hh"
+#include "dumpable_inline_impl.hh"
+#include "material_cohesive.hh"
+
+#ifdef AKANTU_USE_IOHELPER
+#include "dumper_paraview.hh"
+#endif
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+const SolidMechanicsModelCohesiveOptions
+ default_solid_mechanics_model_cohesive_options(_explicit_lumped_mass, false,
+ false);
+
+/* -------------------------------------------------------------------------- */
+
+SolidMechanicsModelCohesive::SolidMechanicsModelCohesive(
+ Mesh & mesh, UInt dim, const ID & id, const MemoryID & memory_id)
+ : SolidMechanicsModel(mesh, dim, id, memory_id), tangents("tangents", id),
+ facet_stress("facet_stress", id), facet_material("facet_material", id) {
+ AKANTU_DEBUG_IN();
+
+ inserter = NULL;
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ facet_synchronizer = NULL;
+ facet_stress_synchronizer = NULL;
+ cohesive_distributed_synchronizer = NULL;
+ global_connectivity = NULL;
+#endif
+
+ delete material_selector;
+ material_selector = new DefaultMaterialCohesiveSelector(*this);
+
+ this->registerEventHandler(*this);
+
+#if defined(AKANTU_USE_IOHELPER)
+ this->mesh.registerDumper<DumperParaview>("cohesive elements", id);
+ this->mesh.addDumpMeshToDumper("cohesive elements", mesh, spatial_dimension,
+ _not_ghost, _ek_cohesive);
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+SolidMechanicsModelCohesive::~SolidMechanicsModelCohesive() {
+ AKANTU_DEBUG_IN();
+
+ delete inserter;
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ delete cohesive_distributed_synchronizer;
+ delete facet_synchronizer;
+ delete facet_stress_synchronizer;
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::setTimeStep(Real time_step) {
+ SolidMechanicsModel::setTimeStep(time_step);
+
+#if defined(AKANTU_USE_IOHELPER)
+ this->mesh.getDumper("cohesive elements").setTimeStep(time_step);
+#endif
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initFull(const ModelOptions & options) {
+ AKANTU_DEBUG_IN();
+
+ const SolidMechanicsModelCohesiveOptions & smmc_options =
+ dynamic_cast<const SolidMechanicsModelCohesiveOptions &>(options);
+
+ this->is_extrinsic = smmc_options.extrinsic;
+
+ if (!inserter)
+ inserter = new CohesiveElementInserter(mesh, is_extrinsic, synch_parallel,
+ id + ":cohesive_element_inserter");
+
+ SolidMechanicsModel::initFull(options);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initMaterials() {
+ AKANTU_DEBUG_IN();
+
+ // make sure the material are instantiated
+ if (!are_materials_instantiated)
+ instantiateMaterials();
+
+ /// find the first cohesive material
+ UInt cohesive_index = 0;
+
+ while (
+ (dynamic_cast<MaterialCohesive *>(materials[cohesive_index]) == NULL) &&
+ cohesive_index <= materials.size())
+ ++cohesive_index;
+
+ AKANTU_DEBUG_ASSERT(cohesive_index != materials.size(),
+ "No cohesive materials in the material input file");
+
+ material_selector->setFallback(cohesive_index);
+
+ // set the facet information in the material in case of dynamic insertion
+ if (is_extrinsic) {
+ const Mesh & mesh_facets = inserter->getMeshFacets();
+ mesh_facets.initElementTypeMapArray(facet_material, 1,
+ spatial_dimension - 1);
+
+ Element element;
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+ element.ghost_type = *gt;
+ Mesh::type_iterator first =
+ mesh_facets.firstType(spatial_dimension - 1, *gt);
+ Mesh::type_iterator last =
+ mesh_facets.lastType(spatial_dimension - 1, *gt);
+ for (; first != last; ++first) {
+ element.type = *first;
+ Array<UInt> & f_material = facet_material(*first, *gt);
+ UInt nb_element = mesh_facets.getNbElement(*first, *gt);
+ f_material.resize(nb_element);
+ f_material.set(cohesive_index);
+ for (UInt el = 0; el < nb_element; ++el) {
+ element.element = el;
+ UInt mat_index = (*material_selector)(element);
+ f_material(el) = mat_index;
+ MaterialCohesive & mat =
+ dynamic_cast<MaterialCohesive &>(*materials[mat_index]);
+ mat.addFacet(element);
+ }
+ }
+ }
+ SolidMechanicsModel::initMaterials();
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_synchronizer != NULL)
+ inserter->initParallel(facet_synchronizer, synch_parallel);
+#endif
+ initAutomaticInsertion();
+ } else {
+ // TODO think of something a bit mor consistant than just coding the first
+ // thing that comes in Fabian's head....
+ typedef ParserSection::const_section_iterator const_section_iterator;
+ std::pair<const_section_iterator, const_section_iterator> sub_sections =
+ this->parser->getSubSections(_st_mesh);
+
+ if (sub_sections.first != sub_sections.second) {
+ std::string cohesive_surfaces =
+ sub_sections.first->getParameter("cohesive_surfaces");
+ this->initIntrinsicCohesiveMaterials(cohesive_surfaces);
+ } else {
+ this->initIntrinsicCohesiveMaterials(cohesive_index);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(
+ std::string cohesive_surfaces) {
+
+ AKANTU_DEBUG_IN();
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_synchronizer != NULL)
+ inserter->initParallel(facet_synchronizer, synch_parallel);
+#endif
+ std::istringstream split(cohesive_surfaces);
+ std::string physname;
+ while (std::getline(split, physname, ',')) {
+ AKANTU_DEBUG_INFO(
+ "Pre-inserting cohesive elements along facets from physical surface: "
+ << physname);
+ insertElementsFromMeshData(physname);
+ }
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_synchronizer != NULL) {
+ facet_synchronizer->asynchronousSynchronize(*inserter, _gst_ce_groups);
+ facet_synchronizer->waitEndSynchronize(*inserter, _gst_ce_groups);
+ }
+#endif
+
+ SolidMechanicsModel::initMaterials();
+
+ if (is_default_material_selector)
+ delete material_selector;
+ material_selector = new MeshDataMaterialCohesiveSelector(*this);
+ inserter->insertElements();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(
+ UInt cohesive_index) {
+
+ AKANTU_DEBUG_IN();
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+ Mesh::type_iterator first =
+ mesh.firstType(spatial_dimension, *gt, _ek_cohesive);
+ Mesh::type_iterator last =
+ mesh.lastType(spatial_dimension, *gt, _ek_cohesive);
+
+ for (; first != last; ++first) {
+ Array<UInt> & mat_indexes = this->material_index(*first, *gt);
+ Array<UInt> & mat_loc_num = this->material_local_numbering(*first, *gt);
+ mat_indexes.set(cohesive_index);
+ mat_loc_num.clear();
+ }
+ }
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_synchronizer != NULL)
+ inserter->initParallel(facet_synchronizer, synch_parallel);
+#endif
+
+ SolidMechanicsModel::initMaterials();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Initialize the model,basically it pre-compute the shapes, shapes derivatives
+ * and jacobian
+ *
+ */
+void SolidMechanicsModelCohesive::initModel() {
+ AKANTU_DEBUG_IN();
+
+ SolidMechanicsModel::initModel();
+
+ registerFEEngineObject<MyFEEngineCohesiveType>("CohesiveFEEngine", mesh,
+ spatial_dimension);
+
+ /// add cohesive type connectivity
+ ElementType type = _not_defined;
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+
+ GhostType type_ghost = *gt;
+
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, type_ghost);
+ Mesh::type_iterator last = mesh.lastType(spatial_dimension, type_ghost);
+
+ for (; it != last; ++it) {
+ const Array<UInt> & connectivity = mesh.getConnectivity(*it, type_ghost);
+ if (connectivity.getSize() != 0) {
+ type = *it;
+ ElementType type_facet = Mesh::getFacetType(type);
+ ElementType type_cohesive =
+ FEEngine::getCohesiveElementType(type_facet);
+ mesh.addConnectivityType(type_cohesive, type_ghost);
+ }
+ }
+ }
+
+ AKANTU_DEBUG_ASSERT(type != _not_defined, "No elements in the mesh");
+
+ getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
+ getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
+
+ registerFEEngineObject<MyFEEngineType>("FacetsFEEngine", mesh.getMeshFacets(),
+ spatial_dimension - 1);
+
+ if (is_extrinsic) {
+ getFEEngine("FacetsFEEngine").initShapeFunctions(_not_ghost);
+ getFEEngine("FacetsFEEngine").initShapeFunctions(_ghost);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::limitInsertion(BC::Axis axis,
+ Real first_limit,
+ Real second_limit) {
+ AKANTU_DEBUG_IN();
+ inserter->setLimit(axis, first_limit, second_limit);
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::insertIntrinsicElements() {
+ AKANTU_DEBUG_IN();
+ inserter->insertIntrinsicElements();
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::insertElementsFromMeshData(
+ std::string physname) {
+ AKANTU_DEBUG_IN();
+
+ UInt material_index = SolidMechanicsModel::getMaterialIndex(physname);
+ inserter->insertIntrinsicElements(physname, material_index);
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initAutomaticInsertion() {
+ AKANTU_DEBUG_IN();
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_stress_synchronizer != NULL) {
+ DataAccessor * data_accessor = this;
+ const ElementTypeMapArray<UInt> & rank_to_element =
+ synch_parallel->getPrankToElement();
+
+ facet_stress_synchronizer->updateFacetStressSynchronizer(
+ *inserter, rank_to_element, *data_accessor);
+ }
+#endif
+
+ inserter->getMeshFacets().initElementTypeMapArray(
+ facet_stress, 2 * spatial_dimension * spatial_dimension,
+ spatial_dimension - 1);
+
+ resizeFacetStress();
+
+ /// compute normals on facets
+ computeNormals();
+
+ initStressInterpolation();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::updateAutomaticInsertion() {
+ AKANTU_DEBUG_IN();
+
+ inserter->limitCheckFacets();
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_stress_synchronizer != NULL) {
+ DataAccessor * data_accessor = this;
+ const ElementTypeMapArray<UInt> & rank_to_element =
+ synch_parallel->getPrankToElement();
+
+ facet_stress_synchronizer->updateFacetStressSynchronizer(
+ *inserter, rank_to_element, *data_accessor);
+ }
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initStressInterpolation() {
+ Mesh & mesh_facets = inserter->getMeshFacets();
+
+ /// compute quadrature points coordinates on facets
+ Array<Real> & position = mesh.getNodes();
+
+ ElementTypeMapArray<Real> quad_facets("quad_facets", id);
+ mesh_facets.initElementTypeMapArray(quad_facets, spatial_dimension,
+ spatial_dimension - 1);
+
+ getFEEngine("FacetsFEEngine")
+ .interpolateOnIntegrationPoints(position, quad_facets);
+
+ /// compute elements quadrature point positions and build
+ /// element-facet quadrature points data structure
+ ElementTypeMapArray<Real> elements_quad_facets("elements_quad_facets", id);
+
+ mesh.initElementTypeMapArray(elements_quad_facets, spatial_dimension,
+ spatial_dimension);
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+
+ GhostType elem_gt = *gt;
+
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, elem_gt);
+ Mesh::type_iterator last = mesh.lastType(spatial_dimension, elem_gt);
+
+ for (; it != last; ++it) {
+ ElementType type = *it;
+ UInt nb_element = mesh.getNbElement(type, elem_gt);
+ if (nb_element == 0)
+ continue;
+
+ /// compute elements' quadrature points and list of facet
+ /// quadrature points positions by element
+ Array<Element> & facet_to_element =
+ mesh_facets.getSubelementToElement(type, elem_gt);
+ UInt nb_facet_per_elem = facet_to_element.getNbComponent();
+
+ Array<Real> & el_q_facet = elements_quad_facets(type, elem_gt);
+
+ ElementType facet_type = Mesh::getFacetType(type);
+
+ UInt nb_quad_per_facet =
+ getFEEngine("FacetsFEEngine").getNbIntegrationPoints(facet_type);
+
+ el_q_facet.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet);
+
+ for (UInt el = 0; el < nb_element; ++el) {
+ for (UInt f = 0; f < nb_facet_per_elem; ++f) {
+ Element global_facet_elem = facet_to_element(el, f);
+ UInt global_facet = global_facet_elem.element;
+ GhostType facet_gt = global_facet_elem.ghost_type;
+ const Array<Real> & quad_f = quad_facets(facet_type, facet_gt);
+
+ for (UInt q = 0; q < nb_quad_per_facet; ++q) {
+ for (UInt s = 0; s < spatial_dimension; ++s) {
+ el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
+ f * nb_quad_per_facet + q,
+ s) = quad_f(global_facet * nb_quad_per_facet + q, s);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /// loop over non cohesive materials
+ for (UInt m = 0; m < materials.size(); ++m) {
+ try {
+ MaterialCohesive & mat __attribute__((unused)) =
+ dynamic_cast<MaterialCohesive &>(*materials[m]);
+ } catch (std::bad_cast &) {
+ /// initialize the interpolation function
+ materials[m]->initElementalFieldInterpolation(elements_quad_facets);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::updateResidual(bool need_initialize) {
+ AKANTU_DEBUG_IN();
+
+ if (need_initialize)
+ initializeUpdateResidualData();
+
+ // f -= fint
+ std::vector<Material *>::iterator mat_it;
+ for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ try {
+ MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(**mat_it);
+ mat.computeTraction(_not_ghost);
+ } catch (std::bad_cast & bce) {
+ }
+ }
+
+ SolidMechanicsModel::updateResidual(false);
+
+ if (isExplicit()) {
+ for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ try {
+ MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(**mat_it);
+ mat.computeEnergies();
+ } catch (std::bad_cast & bce) {
+ }
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::computeNormals() {
+ AKANTU_DEBUG_IN();
+
+ Mesh & mesh_facets = this->inserter->getMeshFacets();
+ this->getFEEngine("FacetsFEEngine")
+ .computeNormalsOnIntegrationPoints(_not_ghost);
+
+ /**
+ * @todo store tangents while computing normals instead of
+ * recomputing them as follows:
+ */
+ /* ------------------------------------------------------------------------ */
+ UInt tangent_components = spatial_dimension * (spatial_dimension - 1);
+
+ mesh_facets.initElementTypeMapArray(tangents, tangent_components,
+ spatial_dimension - 1);
+
+ Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1);
+ Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1);
+
+ for (; it != last; ++it) {
+ ElementType facet_type = *it;
+
+ const Array<Real> & normals =
+ this->getFEEngine("FacetsFEEngine")
+ .getNormalsOnIntegrationPoints(facet_type);
+
+ Array<Real> & tangents = this->tangents(facet_type);
+
+ Math::compute_tangents(normals, tangents);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::interpolateStress() {
+
+ ElementTypeMapArray<Real> by_elem_result("temporary_stress_by_facets", id);
+
+ for (UInt m = 0; m < materials.size(); ++m) {
+ try {
+ MaterialCohesive & mat __attribute__((unused)) =
+ dynamic_cast<MaterialCohesive &>(*materials[m]);
+ } catch (std::bad_cast &) {
+ /// interpolate stress on facet quadrature points positions
+ materials[m]->interpolateStressOnFacets(facet_stress, by_elem_result);
+ }
+ }
+
+#if defined(AKANTU_DEBUG_TOOLS)
+ debug::element_manager.printData(
+ debug::_dm_model_cohesive, "Interpolated stresses before", facet_stress);
+#endif
+
+ synch_registry->synchronize(_gst_smmc_facets_stress);
+
+#if defined(AKANTU_DEBUG_TOOLS)
+ debug::element_manager.printData(debug::_dm_model_cohesive,
+ "Interpolated stresses", facet_stress);
+#endif
+}
+
+/* -------------------------------------------------------------------------- */
+UInt SolidMechanicsModelCohesive::checkCohesiveStress() {
+ interpolateStress();
+
+ for (UInt m = 0; m < materials.size(); ++m) {
+ try {
+ MaterialCohesive & mat_cohesive =
+ dynamic_cast<MaterialCohesive &>(*materials[m]);
+ /// check which not ghost cohesive elements are to be created
+ mat_cohesive.checkInsertion();
+ } catch (std::bad_cast &) {
+ }
+ }
+
+ /* if(static and extrinsic) {
+ check max mean stresses
+ and change inserter.getInsertionFacets(type_facet);
+ }
+ */
+
+ /// communicate data among processors
+ synch_registry->synchronize(_gst_smmc_facets);
+
+ /// insert cohesive elements
+ return inserter->insertElements();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::onElementsAdded(
+ const Array<Element> & element_list, const NewElementsEvent & event) {
+ AKANTU_DEBUG_IN();
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ updateCohesiveSynchronizers();
+#endif
+
+ SolidMechanicsModel::onElementsAdded(element_list, event);
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (cohesive_distributed_synchronizer != NULL)
+ cohesive_distributed_synchronizer->computeAllBufferSizes(*this);
+#endif
+
+ /// update shape functions
+ getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
+ getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
+
+ if (is_extrinsic)
+ resizeFacetStress();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::onNodesAdded(
+ const Array<UInt> & doubled_nodes,
+ __attribute__((unused)) const NewNodesEvent & event) {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_new_nodes = doubled_nodes.getSize();
+ Array<UInt> nodes_list(nb_new_nodes);
+
+ for (UInt n = 0; n < nb_new_nodes; ++n)
+ nodes_list(n) = doubled_nodes(n, 1);
+
+ SolidMechanicsModel::onNodesAdded(nodes_list, event);
+
+ for (UInt n = 0; n < nb_new_nodes; ++n) {
+
+ UInt old_node = doubled_nodes(n, 0);
+ UInt new_node = doubled_nodes(n, 1);
+
+ for (UInt dim = 0; dim < spatial_dimension; ++dim) {
+ (*displacement)(new_node, dim) = (*displacement)(old_node, dim);
+ (*velocity)(new_node, dim) = (*velocity)(old_node, dim);
+ (*acceleration)(new_node, dim) = (*acceleration)(old_node, dim);
+ (*blocked_dofs)(new_node, dim) = (*blocked_dofs)(old_node, dim);
+
+ if (current_position)
+ (*current_position)(new_node, dim) = (*current_position)(old_node, dim);
+
+ if (increment_acceleration)
+ (*increment_acceleration)(new_node, dim) =
+ (*increment_acceleration)(old_node, dim);
+
+ if (increment)
+ (*increment)(new_node, dim) = (*increment)(old_node, dim);
+
+ if (previous_displacement)
+ (*previous_displacement)(new_node, dim) =
+ (*previous_displacement)(old_node, dim);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::onEndSolveStep(
+ __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
+ */
+
+ std::vector<Material *>::iterator mat_it;
+ for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ Material & mat = **mat_it;
+ if (mat.isFiniteDeformation())
+ mat.computeAllCauchyStresses(_not_ghost);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::printself(std::ostream & stream,
+ int indent) const {
+ std::string space;
+ for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
+ ;
+
+ stream << space << "SolidMechanicsModelCohesive [" << std::endl;
+
+ SolidMechanicsModel::printself(stream, indent + 1);
+
+ stream << space << "]" << std::endl;
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::resizeFacetStress() {
+ AKANTU_DEBUG_IN();
+
+ Mesh & mesh_facets = inserter->getMeshFacets();
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+ GhostType ghost_type = *gt;
+
+ Mesh::type_iterator it =
+ mesh_facets.firstType(spatial_dimension - 1, ghost_type);
+ Mesh::type_iterator end =
+ mesh_facets.lastType(spatial_dimension - 1, ghost_type);
+ for (; it != end; ++it) {
+ ElementType type = *it;
+
+ UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
+
+ UInt nb_quadrature_points = getFEEngine("FacetsFEEngine")
+ .getNbIntegrationPoints(type, ghost_type);
+
+ UInt new_size = nb_facet * nb_quadrature_points;
+
+ facet_stress(type, ghost_type).resize(new_size);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::addDumpGroupFieldToDumper(
+ const std::string & dumper_name, const std::string & field_id,
+ const std::string & group_name, const ElementKind & element_kind,
+ bool padding_flag) {
+ AKANTU_DEBUG_IN();
+
+ UInt spatial_dimension = this->spatial_dimension;
+ ElementKind _element_kind = element_kind;
+ if (dumper_name == "cohesive elements") {
+ _element_kind = _ek_cohesive;
+ } else if (dumper_name == "facets") {
+ spatial_dimension = this->spatial_dimension - 1;
+ }
+ SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name, field_id,
+ group_name, spatial_dimension,
+ _element_kind, padding_flag);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+void SolidMechanicsModelCohesive::onDump() {
+ this->flattenAllRegisteredInternals(_ek_cohesive);
+ SolidMechanicsModel::onDump();
+}
+
+/* -------------------------------------------------------------------------- */
+
+__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
new file mode 100644
index 000000000..25df8af48
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
@@ -0,0 +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: Mon Dec 14 2015
+ *
+ * @brief Solid mechanics model for cohesive elements
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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
new file mode 100644
index 000000000..8775a3a89
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
@@ -0,0 +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 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 (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------------- */
+#include <algorithm>
+#include "material_cohesive.hh"
+
+#ifndef __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__
+#define __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__
+
+__BEGIN_AKANTU__
+
+
+
+/* -------------------------------------------------------------------------- */
+template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
+bool SolidMechanicsModelCohesive::solveStepCohesive(Real tolerance,
+ Real & error,
+ UInt max_iteration,
+ bool load_reduction,
+ Real tol_increase_factor,
+ bool do_not_factorize) {
+
+ EventManager::sendEvent(SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
+ this->implicitPred();
+
+ bool insertion_new_element = true;
+ bool converged = false;
+ Array<Real> * displacement_tmp = NULL;
+ Array<Real> * velocity_tmp = NULL;
+ Array<Real> * acceleration_tmp = NULL;
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+ Int prank = comm.whoAmI();
+
+ /// Loop for the insertion of new cohesive elements
+ while (insertion_new_element) {
+
+ if (is_extrinsic) {
+ /**
+ * If in extrinsic the solution of the previous incremental step
+ * is saved in temporary arrays created for displacements,
+ * velocities and accelerations. Such arrays are used to find
+ * the solution with the Newton-Raphson scheme (this is done by
+ * pointing the pointer "displacement" to displacement_tmp). In
+ * this way, inside the array "displacement" is kept the
+ * solution of the previous incremental step, and in
+ * "displacement_tmp" is saved the current solution.
+ */
+
+ Array<Real> * tmp_swap;
+
+ if(!displacement_tmp) {
+ displacement_tmp = new Array<Real>(*(this->displacement));
+ } else {
+ displacement_tmp->resize(this->displacement->getSize());
+ displacement_tmp->copy(*(this->displacement));
+ }
+ tmp_swap = displacement_tmp;
+ displacement_tmp = this->displacement;
+ this->displacement = tmp_swap;
+
+ if(!velocity_tmp) {
+ velocity_tmp = new Array<Real>(*(this->velocity));
+ } else {
+ velocity_tmp->resize(this->velocity->getSize());
+ velocity_tmp->copy(*(this->velocity));
+ }
+ tmp_swap = velocity_tmp;
+ velocity_tmp = this->velocity;
+ this->velocity = tmp_swap;
+
+ if(!acceleration_tmp) {
+ acceleration_tmp = new Array<Real>(*(this->acceleration));
+ } else {
+ acceleration_tmp->resize(this->acceleration->getSize());
+ acceleration_tmp->copy(*(this->acceleration));
+ }
+ tmp_swap = acceleration_tmp;
+ acceleration_tmp = this->acceleration;
+ this->acceleration = tmp_swap;
+ }
+
+ this->updateResidual();
+
+ AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
+ "You should first initialize the implicit solver and assemble the stiffness matrix");
+
+ bool need_factorize = !do_not_factorize;
+
+ if (method ==_implicit_dynamic) {
+ AKANTU_DEBUG_ASSERT(mass_matrix != NULL,
+ "You should first initialize the implicit solver and assemble the mass matrix");
+ }
+
+ switch (cmethod) {
+ case _scm_newton_raphson_tangent:
+ case _scm_newton_raphson_tangent_not_computed:
+ break;
+ case _scm_newton_raphson_tangent_modified:
+ this->assembleStiffnessMatrix();
+ break;
+ default:
+ AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
+ }
+
+ UInt iter = 0;
+ converged = false;
+ error = 0.;
+ if(criteria == _scc_residual) {
+ converged = this->testConvergence<criteria> (tolerance, error);
+ if(converged) return converged;
+ }
+
+ /// Loop to solve the nonlinear system
+ do {
+ if (cmethod == _scm_newton_raphson_tangent)
+ this->assembleStiffnessMatrix();
+
+ solve<NewmarkBeta::_displacement_corrector> (*increment, 1., need_factorize);
+
+ this->implicitCorr();
+
+ this->updateResidual();
+
+ converged = this->testConvergence<criteria> (tolerance, error);
+
+ iter++;
+ AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration "
+ << std::setw(std::log10(max_iteration)) << iter
+ << ": error " << error << (converged ? " < " : " > ") << tolerance);
+
+ switch (cmethod) {
+ case _scm_newton_raphson_tangent:
+ need_factorize = true;
+ break;
+ case _scm_newton_raphson_tangent_not_computed:
+ case _scm_newton_raphson_tangent_modified:
+ need_factorize = false;
+ break;
+ default:
+ AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
+ }
+
+ } while (!converged && iter < max_iteration);
+
+
+ /**
+ * This is to save the obtained result and proceed with the
+ * simulation even if the error is higher than the pre-fixed
+ * tolerance. This is done only after loading reduction
+ * (load_reduction = true).
+ */
+ if (load_reduction && (error < tolerance * tol_increase_factor)) converged = true;
+
+ if (converged) {
+ // EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
+ // !!! add sendEvent to call computeCauchyStress !!!!
+
+ if (prank==0){
+ std::cout << "Error after convergence: " << error << std::endl;
+ std::cout << "no. of iterations: " << iter << std::endl;
+ }
+ } else if(iter == max_iteration) {
+ if (prank==0){
+ AKANTU_DEBUG_WARNING("[" << criteria << "] Convergence not reached after "
+ << std::setw(std::log10(max_iteration)) << iter <<
+ " iteration" << (iter == 1 ? "" : "s") << "!" << std::endl);
+ std::cout << "Error after NON convergence: " << error << std::endl;
+ }
+ }
+
+ if (is_extrinsic) {
+ /**
+ * If is extrinsic the pointer "displacement" is moved back to
+ * the array displacement. In this way, the array displacement is
+ * correctly resized during the checkCohesiveStress function (in
+ * case new cohesive elements are added). This is possible
+ * because the procedure called by checkCohesiveStress does not
+ * use the displacement field (the correct one is now stored in
+ * displacement_tmp), but directly the stress field that is
+ * already computed.
+ */
+ Array<Real> * tmp_swap;
+
+ tmp_swap = displacement_tmp;
+ displacement_tmp = this->displacement;
+ this->displacement = tmp_swap;
+
+ tmp_swap = velocity_tmp;
+ velocity_tmp = this->velocity;
+ this->velocity = tmp_swap;
+
+ tmp_swap = acceleration_tmp;
+ acceleration_tmp = this->acceleration;
+ this->acceleration = tmp_swap;
+
+ /// If convergence is reached, call checkCohesiveStress in order
+ /// to check if cohesive elements have to be introduced
+ if (converged){
+
+ UInt new_cohesive_elements = checkCohesiveStress();
+
+ if(new_cohesive_elements == 0){
+ insertion_new_element = false;
+ } else {
+ insertion_new_element = true;
+ if (prank==0)
+ std::cout << "No. cohesive elements inserted = " << new_cohesive_elements << std::endl;
+ }
+ }
+ }
+
+
+ if (!converged && load_reduction)
+ insertion_new_element = false;
+
+ /**
+ * If convergence is not reached, there is the possibility to
+ * return back to the main file and reduce the load. Before doing
+ * this, a pre-fixed value as to be defined for the parameter
+ * delta_max of the cohesive elements introduced in the current
+ * incremental step. This is done by calling the function
+ * checkDeltaMax.
+ */
+ if (!converged) {
+ insertion_new_element = false;
+
+ for (UInt m = 0; m < materials.size(); ++m) {
+ try {
+ MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(*materials[m]);
+ mat.checkDeltaMax(_not_ghost);
+ } catch(std::bad_cast&) { }
+ }
+
+ }
+
+ } //end loop for the insertion of new cohesive elements
+
+ /**
+ * When the solution to the current incremental step is computed (no
+ * more cohesive elements have to be introduced), call the function
+ * to compute the energies.
+ */
+ if ((is_extrinsic && converged)) {
+
+ for(UInt m = 0; m < materials.size(); ++m) {
+ try {
+ MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(*materials[m]);
+ mat.computeEnergies();
+ } catch (std::bad_cast & bce) { }
+ }
+
+ EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
+
+ /**
+ * The function resetVariables is necessary to correctly set a
+ * variable that permit to decrease locally the penalty parameter
+ * for compression.
+ */
+ for (UInt m = 0; m < materials.size(); ++m) {
+ try {
+ MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(*materials[m]);
+ mat.resetVariables(_not_ghost);
+ } catch(std::bad_cast&) { }
+ }
+
+ /// The correct solution is saved
+ this->displacement->copy(*displacement_tmp);
+ this->velocity ->copy(*velocity_tmp);
+ this->acceleration->copy(*acceleration_tmp);
+
+ delete displacement_tmp;
+ delete velocity_tmp;
+ delete acceleration_tmp;
+
+ }
+
+ return insertion_new_element;
+
+}
+
+__END_AKANTU__
+
+#if defined (AKANTU_PARALLEL_COHESIVE_ELEMENT)
+# include "solid_mechanics_model_cohesive_parallel_inline_impl.cc"
+#endif
+
+#endif /* __AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive_inline_impl.cc
deleted file mode 100644
index e708c8336..000000000
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive_inline_impl.cc
+++ /dev/null
@@ -1,269 +0,0 @@
-/**
- * @file solid_mechanics_model_cohesive_inline_impl.cc
- *
- * @author Mauro Corrado <mauro.corrado@epfl.ch>
- *
- * @date Thu Feb 26 14:23:45 2015
- *
- * @brief Implementation of inline functions for the Cohesive element model
- *
- * @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 <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,
- 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();
-
- while (insertion_new_element) { //loop for insertion of new cohesive elements
-
- //insertion_new_element = false;
-
- if (is_extrinsic) {
- // If in extrinsic saves the current displacements, velocities and accelerations
- Array<Real> * tmp_swap;
-
- if(!displacement_tmp) {
- displacement_tmp = new Array<Real>(*(this->displacement));
- } else {
- (*displacement_tmp).resize(this->displacement->getSize());
- //displacement_tmp->resize(this->displacement->getSize());
- (*displacement_tmp).copy(*(this->displacement));
- //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;
- }
-
- 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);
-
- // dump();
- // dump("cohesive elements");
-
- if (load_reduction && (error < tolerance * 1000)) converged = true;
-
- if (converged) {
- //// EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
- // !!! add sendEvent to call computeCauchyStress !!!!
- if (prank==0){
- std::cout << "Error after convergence: " << error << std::endl;
- std::cout << "no. of iterations: " << iter << std::endl;
- }
- } else if(iter == max_iteration) {
- if (prank==0){
- AKANTU_DEBUG_WARNING("[" << criteria << "] Convergence not reached after "
- << std::setw(std::log10(max_iteration)) << iter <<
- " iteration" << (iter == 1 ? "" : "s") << "!" << std::endl);
- std::cout << "Error after NON convergence: " << error << std::endl;
- }
- }
-
- if (is_extrinsic) {
- 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 (converged || (load_reduction && error < 1.0)){
- // UInt nb_cohesive_elements = this->mesh.getNbElement(this->spatial_dimension, _not_ghost, _ek_cohesive);
- // this->checkCohesiveStress();
- // UInt new_nb_cohesive_elements = this->mesh.getNbElement(this->spatial_dimension, _not_ghost, _ek_cohesive);
-
- UInt new_cohesive_elements = checkCohesiveStress();
-
- // UInt nb_cohe[2];
- //nb_cohe[0] = nb_cohesive_elements;
- //nb_cohe[1] = new_nb_cohesive_elements;
-
- // StaticCommunicator::getStaticCommunicator().allReduce(nb_cohe, 2, _so_sum);
-
- // if(nb_cohe[0] == nb_cohe[1]) {
- 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 ((!converged && !load_reduction) || (error > 1.)){
- if (!converged && !load_reduction){
- 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 while insertion_new_element
-
-
- // if ((is_extrinsic && converged) || (is_extrinsic && load_reduction && error < 1.)) {
- if ((is_extrinsic && converged) || (is_extrinsic && load_reduction)) {
-
- EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
-
- 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
new file mode 100644
index 000000000..85934400d
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
@@ -0,0 +1,160 @@
+/**
+ * @file embedded_interface_intersector.cc
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Fri May 01 2015
+ * @date last modification: Mon Jan 04 2016
+ *
+ * @brief Class that loads the interface from mesh and computes intersections
+ *
+ * @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 "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
new file mode 100644
index 000000000..d36d382d3
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
@@ -0,0 +1,91 @@
+/**
+ * @file embedded_interface_intersector.hh
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Fri May 01 2015
+ * @date last modification: Mon Dec 14 2015
+ *
+ * @brief Class that loads the interface from mesh and computes intersections
+ *
+ * @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_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
new file mode 100644
index 000000000..30d1db3f3
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
@@ -0,0 +1,210 @@
+/**
+ * @file embedded_interface_model.cc
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Fri Mar 13 2015
+ * @date last modification: Mon Dec 14 2015
+ *
+ * @brief Model of Solid Mechanics with embedded interfaces
+ *
+ * @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 "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
new file mode 100644
index 000000000..3960c2cf8
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
@@ -0,0 +1,167 @@
+/**
+ * @file embedded_interface_model.hh
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @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, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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 47e8681f0..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,105 +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
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:
-
- 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);
}
- 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);
}
- 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();
}
- 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();
}
- 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:
- virtual void onBeginningSolveStep(__attribute__((unused)) const AnalysisMethod & method) {}
- virtual void onEndSolveStep(__attribute__((unused)) const AnalysisMethod & method) {}
+ /// function to implement to react on akantu::BeforeSolveStepEvent
+ virtual void onBeginningSolveStep(__attribute__((unused))
+ const AnalysisMethod & method) {}
+ /// function to implement to react on akantu::AfterSolveStepEvent
+ virtual void onEndSolveStep(__attribute__((unused))
+ const AnalysisMethod & method) {}
+ /// function to implement to react on akantu::BeforeDumpEvent
virtual void onDump() {}
+ /// function to implement to react on akantu::BeginningOfDamageIterationEvent
virtual void onDamageIteration() {}
+ /// function to implement to react on akantu::AfterDamageEvent
virtual void onDamageUpdate() {}
};
-
__END_AKANTU__
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
index 226ed6a52..06943f214 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
@@ -1,436 +1,437 @@
/**
* @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;
+ 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(*internal_force, buffer, elements, mesh);
packNodalDataHelper(*external_force, buffer, elements, mesh);
break;
}
case _gst_smm_boundary: {
packNodalDataHelper(*external_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(*internal_force, buffer, elements, mesh);
unpackNodalDataHelper(*external_force, buffer, elements, mesh);
break;
}
case _gst_smm_boundary: {
unpackNodalDataHelper(*external_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 = internal_force->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;
+ 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 = internal_force->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_forc = external_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 = internal_force->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 = internal_force->begin(spatial_dimension);
Array<Real>::vector_iterator it_forc = external_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();
}
/* -------------------------------------------------------------------------- */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_mass.cc b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
index f49a29750..27d9f1770 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_mass.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
@@ -1,152 +1,153 @@
/**
* @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"
#include "model_solver.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(0, spatial_dimension);
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, type, ghost_type);
fem.assembleFieldLumped(rho, *mass,
type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMass() {
AKANTU_DEBUG_IN();
this->getDOFManager().getNewMatrix("mass", "jacobian");
assembleMass(_not_ghost);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMass(GhostType ghost_type) {
AKANTU_DEBUG_IN();
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
Array<Real> rho(0, spatial_dimension);
// UInt nb_element;
// this->getDOFManager().getMatrix("mass").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, type, ghost_type);
fem.assembleFieldMatrix(rho, "mass", "displacement", this->getDOFManager(),
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.getNbQuadraturePoints(type);
+ UInt nb_quadrature_points = fem.getNbIntegrationPoints(type);
rho.resize(nb_element * nb_quadrature_points);
Array<Real>::vector_iterator rho_it = rho.begin(spatial_dimension);
/// 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_it) {
*rho_it = 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 4a188c53f..3fdaa3c41 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_material.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_material.cc
@@ -1,311 +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) \
+#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 ) \
+#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); \
+ 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_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_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(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_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) \
+#define AKANTU_INTANTIATE_OTHER_MATERIAL(r, data, elem) \
else AKANTU_INTANTIATE_MATERIAL_IF(elem)
-#define AKANTU_INSTANTIATE_MATERIALS() \
- do { \
+#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 ?"); \
- } \
+ 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);
+ element.element = (*filter_array)(el);
else
- element.element = el;
+ 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");
+ "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();
+ 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;
+ UInt element;
- if (filter != NULL) element = (*filter_array)(el);
- else element = el;
+ 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;
+ 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;
+ element.element = el;
- UInt old_material = mat_indexes(el);
- UInt new_material = (*material_selector)(element);
+ 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);
- }
+ 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 851f71ae6..c7162df3b 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
@@ -1,104 +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 69555bd2f..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().getNbQuadraturePoints(*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().getNbQuadraturePoints(_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().getNbQuadraturePoints(_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().getNbQuadraturePoints(_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().getNbQuadraturePoints(_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().getNbQuadraturePoints(_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().getNbQuadraturePoints(_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 db5463257..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().getNbQuadraturePoints(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().getNbQuadraturePoints(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().getNbQuadraturePoints(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().getNbQuadraturePoints(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().getNbQuadraturePoints(type);
+ 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().interpolateOnControlPoints<type>(getFEEngine().getMesh().getNodes(),
+ getFEEngineClass<MyFEEngineType>().getShapeFunctions().interpolateOnIntegrationPoints<type>(getFEEngine().getMesh().getNodes(),
quad_coords,
spatial_dimension);
- getFEEngineClass<MyFEEngineType>().getShapeFunctions().interpolateOnControlPoints<type>(getFEEngine().getMesh().getNodes(),
+ 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().interpolateOnControlPoints<type>(getFEEngine().getMesh().getNodes(),
+ 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().getNbQuadraturePoints(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().getNbQuadraturePoints(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 96e4e999d..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().getNbQuadraturePoints(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/model/time_step_solvers/time_step_solver.cc b/src/model/time_step_solvers/time_step_solver.cc
index 496911e26..e79c7140c 100644
--- a/src/model/time_step_solvers/time_step_solver.cc
+++ b/src/model/time_step_solvers/time_step_solver.cc
@@ -1,50 +1,51 @@
/**
* @file time_step_solver.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Oct 12 16:56:43 2015
*
* @brief Implementation of common part of TimeStepSolvers
*
* @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 "time_step_solver.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
TimeStepSolver::TimeStepSolver(DOFManager & dof_manager,
const TimeStepSolverType & type, const ID & id,
UInt memory_id)
: Memory(id, memory_id), _dof_manager(dof_manager), type(type) {}
/* -------------------------------------------------------------------------- */
TimeStepSolver::~TimeStepSolver() {}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/python/python_functor.cc b/src/python/python_functor.cc
new file mode 100644
index 000000000..61278c0bd
--- /dev/null
+++ b/src/python/python_functor.cc
@@ -0,0 +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, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100644
index 000000000..0cf981e24
--- /dev/null
+++ b/src/python/python_functor.hh
@@ -0,0 +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 (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..c4a8268ed
--- /dev/null
+++ b/src/python/python_functor_inline_impl.cc
@@ -0,0 +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__
+
+/* -------------------------------------------------------------------------- */
+
+template <typename T> inline int PythonFunctor::getPythonDataTypeCode() const {
+ AKANTU_EXCEPTION("undefined type");
+}
+
+/* -------------------------------------------------------------------------- */
+template <> inline int PythonFunctor::getPythonDataTypeCode<bool>() const {
+ int data_typecode = NPY_NOTYPE;
+ size_t s = sizeof(bool);
+ switch (s) {
+ case 1:
+ data_typecode = NPY_BOOL;
+ break;
+ case 2:
+ data_typecode = NPY_UINT16;
+ break;
+ case 4:
+ data_typecode = NPY_UINT32;
+ break;
+ case 8:
+ data_typecode = NPY_UINT64;
+ break;
+ }
+ return data_typecode;
+}
+
+/* -------------------------------------------------------------------------- */
+template <> inline int PythonFunctor::getPythonDataTypeCode<double>() const {
+ return NPY_DOUBLE;
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
+PyObject * PythonFunctor::convertToPython(__attribute__((unused))
+ const T & akantu_object) const {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+inline PyObject *
+PythonFunctor::convertToPython<double>(const double & akantu_object) const {
+ return PyFloat_FromDouble(akantu_object);
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+inline PyObject *
+PythonFunctor::convertToPython<UInt>(const UInt & akantu_object) const {
+ return PyInt_FromLong(akantu_object);
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+inline PyObject *
+PythonFunctor::convertToPython<bool>(const bool & akantu_object) const {
+ return PyBool_FromLong(long(akantu_object));
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
+inline PyObject *
+PythonFunctor::convertToPython(const std::vector<T> & array) const {
+ int data_typecode = getPythonDataTypeCode<T>();
+ npy_intp dims[1] = {int(array.size())};
+ PyObject * obj = PyArray_SimpleNewFromData(1, dims, data_typecode,
+ const_cast<T *>(&array[0]));
+ PyArrayObject * res = (PyArrayObject *)obj;
+ return (PyObject *)res;
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
+PyObject * PythonFunctor::convertToPython(const Vector<T> & array) const {
+ int data_typecode = getPythonDataTypeCode<T>();
+ npy_intp dims[1] = {array.size()};
+ PyObject * obj =
+ PyArray_SimpleNewFromData(1, dims, data_typecode, array.storage());
+ PyArrayObject * res = (PyArrayObject *)obj;
+ return (PyObject *)res;
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
+PyObject * PythonFunctor::convertToPython(const Matrix<T> & mat) const {
+ int data_typecode = getPythonDataTypeCode<T>();
+ npy_intp dims[2] = {mat.size(0), mat.size(1)};
+ PyObject * obj =
+ PyArray_SimpleNewFromData(2, dims, data_typecode, mat.storage());
+ PyArrayObject * res = (PyArrayObject *)obj;
+ return (PyObject *)res;
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+inline PyObject *
+PythonFunctor::convertToPython<std::string>(const std::string & str) const {
+ return PyString_FromString(str.c_str());
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+inline PyObject * PythonFunctor::convertToPython<IntegrationPoint>(
+ const IntegrationPoint & qp) const {
+
+ PyObject * input = PyDict_New();
+ PyObject * num_point = this->convertToPython(qp.num_point);
+ PyObject * global_num = this->convertToPython(qp.global_num);
+ PyObject * material_id = this->convertToPython(qp.material_id);
+ PyObject * position = this->convertToPython(qp.getPosition());
+ PyDict_SetItemString(input, "num_point", num_point);
+ PyDict_SetItemString(input, "global_num", global_num);
+ PyDict_SetItemString(input, "material_id", material_id);
+ PyDict_SetItemString(input, "position", position);
+ return input;
+}
+
+/* -------------------------------------------------------------------------- */
+inline PyObject *
+PythonFunctor::getPythonFunction(const std::string & functor_name) const {
+ if (!PyInstance_Check(this->python_obj))
+ AKANTU_EXCEPTION("Python object is not an instance");
+
+ // if (!PyDict_Check(this->python_obj))
+ // AKANTU_EXCEPTION("Python object is not a dictionary");
+
+ // PyObject * keys = PyDict_Keys(dict);
+ // PyObject_Print(keys, stdout, Py_PRINT_RAW);
+
+ PyObject * pFunctor =
+ PyObject_GetAttrString(this->python_obj, functor_name.c_str());
+ if (!pFunctor)
+ AKANTU_EXCEPTION("Python dictionary has no " << functor_name << " entry");
+
+ return pFunctor;
+}
+
+/* -------------------------------------------------------------------------- */
+inline void
+PythonFunctor::packArguments(__attribute__((unused))
+ std::vector<PyObject *> & p_args) const {}
+
+/* -------------------------------------------------------------------------- */
+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(p_args, params...);
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename return_type, typename... Params>
+return_type PythonFunctor::callFunctor(const std::string & functor_name,
+ Params &... parameters) const {
+ _import_array();
+
+ std::vector<PyObject *> arg_vector;
+ this->packArguments(arg_vector, parameters...);
+
+ PyObject * pArgs = PyTuple_New(arg_vector.size());
+ for (UInt i = 0; i < arg_vector.size(); ++i) {
+ PyTuple_SetItem(pArgs, i, arg_vector[i]);
+ }
+
+ PyObject * kwargs = PyDict_New();
+
+ PyObject * pFunctor = getPythonFunction(functor_name);
+ PyObject * res = this->callFunctor(pFunctor, pArgs, kwargs);
+
+ // for (auto a: arg_vector) {
+ // // if (PyDict_Check(a)){
+ // // PyObject* values = PyDict_Values(a);
+ // // UInt sz = PyList_GET_SIZE(values);
+ // // for (UInt i = 0; i < sz; ++i) {
+ // // Py_XDECREF(PyList_GetItem(values,i));
+ // // }
+ // // }
+ // // Py_XDECREF(a);
+ // }
+ Py_XDECREF(pArgs);
+ Py_XDECREF(kwargs);
+
+ return this->convertToAkantu<return_type>(res);
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename return_type>
+inline return_type PythonFunctor::convertToAkantu(PyObject * python_obj) const {
+
+ if (PyList_Check(python_obj)) {
+ return this->convertListToAkantu<typename return_type::value_type>(
+ python_obj);
+ }
+ AKANTU_DEBUG_TO_IMPLEMENT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+inline void PythonFunctor::convertToAkantu<void>(PyObject * python_obj) const {
+ if (python_obj != Py_None)
+ AKANTU_DEBUG_WARNING(
+ "functor return a value while none was expected: ignored");
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+inline std::string
+PythonFunctor::convertToAkantu<std::string>(PyObject * python_obj) const {
+ if (!PyString_Check(python_obj))
+ AKANTU_EXCEPTION("cannot convert object to string");
+ return PyString_AsString(python_obj);
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+inline Real PythonFunctor::convertToAkantu<Real>(PyObject * python_obj) const {
+ if (!PyFloat_Check(python_obj))
+ AKANTU_EXCEPTION("cannot convert object to float");
+ return PyFloat_AsDouble(python_obj);
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
+inline std::vector<T>
+PythonFunctor::convertListToAkantu(PyObject * python_obj) const {
+ std::vector<T> res;
+ UInt size = PyList_Size(python_obj);
+ for (UInt i = 0; i < size; ++i) {
+ PyObject * item = PyList_GET_ITEM(python_obj, i);
+ res.push_back(this->convertToAkantu<T>(item));
+ }
+ return res;
+}
+
+/* -------------------------------------------------------------------------- */
+
+__END_AKANTU__
+
+#endif /* __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__ */
diff --git a/src/solver/petsc_wrapper.hh b/src/solver/petsc_wrapper.hh
index 9c9b149bc..d562af998 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;
/// MPI communicator for PETSc commands
MPI_Comm communicator;
};
/* -------------------------------------------------------------------------- */
struct PETScSolverWrapper {
KSP ksp;
Vec solution;
Vec rhs;
// 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_mumps.cc b/src/solver/solver_mumps.cc
index c90606c1c..27998b448 100644
--- a/src/solver/solver_mumps.cc
+++ b/src/solver/solver_mumps.cc
@@ -1,365 +1,366 @@
/**
* @file sparse_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 SparseSolverMumps 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"
#include "dof_manager_default.hh"
#include "sparse_matrix_aij.hh"
#if defined(AKANTU_USE_MPI)
#include "static_communicator_mpi.hh"
#include "mpi_type_wrapper.hh"
#endif
#include "solver_mumps.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
// static std::ostream & operator <<(std::ostream & stream, const DMUMPS_STRUC_C
// & _this) {
// stream << "DMUMPS Data [" << std::endl;
// stream << " + job : " << _this.job << std::endl;
// stream << " + par : " << _this.par << std::endl;
// stream << " + sym : " << _this.sym << std::endl;
// stream << " + comm_fortran : " << _this.comm_fortran << std::endl;
// stream << " + nz : " << _this.nz << std::endl;
// stream << " + irn : " << _this.irn << std::endl;
// stream << " + jcn : " << _this.jcn << std::endl;
// stream << " + nz_loc : " << _this.nz_loc << std::endl;
// stream << " + irn_loc : " << _this.irn_loc << std::endl;
// stream << " + jcn_loc : " << _this.jcn_loc << std::endl;
// stream << "]";
// return stream;
// }
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SparseSolverMumps::SparseSolverMumps(DOFManagerDefault & dof_manager,
const ID & matrix_id, const ID & id,
const MemoryID & memory_id)
: SparseSolver(dof_manager, matrix_id, id, memory_id),
dof_manager(dof_manager), matrix(dof_manager.getMatrix(matrix_id)),
rhs(dof_manager.getResidual()), master_rhs_solution(0, 1) {
AKANTU_DEBUG_IN();
StaticCommunicator & communicator = StaticCommunicator::getStaticCommunicator();
this->prank = communicator.whoAmI();
#ifdef AKANTU_USE_MPI
this->parallel_method = _fully_distributed;
#else // AKANTU_USE_MPI
this->parallel_method = _not_parallel;
#endif // AKANTU_USE_MPI
this->mumps_data.par = 1; // The host is part of computations
switch (this->parallel_method) {
case _not_parallel:
break;
case _master_slave_distributed:
this->mumps_data.par = 0; // The host is not part of the computations
case _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());
#else
AKANTU_DEBUG_ERROR(
"You cannot use parallel method to solve without activating MPI");
#endif
break;
}
this->mumps_data.sym = 2 * (matrix.getMatrixType() == _symmetric);
this->prank = communicator.whoAmI();
this->mumps_data.job = _smj_initialize; // initialize
dmumps_c(&this->mumps_data);
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
// Output setup
if (AKANTU_DEBUG_TEST(dblTrace)) {
icntl(1) = 6;
icntl(2) = 2;
icntl(3) = 2;
icntl(4) = 4;
} else {
/// No outputs
icntl(1) = 6; // error output
icntl(2) = 0; // dignostics output
icntl(3) = 0; // informations
icntl(4) = 0; // no outputs
}
if (AKANTU_DEBUG_TEST(dblDump)) {
strcpy(this->mumps_data.write_problem, "mumps_matrix.mtx");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseSolverMumps::~SparseSolverMumps() {
AKANTU_DEBUG_IN();
this->mumps_data.job = _smj_destroy; // destroy
dmumps_c(&this->mumps_data);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::initMumpsData() {
// Default Scaling
icntl(8) = 77;
// Assembled matrix
icntl(5) = 0;
/// Default centralized dense second member
icntl(20) = 0;
icntl(21) = 0;
// automatic choice for analysis
icntl(28) = 0;
UInt size = matrix.getSize();
if (prank == 0) {
this->master_rhs_solution.resize(size);
}
this->mumps_data.nz_alloc = 0;
this->mumps_data.n = size;
switch (this->parallel_method) {
case _fully_distributed:
icntl(18) = 3; // fully distributed
this->mumps_data.nz_loc = matrix.getNbNonZero();
this->mumps_data.irn_loc = matrix.getIRN().storage();
this->mumps_data.jcn_loc = matrix.getJCN().storage();
break;
case _not_parallel:
case _master_slave_distributed:
icntl(18) = 0; // centralized
if (prank == 0) {
this->mumps_data.nz = matrix.getNbNonZero();
this->mumps_data.irn = matrix.getIRN().storage();
this->mumps_data.jcn = matrix.getJCN().storage();
} else {
this->mumps_data.nz = 0;
this->mumps_data.irn = NULL;
this->mumps_data.jcn = NULL;
}
break;
default:
AKANTU_DEBUG_ERROR("This case should not happen!!");
}
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::initialize() {
AKANTU_DEBUG_IN();
this->analysis();
// icntl(14) = 80;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::analysis() {
AKANTU_DEBUG_IN();
initMumpsData();
this->mumps_data.job = _smj_analyze; // analyze
dmumps_c(&this->mumps_data);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::factorize() {
AKANTU_DEBUG_IN();
this->mumps_data.rhs = this->rhs.storage();
if (parallel_method == _fully_distributed)
this->mumps_data.a_loc = this->matrix.getA().storage();
else {
if (prank == 0)
this->mumps_data.a = this->matrix.getA().storage();
}
this->mumps_data.job = _smj_factorize; // factorize
dmumps_c(&this->mumps_data);
this->printError();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::solve() {
AKANTU_DEBUG_IN();
// if (prank == 0) {
// // deactivate debug messages
// DebugLevel dbl = debug::getDebugLevel();
// debug::setDebugLevel(dblError);
// matrix.getDOFSynchronizer().gather(this->rhs, 0, this->master_rhs_solution);
// // reactivate debug messages
// debug::setDebugLevel(dbl);
// } else {
// this->matrix.getDOFSynchronizer().gather(this->rhs, 0);
// }
if (prank == 0)
this->mumps_data.rhs = this->master_rhs_solution.storage();
this->mumps_data.job = _smj_solve; // solve
dmumps_c(&this->mumps_data);
this->printError();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolverMumps::printError() {
Int _info_v[2];
_info_v[0] = info(1); // to get errors
_info_v[1] = -info(1); // to get warnings
StaticCommunicator::getStaticCommunicator().allReduce(_info_v, 2, _so_min);
_info_v[1] = -_info_v[1];
if (_info_v[0] < 0) { // < 0 is an error
switch (_info_v[0]) {
case -10:
AKANTU_DEBUG_ERROR("The matrix is singular");
break;
case -9: {
icntl(14) += 10;
if (icntl(14) != 90) {
// std::cout << "Dynamic memory increase of 10%" << std::endl;
AKANTU_DEBUG_WARNING(
"MUMPS dynamic memory is insufficient it will be increased of 10%");
this->analysis();
this->factorize();
this->solve();
} else {
AKANTU_DEBUG_ERROR("The MUMPS workarray is too small INFO(2)="
<< info(2) << "No further increase possible");
break;
}
}
default:
AKANTU_DEBUG_ERROR("Error in mumps during solve process, check mumps "
"user guide INFO(1) = "
<< _info_v[1]);
}
} else if (_info_v[1] > 0) {
AKANTU_DEBUG_WARNING("Warning in mumps during solve process, check mumps "
"user guide INFO(1) = "
<< _info_v[1]);
}
}
__END_AKANTU__
diff --git a/src/solver/solver_mumps.hh b/src/solver/solver_mumps.hh
index be9e63cc4..0882d036e 100644
--- a/src/solver/solver_mumps.hh
+++ b/src/solver/solver_mumps.hh
@@ -1,147 +1,143 @@
/**
* @file sparse_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/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "sparse_solver.hh"
/* -------------------------------------------------------------------------- */
#include <dmumps_c.h>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_MUMPS_HH__
#define __AKANTU_SOLVER_MUMPS_HH__
namespace akantu {
class DOFManagerDefault;
class SparseMatrixAIJ;
}
__BEGIN_AKANTU__
class SparseSolverMumps : public SparseSolver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SparseSolverMumps(DOFManagerDefault & dof_manager,
const ID & matrix_id,
const ID & id = "sparse_solver_mumps",
const MemoryID & memory_id = 0);
virtual ~SparseSolverMumps();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// build the profile and do the analysis part
virtual void initialize();
// 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();
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:
/// DOFManager used by the Mumps implementation of the SparseSolver
DOFManagerDefault & dof_manager;
/// AIJ Matrix, usualy the jacobian matrix
SparseMatrixAIJ & matrix;
/// Right hand side per processors
const Array<Real> & rhs;
/// Full right hand side on the master processors and solution after solve
Array<Real> master_rhs_solution;
/// mumps data
DMUMPS_STRUC_C mumps_data;
/// Rank of the current process
UInt prank;
/* ------------------------------------------------------------------------ */
/* Local types */
/* ------------------------------------------------------------------------ */
private:
SolverParallelMethod 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 b7daa92b8..e7ca06be2 100644
--- a/src/solver/solver_petsc.cc
+++ b/src/solver/solver_petsc.cc
@@ -1,1106 +1,1107 @@
/**
* @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 "solver_petsc.hh"
#include "dof_manager_petsc.hh"
#include "sparse_matrix_petsc.hh"
#include "mpi_type_wrapper.hh"
/* -------------------------------------------------------------------------- */
#include <petscksp.h>
//#include <petscsys.h>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SolverPETSc::SolverPETSc(DOFManagerPETSc & dof_manager, const ID & matrix_id,
const ID & id, const MemoryID & memory_id)
: SparseSolver(dof_manager, matrix_id, id, memory_id),
dof_manager(dof_manager),
matrix(dof_manager.getMatrix(matrix_id)),
is_petsc_data_initialized(false) {
PetscErrorCode ierr;
/// create a solver context
ierr = KSPCreate(PETSC_COMM_WORLD, &this->ksp);
CHKERRXX(ierr);
}
/* -------------------------------------------------------------------------- */
SolverPETSc::~SolverPETSc() {
AKANTU_DEBUG_IN();
this->destroyInternalData();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::destroyInternalData() {
AKANTU_DEBUG_IN();
if (this->is_petsc_data_initialized) {
PetscErrorCode ierr;
ierr = KSPDestroy(&(this->ksp));
CHKERRXX(ierr);
this->is_petsc_data_initialized = false;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::initialize() {
AKANTU_DEBUG_IN();
this->is_petsc_data_initialized = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverPETSc::solve() {
AKANTU_DEBUG_IN();
Vec & rhs = this->dof_manager.getResidual();
Vec & solution = this->dof_manager.getGlobalSolution();
PetscErrorCode ierr;
ierr = KSPSolve(this->ksp, rhs, solution);
CHKERRXX(ierr);
AKANTU_DEBUG_OUT();
}
// /* -------------------------------------------------------------------------- */
// void SolverPETSc::solve(Array<Real> & solution) {
// AKANTU_DEBUG_IN();
// this->solution = &solution;
// this->solve();
// PetscErrorCode ierr;
// PETScMatrix * petsc_matrix = static_cast<PETScMatrix *>(this->matrix);
// // ierr = VecGetOwnershipRange(this->petsc_solver_wrapper->solution,
// // solution_begin, solution_end); CHKERRXX(ierr);
// // ierr = VecGetArray(this->petsc_solver_wrapper->solution, PetscScalar
// // **array); CHKERRXX(ierr);
// UInt nb_component = solution.getNbComponent();
// UInt size = solution.getSize();
// for (UInt i = 0; i < size; ++i) {
// for (UInt j = 0; j < nb_component; ++j) {
// UInt i_local = i * nb_component + j;
// if (this->matrix->getDOFSynchronizer().isLocalOrMasterDOF(i_local)) {
// Int i_global =
// this->matrix->getDOFSynchronizer().getDOFGlobalID(i_local);
// ierr = AOApplicationToPetsc(petsc_matrix->getPETScMatrixWrapper()->ao,
// 1, &(i_global));
// CHKERRXX(ierr);
// ierr = VecGetValues(this->petsc_solver_wrapper->solution, 1, &i_global,
// &solution(i, j));
// CHKERRXX(ierr);
// }
// }
// }
// synch_registry->synchronize(_gst_solver_solution);
// AKANTU_DEBUG_OUT();
// }
/* -------------------------------------------------------------------------- */
void SolverPETSc::setOperators() {
AKANTU_DEBUG_IN();
PetscErrorCode ierr;
/// set the matrix that defines the linear system and the matrix for
/// preconditioning (here they are the same)
#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
ierr = KSPSetOperators(this->ksp,
this->matrix.getPETScMat(),
this->matrix.getPETScMat());
CHKERRXX(ierr);
#else
ierr = KSPSetOperators(this->ksp,
this->matrix.getPETScMat(),
this->matrix.getPETScMat(),
SAME_NONZERO_PATTERN);
CHKERRXX(ierr);
#endif
/// If this is not called the solution vector is zeroed in the call to
/// KSPSolve().
ierr = KSPSetInitialGuessNonzero(this->ksp, PETSC_TRUE);
KSPSetFromOptions(this->ksp);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
// void finalize_petsc() {
// static bool finalized = false;
// if (!finalized) {
// cout<<"*** INFO *** PETSc is finalizing..."<<endl;
// // finalize PETSc
// PetscErrorCode ierr = PetscFinalize();CHKERRCONTINUE(ierr);
// finalized = true;
// }
// }
// SolverPETSc::sparse_vector_type
// SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& AA,
// const SolverPETSc::sparse_vector_type& bb) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside PETSc solver: "<<timer<<endl;
// #endif
// #ifdef CPPUTILS_VERBOSE
// out<<" Inside operator()(const sparse_matrix_type&, const
// sparse_vector_type&)... "<<timer<<endl;
// #endif
// assert(AA.rows() == bb.size());
// // KSP ksp; //!< linear solver context
// Vec b; /* RHS */
// PC pc; /* preconditioner context */
// PetscErrorCode ierr;
// PetscInt nlocal;
// PetscInt n = bb.size();
// VecScatter ctx;
// /*
// Create vectors. Note that we form 1 vector from scratch and
// then duplicate as needed. For this simple case let PETSc decide how
// many elements of the vector are stored on each processor. The second
// argument to VecSetSizes() below causes PETSc to decide.
// */
// ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(b,PETSC_DECIDE,n);CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(b);CHKERRCONTINUE(ierr);
// if (!allocated_) {
// ierr = VecDuplicate(b,&x_);CHKERRCONTINUE(ierr);
// } else
// VecZeroEntries(x_);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vectors created... "<<timer<<endl;
// #endif
// /* Set hight-hand-side vector */
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
// bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(b, 1, &row, &it->second, ADD_VALUES);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Right hand side set... "<<timer<<endl;
// #endif
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(b);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(b);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Right-hand-side vector assembled... "<<timer<<endl;
// ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// Vec b_all;
// ierr = VecScatterCreateToAll(b, &ctx, &b_all);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterBegin(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterEnd(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// value_type nrm;
// VecNorm(b_all,NORM_2,&nrm);
// out<<" Norm of right hand side... "<<nrm<<endl;
// #endif
// /* Identify the starting and ending mesh points on each
// processor for the interior part of the mesh. We let PETSc decide
// above. */
// // PetscInt rstart,rend;
// // ierr = VecGetOwnershipRange(x_,&rstart,&rend);CHKERRCONTINUE(ierr);
// ierr = VecGetLocalSize(x_,&nlocal);CHKERRCONTINUE(ierr);
// /*
// Create matrix. When using MatCreate(), the matrix format can
// be specified at runtime.
// Performance tuning note: For problems of substantial size,
// preallocation of matrix memory is crucial for attaining good
// performance. See the matrix chapter of the users manual for details.
// We pass in nlocal as the "local" size of the matrix to force it
// to have the same parallel layout as the vector created above.
// */
// if (!allocated_) {
// ierr = MatCreate(PETSC_COMM_WORLD,&A_);CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(A_,nlocal,nlocal,n,n);CHKERRCONTINUE(ierr);
// ierr = MatSetFromOptions(A_);CHKERRCONTINUE(ierr);
// ierr = MatSetUp(A_);CHKERRCONTINUE(ierr);
// } else {
// // zero-out matrix
// MatZeroEntries(A_);
// }
// /*
// Assemble matrix.
// The linear system is distributed across the processors by
// chunks of contiguous rows, which correspond to contiguous
// sections of the mesh on which the problem is discretized.
// For matrix assembly, each processor contributes entries for
// the part that it owns locally.
// */
// #ifdef CPPUTILS_VERBOSE
// out<<" Zeroed-out sparse matrix entries... "<<timer<<endl;
// #endif
// for (sparse_matrix_type::const_hash_iterator it = AA.map_.begin(); it !=
// AA.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = AA.unhash(it->first);
// PetscInt row = subs.first;
// PetscInt col = subs.second;
// ierr = MatSetValues(A_, 1, &row, 1, &col, &it->second,
// ADD_VALUES);CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Filled sparse matrix... "<<timer<<endl;
// #endif
// /* Assemble the matrix */
// ierr = MatAssemblyBegin(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// if (!allocated_) {
// // set after the first MatAssemblyEnd
// // ierr = MatSetOption(A_, MAT_NEW_NONZERO_LOCATIONS,
// PETSC_FALSE);CHKERRCONTINUE(ierr);
// ierr = MatSetOption(A_, MAT_NEW_NONZERO_ALLOCATION_ERR,
// PETSC_FALSE);CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Sparse matrix assembled... "<<timer<<endl;
// // view matrix
// MatView(A_, PETSC_VIEWER_STDOUT_WORLD);
// MatNorm(A_,NORM_FROBENIUS,&nrm);
// out<<" Norm of stiffness matrix... "<<nrm<<endl;
// #endif
// /*
// Set operators. Here the matrix that defines the linear system
// also serves as the preconditioning matrix.
// */
// // ierr =
// KSPSetOperators(ksp,A_,A_,DIFFERENT_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
// ierr =
// KSPSetOperators(ksp_,A_,A_,SAME_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
// //
// // /*
// // Set runtime options, e.g.,
// // -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
// // These options will override those specified above as long as
// // KSPSetFromOptions() is called _after_ any other customization
// // routines.
// // */
// // ierr = KSPSetFromOptions(ksp);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Solving system... "<<timer<<endl;
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Solve the linear system
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// /*
// Solve linear system
// */
// ierr = KSPSolve(ksp_,b,x_);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// /*
// View solver info; we could instead use the option -ksp_view to
// print this info to the screen at the conclusion of KSPSolve().
// */
// ierr = KSPView(ksp_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// int iter;
// KSPGetIterationNumber(ksp_, &iter);
// out<<" System solved in "<<iter<<" iterations... "<<timer<<endl;
// KSPConvergedReason reason;
// ierr = KSPGetConvergedReason(ksp_,&reason);CHKERRCONTINUE(ierr);
// if (reason < 0)
// out<<"*** WARNING *** PETSc solver diverged with flag ";
// else
// out<<"*** INFO *** PETSc solver converged with flag ";
// if (reason == KSP_CONVERGED_RTOL)
// out<<"KSP_CONVERGED_RTOL"<<endl;
// else if (reason == KSP_CONVERGED_ATOL)
// out<<"KSP_CONVERGED_ATOL"<<endl;
// else if (reason == KSP_CONVERGED_ITS)
// out<<"KSP_CONVERGED_ITS"<<endl;
// else if (reason == KSP_CONVERGED_CG_NEG_CURVE)
// out<<"KSP_CONVERGED_CG_NEG_CURVE"<<endl;
// else if (reason == KSP_CONVERGED_CG_CONSTRAINED)
// out<<"KSP_CONVERGED_CG_CONSTRAINED"<<endl;
// else if (reason == KSP_CONVERGED_STEP_LENGTH)
// out<<"KSP_CONVERGED_STEP_LENGTH"<<endl;
// else if (reason == KSP_CONVERGED_HAPPY_BREAKDOWN)
// out<<"KSP_CONVERGED_HAPPY_BREAKDOWN"<<endl;
// else if (reason == KSP_DIVERGED_NULL)
// out<<"KSP_DIVERGED_NULL"<<endl;
// else if (reason == KSP_DIVERGED_ITS)
// out<<"KSP_DIVERGED_ITS"<<endl;
// else if (reason == KSP_DIVERGED_DTOL)
// out<<"KSP_DIVERGED_DTOL"<<endl;
// else if (reason == KSP_DIVERGED_BREAKDOWN)
// out<<"KSP_DIVERGED_BREAKDOWN"<<endl;
// else if (reason == KSP_DIVERGED_BREAKDOWN_BICG)
// out<<"KSP_DIVERGED_BREAKDOWN_BICG"<<endl;
// else if (reason == KSP_DIVERGED_NONSYMMETRIC)
// out<<"KSP_DIVERGED_NONSYMMETRIC"<<endl;
// else if (reason == KSP_DIVERGED_INDEFINITE_PC)
// out<<"KSP_DIVERGED_INDEFINITE_PC"<<endl;
// else if (reason == KSP_DIVERGED_NAN)
// out<<"KSP_DIVERGED_NAN"<<endl;
// else if (reason == KSP_DIVERGED_INDEFINITE_MAT)
// out<<"KSP_DIVERGED_INDEFINITE_MAT"<<endl;
// else if (reason == KSP_CONVERGED_ITERATING)
// out<<"KSP_CONVERGED_ITERATING"<<endl;
// PetscReal rnorm;
// ierr = KSPGetResidualNorm(ksp_,&rnorm);CHKERRCONTINUE(ierr);
// out<<"PETSc last residual norm computed: "<<rnorm<<endl;
// ierr = VecView(x_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// VecNorm(x_,NORM_2,&nrm);
// out<<" Norm of solution vector... "<<nrm<<endl;
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Check solution and clean up
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// Vec x_all;
// ierr = VecScatterCreateToAll(x_, &ctx, &x_all);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterBegin(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterEnd(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Solution vector scattered... "<<timer<<endl;
// VecNorm(x_all,NORM_2,&nrm);
// out<<" Norm of scattered vector... "<<nrm<<endl;
// // ierr = VecView(x_all,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Get values from solution and store them in the object that will be
// returned
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// sparse_vector_type xx(bb.size());
// /* Set solution vector */
// double zero = 0.;
// double val;
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
// bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecGetValues(x_all, 1, &row, &val);
// if (val != zero)
// xx[row] = val;
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Solution vector copied... "<<timer<<endl;
// // out<<" Norm of copied solution vector... "<<norm(xx,
// Insert_t)<<endl;
// #endif
// /*
// Free work space. All PETSc objects should be destroyed when they
// are no longer needed.
// */
// ierr = VecDestroy(&b);CHKERRCONTINUE(ierr);
// // ierr = KSPDestroy(&ksp);CHKERRCONTINUE(ierr);
// // set allocated flag
// if (!allocated_) {
// allocated_ = true;
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return xx;
// }
// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const
// SolverPETSc::sparse_matrix_type& KKpf, const SolverPETSc::sparse_matrix_type&
// KKpp, const SolverPETSc::sparse_vector_type& UUp) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::operator()(const sparse_matrix&, const
// sparse_matrix&, const sparse_vector&). "<<timer<<endl;
// #endif
// Mat Kpf, Kpp;
// Vec Up, Pf, Pp;
// PetscErrorCode ierr =
// MatCreate(PETSC_COMM_WORLD,&Kpf);CHKERRCONTINUE(ierr);
// ierr = MatCreate(PETSC_COMM_WORLD,&Kpp);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Allocating memory... "<<timer<<endl;
// #endif
// ierr = MatSetFromOptions(Kpf);CHKERRCONTINUE(ierr);
// ierr = MatSetFromOptions(Kpp);CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(Kpf,PETSC_DECIDE,PETSC_DECIDE, KKpf.rows(),
// KKpf.columns());CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(Kpp,PETSC_DECIDE,PETSC_DECIDE, KKpp.rows(),
// KKpp.columns());CHKERRCONTINUE(ierr);
// // get number of non-zeros in both diagonal and non-diagonal portions of
// the matrix
// std::pair<size_t,size_t> Kpf_nz = KKpf.non_zero_off_diagonal();
// std::pair<size_t,size_t> Kpp_nz = KKpp.non_zero_off_diagonal();
// ierr = MatMPIAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL,
// Kpf_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
// ierr = MatMPIAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL,
// Kpp_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
// ierr = MatSeqAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL);
// CHKERRCONTINUE(ierr);
// ierr = MatSeqAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL);
// CHKERRCONTINUE(ierr);
// for (sparse_matrix_type::const_hash_iterator it = KKpf.map_.begin(); it !=
// KKpf.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = KKpf.unhash(it->first);
// int row = subs.first;
// int col = subs.second;
// ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second,
// ADD_VALUES);CHKERRCONTINUE(ierr);
// }
// for (sparse_matrix_type::const_hash_iterator it = KKpp.map_.begin(); it !=
// KKpp.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = KKpp.unhash(it->first);
// int row = subs.first;
// int col = subs.second;
// ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second,
// ADD_VALUES);CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Filled sparse matrices... "<<timer<<endl;
// #endif
// /*
// Assemble matrix, using the 2-step process:
// MatAssemblyBegin(), MatAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = MatAssemblyBegin(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyBegin(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Sparse matrices assembled... "<<timer<<endl;
// #endif
// ierr = VecCreate(PETSC_COMM_WORLD,&Up);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(Up,PETSC_DECIDE, UUp.size());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(Up);CHKERRCONTINUE(ierr);
// ierr = VecCreate(PETSC_COMM_WORLD,&Pf);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(Pf,PETSC_DECIDE, KKpf.rows());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(Pf);CHKERRCONTINUE(ierr);
// ierr = VecDuplicate(Pf,&Pp);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vectors created... "<<timer<<endl;
// #endif
// /* Set hight-hand-side vector */
// for (sparse_vector_type::const_hash_iterator it = UUp.map_.begin(); it !=
// UUp.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(Up, 1, &row, &it->second, ADD_VALUES);
// }
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(Up);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(Up);CHKERRCONTINUE(ierr);
// // add Kpf*Uf
// ierr = MatMult(Kpf, x_, Pf);
// // add Kpp*Up
// ierr = MatMultAdd(Kpp, Up, Pf, Pp);
// #ifdef CPPUTILS_VERBOSE
// out<<" Matrices multiplied... "<<timer<<endl;
// #endif
// VecScatter ctx;
// Vec Pp_all;
// ierr = VecScatterCreateToAll(Pp, &ctx, &Pp_all);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterBegin(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// ierr =
// VecScatterEnd(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector scattered... "<<timer<<endl;
// #endif
// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Get values from solution and store them in the object that will be
// returned
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// sparse_vector_type pp(KKpf.rows());
// // get reaction vector
// for (int i=0; i<KKpf.rows(); ++i) {
// PetscScalar v;
// ierr = VecGetValues(Pp_all, 1, &i, &v);
// if (v != PetscScalar())
// pp[i] = v;
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector copied... "<<timer<<endl;
// #endif
// ierr = MatDestroy(&Kpf);CHKERRCONTINUE(ierr);
// ierr = MatDestroy(&Kpp);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Up);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Pf);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Pp);CHKERRCONTINUE(ierr);
// ierr = VecDestroy(&Pp_all);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return pp;
// }
// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const
// SolverPETSc::sparse_vector_type& aa, const SolverPETSc::sparse_vector_type&
// bb) {
// assert(aa.size() == bb.size());
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::operator()(const sparse_vector&, const
// sparse_vector&). "<<timer<<endl;
// #endif
// Vec r;
// PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vectors created... "<<timer<<endl;
// #endif
// // set values
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
// aa.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
// }
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
// bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
// }
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
// sparse_vector_type rr(aa.size());
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
// aa.map_.end(); ++it) {
// int row = it->first;
// ierr = VecGetValues(r, 1, &row, &rr[row]);
// }
// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it !=
// bb.map_.end(); ++it) {
// int row = it->first;
// ierr = VecGetValues(r, 1, &row, &rr[row]);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector copied... "<<timer<<endl;
// #endif
// ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return rr;
// }
// SolverPETSc::value_type SolverPETSc::norm(const
// SolverPETSc::sparse_matrix_type& aa, Element_insertion_type flag) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::norm(const sparse_matrix&). "<<timer<<endl;
// #endif
// Mat r;
// PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
// ierr = MatSetSizes(r,PETSC_DECIDE,PETSC_DECIDE, aa.rows(),
// aa.columns());CHKERRCONTINUE(ierr);
// ierr = MatSetFromOptions(r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Matrix created... "<<timer<<endl;
// #endif
// // set values
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
// aa.map_.end(); ++it) {
// // get subscripts
// std::pair<size_t,size_t> subs = aa.unhash(it->first);
// int row = subs.first;
// int col = subs.second;
// if (flag == Add_t)
// ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, ADD_VALUES);
// else if (flag == Insert_t)
// ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, INSERT_VALUES);
// CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Matrix filled..."<<timer<<endl;
// #endif
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = MatAssemblyBegin(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// ierr = MatAssemblyEnd(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
// value_type nrm;
// MatNorm(r,NORM_FROBENIUS,&nrm);
// #ifdef CPPUTILS_VERBOSE
// out<<" Norm computed... "<<timer<<endl;
// #endif
// ierr = MatDestroy(&r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return nrm;
// }
// SolverPETSc::value_type SolverPETSc::norm(const
// SolverPETSc::sparse_vector_type& aa, Element_insertion_type flag) {
// #ifdef CPPUTILS_VERBOSE
// // parallel output stream
// Output_stream out;
// // timer
// cpputils::ctimer timer;
// out<<"Inside SolverPETSc::norm(const sparse_vector&). "<<timer<<endl;
// #endif
// Vec r;
// PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
// ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
// ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector created... "<<timer<<endl;
// #endif
// // set values
// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it !=
// aa.map_.end(); ++it) {
// int row = it->first;
// if (flag == Add_t)
// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
// else if (flag == Insert_t)
// ierr = VecSetValues(r, 1, &row, &it->second, INSERT_VALUES);
// CHKERRCONTINUE(ierr);
// }
// #ifdef CPPUTILS_VERBOSE
// out<<" Vector filled..."<<timer<<endl;
// #endif
// /*
// Assemble vector, using the 2-step process:
// VecAssemblyBegin(), VecAssemblyEnd()
// Computations can be done while messages are in transition
// by placing code between these two statements.
// */
// ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
// ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
// value_type nrm;
// VecNorm(r,NORM_2,&nrm);
// #ifdef CPPUTILS_VERBOSE
// out<<" Norm computed... "<<timer<<endl;
// #endif
// ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
// #ifdef CPPUTILS_VERBOSE
// out<<" Temporary data structures destroyed... "<<timer<<endl;
// #endif
// return nrm;
// }
// //
// ///*
// -------------------------------------------------------------------------- */
// //SolverMumps::SolverMumps(SparseMatrix & matrix,
// // const ID & id,
// // const MemoryID & memory_id) :
// //Solver(matrix, id, memory_id), is_mumps_data_initialized(false),
// rhs_is_local(true) {
// // AKANTU_DEBUG_IN();
// //
// //#ifdef AKANTU_USE_MPI
// // parallel_method = SolverMumpsOptions::_fully_distributed;
// //#else //AKANTU_USE_MPI
// // parallel_method = SolverMumpsOptions::_master_slave_distributed;
// //#endif //AKANTU_USE_MPI
// //
// // CommunicatorEventHandler & comm_event_handler = *this;
// //
// // communicator.registerEventHandler(comm_event_handler);
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //SolverMumps::~SolverMumps() {
// // AKANTU_DEBUG_IN();
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::destroyMumpsData() {
// // AKANTU_DEBUG_IN();
// //
// // if(is_mumps_data_initialized) {
// // mumps_data.job = _smj_destroy; // destroy
// // dmumps_c(&mumps_data);
// // is_mumps_data_initialized = false;
// // }
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::onCommunicatorFinalize(const StaticCommunicator & comm) {
// // AKANTU_DEBUG_IN();
// //
// // try{
// // const StaticCommunicatorMPI & comm_mpi =
// // dynamic_cast<const StaticCommunicatorMPI
// &>(comm.getRealStaticCommunicator());
// // if(mumps_data.comm_fortran ==
// MPI_Comm_c2f(comm_mpi.getMPICommunicator()))
// // destroyMumpsData();
// // } catch(...) {}
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::initMumpsData(SolverMumpsOptions::ParallelMethod
// parallel_method) {
// // switch(parallel_method) {
// // case SolverMumpsOptions::_fully_distributed:
// // icntl(18) = 3; //fully distributed
// // icntl(28) = 0; //automatic choice
// //
// // mumps_data.nz_loc = matrix->getNbNonZero();
// // mumps_data.irn_loc = matrix->getIRN().values;
// // mumps_data.jcn_loc = matrix->getJCN().values;
// // break;
// // case SolverMumpsOptions::_master_slave_distributed:
// // if(prank == 0) {
// // mumps_data.nz = matrix->getNbNonZero();
// // mumps_data.irn = matrix->getIRN().values;
// // mumps_data.jcn = matrix->getJCN().values;
// // } else {
// // mumps_data.nz = 0;
// // mumps_data.irn = NULL;
// // mumps_data.jcn = NULL;
// //
// // icntl(18) = 0; //centralized
// // icntl(28) = 0; //sequential analysis
// // }
// // break;
// // }
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::initialize(SolverOptions & options) {
// // AKANTU_DEBUG_IN();
// //
// // mumps_data.par = 1;
// //
// // if(SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions
// *>(&options)) {
// // if(opt->parallel_method ==
// SolverMumpsOptions::_master_slave_distributed) {
// // mumps_data.par = 0;
// // }
// // }
// //
// // mumps_data.sym = 2 * (matrix->getSparseMatrixType() == _symmetric);
// // prank = communicator.whoAmI();
// //#ifdef AKANTU_USE_MPI
// // mumps_data.comm_fortran = MPI_Comm_c2f(dynamic_cast<const
// StaticCommunicatorMPI
// &>(communicator.getRealStaticCommunicator()).getMPICommunicator());
// //#endif
// //
// // if(AKANTU_DEBUG_TEST(dblTrace)) {
// // icntl(1) = 2;
// // icntl(2) = 2;
// // icntl(3) = 2;
// // icntl(4) = 4;
// // }
// //
// // mumps_data.job = _smj_initialize; //initialize
// // dmumps_c(&mumps_data);
// // is_mumps_data_initialized = true;
// //
// // /*
// ------------------------------------------------------------------------ */
// // UInt size = matrix->getSize();
// //
// // if(prank == 0) {
// // std::stringstream sstr_rhs; sstr_rhs << id << ":rhs";
// // rhs = &(alloc<Real>(sstr_rhs.str(), size, 1, REAL_INIT_VALUE));
// // } else {
// // rhs = NULL;
// // }
// //
// // /// No outputs
// // icntl(1) = 0;
// // icntl(2) = 0;
// // icntl(3) = 0;
// // icntl(4) = 0;
// // mumps_data.nz_alloc = 0;
// //
// // if (AKANTU_DEBUG_TEST(dblDump)) icntl(4) = 4;
// //
// // mumps_data.n = size;
// //
// // if(AKANTU_DEBUG_TEST(dblDump)) {
// // strcpy(mumps_data.write_problem, "mumps_matrix.mtx");
// // }
// //
// // /*
// ------------------------------------------------------------------------ */
// // // Default Scaling
// // icntl(8) = 77;
// //
// // icntl(5) = 0; // Assembled matrix
// //
// // SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options);
// // if(opt)
// // parallel_method = opt->parallel_method;
// //
// // initMumpsData(parallel_method);
// //
// // mumps_data.job = _smj_analyze; //analyze
// // dmumps_c(&mumps_data);
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::setRHS(Array<Real> & rhs) {
// // if(prank == 0) {
// // matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
// // } else {
// // matrix->getDOFSynchronizer().gather(rhs, 0);
// // }
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::solve() {
// // AKANTU_DEBUG_IN();
// //
// // if(parallel_method == SolverMumpsOptions::_fully_distributed)
// // mumps_data.a_loc = matrix->getA().values;
// // else
// // if(prank == 0) {
// // mumps_data.a = matrix->getA().values;
// // }
// //
// // if(prank == 0) {
// // mumps_data.rhs = rhs->values;
// // }
// //
// // /// Default centralized dense second member
// // icntl(20) = 0;
// // icntl(21) = 0;
// //
// // mumps_data.job = _smj_factorize_solve; //solve
// // dmumps_c(&mumps_data);
// //
// // AKANTU_DEBUG_ASSERT(info(1) != -10, "Singular matrix");
// // AKANTU_DEBUG_ASSERT(info(1) == 0,
// // "Error in mumps during solve process, check mumps
// user guide INFO(1) ="
// // << info(1));
// //
// // AKANTU_DEBUG_OUT();
// //}
// //
// ///*
// -------------------------------------------------------------------------- */
// //void SolverMumps::solve(Array<Real> & solution) {
// // AKANTU_DEBUG_IN();
// //
// // solve();
// //
// // if(prank == 0) {
// // matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
// // } else {
// // matrix->getDOFSynchronizer().scatter(solution, 0);
// // }
// //
// // AKANTU_DEBUG_OUT();
// //}
__END_AKANTU__
diff --git a/src/solver/solver_petsc.hh b/src/solver/solver_petsc.hh
index c8d82920f..8394d52e8 100644
--- a/src/solver/solver_petsc.hh
+++ b/src/solver/solver_petsc.hh
@@ -1,181 +1,182 @@
/**
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "sparse_solver.hh"
/* -------------------------------------------------------------------------- */
#include <petscksp.h>
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_PETSC_HH__
#define __AKANTU_SOLVER_PETSC_HH__
namespace akantu {
class SparseMatrixPETSc;
class DOFManagerPETSc;
}
__BEGIN_AKANTU__
class SolverPETSc : public SparseSolver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SolverPETSc(DOFManagerPETSc & dof_manager, const ID & matrix_id,
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();
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:
/// DOFManager correctly typed
DOFManagerPETSc & dof_manager;
/// PETSc linear solver
KSP ksp;
/// Matrix defining the system of equations
SparseMatrixPETSc & matrix;
/// specify if the petsc_data is initialized or not
bool is_petsc_data_initialized;
};
// 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 ae3e805c4..803dc6fce 100644
--- a/src/solver/sparse_matrix.cc
+++ b/src/solver/sparse_matrix.cc
@@ -1,68 +1,69 @@
/**
* @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_manager.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SparseMatrix::SparseMatrix(DOFManager & dof_manager,
const MatrixType & matrix_type, const ID & id,
const MemoryID & memory_id)
: Memory(id, memory_id), dof_manager(dof_manager), matrix_type(matrix_type),
size(dof_manager.getSystemSize()), nb_non_zero(0), matrix_release(1) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
this->nb_proc = comm.getNbProc();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseMatrix::SparseMatrix(const SparseMatrix & matrix, const ID & id,
const MemoryID & memory_id)
: Memory(id, memory_id), dof_manager(matrix.dof_manager),
matrix_type(matrix.matrix_type), size(matrix.size),
nb_proc(matrix.nb_proc), nb_non_zero(matrix.nb_non_zero),
matrix_release(1) {}
/* -------------------------------------------------------------------------- */
SparseMatrix::~SparseMatrix() {}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/solver/sparse_matrix.hh b/src/solver/sparse_matrix.hh
index c9e4efb20..e62635fa4 100644
--- a/src/solver/sparse_matrix.hh
+++ b/src/solver/sparse_matrix.hh
@@ -1,137 +1,138 @@
/**
* @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 "dof_manager.hh"
#include "mesh.hh"
__BEGIN_AKANTU__
class SparseMatrix : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SparseMatrix(DOFManager & dof_manager,
const MatrixType & matrix_type,
const ID & id = "sparse_matrix",
const MemoryID & memory_id = 0);
SparseMatrix(const SparseMatrix & matrix, const ID & id = "sparse_matrix",
const MemoryID & memory_id = 0);
virtual ~SparseMatrix();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// remove the existing profile
virtual void clearProfile();
/// set the matrix to 0
virtual void clear();
/// add a non-zero element to the profile
virtual inline UInt addToProfile(UInt i, UInt j) = 0;
/// assemble a local matrix in the sparse one
virtual inline void addToMatrix(UInt i, UInt j, Real value) = 0;
/// 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);
/// add matrix assuming the profile are the same
virtual void add(const SparseMatrix & matrix, Real alpha);
/// modify the matrix to "remove" the blocked dof
virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// return the values at potition i, j
virtual inline Real operator()(UInt i, UInt j) const { AKANTU_DEBUG_TO_IMPLEMENT(); }
/// return the values at potition i, j
virtual inline Real & operator()(UInt i, UInt j) { AKANTU_DEBUG_TO_IMPLEMENT(); }
AKANTU_GET_MACRO(NbNonZero, nb_non_zero, UInt);
AKANTU_GET_MACRO(Size, size, UInt);
AKANTU_GET_MACRO(MatrixType, matrix_type, const MatrixType &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Underlying dof manager
DOFManager & dof_manager;
/// sparce matrix type
MatrixType matrix_type;
/// Size of the matrix
UInt size;
/// number of processors
UInt nb_proc;
/// number of non zero element
UInt nb_non_zero;
/// matrix definition releasez
UInt matrix_release;
};
Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat);
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "sparse_matrix_inline_impl.cc"
#endif /* __AKANTU_SPARSE_MATRIX_HH__ */
diff --git a/src/solver/sparse_matrix_aij.hh b/src/solver/sparse_matrix_aij.hh
index 7cb8746b8..4af16c5cf 100644
--- a/src/solver/sparse_matrix_aij.hh
+++ b/src/solver/sparse_matrix_aij.hh
@@ -1,187 +1,151 @@
/**
* @file sparse_matrix_aij.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Mon Aug 17 21:22:57 2015
*
* @brief AIJ implementation of the SparseMatrix (this the format used by Mumps)
*
* @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 "sparse_matrix.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SPARSE_MATRIX_AIJ_HH__
#define __AKANTU_SPARSE_MATRIX_AIJ_HH__
-/* -------------------------------------------------------------------------- */
-#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
-
__BEGIN_AKANTU__
class SparseMatrixAIJ : public SparseMatrix {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SparseMatrixAIJ(DOFManager & dof_manager, const MatrixType & matrix_type,
const ID & id = "sparse_matrix_aij",
const MemoryID & memory_id = 0);
SparseMatrixAIJ(const SparseMatrixAIJ & matrix, const ID & id = "sparse_matrix_aij",
const MemoryID & memory_id = 0);
virtual ~SparseMatrixAIJ();
/* ------------------------------------------------------------------------ */
/* 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; }
/// modify the matrix to "remove" the blocked dof
virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
/// 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);
/// add matrix assuming the profile are the same
virtual void add(const SparseMatrix & matrix, Real alpha);
/// Equivalent of *gemv in blas
virtual void matVecMul(const Array<Real> & x, Array<Real> & y,
Real alpha = 1., Real beta = 0.);
/* ------------------------------------------------------------------------ */
/// accessor to A_{ij} - if (i, j) not present it returns 0
inline Real operator()(UInt i, UInt j) const;
/// accessor to A_{ij} - if (i, j) not present it fails, (i, j) should be
/// first added to the profile
inline Real & operator()(UInt i, UInt j);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(IRN, irn, const Array<Int> &);
AKANTU_GET_MACRO(JCN, jcn, const Array<Int> &);
AKANTU_GET_MACRO(A, a, const Array<Real> &);
protected:
typedef std::pair<UInt, UInt> KeyCOO;
typedef unordered_map<KeyCOO, UInt>::type coordinate_list_map;
/// get the pair corresponding to (i, j)
inline KeyCOO key(UInt i, UInt j) const {
if (this->matrix_type == _symmetric && (i > j))
return std::make_pair(j, i);
return std::make_pair(i, j);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// row indexes
Array<Int> irn;
/// column indexes
Array<Int> jcn;
/// values : A[k] = Matrix[irn[k]][jcn[k]]
Array<Real> a;
/// Profile release
UInt profile_release;
/// Value release
UInt value_release;
/*
* map for (i, j) -> k correspondence
*/
coordinate_list_map irn_jcn_k;
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "sparse_matrix_aij_inline_impl.cc"
#endif /* __AKANTU_SPARSE_MATRIX_AIJ_HH__ */
diff --git a/src/solver/sparse_matrix_inline_impl.cc b/src/solver/sparse_matrix_inline_impl.cc
index 67c20ff09..8bce2e569 100644
--- a/src/solver/sparse_matrix_inline_impl.cc
+++ b/src/solver/sparse_matrix_inline_impl.cc
@@ -1,38 +1,39 @@
/**
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
inline void SparseMatrix::clearProfile() {
this->nb_non_zero = 0;
}
__END_AKANTU__
diff --git a/src/solver/sparse_matrix_petsc.hh b/src/solver/sparse_matrix_petsc.hh
index 7ec7eaede..68e20d25b 100644
--- a/src/solver/sparse_matrix_petsc.hh
+++ b/src/solver/sparse_matrix_petsc.hh
@@ -1,138 +1,142 @@
/**
* @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 <petscmat.h>
#include <petscao.h>
/* -------------------------------------------------------------------------- */
namespace akantu {
class DOFManagerPETSc;
}
__BEGIN_AKANTU__
class SparseMatrixPETSc : public SparseMatrix {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SparseMatrixPETSc(DOFManagerPETSc & dof_manager, const MatrixType & matrix_type,
const ID & id = "sparse_matrix",
const MemoryID & memory_id = 0);
SparseMatrixPETSc(const SparseMatrix & matrix,
const ID & id = "sparse_matrix_petsc",
const MemoryID & memory_id = 0);
virtual ~SparseMatrixPETSc();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// set the matrix to 0
virtual void clear();
/// 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 SparseMatrixPETSc & matrix, Real alpha);
Real operator()(UInt i, UInt j) const;
protected:
typedef std::pair<UInt, UInt> KeyCOO;
inline KeyCOO key(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();
/// start to assemble the matrix
void beginAssembly();
/// finishes to assemble the matrix
void endAssembly();
/// perform the assembly stuff from petsc
void performAssembly();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(PETScMat, mat, const Mat &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
// DOFManagerPETSc that contains the numbering for petsc
DOFManagerPETSc & dof_manager;
/// store the PETSc matrix
Mat mat;
AO ao;
/// 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/sparse_solver.cc b/src/solver/sparse_solver.cc
index 138bc7787..51a59d5ec 100644
--- a/src/solver/sparse_solver.cc
+++ b/src/solver/sparse_solver.cc
@@ -1,81 +1,83 @@
/**
* @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 "sparse_solver.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SparseSolver::SparseSolver(DOFManager & dof_manager, const ID & matrix_id,
const ID & id, const MemoryID & memory_id)
: Memory(id, memory_id), Parsable(_st_solver, id),
_dof_manager(dof_manager), matrix_id(matrix_id) {
AKANTU_DEBUG_IN();
// createSynchronizerRegistry();
// this->synch_registry = new SynchronizerRegistry(*this);
// synch_registry->registerSynchronizer(this->matrix->getDOFSynchronizer(),
// _gst_solver_solution);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseSolver::~SparseSolver() {
AKANTU_DEBUG_IN();
this->destroyInternalData();
// delete synch_registry;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolver::beforeStaticSolverDestroy() {
AKANTU_DEBUG_IN();
try {
this->destroyInternalData();
} catch (...) {
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseSolver::createSynchronizerRegistry() {
// this->synch_registry = new SynchronizerRegistry(this);
}
__END_AKANTU__
diff --git a/src/solver/sparse_solver.hh b/src/solver/sparse_solver.hh
index 5078db203..7b85685fa 100644
--- a/src/solver/sparse_solver.hh
+++ b/src/solver/sparse_solver.hh
@@ -1,116 +1,117 @@
/**
* @file sparse_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 "data_accessor.hh"
#include "parsable.hh"
/* -------------------------------------------------------------------------- */
enum SolverParallelMethod {
_not_parallel,
_fully_distributed,
_master_slave_distributed
};
namespace akantu {
class DOFManager;
}
__BEGIN_AKANTU__
class SparseSolver : protected Memory,
public Parsable,
public DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SparseSolver(DOFManager & dof_manager, const ID & matrix_id,
const ID & id = "solver", const MemoryID & memory_id = 0);
virtual ~SparseSolver();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the solver
virtual void initialize() = 0;
virtual void analysis(){};
virtual void factorize(){};
virtual void solve(){};
protected:
virtual void destroyInternalData(){};
public:
virtual void beforeStaticSolverDestroy();
void createSynchronizerRegistry();
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
// inline virtual UInt getNbDataForDOFs(const Array<UInt> & dofs,
// SynchronizationTag tag) const;
// inline virtual void packDOFData(CommunicationBuffer & buffer,
// const Array<UInt> & dofs,
// SynchronizationTag tag) const;
// inline virtual void unpackDOFData(CommunicationBuffer & buffer,
// const Array<UInt> & dofs,
// SynchronizationTag tag);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// manager handling the dofs for this SparseMatrix solver
DOFManager & _dof_manager;
/// The id of the associated matrix
ID matrix_id;
/// How to parallelize the solve
SolverParallelMethod parallel_method;
};
__END_AKANTU__
#endif /* __AKANTU_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 9d8001934..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 {
+ __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 {
+ __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)) 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 {
+ __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) {
+ __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) {
+ __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) {
+ CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ const Mesh & mesh) {
packUnpackNodalDataHelper<T, true>(const_cast<Array<T> &>(data),
- buffer,
- elements,
- mesh);
+ buffer,
+ elements,
+ mesh);
}
template<typename T>
static inline void unpackNodalDataHelper(Array<T> & data,
- CommunicationBuffer & buffer,
- const Array<Element> & elements,
- const Mesh & mesh) {
+ CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ const Mesh & mesh) {
packUnpackNodalDataHelper<T, false>(data,
- buffer,
- elements,
- mesh);
+ 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);
+ 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);
+ 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) {
+ 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);
+ 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) {
+ const FEEngine & fem) {
packUnpackElementalDataHelper<T, false>(data_to_unpack,
- buffer,
- elements,
- per_quadrature_point,
- fem);
+ 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);
+ 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) {
+ CommunicationBuffer & buffer,
+ const Array<UInt> & dofs) {
packUnpackDOFDataHelper<T, true>(const_cast<Array<T> &>(data_to_pack),
- buffer,
- dofs);
+ buffer,
+ dofs);
}
-
+
template<typename T>
static inline void unpackDOFDataHelper(Array<T> & data_to_unpack,
- CommunicationBuffer & buffer,
- const Array<UInt> & dofs) {
+ CommunicationBuffer & buffer,
+ const Array<UInt> & dofs) {
packUnpackDOFDataHelper<T, false>(data_to_unpack,
- buffer,
- dofs);
+ 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 8bba84c11..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.getNbQuadraturePoints(el.type,
+ 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 ab3d43d5b..04f2cef93 100644
--- a/src/synchronizer/distributed_synchronizer.cc
+++ b/src/synchronizer/distributed_synchronizer.cc
@@ -1,1669 +1,1786 @@
/**
* @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) :
- Synchronizer(id, memory_id),
- mesh(mesh),
- prank_to_element("prank_to_element", id)
-{
+DistributedSynchronizer::DistributedSynchronizer(
+ Mesh & mesh, SynchronizerID id, MemoryID memory_id,
+ const bool register_to_event_manager)
+ : Synchronizer(id, memory_id), mesh(mesh),
+ prank_to_element("prank_to_element", id) {
AKANTU_DEBUG_IN();
nb_proc = static_communicator->getNbProc();
- rank = static_communicator->whoAmI();
+ 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());
- }
-
- mesh.registerEventHandler(*this);
+
+ for (UInt p = 0; p < nb_proc; ++p) {
+ std::stringstream sstr;
+ sstr << p;
+ send_element[p].setID(id + ":send_elements_" + sstr.str());
+ recv_element[p].setID(id + ":recv_elements_" + sstr.str());
+ }
+
+ if (register_to_event_manager)
+ mesh.registerEventHandler(*this);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
DistributedSynchronizer::~DistributedSynchronizer() {
AKANTU_DEBUG_IN();
for (UInt p = 0; p < nb_proc; ++p) {
send_element[p].clear();
recv_element[p].clear();
}
- delete [] send_element;
- delete [] recv_element;
+ 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)"
- << " [" << Tag::genTag(rank, counter, tag) << "]");
- communication.send_requests.push_back(static_communicator->asyncSend(buffer.storage(),
- ssize,
- p,
- Tag::genTag(rank, counter, 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);
- 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)));
- }
+ Tag comm_tag = Tag::genTag(rank, counter, tag);
+ buffer << int(comm_tag);
-
-#if defined(AKANTU_DEBUG_TOOLS) && defined(AKANTU_CORE_CXX11)
- static std::set<SynchronizationTag> tags;
- if(tags.find(tag) == tags.end()) {
- debug::element_manager.print(debug::_dm_synch,
- [&send_element, rank, nb_proc, tag, id](const Element & el)->std::string {
- std::stringstream out;
- UInt elp = 0;
- for (UInt p = 0; p < nb_proc; ++p) {
- UInt pos = send_element[p].find(el);
- if(pos != UInt(-1)) {
- if(elp > 0) out << std::endl;
- out << id << " send (" << pos << "/" << send_element[p].getSize() << ") to proc " << p << " tag:" << tag;
- ++elp;
- }
- }
- return out.str();
- });
-
- debug::element_manager.print(debug::_dm_synch,
- [&recv_element, rank, nb_proc, tag, id](const Element & el)->std::string {
- std::stringstream out;
- UInt elp = 0;
- for (UInt p = 0; p < nb_proc; ++p) {
- if(p == rank) continue;
- UInt pos = recv_element[p].find(el);
- if(pos != UInt(-1)) {
- if(elp > 0) out << std::endl;
- out << id << " recv (" << pos << "/" << recv_element[p].getSize() << ") from proc " << p << " tag:" << tag;
- ++elp;
- }
- }
- return out.str();
- });
- tags.insert(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)));
}
-#endif
-
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);
#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);
- }
- }
+ 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");
- 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) {
+ 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) {
+ 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::onElementsRemoved(const Array<Element> & element_to_remove,
- const ElementTypeMapArray<UInt> & new_numbering,
- __attribute__((unused)) const RemovedElementsEvent & event) {
- AKANTU_DEBUG_IN();
+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();
- StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- UInt psize = comm.getNbProc();
- UInt prank = comm.whoAmI();
-
- std::vector<CommunicationRequest *> isend_requests;
- Array<UInt> * list_of_el = new Array<UInt>[nb_proc];
- // Handling ghost elements
- for (UInt p = 0; p < psize; ++p) {
- if (p == prank) continue;
+ for (UInt p = 0; p < nb_proc; ++p) {
+ if (p == rank)
+ continue;
Array<Element> & recv = recv_element[p];
- if(recv.getSize() == 0) continue;
-
- Array<Element>::iterator<Element> recv_begin = recv.begin();
- Array<Element>::iterator<Element> recv_end = recv.end();
-
- Array<Element>::const_iterator<Element> er_it = element_to_remove.begin();
- Array<Element>::const_iterator<Element> er_end = element_to_remove.end();
-
- Array<UInt> & list = list_of_el[p];
- for (UInt i = 0; recv_begin != recv_end; ++i, ++recv_begin) {
- const Element & el = *recv_begin;
- Array<Element>::const_iterator<Element> pos = std::find(er_it, er_end, el);
- if(pos == er_end) {
- list.push_back(i);
- }
- }
-
- if(list.getSize() == recv.getSize())
- list.push_back(UInt(0));
- else list.push_back(UInt(-1));
-
- AKANTU_DEBUG_INFO("Sending a message of size " << list.getSize() << " to proc " << p << " TAG(" << Tag::genTag(prank, 0, 0) << ")");
- isend_requests.push_back(comm.asyncSend(list.storage(), list.getSize(),
- p, Tag::genTag(prank, 0, 0)));
-
- list.erase(list.getSize() - 1);
- if(list.getSize() == recv.getSize()) continue;
-
- Array<Element> new_recv;
- for (UInt nr = 0; nr < list.getSize(); ++nr) {
- Element & el = recv(list(nr));
- el.element = new_numbering(el.type, el.ghost_type)(el.element);
- new_recv.push_back(el);
+ 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;
}
- 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 < psize; ++p) {
- if (p == prank) continue;
Array<Element> & send = send_element[p];
-
- if(send.getSize() == 0) continue;
-
- CommunicationStatus status;
- AKANTU_DEBUG_INFO("Getting number of elements of proc " << p << " not needed anymore TAG("<< Tag::genTag(p, 0, 0) <<")");
- comm.probe<UInt>(p, Tag::genTag(p, 0, 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("<< Tag::genTag(p, 0, 0) <<")");
- comm.receive(list.storage(), list.getSize(),
- p, Tag::genTag(p, 0, 0));
-
- if(list.getSize() == 1 && list(0) == 0) continue;
-
- list.erase(list.getSize() - 1);
-
- Array<Element> new_send;
- for (UInt ns = 0; ns < list.getSize(); ++ns) {
- new_send.push_back(send(list(ns)));
+ 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;
}
+ }
+}
- 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);
+/* -------------------------------------------------------------------------- */
+void DistributedSynchronizer::onElementsChanged(
+ const Array<Element> & old_elements_list,
+ const Array<Element> & new_elements_list,
+ __attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
+ __attribute__((unused)) const ChangedElementsEvent & event) {
+ // create a map to link old elements to new ones
+ std::map<Element, Element> old_to_new_elements;
+
+ for (UInt el = 0; el < old_elements_list.getSize(); ++el) {
+ AKANTU_DEBUG_ASSERT(old_to_new_elements.find(old_elements_list(el)) ==
+ old_to_new_elements.end(),
+ "The same element cannot appear twice in the list");
+
+ old_to_new_elements[old_elements_list(el)] = new_elements_list(el);
}
- comm.waitAll(isend_requests);
- comm.freeCommunicationRequest(isend_requests);
+ substituteElements(old_to_new_elements);
+}
- delete [] list_of_el;
+/* -------------------------------------------------------------------------- */
+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[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;
}
++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[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;
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) {
+ AKANTU_DEBUG_IN();
+
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+
+ std::vector<CommunicationRequest *> isend_requests;
+ Array<UInt> * list_of_el = new Array<UInt>[nb_proc];
+ // Handling ghost elements
+ for (UInt p = 0; p < nb_proc; ++p) {
+ if (p == rank)
+ continue;
+
+ Array<Element> & recv = recv_element[p];
+ if (recv.getSize() == 0)
+ continue;
+
+ Array<Element>::iterator<Element> recv_begin = recv.begin();
+ Array<Element>::iterator<Element> recv_end = recv.end();
+
+ Array<Element>::const_iterator<Element> er_it = element_to_remove.begin();
+ Array<Element>::const_iterator<Element> er_end = element_to_remove.end();
+
+ Array<UInt> & list = list_of_el[p];
+ for (UInt i = 0; recv_begin != recv_end; ++i, ++recv_begin) {
+ const Element & el = *recv_begin;
+ Array<Element>::const_iterator<Element> pos =
+ std::find(er_it, er_end, el);
+ if (pos == er_end) {
+ list.push_back(i);
+ }
+ }
+
+ if (list.getSize() == recv.getSize())
+ list.push_back(UInt(0));
+ else
+ list.push_back(UInt(-1));
+
+ AKANTU_DEBUG_INFO("Sending a message of size "
+ << list.getSize() << " to proc " << p << " TAG("
+ << this->genTagFromID(0) << ")");
+ isend_requests.push_back(comm.asyncSend(list.storage(), list.getSize(), p,
+ this->genTagFromID(0)));
+
+ list.erase(list.getSize() - 1);
+
+ if (list.getSize() == recv.getSize())
+ continue;
+
+ Array<Element> new_recv;
+ for (UInt nr = 0; nr < list.getSize(); ++nr) {
+ Element & el = recv(list(nr));
+ new_recv.push_back(el);
+ }
+
+ AKANTU_DEBUG_INFO("I had " << recv.getSize()
+ << " elements to recv from proc " << p << " and "
+ << list.getSize() << " elements to keep. I have "
+ << new_recv.getSize() << " elements left.");
+ recv.copy(new_recv);
+ }
+
+ for (UInt p = 0; p < nb_proc; ++p) {
+ if (p == rank)
+ continue;
+ Array<Element> & send = send_element[p];
+
+ if (send.getSize() == 0)
+ continue;
+
+ CommunicationStatus status;
+ AKANTU_DEBUG_INFO("Getting number of elements of proc "
+ << p << " not needed anymore TAG("
+ << this->genTagFromID(0) << ")");
+ comm.probe<UInt>(p, this->genTagFromID(0), status);
+ Array<UInt> list(status.getSize());
+
+ AKANTU_DEBUG_INFO("Receiving list of elements ("
+ << status.getSize() - 1
+ << " elements) no longer needed by proc " << p << " TAG("
+ << this->genTagFromID(0) << ")");
+ comm.receive(list.storage(), list.getSize(), p, this->genTagFromID(0));
+
+ if (list.getSize() == 1 && list(0) == 0)
+ continue;
+
+ list.erase(list.getSize() - 1);
+
+ if (list.getSize() == send.getSize())
+ continue;
+
+ Array<Element> new_send;
+ for (UInt ns = 0; ns < list.getSize(); ++ns) {
+ Element & el = send(list(ns));
+ new_send.push_back(el);
+ }
+
+ AKANTU_DEBUG_INFO("I had " << send.getSize() << " elements to send to proc "
+ << p << " and " << list.getSize()
+ << " elements to keep. I have "
+ << new_send.getSize() << " elements left.");
+ send.copy(new_send);
+ }
+
+ comm.waitAll(isend_requests);
+ comm.freeCommunicationRequest(isend_requests);
+
+ delete[] list_of_el;
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void DistributedSynchronizer::renumberElements(
+ const ElementTypeMapArray<UInt> & new_numbering) {
+ // Handling ghost elements
+ for (UInt p = 0; p < nb_proc; ++p) {
+ if (p == rank)
+ continue;
+
+ Array<Element> & recv = recv_element[p];
+
+ for (UInt i = 0; i < recv.getSize(); ++i) {
+ Element & el = recv(i);
+ el.element = new_numbering(el.type, el.ghost_type)(el.element);
+ }
+
+ Array<Element> & send = send_element[p];
+
+ for (UInt i = 0; i < send.getSize(); ++i) {
+ Element & el = send(i);
+ el.element = new_numbering(el.type, el.ghost_type)(el.element);
+ }
+ }
+}
+
__END_AKANTU__
diff --git a/src/synchronizer/distributed_synchronizer.hh b/src/synchronizer/distributed_synchronizer.hh
index 3630c7a70..40620ad0d 100644
--- a/src/synchronizer/distributed_synchronizer.hh
+++ b/src/synchronizer/distributed_synchronizer.hh
@@ -1,271 +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);
+ MemoryID memory_id = 0,
+ const bool register_to_event_manager = true);
public:
virtual ~DistributedSynchronizer();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get a mesh and a partition and create the local mesh and the associated
/// DistributedSynchronizer
- static DistributedSynchronizer *
- createDistributedSynchronizerMesh(Mesh & mesh,
- const MeshPartition * partition,
- UInt root = 0,
- SynchronizerID id = "distributed_synchronizer",
- MemoryID memory_id = 0);
+ 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);
+
/// 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(__attribute__((unused))
+ const Array<UInt> & nodes_list,
+ __attribute__((unused))
+ const NewNodesEvent & event){};
+
+ /// mesh event handler onRemovedNodes
+ 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(__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);
/* ------------------------------------------------------------------------ */
/* 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 381c585f3..236935486 100644
--- a/src/synchronizer/dof_synchronizer.cc
+++ b/src/synchronizer/dof_synchronizer.cc
@@ -1,501 +1,502 @@
/**
* @file dof_synchronizer.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Fri Jun 17 2011
- * @date last modification: Thu Mar 27 2014
+ * @date last modification: Wed Oct 21 2015
*
* @brief DOF synchronizing object implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "dof_synchronizer.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/**
* A DOFSynchronizer needs a mesh and the number of degrees of freedom
* per node to be created. In the constructor computes the local and global dof
* number for each dof. The member
* proc_informations (std vector) is resized with the number of mpi
* processes. Each entry in the vector is a PerProcInformations object
* that contains the interactions of the current mpi process (prank) with the
* mpi process corresponding to the position of that entry. Every
* ProcInformations object contains one array with the dofs that have
* to be sent to prank and a second one with dofs that willl be received form prank.
* This information is needed for the asychronous communications. The
* constructor sets up this information.
* @param mesh mesh discretizing the domain we want to analyze
* @param nb_degree_of_freedom number of degrees of freedom per node
*/
DOFSynchronizer::DOFSynchronizer(const Mesh & mesh, UInt nb_degree_of_freedom) :
global_dof_equation_numbers(0, 1, "global_equation_number"),
local_dof_equation_numbers(0, 1, "local_equation_number"),
dof_global_ids(0, 1, "global_ids"),
dof_types(0, 1, "types") {
gather_scatter_scheme_initialized = false;
prank = static_communicator->whoAmI();
psize = static_communicator->getNbProc();
proc_informations.resize(psize);
UInt nb_nodes = mesh.getNbNodes();
nb_dofs = nb_nodes * nb_degree_of_freedom;
dof_global_ids.resize(nb_dofs);
dof_types.resize(nb_dofs);
nb_global_dofs = mesh.getNbGlobalNodes() * nb_degree_of_freedom;
/// compute the global id for each dof and store the dof type (pure ghost, slave, master or local)
UInt * dof_global_id = dof_global_ids.storage();
Int * dof_type = dof_types.storage();
for(UInt n = 0, ld = 0; n < nb_nodes; ++n) {
UInt node_global_id = mesh.getNodeGlobalId(n);
UInt node_type = mesh.getNodeType(n);
for (UInt d = 0; d < nb_degree_of_freedom; ++d, ++ld) {
*dof_global_id = node_global_id * nb_degree_of_freedom + d;
global_dof_to_local[*dof_global_id] = ld;
*(dof_type++) = node_type;
dof_global_id++;
}
}
if(psize == 1) return;
/// creating communication scheme
dof_global_id = dof_global_ids.storage();
dof_type = dof_types.storage();
for (UInt n = 0; n < nb_dofs; ++n) {
/// check if dof is slave. In that case the value stored in
/// dof_type corresponds to the process that has the corresponding
/// master dof
if(*dof_type >= 0) {
/// has to receive n from proc[*dof_type]
proc_informations[*dof_type].master_dofs.push_back(n);
}
dof_type++;
}
/// at this point the master nodes in PerProcInfo are known
/// exchanging information
for (UInt p = 1; p < psize; ++p) {
UInt sendto = (psize + prank + p) % psize;
UInt recvfrom = (psize + prank - p) % psize;
/// send the master nodes
UInt nb_master_dofs = proc_informations[sendto].master_dofs.getSize();
UInt * master_dofs = proc_informations[sendto].master_dofs.storage();
UInt * send_buffer = new UInt[nb_master_dofs];
for (UInt d = 0; d < nb_master_dofs; ++d) {
send_buffer[d] = dof_global_id[master_dofs[d]];
}
UInt nb_slave_dofs = 0;
UInt * recv_buffer;
std::vector<CommunicationRequest *> requests;
requests.push_back(static_communicator->asyncSend(&nb_master_dofs, 1, sendto, 0));
if(nb_master_dofs != 0) {
- AKANTU_DEBUG(dblInfo, "Sending "<< nb_master_dofs << " dofs to " << sendto + 1);
+ 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 + 1);
+ 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;
+ 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 16f2f9a77..90acb22ef 100644
--- a/src/synchronizer/dof_synchronizer.hh
+++ b/src/synchronizer/dof_synchronizer.hh
@@ -1,237 +1,245 @@
/**
* @file dof_synchronizer.hh
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
* @date creation: Fri Jun 17 2011
- * @date last modification: Fri Mar 21 2014
+ * @date last modification: Tue Dec 08 2015
*
* @brief Synchronize Array of DOFs
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
#include "static_communicator.hh"
#include "synchronizer.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DOF_SYNCHRONIZER_HH__
#define __AKANTU_DOF_SYNCHRONIZER_HH__
__BEGIN_AKANTU__
class Mesh;
template<typename T>
class AddOperation {
public:
inline T operator()(T & b, T & a) { return a + b; };
};
class DOFSynchronizer : public Synchronizer {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DOFSynchronizer(const Mesh & mesh, UInt nb_degree_of_freedom);
virtual ~DOFSynchronizer();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// asynchronous synchronization of ghosts
virtual void asynchronousSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
/// wait end of asynchronous synchronization of ghosts
virtual void waitEndSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
/// compute buffer size for a given tag and data accessor
virtual void computeBufferSize(DataAccessor & data_accessor, SynchronizationTag tag);
/// init the scheme for scatter and gather operation, need extra memory
void initScatterGatherCommunicationScheme();
/// initialize the equation number with local ids
void initLocalDOFEquationNumbers();
/// initialize the equation number with local ids
void initGlobalDOFEquationNumbers();
/**
* Gather the DOF value on the root proccessor
*
* @param to_gather data to gather
* @param root processor on which data are gathered
* @param gathered Array containing the gathered data, only valid on root processor
*/
template<typename T>
+ /// Gather the DOF value on the root proccessor
void gather(const Array<T> & to_gather, UInt root,
Array<T> * gathered = NULL) const;
/**
* Scatter a DOF Array form root to all processors
*
* @param scattered data to scatter, only valid on root processor
* @param root processor scattering data
* @param to_scatter result of scattered data
*/
template<typename T>
+ /// Scatter a DOF Array form root to all processors
void scatter(Array<T> & scattered, UInt root,
const Array<T> * to_scatter = NULL) const;
-
+
template<typename T> void synchronize(Array<T> & vector) const ;
template<template <class> class Op, typename T> void reduceSynchronize(Array<T> & vector) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the equation_number Array
AKANTU_GET_MACRO(LocalDOFEquationNumbers, local_dof_equation_numbers, const Array<Int> &);
AKANTU_GET_MACRO(GlobalDOFEquationNumbers, global_dof_equation_numbers, const Array<Int> &);
Array<Int> * getLocalDOFEquationNumbersPointer(){return &local_dof_equation_numbers;};
Array<Int> * getGlobalDOFEquationNumbersPointer(){return &global_dof_equation_numbers;};
typedef unordered_map<Int, UInt>::type GlobalEquationNumberMap;
AKANTU_GET_MACRO(GlobalEquationNumberToLocal, global_dof_equation_number_to_local, const GlobalEquationNumberMap &)
/// get the Array of global ids of the dofs
AKANTU_GET_MACRO(DOFGlobalIDs, dof_global_ids, const Array<UInt> &);
/// get the global id of a dof
inline UInt getDOFGlobalID(UInt local_id) const {
return dof_global_ids(local_id);
}
/// get the local id of a global dof
inline UInt getDOFLocalID(UInt global_id) const {
return global_dof_to_local.find(global_id)->second;
}
/// get the DOF type Array
AKANTU_GET_MACRO(DOFTypes, dof_types, const Array<Int> &);
AKANTU_GET_MACRO(NbDOFs, nb_dofs, UInt);
AKANTU_GET_MACRO(NbGlobalDOFs, nb_global_dofs, UInt);
/// say if a node is a pure ghost node
inline bool isPureGhostDOF(UInt n) const;
/// say if a node is pure local or master node
inline bool isLocalOrMasterDOF(UInt n) const;
+ /// say if a node is pure local
inline bool isLocalDOF(UInt n) const;
+
+ /// say if a node is a master node
inline bool isMasterDOF(UInt n) const;
+
+ /// say if a node is a slave node
inline bool isSlaveDOF(UInt n) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// equation number position where a dof is synchronized in the matrix (by default = global id)
Array<Int> global_dof_equation_numbers;
Array<Int> local_dof_equation_numbers;
GlobalEquationNumberMap global_dof_equation_number_to_local;
/// DOF global id
Array<UInt> dof_global_ids;
/*
* DOF type -3 pure ghost, -2 master for the dof, -1 normal dof, i in
* [0-N] slave dof and master is proc i
*/
Array<Int> dof_types;
/// number of dofs
UInt nb_dofs;
UInt nb_global_dofs;
unordered_map<UInt, UInt>::type global_dof_to_local;
UInt prank;
UInt psize;
struct PerProcInformations {
/// dofs to send to the proc
Array<UInt> slave_dofs;
/// dofs to recvs from the proc
Array<UInt> master_dofs;
/* ---------------------------------------------------------------------- */
/* Data for gather/scatter */
/* ---------------------------------------------------------------------- */
/// the dof that the node handle
Array<UInt> dofs;
/// the dof that the proc need
Array<UInt> needed_dofs;
};
std::vector<PerProcInformations> proc_informations;
/// nb dofs with type -1 or -2
UInt nb_local_dofs;
/// nb dof with type >= 0
UInt nb_needed_dofs;
bool gather_scatter_scheme_initialized;
std::map<SynchronizationTag, Communication> communications;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "dof_synchronizer_inline_impl.cc"
#endif
/// standard output stream operator
// inline std::ostream & operator <<(std::ostream & stream, const DOFSynchronizer & _this)
// {
// _this.printself(stream);
// return stream;
// }
__END_AKANTU__
#endif /* __AKANTU_DOF_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/dof_synchronizer_inline_impl.cc b/src/synchronizer/dof_synchronizer_inline_impl.cc
index ee040e3b4..0b8a965b1 100644
--- a/src/synchronizer/dof_synchronizer_inline_impl.cc
+++ b/src/synchronizer/dof_synchronizer_inline_impl.cc
@@ -1,315 +1,317 @@
/**
* @file dof_synchronizer_inline_impl.cc
*
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
- * @date last modification: Thu Jun 05 2014
+ * @date last modification: Tue Dec 09 2014
*
* @brief DOFSynchronizer inline implementation
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<typename T> void DOFSynchronizer::gather(const Array<T> & to_gather, UInt root,
Array<T> * gathered) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(gather_scatter_scheme_initialized == true, "You should call initScatterGatherCommunicationScheme before trying to gather a Array !!");
if(psize == 1) {
gathered->copy(to_gather, true);
AKANTU_DEBUG_OUT();
return;
}
UInt * dof_global_id = dof_global_ids.storage();
Int * dof_type = dof_types.storage();
T * to_gather_val = to_gather.storage();
T * buffer;
if(prank == root) {
gathered->resize(nb_global_dofs / gathered->getNbComponent());
buffer = gathered->storage();
} else
buffer = new T[nb_local_dofs];
UInt dof = 0;
for (UInt d = 0; d < nb_dofs; ++d) {
if(*dof_type != -3) {
if(*dof_type == -1 || *dof_type == -2) {
if (prank == root) dof = *dof_global_id;
buffer[dof++] = *to_gather_val;
}
}
dof_type++;
dof_global_id++;
to_gather_val++;
}
if (prank == root) {
for (UInt p = 0; p < psize; ++p) {
if(p == root) continue;
UInt nb_dofs = proc_informations[p].dofs.getSize();
AKANTU_DEBUG_INFO("Gather - Receiving " << nb_dofs << " from " << p);
if(nb_dofs) {
buffer = new T[nb_dofs];
static_communicator->receive(buffer, nb_dofs, p, 0);
T * buffer_tmp = buffer;
UInt * remote_dofs = proc_informations[p].dofs.storage();
for (UInt d = 0; d < nb_dofs; ++d) {
gathered->storage()[*remote_dofs++] = *(buffer_tmp++);
}
delete [] buffer;
}
}
} else {
AKANTU_DEBUG_INFO("Gather - Sending " << nb_local_dofs << " to " << root);
if(nb_local_dofs)
static_communicator->send(buffer, nb_local_dofs, root, 0);
delete [] buffer;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T> void DOFSynchronizer::scatter(Array<T> & scattered, UInt root,
const Array<T> * to_scatter) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(gather_scatter_scheme_initialized == true, "You should call initScatterGatherCommunicationScheme before trying to scatter a Array !!");
if(psize == 1) {
scattered.copy(*to_scatter, true);
AKANTU_DEBUG_OUT();
return;
}
scattered.resize(nb_dofs / scattered.getNbComponent());
UInt * dof_global_id = dof_global_ids.storage();
Int * dof_type = dof_types.storage();
if (prank == root) {
for (UInt p = 0; p < psize; ++p) {
if(p == root) continue;
UInt nb_needed_dof = proc_informations[p].needed_dofs.getSize();
UInt nb_local_dof = proc_informations[p].dofs.getSize();
AKANTU_DEBUG_INFO("Scatter - Sending " << nb_local_dof + nb_needed_dof << " to " << p);
if(nb_local_dof + nb_needed_dof) {
T * send_buffer = new T[nb_local_dof + nb_needed_dof];
T * buffer_tmp = send_buffer;
UInt * remote_dofs = proc_informations[p].dofs.storage();
for (UInt d = 0; d < nb_local_dof; ++d) {
*(buffer_tmp++) = to_scatter->storage()[*remote_dofs++];
}
remote_dofs = proc_informations[p].needed_dofs.storage();
for (UInt d = 0; d < nb_needed_dof; ++d) {
*(buffer_tmp++) = to_scatter->storage()[*remote_dofs++];
}
static_communicator->send(send_buffer, nb_local_dof + nb_needed_dof, p, 0);
delete [] send_buffer;
}
}
T * scattered_val = scattered.storage();
for (UInt d = 0; d < nb_dofs; ++d) {
if(*dof_type != -3) {
if(*dof_type >= -2)
*scattered_val = to_scatter->storage()[*dof_global_id];
}
scattered_val++;
dof_type++;
dof_global_id++;
}
} else {
T * buffer;
AKANTU_DEBUG_INFO("Scatter - Receiving " << nb_dofs << " from " << root);
if(nb_local_dofs + nb_needed_dofs) {
buffer = new T[nb_local_dofs + nb_needed_dofs];
static_communicator->receive(buffer, nb_local_dofs + nb_needed_dofs, root, 0);
T * scattered_val = scattered.storage();
UInt local_dofs = 0;
UInt needed_dofs = nb_local_dofs;
for (UInt d = 0; d < nb_dofs; ++d) {
if(*dof_type != -3) {
if(*dof_type == -1 || *dof_type == -2)
*scattered_val = buffer[local_dofs++];
else if(*dof_type >= 0)
*scattered_val = buffer[needed_dofs++];
}
scattered_val++;
dof_type++;
}
delete [] buffer;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T> void DOFSynchronizer::synchronize(Array<T> & dof_vector) const {
AKANTU_DEBUG_IN();
if(psize == 1) {
AKANTU_DEBUG_OUT();
return;
}
for (UInt p = 1; p < psize; ++p) {
UInt sendto = (psize + prank + p) % psize;
UInt recvfrom = (psize + prank - p) % psize;
UInt nb_slave_dofs = proc_informations[sendto].slave_dofs.getSize();
UInt * slave_dofs = proc_informations[sendto].slave_dofs.storage();
UInt nb_master_dofs = proc_informations[recvfrom].master_dofs.getSize();
UInt * master_dofs = proc_informations[recvfrom].master_dofs.storage();
T * send_buffer = new T[nb_slave_dofs];
T * recv_buffer = new T[nb_master_dofs];
for (UInt d = 0; d < nb_slave_dofs; ++d) {
AKANTU_DEBUG_ASSERT(dof_types(slave_dofs[d]) == -2,
"Sending node " << slave_dofs[d]
<< "(gid" << dof_global_ids(d) << ") to proc "
<< sendto << " but it is not a master node.");
send_buffer[d] = dof_vector.storage()[slave_dofs[d]];
}
/// ring blocking communications
CommunicationRequest * request = NULL;
if(nb_slave_dofs != 0) request = static_communicator->asyncSend(send_buffer, nb_slave_dofs, sendto , 0);
if(nb_master_dofs != 0) static_communicator->receive(recv_buffer, nb_master_dofs, recvfrom, 0);
for (UInt d = 0; d < nb_master_dofs; ++d) {
AKANTU_DEBUG_ASSERT(dof_types(master_dofs[d]) >= 0,
"Received node " << master_dofs[d]
<< "(gid" << dof_global_ids(d) << ") from proc "
<< recvfrom << " but it is not a slave node.");
dof_vector.storage()[master_dofs[d]] = recv_buffer[d];
}
if(nb_slave_dofs != 0) {
static_communicator->wait(request);
static_communicator->freeCommunicationRequest(request);
}
delete [] send_buffer;
delete [] recv_buffer;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <class> class Op, typename T> void DOFSynchronizer::reduceSynchronize(Array<T> & dof_vector) const {
AKANTU_DEBUG_IN();
if(psize == 1) {
AKANTU_DEBUG_OUT();
return;
}
for (UInt p = 1; p < psize; ++p) {
UInt sendto = (psize + prank + p) % psize;
UInt recvfrom = (psize + prank - p) % psize;
UInt nb_slave_dofs = proc_informations[recvfrom].slave_dofs.getSize();
UInt * slave_dofs = proc_informations[recvfrom].slave_dofs.storage();
UInt nb_master_dofs = proc_informations[sendto].master_dofs.getSize();
UInt * master_dofs = proc_informations[sendto].master_dofs.storage();
T * send_buffer = new T[nb_master_dofs];
T * recv_buffer = new T[nb_slave_dofs];
for (UInt d = 0; d < nb_master_dofs; ++d) {
send_buffer[d] = dof_vector.storage()[master_dofs[d]];
}
CommunicationRequest * request = NULL;
if(nb_master_dofs != 0) request = static_communicator->asyncSend(send_buffer, nb_master_dofs, sendto , 0);
if(nb_slave_dofs != 0) static_communicator->receive(recv_buffer, nb_slave_dofs, recvfrom, 0);
Op<T> oper;
for (UInt d = 0; d < nb_slave_dofs; ++d) {
dof_vector.storage()[slave_dofs[d]] = oper(dof_vector.storage()[slave_dofs[d]], recv_buffer[d]);
}
if(nb_master_dofs != 0) {
static_communicator->wait(request);
static_communicator->freeCommunicationRequest(request);
}
delete [] send_buffer;
delete [] recv_buffer;
}
synchronize(dof_vector);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isPureGhostDOF(UInt n) const {
return dof_types.getSize() ? (dof_types(n) == -3) : false;
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isLocalOrMasterDOF(UInt n) const {
return dof_types.getSize() ? (dof_types(n) == -2) || (dof_types(n) == -1) : true;
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isLocalDOF(UInt n) const {
return dof_types.getSize() ? dof_types(n) == -1 : true;
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isMasterDOF(UInt n) const {
return dof_types.getSize() ? dof_types(n) == -2 : false;
}
/* -------------------------------------------------------------------------- */
inline bool DOFSynchronizer::isSlaveDOF(UInt n) const {
return dof_types.getSize() ? dof_types(n) >= 0 : false;
}
diff --git a/src/synchronizer/filtered_synchronizer.cc b/src/synchronizer/filtered_synchronizer.cc
index d1aa14f17..eaa672422 100644
--- a/src/synchronizer/filtered_synchronizer.cc
+++ b/src/synchronizer/filtered_synchronizer.cc
@@ -1,197 +1,197 @@
/**
* @file filtered_synchronizer.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Mathilde Radiguet <mathilde.radiguet@epfl.ch>
*
* @date creation: Wed Sep 18 2013
- * @date last modification: Mon Aug 25 2014
+ * @date last modification: Sat Jul 11 2015
*
* @brief filtered synchronizer
*
* @section LICENSE
*
- * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "filtered_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
FilteredSynchronizer::FilteredSynchronizer(Mesh & mesh,
SynchronizerID id,
MemoryID memory_id) :
DistributedSynchronizer(mesh, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
FilteredSynchronizer * FilteredSynchronizer::
createFilteredSynchronizer(const DistributedSynchronizer & d_synchronizer,
SynchElementFilter & filter) {
AKANTU_DEBUG_IN();
FilteredSynchronizer & f_synchronizer =
*(new FilteredSynchronizer(d_synchronizer.mesh,
d_synchronizer.id + ":filtered",
d_synchronizer.memory_id));
f_synchronizer.setupSynchronizer(d_synchronizer,
filter);
AKANTU_DEBUG_OUT();
return &f_synchronizer;
}
/* -------------------------------------------------------------------------- */
void FilteredSynchronizer::setupSynchronizer(const DistributedSynchronizer & d_synchronizer,
SynchElementFilter & filter) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Array<Element> * d_send_element = d_synchronizer.send_element;
Array<Element> * d_recv_element = d_synchronizer.recv_element;
std::vector<CommunicationRequest *> isend_requests;
Array<UInt> ** keep_element_recv = new Array<UInt>*[this->nb_proc];
// loop over procs
for (UInt p = 0; p < this->nb_proc; ++p) {
keep_element_recv[p] = NULL;
if (p == this->rank) continue;
// access the element for this proc
const Array<Element> & unfiltered_elements = d_recv_element[p];
Array<Element> & filtered_elements = recv_element[p];
if (unfiltered_elements.getSize() == 0) continue;
keep_element_recv[p] = new Array<UInt>(0,1,"keep_element_recv");
// iterator to loop over all source elements
Array<Element>::const_iterator<Element> it = unfiltered_elements.begin();
Array<Element>::const_iterator<Element> end = unfiltered_elements.end();
// if filter accepts this element, push it into the destination elements
for (UInt el=0; it != end; ++it, ++el) {
const Element & element = *it;
if (filter(element)) {
filtered_elements.push_back(element);
keep_element_recv[p]->push_back(el);
}
}
keep_element_recv[p]->push_back(-1); // just to be sure to send
// something due to some shitty
// MPI implementation who do not
// know what to do with a 0 size
// send
AKANTU_DEBUG_INFO("I have " << keep_element_recv[p]->getSize() - 1
<< " elements to still receive from processor " << p
<< " (communication tag : "
<< Tag::genTag(this->rank, 0, RECEIVE_LIST_TAG) << ")");
isend_requests.push_back(comm.asyncSend<UInt>(keep_element_recv[p]->storage(),
keep_element_recv[p]->getSize(),
p,
Tag::genTag(this->rank, 0, RECEIVE_LIST_TAG)));
}
for (UInt p = 0; p < this->nb_proc; ++p) {
if (p == this->rank) continue;
const Array<Element> & unfiltered_elements = d_send_element[p];
Array<Element> & filtered_elements = send_element[p];
if (unfiltered_elements.getSize() == 0) continue;
AKANTU_DEBUG_INFO("Waiting list of elements to keep from processor " << p
<< " (communication tag : "
<< Tag::genTag(p, 0, RECEIVE_LIST_TAG) << ")");
CommunicationStatus status;
comm.probe<UInt>(p, Tag::genTag(p, 0, RECEIVE_LIST_TAG), status);
Array<UInt> keep_element(status.getSize(),1,"keep_element_snd");
AKANTU_DEBUG_INFO("I have " << keep_element.getSize() - 1
<< " elements to keep in my send list to processor " << p
<< " (communication tag : "
<< Tag::genTag(p, 0, RECEIVE_LIST_TAG) << ")");
comm.receive(keep_element.storage(),
keep_element.getSize(),
p,
Tag::genTag(p, 0, RECEIVE_LIST_TAG));
for(UInt i = 0; i < keep_element.getSize() - 1; ++i) {
filtered_elements.push_back(unfiltered_elements(keep_element(i)));
}
}
comm.waitAll(isend_requests);
comm.freeCommunicationRequest(isend_requests);
for (UInt p=0; p < this->nb_proc; ++p) {
delete keep_element_recv[p];
}
delete [] keep_element_recv;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FilteredSynchronizer::updateElementList(Array<Element> * source_elements,
Array<Element> * destination_elements,
SynchElementFilter & filter) {
AKANTU_DEBUG_IN();
// loop over procs
for (UInt p = 0; p < this->nb_proc; ++p) {
if (p == this->rank) continue;
// access the element for this proc
const Array<Element> & unfiltered_elements = source_elements[p];
Array<Element> & filtered_elements = destination_elements[p];
// iterator to loop over all source elements
Array<Element>::const_iterator<Element> it = unfiltered_elements.begin();
Array<Element>::const_iterator<Element> end = unfiltered_elements.end();
// if filter accepts this element, push it into the destination elements
for (; it != end; ++it) {
const Element & element = *it;
if (filter(element)) {
filtered_elements.push_back(element);
}
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/synchronizer/filtered_synchronizer.hh b/src/synchronizer/filtered_synchronizer.hh
index c4a4d85de..992a1dc10 100644
--- a/src/synchronizer/filtered_synchronizer.hh
+++ b/src/synchronizer/filtered_synchronizer.hh
@@ -1,98 +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
+ /// 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 250f39152..1951b3517 100644
--- a/src/synchronizer/grid_synchronizer.cc
+++ b/src/synchronizer/grid_synchronizer.cc
@@ -1,544 +1,594 @@
/**
* @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,
- MemoryID memory_id) :
- DistributedSynchronizer(mesh, id, memory_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) {
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) {
+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));
- 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;
+ std::stringstream sstr;
+ sstr << "element_per_proc_" << p;
element_per_proc[p] = new ElementTypeMapArray<UInt>(sstr.str(), id);
ElementTypeMapArray<UInt> & elempproc = *(element_per_proc[p]);
typename std::set<Element>::iterator elem = to_send->begin();
typename std::set<Element>::iterator last_elem = to_send->end();
for (; elem != last_elem; ++elem) {
ElementType type = elem->type;
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
- // /!\ this part must be slow due to the access in the ElementTypeMapArray<UInt>
- if(!elempproc.exists(type, _not_ghost))
+ // /!\ 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<QuadraturePoint>(Mesh & mesh,
- const SpatialGrid<QuadraturePoint> & grid,
- SynchronizerID id,
- SynchronizerRegistry * synchronizer_registry,
- const std::set<SynchronizationTag> & tags_to_register,
- MemoryID memory_id);
-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);
+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 059309fbe..11e1bba58 100644
--- a/src/synchronizer/grid_synchronizer.hh
+++ b/src/synchronizer/grid_synchronizer.hh
@@ -1,95 +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);
+ 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);
+ 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 7469b8be6..21b83205e 100644
--- a/src/synchronizer/mpi_type_wrapper.hh
+++ b/src/synchronizer/mpi_type_wrapper.hh
@@ -1,98 +1,99 @@
/**
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_MPI
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
# if __cplusplus > 199711L
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wliteral-suffix"
# endif
#endif
# include <mpi.h>
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
# if __cplusplus > 199711L
# pragma GCC diagnostic pop
# endif
#endif
#endif
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "static_communicator_mpi.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MPI_TYPE_WRAPPER_HH__
#define __AKANTU_MPI_TYPE_WRAPPER_HH__
__BEGIN_AKANTU__
class MPITypeWrapper {
public:
MPITypeWrapper(StaticCommunicatorMPI & static_comm) : static_comm(static_comm) {
}
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 ee06e11af..d703386e4 100644
--- a/src/synchronizer/real_static_communicator.hh
+++ b/src/synchronizer/real_static_communicator.hh
@@ -1,98 +1,109 @@
/**
* @file real_static_communicator.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
- * @date creation: Thu Apr 14 2011
- * @date last modification: Tue Nov 06 2012
+ * @date creation: Mon Jun 14 2010
+ * @date last modification: Wed Jan 13 2016
*
* @brief empty class just for inheritance
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_REAL_STATIC_COMMUNICATOR_HH__
#define __AKANTU_REAL_STATIC_COMMUNICATOR_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
class CommunicationRequest {
public:
CommunicationRequest(UInt source, UInt dest);
virtual ~CommunicationRequest();
virtual void printself(std::ostream & stream, int indent = 0) const;
AKANTU_GET_MACRO(Source, source, UInt);
AKANTU_GET_MACRO(Destination, destination, UInt);
private:
UInt source;
UInt destination;
UInt id;
static UInt counter;
};
/* -------------------------------------------------------------------------- */
class CommunicationStatus {
public:
CommunicationStatus() : source(0), size(0), tag(0) {};
AKANTU_GET_MACRO(Source, source, Int);
AKANTU_GET_MACRO(Size, size, UInt);
AKANTU_GET_MACRO(Tag, tag, Int);
AKANTU_SET_MACRO(Source, source, Int);
AKANTU_SET_MACRO(Size, size, UInt);
AKANTU_SET_MACRO(Tag, tag, Int);
private:
Int source;
UInt size;
Int tag;
};
+/* -------------------------------------------------------------------------- */
+/// Datatype to pack pairs for MPI_{MIN,MAX}LOC
+template<typename T1, typename T2>
+struct SCMinMaxLoc {
+ T1 min_max;
+ T2 loc;
+};
+
+/* -------------------------------------------------------------------------- */
+
class StaticCommunicator;
/* -------------------------------------------------------------------------- */
class RealStaticCommunicator {
public:
RealStaticCommunicator(__attribute__ ((unused)) int & argc,
__attribute__ ((unused)) char ** & argv) {
prank = -1;
psize = -1;
};
virtual ~RealStaticCommunicator() { };
friend class StaticCommunicator;
protected:
Int prank;
Int psize;
};
__END_AKANTU__
#endif /* __AKANTU_REAL_STATIC_COMMUNICATOR_HH__ */
diff --git a/src/synchronizer/static_communicator.cc b/src/synchronizer/static_communicator.cc
index f6e3c2e09..a9f1ad009 100644
--- a/src/synchronizer/static_communicator.cc
+++ b/src/synchronizer/static_communicator.cc
@@ -1,115 +1,125 @@
/**
* @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
}
/* -------------------------------------------------------------------------- */
-StaticCommunicator & StaticCommunicator::getStaticCommunicator(CommunicatorType type) {
+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) {
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);
}
__END_AKANTU__
diff --git a/src/synchronizer/static_communicator.hh b/src/synchronizer/static_communicator.hh
index e7f3cc5cc..b27f3b886 100644
--- a/src/synchronizer/static_communicator.hh
+++ b/src/synchronizer/static_communicator.hh
@@ -1,268 +1,277 @@
/**
* @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_array.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;
- };
+ virtual ~StaticCommunicator();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/* ------------------------------------------------------------------------ */
/* Point to Point */
/* ------------------------------------------------------------------------ */
- template<typename T> inline void send(Array<T> & values,
- Int receiver, Int tag) {
- return this->send(values.storage(), values.getSize(),
- receiver, tag);
+ template <typename T>
+ inline void send(Array<T> & values, Int receiver, Int tag) {
+ return this->send(values.storage(), values.getSize(), receiver, tag);
}
- template<typename T> inline void send(T * buffer, Int size,
- Int receiver, Int tag);
+ template <typename T>
+ inline void send(T * buffer, Int size, Int receiver, Int tag);
/* ------------------------------------------------------------------------ */
- template<typename T> inline void receive(Array<T> & values,
- Int sender, Int tag) {
- return this->receive(values.storage(), values.getSize(),
- sender, tag);
+ template <typename T>
+ inline void receive(Array<T> & values, Int sender, Int tag) {
+ return this->receive(values.storage(), values.getSize(), sender, tag);
}
- template<typename T> inline void receive(T * buffer, Int size,
- Int sender, Int tag);
+ template <typename T>
+ inline void receive(T * buffer, Int size, Int sender, Int tag);
/* ------------------------------------------------------------------------ */
- template<typename T> inline CommunicationRequest * asyncSend(Array<T> & values,
- Int receiver,
- Int tag) {
- return this->asyncSend(values.storage(), values.getSize(),
- receiver, tag);
+ template <typename T>
+ inline CommunicationRequest * asyncSend(Array<T> & values, Int receiver,
+ Int tag) {
+ return this->asyncSend(values.storage(), values.getSize(), receiver, tag);
}
- template<typename T> inline CommunicationRequest * asyncSend(T * buffer,
- Int size,
- Int receiver,
- Int tag);
+ template <typename T>
+ inline CommunicationRequest * asyncSend(T * buffer, Int size, Int receiver,
+ Int tag);
/* ------------------------------------------------------------------------ */
- template<typename T> inline CommunicationRequest * asyncReceive(Array<T> & values,
- Int sender,
- Int tag) {
- return this->asyncReceive(values.storage(), values.getSize(),
- sender, tag);
+ template <typename T>
+ inline CommunicationRequest * asyncReceive(Array<T> & values, Int sender,
+ Int tag) {
+ return this->asyncReceive(values.storage(), values.getSize(), sender, tag);
}
- template<typename T> inline CommunicationRequest * asyncReceive(T * buffer,
- Int size,
- Int sender,
- 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 probe(Int sender, Int tag, CommunicationStatus & status);
/* ------------------------------------------------------------------------ */
/* Collectives */
/* ------------------------------------------------------------------------ */
- template<typename T> inline void allReduce(Array<T> & values,
- const SynchronizerOperation & op) {
+ template <typename T>
+ inline void allReduce(Array<T> & values, const SynchronizerOperation & op) {
this->allReduce(values.storage(), values.getSize(), op);
}
- template<typename T> inline void allReduce(T * values, int nb_values,
- const SynchronizerOperation & op);
+ template <typename T>
+ inline void allReduce(T * values, int nb_values,
+ const SynchronizerOperation & op);
/* ------------------------------------------------------------------------ */
- template<typename T> inline void allGather(Array<T> & values) {
+ template <typename T> inline void allGather(Array<T> & values) {
this->allGather(values.storage(), values.getSize());
}
- template<typename T> inline void allGather(T * values, int nb_values);
+ template <typename T> inline void allGather(T * values, int nb_values);
/* ------------------------------------------------------------------------ */
- template<typename T> inline void allGatherV(Array<T> & values) {
+ template <typename T> inline void allGatherV(Array<T> & values) {
this->allGatherV(values.storage(), values.getSize());
}
- template<typename T> inline void allGatherV(T * values, int * nb_values);
+ template <typename T> inline void allGatherV(T * values, int * nb_values);
/* ------------------------------------------------------------------------ */
- template<typename T> inline void gather(Array<T> & values,
- int root = 0) {
+ template <typename T>
+ inline void reduce(Array<T> & values, const SynchronizerOperation & op,
+ int root = 0) {
+ this->reduce(values.storage(), values.getSize(), op, root);
+ }
+
+ template <typename T>
+ inline void reduce(T * values, int nb_values,
+ const SynchronizerOperation & op, int root = 0);
+
+ /* ------------------------------------------------------------------------ */
+ template <typename T> inline void gather(Array<T> & values, int root = 0) {
this->gather(values.storage(), values.getSize(), root);
}
- template<typename T> inline void gather(T * values, int nb_values,
- int root = 0);
+ template <typename T>
+ inline void gather(T * values, int nb_values, int root = 0);
/* ------------------------------------------------------------------------ */
- template<typename T> inline void gatherV(Array<T> & values,
- int root = 0) {
- this->gatherV(values.storage(), values.getSize(), root);
+ template <typename T> inline void gatherV(Array<T> & values, int root = 0) {
+ this->gatherV(values.storage(), values.getSize(), root);
}
- template<typename T> inline void gatherV(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(Array<T> & values,
- int root = 0) {
+ template <typename T> inline void broadcast(Array<T> & values, int root = 0) {
this->broadcast(values.storage(), values.getSize(), root);
}
- template<typename T> inline void broadcast(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 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 0dd56ead5..7820e74ca 100644
--- a/src/synchronizer/static_communicator_dummy.hh
+++ b/src/synchronizer/static_communicator_dummy.hh
@@ -1,151 +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) {
+ StaticCommunicatorDummy(__attribute__((unused)) int & argc,
+ __attribute__((unused)) char **& argv)
+ : RealStaticCommunicator(argc, argv) {
prank = 0;
psize = 1;
};
- virtual ~StaticCommunicatorDummy() {};
+ 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) {
+ 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) {
+ 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) {
- }
+ 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; };
+ bool testRequest(__attribute__((unused)) CommunicationRequest * request) {
+ return true;
+ };
+ void wait(__attribute__((unused)) CommunicationRequest * request){};
- void wait(__attribute__ ((unused)) CommunicationRequest * request) {};
+ void waitAll(__attribute__((unused))
+ std::vector<CommunicationRequest *> & requests){};
- void waitAll(__attribute__ ((unused)) std::vector<CommunicationRequest *> & requests) {};
+ void barrier(){};
- 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>
+ void allReduce(__attribute__((unused)) T * values,
+ __attribute__((unused)) int nb_values,
+ __attribute__((unused)) const SynchronizerOperation & op) {}
- template<typename T>
- inline void allGatherV(__attribute__ ((unused)) T * values,
- __attribute__ ((unused)) int * nb_values) {}
+ 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 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 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) {}
+ template <typename T>
+ inline void broadcast(__attribute__((unused)) T * values,
+ __attribute__((unused)) int nb_values,
+ __attribute__((unused)) int root = 0) {}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
+ /* ------------------------------------------------------------------------ */
+ int getMaxTag() { return std::numeric_limits<int>::max(); }
+ int getMinTag() { return 0; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
};
__END_AKANTU__
#endif /* __AKANTU_STATIC_COMMUNICATOR_DUMMY_HH__ */
diff --git a/src/synchronizer/static_communicator_inline_impl.hh b/src/synchronizer/static_communicator_inline_impl.hh
index 23d8b7c46..44af178db 100644
--- a/src/synchronizer/static_communicator_inline_impl.hh
+++ b/src/synchronizer/static_communicator_inline_impl.hh
@@ -1,160 +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 04d6ca23d..2c2d6cbaa 100644
--- a/src/synchronizer/static_communicator_mpi.cc
+++ b/src/synchronizer/static_communicator_mpi.cc
@@ -1,428 +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_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) {
- if(argc != 0) {
+ int is_initialized = false;
+ MPI_Initialized(&is_initialized);
+ if (!is_initialized) {
MPI_Init(&argc, &argv);
}
+ this->is_externaly_initialized = is_initialized;
+
mpi_data = new MPITypeWrapper(*this);
mpi_data->setMPICommunicator(MPI_COMM_WORLD);
}
/* -------------------------------------------------------------------------- */
StaticCommunicatorMPI::~StaticCommunicatorMPI() {
- 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) {
+ MPI_Comm communicator = mpi_data->getMPICommunicator();
+ MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>();
+
+#if !defined(AKANTU_NDEBUG)
+ int ret =
+#endif
+ MPI_Reduce(MPI_IN_PLACE, values, nb_values, type,
+ MPITypeWrapper::getMPISynchronizerOperation(op), root,
+ communicator);
+ AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Allreduce.");
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
void StaticCommunicatorMPI::allReduce(T * values, int nb_values,
- const SynchronizerOperation & op) {
+ 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::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> >() {
+ return MPI_DOUBLE_INT;
+}
+
+template <>
+MPI_Datatype MPITypeWrapper::getMPIDatatype<SCMinMaxLoc<float, int> >() {
+ return MPI_FLOAT_INT;
+}
+
/* -------------------------------------------------------------------------- */
/* Template instantiation */
/* -------------------------------------------------------------------------- */
-#define AKANTU_MPI_COMM_INSTANTIATE(T) \
- template void StaticCommunicatorMPI::send<T> (T * buffer, Int size, Int receiver, Int tag); \
- template void StaticCommunicatorMPI::receive<T>(T * buffer, Int size, Int sender, Int tag); \
- template CommunicationRequest * StaticCommunicatorMPI::asyncSend<T> (T * buffer, Int size, Int receiver, Int tag); \
- template CommunicationRequest * StaticCommunicatorMPI::asyncReceive<T>(T * buffer, Int size, Int sender, Int tag); \
- template void StaticCommunicatorMPI::probe<T>(Int sender, Int tag, CommunicationStatus & status); \
- template void StaticCommunicatorMPI::allGather<T> (T * values, int nb_values); \
- template void StaticCommunicatorMPI::allGatherV<T>(T * values, int * nb_values); \
- template void StaticCommunicatorMPI::gather<T> (T * values, int nb_values, int root); \
- template void StaticCommunicatorMPI::gatherV<T>(T * values, int * nb_values, int root); \
- template void StaticCommunicatorMPI::broadcast<T>(T * values, int nb_values, int root); \
- template void StaticCommunicatorMPI::allReduce<T>(T * values, int nb_values, const SynchronizerOperation & op);
-
+#define AKANTU_MPI_COMM_INSTANTIATE(T) \
+ template void StaticCommunicatorMPI::send<T>(T * buffer, Int size, \
+ Int receiver, Int tag); \
+ template void StaticCommunicatorMPI::receive<T>(T * buffer, Int size, \
+ Int sender, Int tag); \
+ template CommunicationRequest * StaticCommunicatorMPI::asyncSend<T>( \
+ T * buffer, Int size, Int receiver, Int tag); \
+ template CommunicationRequest * StaticCommunicatorMPI::asyncReceive<T>( \
+ T * buffer, Int size, Int sender, Int tag); \
+ template void StaticCommunicatorMPI::probe<T>(Int sender, Int tag, \
+ CommunicationStatus & status); \
+ template void StaticCommunicatorMPI::allGather<T>(T * values, \
+ int nb_values); \
+ template void StaticCommunicatorMPI::allGatherV<T>(T * values, \
+ int * nb_values); \
+ template void StaticCommunicatorMPI::gather<T>(T * values, int nb_values, \
+ int root); \
+ template void StaticCommunicatorMPI::gatherV<T>(T * values, int * nb_values, \
+ int root); \
+ template void StaticCommunicatorMPI::broadcast<T>(T * values, int nb_values, \
+ int root); \
+ template void StaticCommunicatorMPI::allReduce<T>( \
+ T * values, int nb_values, const SynchronizerOperation & op)
AKANTU_MPI_COMM_INSTANTIATE(Real);
AKANTU_MPI_COMM_INSTANTIATE(UInt);
AKANTU_MPI_COMM_INSTANTIATE(Int);
AKANTU_MPI_COMM_INSTANTIATE(char);
+
+template void StaticCommunicatorMPI::send<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * buffer, Int size, Int receiver, Int tag);
+template void StaticCommunicatorMPI::receive<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * buffer, Int size, Int sender, Int tag);
+template CommunicationRequest *
+StaticCommunicatorMPI::asyncSend<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * buffer, Int size, Int receiver, Int tag);
+template CommunicationRequest *
+StaticCommunicatorMPI::asyncReceive<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * buffer, Int size, Int sender, Int tag);
+template void StaticCommunicatorMPI::probe<SCMinMaxLoc<Real, int> >(
+ Int sender, Int tag, CommunicationStatus & status);
+template void StaticCommunicatorMPI::allGather<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * values, int nb_values);
+template void StaticCommunicatorMPI::allGatherV<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * values, int * nb_values);
+template void StaticCommunicatorMPI::gather<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * values, int nb_values, int root);
+template void StaticCommunicatorMPI::gatherV<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * values, int * nb_values, int root);
+template void StaticCommunicatorMPI::broadcast<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * values, int nb_values, int root);
+template void StaticCommunicatorMPI::allReduce<SCMinMaxLoc<Real, int> >(
+ SCMinMaxLoc<Real, int> * values, int nb_values,
+ const SynchronizerOperation & op);
+
#if AKANTU_INTEGER_SIZE > 4
AKANTU_MPI_COMM_INSTANTIATE(int);
#endif
__END_AKANTU__
diff --git a/src/synchronizer/static_communicator_mpi.hh b/src/synchronizer/static_communicator_mpi.hh
index bfce96da7..27a863f55 100644
--- a/src/synchronizer/static_communicator_mpi.hh
+++ b/src/synchronizer/static_communicator_mpi.hh
@@ -1,122 +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 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();
+
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 bcd018f79..905681e0d 100644
--- a/src/synchronizer/synchronizer.cc
+++ b/src/synchronizer/synchronizer.cc
@@ -1,57 +1,58 @@
/**
* @file synchronizer.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Sep 01 2010
- * @date last modification: Wed Nov 13 2013
+ * @date last modification: Tue Dec 09 2014
*
* @brief implementation of the common part
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
Synchronizer::Synchronizer(SynchronizerID id, MemoryID memory_id) :
Memory(id, memory_id),
static_communicator(&StaticCommunicator::getStaticCommunicator()) {
}
/* -------------------------------------------------------------------------- */
void Synchronizer::synchronize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
asynchronousSynchronize(data_accessor,tag);
waitEndSynchronize(data_accessor,tag);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/synchronizer/synchronizer.hh b/src/synchronizer/synchronizer.hh
index 46c01892b..769105630 100644
--- a/src/synchronizer/synchronizer.hh
+++ b/src/synchronizer/synchronizer.hh
@@ -1,163 +1,174 @@
/**
* @file synchronizer.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
*
- * @date creation: Wed Sep 01 2010
- * @date last modification: Tue Apr 30 2013
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Thu Dec 10 2015
*
- * @brief interface for communicator and pbc synchronizers
+ * @brief Common interface for synchronizers
*
* @section LICENSE
*
- * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
- * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SYNCHRONIZER_HH__
#define __AKANTU_SYNCHRONIZER_HH__
/* -------------------------------------------------------------------------- */
#include "aka_memory.hh"
#include "data_accessor.hh"
#include "real_static_communicator.hh"
#include "static_communicator.hh"
/* -------------------------------------------------------------------------- */
#include <map>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class Synchronizer : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
-
Synchronizer(SynchronizerID id = "synchronizer", MemoryID memory_id = 0);
- virtual ~Synchronizer() { };
+ virtual ~Synchronizer(){};
virtual void printself(__attribute__((unused)) std::ostream & stream,
- __attribute__((unused)) int indent = 0) const {};
+ __attribute__((unused)) int indent = 0) const {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// synchronize ghosts
- void synchronize(DataAccessor & data_accessor,SynchronizationTag tag);
+ void synchronize(DataAccessor & data_accessor, SynchronizationTag tag);
/// asynchronous synchronization of ghosts
- virtual void asynchronousSynchronize(DataAccessor & data_accessor,SynchronizationTag tag) = 0;
+ 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;
+ 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;
+ virtual void computeBufferSize(DataAccessor & data_accessor,
+ SynchronizationTag tag) = 0;
/**
* tag = |__________20_________|___8____|_4_|
* | proc | num mes| ct|
*/
class Tag {
public:
- operator int() { return int(tag); }
+ Tag() : tag(0) {}
+ Tag(int val) : tag(val) {}
+
+ operator int() { return int(tag); } // remove the sign bit
- template<typename CommTag>
+ template <typename CommTag>
static inline Tag genTag(int proc, UInt msg_count, CommTag tag) {
- Tag t;
- t.tag = (((proc & 0xFFFFF) << 12) + ((msg_count & 0xFF) << 4) + ((Int)tag & 0xF));
+ 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 {
+ __attribute__((unused)) int indent = 0) const {
stream << (tag >> 12) << ":" << (tag >> 4 & 0xFF) << ":" << (tag & 0xF);
}
+
private:
- UInt tag;
+ int tag;
};
-protected:
+ /// 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_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<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)
-{
+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)
-{
+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 c6761b73c..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);
+ (*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 5ca640c77..8f0da7ceb 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,87 +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 134a7fbf1..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
- DEPENDENCIES test_grid_mesh
+ 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 2516ffeb7..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
- DEPENDENCIES 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
- DEPENDENCIES 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
- DEPENDENCIES 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
- DEPENDENCIES 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
- DEPENDENCIES 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
- DEPENDENCIES 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
- DEPENDENCIES 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
- DEPENDENCIES 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
- DEPENDENCIES 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 10271d187..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
- DEPENDENCIES test_boundary_msh test_boundary_msh_physical_names
+ DEPENDS test_boundary_msh test_boundary_msh_physical_names
PACKAGE core)
register_test(test_facet_element_mapping
SOURCES test_facet_element_mapping.cc
- DEPENDENCIES test_boundary_msh_physical_names
+ 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_fe_engine_precomputation_pentahedron_6.verified b/test/test_fe_engine/test_fe_engine_precomputation_pentahedron_6.verified
index 38d06a919..71e57878d 100644
--- a/test/test_fe_engine/test_fe_engine_precomputation_pentahedron_6.verified
+++ b/test/test_fe_engine/test_fe_engine_precomputation_pentahedron_6.verified
@@ -1,89 +1,89 @@
FEEngineTemplate [
+ parent [
FEEngine [
+ id : my_fem
+ element dimension : 3
+ mesh [
Mesh [
+ id : mesh
+ spatial dimension : 3
+ nodes [
Array<double> [
+ id : mesh:coordinates
+ size : 75
+ nb_component : 3
+ allocated size : 2000
+ memory size : 46.88KiByte
+ values : {{0, 0, -1}, {1, 0, -1}, {0, 1, -1}, {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {0.5, 0, -1}, {0, 0.5, -1}, {0, 0, 0}, {0.5, 0.5, -1}, {1, 0, 0}, {0, 1, 0}, {0.5, 0, 1}, {0, 0.5, 1}, {0.5, 0.5, 1}, {0.5, 0, 0}, {0, 0.5, 0}, {0.5, 0.5, 0}, {0.25, 0, -1}, {0, 0.25, -1}, {0, 0, -0.5}, {0.25, 0.25, -1}, {0.5, 0, -0.5}, {0, 0.5, -0.5}, {0.25, 0, 0}, {0, 0.25, 0}, {0.25, 0.25, 0}, {0.25, 0, -0.5}, {0, 0.25, -0.5}, {0.25, 0.25, -0.5}, {0, 0, 0.5}, {0.5, 0, 0.5}, {0, 0.5, 0.5}, {0.25, 0, 1}, {0, 0.25, 1}, {0.25, 0.25, 1}, {0.25, 0, 0.5}, {0, 0.25, 0.5}, {0.25, 0.25, 0.5}, {0.75, 0, -1}, {0.5, 0.25, -1}, {0.75, 0.25, -1}, {1, 0, -0.5}, {0.5, 0.5, -0.5}, {0.75, 0, 0}, {0.5, 0.25, 0}, {0.75, 0.25, 0}, {0.75, 0, -0.5}, {0.5, 0.25, -0.5}, {0.75, 0.25, -0.5}, {1, 0, 0.5}, {0.5, 0.5, 0.5}, {0.75, 0, 1}, {0.5, 0.25, 1}, {0.75, 0.25, 1}, {0.75, 0, 0.5}, {0.5, 0.25, 0.5}, {0.75, 0.25, 0.5}, {0.25, 0.5, -1}, {0, 0.75, -1}, {0.25, 0.75, -1}, {0, 1, -0.5}, {0.25, 0.5, 0}, {0, 0.75, 0}, {0.25, 0.75, 0}, {0.25, 0.5, -0.5}, {0, 0.75, -0.5}, {0.25, 0.75, -0.5}, {0, 1, 0.5}, {0.25, 0.5, 1}, {0, 0.75, 1}, {0.25, 0.75, 1}, {0.25, 0.5, 0.5}, {0, 0.75, 0.5}, {0.25, 0.75, 0.5}}
]
+ connectivities [
ElementTypeMapArray<unsigned int> [
(not_ghost:_pentahedron_6) [
Array<unsigned int> [
+ id : mesh:connectivities:_pentahedron_6
+ size : 64
+ nb_component : 6
+ allocated size : 2000
+ memory size : 46.88KiByte
- + values : {{0, 18, 19, 20, 27, 28}, {20, 27, 28, 8, 24, 25}, {18, 6, 21, 27, 22, 29}, {27, 22, 29, 24, 15, 26}, {19, 21, 7, 28, 29, 23}, {28, 29, 23, 25, 26, 16}, {21, 19, 18, 29, 28, 27}, {29, 28, 27, 26, 25, 24}, {8, 24, 25, 30, 36, 37}, {30, 36, 37, 3, 33, 34}, {24, 15, 26, 36, 31, 38}, {36, 31, 38, 33, 12, 35}, {25, 26, 16, 37, 38, 32}, {37, 38, 32, 34, 35, 13}, {26, 25, 24, 38, 37, 36}, {38, 37, 36, 35, 34, 33}, {6, 39, 40, 22, 47, 48}, {22, 47, 48, 15, 44, 45}, {39, 1, 41, 47, 42, 49}, {47, 42, 49, 44, 10, 46}, {40, 41, 9, 48, 49, 43}, {48, 49, 43, 45, 46, 17}, {41, 40, 39, 49, 48, 47}, {49, 48, 47, 46, 45, 44}, {15, 44, 45, 31, 55, 56}, {31, 55, 56, 12, 52, 53}, {44, 10, 46, 55, 50, 57}, {55, 50, 57, 52, 4, 54}, {45, 46, 17, 56, 57, 51}, {56, 57, 51, 53, 54, 14}, {46, 45, 44, 57, 56, 55}, {57, 56, 55, 54, 53, 52}, {7, 58, 59, 23, 65, 66}, {23, 65, 66, 16, 62, 63}, {58, 9, 60, 65, 43, 67}, {65, 43, 67, 62, 17, 64}, {59, 60, 2, 66, 67, 61}, {66, 67, 61, 63, 64, 11}, {60, 59, 58, 67, 66, 65}, {67, 66, 65, 64, 63, 62}, {16, 62, 63, 32, 72, 73}, {32, 72, 73, 13, 69, 70}, {62, 17, 64, 72, 51, 74}, {72, 51, 74, 69, 14, 71}, {63, 64, 11, 73, 74, 68}, {73, 74, 68, 70, 71, 5}, {64, 63, 62, 74, 73, 72}, {74, 73, 72, 71, 70, 69}, {9, 58, 40, 43, 65, 48}, {43, 65, 48, 17, 62, 45}, {58, 7, 21, 65, 23, 29}, {65, 23, 29, 62, 16, 26}, {40, 21, 6, 48, 29, 22}, {48, 29, 22, 45, 26, 15}, {21, 40, 58, 29, 48, 65}, {29, 48, 65, 26, 45, 62}, {17, 62, 45, 51, 72, 56}, {51, 72, 56, 14, 69, 53}, {62, 16, 26, 72, 32, 38}, {72, 32, 38, 69, 13, 35}, {45, 26, 15, 56, 38, 31}, {56, 38, 31, 53, 35, 12}, {26, 45, 62, 38, 56, 72}, {38, 56, 72, 35, 53, 69}}
+ + values : {{18, 19, 0, 27, 28, 20}, {27, 28, 20, 24, 25, 8}, {6, 21, 18, 22, 29, 27}, {22, 29, 27, 15, 26, 24}, {21, 7, 19, 29, 23, 28}, {29, 23, 28, 26, 16, 25}, {19, 18, 21, 28, 27, 29}, {28, 27, 29, 25, 24, 26}, {24, 25, 8, 36, 37, 30}, {36, 37, 30, 33, 34, 3}, {15, 26, 24, 31, 38, 36}, {31, 38, 36, 12, 35, 33}, {26, 16, 25, 38, 32, 37}, {38, 32, 37, 35, 13, 34}, {25, 24, 26, 37, 36, 38}, {37, 36, 38, 34, 33, 35}, {39, 40, 6, 47, 48, 22}, {47, 48, 22, 44, 45, 15}, {1, 41, 39, 42, 49, 47}, {42, 49, 47, 10, 46, 44}, {41, 9, 40, 49, 43, 48}, {49, 43, 48, 46, 17, 45}, {40, 39, 41, 48, 47, 49}, {48, 47, 49, 45, 44, 46}, {44, 45, 15, 55, 56, 31}, {55, 56, 31, 52, 53, 12}, {10, 46, 44, 50, 57, 55}, {50, 57, 55, 4, 54, 52}, {46, 17, 45, 57, 51, 56}, {57, 51, 56, 54, 14, 53}, {45, 44, 46, 56, 55, 57}, {56, 55, 57, 53, 52, 54}, {58, 59, 7, 65, 66, 23}, {65, 66, 23, 62, 63, 16}, {9, 60, 58, 43, 67, 65}, {43, 67, 65, 17, 64, 62}, {60, 2, 59, 67, 61, 66}, {67, 61, 66, 64, 11, 63}, {59, 58, 60, 66, 65, 67}, {66, 65, 67, 63, 62, 64}, {62, 63, 16, 72, 73, 32}, {72, 73, 32, 69, 70, 13}, {17, 64, 62, 51, 74, 72}, {51, 74, 72, 14, 71, 69}, {64, 11, 63, 74, 68, 73}, {74, 68, 73, 71, 5, 70}, {63, 62, 64, 73, 72, 74}, {73, 72, 74, 70, 69, 71}, {58, 40, 9, 65, 48, 43}, {65, 48, 43, 62, 45, 17}, {7, 21, 58, 23, 29, 65}, {23, 29, 65, 16, 26, 62}, {21, 6, 40, 29, 22, 48}, {29, 22, 48, 26, 15, 45}, {40, 58, 21, 48, 65, 29}, {48, 65, 29, 45, 62, 26}, {62, 45, 17, 72, 56, 51}, {72, 56, 51, 69, 53, 14}, {16, 26, 62, 32, 38, 72}, {32, 38, 72, 13, 35, 69}, {26, 15, 45, 38, 31, 56}, {38, 31, 56, 35, 12, 53}, {45, 62, 26, 56, 72, 38}, {56, 72, 38, 53, 69, 35}}
]
]
]
]
GroupManager [
]
]
]
]
]
+ shape functions [
Shapes Lagrange [
Shapes [
ElementTypeMap<akantu::Matrix<double>> [
(not_ghost:_pentahedron_6)
]
]
ElementTypeMapArray<double> [
(not_ghost:_itp_lagrange_pentahedron_6) [
Array<double> [
+ id : my_fem:shapes_generic:_itp_lagrange_pentahedron_6
+ size : 384
+ nb_component : 6
+ allocated size : 384
+ memory size : 18.00KiByte
- + values : {{-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}, {-0.144338, 0.125, 0.269338, -0.433013, 0.375, 0.808013}, {-0.144338, 0, 0.394338, -0.433013, 0, 1.18301}, {-0.288675, 0.25, 0.538675, -0.288675, 0.25, 0.538675}, {0.144338, 0.125, -0.0193376, 0.433013, 0.375, -0.0580127}, {0.144338, 0, 0.105662, 0.433013, 0, 0.316987}, {0.288675, 0.25, -0.0386751, 0.288675, 0.25, -0.0386751}}
+ + values : {{0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}, {0.394338, 0.394338, 0, 0.105662, 0.105662, 0}, {0, 0.394338, 0.394338, 0, 0.105662, 0.105662}, {0.394338, 0, 0.394338, 0.105662, 0, 0.105662}, {0.105662, 0.105662, 0, 0.394338, 0.394338, 0}, {0, 0.105662, 0.105662, 0, 0.394338, 0.394338}, {0.105662, 0, 0.105662, 0.394338, 0, 0.394338}}
]
]
]
ElementTypeMapArray<double> [
(not_ghost:_itp_lagrange_pentahedron_6) [
Array<double> [
+ id : my_fem:shapes_derivatives_generic:_itp_lagrange_pentahedron_6
+ size : 384
+ nb_component : 18
+ allocated size : 384
+ memory size : 54.00KiByte
- + values : {{-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {1, 1, 1.1547, -1, 0, -1, 0, -1, -2.1547, 3, 3, -1.1547, -3, 0, 1, 0, -3, 2.1547}, {1, 1, 1.1547, -1, 0, 0, 0, -1, -3.1547, 3, 3, -1.1547, -3, 0, 0, 0, -3, 3.1547}, {2, 2, 1.1547, -2, 0, -1, 0, -2, -2.1547, 2, 2, -1.1547, -2, 0, 1, 0, -2, 2.1547}, {1, 1, -1.1547, -1, 0, -1, 0, -1, 0.154701, 3, 3, 1.1547, -3, 0, 1, 0, -3, -0.154701}, {1, 1, -1.1547, -1, 0, 0, 0, -1, -0.845299, 3, 3, 1.1547, -3, 0, 0, 0, -3, 0.845299}, {2, 2, -1.1547, -2, 0, -1, 0, -2, 0.154701, 2, 2, 1.1547, -2, 0, 1, 0, -2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}, {-1, -1, 1.1547, 1, 0, -1, 0, 1, -2.1547, -3, -3, -1.1547, 3, 0, 1, 0, 3, 2.1547}, {-1, -1, 1.1547, 1, 0, 0, 0, 1, -3.1547, -3, -3, -1.1547, 3, 0, 0, 0, 3, 3.1547}, {-2, -2, 1.1547, 2, 0, -1, 0, 2, -2.1547, -2, -2, -1.1547, 2, 0, 1, 0, 2, 2.1547}, {-1, -1, -1.1547, 1, 0, -1, 0, 1, 0.154701, -3, -3, 1.1547, 3, 0, 1, 0, 3, -0.154701}, {-1, -1, -1.1547, 1, 0, 0, 0, 1, -0.845299, -3, -3, 1.1547, 3, 0, 0, 0, 3, 0.845299}, {-2, -2, -1.1547, 2, 0, -1, 0, 2, 0.154701, -2, -2, 1.1547, 2, 0, 1, 0, 2, -0.154701}}
+ + values : {{3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {-3.1547, 0, -1, 0, -3.1547, -1, 3.1547, 3.1547, 0, -0.845299, 0, 1, 0, -0.845299, 1, 0.845299, 0.845299, 0}, {-3.1547, 0, 0, 0, -3.1547, -1, 3.1547, 3.1547, -1, -0.845299, 0, 0, 0, -0.845299, 1, 0.845299, 0.845299, 1}, {-3.1547, 0, -1, 0, -3.1547, 0, 3.1547, 3.1547, -1, -0.845299, 0, 1, 0, -0.845299, 0, 0.845299, 0.845299, 1}, {-0.845299, 0, -1, 0, -0.845299, -1, 0.845299, 0.845299, 0, -3.1547, 0, 1, 0, -3.1547, 1, 3.1547, 3.1547, 0}, {-0.845299, 0, 0, 0, -0.845299, -1, 0.845299, 0.845299, -1, -3.1547, 0, 0, 0, -3.1547, 1, 3.1547, 3.1547, 1}, {-0.845299, 0, -1, 0, -0.845299, 0, 0.845299, 0.845299, -1, -3.1547, 0, 1, 0, -3.1547, 0, 3.1547, 3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}, {3.1547, 0, -1, 0, 3.1547, -1, -3.1547, -3.1547, 0, 0.845299, 0, 1, 0, 0.845299, 1, -0.845299, -0.845299, 0}, {3.1547, 0, 0, 0, 3.1547, -1, -3.1547, -3.1547, -1, 0.845299, 0, 0, 0, 0.845299, 1, -0.845299, -0.845299, 1}, {3.1547, 0, -1, 0, 3.1547, 0, -3.1547, -3.1547, -1, 0.845299, 0, 1, 0, 0.845299, 0, -0.845299, -0.845299, 1}, {0.845299, 0, -1, 0, 0.845299, -1, -0.845299, -0.845299, 0, 3.1547, 0, 1, 0, 3.1547, 1, -3.1547, -3.1547, 0}, {0.845299, 0, 0, 0, 0.845299, -1, -0.845299, -0.845299, -1, 3.1547, 0, 0, 0, 3.1547, 1, -3.1547, -3.1547, 1}, {0.845299, 0, -1, 0, 0.845299, 0, -0.845299, -0.845299, -1, 3.1547, 0, 1, 0, 3.1547, 0, -3.1547, -3.1547, 1}}
]
]
]
]
]
+ integrator [
Integrator [
ElementTypeMapArray<double> [
(not_ghost:_pentahedron_6) [
Array<double> [
+ id : my_fem:jacobians:_pentahedron_6
+ size : 384
+ nb_component : 1
+ allocated size : 384
+ memory size : 3.00KiByte
+ values : {{0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}, {0.00260417}}
]
]
]
]
]
]
diff --git a/test/test_fe_engine/test_gradient.cc b/test/test_fe_engine/test_gradient.cc
index ca5e91f5f..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->getNbQuadraturePoints(type) * nb_element;
+ 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->gradientOnQuadraturePoints(const_val, grad_on_quad, 2, type);
+ 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->gradientOnQuadraturePoints(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 6649622c4..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->getNbQuadraturePoints(type) * nb_element;
+ 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->interpolateOnQuadraturePoints(const_val, val_on_quad, 2, type);
+ 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 18754bea9..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->getNbQuadraturePoints(type) * nb_element;
+ 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->interpolateOnQuadraturePoints(const_val, val_on_quad, 2, type);
+ 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->interpolateOnQuadraturePoints(my_mesh.getNodes(),
+ 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 ac9698929..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->getNbQuadraturePoints(type);
+ 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->interpolateOnQuadraturePoints(my_mesh.getNodes(),
+ 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 2226ea5c9..70f83bed2 100644
--- a/test/test_mesh_utils/CMakeLists.txt
+++ b/test/test_mesh_utils/CMakeLists.txt
@@ -1,48 +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/CMakeLists.txt b/test/test_mesh_utils/test_buildfacets/CMakeLists.txt
index 25a03db1c..ed6eeb2da 100644
--- a/test/test_mesh_utils/test_buildfacets/CMakeLists.txt
+++ b/test/test_mesh_utils/test_buildfacets/CMakeLists.txt
@@ -1,42 +1,108 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
-#
-# @date Tue May 08 13:01:18 2012
+# @author Mauro Corrado <mauro.corrado@epfl.ch>
+# @date Thu Sep 17 13:01:18 2015
#
# @brief configuration for build facets 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/>.
#
# @section DESCRIPTION
#
#===============================================================================
-register_test(test_buildfacets_tetrahedron
- SOURCES test_buildfacets_tetrahedron.cc
- FILES_TO_COPY tetrahedron.msh
+register_test(test_buildfacets_triangle_3
+ SOURCES test_buildfacets_triangle_3.cc
+ FILES_TO_COPY triangle_3.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_triangle_6
+ SOURCES test_buildfacets_triangle_6.cc
+ FILES_TO_COPY triangle_6.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_quadrangle_4
+ SOURCES test_buildfacets_quadrangle_4.cc
+ FILES_TO_COPY quadrangle_4.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_quadrangle_8
+ SOURCES test_buildfacets_quadrangle_8.cc
+ FILES_TO_COPY quadrangle_8.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_mixed2d_linear
+ SOURCES test_buildfacets_mixed2d_linear.cc
+ FILES_TO_COPY mixed2d_linear.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_mixed2d_quadratic
+ SOURCES test_buildfacets_mixed2d_quadratic.cc
+ FILES_TO_COPY mixed2d_quadratic.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_tetrahedron_10
+ SOURCES test_buildfacets_tetrahedron_10.cc
+ FILES_TO_COPY tetrahedron_10.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_hexahedron_8
+ SOURCES test_buildfacets_hexahedron_8.cc
+ FILES_TO_COPY hexahedron_8.msh
PACKAGE cohesive_element
)
-register_test(test_buildfacets_hexahedron
- SOURCES test_buildfacets_hexahedron.cc
- FILES_TO_COPY hexahedron.msh
+
+register_test(test_buildfacets_hexahedron_20
+ SOURCES test_buildfacets_hexahedron_20.cc
+ FILES_TO_COPY hexahedron_20.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_pentahedron_6
+ SOURCES test_buildfacets_pentahedron_6.cc
+ FILES_TO_COPY pentahedron_6.msh
PACKAGE cohesive_element
)
+register_test(test_buildfacets_pentahedron_15
+ SOURCES test_buildfacets_pentahedron_15.cc
+ FILES_TO_COPY pentahedron_15.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_mixed3d_linear
+ SOURCES test_buildfacets_mixed3d_linear.cc
+ FILES_TO_COPY mixed3d_linear.msh
+ PACKAGE cohesive_element
+ )
+
+register_test(test_buildfacets_mixed3d_quadratic
+ SOURCES test_buildfacets_mixed3d_quadratic.cc
+ FILES_TO_COPY mixed3d_quadratic.msh
+ PACKAGE cohesive_element
+ )
diff --git a/test/test_mesh_utils/test_buildfacets/hexahedron_20.msh b/test/test_mesh_utils/test_buildfacets/hexahedron_20.msh
new file mode 100644
index 000000000..0ede87c7d
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/hexahedron_20.msh
@@ -0,0 +1,64 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+51
+1 0 0 0
+2 1 0 0
+3 1 1 0
+4 0 1 0
+5 0 0 1
+6 1 0 1
+7 1 1 1
+8 0 1 1
+9 0.5 0 1
+10 1 0.5 1
+11 1 0 0.5
+12 0 0.5 1
+13 0 0 0.5
+14 0.5 1 1
+15 0 1 0.5
+16 1 1 0.5
+17 0.5 0 0
+18 1 0.5 0
+19 0 0.5 0
+20 0.5 1 0
+21 -1 1 0
+22 -1 0 0
+23 -1 1 1
+24 -1 0 1
+25 -0.5 1 0
+26 -0.5 0 0
+27 -0.5 0 1
+28 -0.5 1 1
+29 -1 0.5 0
+30 -1 1 0.5
+31 -1 0 0.5
+32 -1 0.5 1
+33 -1 -1 0
+34 0 -1 0
+35 -1 -1 1
+36 0 -1 1
+37 0 -0.5 1
+38 0 -0.5 0
+39 0 -1 0.5
+40 -0.5 -1 0
+41 -0.5 -1 1
+42 -1 -0.5 1
+43 -1 -0.5 0
+44 -1 -1 0.5
+45 1 -1 0
+46 1 -1 1
+47 0.5 -1 0
+48 0.5 -1 1
+49 1 -0.5 0
+50 1 -1 0.5
+51 1 -0.5 1
+$EndNodes
+$Elements
+4
+1 17 2 82 75 6 5 8 7 2 1 4 3 9 10 11 12 13 14 15 16 17 18 19 20
+2 17 2 82 77 4 1 5 8 21 22 24 23 19 15 25 13 26 12 27 28 29 30 31 32
+3 17 2 82 79 5 1 34 36 24 22 33 35 13 37 27 38 26 39 40 41 31 42 43 44
+4 17 2 82 81 34 1 5 36 45 2 6 46 38 39 47 13 17 37 9 48 49 50 11 51
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/hexahedron.msh b/test/test_mesh_utils/test_buildfacets/hexahedron_8.msh
similarity index 100%
rename from test/test_mesh_utils/test_buildfacets/hexahedron.msh
rename to test/test_mesh_utils/test_buildfacets/hexahedron_8.msh
diff --git a/test/test_mesh_utils/test_buildfacets/mixed2d_linear.msh b/test/test_mesh_utils/test_buildfacets/mixed2d_linear.msh
new file mode 100644
index 000000000..ee378facf
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/mixed2d_linear.msh
@@ -0,0 +1,24 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+9
+1 0 0 0
+2 1 0 0
+3 2 0 0
+4 0 1 0
+5 1 1 0
+6 2 1 0
+7 0 2 0
+8 1 2 0
+9 2 2 0
+$EndNodes
+$Elements
+6
+1 2 2 2 2 4 5 7
+2 2 2 2 2 5 6 8
+3 2 2 2 2 8 7 5
+4 2 2 2 2 9 8 6
+5 3 2 2 2 1 2 5 4
+6 3 2 2 2 2 3 6 5
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/mixed2d_quadratic.msh b/test/test_mesh_utils/test_buildfacets/mixed2d_quadratic.msh
new file mode 100644
index 000000000..2c527a175
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/mixed2d_quadratic.msh
@@ -0,0 +1,38 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+23
+1 0 1 0
+2 1 1 0
+3 2 1 0
+4 0.5 1 0
+5 1.5 1 0
+6 0 0 0
+7 1 0 0
+8 2 0 0
+9 0 2 0
+10 1 2 0
+11 2 2 0
+12 0.5 1.5 0
+13 0 1.5 0
+14 1.5 1.5 0
+15 1 1.5 0
+16 0.5 2 0
+17 1.5 2 0
+18 2 1.5 0
+19 0.5 0 0
+20 1 0.5 0
+21 0 0.5 0
+22 1.5 0 0
+23 2 0.5 0
+$EndNodes
+$Elements
+6
+1 9 2 2 2 1 2 9 4 12 13
+2 9 2 2 2 2 3 10 5 14 15
+3 9 2 2 2 10 9 2 16 12 15
+4 9 2 2 2 11 10 3 17 14 18
+5 16 2 2 2 6 7 2 1 19 20 4 21
+6 16 2 2 2 7 8 3 2 22 23 5 20
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/mixed3d_linear.msh b/test/test_mesh_utils/test_buildfacets/mixed3d_linear.msh
new file mode 100644
index 000000000..895001e7b
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/mixed3d_linear.msh
@@ -0,0 +1,33 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+18
+1 0 0 0
+2 1 0 0
+3 2 0 0
+4 0 0 1
+5 1 0 1
+6 2 0 1
+7 0 1 0
+8 1 1 0
+9 2 1 0
+10 0 1 1
+11 1 1 1
+12 2 1 1
+13 0 0 2
+14 1 0 2
+15 2 0 2
+16 0 1 2
+17 1 1 2
+18 2 1 2
+$EndNodes
+$Elements
+6
+1 5 2 2 2 1 4 5 2 7 10 11 8
+2 5 2 2 2 2 5 6 3 8 11 12 9
+3 6 2 2 2 4 13 5 10 16 11
+4 6 2 2 2 5 14 6 11 17 12
+5 6 2 2 2 14 5 13 17 11 16
+6 6 2 2 2 15 6 14 18 12 17
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/mixed3d_quadratic.msh b/test/test_mesh_utils/test_buildfacets/mixed3d_quadratic.msh
new file mode 100644
index 000000000..601b17789
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/mixed3d_quadratic.msh
@@ -0,0 +1,70 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+55
+1 0 0 1
+2 1 0 1
+3 2 0 1
+4 0 1 1
+5 1 1 1
+6 2 1 1
+7 0.5 0 1
+8 1 0.5 1
+9 0.5 1 1
+10 0 0.5 1
+11 1.5 0 1
+12 2 0.5 1
+13 1.5 1 1
+14 0 0 0
+15 1 0 0
+16 2 0 0
+17 0 1 0
+18 1 1 0
+19 2 1 0
+20 0 0 2
+21 1 0 2
+22 2 0 2
+23 0 1 2
+24 1 1 2
+25 2 1 2
+26 0 0 0.5
+27 0.5 0 0
+28 0 0.5 0
+29 1 0 0.5
+30 1 0.5 0
+31 0 1 0.5
+32 0.5 1 0
+33 1 1 0.5
+34 1.5 0 0
+35 2 0 0.5
+36 2 0.5 0
+37 1.5 1 0
+38 2 1 0.5
+39 0 0 1.5
+40 0.5 0 1.5
+41 0 0.5 2
+42 0 1 1.5
+43 0.5 1 1.5
+44 1 0 1.5
+45 1.5 0 1.5
+46 1 0.5 2
+47 1 1 1.5
+48 1.5 1 1.5
+49 0.5 0 2
+50 0.5 1 2
+51 2 0 1.5
+52 1.5 0 2
+53 2 0.5 2
+54 2 1 1.5
+55 1.5 1 2
+$EndNodes
+$Elements
+6
+1 17 2 2 2 14 1 2 15 17 4 5 18 26 27 28 7 10 29 8 30 31 32 9 33
+2 17 2 2 2 15 2 3 16 18 5 6 19 29 34 30 11 8 35 12 36 33 37 13 38
+3 18 2 2 2 1 20 2 4 23 5 39 7 10 40 41 8 42 9 43
+4 18 2 2 2 2 21 3 5 24 6 44 11 8 45 46 12 47 13 48
+5 18 2 2 2 21 2 20 24 5 23 44 49 46 40 8 41 47 50 43
+6 18 2 2 2 22 3 21 25 6 24 51 52 53 45 12 46 54 55 48
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/pentahedron_15.msh b/test/test_mesh_utils/test_buildfacets/pentahedron_15.msh
new file mode 100644
index 000000000..92d11e1c1
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/pentahedron_15.msh
@@ -0,0 +1,48 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+35
+1 0 0 0
+2 1 0 0
+3 0 1 0
+4 1 1 0
+5 0 0 1
+6 1 0 1
+7 0 1 1
+8 1 1 1
+9 0 0 2
+10 1 0 2
+11 0 1 2
+12 1 1 2
+13 0.5 0 0
+14 0 0.5 0
+15 0 0 0.5
+16 0.5 0.5 0
+17 1 0 0.5
+18 0 1 0.5
+19 0.5 0 1
+20 0 0.5 1
+21 0.5 0.5 1
+22 1 0.5 0
+23 0.5 1 0
+24 1 1 0.5
+25 1 0.5 1
+26 0.5 1 1
+27 0 0 1.5
+28 1 0 1.5
+29 0 1 1.5
+30 0.5 0 2
+31 0 0.5 2
+32 0.5 0.5 2
+33 1 1 1.5
+34 1 0.5 2
+35 0.5 1 2
+$EndNodes
+$Elements
+4
+1 18 2 0 0 1 2 3 5 6 7 13 14 15 16 17 18 19 20 21
+2 18 2 0 0 2 4 3 6 8 7 22 16 17 23 24 18 25 21 26
+3 18 2 0 0 5 6 7 9 10 11 19 20 27 21 28 29 30 31 32
+4 18 2 0 0 6 8 7 10 12 11 25 21 28 26 33 29 34 32 35
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/pentahedron_6.msh b/test/test_mesh_utils/test_buildfacets/pentahedron_6.msh
new file mode 100644
index 000000000..4832641f2
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/pentahedron_6.msh
@@ -0,0 +1,25 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+12
+1 0 0 0
+2 1 0 0
+3 0 1 0
+4 1 1 0
+5 0 0 1
+6 1 0 1
+7 0 1 1
+8 1 1 1
+9 0 0 2
+10 1 0 2
+11 0 1 2
+12 1 1 2
+$EndNodes
+$Elements
+4
+1 6 2 0 0 1 2 3 5 6 7
+2 6 2 0 0 2 4 3 6 8 7
+3 6 2 0 0 5 6 7 9 10 11
+4 6 2 0 0 6 8 7 10 12 11
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/quadrangle_4.msh b/test/test_mesh_utils/test_buildfacets/quadrangle_4.msh
new file mode 100644
index 000000000..72e4d9e0b
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/quadrangle_4.msh
@@ -0,0 +1,22 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+9
+1 0 0 0
+2 1 0 0
+3 0 1 0
+4 1 1 0
+5 0 2 0
+6 1 2 0
+7 2 0 0
+8 2 1 0
+9 2 2 0
+$EndNodes
+$Elements
+4
+1 3 2 2 2 1 2 4 3
+2 3 2 2 2 3 4 6 5
+3 3 2 2 2 2 7 8 4
+4 3 2 2 2 4 8 9 6
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/quadrangle_8.msh b/test/test_mesh_utils/test_buildfacets/quadrangle_8.msh
new file mode 100644
index 000000000..b774f2feb
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/quadrangle_8.msh
@@ -0,0 +1,34 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+21
+1 0 0 0
+2 1 0 0
+3 0 1 0
+4 1 1 0
+5 0 2 0
+6 1 2 0
+7 2 0 0
+8 2 1 0
+9 2 2 0
+10 0.5 0 0
+11 1 0.5 0
+12 0.5 1 0
+13 0 0.5 0
+14 1 1.5 0
+15 0.5 2 0
+16 0 1.5 0
+17 1.5 0 0
+18 2 0.5 0
+19 1.5 1 0
+20 2 1.5 0
+21 1.5 2 0
+$EndNodes
+$Elements
+4
+1 16 2 2 2 1 2 4 3 10 11 12 13
+2 16 2 2 2 3 4 6 5 12 14 15 16
+3 16 2 2 2 2 7 8 4 17 18 19 11
+4 16 2 2 2 4 8 9 6 19 20 21 14
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron.cc
deleted file mode 100644
index c4d5024cb..000000000
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- * @file test_cohesive_buildfacets_hexahedron.cc
- *
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date Wed Oct 03 10:20:53 2012
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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.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);
-
- /// build vectors for comparison
- Array<Element> hexahedron(2);
- hexahedron(0).type = type;
- hexahedron(0).element = 0;
-
- hexahedron(1).type = type;
- hexahedron(1).element = 3;
-
- Array<Element> quadrangle(4);
- quadrangle(0).type = type_facet;
- quadrangle(0).element = 1;
-
- quadrangle(1).type = type_facet;
- quadrangle(1).element = 2;
-
- quadrangle(2).type = type_facet;
- quadrangle(2).element = 7;
-
- quadrangle(3).type = type_facet;
- quadrangle(3).element = 11;
-
- Array<Element> segment(5);
- segment(0).type = type_subfacet;
- segment(0).element = 0;
-
- segment(1).type = type_subfacet;
- segment(1).element = 1;
-
- segment(2).type = type_subfacet;
- segment(2).element = 4;
-
- segment(3).type = type_subfacet;
- segment(3).element = 15;
-
- segment(4).type = type_subfacet;
- segment(4).element = 22;
-
-
- /// comparison
-
- for (UInt i = 0; i < hexahedron.getSize(); ++i) {
- if (hexahedron(i).type != el_to_subel3(1)[i].type ||
- hexahedron(i).element != el_to_subel3(1)[i].element) {
- std::cout << hexahedron(i).element << " " << el_to_subel3(4)[i].element << std::endl;
- std::cout << "The two hexahedrons connected to quadrangle 1 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- for (UInt i = 0; i < quadrangle.getSize(); ++i) {
- if (quadrangle(i).type != el_to_subel2(4)[i].type ||
- quadrangle(i).element != el_to_subel2(4)[i].element) {
- std::cout << "The quadrangles connected to segment 4 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- for (UInt i = 0; i < segment.getSize(); ++i) {
- if (segment(i).type != el_to_subel1(1)[i].type ||
- segment(i).element != el_to_subel1(1)[i].element) {
- std::cout << "The segments connected to point 1 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* 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);
-
- /// build vectors for comparison
- Array<Element> quadrangle2(mesh.getNbFacetsPerElement(type));
- quadrangle2(0).type = type_facet;
- quadrangle2(0).element = 1;
-
- quadrangle2(1).type = type_facet;
- quadrangle2(1).element = 11;
-
- quadrangle2(2).type = type_facet;
- quadrangle2(2).element = 16;
-
- quadrangle2(3).type = type_facet;
- quadrangle2(3).element = 17;
-
- quadrangle2(4).type = type_facet;
- quadrangle2(4).element = 18;
-
- quadrangle2(5).type = type_facet;
- quadrangle2(5).element = 19;
-
- Array<Element> segment2(4);
- segment2(0).type = type_subfacet;
- segment2(0).element = 3;
-
- segment2(1).type = type_subfacet;
- segment2(1).element = 6;
-
- segment2(2).type = type_subfacet;
- segment2(2).element = 9;
-
- segment2(3).type = type_subfacet;
- segment2(3).element = 11;
-
- Array<Element> point(2);
- point(0).type = mesh.getFacetType(type_subfacet);
- point(0).element = 5;
-
- point(1).type = mesh.getFacetType(type_subfacet);
- point(1).element = 7;
-
-
- /// comparison
-
- for (UInt i = 0; i < quadrangle2.getSize(); ++i) {
- if (quadrangle2(i).type != subel_to_el3(3, i).type ||
- quadrangle2(i).element != subel_to_el3(3, i).element) {
- std::cout << "The quadrangles connected to hexahedron 3 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- for (UInt i = 0; i < segment2.getSize(); ++i) {
- if (segment2(i).type != subel_to_el2(4, i).type ||
- segment2(i).element != subel_to_el2(4, i).element) {
- std::cout << "The segments connected to quadrangle 4 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- for (UInt i = 0; i < point.getSize(); ++i) {
- if (point(i).type != subel_to_el1(11, i).type ||
- point(i).element != subel_to_el1(11, i).element) {
- std::cout << "The points connected to segment 11 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
-
- finalize();
-
- std::cout << "OK: test_cohesive_buildfacets was passed!" << std::endl;
-
- return EXIT_SUCCESS;
-}
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
new file mode 100644
index 000000000..9f814dc7b
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
@@ -0,0 +1,143 @@
+/**
+ * @file test_buildfacets_hexahedron_20.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @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-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_20.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.verified
new file mode 100644
index 000000000..79ae07364
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.verified
@@ -0,0 +1,135 @@
+ElementToSubelement3
+_quadrangle_8 0 connected to _hexahedron_20 0, _hexahedron_20 3,
+_quadrangle_8 1 connected to _hexahedron_20 0, _hexahedron_20 1,
+_quadrangle_8 2 connected to _hexahedron_20 0, _not_defined 0,
+_quadrangle_8 3 connected to _hexahedron_20 0, _not_defined 0,
+_quadrangle_8 4 connected to _hexahedron_20 0, _not_defined 0,
+_quadrangle_8 5 connected to _hexahedron_20 0, _not_defined 0,
+_quadrangle_8 6 connected to _hexahedron_20 1, _not_defined 0,
+_quadrangle_8 7 connected to _hexahedron_20 1, _hexahedron_20 2,
+_quadrangle_8 8 connected to _hexahedron_20 1, _not_defined 0,
+_quadrangle_8 9 connected to _hexahedron_20 1, _not_defined 0,
+_quadrangle_8 10 connected to _hexahedron_20 1, _not_defined 0,
+_quadrangle_8 11 connected to _hexahedron_20 2, _not_defined 0,
+_quadrangle_8 12 connected to _hexahedron_20 2, _not_defined 0,
+_quadrangle_8 13 connected to _hexahedron_20 2, _not_defined 0,
+_quadrangle_8 14 connected to _hexahedron_20 2, _hexahedron_20 3,
+_quadrangle_8 15 connected to _hexahedron_20 2, _not_defined 0,
+_quadrangle_8 16 connected to _hexahedron_20 3, _not_defined 0,
+_quadrangle_8 17 connected to _hexahedron_20 3, _not_defined 0,
+_quadrangle_8 18 connected to _hexahedron_20 3, _not_defined 0,
+_quadrangle_8 19 connected to _hexahedron_20 3, _not_defined 0,
+ElementToSubelement2
+_segment_3 0 connected to _quadrangle_8 0, _quadrangle_8 4, _quadrangle_8 17,
+_segment_3 1 connected to _quadrangle_8 0, _quadrangle_8 1, _quadrangle_8 7, _quadrangle_8 14,
+_segment_3 2 connected to _quadrangle_8 0, _quadrangle_8 5, _quadrangle_8 16,
+_segment_3 3 connected to _quadrangle_8 0, _quadrangle_8 3, _quadrangle_8 19,
+_segment_3 4 connected to _quadrangle_8 1, _quadrangle_8 4, _quadrangle_8 8,
+_segment_3 5 connected to _quadrangle_8 1, _quadrangle_8 2, _quadrangle_8 9,
+_segment_3 6 connected to _quadrangle_8 1, _quadrangle_8 5, _quadrangle_8 6,
+_segment_3 7 connected to _quadrangle_8 2, _quadrangle_8 4,
+_segment_3 8 connected to _quadrangle_8 2, _quadrangle_8 3,
+_segment_3 9 connected to _quadrangle_8 2, _quadrangle_8 5,
+_segment_3 10 connected to _quadrangle_8 3, _quadrangle_8 4,
+_segment_3 11 connected to _quadrangle_8 3, _quadrangle_8 5,
+_segment_3 12 connected to _quadrangle_8 6, _quadrangle_8 7, _quadrangle_8 11,
+_segment_3 13 connected to _quadrangle_8 6, _quadrangle_8 10,
+_segment_3 14 connected to _quadrangle_8 6, _quadrangle_8 9,
+_segment_3 15 connected to _quadrangle_8 7, _quadrangle_8 8, _quadrangle_8 13,
+_segment_3 16 connected to _quadrangle_8 7, _quadrangle_8 10, _quadrangle_8 15,
+_segment_3 17 connected to _quadrangle_8 8, _quadrangle_8 9,
+_segment_3 18 connected to _quadrangle_8 8, _quadrangle_8 10,
+_segment_3 19 connected to _quadrangle_8 9, _quadrangle_8 10,
+_segment_3 20 connected to _quadrangle_8 11, _quadrangle_8 14, _quadrangle_8 16,
+_segment_3 21 connected to _quadrangle_8 11, _quadrangle_8 12,
+_segment_3 22 connected to _quadrangle_8 11, _quadrangle_8 15,
+_segment_3 23 connected to _quadrangle_8 12, _quadrangle_8 14, _quadrangle_8 18,
+_segment_3 24 connected to _quadrangle_8 12, _quadrangle_8 13,
+_segment_3 25 connected to _quadrangle_8 12, _quadrangle_8 15,
+_segment_3 26 connected to _quadrangle_8 13, _quadrangle_8 14, _quadrangle_8 17,
+_segment_3 27 connected to _quadrangle_8 13, _quadrangle_8 15,
+_segment_3 28 connected to _quadrangle_8 16, _quadrangle_8 19,
+_segment_3 29 connected to _quadrangle_8 16, _quadrangle_8 18,
+_segment_3 30 connected to _quadrangle_8 17, _quadrangle_8 18,
+_segment_3 31 connected to _quadrangle_8 17, _quadrangle_8 19,
+_segment_3 32 connected to _quadrangle_8 18, _quadrangle_8 19,
+ElementToSubelement1
+_point_1 0 connected to _segment_3 0, _segment_3 3, _segment_3 10, _segment_3 31,
+_point_1 1 connected to _segment_3 0, _segment_3 1, _segment_3 4, _segment_3 15, _segment_3 26,
+_point_1 2 connected to _segment_3 1, _segment_3 2, _segment_3 6, _segment_3 12, _segment_3 20,
+_point_1 3 connected to _segment_3 2, _segment_3 3, _segment_3 11, _segment_3 28,
+_point_1 4 connected to _segment_3 4, _segment_3 5, _segment_3 7, _segment_3 17,
+_point_1 5 connected to _segment_3 5, _segment_3 6, _segment_3 9, _segment_3 14,
+_point_1 6 connected to _segment_3 7, _segment_3 8, _segment_3 10,
+_point_1 7 connected to _segment_3 8, _segment_3 9, _segment_3 11,
+_point_1 8 connected to _segment_3 12, _segment_3 13, _segment_3 16, _segment_3 22,
+_point_1 9 connected to _segment_3 13, _segment_3 14, _segment_3 19,
+_point_1 10 connected to _segment_3 15, _segment_3 16, _segment_3 18, _segment_3 27,
+_point_1 11 connected to _segment_3 17, _segment_3 18, _segment_3 19,
+_point_1 12 connected to _segment_3 20, _segment_3 21, _segment_3 23, _segment_3 29,
+_point_1 13 connected to _segment_3 21, _segment_3 22, _segment_3 25,
+_point_1 14 connected to _segment_3 23, _segment_3 24, _segment_3 26, _segment_3 30,
+_point_1 15 connected to _segment_3 24, _segment_3 25, _segment_3 27,
+_point_1 16 connected to _segment_3 28, _segment_3 29, _segment_3 32,
+_point_1 17 connected to _segment_3 30, _segment_3 31, _segment_3 32,
+
+SubelementToElement3
+_hexahedron_20 0 connected to _quadrangle_8 0, _quadrangle_8 1, _quadrangle_8 2, _quadrangle_8 3, _quadrangle_8 4, _quadrangle_8 5,
+_hexahedron_20 1 connected to _quadrangle_8 1, _quadrangle_8 6, _quadrangle_8 7, _quadrangle_8 8, _quadrangle_8 9, _quadrangle_8 10,
+_hexahedron_20 2 connected to _quadrangle_8 7, _quadrangle_8 11, _quadrangle_8 12, _quadrangle_8 13, _quadrangle_8 14, _quadrangle_8 15,
+_hexahedron_20 3 connected to _quadrangle_8 0, _quadrangle_8 14, _quadrangle_8 16, _quadrangle_8 17, _quadrangle_8 18, _quadrangle_8 19,
+SubelementToElement2
+_quadrangle_8 0 connected to _segment_3 0, _segment_3 1, _segment_3 2, _segment_3 3,
+_quadrangle_8 1 connected to _segment_3 1, _segment_3 4, _segment_3 5, _segment_3 6,
+_quadrangle_8 2 connected to _segment_3 5, _segment_3 7, _segment_3 8, _segment_3 9,
+_quadrangle_8 3 connected to _segment_3 3, _segment_3 8, _segment_3 10, _segment_3 11,
+_quadrangle_8 4 connected to _segment_3 0, _segment_3 4, _segment_3 7, _segment_3 10,
+_quadrangle_8 5 connected to _segment_3 2, _segment_3 6, _segment_3 9, _segment_3 11,
+_quadrangle_8 6 connected to _segment_3 6, _segment_3 12, _segment_3 13, _segment_3 14,
+_quadrangle_8 7 connected to _segment_3 1, _segment_3 12, _segment_3 15, _segment_3 16,
+_quadrangle_8 8 connected to _segment_3 4, _segment_3 15, _segment_3 17, _segment_3 18,
+_quadrangle_8 9 connected to _segment_3 5, _segment_3 14, _segment_3 17, _segment_3 19,
+_quadrangle_8 10 connected to _segment_3 13, _segment_3 16, _segment_3 18, _segment_3 19,
+_quadrangle_8 11 connected to _segment_3 12, _segment_3 20, _segment_3 21, _segment_3 22,
+_quadrangle_8 12 connected to _segment_3 21, _segment_3 23, _segment_3 24, _segment_3 25,
+_quadrangle_8 13 connected to _segment_3 15, _segment_3 24, _segment_3 26, _segment_3 27,
+_quadrangle_8 14 connected to _segment_3 1, _segment_3 20, _segment_3 23, _segment_3 26,
+_quadrangle_8 15 connected to _segment_3 16, _segment_3 22, _segment_3 25, _segment_3 27,
+_quadrangle_8 16 connected to _segment_3 2, _segment_3 20, _segment_3 28, _segment_3 29,
+_quadrangle_8 17 connected to _segment_3 0, _segment_3 26, _segment_3 30, _segment_3 31,
+_quadrangle_8 18 connected to _segment_3 23, _segment_3 29, _segment_3 30, _segment_3 32,
+_quadrangle_8 19 connected to _segment_3 3, _segment_3 28, _segment_3 31, _segment_3 32,
+SubelementToElement1
+_segment_3 0 connected to _point_1 0, _point_1 1,
+_segment_3 1 connected to _point_1 1, _point_1 2,
+_segment_3 2 connected to _point_1 2, _point_1 3,
+_segment_3 3 connected to _point_1 0, _point_1 3,
+_segment_3 4 connected to _point_1 1, _point_1 4,
+_segment_3 5 connected to _point_1 4, _point_1 5,
+_segment_3 6 connected to _point_1 2, _point_1 5,
+_segment_3 7 connected to _point_1 4, _point_1 6,
+_segment_3 8 connected to _point_1 6, _point_1 7,
+_segment_3 9 connected to _point_1 5, _point_1 7,
+_segment_3 10 connected to _point_1 0, _point_1 6,
+_segment_3 11 connected to _point_1 3, _point_1 7,
+_segment_3 12 connected to _point_1 2, _point_1 8,
+_segment_3 13 connected to _point_1 8, _point_1 9,
+_segment_3 14 connected to _point_1 5, _point_1 9,
+_segment_3 15 connected to _point_1 1, _point_1 10,
+_segment_3 16 connected to _point_1 8, _point_1 10,
+_segment_3 17 connected to _point_1 4, _point_1 11,
+_segment_3 18 connected to _point_1 10, _point_1 11,
+_segment_3 19 connected to _point_1 9, _point_1 11,
+_segment_3 20 connected to _point_1 2, _point_1 12,
+_segment_3 21 connected to _point_1 12, _point_1 13,
+_segment_3 22 connected to _point_1 8, _point_1 13,
+_segment_3 23 connected to _point_1 12, _point_1 14,
+_segment_3 24 connected to _point_1 14, _point_1 15,
+_segment_3 25 connected to _point_1 13, _point_1 15,
+_segment_3 26 connected to _point_1 1, _point_1 14,
+_segment_3 27 connected to _point_1 10, _point_1 15,
+_segment_3 28 connected to _point_1 3, _point_1 16,
+_segment_3 29 connected to _point_1 12, _point_1 16,
+_segment_3 30 connected to _point_1 14, _point_1 17,
+_segment_3 31 connected to _point_1 0, _point_1 17,
+_segment_3 32 connected to _point_1 16, _point_1 17,
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
new file mode 100644
index 000000000..1ea23ee9c
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
@@ -0,0 +1,144 @@
+/**
+ * @file test_buildfacets_hexahedron_8.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @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-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_hexahedron_8.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.verified
new file mode 100644
index 000000000..1119f846b
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.verified
@@ -0,0 +1,135 @@
+ElementToSubelement3
+_quadrangle_4 0 connected to _hexahedron_8 0, _not_defined 0,
+_quadrangle_4 1 connected to _hexahedron_8 0, _hexahedron_8 3,
+_quadrangle_4 2 connected to _hexahedron_8 0, _hexahedron_8 1,
+_quadrangle_4 3 connected to _hexahedron_8 0, _not_defined 0,
+_quadrangle_4 4 connected to _hexahedron_8 0, _not_defined 0,
+_quadrangle_4 5 connected to _hexahedron_8 0, _not_defined 0,
+_quadrangle_4 6 connected to _hexahedron_8 1, _not_defined 0,
+_quadrangle_4 7 connected to _hexahedron_8 1, _hexahedron_8 2,
+_quadrangle_4 8 connected to _hexahedron_8 1, _not_defined 0,
+_quadrangle_4 9 connected to _hexahedron_8 1, _not_defined 0,
+_quadrangle_4 10 connected to _hexahedron_8 1, _not_defined 0,
+_quadrangle_4 11 connected to _hexahedron_8 2, _hexahedron_8 3,
+_quadrangle_4 12 connected to _hexahedron_8 2, _not_defined 0,
+_quadrangle_4 13 connected to _hexahedron_8 2, _not_defined 0,
+_quadrangle_4 14 connected to _hexahedron_8 2, _not_defined 0,
+_quadrangle_4 15 connected to _hexahedron_8 2, _not_defined 0,
+_quadrangle_4 16 connected to _hexahedron_8 3, _not_defined 0,
+_quadrangle_4 17 connected to _hexahedron_8 3, _not_defined 0,
+_quadrangle_4 18 connected to _hexahedron_8 3, _not_defined 0,
+_quadrangle_4 19 connected to _hexahedron_8 3, _not_defined 0,
+ElementToSubelement2
+_segment_2 0 connected to _quadrangle_4 0, _quadrangle_4 4,
+_segment_2 1 connected to _quadrangle_4 0, _quadrangle_4 3,
+_segment_2 2 connected to _quadrangle_4 0, _quadrangle_4 2, _quadrangle_4 8,
+_segment_2 3 connected to _quadrangle_4 0, _quadrangle_4 1, _quadrangle_4 17,
+_segment_2 4 connected to _quadrangle_4 1, _quadrangle_4 2, _quadrangle_4 7, _quadrangle_4 11,
+_segment_2 5 connected to _quadrangle_4 1, _quadrangle_4 5, _quadrangle_4 16,
+_segment_2 6 connected to _quadrangle_4 1, _quadrangle_4 4, _quadrangle_4 19,
+_segment_2 7 connected to _quadrangle_4 2, _quadrangle_4 3, _quadrangle_4 9,
+_segment_2 8 connected to _quadrangle_4 2, _quadrangle_4 5, _quadrangle_4 6,
+_segment_2 9 connected to _quadrangle_4 3, _quadrangle_4 4,
+_segment_2 10 connected to _quadrangle_4 3, _quadrangle_4 5,
+_segment_2 11 connected to _quadrangle_4 4, _quadrangle_4 5,
+_segment_2 12 connected to _quadrangle_4 6, _quadrangle_4 7, _quadrangle_4 12,
+_segment_2 13 connected to _quadrangle_4 6, _quadrangle_4 10,
+_segment_2 14 connected to _quadrangle_4 6, _quadrangle_4 9,
+_segment_2 15 connected to _quadrangle_4 7, _quadrangle_4 8, _quadrangle_4 14,
+_segment_2 16 connected to _quadrangle_4 7, _quadrangle_4 10, _quadrangle_4 15,
+_segment_2 17 connected to _quadrangle_4 8, _quadrangle_4 9,
+_segment_2 18 connected to _quadrangle_4 8, _quadrangle_4 10,
+_segment_2 19 connected to _quadrangle_4 9, _quadrangle_4 10,
+_segment_2 20 connected to _quadrangle_4 11, _quadrangle_4 14, _quadrangle_4 17,
+_segment_2 21 connected to _quadrangle_4 11, _quadrangle_4 13, _quadrangle_4 18,
+_segment_2 22 connected to _quadrangle_4 11, _quadrangle_4 12, _quadrangle_4 16,
+_segment_2 23 connected to _quadrangle_4 12, _quadrangle_4 13,
+_segment_2 24 connected to _quadrangle_4 12, _quadrangle_4 15,
+_segment_2 25 connected to _quadrangle_4 13, _quadrangle_4 14,
+_segment_2 26 connected to _quadrangle_4 13, _quadrangle_4 15,
+_segment_2 27 connected to _quadrangle_4 14, _quadrangle_4 15,
+_segment_2 28 connected to _quadrangle_4 16, _quadrangle_4 19,
+_segment_2 29 connected to _quadrangle_4 16, _quadrangle_4 18,
+_segment_2 30 connected to _quadrangle_4 17, _quadrangle_4 18,
+_segment_2 31 connected to _quadrangle_4 17, _quadrangle_4 19,
+_segment_2 32 connected to _quadrangle_4 18, _quadrangle_4 19,
+ElementToSubelement1
+_point_1 0 connected to _segment_2 0, _segment_2 3, _segment_2 6, _segment_2 31,
+_point_1 1 connected to _segment_2 0, _segment_2 1, _segment_2 9,
+_point_1 2 connected to _segment_2 1, _segment_2 2, _segment_2 7, _segment_2 17,
+_point_1 3 connected to _segment_2 2, _segment_2 3, _segment_2 4, _segment_2 15, _segment_2 20,
+_point_1 4 connected to _segment_2 4, _segment_2 5, _segment_2 8, _segment_2 12, _segment_2 22,
+_point_1 5 connected to _segment_2 5, _segment_2 6, _segment_2 11, _segment_2 28,
+_point_1 6 connected to _segment_2 7, _segment_2 8, _segment_2 10, _segment_2 14,
+_point_1 7 connected to _segment_2 9, _segment_2 10, _segment_2 11,
+_point_1 8 connected to _segment_2 12, _segment_2 13, _segment_2 16, _segment_2 24,
+_point_1 9 connected to _segment_2 13, _segment_2 14, _segment_2 19,
+_point_1 10 connected to _segment_2 15, _segment_2 16, _segment_2 18, _segment_2 27,
+_point_1 11 connected to _segment_2 17, _segment_2 18, _segment_2 19,
+_point_1 12 connected to _segment_2 20, _segment_2 21, _segment_2 25, _segment_2 30,
+_point_1 13 connected to _segment_2 21, _segment_2 22, _segment_2 23, _segment_2 29,
+_point_1 14 connected to _segment_2 23, _segment_2 24, _segment_2 26,
+_point_1 15 connected to _segment_2 25, _segment_2 26, _segment_2 27,
+_point_1 16 connected to _segment_2 28, _segment_2 29, _segment_2 32,
+_point_1 17 connected to _segment_2 30, _segment_2 31, _segment_2 32,
+
+SubelementToElement3
+_hexahedron_8 0 connected to _quadrangle_4 0, _quadrangle_4 1, _quadrangle_4 2, _quadrangle_4 3, _quadrangle_4 4, _quadrangle_4 5,
+_hexahedron_8 1 connected to _quadrangle_4 2, _quadrangle_4 6, _quadrangle_4 7, _quadrangle_4 8, _quadrangle_4 9, _quadrangle_4 10,
+_hexahedron_8 2 connected to _quadrangle_4 7, _quadrangle_4 11, _quadrangle_4 12, _quadrangle_4 13, _quadrangle_4 14, _quadrangle_4 15,
+_hexahedron_8 3 connected to _quadrangle_4 1, _quadrangle_4 11, _quadrangle_4 16, _quadrangle_4 17, _quadrangle_4 18, _quadrangle_4 19,
+SubelementToElement2
+_quadrangle_4 0 connected to _segment_2 0, _segment_2 1, _segment_2 2, _segment_2 3,
+_quadrangle_4 1 connected to _segment_2 3, _segment_2 4, _segment_2 5, _segment_2 6,
+_quadrangle_4 2 connected to _segment_2 2, _segment_2 4, _segment_2 7, _segment_2 8,
+_quadrangle_4 3 connected to _segment_2 1, _segment_2 7, _segment_2 9, _segment_2 10,
+_quadrangle_4 4 connected to _segment_2 0, _segment_2 6, _segment_2 9, _segment_2 11,
+_quadrangle_4 5 connected to _segment_2 5, _segment_2 8, _segment_2 10, _segment_2 11,
+_quadrangle_4 6 connected to _segment_2 8, _segment_2 12, _segment_2 13, _segment_2 14,
+_quadrangle_4 7 connected to _segment_2 4, _segment_2 12, _segment_2 15, _segment_2 16,
+_quadrangle_4 8 connected to _segment_2 2, _segment_2 15, _segment_2 17, _segment_2 18,
+_quadrangle_4 9 connected to _segment_2 7, _segment_2 14, _segment_2 17, _segment_2 19,
+_quadrangle_4 10 connected to _segment_2 13, _segment_2 16, _segment_2 18, _segment_2 19,
+_quadrangle_4 11 connected to _segment_2 4, _segment_2 20, _segment_2 21, _segment_2 22,
+_quadrangle_4 12 connected to _segment_2 12, _segment_2 22, _segment_2 23, _segment_2 24,
+_quadrangle_4 13 connected to _segment_2 21, _segment_2 23, _segment_2 25, _segment_2 26,
+_quadrangle_4 14 connected to _segment_2 15, _segment_2 20, _segment_2 25, _segment_2 27,
+_quadrangle_4 15 connected to _segment_2 16, _segment_2 24, _segment_2 26, _segment_2 27,
+_quadrangle_4 16 connected to _segment_2 5, _segment_2 22, _segment_2 28, _segment_2 29,
+_quadrangle_4 17 connected to _segment_2 3, _segment_2 20, _segment_2 30, _segment_2 31,
+_quadrangle_4 18 connected to _segment_2 21, _segment_2 29, _segment_2 30, _segment_2 32,
+_quadrangle_4 19 connected to _segment_2 6, _segment_2 28, _segment_2 31, _segment_2 32,
+SubelementToElement1
+_segment_2 0 connected to _point_1 0, _point_1 1,
+_segment_2 1 connected to _point_1 1, _point_1 2,
+_segment_2 2 connected to _point_1 2, _point_1 3,
+_segment_2 3 connected to _point_1 0, _point_1 3,
+_segment_2 4 connected to _point_1 3, _point_1 4,
+_segment_2 5 connected to _point_1 4, _point_1 5,
+_segment_2 6 connected to _point_1 0, _point_1 5,
+_segment_2 7 connected to _point_1 2, _point_1 6,
+_segment_2 8 connected to _point_1 4, _point_1 6,
+_segment_2 9 connected to _point_1 1, _point_1 7,
+_segment_2 10 connected to _point_1 6, _point_1 7,
+_segment_2 11 connected to _point_1 5, _point_1 7,
+_segment_2 12 connected to _point_1 4, _point_1 8,
+_segment_2 13 connected to _point_1 8, _point_1 9,
+_segment_2 14 connected to _point_1 6, _point_1 9,
+_segment_2 15 connected to _point_1 3, _point_1 10,
+_segment_2 16 connected to _point_1 8, _point_1 10,
+_segment_2 17 connected to _point_1 2, _point_1 11,
+_segment_2 18 connected to _point_1 10, _point_1 11,
+_segment_2 19 connected to _point_1 9, _point_1 11,
+_segment_2 20 connected to _point_1 3, _point_1 12,
+_segment_2 21 connected to _point_1 12, _point_1 13,
+_segment_2 22 connected to _point_1 4, _point_1 13,
+_segment_2 23 connected to _point_1 13, _point_1 14,
+_segment_2 24 connected to _point_1 8, _point_1 14,
+_segment_2 25 connected to _point_1 12, _point_1 15,
+_segment_2 26 connected to _point_1 14, _point_1 15,
+_segment_2 27 connected to _point_1 10, _point_1 15,
+_segment_2 28 connected to _point_1 5, _point_1 16,
+_segment_2 29 connected to _point_1 13, _point_1 16,
+_segment_2 30 connected to _point_1 12, _point_1 17,
+_segment_2 31 connected to _point_1 0, _point_1 17,
+_segment_2 32 connected to _point_1 16, _point_1 17,
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
new file mode 100644
index 000000000..05aa17362
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
@@ -0,0 +1,128 @@
+/**
+ * @file test_buildfacets_mixed2d_linear.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @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
+ *
+ * @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 <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_linear.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.verified
new file mode 100644
index 000000000..cae7bf393
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.verified
@@ -0,0 +1,48 @@
+ElementToSubelement2
+_segment_2 0 connected to _triangle_3 0, _quadrangle_4 0,
+_segment_2 1 connected to _triangle_3 0, _triangle_3 2,
+_segment_2 2 connected to _triangle_3 0, _not_defined 0,
+_segment_2 3 connected to _triangle_3 1, _quadrangle_4 1,
+_segment_2 4 connected to _triangle_3 1, _triangle_3 3,
+_segment_2 5 connected to _triangle_3 1, _triangle_3 2,
+_segment_2 6 connected to _triangle_3 2, _not_defined 0,
+_segment_2 7 connected to _triangle_3 3, _not_defined 0,
+_segment_2 8 connected to _triangle_3 3, _not_defined 0,
+_segment_2 9 connected to _quadrangle_4 0, _not_defined 0,
+_segment_2 10 connected to _quadrangle_4 0, _quadrangle_4 1,
+_segment_2 11 connected to _quadrangle_4 0, _not_defined 0,
+_segment_2 12 connected to _quadrangle_4 1, _not_defined 0,
+_segment_2 13 connected to _quadrangle_4 1, _not_defined 0,
+ElementToSubelement1
+_point_1 0 connected to _segment_2 0, _segment_2 2, _segment_2 11,
+_point_1 1 connected to _segment_2 0, _segment_2 1, _segment_2 3, _segment_2 5, _segment_2 10,
+_point_1 2 connected to _segment_2 1, _segment_2 2, _segment_2 6,
+_point_1 3 connected to _segment_2 3, _segment_2 4, _segment_2 8, _segment_2 13,
+_point_1 4 connected to _segment_2 4, _segment_2 5, _segment_2 6, _segment_2 7,
+_point_1 5 connected to _segment_2 7, _segment_2 8,
+_point_1 6 connected to _segment_2 9, _segment_2 11,
+_point_1 7 connected to _segment_2 9, _segment_2 10, _segment_2 12,
+_point_1 8 connected to _segment_2 12, _segment_2 13,
+
+SubelementToElement2
+_quadrangle_4 0 connected to _segment_2 0, _segment_2 9, _segment_2 10, _segment_2 11,
+_quadrangle_4 1 connected to _segment_2 3, _segment_2 10, _segment_2 12, _segment_2 13,
+_triangle_3 0 connected to _segment_2 0, _segment_2 1, _segment_2 2,
+_triangle_3 1 connected to _segment_2 3, _segment_2 4, _segment_2 5,
+_triangle_3 2 connected to _segment_2 1, _segment_2 5, _segment_2 6,
+_triangle_3 3 connected to _segment_2 4, _segment_2 7, _segment_2 8,
+SubelementToElement1
+_segment_2 0 connected to _point_1 0, _point_1 1,
+_segment_2 1 connected to _point_1 1, _point_1 2,
+_segment_2 2 connected to _point_1 0, _point_1 2,
+_segment_2 3 connected to _point_1 1, _point_1 3,
+_segment_2 4 connected to _point_1 3, _point_1 4,
+_segment_2 5 connected to _point_1 1, _point_1 4,
+_segment_2 6 connected to _point_1 2, _point_1 4,
+_segment_2 7 connected to _point_1 4, _point_1 5,
+_segment_2 8 connected to _point_1 3, _point_1 5,
+_segment_2 9 connected to _point_1 6, _point_1 7,
+_segment_2 10 connected to _point_1 1, _point_1 7,
+_segment_2 11 connected to _point_1 0, _point_1 6,
+_segment_2 12 connected to _point_1 7, _point_1 8,
+_segment_2 13 connected to _point_1 3, _point_1 8,
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
new file mode 100644
index 000000000..96bbd9bda
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
@@ -0,0 +1,128 @@
+/**
+ * @file test_buildfacets_mixed2d_quadratic.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @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
+ *
+ * @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 <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_mixed2d_quadratic.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.verified
new file mode 100644
index 000000000..ad6ea85ca
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.verified
@@ -0,0 +1,48 @@
+ElementToSubelement2
+_segment_3 0 connected to _triangle_6 0, _quadrangle_8 0,
+_segment_3 1 connected to _triangle_6 0, _triangle_6 2,
+_segment_3 2 connected to _triangle_6 0, _not_defined 0,
+_segment_3 3 connected to _triangle_6 1, _quadrangle_8 1,
+_segment_3 4 connected to _triangle_6 1, _triangle_6 3,
+_segment_3 5 connected to _triangle_6 1, _triangle_6 2,
+_segment_3 6 connected to _triangle_6 2, _not_defined 0,
+_segment_3 7 connected to _triangle_6 3, _not_defined 0,
+_segment_3 8 connected to _triangle_6 3, _not_defined 0,
+_segment_3 9 connected to _quadrangle_8 0, _not_defined 0,
+_segment_3 10 connected to _quadrangle_8 0, _quadrangle_8 1,
+_segment_3 11 connected to _quadrangle_8 0, _not_defined 0,
+_segment_3 12 connected to _quadrangle_8 1, _not_defined 0,
+_segment_3 13 connected to _quadrangle_8 1, _not_defined 0,
+ElementToSubelement1
+_point_1 0 connected to _segment_3 0, _segment_3 2, _segment_3 11,
+_point_1 1 connected to _segment_3 0, _segment_3 1, _segment_3 3, _segment_3 5, _segment_3 10,
+_point_1 2 connected to _segment_3 1, _segment_3 2, _segment_3 6,
+_point_1 3 connected to _segment_3 3, _segment_3 4, _segment_3 8, _segment_3 13,
+_point_1 4 connected to _segment_3 4, _segment_3 5, _segment_3 6, _segment_3 7,
+_point_1 5 connected to _segment_3 7, _segment_3 8,
+_point_1 6 connected to _segment_3 9, _segment_3 11,
+_point_1 7 connected to _segment_3 9, _segment_3 10, _segment_3 12,
+_point_1 8 connected to _segment_3 12, _segment_3 13,
+
+SubelementToElement2
+_quadrangle_8 0 connected to _segment_3 0, _segment_3 9, _segment_3 10, _segment_3 11,
+_quadrangle_8 1 connected to _segment_3 3, _segment_3 10, _segment_3 12, _segment_3 13,
+_triangle_6 0 connected to _segment_3 0, _segment_3 1, _segment_3 2,
+_triangle_6 1 connected to _segment_3 3, _segment_3 4, _segment_3 5,
+_triangle_6 2 connected to _segment_3 1, _segment_3 5, _segment_3 6,
+_triangle_6 3 connected to _segment_3 4, _segment_3 7, _segment_3 8,
+SubelementToElement1
+_segment_3 0 connected to _point_1 0, _point_1 1,
+_segment_3 1 connected to _point_1 1, _point_1 2,
+_segment_3 2 connected to _point_1 0, _point_1 2,
+_segment_3 3 connected to _point_1 1, _point_1 3,
+_segment_3 4 connected to _point_1 3, _point_1 4,
+_segment_3 5 connected to _point_1 1, _point_1 4,
+_segment_3 6 connected to _point_1 2, _point_1 4,
+_segment_3 7 connected to _point_1 4, _point_1 5,
+_segment_3 8 connected to _point_1 3, _point_1 5,
+_segment_3 9 connected to _point_1 6, _point_1 7,
+_segment_3 10 connected to _point_1 1, _point_1 7,
+_segment_3 11 connected to _point_1 0, _point_1 6,
+_segment_3 12 connected to _point_1 7, _point_1 8,
+_segment_3 13 connected to _point_1 3, _point_1 8,
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
new file mode 100644
index 000000000..13fd0dd0e
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
@@ -0,0 +1,167 @@
+/**
+ * @file test_buildfacets_mixed3d_linear.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @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
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <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_linear.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.verified
new file mode 100644
index 000000000..d89918c84
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.verified
@@ -0,0 +1,157 @@
+ElementToSubelement3
+_quadrangle_4 0 connected to _pentahedron_6 0, _pentahedron_6 2,
+_quadrangle_4 1 connected to _pentahedron_6 0, _not_defined 0,
+_quadrangle_4 2 connected to _pentahedron_6 0, _hexahedron_8 0,
+_quadrangle_4 3 connected to _pentahedron_6 1, _pentahedron_6 3,
+_quadrangle_4 4 connected to _pentahedron_6 1, _pentahedron_6 2,
+_quadrangle_4 5 connected to _pentahedron_6 1, _hexahedron_8 1,
+_quadrangle_4 6 connected to _pentahedron_6 2, _not_defined 0,
+_quadrangle_4 7 connected to _pentahedron_6 3, _not_defined 0,
+_quadrangle_4 8 connected to _pentahedron_6 3, _not_defined 0,
+_quadrangle_4 9 connected to _hexahedron_8 0, _not_defined 0,
+_quadrangle_4 10 connected to _hexahedron_8 0, _not_defined 0,
+_quadrangle_4 11 connected to _hexahedron_8 0, _hexahedron_8 1,
+_quadrangle_4 12 connected to _hexahedron_8 0, _not_defined 0,
+_quadrangle_4 13 connected to _hexahedron_8 0, _not_defined 0,
+_quadrangle_4 14 connected to _hexahedron_8 1, _not_defined 0,
+_quadrangle_4 15 connected to _hexahedron_8 1, _not_defined 0,
+_quadrangle_4 16 connected to _hexahedron_8 1, _not_defined 0,
+_quadrangle_4 17 connected to _hexahedron_8 1, _not_defined 0,
+_triangle_3 0 connected to _pentahedron_6 0, _not_defined 0,
+_triangle_3 1 connected to _pentahedron_6 0, _not_defined 0,
+_triangle_3 2 connected to _pentahedron_6 1, _not_defined 0,
+_triangle_3 3 connected to _pentahedron_6 1, _not_defined 0,
+_triangle_3 4 connected to _pentahedron_6 2, _not_defined 0,
+_triangle_3 5 connected to _pentahedron_6 2, _not_defined 0,
+_triangle_3 6 connected to _pentahedron_6 3, _not_defined 0,
+_triangle_3 7 connected to _pentahedron_6 3, _not_defined 0,
+ElementToSubelement2
+_segment_2 0 connected to _triangle_3 0, _quadrangle_4 1,
+_segment_2 1 connected to _triangle_3 0, _quadrangle_4 2, _quadrangle_4 9,
+_segment_2 2 connected to _triangle_3 0, _triangle_3 4, _quadrangle_4 0,
+_segment_2 3 connected to _triangle_3 1, _triangle_3 5, _quadrangle_4 0,
+_segment_2 4 connected to _triangle_3 1, _quadrangle_4 2, _quadrangle_4 13,
+_segment_2 5 connected to _triangle_3 1, _quadrangle_4 1,
+_segment_2 6 connected to _triangle_3 2, _triangle_3 4, _quadrangle_4 4,
+_segment_2 7 connected to _triangle_3 2, _quadrangle_4 5, _quadrangle_4 14,
+_segment_2 8 connected to _triangle_3 2, _triangle_3 6, _quadrangle_4 3,
+_segment_2 9 connected to _triangle_3 3, _triangle_3 7, _quadrangle_4 3,
+_segment_2 10 connected to _triangle_3 3, _quadrangle_4 5, _quadrangle_4 17,
+_segment_2 11 connected to _triangle_3 3, _triangle_3 5, _quadrangle_4 4,
+_segment_2 12 connected to _triangle_3 4, _quadrangle_4 6,
+_segment_2 13 connected to _triangle_3 5, _quadrangle_4 6,
+_segment_2 14 connected to _triangle_3 6, _quadrangle_4 7,
+_segment_2 15 connected to _triangle_3 6, _quadrangle_4 8,
+_segment_2 16 connected to _triangle_3 7, _quadrangle_4 8,
+_segment_2 17 connected to _triangle_3 7, _quadrangle_4 7,
+_segment_2 18 connected to _quadrangle_4 0, _quadrangle_4 2, _quadrangle_4 4, _quadrangle_4 5, _quadrangle_4 11,
+_segment_2 19 connected to _quadrangle_4 0, _quadrangle_4 1, _quadrangle_4 6,
+_segment_2 20 connected to _quadrangle_4 1, _quadrangle_4 2, _quadrangle_4 10,
+_segment_2 21 connected to _quadrangle_4 3, _quadrangle_4 5, _quadrangle_4 7, _quadrangle_4 15,
+_segment_2 22 connected to _quadrangle_4 3, _quadrangle_4 4, _quadrangle_4 6, _quadrangle_4 8,
+_segment_2 23 connected to _quadrangle_4 7, _quadrangle_4 8,
+_segment_2 24 connected to _quadrangle_4 9, _quadrangle_4 12,
+_segment_2 25 connected to _quadrangle_4 9, _quadrangle_4 11, _quadrangle_4 14,
+_segment_2 26 connected to _quadrangle_4 9, _quadrangle_4 10,
+_segment_2 27 connected to _quadrangle_4 10, _quadrangle_4 13,
+_segment_2 28 connected to _quadrangle_4 10, _quadrangle_4 12,
+_segment_2 29 connected to _quadrangle_4 11, _quadrangle_4 12, _quadrangle_4 16,
+_segment_2 30 connected to _quadrangle_4 11, _quadrangle_4 13, _quadrangle_4 17,
+_segment_2 31 connected to _quadrangle_4 12, _quadrangle_4 13,
+_segment_2 32 connected to _quadrangle_4 14, _quadrangle_4 16,
+_segment_2 33 connected to _quadrangle_4 14, _quadrangle_4 15,
+_segment_2 34 connected to _quadrangle_4 15, _quadrangle_4 16,
+_segment_2 35 connected to _quadrangle_4 15, _quadrangle_4 17,
+_segment_2 36 connected to _quadrangle_4 16, _quadrangle_4 17,
+ElementToSubelement1
+_point_1 0 connected to _segment_2 0, _segment_2 2, _segment_2 12, _segment_2 19,
+_point_1 1 connected to _segment_2 0, _segment_2 1, _segment_2 20, _segment_2 26,
+_point_1 2 connected to _segment_2 1, _segment_2 2, _segment_2 6, _segment_2 7, _segment_2 18, _segment_2 25,
+_point_1 3 connected to _segment_2 3, _segment_2 5, _segment_2 13, _segment_2 19,
+_point_1 4 connected to _segment_2 3, _segment_2 4, _segment_2 10, _segment_2 11, _segment_2 18, _segment_2 30,
+_point_1 5 connected to _segment_2 4, _segment_2 5, _segment_2 20, _segment_2 27,
+_point_1 6 connected to _segment_2 6, _segment_2 8, _segment_2 12, _segment_2 15, _segment_2 22,
+_point_1 7 connected to _segment_2 7, _segment_2 8, _segment_2 14, _segment_2 21, _segment_2 33,
+_point_1 8 connected to _segment_2 9, _segment_2 11, _segment_2 13, _segment_2 16, _segment_2 22,
+_point_1 9 connected to _segment_2 9, _segment_2 10, _segment_2 17, _segment_2 21, _segment_2 35,
+_point_1 10 connected to _segment_2 14, _segment_2 15, _segment_2 23,
+_point_1 11 connected to _segment_2 16, _segment_2 17, _segment_2 23,
+_point_1 12 connected to _segment_2 24, _segment_2 26, _segment_2 28,
+_point_1 13 connected to _segment_2 24, _segment_2 25, _segment_2 29, _segment_2 32,
+_point_1 14 connected to _segment_2 27, _segment_2 28, _segment_2 31,
+_point_1 15 connected to _segment_2 29, _segment_2 30, _segment_2 31, _segment_2 36,
+_point_1 16 connected to _segment_2 32, _segment_2 33, _segment_2 34,
+_point_1 17 connected to _segment_2 34, _segment_2 35, _segment_2 36,
+
+SubelementToElement3
+_hexahedron_8 0 connected to _quadrangle_4 2, _quadrangle_4 9, _quadrangle_4 10, _quadrangle_4 11, _quadrangle_4 12, _quadrangle_4 13,
+_hexahedron_8 1 connected to _quadrangle_4 5, _quadrangle_4 11, _quadrangle_4 14, _quadrangle_4 15, _quadrangle_4 16, _quadrangle_4 17,
+_pentahedron_6 0 connected to _triangle_3 0, _triangle_3 1, _quadrangle_4 0, _quadrangle_4 1, _quadrangle_4 2,
+_pentahedron_6 1 connected to _triangle_3 2, _triangle_3 3, _quadrangle_4 3, _quadrangle_4 4, _quadrangle_4 5,
+_pentahedron_6 2 connected to _triangle_3 4, _triangle_3 5, _quadrangle_4 0, _quadrangle_4 4, _quadrangle_4 6,
+_pentahedron_6 3 connected to _triangle_3 6, _triangle_3 7, _quadrangle_4 3, _quadrangle_4 7, _quadrangle_4 8,
+SubelementToElement2
+_quadrangle_4 0 connected to _segment_2 2, _segment_2 3, _segment_2 18, _segment_2 19,
+_quadrangle_4 1 connected to _segment_2 0, _segment_2 5, _segment_2 19, _segment_2 20,
+_quadrangle_4 2 connected to _segment_2 1, _segment_2 4, _segment_2 18, _segment_2 20,
+_quadrangle_4 3 connected to _segment_2 8, _segment_2 9, _segment_2 21, _segment_2 22,
+_quadrangle_4 4 connected to _segment_2 6, _segment_2 11, _segment_2 18, _segment_2 22,
+_quadrangle_4 5 connected to _segment_2 7, _segment_2 10, _segment_2 18, _segment_2 21,
+_quadrangle_4 6 connected to _segment_2 12, _segment_2 13, _segment_2 19, _segment_2 22,
+_quadrangle_4 7 connected to _segment_2 14, _segment_2 17, _segment_2 21, _segment_2 23,
+_quadrangle_4 8 connected to _segment_2 15, _segment_2 16, _segment_2 22, _segment_2 23,
+_quadrangle_4 9 connected to _segment_2 1, _segment_2 24, _segment_2 25, _segment_2 26,
+_quadrangle_4 10 connected to _segment_2 20, _segment_2 26, _segment_2 27, _segment_2 28,
+_quadrangle_4 11 connected to _segment_2 18, _segment_2 25, _segment_2 29, _segment_2 30,
+_quadrangle_4 12 connected to _segment_2 24, _segment_2 28, _segment_2 29, _segment_2 31,
+_quadrangle_4 13 connected to _segment_2 4, _segment_2 27, _segment_2 30, _segment_2 31,
+_quadrangle_4 14 connected to _segment_2 7, _segment_2 25, _segment_2 32, _segment_2 33,
+_quadrangle_4 15 connected to _segment_2 21, _segment_2 33, _segment_2 34, _segment_2 35,
+_quadrangle_4 16 connected to _segment_2 29, _segment_2 32, _segment_2 34, _segment_2 36,
+_quadrangle_4 17 connected to _segment_2 10, _segment_2 30, _segment_2 35, _segment_2 36,
+_triangle_3 0 connected to _segment_2 0, _segment_2 1, _segment_2 2,
+_triangle_3 1 connected to _segment_2 3, _segment_2 4, _segment_2 5,
+_triangle_3 2 connected to _segment_2 6, _segment_2 7, _segment_2 8,
+_triangle_3 3 connected to _segment_2 9, _segment_2 10, _segment_2 11,
+_triangle_3 4 connected to _segment_2 2, _segment_2 6, _segment_2 12,
+_triangle_3 5 connected to _segment_2 3, _segment_2 11, _segment_2 13,
+_triangle_3 6 connected to _segment_2 8, _segment_2 14, _segment_2 15,
+_triangle_3 7 connected to _segment_2 9, _segment_2 16, _segment_2 17,
+SubelementToElement1
+_segment_2 0 connected to _point_1 0, _point_1 1,
+_segment_2 1 connected to _point_1 1, _point_1 2,
+_segment_2 2 connected to _point_1 0, _point_1 2,
+_segment_2 3 connected to _point_1 3, _point_1 4,
+_segment_2 4 connected to _point_1 4, _point_1 5,
+_segment_2 5 connected to _point_1 3, _point_1 5,
+_segment_2 6 connected to _point_1 2, _point_1 6,
+_segment_2 7 connected to _point_1 2, _point_1 7,
+_segment_2 8 connected to _point_1 6, _point_1 7,
+_segment_2 9 connected to _point_1 8, _point_1 9,
+_segment_2 10 connected to _point_1 4, _point_1 9,
+_segment_2 11 connected to _point_1 4, _point_1 8,
+_segment_2 12 connected to _point_1 0, _point_1 6,
+_segment_2 13 connected to _point_1 3, _point_1 8,
+_segment_2 14 connected to _point_1 7, _point_1 10,
+_segment_2 15 connected to _point_1 6, _point_1 10,
+_segment_2 16 connected to _point_1 8, _point_1 11,
+_segment_2 17 connected to _point_1 9, _point_1 11,
+_segment_2 18 connected to _point_1 2, _point_1 4,
+_segment_2 19 connected to _point_1 0, _point_1 3,
+_segment_2 20 connected to _point_1 1, _point_1 5,
+_segment_2 21 connected to _point_1 7, _point_1 9,
+_segment_2 22 connected to _point_1 6, _point_1 8,
+_segment_2 23 connected to _point_1 10, _point_1 11,
+_segment_2 24 connected to _point_1 12, _point_1 13,
+_segment_2 25 connected to _point_1 2, _point_1 13,
+_segment_2 26 connected to _point_1 1, _point_1 12,
+_segment_2 27 connected to _point_1 5, _point_1 14,
+_segment_2 28 connected to _point_1 12, _point_1 14,
+_segment_2 29 connected to _point_1 13, _point_1 15,
+_segment_2 30 connected to _point_1 4, _point_1 15,
+_segment_2 31 connected to _point_1 14, _point_1 15,
+_segment_2 32 connected to _point_1 13, _point_1 16,
+_segment_2 33 connected to _point_1 7, _point_1 16,
+_segment_2 34 connected to _point_1 16, _point_1 17,
+_segment_2 35 connected to _point_1 9, _point_1 17,
+_segment_2 36 connected to _point_1 15, _point_1 17,
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
new file mode 100644
index 000000000..4ebdd56d5
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
@@ -0,0 +1,169 @@
+/**
+ * @file test_buildfacets_mixed3d_quadratic.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @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
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <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_mixed3d_quadratic.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.verified
new file mode 100644
index 000000000..36b30be5d
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.verified
@@ -0,0 +1,158 @@
+ElementToSubelement3
+_quadrangle_8 0 connected to _pentahedron_15 0, _pentahedron_15 2,
+_quadrangle_8 1 connected to _pentahedron_15 0, _not_defined 0,
+_quadrangle_8 2 connected to _pentahedron_15 0, _hexahedron_20 0,
+_quadrangle_8 3 connected to _pentahedron_15 1, _pentahedron_15 3,
+_quadrangle_8 4 connected to _pentahedron_15 1, _pentahedron_15 2,
+_quadrangle_8 5 connected to _pentahedron_15 1, _hexahedron_20 1,
+_quadrangle_8 6 connected to _pentahedron_15 2, _not_defined 0,
+_quadrangle_8 7 connected to _pentahedron_15 3, _not_defined 0,
+_quadrangle_8 8 connected to _pentahedron_15 3, _not_defined 0,
+_quadrangle_8 9 connected to _hexahedron_20 0, _not_defined 0,
+_quadrangle_8 10 connected to _hexahedron_20 0, _hexahedron_20 1,
+_quadrangle_8 11 connected to _hexahedron_20 0, _not_defined 0,
+_quadrangle_8 12 connected to _hexahedron_20 0, _not_defined 0,
+_quadrangle_8 13 connected to _hexahedron_20 0, _not_defined 0,
+_quadrangle_8 14 connected to _hexahedron_20 1, _not_defined 0,
+_quadrangle_8 15 connected to _hexahedron_20 1, _not_defined 0,
+_quadrangle_8 16 connected to _hexahedron_20 1, _not_defined 0,
+_quadrangle_8 17 connected to _hexahedron_20 1, _not_defined 0,
+_triangle_6 0 connected to _pentahedron_15 0, _not_defined 0,
+_triangle_6 1 connected to _pentahedron_15 0, _not_defined 0,
+_triangle_6 2 connected to _pentahedron_15 1, _not_defined 0,
+_triangle_6 3 connected to _pentahedron_15 1, _not_defined 0,
+_triangle_6 4 connected to _pentahedron_15 2, _not_defined 0,
+_triangle_6 5 connected to _pentahedron_15 2, _not_defined 0,
+_triangle_6 6 connected to _pentahedron_15 3, _not_defined 0,
+_triangle_6 7 connected to _pentahedron_15 3, _not_defined 0,
+ElementToSubelement2
+_segment_3 0 connected to _triangle_6 0, _quadrangle_8 1,
+_segment_3 1 connected to _triangle_6 0, _quadrangle_8 2, _quadrangle_8 12,
+_segment_3 2 connected to _triangle_6 0, _triangle_6 4, _quadrangle_8 0,
+_segment_3 3 connected to _triangle_6 1, _triangle_6 5, _quadrangle_8 0,
+_segment_3 4 connected to _triangle_6 1, _quadrangle_8 2, _quadrangle_8 13,
+_segment_3 5 connected to _triangle_6 1, _quadrangle_8 1,
+_segment_3 6 connected to _triangle_6 2, _triangle_6 4, _quadrangle_8 4,
+_segment_3 7 connected to _triangle_6 2, _quadrangle_8 5, _quadrangle_8 16,
+_segment_3 8 connected to _triangle_6 2, _triangle_6 6, _quadrangle_8 3,
+_segment_3 9 connected to _triangle_6 3, _triangle_6 7, _quadrangle_8 3,
+_segment_3 10 connected to _triangle_6 3, _quadrangle_8 5, _quadrangle_8 17,
+_segment_3 11 connected to _triangle_6 3, _triangle_6 5, _quadrangle_8 4,
+_segment_3 12 connected to _triangle_6 4, _quadrangle_8 6,
+_segment_3 13 connected to _triangle_6 5, _quadrangle_8 6,
+_segment_3 14 connected to _triangle_6 6, _quadrangle_8 7,
+_segment_3 15 connected to _triangle_6 6, _quadrangle_8 8,
+_segment_3 16 connected to _triangle_6 7, _quadrangle_8 8,
+_segment_3 17 connected to _triangle_6 7, _quadrangle_8 7,
+_segment_3 18 connected to _quadrangle_8 0, _quadrangle_8 2, _quadrangle_8 4, _quadrangle_8 5, _quadrangle_8 10,
+_segment_3 19 connected to _quadrangle_8 0, _quadrangle_8 1, _quadrangle_8 6,
+_segment_3 20 connected to _quadrangle_8 1, _quadrangle_8 2, _quadrangle_8 9,
+_segment_3 21 connected to _quadrangle_8 3, _quadrangle_8 5, _quadrangle_8 7, _quadrangle_8 14,
+_segment_3 22 connected to _quadrangle_8 3, _quadrangle_8 4, _quadrangle_8 6, _quadrangle_8 8,
+_segment_3 23 connected to _quadrangle_8 7, _quadrangle_8 8,
+_segment_3 24 connected to _quadrangle_8 9, _quadrangle_8 12,
+_segment_3 25 connected to _quadrangle_8 9, _quadrangle_8 13,
+_segment_3 26 connected to _quadrangle_8 9, _quadrangle_8 11,
+_segment_3 27 connected to _quadrangle_8 10, _quadrangle_8 12, _quadrangle_8 16,
+_segment_3 28 connected to _quadrangle_8 10, _quadrangle_8 11, _quadrangle_8 15,
+_segment_3 29 connected to _quadrangle_8 10, _quadrangle_8 13, _quadrangle_8 17,
+_segment_3 30 connected to _quadrangle_8 11, _quadrangle_8 12,
+_segment_3 31 connected to _quadrangle_8 11, _quadrangle_8 13,
+_segment_3 32 connected to _quadrangle_8 14, _quadrangle_8 16,
+_segment_3 33 connected to _quadrangle_8 14, _quadrangle_8 15,
+_segment_3 34 connected to _quadrangle_8 14, _quadrangle_8 17,
+_segment_3 35 connected to _quadrangle_8 15, _quadrangle_8 16,
+_segment_3 36 connected to _quadrangle_8 15, _quadrangle_8 17,
+ElementToSubelement1
+_point_1 0 connected to _segment_3 0, _segment_3 2, _segment_3 12, _segment_3 19,
+_point_1 1 connected to _segment_3 0, _segment_3 1, _segment_3 20, _segment_3 24,
+_point_1 2 connected to _segment_3 1, _segment_3 2, _segment_3 6, _segment_3 7, _segment_3 18, _segment_3 27,
+_point_1 3 connected to _segment_3 3, _segment_3 5, _segment_3 13, _segment_3 19,
+_point_1 4 connected to _segment_3 3, _segment_3 4, _segment_3 10, _segment_3 11, _segment_3 18, _segment_3 29,
+_point_1 5 connected to _segment_3 4, _segment_3 5, _segment_3 20, _segment_3 25,
+_point_1 6 connected to _segment_3 6, _segment_3 8, _segment_3 12, _segment_3 15, _segment_3 22,
+_point_1 7 connected to _segment_3 7, _segment_3 8, _segment_3 14, _segment_3 21, _segment_3 32,
+_point_1 8 connected to _segment_3 9, _segment_3 11, _segment_3 13, _segment_3 16, _segment_3 22,
+_point_1 9 connected to _segment_3 9, _segment_3 10, _segment_3 17, _segment_3 21, _segment_3 34,
+_point_1 10 connected to _segment_3 14, _segment_3 15, _segment_3 23,
+_point_1 11 connected to _segment_3 16, _segment_3 17, _segment_3 23,
+_point_1 12 connected to _segment_3 24, _segment_3 26, _segment_3 30,
+_point_1 13 connected to _segment_3 25, _segment_3 26, _segment_3 31,
+_point_1 14 connected to _segment_3 27, _segment_3 28, _segment_3 30, _segment_3 35,
+_point_1 15 connected to _segment_3 28, _segment_3 29, _segment_3 31, _segment_3 36,
+_point_1 16 connected to _segment_3 32, _segment_3 33, _segment_3 35,
+_point_1 17 connected to _segment_3 33, _segment_3 34, _segment_3 36,
+
+SubelementToElement3
+_hexahedron_20 0 connected to _quadrangle_8 2, _quadrangle_8 9, _quadrangle_8 10, _quadrangle_8 11, _quadrangle_8 12, _quadrangle_8 13,
+_hexahedron_20 1 connected to _quadrangle_8 5, _quadrangle_8 10, _quadrangle_8 14, _quadrangle_8 15, _quadrangle_8 16, _quadrangle_8 17,
+_pentahedron_15 0 connected to _triangle_6 0, _triangle_6 1, _quadrangle_8 0, _quadrangle_8 1, _quadrangle_8 2,
+_pentahedron_15 1 connected to _triangle_6 2, _triangle_6 3, _quadrangle_8 3, _quadrangle_8 4, _quadrangle_8 5,
+_pentahedron_15 2 connected to _triangle_6 4, _triangle_6 5, _quadrangle_8 0, _quadrangle_8 4, _quadrangle_8 6,
+_pentahedron_15 3 connected to _triangle_6 6, _triangle_6 7, _quadrangle_8 3, _quadrangle_8 7, _quadrangle_8 8,
+SubelementToElement2
+_quadrangle_8 0 connected to _segment_3 2, _segment_3 3, _segment_3 18, _segment_3 19,
+_quadrangle_8 1 connected to _segment_3 0, _segment_3 5, _segment_3 19, _segment_3 20,
+_quadrangle_8 2 connected to _segment_3 1, _segment_3 4, _segment_3 18, _segment_3 20,
+_quadrangle_8 3 connected to _segment_3 8, _segment_3 9, _segment_3 21, _segment_3 22,
+_quadrangle_8 4 connected to _segment_3 6, _segment_3 11, _segment_3 18, _segment_3 22,
+_quadrangle_8 5 connected to _segment_3 7, _segment_3 10, _segment_3 18, _segment_3 21,
+_quadrangle_8 6 connected to _segment_3 12, _segment_3 13, _segment_3 19, _segment_3 22,
+_quadrangle_8 7 connected to _segment_3 14, _segment_3 17, _segment_3 21, _segment_3 23,
+_quadrangle_8 8 connected to _segment_3 15, _segment_3 16, _segment_3 22, _segment_3 23,
+_quadrangle_8 9 connected to _segment_3 20, _segment_3 24, _segment_3 25, _segment_3 26,
+_quadrangle_8 10 connected to _segment_3 18, _segment_3 27, _segment_3 28, _segment_3 29,
+_quadrangle_8 11 connected to _segment_3 26, _segment_3 28, _segment_3 30, _segment_3 31,
+_quadrangle_8 12 connected to _segment_3 1, _segment_3 24, _segment_3 27, _segment_3 30,
+_quadrangle_8 13 connected to _segment_3 4, _segment_3 25, _segment_3 29, _segment_3 31,
+_quadrangle_8 14 connected to _segment_3 21, _segment_3 32, _segment_3 33, _segment_3 34,
+_quadrangle_8 15 connected to _segment_3 28, _segment_3 33, _segment_3 35, _segment_3 36,
+_quadrangle_8 16 connected to _segment_3 7, _segment_3 27, _segment_3 32, _segment_3 35,
+_quadrangle_8 17 connected to _segment_3 10, _segment_3 29, _segment_3 34, _segment_3 36,
+SubelementToElement2
+_triangle_6 0 connected to _segment_3 0, _segment_3 1, _segment_3 2,
+_triangle_6 1 connected to _segment_3 3, _segment_3 4, _segment_3 5,
+_triangle_6 2 connected to _segment_3 6, _segment_3 7, _segment_3 8,
+_triangle_6 3 connected to _segment_3 9, _segment_3 10, _segment_3 11,
+_triangle_6 4 connected to _segment_3 2, _segment_3 6, _segment_3 12,
+_triangle_6 5 connected to _segment_3 3, _segment_3 11, _segment_3 13,
+_triangle_6 6 connected to _segment_3 8, _segment_3 14, _segment_3 15,
+_triangle_6 7 connected to _segment_3 9, _segment_3 16, _segment_3 17,
+SubelementToElement1
+_segment_3 0 connected to _point_1 0, _point_1 1,
+_segment_3 1 connected to _point_1 1, _point_1 2,
+_segment_3 2 connected to _point_1 0, _point_1 2,
+_segment_3 3 connected to _point_1 3, _point_1 4,
+_segment_3 4 connected to _point_1 4, _point_1 5,
+_segment_3 5 connected to _point_1 3, _point_1 5,
+_segment_3 6 connected to _point_1 2, _point_1 6,
+_segment_3 7 connected to _point_1 2, _point_1 7,
+_segment_3 8 connected to _point_1 6, _point_1 7,
+_segment_3 9 connected to _point_1 8, _point_1 9,
+_segment_3 10 connected to _point_1 4, _point_1 9,
+_segment_3 11 connected to _point_1 4, _point_1 8,
+_segment_3 12 connected to _point_1 0, _point_1 6,
+_segment_3 13 connected to _point_1 3, _point_1 8,
+_segment_3 14 connected to _point_1 7, _point_1 10,
+_segment_3 15 connected to _point_1 6, _point_1 10,
+_segment_3 16 connected to _point_1 8, _point_1 11,
+_segment_3 17 connected to _point_1 9, _point_1 11,
+_segment_3 18 connected to _point_1 2, _point_1 4,
+_segment_3 19 connected to _point_1 0, _point_1 3,
+_segment_3 20 connected to _point_1 1, _point_1 5,
+_segment_3 21 connected to _point_1 7, _point_1 9,
+_segment_3 22 connected to _point_1 6, _point_1 8,
+_segment_3 23 connected to _point_1 10, _point_1 11,
+_segment_3 24 connected to _point_1 1, _point_1 12,
+_segment_3 25 connected to _point_1 5, _point_1 13,
+_segment_3 26 connected to _point_1 12, _point_1 13,
+_segment_3 27 connected to _point_1 2, _point_1 14,
+_segment_3 28 connected to _point_1 14, _point_1 15,
+_segment_3 29 connected to _point_1 4, _point_1 15,
+_segment_3 30 connected to _point_1 12, _point_1 14,
+_segment_3 31 connected to _point_1 13, _point_1 15,
+_segment_3 32 connected to _point_1 7, _point_1 16,
+_segment_3 33 connected to _point_1 16, _point_1 17,
+_segment_3 34 connected to _point_1 9, _point_1 17,
+_segment_3 35 connected to _point_1 14, _point_1 16,
+_segment_3 36 connected to _point_1 15, _point_1 17,
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
new file mode 100644
index 000000000..208ed4af1
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
@@ -0,0 +1,148 @@
+/**
+ * @file test_buildfacets_pentahedron_15.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date creation: Tue May 08 2012
+ * @date last modification: Mon Sep 28 2015
+ *
+ * @brief Test for cohesive elements
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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_15.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.verified
new file mode 100644
index 000000000..28e18d18d
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.verified
@@ -0,0 +1,103 @@
+ElementToSubelement3
+_triangle_6 0 connected to _pentahedron_15 0, _not_defined 0,
+_triangle_6 1 connected to _pentahedron_15 0, _pentahedron_15 2,
+_triangle_6 2 connected to _pentahedron_15 1, _not_defined 0,
+_triangle_6 3 connected to _pentahedron_15 1, _pentahedron_15 3,
+_triangle_6 4 connected to _pentahedron_15 2, _not_defined 0,
+_triangle_6 5 connected to _pentahedron_15 3, _not_defined 0,
+ElementToSubelement3
+_quadrangle_8 0 connected to _pentahedron_15 0, _pentahedron_15 1,
+_quadrangle_8 1 connected to _pentahedron_15 0, _not_defined 0,
+_quadrangle_8 2 connected to _pentahedron_15 0, _not_defined 0,
+_quadrangle_8 3 connected to _pentahedron_15 1, _not_defined 0,
+_quadrangle_8 4 connected to _pentahedron_15 1, _not_defined 0,
+_quadrangle_8 5 connected to _pentahedron_15 2, _pentahedron_15 3,
+_quadrangle_8 6 connected to _pentahedron_15 2, _not_defined 0,
+_quadrangle_8 7 connected to _pentahedron_15 2, _not_defined 0,
+_quadrangle_8 8 connected to _pentahedron_15 3, _not_defined 0,
+_quadrangle_8 9 connected to _pentahedron_15 3, _not_defined 0,
+ElementToSubelement2
+_segment_3 0 connected to _triangle_6 0, _quadrangle_8 1,
+_segment_3 1 connected to _triangle_6 0, _quadrangle_8 2,
+_segment_3 2 connected to _triangle_6 0, _triangle_6 2, _quadrangle_8 0,
+_segment_3 3 connected to _triangle_6 1, _triangle_6 3, _quadrangle_8 0, _quadrangle_8 5,
+_segment_3 4 connected to _triangle_6 1, _quadrangle_8 2, _quadrangle_8 7,
+_segment_3 5 connected to _triangle_6 1, _quadrangle_8 1, _quadrangle_8 6,
+_segment_3 6 connected to _triangle_6 2, _quadrangle_8 4,
+_segment_3 7 connected to _triangle_6 2, _quadrangle_8 3,
+_segment_3 8 connected to _triangle_6 3, _quadrangle_8 3, _quadrangle_8 8,
+_segment_3 9 connected to _triangle_6 3, _quadrangle_8 4, _quadrangle_8 9,
+_segment_3 10 connected to _triangle_6 4, _triangle_6 5, _quadrangle_8 5,
+_segment_3 11 connected to _triangle_6 4, _quadrangle_8 7,
+_segment_3 12 connected to _triangle_6 4, _quadrangle_8 6,
+_segment_3 13 connected to _triangle_6 5, _quadrangle_8 8,
+_segment_3 14 connected to _triangle_6 5, _quadrangle_8 9,
+_segment_3 15 connected to _quadrangle_8 0, _quadrangle_8 2, _quadrangle_8 3,
+_segment_3 16 connected to _quadrangle_8 0, _quadrangle_8 1, _quadrangle_8 4,
+_segment_3 17 connected to _quadrangle_8 1, _quadrangle_8 2,
+_segment_3 18 connected to _quadrangle_8 3, _quadrangle_8 4,
+_segment_3 19 connected to _quadrangle_8 5, _quadrangle_8 7, _quadrangle_8 8,
+_segment_3 20 connected to _quadrangle_8 5, _quadrangle_8 6, _quadrangle_8 9,
+_segment_3 21 connected to _quadrangle_8 6, _quadrangle_8 7,
+_segment_3 22 connected to _quadrangle_8 8, _quadrangle_8 9,
+ElementToSubelement1
+_point_1 0 connected to _segment_3 0, _segment_3 2, _segment_3 6, _segment_3 16,
+_point_1 1 connected to _segment_3 0, _segment_3 1, _segment_3 17,
+_point_1 2 connected to _segment_3 1, _segment_3 2, _segment_3 7, _segment_3 15,
+_point_1 3 connected to _segment_3 3, _segment_3 5, _segment_3 9, _segment_3 16, _segment_3 20,
+_point_1 4 connected to _segment_3 3, _segment_3 4, _segment_3 8, _segment_3 15, _segment_3 19,
+_point_1 5 connected to _segment_3 4, _segment_3 5, _segment_3 17, _segment_3 21,
+_point_1 6 connected to _segment_3 6, _segment_3 7, _segment_3 18,
+_point_1 7 connected to _segment_3 8, _segment_3 9, _segment_3 18, _segment_3 22,
+_point_1 8 connected to _segment_3 10, _segment_3 12, _segment_3 14, _segment_3 20,
+_point_1 9 connected to _segment_3 10, _segment_3 11, _segment_3 13, _segment_3 19,
+_point_1 10 connected to _segment_3 11, _segment_3 12, _segment_3 21,
+_point_1 11 connected to _segment_3 13, _segment_3 14, _segment_3 22,
+
+SubelementToElement3
+_pentahedron_15 0 connected to _triangle_6 0, _triangle_6 1, _quadrangle_8 0, _quadrangle_8 1, _quadrangle_8 2,
+_pentahedron_15 1 connected to _triangle_6 2, _triangle_6 3, _quadrangle_8 0, _quadrangle_8 3, _quadrangle_8 4,
+_pentahedron_15 2 connected to _triangle_6 1, _triangle_6 4, _quadrangle_8 5, _quadrangle_8 6, _quadrangle_8 7,
+_pentahedron_15 3 connected to _triangle_6 3, _triangle_6 5, _quadrangle_8 5, _quadrangle_8 8, _quadrangle_8 9,
+SubelementToElement2
+_triangle_6 0 connected to _segment_3 0, _segment_3 1, _segment_3 2,
+_triangle_6 1 connected to _segment_3 3, _segment_3 4, _segment_3 5,
+_triangle_6 2 connected to _segment_3 2, _segment_3 6, _segment_3 7,
+_triangle_6 3 connected to _segment_3 3, _segment_3 8, _segment_3 9,
+_triangle_6 4 connected to _segment_3 10, _segment_3 11, _segment_3 12,
+_triangle_6 5 connected to _segment_3 10, _segment_3 13, _segment_3 14,
+SubelementToElement2
+_quadrangle_8 0 connected to _segment_3 2, _segment_3 3, _segment_3 15, _segment_3 16,
+_quadrangle_8 1 connected to _segment_3 0, _segment_3 5, _segment_3 16, _segment_3 17,
+_quadrangle_8 2 connected to _segment_3 1, _segment_3 4, _segment_3 15, _segment_3 17,
+_quadrangle_8 3 connected to _segment_3 7, _segment_3 8, _segment_3 15, _segment_3 18,
+_quadrangle_8 4 connected to _segment_3 6, _segment_3 9, _segment_3 16, _segment_3 18,
+_quadrangle_8 5 connected to _segment_3 3, _segment_3 10, _segment_3 19, _segment_3 20,
+_quadrangle_8 6 connected to _segment_3 5, _segment_3 12, _segment_3 20, _segment_3 21,
+_quadrangle_8 7 connected to _segment_3 4, _segment_3 11, _segment_3 19, _segment_3 21,
+_quadrangle_8 8 connected to _segment_3 8, _segment_3 13, _segment_3 19, _segment_3 22,
+_quadrangle_8 9 connected to _segment_3 9, _segment_3 14, _segment_3 20, _segment_3 22,
+SubelementToElement1
+_segment_3 0 connected to _point_1 0, _point_1 1,
+_segment_3 1 connected to _point_1 1, _point_1 2,
+_segment_3 2 connected to _point_1 0, _point_1 2,
+_segment_3 3 connected to _point_1 3, _point_1 4,
+_segment_3 4 connected to _point_1 4, _point_1 5,
+_segment_3 5 connected to _point_1 3, _point_1 5,
+_segment_3 6 connected to _point_1 0, _point_1 6,
+_segment_3 7 connected to _point_1 2, _point_1 6,
+_segment_3 8 connected to _point_1 4, _point_1 7,
+_segment_3 9 connected to _point_1 3, _point_1 7,
+_segment_3 10 connected to _point_1 8, _point_1 9,
+_segment_3 11 connected to _point_1 9, _point_1 10,
+_segment_3 12 connected to _point_1 8, _point_1 10,
+_segment_3 13 connected to _point_1 9, _point_1 11,
+_segment_3 14 connected to _point_1 8, _point_1 11,
+_segment_3 15 connected to _point_1 2, _point_1 4,
+_segment_3 16 connected to _point_1 0, _point_1 3,
+_segment_3 17 connected to _point_1 1, _point_1 5,
+_segment_3 18 connected to _point_1 6, _point_1 7,
+_segment_3 19 connected to _point_1 4, _point_1 9,
+_segment_3 20 connected to _point_1 3, _point_1 8,
+_segment_3 21 connected to _point_1 5, _point_1 10,
+_segment_3 22 connected to _point_1 7, _point_1 11,
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
new file mode 100644
index 000000000..b11759516
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
@@ -0,0 +1,148 @@
+/**
+ * @file test_buildfacets_pentahedron_6.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date creation: Tue May 08 2012
+ * @date last modification: Mon Sep 28 2015
+ *
+ * @brief Test for cohesive elements
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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_pentahedron_6.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.verified
new file mode 100644
index 000000000..58f6b341d
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.verified
@@ -0,0 +1,103 @@
+ElementToSubelement3
+_triangle_3 0 connected to _pentahedron_6 0, _not_defined 0,
+_triangle_3 1 connected to _pentahedron_6 0, _pentahedron_6 2,
+_triangle_3 2 connected to _pentahedron_6 1, _not_defined 0,
+_triangle_3 3 connected to _pentahedron_6 1, _pentahedron_6 3,
+_triangle_3 4 connected to _pentahedron_6 2, _not_defined 0,
+_triangle_3 5 connected to _pentahedron_6 3, _not_defined 0,
+ElementToSubelement3
+_quadrangle_4 0 connected to _pentahedron_6 0, _pentahedron_6 1,
+_quadrangle_4 1 connected to _pentahedron_6 0, _not_defined 0,
+_quadrangle_4 2 connected to _pentahedron_6 0, _not_defined 0,
+_quadrangle_4 3 connected to _pentahedron_6 1, _not_defined 0,
+_quadrangle_4 4 connected to _pentahedron_6 1, _not_defined 0,
+_quadrangle_4 5 connected to _pentahedron_6 2, _pentahedron_6 3,
+_quadrangle_4 6 connected to _pentahedron_6 2, _not_defined 0,
+_quadrangle_4 7 connected to _pentahedron_6 2, _not_defined 0,
+_quadrangle_4 8 connected to _pentahedron_6 3, _not_defined 0,
+_quadrangle_4 9 connected to _pentahedron_6 3, _not_defined 0,
+ElementToSubelement2
+_segment_2 0 connected to _triangle_3 0, _quadrangle_4 1,
+_segment_2 1 connected to _triangle_3 0, _quadrangle_4 2,
+_segment_2 2 connected to _triangle_3 0, _triangle_3 2, _quadrangle_4 0,
+_segment_2 3 connected to _triangle_3 1, _triangle_3 3, _quadrangle_4 0, _quadrangle_4 5,
+_segment_2 4 connected to _triangle_3 1, _quadrangle_4 2, _quadrangle_4 7,
+_segment_2 5 connected to _triangle_3 1, _quadrangle_4 1, _quadrangle_4 6,
+_segment_2 6 connected to _triangle_3 2, _quadrangle_4 4,
+_segment_2 7 connected to _triangle_3 2, _quadrangle_4 3,
+_segment_2 8 connected to _triangle_3 3, _quadrangle_4 3, _quadrangle_4 8,
+_segment_2 9 connected to _triangle_3 3, _quadrangle_4 4, _quadrangle_4 9,
+_segment_2 10 connected to _triangle_3 4, _triangle_3 5, _quadrangle_4 5,
+_segment_2 11 connected to _triangle_3 4, _quadrangle_4 7,
+_segment_2 12 connected to _triangle_3 4, _quadrangle_4 6,
+_segment_2 13 connected to _triangle_3 5, _quadrangle_4 8,
+_segment_2 14 connected to _triangle_3 5, _quadrangle_4 9,
+_segment_2 15 connected to _quadrangle_4 0, _quadrangle_4 2, _quadrangle_4 3,
+_segment_2 16 connected to _quadrangle_4 0, _quadrangle_4 1, _quadrangle_4 4,
+_segment_2 17 connected to _quadrangle_4 1, _quadrangle_4 2,
+_segment_2 18 connected to _quadrangle_4 3, _quadrangle_4 4,
+_segment_2 19 connected to _quadrangle_4 5, _quadrangle_4 7, _quadrangle_4 8,
+_segment_2 20 connected to _quadrangle_4 5, _quadrangle_4 6, _quadrangle_4 9,
+_segment_2 21 connected to _quadrangle_4 6, _quadrangle_4 7,
+_segment_2 22 connected to _quadrangle_4 8, _quadrangle_4 9,
+ElementToSubelement1
+_point_1 0 connected to _segment_2 0, _segment_2 2, _segment_2 6, _segment_2 16,
+_point_1 1 connected to _segment_2 0, _segment_2 1, _segment_2 17,
+_point_1 2 connected to _segment_2 1, _segment_2 2, _segment_2 7, _segment_2 15,
+_point_1 3 connected to _segment_2 3, _segment_2 5, _segment_2 9, _segment_2 16, _segment_2 20,
+_point_1 4 connected to _segment_2 3, _segment_2 4, _segment_2 8, _segment_2 15, _segment_2 19,
+_point_1 5 connected to _segment_2 4, _segment_2 5, _segment_2 17, _segment_2 21,
+_point_1 6 connected to _segment_2 6, _segment_2 7, _segment_2 18,
+_point_1 7 connected to _segment_2 8, _segment_2 9, _segment_2 18, _segment_2 22,
+_point_1 8 connected to _segment_2 10, _segment_2 12, _segment_2 14, _segment_2 20,
+_point_1 9 connected to _segment_2 10, _segment_2 11, _segment_2 13, _segment_2 19,
+_point_1 10 connected to _segment_2 11, _segment_2 12, _segment_2 21,
+_point_1 11 connected to _segment_2 13, _segment_2 14, _segment_2 22,
+
+SubelementToElement3
+_pentahedron_6 0 connected to _triangle_3 0, _triangle_3 1, _quadrangle_4 0, _quadrangle_4 1, _quadrangle_4 2,
+_pentahedron_6 1 connected to _triangle_3 2, _triangle_3 3, _quadrangle_4 0, _quadrangle_4 3, _quadrangle_4 4,
+_pentahedron_6 2 connected to _triangle_3 1, _triangle_3 4, _quadrangle_4 5, _quadrangle_4 6, _quadrangle_4 7,
+_pentahedron_6 3 connected to _triangle_3 3, _triangle_3 5, _quadrangle_4 5, _quadrangle_4 8, _quadrangle_4 9,
+SubelementToElement2
+_triangle_3 0 connected to _segment_2 0, _segment_2 1, _segment_2 2,
+_triangle_3 1 connected to _segment_2 3, _segment_2 4, _segment_2 5,
+_triangle_3 2 connected to _segment_2 2, _segment_2 6, _segment_2 7,
+_triangle_3 3 connected to _segment_2 3, _segment_2 8, _segment_2 9,
+_triangle_3 4 connected to _segment_2 10, _segment_2 11, _segment_2 12,
+_triangle_3 5 connected to _segment_2 10, _segment_2 13, _segment_2 14,
+SubelementToElement2
+_quadrangle_4 0 connected to _segment_2 2, _segment_2 3, _segment_2 15, _segment_2 16,
+_quadrangle_4 1 connected to _segment_2 0, _segment_2 5, _segment_2 16, _segment_2 17,
+_quadrangle_4 2 connected to _segment_2 1, _segment_2 4, _segment_2 15, _segment_2 17,
+_quadrangle_4 3 connected to _segment_2 7, _segment_2 8, _segment_2 15, _segment_2 18,
+_quadrangle_4 4 connected to _segment_2 6, _segment_2 9, _segment_2 16, _segment_2 18,
+_quadrangle_4 5 connected to _segment_2 3, _segment_2 10, _segment_2 19, _segment_2 20,
+_quadrangle_4 6 connected to _segment_2 5, _segment_2 12, _segment_2 20, _segment_2 21,
+_quadrangle_4 7 connected to _segment_2 4, _segment_2 11, _segment_2 19, _segment_2 21,
+_quadrangle_4 8 connected to _segment_2 8, _segment_2 13, _segment_2 19, _segment_2 22,
+_quadrangle_4 9 connected to _segment_2 9, _segment_2 14, _segment_2 20, _segment_2 22,
+SubelementToElement1
+_segment_2 0 connected to _point_1 0, _point_1 1,
+_segment_2 1 connected to _point_1 1, _point_1 2,
+_segment_2 2 connected to _point_1 0, _point_1 2,
+_segment_2 3 connected to _point_1 3, _point_1 4,
+_segment_2 4 connected to _point_1 4, _point_1 5,
+_segment_2 5 connected to _point_1 3, _point_1 5,
+_segment_2 6 connected to _point_1 0, _point_1 6,
+_segment_2 7 connected to _point_1 2, _point_1 6,
+_segment_2 8 connected to _point_1 4, _point_1 7,
+_segment_2 9 connected to _point_1 3, _point_1 7,
+_segment_2 10 connected to _point_1 8, _point_1 9,
+_segment_2 11 connected to _point_1 9, _point_1 10,
+_segment_2 12 connected to _point_1 8, _point_1 10,
+_segment_2 13 connected to _point_1 9, _point_1 11,
+_segment_2 14 connected to _point_1 8, _point_1 11,
+_segment_2 15 connected to _point_1 2, _point_1 4,
+_segment_2 16 connected to _point_1 0, _point_1 3,
+_segment_2 17 connected to _point_1 1, _point_1 5,
+_segment_2 18 connected to _point_1 6, _point_1 7,
+_segment_2 19 connected to _point_1 4, _point_1 9,
+_segment_2 20 connected to _point_1 3, _point_1 8,
+_segment_2 21 connected to _point_1 5, _point_1 10,
+_segment_2 22 connected to _point_1 7, _point_1 11,
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
new file mode 100644
index 000000000..52d73dd7b
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
@@ -0,0 +1,116 @@
+/**
+ * @file test_buildfacets_quadrangle_4.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_4.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.verified
new file mode 100644
index 000000000..70cbcee51
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.verified
@@ -0,0 +1,42 @@
+ElementToSubelement2
+_segment_2 0 connected to _quadrangle_4 0, _not_defined 0,
+_segment_2 1 connected to _quadrangle_4 0, _quadrangle_4 2,
+_segment_2 2 connected to _quadrangle_4 0, _quadrangle_4 1,
+_segment_2 3 connected to _quadrangle_4 0, _not_defined 0,
+_segment_2 4 connected to _quadrangle_4 1, _quadrangle_4 3,
+_segment_2 5 connected to _quadrangle_4 1, _not_defined 0,
+_segment_2 6 connected to _quadrangle_4 1, _not_defined 0,
+_segment_2 7 connected to _quadrangle_4 2, _not_defined 0,
+_segment_2 8 connected to _quadrangle_4 2, _not_defined 0,
+_segment_2 9 connected to _quadrangle_4 2, _quadrangle_4 3,
+_segment_2 10 connected to _quadrangle_4 3, _not_defined 0,
+_segment_2 11 connected to _quadrangle_4 3, _not_defined 0,
+ElementToSubelement1
+_point_1 0 connected to _segment_2 0, _segment_2 3,
+_point_1 1 connected to _segment_2 0, _segment_2 1, _segment_2 7,
+_point_1 2 connected to _segment_2 1, _segment_2 2, _segment_2 4, _segment_2 9,
+_point_1 3 connected to _segment_2 2, _segment_2 3, _segment_2 6,
+_point_1 4 connected to _segment_2 4, _segment_2 5, _segment_2 11,
+_point_1 5 connected to _segment_2 5, _segment_2 6,
+_point_1 6 connected to _segment_2 7, _segment_2 8,
+_point_1 7 connected to _segment_2 8, _segment_2 9, _segment_2 10,
+_point_1 8 connected to _segment_2 10, _segment_2 11,
+
+SubelementToElement2
+_quadrangle_4 0 connected to _segment_2 0, _segment_2 1, _segment_2 2, _segment_2 3,
+_quadrangle_4 1 connected to _segment_2 2, _segment_2 4, _segment_2 5, _segment_2 6,
+_quadrangle_4 2 connected to _segment_2 1, _segment_2 7, _segment_2 8, _segment_2 9,
+_quadrangle_4 3 connected to _segment_2 4, _segment_2 9, _segment_2 10, _segment_2 11,
+SubelementToElement1
+_segment_2 0 connected to _point_1 0, _point_1 1,
+_segment_2 1 connected to _point_1 1, _point_1 2,
+_segment_2 2 connected to _point_1 2, _point_1 3,
+_segment_2 3 connected to _point_1 0, _point_1 3,
+_segment_2 4 connected to _point_1 2, _point_1 4,
+_segment_2 5 connected to _point_1 4, _point_1 5,
+_segment_2 6 connected to _point_1 3, _point_1 5,
+_segment_2 7 connected to _point_1 1, _point_1 6,
+_segment_2 8 connected to _point_1 6, _point_1 7,
+_segment_2 9 connected to _point_1 2, _point_1 7,
+_segment_2 10 connected to _point_1 7, _point_1 8,
+_segment_2 11 connected to _point_1 4, _point_1 8,
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
new file mode 100644
index 000000000..0072e9aa5
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
@@ -0,0 +1,116 @@
+/**
+ * @file test_buildfacets_quadrangle_8.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_quadrangle_8.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.verified
new file mode 100644
index 000000000..d70084859
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.verified
@@ -0,0 +1,42 @@
+ElementToSubelement2
+_segment_3 0 connected to _quadrangle_8 0, _not_defined 0,
+_segment_3 1 connected to _quadrangle_8 0, _quadrangle_8 2,
+_segment_3 2 connected to _quadrangle_8 0, _quadrangle_8 1,
+_segment_3 3 connected to _quadrangle_8 0, _not_defined 0,
+_segment_3 4 connected to _quadrangle_8 1, _quadrangle_8 3,
+_segment_3 5 connected to _quadrangle_8 1, _not_defined 0,
+_segment_3 6 connected to _quadrangle_8 1, _not_defined 0,
+_segment_3 7 connected to _quadrangle_8 2, _not_defined 0,
+_segment_3 8 connected to _quadrangle_8 2, _not_defined 0,
+_segment_3 9 connected to _quadrangle_8 2, _quadrangle_8 3,
+_segment_3 10 connected to _quadrangle_8 3, _not_defined 0,
+_segment_3 11 connected to _quadrangle_8 3, _not_defined 0,
+ElementToSubelement1
+_point_1 0 connected to _segment_3 0, _segment_3 3,
+_point_1 1 connected to _segment_3 0, _segment_3 1, _segment_3 7,
+_point_1 2 connected to _segment_3 1, _segment_3 2, _segment_3 4, _segment_3 9,
+_point_1 3 connected to _segment_3 2, _segment_3 3, _segment_3 6,
+_point_1 4 connected to _segment_3 4, _segment_3 5, _segment_3 11,
+_point_1 5 connected to _segment_3 5, _segment_3 6,
+_point_1 6 connected to _segment_3 7, _segment_3 8,
+_point_1 7 connected to _segment_3 8, _segment_3 9, _segment_3 10,
+_point_1 8 connected to _segment_3 10, _segment_3 11,
+
+SubelementToElement2
+_quadrangle_8 0 connected to _segment_3 0, _segment_3 1, _segment_3 2, _segment_3 3,
+_quadrangle_8 1 connected to _segment_3 2, _segment_3 4, _segment_3 5, _segment_3 6,
+_quadrangle_8 2 connected to _segment_3 1, _segment_3 7, _segment_3 8, _segment_3 9,
+_quadrangle_8 3 connected to _segment_3 4, _segment_3 9, _segment_3 10, _segment_3 11,
+SubelementToElement1
+_segment_3 0 connected to _point_1 0, _point_1 1,
+_segment_3 1 connected to _point_1 1, _point_1 2,
+_segment_3 2 connected to _point_1 2, _point_1 3,
+_segment_3 3 connected to _point_1 0, _point_1 3,
+_segment_3 4 connected to _point_1 2, _point_1 4,
+_segment_3 5 connected to _point_1 4, _point_1 5,
+_segment_3 6 connected to _point_1 3, _point_1 5,
+_segment_3 7 connected to _point_1 1, _point_1 6,
+_segment_3 8 connected to _point_1 6, _point_1 7,
+_segment_3 9 connected to _point_1 2, _point_1 7,
+_segment_3 10 connected to _point_1 7, _point_1 8,
+_segment_3 11 connected to _point_1 4, _point_1 8,
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron.cc
deleted file mode 100644
index 19ad0eccb..000000000
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron.cc
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * @file test_cohesive_buildfacets_tetrahedron.cc
- *
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date Wed Oct 03 10:20:53 2012
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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.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);
-
- /// build vectors for comparison
- Array<Element> tetrahedron(2);
- tetrahedron(0).type = type;
- tetrahedron(0).element = 1;
-
- tetrahedron(1).type = type;
- tetrahedron(1).element = 11;
-
- Array<Element> triangle(8);
- triangle(0).type = type_facet;
- triangle(0).element = 0;
-
- triangle(1).type = type_facet;
- triangle(1).element = 2;
-
- triangle(2).type = type_facet;
- triangle(2).element = 4;
-
- triangle(3).type = type_facet;
- triangle(3).element = 7;
-
- triangle(4).type = type_facet;
- triangle(4).element = 16;
-
- triangle(5).type = type_facet;
- triangle(5).element = 18;
-
- triangle(6).type = type_facet;
- triangle(6).element = 24;
-
- triangle(7).type = type_facet;
- triangle(7).element = 26;
-
- Array<Element> segment(13);
- segment(0).type = type_subfacet;
- segment(0).element = 0;
-
- segment(1).type = type_subfacet;
- segment(1).element = 1;
-
- segment(2).type = type_subfacet;
- segment(2).element = 3;
-
- segment(3).type = type_subfacet;
- segment(3).element = 7;
-
- segment(4).type = type_subfacet;
- segment(4).element = 9;
-
- segment(5).type = type_subfacet;
- segment(5).element = 12;
-
- segment(6).type = type_subfacet;
- segment(6).element = 13;
-
- segment(7).type = type_subfacet;
- segment(7).element = 16;
-
- segment(8).type = type_subfacet;
- segment(8).element = 18;
-
- segment(9).type = type_subfacet;
- segment(9).element = 21;
-
- segment(10).type = type_subfacet;
- segment(10).element = 27;
-
- segment(11).type = type_subfacet;
- segment(11).element = 32;
-
- segment(12).type = type_subfacet;
- segment(12).element = 34;
-
- /// comparison
-
- for (UInt i = 0; i < tetrahedron.getSize(); ++i) {
- if (tetrahedron(i).type != el_to_subel3(4)[i].type ||
- tetrahedron(i).element != el_to_subel3(4)[i].element) {
- std::cout << tetrahedron(i).element << " " << el_to_subel3(4)[i].element << std::endl;
- std::cout << "The two tetrahedrons connected to triangle 4 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- for (UInt i = 0; i < triangle.getSize(); ++i) {
- if (triangle(i).type != el_to_subel2(0)[i].type ||
- triangle(i).element != el_to_subel2(0)[i].element) {
- std::cout << "The triangles connected to segment 0 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- for (UInt i = 0; i < segment.getSize(); ++i) {
- if (segment(i).type != el_to_subel1(1)[i].type ||
- segment(i).element != el_to_subel1(1)[i].element) {
- std::cout << "The segments connected to point 1 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* 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);
-
- /// build vectors for comparison
- Array<Element> triangle2(mesh.getNbFacetsPerElement(type));
- triangle2(0).type = type_facet;
- triangle2(0).element = 4;
-
- triangle2(1).type = type_facet;
- triangle2(1).element = 5;
-
- triangle2(2).type = type_facet;
- triangle2(2).element = 6;
-
- triangle2(3).type = type_facet;
- triangle2(3).element = 7;
-
- Array<Element> segment2(3);
- segment2(0).type = type_subfacet;
- segment2(0).element = 1;
-
- segment2(1).type = type_subfacet;
- segment2(1).element = 3;
-
- segment2(2).type = type_subfacet;
- segment2(2).element = 4;
-
- Array<Element> point(2);
- point(0).type = mesh.getFacetType(type_subfacet);
- point(0).element = 1;
-
- point(1).type = mesh.getFacetType(type_subfacet);
- point(1).element = 2;
-
- /// comparison
-
- for (UInt i = 0; i < triangle2.getSize(); ++i) {
- if (triangle2(i).type != subel_to_el3(1, i).type ||
- triangle2(i).element != subel_to_el3(1, i).element) {
- std::cout << "The triangles connected to tetrahedron 1 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- for (UInt i = 0; i < segment2.getSize(); ++i) {
- if (segment2(i).type != subel_to_el2(1, i).type ||
- segment2(i).element != subel_to_el2(1, i).element) {
- std::cout << "The segments connected to triangle 1 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
- for (UInt i = 0; i < point.getSize(); ++i) {
- if (point(i).type != subel_to_el1(1, i).type ||
- point(i).element != subel_to_el1(1, i).element) {
- std::cout << "The points connected to segment 1 are wrong"
- << std::endl;
- return EXIT_FAILURE;
- }
- }
-
-
- finalize();
-
- std::cout << "OK: test_cohesive_buildfacets was passed!" << std::endl;
-
- 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
new file mode 100644
index 000000000..70495db8b
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
@@ -0,0 +1,143 @@
+/**
+ * @file test_buildfacets_tetrahedron_10.cc
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @date creation: Tue May 08 2012
+ * @date last modification: Sat Sep 19 2015
+ *
+ * @brief Test for cohesive elements
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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_tetrahedron_10.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.verified
new file mode 100644
index 000000000..a6b2fbc95
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.verified
@@ -0,0 +1,207 @@
+ElementToSubelement3
+_triangle_6 0 connected to _tetrahedron_10 0, _tetrahedron_10 11,
+_triangle_6 1 connected to _tetrahedron_10 0, _tetrahedron_10 12,
+_triangle_6 2 connected to _tetrahedron_10 0, _tetrahedron_10 6,
+_triangle_6 3 connected to _tetrahedron_10 0, _not_defined 0,
+_triangle_6 4 connected to _tetrahedron_10 1, _tetrahedron_10 11,
+_triangle_6 5 connected to _tetrahedron_10 1, _tetrahedron_10 15,
+_triangle_6 6 connected to _tetrahedron_10 1, _not_defined 0,
+_triangle_6 7 connected to _tetrahedron_10 1, _tetrahedron_10 13,
+_triangle_6 8 connected to _tetrahedron_10 2, _not_defined 0,
+_triangle_6 9 connected to _tetrahedron_10 2, _tetrahedron_10 12,
+_triangle_6 10 connected to _tetrahedron_10 2, _not_defined 0,
+_triangle_6 11 connected to _tetrahedron_10 2, _tetrahedron_10 6,
+_triangle_6 12 connected to _tetrahedron_10 3, _tetrahedron_10 5,
+_triangle_6 13 connected to _tetrahedron_10 3, _not_defined 0,
+_triangle_6 14 connected to _tetrahedron_10 3, _not_defined 0,
+_triangle_6 15 connected to _tetrahedron_10 3, _tetrahedron_10 8,
+_triangle_6 16 connected to _tetrahedron_10 4, _tetrahedron_10 8,
+_triangle_6 17 connected to _tetrahedron_10 4, _not_defined 0,
+_triangle_6 18 connected to _tetrahedron_10 4, _tetrahedron_10 6,
+_triangle_6 19 connected to _tetrahedron_10 4, _tetrahedron_10 5,
+_triangle_6 20 connected to _tetrahedron_10 5, _not_defined 0,
+_triangle_6 21 connected to _tetrahedron_10 5, _not_defined 0,
+_triangle_6 22 connected to _tetrahedron_10 6, _not_defined 0,
+_triangle_6 23 connected to _tetrahedron_10 7, _tetrahedron_10 9,
+_triangle_6 24 connected to _tetrahedron_10 7, _tetrahedron_10 8,
+_triangle_6 25 connected to _tetrahedron_10 7, _not_defined 0,
+_triangle_6 26 connected to _tetrahedron_10 7, _tetrahedron_10 13,
+_triangle_6 27 connected to _tetrahedron_10 8, _not_defined 0,
+_triangle_6 28 connected to _tetrahedron_10 9, _not_defined 0,
+_triangle_6 29 connected to _tetrahedron_10 9, _not_defined 0,
+_triangle_6 30 connected to _tetrahedron_10 9, _tetrahedron_10 14,
+_triangle_6 31 connected to _tetrahedron_10 10, _tetrahedron_10 15,
+_triangle_6 32 connected to _tetrahedron_10 10, _tetrahedron_10 11,
+_triangle_6 33 connected to _tetrahedron_10 10, _not_defined 0,
+_triangle_6 34 connected to _tetrahedron_10 10, _not_defined 0,
+_triangle_6 35 connected to _tetrahedron_10 11, _not_defined 0,
+_triangle_6 36 connected to _tetrahedron_10 12, _not_defined 0,
+_triangle_6 37 connected to _tetrahedron_10 12, _not_defined 0,
+_triangle_6 38 connected to _tetrahedron_10 13, _not_defined 0,
+_triangle_6 39 connected to _tetrahedron_10 13, _tetrahedron_10 14,
+_triangle_6 40 connected to _tetrahedron_10 14, _not_defined 0,
+_triangle_6 41 connected to _tetrahedron_10 14, _not_defined 0,
+_triangle_6 42 connected to _tetrahedron_10 15, _not_defined 0,
+_triangle_6 43 connected to _tetrahedron_10 15, _not_defined 0,
+ElementToSubelement2
+_segment_3 0 connected to _triangle_6 0, _triangle_6 2, _triangle_6 4, _triangle_6 7, _triangle_6 16, _triangle_6 18, _triangle_6 24, _triangle_6 26,
+_segment_3 1 connected to _triangle_6 0, _triangle_6 1, _triangle_6 32, _triangle_6 34, _triangle_6 37,
+_segment_3 2 connected to _triangle_6 0, _triangle_6 3, _triangle_6 35,
+_segment_3 3 connected to _triangle_6 1, _triangle_6 2, _triangle_6 9, _triangle_6 11,
+_segment_3 4 connected to _triangle_6 1, _triangle_6 3, _triangle_6 36,
+_segment_3 5 connected to _triangle_6 2, _triangle_6 3, _triangle_6 22,
+_segment_3 6 connected to _triangle_6 4, _triangle_6 6, _triangle_6 35,
+_segment_3 7 connected to _triangle_6 4, _triangle_6 5, _triangle_6 31, _triangle_6 32,
+_segment_3 8 connected to _triangle_6 5, _triangle_6 6, _triangle_6 42,
+_segment_3 9 connected to _triangle_6 5, _triangle_6 7, _triangle_6 39, _triangle_6 40, _triangle_6 43,
+_segment_3 10 connected to _triangle_6 6, _triangle_6 7, _triangle_6 38,
+_segment_3 11 connected to _triangle_6 8, _triangle_6 10,
+_segment_3 12 connected to _triangle_6 8, _triangle_6 9, _triangle_6 37,
+_segment_3 13 connected to _triangle_6 8, _triangle_6 11, _triangle_6 18, _triangle_6 19, _triangle_6 20,
+_segment_3 14 connected to _triangle_6 9, _triangle_6 10, _triangle_6 36,
+_segment_3 15 connected to _triangle_6 10, _triangle_6 11, _triangle_6 22,
+_segment_3 16 connected to _triangle_6 12, _triangle_6 14, _triangle_6 20,
+_segment_3 17 connected to _triangle_6 12, _triangle_6 13, _triangle_6 21,
+_segment_3 18 connected to _triangle_6 12, _triangle_6 15, _triangle_6 16, _triangle_6 19,
+_segment_3 19 connected to _triangle_6 13, _triangle_6 14,
+_segment_3 20 connected to _triangle_6 13, _triangle_6 15, _triangle_6 27,
+_segment_3 21 connected to _triangle_6 14, _triangle_6 15, _triangle_6 23, _triangle_6 24, _triangle_6 29,
+_segment_3 22 connected to _triangle_6 16, _triangle_6 17, _triangle_6 27,
+_segment_3 23 connected to _triangle_6 17, _triangle_6 18, _triangle_6 22,
+_segment_3 24 connected to _triangle_6 17, _triangle_6 19, _triangle_6 21,
+_segment_3 25 connected to _triangle_6 20, _triangle_6 21,
+_segment_3 26 connected to _triangle_6 23, _triangle_6 25, _triangle_6 28,
+_segment_3 27 connected to _triangle_6 23, _triangle_6 26, _triangle_6 30, _triangle_6 39,
+_segment_3 28 connected to _triangle_6 24, _triangle_6 25, _triangle_6 27,
+_segment_3 29 connected to _triangle_6 25, _triangle_6 26, _triangle_6 38,
+_segment_3 30 connected to _triangle_6 28, _triangle_6 29,
+_segment_3 31 connected to _triangle_6 28, _triangle_6 30, _triangle_6 41,
+_segment_3 32 connected to _triangle_6 29, _triangle_6 30, _triangle_6 40,
+_segment_3 33 connected to _triangle_6 31, _triangle_6 33, _triangle_6 42,
+_segment_3 34 connected to _triangle_6 31, _triangle_6 34, _triangle_6 43,
+_segment_3 35 connected to _triangle_6 32, _triangle_6 33, _triangle_6 35,
+_segment_3 36 connected to _triangle_6 33, _triangle_6 34,
+_segment_3 37 connected to _triangle_6 36, _triangle_6 37,
+_segment_3 38 connected to _triangle_6 38, _triangle_6 39, _triangle_6 41,
+_segment_3 39 connected to _triangle_6 40, _triangle_6 41,
+_segment_3 40 connected to _triangle_6 42, _triangle_6 43,
+ElementToSubelement1
+_point_1 0 connected to _segment_3 0, _segment_3 2, _segment_3 5, _segment_3 6, _segment_3 10, _segment_3 22, _segment_3 23, _segment_3 28, _segment_3 29,
+_point_1 1 connected to _segment_3 0, _segment_3 1, _segment_3 3, _segment_3 7, _segment_3 9, _segment_3 12, _segment_3 13, _segment_3 16, _segment_3 18, _segment_3 21, _segment_3 27, _segment_3 32, _segment_3 34,
+_point_1 2 connected to _segment_3 1, _segment_3 2, _segment_3 4, _segment_3 35, _segment_3 36, _segment_3 37,
+_point_1 3 connected to _segment_3 3, _segment_3 4, _segment_3 5, _segment_3 14, _segment_3 15,
+_point_1 4 connected to _segment_3 6, _segment_3 7, _segment_3 8, _segment_3 33, _segment_3 35,
+_point_1 5 connected to _segment_3 8, _segment_3 9, _segment_3 10, _segment_3 38, _segment_3 39, _segment_3 40,
+_point_1 6 connected to _segment_3 11, _segment_3 13, _segment_3 15, _segment_3 23, _segment_3 24, _segment_3 25,
+_point_1 7 connected to _segment_3 11, _segment_3 12, _segment_3 14, _segment_3 37,
+_point_1 8 connected to _segment_3 16, _segment_3 17, _segment_3 19, _segment_3 25,
+_point_1 9 connected to _segment_3 17, _segment_3 18, _segment_3 20, _segment_3 22, _segment_3 24,
+_point_1 10 connected to _segment_3 19, _segment_3 20, _segment_3 21, _segment_3 26, _segment_3 28, _segment_3 30,
+_point_1 11 connected to _segment_3 26, _segment_3 27, _segment_3 29, _segment_3 31, _segment_3 38,
+_point_1 12 connected to _segment_3 30, _segment_3 31, _segment_3 32, _segment_3 39,
+_point_1 13 connected to _segment_3 33, _segment_3 34, _segment_3 36, _segment_3 40,
+
+SubelementToElement3
+_tetrahedron_10 0 connected to _triangle_6 0, _triangle_6 1, _triangle_6 2, _triangle_6 3,
+_tetrahedron_10 1 connected to _triangle_6 4, _triangle_6 5, _triangle_6 6, _triangle_6 7,
+_tetrahedron_10 2 connected to _triangle_6 8, _triangle_6 9, _triangle_6 10, _triangle_6 11,
+_tetrahedron_10 3 connected to _triangle_6 12, _triangle_6 13, _triangle_6 14, _triangle_6 15,
+_tetrahedron_10 4 connected to _triangle_6 16, _triangle_6 17, _triangle_6 18, _triangle_6 19,
+_tetrahedron_10 5 connected to _triangle_6 12, _triangle_6 19, _triangle_6 20, _triangle_6 21,
+_tetrahedron_10 6 connected to _triangle_6 2, _triangle_6 11, _triangle_6 18, _triangle_6 22,
+_tetrahedron_10 7 connected to _triangle_6 23, _triangle_6 24, _triangle_6 25, _triangle_6 26,
+_tetrahedron_10 8 connected to _triangle_6 15, _triangle_6 16, _triangle_6 24, _triangle_6 27,
+_tetrahedron_10 9 connected to _triangle_6 23, _triangle_6 28, _triangle_6 29, _triangle_6 30,
+_tetrahedron_10 10 connected to _triangle_6 31, _triangle_6 32, _triangle_6 33, _triangle_6 34,
+_tetrahedron_10 11 connected to _triangle_6 0, _triangle_6 4, _triangle_6 32, _triangle_6 35,
+_tetrahedron_10 12 connected to _triangle_6 1, _triangle_6 9, _triangle_6 36, _triangle_6 37,
+_tetrahedron_10 13 connected to _triangle_6 7, _triangle_6 26, _triangle_6 38, _triangle_6 39,
+_tetrahedron_10 14 connected to _triangle_6 30, _triangle_6 39, _triangle_6 40, _triangle_6 41,
+_tetrahedron_10 15 connected to _triangle_6 5, _triangle_6 31, _triangle_6 42, _triangle_6 43,
+SubelementToElement2
+_triangle_6 0 connected to _segment_3 0, _segment_3 1, _segment_3 2,
+_triangle_6 1 connected to _segment_3 1, _segment_3 3, _segment_3 4,
+_triangle_6 2 connected to _segment_3 0, _segment_3 3, _segment_3 5,
+_triangle_6 3 connected to _segment_3 2, _segment_3 4, _segment_3 5,
+_triangle_6 4 connected to _segment_3 0, _segment_3 6, _segment_3 7,
+_triangle_6 5 connected to _segment_3 7, _segment_3 8, _segment_3 9,
+_triangle_6 6 connected to _segment_3 6, _segment_3 8, _segment_3 10,
+_triangle_6 7 connected to _segment_3 0, _segment_3 9, _segment_3 10,
+_triangle_6 8 connected to _segment_3 11, _segment_3 12, _segment_3 13,
+_triangle_6 9 connected to _segment_3 3, _segment_3 12, _segment_3 14,
+_triangle_6 10 connected to _segment_3 11, _segment_3 14, _segment_3 15,
+_triangle_6 11 connected to _segment_3 3, _segment_3 13, _segment_3 15,
+_triangle_6 12 connected to _segment_3 16, _segment_3 17, _segment_3 18,
+_triangle_6 13 connected to _segment_3 17, _segment_3 19, _segment_3 20,
+_triangle_6 14 connected to _segment_3 16, _segment_3 19, _segment_3 21,
+_triangle_6 15 connected to _segment_3 18, _segment_3 20, _segment_3 21,
+_triangle_6 16 connected to _segment_3 0, _segment_3 18, _segment_3 22,
+_triangle_6 17 connected to _segment_3 22, _segment_3 23, _segment_3 24,
+_triangle_6 18 connected to _segment_3 0, _segment_3 13, _segment_3 23,
+_triangle_6 19 connected to _segment_3 13, _segment_3 18, _segment_3 24,
+_triangle_6 20 connected to _segment_3 13, _segment_3 16, _segment_3 25,
+_triangle_6 21 connected to _segment_3 17, _segment_3 24, _segment_3 25,
+_triangle_6 22 connected to _segment_3 5, _segment_3 15, _segment_3 23,
+_triangle_6 23 connected to _segment_3 21, _segment_3 26, _segment_3 27,
+_triangle_6 24 connected to _segment_3 0, _segment_3 21, _segment_3 28,
+_triangle_6 25 connected to _segment_3 26, _segment_3 28, _segment_3 29,
+_triangle_6 26 connected to _segment_3 0, _segment_3 27, _segment_3 29,
+_triangle_6 27 connected to _segment_3 20, _segment_3 22, _segment_3 28,
+_triangle_6 28 connected to _segment_3 26, _segment_3 30, _segment_3 31,
+_triangle_6 29 connected to _segment_3 21, _segment_3 30, _segment_3 32,
+_triangle_6 30 connected to _segment_3 27, _segment_3 31, _segment_3 32,
+_triangle_6 31 connected to _segment_3 7, _segment_3 33, _segment_3 34,
+_triangle_6 32 connected to _segment_3 1, _segment_3 7, _segment_3 35,
+_triangle_6 33 connected to _segment_3 33, _segment_3 35, _segment_3 36,
+_triangle_6 34 connected to _segment_3 1, _segment_3 34, _segment_3 36,
+_triangle_6 35 connected to _segment_3 2, _segment_3 6, _segment_3 35,
+_triangle_6 36 connected to _segment_3 4, _segment_3 14, _segment_3 37,
+_triangle_6 37 connected to _segment_3 1, _segment_3 12, _segment_3 37,
+_triangle_6 38 connected to _segment_3 10, _segment_3 29, _segment_3 38,
+_triangle_6 39 connected to _segment_3 9, _segment_3 27, _segment_3 38,
+_triangle_6 40 connected to _segment_3 9, _segment_3 32, _segment_3 39,
+_triangle_6 41 connected to _segment_3 31, _segment_3 38, _segment_3 39,
+_triangle_6 42 connected to _segment_3 8, _segment_3 33, _segment_3 40,
+_triangle_6 43 connected to _segment_3 9, _segment_3 34, _segment_3 40,
+SubelementToElement1
+_segment_3 0 connected to _point_1 0, _point_1 1,
+_segment_3 1 connected to _point_1 1, _point_1 2,
+_segment_3 2 connected to _point_1 0, _point_1 2,
+_segment_3 3 connected to _point_1 1, _point_1 3,
+_segment_3 4 connected to _point_1 2, _point_1 3,
+_segment_3 5 connected to _point_1 0, _point_1 3,
+_segment_3 6 connected to _point_1 0, _point_1 4,
+_segment_3 7 connected to _point_1 1, _point_1 4,
+_segment_3 8 connected to _point_1 4, _point_1 5,
+_segment_3 9 connected to _point_1 1, _point_1 5,
+_segment_3 10 connected to _point_1 0, _point_1 5,
+_segment_3 11 connected to _point_1 6, _point_1 7,
+_segment_3 12 connected to _point_1 1, _point_1 7,
+_segment_3 13 connected to _point_1 1, _point_1 6,
+_segment_3 14 connected to _point_1 3, _point_1 7,
+_segment_3 15 connected to _point_1 3, _point_1 6,
+_segment_3 16 connected to _point_1 1, _point_1 8,
+_segment_3 17 connected to _point_1 8, _point_1 9,
+_segment_3 18 connected to _point_1 1, _point_1 9,
+_segment_3 19 connected to _point_1 8, _point_1 10,
+_segment_3 20 connected to _point_1 9, _point_1 10,
+_segment_3 21 connected to _point_1 1, _point_1 10,
+_segment_3 22 connected to _point_1 0, _point_1 9,
+_segment_3 23 connected to _point_1 0, _point_1 6,
+_segment_3 24 connected to _point_1 6, _point_1 9,
+_segment_3 25 connected to _point_1 6, _point_1 8,
+_segment_3 26 connected to _point_1 10, _point_1 11,
+_segment_3 27 connected to _point_1 1, _point_1 11,
+_segment_3 28 connected to _point_1 0, _point_1 10,
+_segment_3 29 connected to _point_1 0, _point_1 11,
+_segment_3 30 connected to _point_1 10, _point_1 12,
+_segment_3 31 connected to _point_1 11, _point_1 12,
+_segment_3 32 connected to _point_1 1, _point_1 12,
+_segment_3 33 connected to _point_1 4, _point_1 13,
+_segment_3 34 connected to _point_1 1, _point_1 13,
+_segment_3 35 connected to _point_1 2, _point_1 4,
+_segment_3 36 connected to _point_1 2, _point_1 13,
+_segment_3 37 connected to _point_1 2, _point_1 7,
+_segment_3 38 connected to _point_1 5, _point_1 11,
+_segment_3 39 connected to _point_1 5, _point_1 12,
+_segment_3 40 connected to _point_1 5, _point_1 13,
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
new file mode 100644
index 000000000..383648403
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
@@ -0,0 +1,116 @@
+/**
+ * @file test_buildfacets_triangle_3.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_3.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.verified
new file mode 100644
index 000000000..55854cf53
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.verified
@@ -0,0 +1,54 @@
+ElementToSubelement2
+_segment_2 0 connected to _triangle_3 0, _not_defined 0,
+_segment_2 1 connected to _triangle_3 0, _triangle_3 1,
+_segment_2 2 connected to _triangle_3 0, _not_defined 0,
+_segment_2 3 connected to _triangle_3 1, _triangle_3 4,
+_segment_2 4 connected to _triangle_3 1, _triangle_3 2,
+_segment_2 5 connected to _triangle_3 2, _triangle_3 3,
+_segment_2 6 connected to _triangle_3 2, _not_defined 0,
+_segment_2 7 connected to _triangle_3 3, _triangle_3 6,
+_segment_2 8 connected to _triangle_3 3, _not_defined 0,
+_segment_2 9 connected to _triangle_3 4, _not_defined 0,
+_segment_2 10 connected to _triangle_3 4, _triangle_3 5,
+_segment_2 11 connected to _triangle_3 5, _not_defined 0,
+_segment_2 12 connected to _triangle_3 5, _triangle_3 6,
+_segment_2 13 connected to _triangle_3 6, _triangle_3 7,
+_segment_2 14 connected to _triangle_3 7, _not_defined 0,
+_segment_2 15 connected to _triangle_3 7, _not_defined 0,
+ElementToSubelement1
+_point_1 0 connected to _segment_2 0, _segment_2 2,
+_point_1 1 connected to _segment_2 0, _segment_2 1, _segment_2 3, _segment_2 9,
+_point_1 2 connected to _segment_2 1, _segment_2 2, _segment_2 4, _segment_2 6,
+_point_1 3 connected to _segment_2 3, _segment_2 4, _segment_2 5, _segment_2 7, _segment_2 10, _segment_2 12,
+_point_1 4 connected to _segment_2 5, _segment_2 6, _segment_2 8,
+_point_1 5 connected to _segment_2 7, _segment_2 8, _segment_2 13, _segment_2 15,
+_point_1 6 connected to _segment_2 9, _segment_2 10, _segment_2 11,
+_point_1 7 connected to _segment_2 11, _segment_2 12, _segment_2 13, _segment_2 14,
+_point_1 8 connected to _segment_2 14, _segment_2 15,
+
+SubelementToElement2
+_triangle_3 0 connected to _segment_2 0, _segment_2 1, _segment_2 2,
+_triangle_3 1 connected to _segment_2 1, _segment_2 3, _segment_2 4,
+_triangle_3 2 connected to _segment_2 4, _segment_2 5, _segment_2 6,
+_triangle_3 3 connected to _segment_2 5, _segment_2 7, _segment_2 8,
+_triangle_3 4 connected to _segment_2 3, _segment_2 9, _segment_2 10,
+_triangle_3 5 connected to _segment_2 10, _segment_2 11, _segment_2 12,
+_triangle_3 6 connected to _segment_2 7, _segment_2 12, _segment_2 13,
+_triangle_3 7 connected to _segment_2 13, _segment_2 14, _segment_2 15,
+SubelementToElement1
+_segment_2 0 connected to _point_1 0, _point_1 1,
+_segment_2 1 connected to _point_1 1, _point_1 2,
+_segment_2 2 connected to _point_1 0, _point_1 2,
+_segment_2 3 connected to _point_1 1, _point_1 3,
+_segment_2 4 connected to _point_1 2, _point_1 3,
+_segment_2 5 connected to _point_1 3, _point_1 4,
+_segment_2 6 connected to _point_1 2, _point_1 4,
+_segment_2 7 connected to _point_1 3, _point_1 5,
+_segment_2 8 connected to _point_1 4, _point_1 5,
+_segment_2 9 connected to _point_1 1, _point_1 6,
+_segment_2 10 connected to _point_1 3, _point_1 6,
+_segment_2 11 connected to _point_1 6, _point_1 7,
+_segment_2 12 connected to _point_1 3, _point_1 7,
+_segment_2 13 connected to _point_1 5, _point_1 7,
+_segment_2 14 connected to _point_1 7, _point_1 8,
+_segment_2 15 connected to _point_1 5, _point_1 8,
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
new file mode 100644
index 000000000..5e0a5f12d
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
@@ -0,0 +1,116 @@
+/**
+ * @file test_buildfacets_triangle_6.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_buildfacets/test_buildfacets_triangle_6.verified b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.verified
new file mode 100644
index 000000000..95aa76a93
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.verified
@@ -0,0 +1,54 @@
+ElementToSubelement2
+_segment_3 0 connected to _triangle_6 0, _not_defined 0,
+_segment_3 1 connected to _triangle_6 0, _triangle_6 1,
+_segment_3 2 connected to _triangle_6 0, _not_defined 0,
+_segment_3 3 connected to _triangle_6 1, _triangle_6 4,
+_segment_3 4 connected to _triangle_6 1, _triangle_6 2,
+_segment_3 5 connected to _triangle_6 2, _triangle_6 3,
+_segment_3 6 connected to _triangle_6 2, _not_defined 0,
+_segment_3 7 connected to _triangle_6 3, _triangle_6 6,
+_segment_3 8 connected to _triangle_6 3, _not_defined 0,
+_segment_3 9 connected to _triangle_6 4, _not_defined 0,
+_segment_3 10 connected to _triangle_6 4, _triangle_6 5,
+_segment_3 11 connected to _triangle_6 5, _not_defined 0,
+_segment_3 12 connected to _triangle_6 5, _triangle_6 6,
+_segment_3 13 connected to _triangle_6 6, _triangle_6 7,
+_segment_3 14 connected to _triangle_6 7, _not_defined 0,
+_segment_3 15 connected to _triangle_6 7, _not_defined 0,
+ElementToSubelement1
+_point_1 0 connected to _segment_3 0, _segment_3 2,
+_point_1 1 connected to _segment_3 0, _segment_3 1, _segment_3 3, _segment_3 9,
+_point_1 2 connected to _segment_3 1, _segment_3 2, _segment_3 4, _segment_3 6,
+_point_1 3 connected to _segment_3 3, _segment_3 4, _segment_3 5, _segment_3 7, _segment_3 10, _segment_3 12,
+_point_1 4 connected to _segment_3 5, _segment_3 6, _segment_3 8,
+_point_1 5 connected to _segment_3 7, _segment_3 8, _segment_3 13, _segment_3 15,
+_point_1 6 connected to _segment_3 9, _segment_3 10, _segment_3 11,
+_point_1 7 connected to _segment_3 11, _segment_3 12, _segment_3 13, _segment_3 14,
+_point_1 8 connected to _segment_3 14, _segment_3 15,
+
+SubelementToElement2
+_triangle_6 0 connected to _segment_3 0, _segment_3 1, _segment_3 2,
+_triangle_6 1 connected to _segment_3 1, _segment_3 3, _segment_3 4,
+_triangle_6 2 connected to _segment_3 4, _segment_3 5, _segment_3 6,
+_triangle_6 3 connected to _segment_3 5, _segment_3 7, _segment_3 8,
+_triangle_6 4 connected to _segment_3 3, _segment_3 9, _segment_3 10,
+_triangle_6 5 connected to _segment_3 10, _segment_3 11, _segment_3 12,
+_triangle_6 6 connected to _segment_3 7, _segment_3 12, _segment_3 13,
+_triangle_6 7 connected to _segment_3 13, _segment_3 14, _segment_3 15,
+SubelementToElement1
+_segment_3 0 connected to _point_1 0, _point_1 1,
+_segment_3 1 connected to _point_1 1, _point_1 2,
+_segment_3 2 connected to _point_1 0, _point_1 2,
+_segment_3 3 connected to _point_1 1, _point_1 3,
+_segment_3 4 connected to _point_1 2, _point_1 3,
+_segment_3 5 connected to _point_1 3, _point_1 4,
+_segment_3 6 connected to _point_1 2, _point_1 4,
+_segment_3 7 connected to _point_1 3, _point_1 5,
+_segment_3 8 connected to _point_1 4, _point_1 5,
+_segment_3 9 connected to _point_1 1, _point_1 6,
+_segment_3 10 connected to _point_1 3, _point_1 6,
+_segment_3 11 connected to _point_1 6, _point_1 7,
+_segment_3 12 connected to _point_1 3, _point_1 7,
+_segment_3 13 connected to _point_1 5, _point_1 7,
+_segment_3 14 connected to _point_1 7, _point_1 8,
+_segment_3 15 connected to _point_1 5, _point_1 8,
diff --git a/test/test_mesh_utils/test_buildfacets/tetrahedron.msh b/test/test_mesh_utils/test_buildfacets/tetrahedron_10.msh
similarity index 100%
rename from test/test_mesh_utils/test_buildfacets/tetrahedron.msh
rename to test/test_mesh_utils/test_buildfacets/tetrahedron_10.msh
diff --git a/test/test_mesh_utils/test_buildfacets/triangle_3.msh b/test/test_mesh_utils/test_buildfacets/triangle_3.msh
new file mode 100644
index 000000000..436610c75
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/triangle_3.msh
@@ -0,0 +1,26 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+9
+1 0 0 0
+2 1 0 0
+3 0 1 0
+4 1 1 0
+5 0 2 0
+6 1 2 0
+7 2 0 0
+8 2 1 0
+9 2 2 0
+$EndNodes
+$Elements
+8
+1 2 2 0 0 1 2 3
+2 2 2 0 0 2 4 3
+3 2 2 0 0 3 4 5
+4 2 2 0 0 4 6 5
+5 2 2 0 0 2 7 4
+6 2 2 0 0 7 8 4
+7 2 2 0 0 4 8 6
+8 2 2 0 0 8 9 6
+$EndElements
diff --git a/test/test_mesh_utils/test_buildfacets/triangle_6.msh b/test/test_mesh_utils/test_buildfacets/triangle_6.msh
new file mode 100644
index 000000000..8d9f20790
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/triangle_6.msh
@@ -0,0 +1,42 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+25
+1 0 0 0
+2 1 0 0
+3 0 1 0
+4 1 1 0
+5 0 2 0
+6 1 2 0
+7 2 0 0
+8 2 1 0
+9 2 2 0
+10 0.5 0 0
+11 0.5 0.5 0
+12 0 0.5 0
+13 1 0.5 0
+14 0.5 1 0
+15 0.5 1.5 0
+16 0 1.5 0
+17 1 1.5 0
+18 0.5 2 0
+19 1.5 0 0
+20 1.5 0.5 0
+21 2 0.5 0
+22 1.5 1 0
+23 1.5 1.5 0
+24 2 1.5 0
+25 1.5 2 0
+$EndNodes
+$Elements
+8
+1 9 2 0 0 1 2 3 10 11 12
+2 9 2 0 0 2 4 3 13 14 11
+3 9 2 0 0 3 4 5 14 15 16
+4 9 2 0 0 4 6 5 17 18 15
+5 9 2 0 0 2 7 4 19 20 13
+6 9 2 0 0 7 8 4 21 22 20
+7 9 2 0 0 4 8 6 22 23 17
+8 9 2 0 0 8 9 6 24 25 23
+$EndElements
diff --git a/test/test_mesh_utils/test_mesh_io/CMakeLists.txt b/test/test_mesh_utils/test_mesh_io/CMakeLists.txt
index 45b60ff1b..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
- DEPENDENCIES test_msh_cube
+ 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
- DEPENDENCIES test_msh_cube_physical_names
+ 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 1e3e024ee..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
- DEPENDENCIES test_mesh_partitionate_mesh
+ 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
- DEPENDENCIES test_mesh_partitionate_mesh_data_mesh
+ 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 2ffeed57d..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
- DEPENDENCIES test_pbc_cube_mesh
+ 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
new file mode 100644
index 000000000..aea1a0789
--- /dev/null
+++ b/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt
@@ -0,0 +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/mesh.geo b/test/test_mesh_utils/test_segment_nodetype/mesh.geo
new file mode 100644
index 000000000..17355b05f
--- /dev/null
+++ b/test/test_mesh_utils/test_segment_nodetype/mesh.geo
@@ -0,0 +1,14 @@
+L = 1;
+
+Point(1) = {-L/2., 0, 0, L/2};
+
+line[] = Extrude{L,0,0}{ Point{1}; };
+surface[] = Extrude{0,L,0}{ Line{line[1]}; };
+volume[] = Extrude{0,0,L/2}{ Surface{surface[1]}; };
+
+Physical Volume(1) = {volume[1]};
+//Physical Surface(1) = {surface[1]};
+
+Transfinite Surface "*";
+Recombine Surface "*";
+Transfinite Volume "*";
diff --git a/test/test_mesh_utils/test_segment_nodetype/mesh.msh b/test/test_mesh_utils/test_segment_nodetype/mesh.msh
new file mode 100644
index 000000000..188e32acc
--- /dev/null
+++ b/test/test_mesh_utils/test_segment_nodetype/mesh.msh
@@ -0,0 +1,44 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+27
+1 -0.5 0 0
+2 0.5 0 0
+3 -0.5 1 0
+4 0.5 1 0
+5 -0.5 0 0.5
+6 0.5 0 0.5
+7 0.5 1 0.5
+8 -0.5 1 0.5
+9 -1.376398994779038e-12 0 0
+10 -1.376398994779038e-12 1 0
+11 -0.5 0.499999999998694 0
+12 0.5 0.499999999998694 0
+13 -1.376398994779038e-12 0 0.5
+14 0.5 0.499999999998694 0.5
+15 1.376398994779038e-12 1 0.5
+16 -0.5 0.5000000000020591 0.5
+17 -0.5 0 0.249999999999347
+18 0.5 0 0.249999999999347
+19 0.5 1 0.249999999999347
+20 -0.5 1 0.249999999999347
+21 -1.376454505930269e-12 0.499999999998694 0
+22 -1.376454505930269e-12 0 0.249999999999347
+23 0.5 0.4999999999986939 0.249999999999347
+24 0 1 0.2499999999993469
+25 -0.5 0.5000000000003766 0.2499999999993469
+26 0 0.5000000000003766 0.5
+27 -6.882411307529424e-13 0.4999999999995353 0.2499999999993469
+$EndNodes
+$Elements
+8
+1 5 2 1 1 1 9 21 11 17 22 27 25
+2 5 2 1 1 17 22 27 25 5 13 26 16
+3 5 2 1 1 11 21 10 3 25 27 24 20
+4 5 2 1 1 25 27 24 20 16 26 15 8
+5 5 2 1 1 9 2 12 21 22 18 23 27
+6 5 2 1 1 22 18 23 27 13 6 14 26
+7 5 2 1 1 21 12 4 10 27 23 19 24
+8 5 2 1 1 27 23 19 24 26 14 7 15
+$EndElements
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
new file mode 100644
index 000000000..fc9fadad7
--- /dev/null
+++ b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
@@ -0,0 +1,107 @@
+/**
+ * @file test_segment_nodetype.cc
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "mesh_utils.hh"
+#include "distributed_synchronizer.hh"
+
+/* -------------------------------------------------------------------------- */
+using namespace akantu;
+
+int main(int argc, char * argv[]) {
+ initialize(argc, argv);
+
+ UInt spatial_dimension = 3;
+ Mesh mesh(spatial_dimension);
+
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+ Int psize = comm.getNbProc();
+ Int prank = comm.whoAmI();
+ DistributedSynchronizer * dist = NULL;
+
+ // partition the mesh
+ if (prank == 0) {
+ mesh.read("mesh.msh");
+ MeshPartitionScotch partition(mesh, spatial_dimension);
+ partition.partitionate(psize);
+ dist = DistributedSynchronizer::createDistributedSynchronizerMesh(
+ mesh, &partition);
+ } else {
+ dist =
+ DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ }
+
+ // compute the node types for each segment
+ Mesh mesh_facets(mesh.initMeshFacets());
+ MeshUtils::buildSegmentToNodeType(mesh, mesh_facets, dist);
+
+ // verify that the number of segments per node type makes sense
+ std::map<Int, UInt> nb_facets_per_nodetype;
+ UInt nb_segments = 0;
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+ GhostType ghost_type = *gt;
+
+ const Array<Int> & segment_to_nodetype =
+ mesh_facets.getData<Int>("segment_to_nodetype", _segment_2, ghost_type);
+
+ // count the number of segments per node type
+ for (UInt s = 0; s < segment_to_nodetype.getSize(); ++s) {
+ if (nb_facets_per_nodetype.find(segment_to_nodetype(s)) ==
+ nb_facets_per_nodetype.end())
+ nb_facets_per_nodetype[segment_to_nodetype(s)] = 1;
+ else
+ ++nb_facets_per_nodetype[segment_to_nodetype(s)];
+ }
+ nb_segments += segment_to_nodetype.getSize();
+ }
+
+ // checking the solution
+ if (nb_segments != 24)
+ AKANTU_DEBUG_ERROR("The number of segments is wrong");
+
+ if (prank == 0) {
+ if (nb_facets_per_nodetype[-1] != 3 || nb_facets_per_nodetype[-2] != 9 ||
+ nb_facets_per_nodetype[-3] != 12)
+ AKANTU_DEBUG_ERROR(
+ "The segments of processor 0 have the wrong node type");
+
+ if (nb_facets_per_nodetype.size() > 3)
+ AKANTU_DEBUG_ERROR("Processor 0 cannot have any slave segment");
+ }
+
+ if (prank == psize - 1 &&
+ nb_facets_per_nodetype.find(-2) != nb_facets_per_nodetype.end())
+ AKANTU_DEBUG_ERROR("The last processor must not have any master facets");
+
+ finalize();
+ return 0;
+}
diff --git a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.sh b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.sh
new file mode 100755
index 000000000..f49a62700
--- /dev/null
+++ b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+mpirun -np 8 ./test_segment_nodetype
diff --git a/test/test_model/CMakeLists.txt b/test/test_model/CMakeLists.txt
index b9b96137c..2d6a5987c 100644
--- a/test/test_model/CMakeLists.txt
+++ b/test/test_model/CMakeLists.txt
@@ -1,37 +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")
\ No newline at end of file
+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 4707414da..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
- DEPENDENCIES test_heat_cube3d_mesh1 test_heat_square_mesh1 test_heat_line_mesh
+ 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
- DEPENDENCIES test_heat_cube_tet4
+ 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
- DEPENDENCIES test_heat_square_tri3
+ 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
- DEPENDENCIES test_heat_square_tri3
+ 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
- DEPENDENCIES test_heat_square_tri3
+ 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
- DEPENDENCIES test_heat_cube3d_mesh1
+ 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
new file mode 100644
index 000000000..a00855e9f
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/CMakeLists.txt
@@ -0,0 +1,75 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+# @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+#
+# @date creation: Sat Sep 26 2015
+# @date last modification: Wed Dec 16 2015
+#
+# @brief configuration for heat transfer model 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/>.
+#
+# @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/fine_mesh.msh b/test/test_model/test_non_local_toolbox/fine_mesh.msh
new file mode 100644
index 000000000..599110623
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/fine_mesh.msh
@@ -0,0 +1,223 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$PhysicalNames
+2
+2 1 "mat_1"
+2 2 "mat_2"
+$EndPhysicalNames
+$Nodes
+81
+1 -1 -1 0
+2 0 -1 0
+3 1 -1 0
+4 -1 1 0
+5 0 1 0
+6 1 1 0
+7 -0.7500000000003465 -1 0
+8 -0.5000000000020591 -1 0
+9 -0.2500000000010404 -1 0
+10 0.2499999999994121 -1 0
+11 0.499999999998694 -1 0
+12 0.7499999999993416 -1 0
+13 -0.7500000000003465 1 0
+14 -0.5000000000020591 1 0
+15 -0.2500000000010404 1 0
+16 -1 -0.7500000000006933 0
+17 -1 -0.5000000000013871 0
+18 -1 -0.2500000000020808 0
+19 -1 -2.752797989558076e-12 0
+20 -1 0.2499999999979192 0
+21 -1 0.4999999999986129 0
+22 -1 0.7499999999993063 0
+23 0 -0.7500000000006933 0
+24 0 -0.5000000000013871 0
+25 0 -0.2500000000020808 0
+26 0 -2.752797989558076e-12 0
+27 0 0.2499999999979192 0
+28 0 0.4999999999986129 0
+29 0 0.7499999999993063 0
+30 0.2499999999994121 1 0
+31 0.499999999998694 1 0
+32 0.7499999999993416 1 0
+33 1 -0.7500000000006933 0
+34 1 -0.5000000000013871 0
+35 1 -0.2500000000020808 0
+36 1 -2.752797989558076e-12 0
+37 1 0.2499999999979192 0
+38 1 0.4999999999986129 0
+39 1 0.7499999999993063 0
+40 -0.7500000000003465 -0.7500000000006932 0
+41 -0.7500000000003465 -0.5000000000013871 0
+42 -0.7500000000003465 -0.2500000000020808 0
+43 -0.7500000000003465 -2.753020034163001e-12 0
+44 -0.7500000000003465 0.2499999999979192 0
+45 -0.7500000000003465 0.4999999999986127 0
+46 -0.7500000000003465 0.7499999999993063 0
+47 -0.5000000000020591 -0.7500000000006932 0
+48 -0.5000000000020591 -0.5000000000013871 0
+49 -0.5000000000020591 -0.2500000000020808 0
+50 -0.5000000000020591 -2.752909011860538e-12 0
+51 -0.5000000000020591 0.2499999999979192 0
+52 -0.5000000000020591 0.4999999999986129 0
+53 -0.5000000000020591 0.7499999999993063 0
+54 -0.2500000000010404 -0.7500000000006932 0
+55 -0.2500000000010404 -0.5000000000013871 0
+56 -0.2500000000010404 -0.2500000000020808 0
+57 -0.2500000000010405 -2.752797989558076e-12 0
+58 -0.2500000000010402 0.2499999999979192 0
+59 -0.2500000000010403 0.4999999999986131 0
+60 -0.2500000000010404 0.7499999999993063 0
+61 0.2499999999994121 -0.7500000000006932 0
+62 0.249999999999412 -0.5000000000013871 0
+63 0.249999999999412 -0.2500000000020808 0
+64 0.2499999999994121 -2.753131056465463e-12 0
+65 0.249999999999412 0.2499999999979192 0
+66 0.249999999999412 0.4999999999986131 0
+67 0.249999999999412 0.7499999999993063 0
+68 0.4999999999986939 -0.7500000000006932 0
+69 0.4999999999986941 -0.5000000000013871 0
+70 0.4999999999986939 -0.2500000000020808 0
+71 0.499999999998694 -2.752909011860538e-12 0
+72 0.4999999999986939 0.2499999999979194 0
+73 0.4999999999986939 0.4999999999986131 0
+74 0.4999999999986939 0.7499999999993063 0
+75 0.7499999999993416 -0.7500000000006932 0
+76 0.7499999999993416 -0.5000000000013871 0
+77 0.7499999999993416 -0.2500000000020808 0
+78 0.7499999999993416 -2.752797989558076e-12 0
+79 0.7499999999993416 0.2499999999979192 0
+80 0.7499999999993416 0.4999999999986129 0
+81 0.7499999999993416 0.7499999999993063 0
+$EndNodes
+$Elements
+128
+1 2 2 1 6 1 7 16
+2 2 2 1 6 16 7 40
+3 2 2 1 6 16 40 17
+4 2 2 1 6 17 40 41
+5 2 2 1 6 17 41 18
+6 2 2 1 6 18 41 42
+7 2 2 1 6 18 42 19
+8 2 2 1 6 19 42 43
+9 2 2 1 6 19 43 20
+10 2 2 1 6 20 43 44
+11 2 2 1 6 20 44 21
+12 2 2 1 6 21 44 45
+13 2 2 1 6 21 45 22
+14 2 2 1 6 22 45 46
+15 2 2 1 6 22 46 4
+16 2 2 1 6 4 46 13
+17 2 2 1 6 7 8 40
+18 2 2 1 6 40 8 47
+19 2 2 1 6 40 47 41
+20 2 2 1 6 41 47 48
+21 2 2 1 6 41 48 42
+22 2 2 1 6 42 48 49
+23 2 2 1 6 42 49 43
+24 2 2 1 6 43 49 50
+25 2 2 1 6 43 50 44
+26 2 2 1 6 44 50 51
+27 2 2 1 6 44 51 45
+28 2 2 1 6 45 51 52
+29 2 2 1 6 45 52 46
+30 2 2 1 6 46 52 53
+31 2 2 1 6 46 53 13
+32 2 2 1 6 13 53 14
+33 2 2 1 6 8 9 47
+34 2 2 1 6 47 9 54
+35 2 2 1 6 47 54 48
+36 2 2 1 6 48 54 55
+37 2 2 1 6 48 55 49
+38 2 2 1 6 49 55 56
+39 2 2 1 6 49 56 50
+40 2 2 1 6 50 56 57
+41 2 2 1 6 50 57 51
+42 2 2 1 6 51 57 58
+43 2 2 1 6 51 58 52
+44 2 2 1 6 52 58 59
+45 2 2 1 6 52 59 53
+46 2 2 1 6 53 59 60
+47 2 2 1 6 53 60 14
+48 2 2 1 6 14 60 15
+49 2 2 1 6 9 2 54
+50 2 2 1 6 54 2 23
+51 2 2 1 6 54 23 55
+52 2 2 1 6 55 23 24
+53 2 2 1 6 55 24 56
+54 2 2 1 6 56 24 25
+55 2 2 1 6 56 25 57
+56 2 2 1 6 57 25 26
+57 2 2 1 6 57 26 58
+58 2 2 1 6 58 26 27
+59 2 2 1 6 58 27 59
+60 2 2 1 6 59 27 28
+61 2 2 1 6 59 28 60
+62 2 2 1 6 60 28 29
+63 2 2 1 6 60 29 15
+64 2 2 1 6 15 29 5
+65 2 2 2 10 2 10 23
+66 2 2 2 10 23 10 61
+67 2 2 2 10 23 61 24
+68 2 2 2 10 24 61 62
+69 2 2 2 10 24 62 25
+70 2 2 2 10 25 62 63
+71 2 2 2 10 25 63 26
+72 2 2 2 10 26 63 64
+73 2 2 2 10 26 64 27
+74 2 2 2 10 27 64 65
+75 2 2 2 10 27 65 28
+76 2 2 2 10 28 65 66
+77 2 2 2 10 28 66 29
+78 2 2 2 10 29 66 67
+79 2 2 2 10 29 67 5
+80 2 2 2 10 5 67 30
+81 2 2 2 10 10 11 61
+82 2 2 2 10 61 11 68
+83 2 2 2 10 61 68 62
+84 2 2 2 10 62 68 69
+85 2 2 2 10 62 69 63
+86 2 2 2 10 63 69 70
+87 2 2 2 10 63 70 64
+88 2 2 2 10 64 70 71
+89 2 2 2 10 64 71 65
+90 2 2 2 10 65 71 72
+91 2 2 2 10 65 72 66
+92 2 2 2 10 66 72 73
+93 2 2 2 10 66 73 67
+94 2 2 2 10 67 73 74
+95 2 2 2 10 67 74 30
+96 2 2 2 10 30 74 31
+97 2 2 2 10 11 12 68
+98 2 2 2 10 68 12 75
+99 2 2 2 10 68 75 69
+100 2 2 2 10 69 75 76
+101 2 2 2 10 69 76 70
+102 2 2 2 10 70 76 77
+103 2 2 2 10 70 77 71
+104 2 2 2 10 71 77 78
+105 2 2 2 10 71 78 72
+106 2 2 2 10 72 78 79
+107 2 2 2 10 72 79 73
+108 2 2 2 10 73 79 80
+109 2 2 2 10 73 80 74
+110 2 2 2 10 74 80 81
+111 2 2 2 10 74 81 31
+112 2 2 2 10 31 81 32
+113 2 2 2 10 12 3 75
+114 2 2 2 10 75 3 33
+115 2 2 2 10 75 33 76
+116 2 2 2 10 76 33 34
+117 2 2 2 10 76 34 77
+118 2 2 2 10 77 34 35
+119 2 2 2 10 77 35 78
+120 2 2 2 10 78 35 36
+121 2 2 2 10 78 36 79
+122 2 2 2 10 79 36 37
+123 2 2 2 10 79 37 80
+124 2 2 2 10 80 37 38
+125 2 2 2 10 80 38 81
+126 2 2 2 10 81 38 39
+127 2 2 2 10 81 39 32
+128 2 2 2 10 32 39 6
+$EndElements
diff --git a/test/test_model/test_non_local_toolbox/material.dat b/test/test_model/test_non_local_toolbox/material.dat
new file mode 100644
index 000000000..46f983fb1
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/material.dat
@@ -0,0 +1,22 @@
+material test_material [
+ name = mat_1
+ rho = 1 # density
+ E = 1 # young's modulus
+ nu = 0 # poisson's ratio
+]
+
+material test_material [
+ name = mat_2
+ rho = 1 # density
+ E = 1 # young's modulus
+ nu = 0 # poisson's ratio
+]
+
+
+non_local test_region base_wf [
+ radius = 0.5
+ weight_function weight_parameter [
+ update_rate = 1
+ ]
+]
+
\ No newline at end of file
diff --git a/test/test_model/test_non_local_toolbox/material_parallel_test.dat b/test/test_model/test_non_local_toolbox/material_parallel_test.dat
new file mode 100644
index 000000000..210e01dec
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/material_parallel_test.dat
@@ -0,0 +1,21 @@
+material test_material [
+ name = mat_1
+ rho = 1 # density
+ E = 1 # young's modulus
+ nu = 0 # poisson's ratio
+]
+
+material test_material [
+ name = mat_2
+ rho = 1 # density
+ E = 1 # young's modulus
+ nu = 0 # poisson's ratio
+]
+
+non_local test_region remove_wf [
+ radius = 0.5
+ weight_function weight_parameter [
+ update_rate = 1
+ damage_limit = 0.9
+ ]
+]
diff --git a/test/test_model/test_non_local_toolbox/material_remove_damage.dat b/test/test_model/test_non_local_toolbox/material_remove_damage.dat
new file mode 100644
index 000000000..9976cf085
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/material_remove_damage.dat
@@ -0,0 +1,30 @@
+material test_material [
+ name = mat_1
+ rho = 1 # density
+ E = 1 # young's modulus
+ nu = 0 # poisson's ratio
+]
+
+material test_material [
+ name = mat_2
+ rho = 1 # density
+ E = 1 # young's modulus
+ nu = 0 # poisson's ratio
+]
+
+
+non_local mat_1 remove_wf [
+ radius = 0.5
+ weight_function weight_parameter [
+ update_rate = 1
+ damage_limit = 0.9
+ ]
+]
+
+non_local mat_2 remove_wf [
+ radius = 0.5
+ weight_function weight_parameter [
+ update_rate = 1
+ damage_limit = 0.9
+ ]
+]
diff --git a/test/test_model/test_non_local_toolbox/material_weight_computation.dat b/test/test_model/test_non_local_toolbox/material_weight_computation.dat
new file mode 100644
index 000000000..cff38fa19
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/material_weight_computation.dat
@@ -0,0 +1,13 @@
+material test_material [
+ name = mat_1
+ rho = 1 # density
+ E = 1 # young's modulus
+ nu = 0 # poisson's ratio
+]
+
+non_local test_region base_wf [
+ radius = 0.5
+ weight_function weight_parameter [
+ update_rate = 1
+ ]
+]
diff --git a/test/test_model/test_non_local_toolbox/pair_test.msh b/test/test_model/test_non_local_toolbox/pair_test.msh
new file mode 100644
index 000000000..adf79c73c
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/pair_test.msh
@@ -0,0 +1,285 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$PhysicalNames
+2
+2 1 "mat_1"
+2 2 "mat_2"
+$EndPhysicalNames
+$Nodes
+147
+1 -1 -1 0
+2 0 -1 0
+3 1 -1 0
+4 -1 1 0
+5 0 1 0
+6 1 1 0
+7 -0.8333333333331019 -1 0
+8 -0.6666666666675911 -1 0
+9 -0.5000000000020587 -1 0
+10 -0.3333333333347203 -1 0
+11 -0.1666666666673601 -1 0
+12 0.1666666666663217 -1 0
+13 0.3333333333325025 -1 0
+14 0.4999999999986943 -1 0
+15 0.6666666666657889 -1 0
+16 0.8333333333328945 -1 0
+17 -0.8333333333331019 1 0
+18 -0.6666666666675911 1 0
+19 -0.5000000000020587 1 0
+20 -0.3333333333347203 1 0
+21 -0.1666666666673601 1 0
+22 -1 -0.8000000000005548 0
+23 -1 -0.6000000000011096 0
+24 -1 -0.4000000000016644 0
+25 -1 -0.2000000000022192 0
+26 -1 -2.752242878045763e-12 0
+27 -1 0.1999999999977808 0
+28 -1 0.3999999999983355 0
+29 -1 0.5999999999988903 0
+30 -1 0.7999999999994454 0
+31 0 -0.8000000000005548 0
+32 0 -0.6000000000011096 0
+33 0 -0.4000000000016644 0
+34 0 -0.2000000000022192 0
+35 0 -2.752242878045763e-12 0
+36 0 0.1999999999977808 0
+37 0 0.3999999999983355 0
+38 0 0.5999999999988903 0
+39 0 0.7999999999994454 0
+40 0.1666666666663217 1 0
+41 0.3333333333325025 1 0
+42 0.4999999999986943 1 0
+43 0.6666666666657889 1 0
+44 0.8333333333328945 1 0
+45 1 -0.8000000000005548 0
+46 1 -0.6000000000011096 0
+47 1 -0.4000000000016644 0
+48 1 -0.2000000000022192 0
+49 1 -2.752242878045763e-12 0
+50 1 0.1999999999977808 0
+51 1 0.3999999999983355 0
+52 1 0.5999999999988903 0
+53 1 0.7999999999994454 0
+54 -0.5030532339989087 -0.4604795752809341 0
+55 -0.4991893376216041 -0.2579310797335558 0
+56 -0.4928253212984854 -0.04915482098893964 0
+57 -0.4825167969647393 0.1593831942110211 0
+58 -0.4537131445391057 0.3723675083221218 0
+59 -0.3354763679671945 -0.6495749373148603 0
+60 -0.6720637212240133 -0.6440527727539086 0
+61 -0.8327922142909066 -0.424411789814217 0
+62 -0.1694948826748436 -0.2439216871722153 0
+63 -0.8304654877577068 -0.2263545688411482 0
+64 -0.1676070140031115 -0.03245149868737207 0
+65 -0.8288973697128403 -0.02296850226233027 0
+66 -0.3177756975560099 0.1506226532199915 0
+67 -0.6499513239747395 0.168281999590373 0
+68 -0.332632043786547 0.357209176158553 0
+69 -0.8097098566948024 0.3897528736091556 0
+70 -0.6942802675450694 0.854998657441377 0
+71 -0.3461850865710019 0.8421692582322702 0
+72 -0.5039727684306142 -0.6480714308820643 0
+73 -0.5417691612917842 0.7095854596117401 0
+74 -0.6712440556236705 -0.8238117172557884 0
+75 -0.4095392398396389 0.5279845453194498 0
+76 -0.5861069356184923 0.5558355660389873 0
+77 -0.1857309125373677 0.6523401892267553 0
+78 -0.8349439676325913 -0.6216259170217607 0
+79 -0.7802102628071158 0.6237266553450271 0
+80 -0.5144127730589734 0.8547115964385665 0
+81 -0.6675822792485565 -0.4444452989962474 0
+82 -0.3352489460827015 -0.2600911224288346 0
+83 -0.3374221621912897 -0.4639046570587465 0
+84 -0.3684914749282594 0.6852797329236604 0
+85 -0.5026927486076159 -0.8325836051754552 0
+86 -0.8311761773120493 0.8250586641991118 0
+87 -0.1727521450940143 0.8250426798690156 0
+88 -0.8241972940158289 0.1799786621409103 0
+89 -0.1721159395472645 0.1907669303977386 0
+90 -0.6716244436213226 0.7348369083408823 0
+91 -0.6320795187011508 0.3738573043386093 0
+92 -0.6598292686862797 -0.04213464686197599 0
+93 -0.3303430162643356 -0.0504186782770587 0
+94 -0.2136488293768658 0.4970254941325962 0
+95 -0.6628941913558752 -0.2484656369854851 0
+96 -0.1670116616510103 -0.6300634213566896 0
+97 -0.8360993377658784 -0.8136490127044709 0
+98 -0.165715790497087 -0.81294453704069 0
+99 -0.1687701320665355 -0.4369115603852289 0
+100 -0.3304024146094647 -0.8257352634398845 0
+101 0.497377900174956 -0.4560773336865299 0
+102 0.4988080615949736 -0.2663875869302658 0
+103 0.5050785223400323 -0.05701180906688275 0
+104 0.5158686400624251 0.1548699527023594 0
+105 0.5479694074400454 0.3737343876194663 0
+106 0.6633117489460233 -0.6464584085641401 0
+107 0.3314794870252118 -0.6338404827850097 0
+108 0.1680737454349881 -0.4237359282602401 0
+109 0.8314174022948281 -0.2358261489074746 0
+110 0.1689970784875456 -0.2260911940794778 0
+111 0.8331351238044343 -0.02872858712754478 0
+112 0.1703500751789856 -0.02369232428030787 0
+113 0.6817794215333505 0.1426920479096527 0
+114 0.3486617917953876 0.1661941850090003 0
+115 0.6673679562135154 0.357209176158553 0
+116 0.1786615138291235 0.3881464583742862 0
+117 0.3290488584359573 0.848871509710434 0
+118 0.6552261020460025 0.8413068550720801 0
+119 0.497245429073263 -0.6423454109913329 0
+120 0.4607906126344682 0.7074758864397657 0
+121 0.331666476308289 -0.8184202011724826 0
+122 0.5893203782825908 0.5246371009306479 0
+123 0.4102193202759227 0.5531292234514229 0
+124 0.8142961840162048 0.649742889167632 0
+125 0.1666793877474982 -0.6180944722490216 0
+126 0.2022990824380825 0.619189395677995 0
+127 0.4909473284395671 0.8532569838628081 0
+128 0.3332959984992943 -0.4459043819891003 0
+129 0.6640817912568999 -0.2607101734672508 0
+130 0.6622369248641241 -0.4597222677300552 0
+131 0.63265243918391 0.6835849843356157 0
+132 0.4972910449700644 -0.8310432453089057 0
+133 0.1713211907200942 0.8224535461879088 0
+134 0.82866663878312 0.8252820078498277 0
+135 0.1738363498222202 0.1793980605350007 0
+136 0.827813894920819 0.1893863917079048 0
+137 0.3364814534902554 0.7323669204972425 0
+138 0.3686287965189134 0.3695097298820902 0
+139 0.3392849112652694 -0.043889750338033 0
+140 0.6692420017210666 -0.05191534823397626 0
+141 0.7852589983383298 0.4901695024320518 0
+142 0.3373554832196469 -0.2547720943966668 0
+143 0.8314551357200138 -0.6268873740648218 0
+144 0.1656927329997094 -0.8098568927107836 0
+145 0.8328842890948791 -0.8127159474435377 0
+146 0.8300389178979889 -0.441063907651599 0
+147 0.6660151161336012 -0.8240944407584765 0
+$EndNodes
+$Elements
+124
+1 3 2 1 6 35 64 62 34
+2 3 2 1 6 26 25 63 65
+3 3 2 1 6 25 24 61 63
+4 3 2 1 6 58 57 66 68
+5 3 2 1 6 59 83 54 72
+6 3 2 1 6 60 74 85 72
+7 3 2 1 6 17 4 30 86
+8 3 2 1 6 21 87 39 5
+9 3 2 1 6 27 26 65 88
+10 3 2 1 6 36 89 64 35
+11 3 2 1 6 88 67 91 69
+12 3 2 1 6 58 91 67 57
+13 3 2 1 6 55 54 83 82
+14 3 2 1 6 72 54 81 60
+15 3 2 1 6 37 94 89 36
+16 3 2 1 6 68 66 89 94
+17 3 2 1 6 75 76 91 58
+18 3 2 1 6 79 69 91 76
+19 3 2 1 6 19 18 70 80
+20 3 2 1 6 19 80 71 20
+21 3 2 1 6 80 70 90 73
+22 3 2 1 6 73 90 79 76
+23 3 2 1 6 76 75 84 73
+24 3 2 1 6 71 80 73 84
+25 3 2 1 6 9 85 74 8
+26 3 2 1 6 29 79 86 30
+27 3 2 1 6 18 17 86 70
+28 3 2 1 6 70 86 79 90
+29 3 2 1 6 38 39 87 77
+30 3 2 1 6 20 71 87 21
+31 3 2 1 6 71 84 77 87
+32 3 2 1 6 81 61 78 60
+33 3 2 1 6 24 23 78 61
+34 3 2 1 6 57 67 92 56
+35 3 2 1 6 88 65 92 67
+36 3 2 1 6 57 56 93 66
+37 3 2 1 6 89 66 93 64
+38 3 2 1 6 58 68 94 75
+39 3 2 1 6 84 75 94 77
+40 3 2 1 6 54 55 95 81
+41 3 2 1 6 61 81 95 63
+42 3 2 1 6 63 95 92 65
+43 3 2 1 6 55 56 92 95
+44 3 2 1 6 62 64 93 82
+45 3 2 1 6 55 82 93 56
+46 3 2 1 6 37 38 77 94
+47 3 2 1 6 69 79 29 28
+48 3 2 1 6 27 88 69 28
+49 3 2 1 6 7 97 22 1
+50 3 2 1 6 23 22 97 78
+51 3 2 1 6 60 78 97 74
+52 3 2 1 6 8 74 97 7
+53 3 2 1 6 34 62 99 33
+54 3 2 1 6 31 32 96 98
+55 3 2 1 6 33 99 96 32
+56 3 2 1 6 62 82 83 99
+57 3 2 1 6 59 96 99 83
+58 3 2 1 6 96 59 100 98
+59 3 2 1 6 9 10 100 85
+60 3 2 1 6 72 85 100 59
+61 3 2 1 6 11 2 31 98
+62 3 2 1 6 10 11 98 100
+63 3 2 2 10 49 111 109 48
+64 3 2 2 10 35 34 110 112
+65 3 2 2 10 34 33 108 110
+66 3 2 2 10 105 104 113 115
+67 3 2 2 10 106 130 101 119
+68 3 2 2 10 107 121 132 119
+69 3 2 2 10 39 133 40 5
+70 3 2 2 10 44 134 53 6
+71 3 2 2 10 36 35 112 135
+72 3 2 2 10 50 136 111 49
+73 3 2 2 10 135 114 138 116
+74 3 2 2 10 105 138 114 104
+75 3 2 2 10 102 101 130 129
+76 3 2 2 10 119 101 128 107
+77 3 2 2 10 51 141 136 50
+78 3 2 2 10 115 113 136 141
+79 3 2 2 10 122 123 138 105
+80 3 2 2 10 126 116 138 123
+81 3 2 2 10 42 127 118 43
+82 3 2 2 10 127 117 137 120
+83 3 2 2 10 120 137 126 123
+84 3 2 2 10 123 122 131 120
+85 3 2 2 10 118 127 120 131
+86 3 2 2 10 14 132 121 13
+87 3 2 2 10 38 126 133 39
+88 3 2 2 10 41 40 133 117
+89 3 2 2 10 117 133 126 137
+90 3 2 2 10 52 53 134 124
+91 3 2 2 10 43 118 134 44
+92 3 2 2 10 118 131 124 134
+93 3 2 2 10 128 108 125 107
+94 3 2 2 10 33 32 125 108
+95 3 2 2 10 104 114 139 103
+96 3 2 2 10 135 112 139 114
+97 3 2 2 10 104 103 140 113
+98 3 2 2 10 136 113 140 111
+99 3 2 2 10 105 115 141 122
+100 3 2 2 10 131 122 141 124
+101 3 2 2 10 101 102 142 128
+102 3 2 2 10 108 128 142 110
+103 3 2 2 10 110 142 139 112
+104 3 2 2 10 102 103 139 142
+105 3 2 2 10 109 111 140 129
+106 3 2 2 10 102 129 140 103
+107 3 2 2 10 51 52 124 141
+108 3 2 2 10 116 126 38 37
+109 3 2 2 10 36 135 116 37
+110 3 2 2 10 12 144 31 2
+111 3 2 2 10 32 31 144 125
+112 3 2 2 10 107 125 144 121
+113 3 2 2 10 13 121 144 12
+114 3 2 2 10 48 109 146 47
+115 3 2 2 10 45 46 143 145
+116 3 2 2 10 47 146 143 46
+117 3 2 2 10 109 129 130 146
+118 3 2 2 10 106 143 146 130
+119 3 2 2 10 143 106 147 145
+120 3 2 2 10 14 15 147 132
+121 3 2 2 10 119 132 147 106
+122 3 2 2 10 16 3 45 145
+123 3 2 2 10 15 16 145 147
+124 3 2 2 10 41 117 127 42
+$EndElements
diff --git a/test/test_model/test_non_local_toolbox/parallel_test.msh b/test/test_model/test_non_local_toolbox/parallel_test.msh
new file mode 100644
index 000000000..54d9cddc3
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/parallel_test.msh
@@ -0,0 +1,2190 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$PhysicalNames
+2
+2 1 "mat_1"
+2 2 "mat_2"
+$EndPhysicalNames
+$Nodes
+760
+1 -1 -1 0
+2 -0.3333333333333333 -1 0
+3 1 -1 0
+4 -1 1 0
+5 -0.3333333333333333 1 0
+6 1 1 0
+7 -0.9259259259261259 -1 0
+8 -0.851851851852264 -1 0
+9 -0.7777777777783994 -1 0
+10 -0.7037037037045228 -1 0
+11 -0.6296296296304319 -1 0
+12 -0.5555555555561553 -1 0
+13 -0.4814814814818934 -1 0
+14 -0.4074074074076072 -1 0
+15 -0.2549019607844754 -1 0
+16 -0.1764705882355741 -1 0
+17 -0.09803921568677137 -1 0
+18 -0.0196078431379782 -1 0
+19 0.05882352941081553 -1 0
+20 0.1372549019596017 -1 0
+21 0.2156862745084134 -1 0
+22 0.2941176470571926 -1 0
+23 0.3725490196062002 -1 0
+24 0.450980392155436 -1 0
+25 0.5294117647046463 -1 0
+26 0.6078431372538782 -1 0
+27 0.6862745098030976 -1 0
+28 0.7647058823523272 -1 0
+29 0.8431372549015488 -1 0
+30 0.9215686274507757 -1 0
+31 -0.9259259259261259 1 0
+32 -0.851851851852264 1 0
+33 -0.7777777777783994 1 0
+34 -0.7037037037045228 1 0
+35 -0.6296296296304319 1 0
+36 -0.5555555555561553 1 0
+37 -0.4814814814818934 1 0
+38 -0.4074074074076072 1 0
+39 -1 -0.9200000000002219 0
+40 -1 -0.8400000000004438 0
+41 -1 -0.7600000000006657 0
+42 -1 -0.6800000000008877 0
+43 -1 -0.6000000000011096 0
+44 -1 -0.5200000000013315 0
+45 -1 -0.4400000000015535 0
+46 -1 -0.3600000000017753 0
+47 -1 -0.2800000000019972 0
+48 -1 -0.2000000000022192 0
+49 -1 -0.1200000000024412 0
+50 -1 -0.04000000000266302 0
+51 -1 0.03999999999733728 0
+52 -1 0.1199999999975589 0
+53 -1 0.1999999999977808 0
+54 -1 0.2799999999980027 0
+55 -1 0.3599999999982249 0
+56 -1 0.4399999999984467 0
+57 -1 0.5199999999986684 0
+58 -1 0.5999999999988903 0
+59 -1 0.6799999999991124 0
+60 -1 0.7599999999993341 0
+61 -1 0.839999999999556 0
+62 -1 0.9199999999997781 0
+63 -0.3333333333333333 -0.9200000000002219 0
+64 -0.3333333333333333 -0.8400000000004438 0
+65 -0.3333333333333333 -0.7600000000006657 0
+66 -0.3333333333333333 -0.6800000000008877 0
+67 -0.3333333333333333 -0.6000000000011096 0
+68 -0.3333333333333333 -0.5200000000013315 0
+69 -0.3333333333333333 -0.4400000000015535 0
+70 -0.3333333333333333 -0.3600000000017753 0
+71 -0.3333333333333333 -0.2800000000019972 0
+72 -0.3333333333333333 -0.2000000000022192 0
+73 -0.3333333333333333 -0.1200000000024412 0
+74 -0.3333333333333333 -0.04000000000266302 0
+75 -0.3333333333333333 0.03999999999733728 0
+76 -0.3333333333333333 0.1199999999975589 0
+77 -0.3333333333333333 0.1999999999977808 0
+78 -0.3333333333333333 0.2799999999980027 0
+79 -0.3333333333333333 0.3599999999982249 0
+80 -0.3333333333333333 0.4399999999984467 0
+81 -0.3333333333333333 0.5199999999986684 0
+82 -0.3333333333333333 0.5999999999988903 0
+83 -0.3333333333333333 0.6799999999991124 0
+84 -0.3333333333333333 0.7599999999993341 0
+85 -0.3333333333333333 0.839999999999556 0
+86 -0.3333333333333333 0.9199999999997781 0
+87 -0.2549019607844754 1 0
+88 -0.1764705882355741 1 0
+89 -0.09803921568677137 1 0
+90 -0.0196078431379782 1 0
+91 0.05882352941081553 1 0
+92 0.1372549019596017 1 0
+93 0.2156862745084134 1 0
+94 0.2941176470571926 1 0
+95 0.3725490196062002 1 0
+96 0.450980392155436 1 0
+97 0.5294117647046463 1 0
+98 0.6078431372538782 1 0
+99 0.6862745098030976 1 0
+100 0.7647058823523272 1 0
+101 0.8431372549015488 1 0
+102 0.9215686274507757 1 0
+103 1 -0.9200000000002219 0
+104 1 -0.8400000000004438 0
+105 1 -0.7600000000006657 0
+106 1 -0.6800000000008877 0
+107 1 -0.6000000000011096 0
+108 1 -0.5200000000013315 0
+109 1 -0.4400000000015535 0
+110 1 -0.3600000000017753 0
+111 1 -0.2800000000019972 0
+112 1 -0.2000000000022192 0
+113 1 -0.1200000000024412 0
+114 1 -0.04000000000266302 0
+115 1 0.03999999999733728 0
+116 1 0.1199999999975589 0
+117 1 0.1999999999977808 0
+118 1 0.2799999999980027 0
+119 1 0.3599999999982249 0
+120 1 0.4399999999984467 0
+121 1 0.5199999999986684 0
+122 1 0.5999999999988903 0
+123 1 0.6799999999991124 0
+124 1 0.7599999999993341 0
+125 1 0.839999999999556 0
+126 1 0.9199999999997781 0
+127 -0.6244923549273574 -0.7804476162728123 0
+128 -0.6672821210865347 -0.3981363141022898 0
+129 -0.6546070565370572 -0.1501342028045368 0
+130 -0.6549876531186305 -0.6448073520353281 0
+131 -0.687618036671638 -0.4877235743127334 0
+132 -0.662991527169032 -0.04961904671683437 0
+133 -0.6666459542733651 0.1441432019957372 0
+134 -0.6666615662751374 0.2324109185942875 0
+135 -0.6657143001026753 0.4799321870408348 0
+136 -0.6666651780713242 0.2970878580001537 0
+137 -0.6663753889113118 0.3968954519929966 0
+138 -0.6560175284425774 0.647682552699709 0
+139 -0.6489487102959535 0.8043540454674649 0
+140 -0.4914334971528428 0.8013081036101941 0
+141 -0.4967781346352358 -0.8136867978734854 0
+142 -0.8573417764605045 0.8586666720417473 0
+143 -0.8205201644696922 -0.8750788065476156 0
+144 -0.5001465324794911 0.9371641616555626 0
+145 -0.5166520215486673 -0.9297851450900305 0
+146 -0.9443396432568872 -0.9402472510418199 0
+147 -0.4375568389278687 -0.9374496470532463 0
+148 -0.8501921865700612 0.1540270337199472 0
+149 -0.4999909933375396 0.145439513990369 0
+150 -0.8266989707677244 0.05946672626156468 0
+151 -0.4880258810232836 0.04713591947759244 0
+152 -0.8408324618684195 -0.6533803594796295 0
+153 -0.826405819172509 -0.0443090531025031 0
+154 -0.5137934946953118 -0.04237186312081742 0
+155 -0.8540748231619797 0.6421839792527517 0
+156 -0.4740268662571406 0.6434087470905732 0
+157 -0.8285462133901065 -0.3876825609352906 0
+158 -0.4976824858420978 -0.3824284142856437 0
+159 -0.4880473961795723 -0.1054702152744524 0
+160 -0.8684077064397683 -0.1191761642744301 0
+161 -0.821906478890814 0.5631107390036338 0
+162 -0.4862399563789741 0.5567431347057035 0
+163 -0.8062405654934396 -0.5314484672287578 0
+164 -0.8541361864145768 -0.4583788053768032 0
+165 -0.5015600293332532 -0.4821684630329319 0
+166 -0.8049390915997143 0.335844379477229 0
+167 -0.5280710451144749 0.3355938573168094 0
+168 -0.8331082339413101 0.2599498730172698 0
+169 -0.4992745912700584 0.2560686358079596 0
+170 -0.825099209932868 -0.1869138376003714 0
+171 -0.4724719391519341 -0.170957859863177 0
+172 -0.5205590325227096 -0.2973949323149156 0
+173 -0.8235336074293348 0.4136044564043972 0
+174 -0.5088772633724278 0.4128865809231126 0
+175 -0.475389438600217 -0.6343321934901129 0
+176 -0.7494546432204144 -0.7670885374250602 0
+177 -0.5768505667286512 -0.7442449480650046 0
+178 -0.7698406898983896 0.7439341405826287 0
+179 -0.9219568190305194 0.7764345944748439 0
+180 -0.5457410498033263 -0.8605460963742542 0
+181 -0.5307737233108213 0.8689282965306713 0
+182 -0.6491109705801293 -0.9218559664259203 0
+183 -0.56392009259897 -0.8048398212702833 0
+184 -0.5771920553036334 0.7962643532786153 0
+185 -0.754940055423068 -0.8399272164270225 0
+186 -0.7081717037607804 0.862757252616106 0
+187 -0.7345962277479952 0.9339770509644356 0
+188 -0.9237035150133056 0.8571343600137336 0
+189 -0.928158436571582 -0.7887246819536249 0
+190 -0.6457015386697935 -0.7235512692838604 0
+191 -0.7832505502451312 -0.9265532896430192 0
+192 -0.8748255243959532 -0.9349122021788833 0
+193 -0.9045210102347154 0.9307558922919594 0
+194 -0.4201449982563817 -0.7928640269919773 0
+195 -0.6836801207261622 -0.5677980563037506 0
+196 -0.4697151211356907 -0.8698916569202506 0
+197 -0.4395311549937636 -0.4965542994237602 0
+198 -0.864342469535104 -0.5242966465836461 0
+199 -0.7583061485894145 -0.6156714396482862 0
+200 -0.7605960047827529 -0.4542143824158388 0
+201 -0.5589328210212259 -0.6229263835680147 0
+202 -0.7537505900552766 0.6199889645565002 0
+203 -0.5682270969362844 0.619019684609635 0
+204 -0.8770024795417555 -0.7203102973989448 0
+205 -0.5819090556474992 0.5319079404024698 0
+206 -0.7487847778257903 0.5314943763234234 0
+207 -0.7485303995518826 -0.170961278500834 0
+208 -0.5831751236985908 0.3642509182530955 0
+209 -0.7500871031331759 0.3642797127811306 0
+210 -0.5784625541823176 -0.3481724683805454 0
+211 -0.9227106648752721 -0.1190386604344363 0
+212 -0.9137631510227066 -0.2095564355177125 0
+213 -0.5833485289178013 0.002783626956833984 0
+214 -0.5740021505102716 -0.09218702079842511 0
+215 -0.749221544790817 0.002783626956833984 0
+216 -0.5844821521404916 0.4469284708565369 0
+217 -0.7406816046187994 -0.08706403681024388 0
+218 -0.7473919877286757 0.4470897117150028 0
+219 -0.9141236982689971 0.5693689107456876 0
+220 -0.9119364185580593 -0.05126372956918035 0
+221 -0.4008941191332082 0.02127905204681357 0
+222 -0.9190944810080419 0.07370766894413516 0
+223 -0.4141662935918158 0.09892847880141198 0
+224 -0.7435085903777969 0.09515748908761612 0
+225 -0.58132004753115 0.09773937347300143 0
+226 -0.4380685619207502 -0.04155644135983749 0
+227 -0.7586253749127442 0.1843190229197116 0
+228 -0.5829914569564005 0.188884697971621 0
+229 -0.7484759069081384 0.2787350318359223 0
+230 -0.584805258099573 0.278717038582051 0
+231 -0.4050114461956372 0.1972524722595226 0
+232 -0.9080202880474837 0.2915105616952645 0
+233 -0.4054955743166661 0.3062445215163165 0
+234 -0.8841920956776853 0.4296293537136733 0
+235 -0.3998287469862251 -0.1279614329037643 0
+236 -0.4530003100184419 0.428929577149346 0
+237 -0.3983906762803199 -0.2838061295471579 0
+238 -0.3967145456380078 0.5765956366982687 0
+239 -0.7520861351594814 -0.3776369706956232 0
+240 -0.9241433744849579 -0.3060385988582185 0
+241 -0.4525947653370216 -0.7013524299747442 0
+242 -0.4002133316513193 -0.2177455138215594 0
+243 -0.7186706349198024 0.6894767787917864 0
+244 -0.6328621671115469 0.7277513365320252 0
+245 -0.788552247669306 -0.7114647056032219 0
+246 -0.640637471083455 -0.3019361744588318 0
+247 -0.9160252953912966 -0.6520682434409328 0
+248 -0.4182865221385997 -0.4231902278714372 0
+249 -0.4006128317795927 -0.6477308186442807 0
+250 -0.5032339910315216 -0.76122992622818 0
+251 -0.9158427251984841 -0.3941147599209458 0
+252 -0.7402155092100058 -0.5317651146634402 0
+253 -0.6164011852097693 -0.2207442587790357 0
+254 -0.7157822323799772 -0.7052537161998844 0
+255 -0.5711346785908226 -0.4870792912459441 0
+256 -0.5910540522527449 -0.6847591391684578 0
+257 -0.6256110067176386 -0.8476366178814017 0
+258 -0.7869862404445154 0.8243025699279969 0
+259 -0.5275199191648444 -0.6958593527651393 0
+260 -0.8336502431824969 0.7595939727588925 0
+261 -0.8007386067933593 0.6921994534383267 0
+262 -0.394346282512787 -0.8882586576135511 0
+263 -0.7073965329146505 0.7724298376541272 0
+264 -0.4883930111156681 -0.5578546113514069 0
+265 -0.8491509365191895 -0.5925147606700525 0
+266 -0.6869186018262259 -0.7930672723777387 0
+267 -0.5450020985580005 0.7142479312462844 0
+268 -0.8341686582883933 -0.7966656257487901 0
+269 -0.8616973963562642 0.8059892194369476 0
+270 -0.5874757387560344 -0.9256884119005868 0
+271 -0.7003353186598691 -0.8790597717007178 0
+272 -0.6643393491054927 0.5738206615361978 0
+273 -0.6895948043704794 -0.2370736623094637 0
+274 -0.6664024329624116 0.0498570691527378 0
+275 -0.3933305362977552 0.6876636280830637 0
+276 -0.809861039427745 0.9194902139885692 0
+277 -0.9134495363225035 -0.8721597962527061 0
+278 -0.6730191503732064 0.9375631969675255 0
+279 -0.3811954391029859 -0.9491416609334038 0
+280 -0.8438098276928968 0.4896826996315105 0
+281 -0.4957913148018029 0.4755051382256419 0
+282 -0.5750905929619263 -0.423879999561232 0
+283 -0.6274777878864091 -0.4657669472805289 0
+284 -0.6150719177651186 -0.580511965197597 0
+285 -0.923913343230938 -0.4858356032538904 0
+286 -0.4641773464937841 -0.2511288131657291 0
+287 -0.43996271065373 -0.3318789574445448 0
+288 -0.9442372423009268 -0.7202206445590111 0
+289 -0.5314433475740266 -0.1460922617911571 0
+290 -0.5827727131913574 -0.162026650929698 0
+291 -0.6210796709131001 -0.5206487185401667 0
+292 -0.581230055707008 -0.2738964798825673 0
+293 -0.5384365171215126 -0.2174630366751827 0
+294 -0.8710605370111091 0.7135707072592665 0
+295 -0.7210574327096394 -0.3104457219597467 0
+296 -0.7726201734487623 -0.2456748795498428 0
+297 -0.4083788492509824 0.4847726588703622 0
+298 -0.9472660375206725 0.339395884241571 0
+299 -0.938462949189641 0.4025777539396251 0
+300 -0.3999261187603369 0.3957570379912188 0
+301 -0.3880038524079324 -0.7163894551225112 0
+302 -0.865174559484694 -0.3299145215971327 0
+303 -0.5593620214565314 -0.5418649054893434 0
+304 -0.9341925652500994 0.4731634209628401 0
+305 -0.8883708847554465 0.006508821652336128 0
+306 -0.4075993872337992 -0.5608247691174075 0
+307 -0.8500798112038628 -0.2626458761097465 0
+308 -0.7982607208994243 -0.3190000884745637 0
+309 -0.8784261412971217 0.351759526169291 0
+310 -0.7577726477361018 0.8852541173153972 0
+311 -0.925572007446088 -0.5624525423251605 0
+312 -0.4660153123092644 0.3545954704146153 0
+313 -0.8018249479431654 -0.1216848740576765 0
+314 -0.9439322047205646 0.007076908103463841 0
+315 -0.9373165539246578 0.6773654559614122 0
+316 -0.5870483722123127 0.9341772288764594 0
+317 -0.3864167462065659 -0.488113859283098 0
+318 -0.5981705740708101 0.6766506983909344 0
+319 -0.6223896294171036 0.8669750235806821 0
+320 -0.9301175390112836 0.1548364455419218 0
+321 -0.9202397079283564 0.2233873189950311 0
+322 -0.4648039417830571 0.7340825566702143 0
+323 -0.7947562806570817 0.1232425679972098 0
+324 -0.4033518907016452 0.7833359247375731 0
+325 -0.4300259238408463 0.8700994716250599 0
+326 -0.420460841485607 0.9478772722133815 0
+327 -0.7073013250997473 -0.9545781712949429 0
+328 -0.9576117340402104 0.9626889730729342 0
+329 -0.3736337288899702 0.9669693180532899 0
+330 0.4508308159640792 -0.1802759457247832 0
+331 0.2878816483017712 -0.3715322579997635 0
+332 0.3703604257188499 -0.5494513245142314 0
+333 0.3294345853558869 -0.1615471184526278 0
+334 0.4189291329187566 0.5605265377064119 0
+335 0.4242748751816585 0.3730477779064076 0
+336 0.7541500575037561 0.5453869936773861 0
+337 0.7532989415942151 -0.5965249326275224 0
+338 0.03098737734178242 0.6955217362337818 0
+339 0.0378195376335837 -0.7039765548176496 0
+340 0.6813905836475949 -0.7452788857647963 0
+341 0.8531273246621092 0.8266589451105564 0
+342 0.8562906787517015 -0.8382920433209551 0
+343 -0.2904925795061188 -0.8721173774777647 0
+344 0.07568598954709133 0.5256321229122163 0
+345 0.02175758137025552 0.392647762643465 0
+346 0.6735511377855465 0.1656650061318301 0
+347 -0.01376131212848714 0.02899718288150721 0
+348 0.6989900744058704 0.0714134954488499 0
+349 0.6446606494084912 0.01513793883213999 0
+350 0.6211506387015771 -0.1122676496220926 0
+351 0.01576500406494435 0.1287841027737613 0
+352 -0.05781087807995672 -0.3708690232307246 0
+353 0.6963716693672031 -0.3503402521283111 0
+354 0.5302282347197813 -0.465416077875027 0
+355 0.53492981783488 0.4359841768177635 0
+356 0.546538130090938 0.7053722598910028 0
+357 0.5984225221869495 0.5624646474101394 0
+358 0.3642185206168465 -0.7871003895957696 0
+359 0.5934153903093411 -0.5983798715029891 0
+360 0.5209919521038673 -0.7205263663980557 0
+361 0.207783547776502 0.6556355951596087 0
+362 0.2079512653465247 -0.6976774005296691 0
+363 0.1517673253122465 0.8527899432424759 0
+364 0.1353373331634406 -0.8524698123609364 0
+365 0.578149059606871 0.851795076064813 0
+366 0.5645427434228807 -0.856219176069275 0
+367 -0.1372784201683939 -0.5698195840822946 0
+368 -0.1091710749187856 0.5671664694882281 0
+369 0.8607061817694395 0.4169103172449447 0
+370 -0.02079022021381399 0.8364405012056719 0
+371 0.3787602233843088 -0.4637712616215949 0
+372 0.8444924036180135 -0.4400040766155091 0
+373 -0.0817391651926524 0.8932475748942685 0
+374 -0.03876178214923953 -0.8783897291568521 0
+375 -0.1653618888890701 -0.7222113178046601 0
+376 0.8361804066162064 0.6958323294363311 0
+377 -0.214990889585209 0.7075829412504064 0
+378 0.9321277701825228 0.5652036456385421 0
+379 0.236409848520515 0.4681687202165652 0
+380 0.9321338012134788 -0.8481287707287297 0
+381 -0.2710102704570193 -0.8029980119154044 0
+382 0.9186593491545929 0.8472817195238205 0
+383 -0.2654469864017179 0.8661901384127872 0
+384 0.6769039829666808 0.6894215947030027 0
+385 -0.1476105531898192 0.9305984082665908 0
+386 -0.1279836648971696 -0.9035514617235737 0
+387 0.8018958840324333 -0.9075846862717796 0
+388 0.7163741951469191 -0.6748342071718143 0
+389 0.3221618967486721 0.2613260493188259 0
+390 0.7567366182954574 -0.7520298134259603 0
+391 -0.1439383477594928 -0.8023748862164626 0
+392 -0.1703442858967485 0.3734586589341682 0
+393 0.1647412767900608 -0.2182992406065184 0
+394 -0.1455796773826976 0.2314198350770134 0
+395 -0.1992174952133865 -0.09854268262904642 0
+396 -0.1508805313546217 -0.03418344976830345 0
+397 0.1853176014390969 0.005518235676573058 0
+398 -0.1807763823395043 0.03651385924528738 0
+399 0.1827504435312923 -0.07915147610801621 0
+400 -0.19776065095986 0.09917127454472796 0
+401 0.1821375864442695 0.08655236169136682 0
+402 0.842210524455784 0.07863887597670405 0
+403 0.5459063468899292 0.1559769806073428 0
+404 0.8487851537313837 0.2345914320154336 0
+405 0.8392159015188754 -0.009951450555311325 0
+406 -0.1448598610078251 -0.2590119778596691 0
+407 0.1705107993188411 0.2439371231596141 0
+408 0.1688206237783456 0.3290543124519518 0
+409 0.1852303496643452 -0.3053358999649696 0
+410 0.8134831529354445 -0.1788338136920798 0
+411 -0.0007181255302391443 -0.5361686692124887 0
+412 0.5366693076220141 -0.2966849608815568 0
+413 0.4772291508409621 -0.3329821045812995 0
+414 0.4120889817430798 -0.3911217389966333 0
+415 0.7576330428811404 -0.4636739353420143 0
+416 0.5835434969069777 -0.2243540344058305 0
+417 -0.0924446730855315 0.5015421374591849 0
+418 -0.211726168139856 -0.3930781568774337 0
+419 0.1677292907562871 0.416121237429192 0
+420 0.3934664896499614 0.6782733755740338 0
+421 0.7735907738387717 0.3884044286357831 0
+422 0.2194204769182224 -0.3879969631903369 0
+423 0.3759920278368225 -0.7125404995848921 0
+424 -0.009371290635787288 -0.443245311028042 0
+425 -0.0378176788386923 -0.669446498141252 0
+426 -0.01893394242915192 0.5347763152669012 0
+427 0.3115937177523073 0.6913726047679916 0
+428 0.07868146027075418 -0.7896618590702983 0
+429 0.4683416134262831 0.7417752253964729 0
+430 0.5026572762607875 -0.6034520279648858 0
+431 0.2263493320089005 -0.8223355013842867 0
+432 0.06347877847661404 -0.6301701434879105 0
+433 0.6399941577669275 -0.5252003718289202 0
+434 0.6215661615834747 0.4709047903172094 0
+435 0.2635905934238891 -0.6423734159429799 0
+436 0.23593669378359 0.8400135261091999 0
+437 0.4110828862988562 0.4678333234162706 0
+438 -0.05754925439315456 0.6187531649203677 0
+439 0.7693500901624439 -0.3908270091536976 0
+440 0.3380839464222379 0.6077852743592256 0
+441 0.158623928973225 0.5011116649521032 0
+442 0.286247770798228 -0.7378493704018891 0
+443 0.6075930492916466 -0.3930657659073938 0
+444 0.4642264576750365 -0.6828871913450205 0
+445 0.4742320977032526 0.6452797202154759 0
+446 0.7897224118275503 0.6295803476820427 0
+447 0.4948355507775083 0.8436035553010146 0
+448 0.04060395738875217 -0.8671347953695643 0
+449 0.4494265195333093 -0.5309735115653487 0
+450 0.1566741133920183 -0.7602250248005729 0
+451 0.4835554035529843 -0.8511606607645968 0
+452 0.1261733952568868 -0.675113382028963 0
+453 0.1333704859974818 0.5823229250456847 0
+454 0.7210565691714652 0.4712024239423684 0
+455 0.4517416504426752 -0.7663751366204676 0
+456 0.5526301802339477 0.7781051240864238 0
+457 0.5177942632364068 0.5726028072924982 0
+458 -0.2509091881878571 0.6407363683495451 0
+459 -0.147869827480575 0.65195952297824 0
+460 0.3497718082090116 -0.9266851285349177 0
+461 0.8085417685487142 0.4804397360439072 0
+462 0.8514353969922135 0.5571945284019764 0
+463 0.4668491095113143 0.4231643640192824 0
+464 0.2935590034124374 0.4263035927981709 0
+465 0.7966615425371313 -0.5198006360614196 0
+466 0.626211593008416 0.7967847356252624 0
+467 0.0671821995936232 0.8639019824401164 0
+468 -0.02440388283027889 0.7465511057659346 0
+469 0.0324378999623518 0.6078464607738747 0
+470 0.0118915539623814 0.30293320607986 0
+471 -0.02173325311379598 -0.3169301580218019 0
+472 -0.008856447094295949 -0.7888218387547676 0
+473 0.2394638659917668 0.5684678409461921 0
+474 0.3257409212348304 0.5041887515798973 0
+475 0.6291076785045788 0.2390787296325303 0
+476 0.5452558574735042 -0.7898449406969117 0
+477 0.9259841522451724 -0.7189206621028029 0
+478 0.926532078149646 0.7019809093074048 0
+479 0.6573793168262703 0.8571090023302055 0
+480 0.8398894257413392 -0.5932380411092031 0
+481 0.8696612926816956 -0.5208368818882751 0
+482 0.0005376543057973304 0.9230899073407215 0
+483 0.02826213428542834 0.4749405284165642 0
+484 0.6738118324227549 0.5467238981015818 0
+485 0.5450772132214672 0.5108237319303814 0
+486 0.8800087960850094 0.6270344836874191 0
+487 0.3329898227580617 -0.3094913949599166 0
+488 0.2973324806690067 -0.4287786141303099 0
+489 0.713800603240901 0.6246290673856887 0
+490 0.8782165354295788 -0.6538447919856165 0
+491 0.556942146085684 -0.5343947043227071 0
+492 0.481025151814912 0.496070804500367 0
+493 0.9268110038539028 -0.3967685742109713 0
+494 0.6458197406627291 0.629787563211031 0
+495 0.5544500705003945 -0.6631403599496437 0
+496 0.667860811558479 -0.9176427077388493 0
+497 0.006321130435200273 -0.934662494651444 0
+498 0.6009593390641033 -0.7323471029929389 0
+499 -0.2039455186213591 -0.6417787999482342 0
+500 0.6363544150422114 -0.6709025590467899 0
+501 0.896117925669232 0.3608900093024103 0
+502 0.6929172282837095 -0.2861322189471934 0
+503 0.5460696586691935 0.9187285923202035 0
+504 0.916033549719691 0.4829334586508156 0
+505 0.8771713545215618 0.7632830517725091 0
+506 0.6107484520801518 0.7139659854058462 0
+507 0.9481913412379204 -0.6420833225378739 0
+508 0.5386544949834027 -0.9209622935047785 0
+509 0.7924766063265298 0.8691367977256439 0
+510 0.7278961114349209 -0.8413700148388672 0
+511 0.8938180049662419 -0.7842930860615039 0
+512 -0.0818155887732927 -0.7404056832289673 0
+513 0.7928247730300773 -0.6726427128611996 0
+514 0.5690283905147411 0.6383757306288673 0
+515 -0.155578031266789 0.7521328157456189 0
+516 0.01146919408931085 -0.171954869380737 0
+517 0.9022586514393325 -0.9248579286173996 0
+518 0.8698154134379867 0.9205743185568152 0
+519 -0.2192709294648614 0.9300904632325946 0
+520 -0.0843538401633383 0.7027743007030951 0
+521 0.9236823346260659 -0.5729219905455327 0
+522 0.33102711010049 0.04251673935710332 0
+523 0.7462839295169752 0.695111275657222 0
+524 -0.07927759598138262 -0.8246716183537856 0
+525 0.7822287146882352 0.2334829784056109 0
+526 -0.2402399221718588 -0.246117125821281 0
+527 0.9074341856375356 -0.1600445437608213 0
+528 0.2652466711834908 0.9243862742073377 0
+529 0.2451239911470414 0.2928219893348307 0
+530 0.2528493681468596 -0.2625826784379974 0
+531 -0.07333300847410157 0.3571485347281038 0
+532 0.5562812651861855 0.2337910993247949 0
+533 0.2472114277564539 0.06521096158170891 0
+534 0.4270366577290943 0.03665210550555753 0
+535 0.1074546202563891 -0.1349593876748703 0
+536 -0.07319464965434302 0.27006014190247 0
+537 0.2597530315283658 -0.1158546029118703 0
+538 0.5664840643139766 -0.1519146411938465 0
+539 -0.07614173283605591 0.1751217179009061 0
+540 0.7599815247437782 0.1437126601295968 0
+541 0.4511044416270512 0.2963502800531124 0
+542 0.08905620785417412 0.1873977523253636 0
+543 -0.2070493182332927 0.2293781653998803 0
+544 -0.2558455609091826 0.4047470643980537 0
+545 0.09149997717323338 0.2752205232212785 0
+546 -0.2013333598282817 0.4420304039911265 0
+547 0.4757066065599606 0.9325573332251427 0
+548 0.4047037902405795 -0.3364921156462276 0
+549 0.1040891915008211 -0.2736966173692181 0
+550 0.5130684941947552 -0.02303776035267446 0
+551 0.6058877923619497 0.09544767248009522 0
+552 -0.07214650886340274 -0.2010853413913382 0
+553 0.1047516668609316 0.1106677242203482 0
+554 0.7630497499140045 -0.03803509871278832 0
+555 0.2513225328645418 -0.188719375175992 0
+556 -0.2553171017070138 0.1535699053822728 0
+557 -0.2446113091230612 -0.02266132661312603 0
+558 0.9225327696153702 0.13756162703217 0
+559 -0.2602785039071151 -0.1542957905136983 0
+560 0.9160997127447637 -0.07056810288203419 0
+561 0.9108273364916 -0.3197783138694478 0
+562 0.930248641194132 0.03520869252654513 0
+563 -0.2627702384129518 0.05639593400821652 0
+564 0.2511274160680965 0.1389993060418055 0
+565 -0.1347412710768505 -0.3775521932660622 0
+566 0.4650970165074158 -0.9427956125538957 0
+567 -0.1823953098350677 -0.3153518510285358 0
+568 0.1836586398955459 -0.535268012270296 0
+569 0.09214599593487049 0.3615414893226916 0
+570 -0.119344879253717 -0.1144786067912538 0
+571 0.8761239560901262 -0.3802623382262479 0
+572 -0.2642572295746519 -0.3341645583967067 0
+573 -0.1012125164843963 0.03391634527348319 0
+574 0.4247126365573582 -0.04704972233871929 0
+575 0.07379828852035447 -0.2071705236335691 0
+576 0.265175404243797 -0.02895856055056512 0
+577 0.7714187848421503 0.04170454602971785 0
+578 0.8766958354816772 0.2963161654444493 0
+579 0.30608645206572 0.8587012394102804 0
+580 0.318992529289046 0.173643628765207 0
+581 0.2392071563637252 0.3791386041434144 0
+582 0.7606838436750247 -0.2994772417005772 0
+583 0.4165445849817408 0.8863172520766271 0
+584 0.2492759659819412 0.2162299268561925 0
+585 0.307789665728289 0.3526774884042601 0
+586 0.07521680162229366 0.9343778624537897 0
+587 0.3945350088258401 -0.195418482274059 0
+588 0.06577796515527295 0.002061325616971255 0
+589 -0.2587282984945163 -0.5086317994655229 0
+590 0.9190106175965136 0.2337614530077867 0
+591 0.8413007250889537 -0.2633372097968917 0
+592 0.006072226073742693 -0.2549815364305744 0
+593 0.28483244299162 -0.9003388629288847 0
+594 -0.1698935275235141 -0.4744532017183704 0
+595 0.09770278185983461 -0.9264659783821004 0
+596 0.7996936560594574 0.3021537879297467 0
+597 0.1893272574902737 0.9181186087451305 0
+598 0.3084567318579005 0.1005372544136531 0
+599 0.1139420809863027 -0.3634724479179611 0
+600 0.338824399579243 -0.08363354439324056 0
+601 0.3555754675059907 -0.01731196009002556 0
+602 0.750024466588689 -0.1796415944800979 0
+603 0.4086561422274546 -0.9020501042103343 0
+604 0.02214288507568957 -0.0700508277249956 0
+605 0.02644283428823457 -0.3751906637556569 0
+606 0.1478822671388655 -0.4601468960804789 0
+607 0.1915927523553709 -0.6142566007187205 0
+608 -0.1242891827704753 0.4445122517178897 0
+609 -0.2675694981276602 0.566335335822816 0
+610 0.06875727798578252 -0.4920581224287041 0
+611 0.5132223143333541 -0.2001887869340697 0
+612 -0.04971214242790117 0.9540843705587476 0
+613 0.8280836510050344 -0.09535163853142326 0
+614 0.8413183196945435 0.1686744748773354 0
+615 0.1245786207942827 0.9111581991840416 0
+616 0.6310478850831078 0.923299601879914 0
+617 0.5059123110019579 0.3552141602613095 0
+618 0.3044990386402959 -0.8260763643308568 0
+619 -0.1646967458767389 -0.1791736475293985 0
+620 0.3642908092705765 0.8324201325494256 0
+621 0.0907008201445263 0.4453324676127053 0
+622 0.8413608745637156 0.3529349417114669 0
+623 0.2387267075001884 -0.4837965354275237 0
+624 -0.2161905009585778 -0.8621576596462995 0
+625 0.3172797697304954 -0.5975621229303623 0
+626 0.2518724215665587 -0.5621023225878843 0
+627 0.1934256582239459 -0.9231424655819773 0
+628 0.8315329806587433 -0.3500486663134575 0
+629 -0.1492655054969645 0.2999240650707995 0
+630 0.9446737760203183 0.7796857186207611 0
+631 0.4105584660622567 0.9519884332625339 0
+632 0.5317741214150502 -0.3770758840234375 0
+633 -0.08711095557656426 -0.3016611633303758 0
+634 0.6469666806251693 -0.2437185297799305 0
+635 0.351698713777412 -0.3815763105204479 0
+636 -0.09353826188362868 0.7987776180102182 0
+637 0.3351072666724287 -0.2308413464122389 0
+638 0.6081950179678499 -0.9017968114393392 0
+639 0.6154466089539621 -0.4644825438377278 0
+640 0.6834750130593659 -0.4428613333329899 0
+641 0.7304882172282487 -0.9338325484510682 0
+642 0.4002671823196738 -0.6211235780061323 0
+643 -0.05591773851246462 -0.9454857637614669 0
+644 0.4063905961757812 -0.1258203219999712 0
+645 0.6788473561438677 0.3878477284515522 0
+646 -0.2528886578608556 -0.7218628754625882 0
+647 0.04576261594706105 -0.3168542846990425 0
+648 -0.2458912159522055 0.4946955815070218 0
+649 -0.2772614385754695 -0.3950961042799813 0
+650 0.4634859539315725 -0.4280262282210496 0
+651 0.5683820255349146 0.3010442515328657 0
+652 0.774212602884089 0.7781360154209722 0
+653 0.7284767924832001 0.3123880418104026 0
+654 0.3798554962334621 0.7510808973838479 0
+655 -0.170236761965572 0.8506913009566408 0
+656 0.5893308014889409 0.3778375317972154 0
+657 0.4308163158917767 -0.2646720068400692 0
+658 0.1276283996643481 -0.5905558730725458 0
+659 0.3543968951489299 -0.8623591743238406 0
+660 -0.04316351518392941 0.4509279217053515 0
+661 0.04004852444628759 0.7798462270872752 0
+662 0.691585034197439 0.8022558349380251 0
+663 0.424773610937914 0.8110394125414779 0
+664 0.4885220023819107 -0.1157008831437231 0
+665 0.7164448779648906 0.9206044172492969 0
+666 0.3582031786896948 0.4067827272565083 0
+667 -0.1559443367340285 0.5040862407589783 0
+668 -0.1139332792967346 -0.6537482851763414 0
+669 0.4041230517403432 0.6241700625197997 0
+670 0.9437422446526196 0.3191864716893345 0
+671 0.8417943759747502 -0.750705083762723 0
+672 0.2543859354458 -0.3269267988982385 0
+673 0.310346947217595 0.7847699967459132 0
+674 0.9477337288834358 0.6348438077262739 0
+675 0.4896671793824416 0.2201160329445528 0
+676 0.3090553380949012 -0.514243696868651 0
+677 -0.1730952050079148 0.1654583066256123 0
+678 0.1729458184664439 0.1627160552678173 0
+679 0.007775127692827233 -0.614222297780314 0
+680 0.009394372300446763 0.2210382842084775 0
+681 0.3252644381648781 -0.6632510570175412 0
+682 0.412513722397778 -0.8338090931030018 0
+683 0.3790424500011799 0.3150766834285765 0
+684 0.9298177472919271 -0.4804508962953197 0
+685 -0.2141616373145244 -0.9423520039625769 0
+686 0.5205634572783044 0.07200051002568553 0
+687 0.6199286377401492 -0.3057965612463592 0
+688 -0.07510483034684096 -0.5060404321857541 0
+689 0.3470562357467395 0.9219733330723148 0
+690 0.9360999836351638 0.3966533761473627 0
+691 0.2380221886741546 0.7467408047891848 0
+692 -0.2103101197948715 -0.5590829704898292 0
+693 -0.05750675223929047 -0.5868135365579834 0
+694 0.9482307735414779 -0.7873082367159403 0
+695 0.7477256615419348 -0.1143663188520017 0
+696 0.06019740425305958 0.06033215768713918 0
+697 -0.06610157490812452 -0.04879416668706626 0
+698 0.7989544178449626 0.940942767537797 0
+699 -0.1306605032235158 0.1033694561250789 0
+700 0.6861875036940401 -0.1438106957750942 0
+701 0.9209041025695848 -0.2390507955767557 0
+702 0.2751517315667942 0.6334823699390395 0
+703 0.19320438099413 -0.1473968164954534 0
+704 0.07063610879826704 -0.4297092676054033 0
+705 -0.2754492783661755 0.728525394403077 0
+706 0.121254656740209 0.03700902749744817 0
+707 -0.2700774367997275 -0.6074355218561081 0
+708 0.1131877223714935 -0.04061352608840541 0
+709 0.247015505695293 -0.9558703321277155 0
+710 0.6106830230672757 0.1801351708570647 0
+711 -0.04479617677204878 -0.1212727623950782 0
+712 0.7948267626616252 -0.8190615823358236 0
+713 0.5843314223963174 0.0219897947247496 0
+714 0.6876575991089584 0.7459459069583885 0
+715 0.7264196876398439 0.8454484135328286 0
+716 0.6397439323089948 -0.1835993699335191 0
+717 -0.2276982278803913 0.7854556016180672 0
+718 0.7078183763228549 -0.2251491189147913 0
+719 0.6849682004601036 -0.06264916950773469 0
+720 -0.08760198367061081 -0.4331826712576287 0
+721 0.6280143520813333 -0.8263570913629968 0
+722 -0.2458268956321301 0.307916455239764 0
+723 0.110461412165661 0.6638888232746314 0
+724 0.573991279017215 -0.3431557930146869 0
+725 0.3983438713541476 0.2147522261103778 0
+726 -0.2818256209576052 0.9397161478808786 0
+727 -0.2735024776181197 -0.9295531143810005 0
+728 0.7069088706606104 0.005056903740016994 0
+729 -0.2944509896935912 0.003128339952431336 0
+730 0.09125735825609399 0.7326487438364229 0
+731 -0.2098779331850031 -0.782320950209083 0
+732 0.1551165664146321 0.7309359671483333 0
+733 0.650716295248303 0.3107675878769496 0
+734 0.5142694445465101 0.2813031648233271 0
+735 0.1784366727252177 0.793573142291677 0
+736 0.1139681077913502 0.7922826676743835 0
+737 0.6757385414276664 -0.5950613151606716 0
+738 -0.1962258569001853 0.5708299198174716 0
+739 0.4594357477702311 0.1338939455053811 0
+740 -0.2650612366538189 -0.6627692993169545 0
+741 0.8707805415578798 -0.2103165907066372 0
+742 -0.06120221212150218 0.09403776099094729 0
+743 -0.02057634001652747 0.6742893536794106 0
+744 0.7178002065444076 -0.523853754058923 0
+745 0.06716406662409696 -0.5642123981204208 0
+746 -0.2741547949820459 -0.08709995995219511 0
+747 0.5988540833825524 -0.04040764156460153 0
+748 0.7746621129221933 -0.2292877957168875 0
+749 0.3738821080168181 0.1169993166095467 0
+750 0.7040103572422738 0.2341825006644866 0
+751 0.1190181302617279 -0.528448260394489 0
+752 0.1001090573499544 -0.7328768834007398 0
+753 -0.2870522318629903 0.7960342268865646 0
+754 -0.2501885532133379 -0.4422518524685723 0
+755 0.2193056203864178 -0.7545218242791044 0
+756 -0.0226675442681743 -0.7256626437356591 0
+757 -0.2749719964478207 0.2341729052035402 0
+758 0.5576158565949545 -0.08866571517538768 0
+759 0.9516738983405593 0.921309339679995 0
+760 0.955956819722527 -0.9612144821544054 0
+$EndNodes
+$Elements
+1416
+1 2 2 1 6 144 37 36
+2 2 2 1 6 13 145 12
+3 2 2 1 6 127 183 177
+4 2 2 1 6 141 183 180
+5 2 2 1 6 184 140 181
+6 2 2 1 6 187 34 33
+7 2 2 1 6 190 127 177
+8 2 2 1 6 9 191 8
+9 2 2 1 6 142 193 188
+10 2 2 1 6 196 141 180
+11 2 2 1 6 145 196 180
+12 2 2 1 6 188 62 61
+13 2 2 1 6 31 193 32
+14 2 2 1 6 191 192 8
+15 2 2 1 6 192 7 8
+16 2 2 1 6 192 146 7
+17 2 2 1 6 191 143 192
+18 2 2 1 6 191 185 143
+19 2 2 1 6 194 141 196
+20 2 2 1 6 147 196 145
+21 2 2 1 6 65 194 64
+22 2 2 1 6 189 41 40
+23 2 2 1 6 147 13 14
+24 2 2 1 6 145 13 147
+25 2 2 1 6 146 1 7
+26 2 2 1 6 39 1 146
+27 2 2 1 6 198 163 164
+28 2 2 1 6 200 164 163
+29 2 2 1 6 205 162 203
+30 2 2 1 6 161 206 202
+31 2 2 1 6 152 245 199
+32 2 2 1 6 245 152 204
+33 2 2 1 6 250 194 241
+34 2 2 1 6 194 250 141
+35 2 2 1 6 130 254 190
+36 2 2 1 6 254 130 199
+37 2 2 1 6 256 130 190
+38 2 2 1 6 177 256 190
+39 2 2 1 6 130 256 201
+40 2 2 1 6 259 175 201
+41 2 2 1 6 175 259 241
+42 2 2 1 6 260 178 258
+43 2 2 1 6 261 178 260
+44 2 2 1 6 262 64 194
+45 2 2 1 6 196 262 194
+46 2 2 1 6 263 139 186
+47 2 2 1 6 175 264 201
+48 2 2 1 6 265 163 198
+49 2 2 1 6 266 127 190
+50 2 2 1 6 268 143 185
+51 2 2 1 6 176 268 185
+52 2 2 1 6 269 142 188
+53 2 2 1 6 179 269 188
+54 2 2 1 6 142 269 258
+55 2 2 1 6 182 270 257
+56 2 2 1 6 270 180 257
+57 2 2 1 6 271 182 257
+58 2 2 1 6 138 272 203
+59 2 2 1 6 272 138 202
+60 2 2 1 6 273 129 207
+61 2 2 1 6 277 189 40
+62 2 2 1 6 34 278 35
+63 2 2 1 6 279 14 2
+64 2 2 1 6 63 279 2
+65 2 2 1 6 14 279 147
+66 2 2 1 6 161 280 206
+67 2 2 1 6 281 162 205
+68 2 2 1 6 250 183 141
+69 2 2 1 6 177 183 250
+70 2 2 1 6 257 183 127
+71 2 2 1 6 180 183 257
+72 2 2 1 6 258 276 142
+73 2 2 1 6 263 258 178
+74 2 2 1 6 186 258 263
+75 2 2 1 6 266 254 176
+76 2 2 1 6 190 254 266
+77 2 2 1 6 243 263 178
+78 2 2 1 6 39 277 40
+79 2 2 1 6 39 146 277
+80 2 2 1 6 261 243 178
+81 2 2 1 6 254 245 176
+82 2 2 1 6 199 245 254
+83 2 2 1 6 259 256 177
+84 2 2 1 6 201 256 259
+85 2 2 1 6 272 206 135
+86 2 2 1 6 202 206 272
+87 2 2 1 6 205 272 135
+88 2 2 1 6 205 203 272
+89 2 2 1 6 219 280 161
+90 2 2 1 6 250 259 177
+91 2 2 1 6 250 241 259
+92 2 2 1 6 260 269 179
+93 2 2 1 6 260 258 269
+94 2 2 1 6 185 266 176
+95 2 2 1 6 135 216 205
+96 2 2 1 6 281 216 174
+97 2 2 1 6 205 216 281
+98 2 2 1 6 218 135 206
+99 2 2 1 6 218 280 173
+100 2 2 1 6 218 206 280
+101 2 2 1 6 167 208 230
+102 2 2 1 6 209 166 229
+103 2 2 1 6 137 208 216
+104 2 2 1 6 209 137 218
+105 2 2 1 6 222 52 51
+106 2 2 1 6 222 150 148
+107 2 2 1 6 76 223 75
+108 2 2 1 6 151 223 149
+109 2 2 1 6 151 221 223
+110 2 2 1 6 221 75 223
+111 2 2 1 6 224 274 133
+112 2 2 1 6 274 225 133
+113 2 2 1 6 225 151 149
+114 2 2 1 6 277 192 143
+115 2 2 1 6 192 277 146
+116 2 2 1 6 64 262 63
+117 2 2 1 6 147 262 196
+118 2 2 1 6 262 147 279
+119 2 2 1 6 262 279 63
+120 2 2 1 6 207 129 217
+121 2 2 1 6 200 131 128
+122 2 2 1 6 200 157 164
+123 2 2 1 6 239 157 200
+124 2 2 1 6 128 239 200
+125 2 2 1 6 73 235 72
+126 2 2 1 6 171 235 159
+127 2 2 1 6 171 242 235
+128 2 2 1 6 242 72 235
+129 2 2 1 6 220 160 153
+130 2 2 1 6 211 160 220
+131 2 2 1 6 159 226 154
+132 2 2 1 6 159 235 226
+133 2 2 1 6 215 153 217
+134 2 2 1 6 132 215 217
+135 2 2 1 6 154 214 159
+136 2 2 1 6 154 213 214
+137 2 2 1 6 213 132 214
+138 2 2 1 6 193 62 188
+139 2 2 1 6 265 152 199
+140 2 2 1 6 195 199 130
+141 2 2 1 6 195 252 199
+142 2 2 1 6 252 163 199
+143 2 2 1 6 163 265 199
+144 2 2 1 6 154 226 151
+145 2 2 1 6 221 151 226
+146 2 2 1 6 169 231 233
+147 2 2 1 6 231 76 77
+148 2 2 1 6 223 76 231
+149 2 2 1 6 231 169 149
+150 2 2 1 6 149 223 231
+151 2 2 1 6 212 170 160
+152 2 2 1 6 160 211 212
+153 2 2 1 6 237 70 71
+154 2 2 1 6 248 165 197
+155 2 2 1 6 70 248 69
+156 2 2 1 6 248 158 165
+157 2 2 1 6 281 174 236
+158 2 2 1 6 173 280 234
+159 2 2 1 6 251 46 45
+160 2 2 1 6 157 251 164
+161 2 2 1 6 82 238 81
+162 2 2 1 6 162 238 156
+163 2 2 1 6 219 58 57
+164 2 2 1 6 219 161 155
+165 2 2 1 6 249 66 67
+166 2 2 1 6 249 175 241
+167 2 2 1 6 42 247 43
+168 2 2 1 6 152 247 204
+169 2 2 1 6 265 247 152
+170 2 2 1 6 274 132 213
+171 2 2 1 6 151 213 154
+172 2 2 1 6 151 225 213
+173 2 2 1 6 213 225 274
+174 2 2 1 6 132 274 215
+175 2 2 1 6 215 150 153
+176 2 2 1 6 224 150 215
+177 2 2 1 6 224 215 274
+178 2 2 1 6 246 128 210
+179 2 2 1 6 172 210 158
+180 2 2 1 6 134 230 136
+181 2 2 1 6 134 228 230
+182 2 2 1 6 228 169 230
+183 2 2 1 6 229 134 136
+184 2 2 1 6 227 134 229
+185 2 2 1 6 168 227 229
+186 2 2 1 6 187 278 34
+187 2 2 1 6 134 227 133
+188 2 2 1 6 148 227 168
+189 2 2 1 6 224 133 227
+190 2 2 1 6 228 134 133
+191 2 2 1 6 228 149 169
+192 2 2 1 6 225 149 228
+193 2 2 1 6 133 225 228
+194 2 2 1 6 253 129 273
+195 2 2 1 6 191 271 185
+196 2 2 1 6 187 33 276
+197 2 2 1 6 276 193 142
+198 2 2 1 6 193 276 32
+199 2 2 1 6 33 32 276
+200 2 2 1 6 275 82 83
+201 2 2 1 6 275 156 238
+202 2 2 1 6 82 275 238
+203 2 2 1 6 184 267 140
+204 2 2 1 6 246 253 273
+205 2 2 1 6 156 203 162
+206 2 2 1 6 156 267 203
+207 2 2 1 6 131 252 195
+208 2 2 1 6 252 131 200
+209 2 2 1 6 163 252 200
+210 2 2 1 6 127 266 257
+211 2 2 1 6 271 266 185
+212 2 2 1 6 257 266 271
+213 2 2 1 6 138 243 202
+214 2 2 1 6 202 155 161
+215 2 2 1 6 261 155 202
+216 2 2 1 6 202 243 261
+217 2 2 1 6 245 268 176
+218 2 2 1 6 189 268 204
+219 2 2 1 6 268 189 277
+220 2 2 1 6 268 277 143
+221 2 2 1 6 204 268 245
+222 2 2 1 6 136 208 137
+223 2 2 1 6 136 230 208
+224 2 2 1 6 209 136 137
+225 2 2 1 6 229 136 209
+226 2 2 1 6 174 208 167
+227 2 2 1 6 174 216 208
+228 2 2 1 6 209 173 166
+229 2 2 1 6 218 173 209
+230 2 2 1 6 211 50 49
+231 2 2 1 6 220 50 211
+232 2 2 1 6 48 211 49
+233 2 2 1 6 48 212 211
+234 2 2 1 6 242 71 72
+235 2 2 1 6 237 71 242
+236 2 2 1 6 46 240 47
+237 2 2 1 6 46 251 240
+238 2 2 1 6 158 282 165
+239 2 2 1 6 283 128 131
+240 2 2 1 6 284 195 130
+241 2 2 1 6 201 284 130
+242 2 2 1 6 285 198 164
+243 2 2 1 6 251 285 164
+244 2 2 1 6 242 286 237
+245 2 2 1 6 286 242 171
+246 2 2 1 6 158 287 172
+247 2 2 1 6 288 41 189
+248 2 2 1 6 204 288 189
+249 2 2 1 6 289 171 159
+250 2 2 1 6 214 289 159
+251 2 2 1 6 290 214 129
+252 2 2 1 6 253 290 129
+253 2 2 1 6 214 290 289
+254 2 2 1 6 195 291 131
+255 2 2 1 6 291 195 284
+256 2 2 1 6 292 210 172
+257 2 2 1 6 292 253 246
+258 2 2 1 6 210 292 246
+259 2 2 1 6 293 171 289
+260 2 2 1 6 179 294 260
+261 2 2 1 6 128 295 239
+262 2 2 1 6 295 128 246
+263 2 2 1 6 170 296 207
+264 2 2 1 6 81 297 80
+265 2 2 1 6 298 55 54
+266 2 2 1 6 299 56 55
+267 2 2 1 6 300 79 80
+268 2 2 1 6 301 66 249
+269 2 2 1 6 241 301 249
+270 2 2 1 6 251 302 240
+271 2 2 1 6 302 251 157
+272 2 2 1 6 304 57 56
+273 2 2 1 6 150 305 153
+274 2 2 1 6 305 220 153
+275 2 2 1 6 306 197 264
+276 2 2 1 6 170 307 296
+277 2 2 1 6 173 309 166
+278 2 2 1 6 309 173 234
+279 2 2 1 6 310 186 187
+280 2 2 1 6 310 276 258
+281 2 2 1 6 276 310 187
+282 2 2 1 6 186 310 258
+283 2 2 1 6 198 311 265
+284 2 2 1 6 311 247 265
+285 2 2 1 6 312 174 167
+286 2 2 1 6 174 312 236
+287 2 2 1 6 160 313 153
+288 2 2 1 6 313 217 153
+289 2 2 1 6 293 286 171
+290 2 2 1 6 172 286 293
+291 2 2 1 6 298 299 55
+292 2 2 1 6 299 304 56
+293 2 2 1 6 299 234 304
+294 2 2 1 6 297 300 80
+295 2 2 1 6 297 236 300
+296 2 2 1 6 287 286 172
+297 2 2 1 6 237 286 287
+298 2 2 1 6 291 283 131
+299 2 2 1 6 255 283 291
+300 2 2 1 6 261 294 155
+301 2 2 1 6 261 260 294
+302 2 2 1 6 239 308 157
+303 2 2 1 6 306 175 249
+304 2 2 1 6 264 175 306
+305 2 2 1 6 296 273 207
+306 2 2 1 6 293 292 172
+307 2 2 1 6 253 292 293
+308 2 2 1 6 293 290 253
+309 2 2 1 6 289 290 293
+310 2 2 1 6 296 307 308
+311 2 2 1 6 306 67 68
+312 2 2 1 6 67 306 249
+313 2 2 1 6 43 311 44
+314 2 2 1 6 311 43 247
+315 2 2 1 6 65 301 194
+316 2 2 1 6 301 65 66
+317 2 2 1 6 301 241 194
+318 2 2 1 6 288 42 41
+319 2 2 1 6 42 288 247
+320 2 2 1 6 288 204 247
+321 2 2 1 6 165 264 197
+322 2 2 1 6 255 303 165
+323 2 2 1 6 255 165 282
+324 2 2 1 6 303 264 165
+325 2 2 1 6 278 187 186
+326 2 2 1 6 217 129 132
+327 2 2 1 6 129 214 132
+328 2 2 1 6 303 201 264
+329 2 2 1 6 201 303 284
+330 2 2 1 6 291 303 255
+331 2 2 1 6 284 303 291
+332 2 2 1 6 285 45 44
+333 2 2 1 6 45 285 251
+334 2 2 1 6 198 285 311
+335 2 2 1 6 311 285 44
+336 2 2 1 6 229 166 168
+337 2 2 1 6 167 230 169
+338 2 2 1 6 170 313 160
+339 2 2 1 6 313 170 207
+340 2 2 1 6 217 313 207
+341 2 2 1 6 12 270 11
+342 2 2 1 6 145 270 12
+343 2 2 1 6 270 182 11
+344 2 2 1 6 270 145 180
+345 2 2 1 6 137 216 135
+346 2 2 1 6 218 137 135
+347 2 2 1 6 282 210 128
+348 2 2 1 6 210 282 158
+349 2 2 1 6 283 255 282
+350 2 2 1 6 128 283 282
+351 2 2 1 6 184 139 244
+352 2 2 1 6 184 244 267
+353 2 2 1 6 236 297 281
+354 2 2 1 6 238 297 81
+355 2 2 1 6 162 297 238
+356 2 2 1 6 162 281 297
+357 2 2 1 6 237 287 70
+358 2 2 1 6 248 287 158
+359 2 2 1 6 287 248 70
+360 2 2 1 6 304 219 57
+361 2 2 1 6 219 304 280
+362 2 2 1 6 304 234 280
+363 2 2 1 6 243 138 244
+364 2 2 1 6 139 263 244
+365 2 2 1 6 243 244 263
+366 2 2 1 6 60 179 61
+367 2 2 1 6 188 61 179
+368 2 2 1 6 305 150 222
+369 2 2 1 6 307 212 240
+370 2 2 1 6 212 307 170
+371 2 2 1 6 314 51 50
+372 2 2 1 6 314 220 305
+373 2 2 1 6 220 314 50
+374 2 2 1 6 316 35 278
+375 2 2 1 6 317 69 248
+376 2 2 1 6 197 317 248
+377 2 2 1 6 69 317 68
+378 2 2 1 6 203 318 138
+379 2 2 1 6 244 318 267
+380 2 2 1 6 318 244 138
+381 2 2 1 6 318 203 267
+382 2 2 1 6 186 319 278
+383 2 2 1 6 316 278 319
+384 2 2 1 6 314 222 51
+385 2 2 1 6 305 222 314
+386 2 2 1 6 317 306 68
+387 2 2 1 6 197 306 317
+388 2 2 1 6 316 36 35
+389 2 2 1 6 36 316 144
+390 2 2 1 6 308 302 157
+391 2 2 1 6 302 307 240
+392 2 2 1 6 308 307 302
+393 2 2 1 6 60 315 179
+394 2 2 1 6 315 60 59
+395 2 2 1 6 315 294 179
+396 2 2 1 6 58 315 59
+397 2 2 1 6 155 315 219
+398 2 2 1 6 155 294 315
+399 2 2 1 6 315 58 219
+400 2 2 1 6 139 319 186
+401 2 2 1 6 184 319 139
+402 2 2 1 6 319 184 181
+403 2 2 1 6 312 167 169
+404 2 2 1 6 233 312 169
+405 2 2 1 6 166 309 168
+406 2 2 1 6 309 232 168
+407 2 2 1 6 77 78 231
+408 2 2 1 6 78 233 231
+409 2 2 1 6 54 232 298
+410 2 2 1 6 312 233 300
+411 2 2 1 6 312 300 236
+412 2 2 1 6 239 295 308
+413 2 2 1 6 273 295 246
+414 2 2 1 6 295 273 296
+415 2 2 1 6 308 295 296
+416 2 2 1 6 298 232 309
+417 2 2 1 6 299 309 234
+418 2 2 1 6 298 309 299
+419 2 2 1 6 222 320 52
+420 2 2 1 6 320 222 148
+421 2 2 1 6 321 168 232
+422 2 2 1 6 168 321 148
+423 2 2 1 6 267 322 140
+424 2 2 1 6 322 267 156
+425 2 2 1 6 320 53 52
+426 2 2 1 6 233 78 79
+427 2 2 1 6 233 79 300
+428 2 2 1 6 144 316 181
+429 2 2 1 6 316 319 181
+430 2 2 1 6 73 74 235
+431 2 2 1 6 74 226 235
+432 2 2 1 6 74 75 221
+433 2 2 1 6 226 74 221
+434 2 2 1 6 212 47 240
+435 2 2 1 6 47 212 48
+436 2 2 1 6 323 148 150
+437 2 2 1 6 323 224 227
+438 2 2 1 6 224 323 150
+439 2 2 1 6 148 323 227
+440 2 2 1 6 54 53 321
+441 2 2 1 6 321 53 320
+442 2 2 1 6 232 54 321
+443 2 2 1 6 321 320 148
+444 2 2 1 6 325 324 85
+445 2 2 1 6 86 325 85
+446 2 2 1 6 275 83 84
+447 2 2 1 6 275 322 156
+448 2 2 1 6 84 85 324
+449 2 2 1 6 84 324 275
+450 2 2 1 6 322 324 140
+451 2 2 1 6 322 275 324
+452 2 2 1 6 140 325 181
+453 2 2 1 6 325 144 181
+454 2 2 1 6 140 324 325
+455 2 2 1 6 325 326 144
+456 2 2 1 6 326 325 86
+457 2 2 1 6 271 327 182
+458 2 2 1 6 327 271 191
+459 2 2 1 6 31 328 193
+460 2 2 1 6 62 328 4
+461 2 2 1 6 328 62 193
+462 2 2 1 6 328 31 4
+463 2 2 1 6 38 329 5
+464 2 2 1 6 86 329 326
+465 2 2 1 6 329 86 5
+466 2 2 1 6 329 38 326
+467 2 2 1 6 327 9 10
+468 2 2 1 6 191 9 327
+469 2 2 1 6 11 327 10
+470 2 2 1 6 11 182 327
+471 2 2 1 6 38 37 326
+472 2 2 1 6 37 144 326
+473 2 2 2 10 343 64 63
+474 2 2 2 10 381 64 343
+475 2 2 2 10 385 89 88
+476 2 2 2 10 17 386 16
+477 2 2 2 10 387 28 29
+478 2 2 2 10 378 121 122
+479 2 2 2 10 381 65 64
+480 2 2 2 10 426 368 417
+481 2 2 2 10 438 368 426
+482 2 2 2 10 372 439 415
+483 2 2 2 10 379 441 419
+484 2 2 2 10 442 358 423
+485 2 2 2 10 448 364 428
+486 2 2 2 10 450 364 431
+487 2 2 2 10 364 450 428
+488 2 2 2 10 339 452 432
+489 2 2 2 10 453 344 441
+490 2 2 2 10 358 455 423
+491 2 2 2 10 356 456 429
+492 2 2 2 10 334 457 445
+493 2 2 2 10 82 458 83
+494 2 2 2 10 459 377 458
+495 2 2 2 10 369 461 421
+496 2 2 2 10 336 462 446
+497 2 2 2 10 462 336 461
+498 2 2 2 10 335 463 437
+499 2 2 2 10 465 372 415
+500 2 2 2 10 466 365 456
+501 2 2 2 10 344 469 426
+502 2 2 2 10 339 472 428
+503 2 2 2 10 379 473 441
+504 2 2 2 10 334 474 437
+505 2 2 2 10 474 334 440
+506 2 2 2 10 366 476 451
+507 2 2 2 10 479 365 466
+508 2 2 2 10 337 480 465
+509 2 2 2 10 481 372 465
+510 2 2 2 10 370 482 373
+511 2 2 2 10 484 357 434
+512 2 2 2 10 485 355 434
+513 2 2 2 10 485 357 457
+514 2 2 2 10 357 485 434
+515 2 2 2 10 486 376 446
+516 2 2 2 10 376 486 478
+517 2 2 2 10 488 331 422
+518 2 2 2 10 489 336 446
+519 2 2 2 10 336 489 484
+520 2 2 2 10 491 359 433
+521 2 2 2 10 359 491 430
+522 2 2 2 10 492 334 437
+523 2 2 2 10 334 492 457
+524 2 2 2 10 494 357 484
+525 2 2 2 10 495 359 430
+526 2 2 2 10 360 498 495
+527 2 2 2 10 500 359 495
+528 2 2 2 10 121 504 120
+529 2 2 2 10 505 376 478
+530 2 2 2 10 356 506 456
+531 2 2 2 10 507 106 107
+532 2 2 2 10 106 507 477
+533 2 2 2 10 514 356 445
+534 2 2 2 10 514 357 494
+535 2 2 2 10 342 517 380
+536 2 2 2 10 518 341 382
+537 2 2 2 10 108 521 107
+538 2 2 2 10 521 507 107
+539 2 2 2 10 426 483 344
+540 2 2 2 10 420 427 440
+541 2 2 2 10 429 445 356
+542 2 2 2 10 429 420 445
+543 2 2 2 10 454 461 336
+544 2 2 2 10 454 421 461
+545 2 2 2 10 442 435 362
+546 2 2 2 10 444 455 360
+547 2 2 2 10 444 423 455
+548 2 2 2 10 438 426 469
+549 2 2 2 10 452 450 362
+550 2 2 2 10 448 472 374
+551 2 2 2 10 448 428 472
+552 2 2 2 10 447 456 365
+553 2 2 2 10 447 429 456
+554 2 2 2 10 449 491 354
+555 2 2 2 10 449 430 491
+556 2 2 2 10 495 444 360
+557 2 2 2 10 430 444 495
+558 2 2 2 10 484 454 336
+559 2 2 2 10 434 454 484
+560 2 2 2 10 492 463 355
+561 2 2 2 10 437 463 492
+562 2 2 2 10 464 474 379
+563 2 2 2 10 453 469 344
+564 2 2 2 10 474 473 379
+565 2 2 2 10 440 473 474
+566 2 2 2 10 453 473 361
+567 2 2 2 10 453 441 473
+568 2 2 2 10 514 457 357
+569 2 2 2 10 445 457 514
+570 2 2 2 10 486 462 378
+571 2 2 2 10 446 462 486
+572 2 2 2 10 455 476 360
+573 2 2 2 10 455 451 476
+574 2 2 2 10 476 498 360
+575 2 2 2 10 466 456 506
+576 2 2 2 10 485 492 355
+577 2 2 2 10 485 457 492
+578 2 2 2 10 465 480 481
+579 2 2 2 10 490 477 507
+580 2 2 2 10 494 489 384
+581 2 2 2 10 484 489 494
+582 2 2 2 10 500 498 340
+583 2 2 2 10 495 498 500
+584 2 2 2 10 524 374 472
+585 2 2 2 10 524 472 512
+586 2 2 2 10 374 524 386
+587 2 2 2 10 105 106 477
+588 2 2 2 10 123 124 478
+589 2 2 2 10 19 497 18
+590 2 2 2 10 374 497 448
+591 2 2 2 10 496 26 27
+592 2 2 2 10 460 22 23
+593 2 2 2 10 482 91 90
+594 2 2 2 10 482 370 467
+595 2 2 2 10 503 447 365
+596 2 2 2 10 503 98 97
+597 2 2 2 10 451 508 366
+598 2 2 2 10 26 508 25
+599 2 2 2 10 110 493 109
+600 2 2 2 10 388 500 340
+601 2 2 2 10 514 506 356
+602 2 2 2 10 384 506 494
+603 2 2 2 10 494 506 514
+604 2 2 2 10 376 523 446
+605 2 2 2 10 489 523 384
+606 2 2 2 10 446 523 489
+607 2 2 2 10 87 519 88
+608 2 2 2 10 519 385 88
+609 2 2 2 10 524 512 391
+610 2 2 2 10 518 102 101
+611 2 2 2 10 342 387 517
+612 2 2 2 10 30 517 29
+613 2 2 2 10 517 387 29
+614 2 2 2 10 390 388 340
+615 2 2 2 10 513 388 390
+616 2 2 2 10 513 337 388
+617 2 2 2 10 480 337 513
+618 2 2 2 10 480 513 490
+619 2 2 2 10 459 368 438
+620 2 2 2 10 459 438 520
+621 2 2 2 10 511 342 380
+622 2 2 2 10 341 505 382
+623 2 2 2 10 449 371 332
+624 2 2 2 10 369 504 461
+625 2 2 2 10 378 504 121
+626 2 2 2 10 462 504 378
+627 2 2 2 10 462 461 504
+628 2 2 2 10 529 408 407
+629 2 2 2 10 530 393 409
+630 2 2 2 10 533 401 397
+631 2 2 2 10 536 470 531
+632 2 2 2 10 394 539 536
+633 2 2 2 10 540 346 348
+634 2 2 2 10 545 407 408
+635 2 2 2 10 407 545 542
+636 2 2 2 10 547 447 503
+637 2 2 2 10 413 548 414
+638 2 2 2 10 549 409 393
+639 2 2 2 10 555 393 530
+640 2 2 2 10 555 333 537
+641 2 2 2 10 564 401 533
+642 2 2 2 10 451 566 508
+643 2 2 2 10 567 406 526
+644 2 2 2 10 567 418 565
+645 2 2 2 10 569 408 419
+646 2 2 2 10 493 571 372
+647 2 2 2 10 572 71 70
+648 2 2 2 10 71 572 526
+649 2 2 2 10 393 575 549
+650 2 2 2 10 436 579 528
+651 2 2 2 10 581 408 529
+652 2 2 2 10 582 353 439
+653 2 2 2 10 583 447 547
+654 2 2 2 10 389 585 529
+655 2 2 2 10 586 91 482
+656 2 2 2 10 467 586 482
+657 2 2 2 10 589 69 68
+658 2 2 2 10 592 516 552
+659 2 2 2 10 418 594 565
+660 2 2 2 10 19 595 497
+661 2 2 2 10 595 448 497
+662 2 2 2 10 404 596 525
+663 2 2 2 10 436 597 363
+664 2 2 2 10 597 436 528
+665 2 2 2 10 522 598 533
+666 2 2 2 10 599 409 549
+667 2 2 2 10 333 600 537
+668 2 2 2 10 522 601 534
+669 2 2 2 10 451 603 566
+670 2 2 2 10 604 516 535
+671 2 2 2 10 605 352 424
+672 2 2 2 10 352 605 471
+673 2 2 2 10 392 608 546
+674 2 2 2 10 609 82 81
+675 2 2 2 10 611 416 538
+676 2 2 2 10 612 90 89
+677 2 2 2 10 612 373 482
+678 2 2 2 10 90 612 482
+679 2 2 2 10 615 467 363
+680 2 2 2 10 467 615 586
+681 2 2 2 10 479 616 365
+682 2 2 2 10 616 503 365
+683 2 2 2 10 617 335 541
+684 2 2 2 10 618 358 442
+685 2 2 2 10 618 431 593
+686 2 2 2 10 431 618 442
+687 2 2 2 10 483 621 344
+688 2 2 2 10 622 369 421
+689 2 2 2 10 422 623 488
+690 2 2 2 10 435 626 607
+691 2 2 2 10 627 431 364
+692 2 2 2 10 372 628 439
+693 2 2 2 10 628 372 571
+694 2 2 2 10 392 629 531
+695 2 2 2 10 630 505 478
+696 2 2 2 10 505 630 382
+697 2 2 2 10 124 630 478
+698 2 2 2 10 631 96 95
+699 2 2 2 10 96 631 547
+700 2 2 2 10 406 633 552
+701 2 2 2 10 635 331 488
+702 2 2 2 10 468 636 520
+703 2 2 2 10 487 637 530
+704 2 2 2 10 333 637 587
+705 2 2 2 10 508 638 366
+706 2 2 2 10 639 354 491
+707 2 2 2 10 433 639 491
+708 2 2 2 10 353 640 439
+709 2 2 2 10 640 415 439
+710 2 2 2 10 387 641 28
+711 2 2 2 10 642 332 625
+712 2 2 2 10 386 643 374
+713 2 2 2 10 643 497 374
+714 2 2 2 10 643 386 17
+715 2 2 2 10 381 646 65
+716 2 2 2 10 80 648 81
+717 2 2 2 10 69 649 70
+718 2 2 2 10 650 414 371
+719 2 2 2 10 449 650 371
+720 2 2 2 10 376 652 523
+721 2 2 2 10 654 420 429
+722 2 2 2 10 420 654 427
+723 2 2 2 10 413 657 548
+724 2 2 2 10 658 432 452
+725 2 2 2 10 659 460 603
+726 2 2 2 10 460 659 593
+727 2 2 2 10 417 660 426
+728 2 2 2 10 660 483 426
+729 2 2 2 10 370 661 467
+730 2 2 2 10 661 370 468
+731 2 2 2 10 663 447 583
+732 2 2 2 10 447 663 429
+733 2 2 2 10 666 437 474
+734 2 2 2 10 464 666 474
+735 2 2 2 10 334 669 440
+736 2 2 2 10 420 669 445
+737 2 2 2 10 669 420 440
+738 2 2 2 10 669 334 445
+739 2 2 2 10 670 118 119
+740 2 2 2 10 511 671 342
+741 2 2 2 10 331 672 422
+742 2 2 2 10 672 409 422
+743 2 2 2 10 673 427 654
+744 2 2 2 10 122 674 378
+745 2 2 2 10 674 486 378
+746 2 2 2 10 676 371 488
+747 2 2 2 10 678 407 542
+748 2 2 2 10 678 401 564
+749 2 2 2 10 679 425 339
+750 2 2 2 10 432 679 339
+751 2 2 2 10 680 470 536
+752 2 2 2 10 680 351 542
+753 2 2 2 10 423 681 442
+754 2 2 2 10 435 681 625
+755 2 2 2 10 681 435 442
+756 2 2 2 10 358 682 455
+757 2 2 2 10 451 682 603
+758 2 2 2 10 682 451 455
+759 2 2 2 10 335 683 541
+760 2 2 2 10 389 683 585
+761 2 2 2 10 481 684 372
+762 2 2 2 10 684 493 372
+763 2 2 2 10 16 685 15
+764 2 2 2 10 685 16 386
+765 2 2 2 10 94 689 95
+766 2 2 2 10 689 94 528
+767 2 2 2 10 120 690 119
+768 2 2 2 10 427 691 361
+769 2 2 2 10 693 425 679
+770 2 2 2 10 411 693 679
+771 2 2 2 10 511 694 477
+772 2 2 2 10 694 511 380
+773 2 2 2 10 694 105 477
+774 2 2 2 10 694 104 105
+775 2 2 2 10 380 104 694
+776 2 2 2 10 125 630 124
+777 2 2 2 10 125 382 630
+778 2 2 2 10 617 463 335
+779 2 2 2 10 649 572 70
+780 2 2 2 10 418 572 649
+781 2 2 2 10 621 441 344
+782 2 2 2 10 419 441 621
+783 2 2 2 10 668 693 367
+784 2 2 2 10 668 425 693
+785 2 2 2 10 512 425 668
+786 2 2 2 10 654 429 663
+787 2 2 2 10 582 439 628
+788 2 2 2 10 689 631 95
+789 2 2 2 10 468 338 661
+790 2 2 2 10 471 605 647
+791 2 2 2 10 648 609 81
+792 2 2 2 10 635 371 414
+793 2 2 2 10 488 371 635
+794 2 2 2 10 646 66 65
+795 2 2 2 10 597 615 363
+796 2 2 2 10 690 670 119
+797 2 2 2 10 501 670 690
+798 2 2 2 10 343 624 381
+799 2 2 2 10 646 375 499
+800 2 2 2 10 488 623 676
+801 2 2 2 10 99 665 100
+802 2 2 2 10 641 27 28
+803 2 2 2 10 496 27 641
+804 2 2 2 10 614 540 402
+805 2 2 2 10 567 572 418
+806 2 2 2 10 567 526 572
+807 2 2 2 10 528 579 689
+808 2 2 2 10 581 585 464
+809 2 2 2 10 581 529 585
+810 2 2 2 10 555 637 333
+811 2 2 2 10 555 530 637
+812 2 2 2 10 536 629 394
+813 2 2 2 10 536 531 629
+814 2 2 2 10 564 533 598
+815 2 2 2 10 574 534 601
+816 2 2 2 10 543 677 394
+817 2 2 2 10 552 619 406
+818 2 2 2 10 677 539 394
+819 2 2 2 10 680 539 351
+820 2 2 2 10 536 539 680
+821 2 2 2 10 680 545 470
+822 2 2 2 10 542 545 680
+823 2 2 2 10 558 614 402
+824 2 2 2 10 583 547 631
+825 2 2 2 10 599 549 647
+826 2 2 2 10 592 633 471
+827 2 2 2 10 592 552 633
+828 2 2 2 10 678 584 407
+829 2 2 2 10 564 584 678
+830 2 2 2 10 578 596 404
+831 2 2 2 10 606 623 422
+832 2 2 2 10 606 568 623
+833 2 2 2 10 578 670 501
+834 2 2 2 10 574 644 664
+835 2 2 2 10 583 620 663
+836 2 2 2 10 618 659 358
+837 2 2 2 10 618 593 659
+838 2 2 2 10 625 626 435
+839 2 2 2 10 659 682 358
+840 2 2 2 10 659 603 682
+841 2 2 2 10 642 681 423
+842 2 2 2 10 642 625 681
+843 2 2 2 10 351 553 542
+844 2 2 2 10 678 553 401
+845 2 2 2 10 542 553 678
+846 2 2 2 10 558 402 562
+847 2 2 2 10 348 577 540
+848 2 2 2 10 577 402 540
+849 2 2 2 10 421 645 653
+850 2 2 2 10 633 352 471
+851 2 2 2 10 352 633 565
+852 2 2 2 10 567 633 406
+853 2 2 2 10 567 565 633
+854 2 2 2 10 655 373 385
+855 2 2 2 10 519 655 385
+856 2 2 2 10 655 519 383
+857 2 2 2 10 109 493 684
+858 2 2 2 10 521 684 481
+859 2 2 2 10 684 521 108
+860 2 2 2 10 109 684 108
+861 2 2 2 10 662 479 466
+862 2 2 2 10 636 370 373
+863 2 2 2 10 370 636 468
+864 2 2 2 10 655 515 636
+865 2 2 2 10 373 655 636
+866 2 2 2 10 398 557 396
+867 2 2 2 10 398 563 557
+868 2 2 2 10 396 573 398
+869 2 2 2 10 454 645 421
+870 2 2 2 10 645 454 434
+871 2 2 2 10 560 113 114
+872 2 2 2 10 613 560 405
+873 2 2 2 10 562 114 115
+874 2 2 2 10 560 114 562
+875 2 2 2 10 405 560 562
+876 2 2 2 10 563 76 75
+877 2 2 2 10 556 76 563
+878 2 2 2 10 563 398 400
+879 2 2 2 10 400 556 563
+880 2 2 2 10 396 557 395
+881 2 2 2 10 72 559 73
+882 2 2 2 10 559 619 395
+883 2 2 2 10 556 77 76
+884 2 2 2 10 400 677 556
+885 2 2 2 10 543 556 677
+886 2 2 2 10 113 527 112
+887 2 2 2 10 113 560 527
+888 2 2 2 10 613 410 527
+889 2 2 2 10 527 560 613
+890 2 2 2 10 118 590 117
+891 2 2 2 10 118 670 590
+892 2 2 2 10 578 404 590
+893 2 2 2 10 578 590 670
+894 2 2 2 10 404 614 590
+895 2 2 2 10 558 590 614
+896 2 2 2 10 629 543 394
+897 2 2 2 10 526 72 71
+898 2 2 2 10 559 72 526
+899 2 2 2 10 406 619 526
+900 2 2 2 10 559 526 619
+901 2 2 2 10 561 110 111
+902 2 2 2 10 110 561 493
+903 2 2 2 10 571 493 561
+904 2 2 2 10 544 80 79
+905 2 2 2 10 648 80 544
+906 2 2 2 10 392 546 544
+907 2 2 2 10 544 546 648
+908 2 2 2 10 674 122 123
+909 2 2 2 10 674 478 486
+910 2 2 2 10 478 674 123
+911 2 2 2 10 94 93 528
+912 2 2 2 10 409 672 530
+913 2 2 2 10 672 487 530
+914 2 2 2 10 487 672 331
+915 2 2 2 10 635 414 548
+916 2 2 2 10 487 635 548
+917 2 2 2 10 635 487 331
+918 2 2 2 10 20 595 19
+919 2 2 2 10 660 345 483
+920 2 2 2 10 608 660 417
+921 2 2 2 10 345 621 483
+922 2 2 2 10 621 345 569
+923 2 2 2 10 419 621 569
+924 2 2 2 10 575 393 535
+925 2 2 2 10 516 575 535
+926 2 2 2 10 652 505 341
+927 2 2 2 10 505 652 376
+928 2 2 2 10 509 652 341
+929 2 2 2 10 92 91 586
+930 2 2 2 10 92 586 615
+931 2 2 2 10 622 501 369
+932 2 2 2 10 578 501 622
+933 2 2 2 10 578 622 596
+934 2 2 2 10 609 458 82
+935 2 2 2 10 355 656 434
+936 2 2 2 10 434 656 645
+937 2 2 2 10 397 576 533
+938 2 2 2 10 576 522 533
+939 2 2 2 10 613 405 554
+940 2 2 2 10 582 502 353
+941 2 2 2 10 17 18 643
+942 2 2 2 10 18 497 643
+943 2 2 2 10 647 592 471
+944 2 2 2 10 575 516 592
+945 2 2 2 10 575 592 549
+946 2 2 2 10 592 647 549
+947 2 2 2 10 614 404 525
+948 2 2 2 10 525 540 614
+949 2 2 2 10 395 619 570
+950 2 2 2 10 552 570 619
+951 2 2 2 10 333 587 644
+952 2 2 2 10 587 330 644
+953 2 2 2 10 688 411 424
+954 2 2 2 10 411 688 693
+955 2 2 2 10 693 688 367
+956 2 2 2 10 411 610 424
+957 2 2 2 10 354 650 449
+958 2 2 2 10 354 632 650
+959 2 2 2 10 414 650 413
+960 2 2 2 10 632 413 650
+961 2 2 2 10 522 576 601
+962 2 2 2 10 599 422 409
+963 2 2 2 10 606 422 599
+964 2 2 2 10 413 632 412
+965 2 2 2 10 443 632 354
+966 2 2 2 10 330 657 611
+967 2 2 2 10 611 412 416
+968 2 2 2 10 639 443 354
+969 2 2 2 10 667 417 368
+970 2 2 2 10 667 608 417
+971 2 2 2 10 667 546 608
+972 2 2 2 10 501 690 369
+973 2 2 2 10 690 504 369
+974 2 2 2 10 504 690 120
+975 2 2 2 10 616 98 503
+976 2 2 2 10 616 99 98
+977 2 2 2 10 340 510 390
+978 2 2 2 10 551 348 346
+979 2 2 2 10 551 349 348
+980 2 2 2 10 403 686 551
+981 2 2 2 10 676 332 371
+982 2 2 2 10 625 332 676
+983 2 2 2 10 625 676 626
+984 2 2 2 10 97 96 547
+985 2 2 2 10 503 97 547
+986 2 2 2 10 570 396 395
+987 2 2 2 10 332 642 449
+988 2 2 2 10 444 642 423
+989 2 2 2 10 430 642 444
+990 2 2 2 10 642 430 449
+991 2 2 2 10 512 375 391
+992 2 2 2 10 512 668 375
+993 2 2 2 10 345 531 470
+994 2 2 2 10 345 660 531
+995 2 2 2 10 608 392 531
+996 2 2 2 10 531 660 608
+997 2 2 2 10 408 569 545
+998 2 2 2 10 569 470 545
+999 2 2 2 10 470 569 345
+1000 2 2 2 10 490 671 477
+1001 2 2 2 10 671 511 477
+1002 2 2 2 10 671 490 513
+1003 2 2 2 10 671 513 390
+1004 2 2 2 10 333 644 600
+1005 2 2 2 10 600 644 574
+1006 2 2 2 10 574 601 600
+1007 2 2 2 10 638 26 496
+1008 2 2 2 10 26 638 508
+1009 2 2 2 10 641 387 510
+1010 2 2 2 10 496 641 510
+1011 2 2 2 10 584 389 529
+1012 2 2 2 10 407 584 529
+1013 2 2 2 10 24 25 566
+1014 2 2 2 10 25 508 566
+1015 2 2 2 10 576 399 537
+1016 2 2 2 10 399 576 397
+1017 2 2 2 10 576 537 600
+1018 2 2 2 10 576 600 601
+1019 2 2 2 10 666 335 437
+1020 2 2 2 10 666 683 335
+1021 2 2 2 10 666 464 585
+1022 2 2 2 10 666 585 683
+1023 2 2 2 10 593 22 460
+1024 2 2 2 10 431 627 593
+1025 2 2 2 10 23 24 566
+1026 2 2 2 10 23 603 460
+1027 2 2 2 10 566 603 23
+1028 2 2 2 10 353 687 443
+1029 2 2 2 10 502 687 353
+1030 2 2 2 10 412 687 416
+1031 2 2 2 10 634 416 687
+1032 2 2 2 10 502 634 687
+1033 2 2 2 10 443 640 353
+1034 2 2 2 10 443 639 640
+1035 2 2 2 10 639 433 640
+1036 2 2 2 10 673 691 427
+1037 2 2 2 10 509 341 518
+1038 2 2 2 10 389 584 580
+1039 2 2 2 10 580 584 564
+1040 2 2 2 10 564 598 580
+1041 2 2 2 10 419 581 379
+1042 2 2 2 10 581 419 408
+1043 2 2 2 10 581 464 379
+1044 2 2 2 10 385 612 89
+1045 2 2 2 10 385 373 612
+1046 2 2 2 10 412 657 413
+1047 2 2 2 10 611 657 412
+1048 2 2 2 10 554 695 613
+1049 2 2 2 10 347 696 351
+1050 2 2 2 10 696 553 351
+1051 2 2 2 10 696 347 588
+1052 2 2 2 10 697 396 570
+1053 2 2 2 10 396 697 573
+1054 2 2 2 10 698 100 665
+1055 2 2 2 10 509 698 665
+1056 2 2 2 10 699 677 400
+1057 2 2 2 10 700 602 695
+1058 2 2 2 10 527 701 112
+1059 2 2 2 10 561 701 591
+1060 2 2 2 10 702 361 473
+1061 2 2 2 10 702 440 427
+1062 2 2 2 10 440 702 473
+1063 2 2 2 10 361 702 427
+1064 2 2 2 10 393 703 535
+1065 2 2 2 10 399 703 537
+1066 2 2 2 10 703 399 535
+1067 2 2 2 10 704 610 606
+1068 2 2 2 10 599 704 606
+1069 2 2 2 10 83 705 84
+1070 2 2 2 10 705 83 458
+1071 2 2 2 10 401 706 397
+1072 2 2 2 10 706 401 553
+1073 2 2 2 10 708 399 397
+1074 2 2 2 10 709 21 22
+1075 2 2 2 10 709 593 627
+1076 2 2 2 10 593 709 22
+1077 2 2 2 10 516 711 552
+1078 2 2 2 10 711 570 552
+1079 2 2 2 10 711 516 604
+1080 2 2 2 10 342 712 387
+1081 2 2 2 10 712 510 387
+1082 2 2 2 10 713 551 686
+1083 2 2 2 10 551 713 349
+1084 2 2 2 10 550 713 686
+1085 2 2 2 10 714 506 384
+1086 2 2 2 10 714 662 466
+1087 2 2 2 10 506 714 466
+1088 2 2 2 10 662 715 479
+1089 2 2 2 10 715 665 479
+1090 2 2 2 10 716 350 538
+1091 2 2 2 10 416 716 538
+1092 2 2 2 10 717 515 655
+1093 2 2 2 10 383 717 655
+1094 2 2 2 10 502 718 634
+1095 2 2 2 10 565 720 352
+1096 2 2 2 10 720 565 594
+1097 2 2 2 10 721 510 340
+1098 2 2 2 10 544 722 392
+1099 2 2 2 10 722 629 392
+1100 2 2 2 10 723 469 453
+1101 2 2 2 10 469 723 338
+1102 2 2 2 10 724 632 443
+1103 2 2 2 10 724 687 412
+1104 2 2 2 10 687 724 443
+1105 2 2 2 10 632 724 412
+1106 2 2 2 10 86 726 5
+1107 2 2 2 10 87 726 519
+1108 2 2 2 10 726 87 5
+1109 2 2 2 10 15 727 2
+1110 2 2 2 10 727 63 2
+1111 2 2 2 10 728 348 349
+1112 2 2 2 10 728 554 577
+1113 2 2 2 10 348 728 577
+1114 2 2 2 10 729 75 74
+1115 2 2 2 10 729 557 563
+1116 2 2 2 10 75 729 563
+1117 2 2 2 10 555 703 393
+1118 2 2 2 10 555 537 703
+1119 2 2 2 10 706 708 397
+1120 2 2 2 10 706 588 708
+1121 2 2 2 10 377 705 458
+1122 2 2 2 10 410 695 602
+1123 2 2 2 10 410 613 695
+1124 2 2 2 10 398 699 400
+1125 2 2 2 10 398 573 699
+1126 2 2 2 10 696 706 553
+1127 2 2 2 10 696 588 706
+1128 2 2 2 10 700 718 602
+1129 2 2 2 10 523 714 384
+1130 2 2 2 10 720 424 352
+1131 2 2 2 10 688 424 720
+1132 2 2 2 10 424 610 704
+1133 2 2 2 10 63 727 343
+1134 2 2 2 10 685 727 15
+1135 2 2 2 10 350 716 700
+1136 2 2 2 10 634 716 416
+1137 2 2 2 10 718 716 634
+1138 2 2 2 10 700 716 718
+1139 2 2 2 10 698 101 100
+1140 2 2 2 10 101 698 518
+1141 2 2 2 10 698 509 518
+1142 2 2 2 10 582 718 502
+1143 2 2 2 10 715 509 665
+1144 2 2 2 10 715 652 509
+1145 2 2 2 10 665 99 616
+1146 2 2 2 10 616 479 665
+1147 2 2 2 10 510 712 390
+1148 2 2 2 10 712 671 390
+1149 2 2 2 10 671 712 342
+1150 2 2 2 10 699 539 677
+1151 2 2 2 10 448 595 364
+1152 2 2 2 10 708 535 399
+1153 2 2 2 10 535 708 604
+1154 2 2 2 10 667 648 546
+1155 2 2 2 10 424 704 605
+1156 2 2 2 10 599 647 605
+1157 2 2 2 10 704 599 605
+1158 2 2 2 10 85 383 86
+1159 2 2 2 10 383 726 86
+1160 2 2 2 10 383 519 726
+1161 2 2 2 10 710 346 475
+1162 2 2 2 10 475 651 532
+1163 2 2 2 10 532 710 475
+1164 2 2 2 10 588 347 604
+1165 2 2 2 10 604 708 588
+1166 2 2 2 10 597 93 92
+1167 2 2 2 10 92 615 597
+1168 2 2 2 10 597 528 93
+1169 2 2 2 10 481 480 521
+1170 2 2 2 10 480 490 521
+1171 2 2 2 10 490 507 521
+1172 2 2 2 10 459 515 377
+1173 2 2 2 10 459 520 515
+1174 2 2 2 10 515 520 636
+1175 2 2 2 10 607 626 568
+1176 2 2 2 10 626 623 568
+1177 2 2 2 10 676 623 626
+1178 2 2 2 10 663 620 654
+1179 2 2 2 10 722 543 629
+1180 2 2 2 10 111 112 701
+1181 2 2 2 10 561 111 701
+1182 2 2 2 10 594 692 367
+1183 2 2 2 10 688 594 367
+1184 2 2 2 10 594 688 720
+1185 2 2 2 10 620 689 579
+1186 2 2 2 10 689 620 583
+1187 2 2 2 10 583 631 689
+1188 2 2 2 10 628 571 561
+1189 2 2 2 10 591 628 561
+1190 2 2 2 10 628 591 582
+1191 2 2 2 10 707 499 692
+1192 2 2 2 10 700 719 350
+1193 2 2 2 10 554 719 695
+1194 2 2 2 10 719 554 728
+1195 2 2 2 10 719 728 349
+1196 2 2 2 10 695 719 700
+1197 2 2 2 10 355 463 617
+1198 2 2 2 10 656 355 617
+1199 2 2 2 10 656 617 651
+1200 2 2 2 10 727 624 343
+1201 2 2 2 10 624 685 386
+1202 2 2 2 10 685 624 727
+1203 2 2 2 10 596 622 421
+1204 2 2 2 10 653 596 421
+1205 2 2 2 10 596 653 525
+1206 2 2 2 10 562 402 405
+1207 2 2 2 10 402 577 405
+1208 2 2 2 10 405 577 554
+1209 2 2 2 10 532 675 403
+1210 2 2 2 10 607 568 658
+1211 2 2 2 10 657 330 587
+1212 2 2 2 10 657 487 548
+1213 2 2 2 10 657 637 487
+1214 2 2 2 10 657 587 637
+1215 2 2 2 10 710 532 403
+1216 2 2 2 10 551 710 403
+1217 2 2 2 10 710 551 346
+1218 2 2 2 10 436 673 579
+1219 2 2 2 10 436 691 673
+1220 2 2 2 10 579 673 620
+1221 2 2 2 10 620 673 654
+1222 2 2 2 10 21 627 20
+1223 2 2 2 10 20 627 595
+1224 2 2 2 10 595 627 364
+1225 2 2 2 10 709 627 21
+1226 2 2 2 10 338 730 661
+1227 2 2 2 10 375 731 391
+1228 2 2 2 10 732 361 691
+1229 2 2 2 10 475 733 651
+1230 2 2 2 10 733 656 651
+1231 2 2 2 10 734 617 541
+1232 2 2 2 10 675 734 541
+1233 2 2 2 10 617 734 651
+1234 2 2 2 10 735 436 363
+1235 2 2 2 10 436 735 691
+1236 2 2 2 10 467 736 363
+1237 2 2 2 10 736 467 661
+1238 2 2 2 10 500 737 359
+1239 2 2 2 10 737 500 388
+1240 2 2 2 10 459 738 368
+1241 2 2 2 10 738 667 368
+1242 2 2 2 10 740 646 499
+1243 2 2 2 10 707 740 499
+1244 2 2 2 10 646 740 66
+1245 2 2 2 10 741 527 410
+1246 2 2 2 10 741 591 701
+1247 2 2 2 10 591 741 410
+1248 2 2 2 10 527 741 701
+1249 2 2 2 10 742 351 539
+1250 2 2 2 10 699 742 539
+1251 2 2 2 10 743 438 469
+1252 2 2 2 10 438 743 520
+1253 2 2 2 10 338 743 469
+1254 2 2 2 10 640 744 415
+1255 2 2 2 10 744 640 433
+1256 2 2 2 10 658 745 432
+1257 2 2 2 10 411 745 610
+1258 2 2 2 10 73 746 74
+1259 2 2 2 10 746 73 559
+1260 2 2 2 10 747 719 349
+1261 2 2 2 10 591 748 582
+1262 2 2 2 10 748 718 582
+1263 2 2 2 10 748 591 410
+1264 2 2 2 10 749 522 534
+1265 2 2 2 10 522 749 598
+1266 2 2 2 10 750 525 653
+1267 2 2 2 10 606 751 568
+1268 2 2 2 10 751 658 568
+1269 2 2 2 10 751 606 610
+1270 2 2 2 10 679 745 411
+1271 2 2 2 10 679 432 745
+1272 2 2 2 10 723 730 338
+1273 2 2 2 10 468 743 338
+1274 2 2 2 10 468 520 743
+1275 2 2 2 10 713 747 349
+1276 2 2 2 10 713 550 747
+1277 2 2 2 10 736 735 363
+1278 2 2 2 10 746 395 557
+1279 2 2 2 10 559 395 746
+1280 2 2 2 10 749 580 598
+1281 2 2 2 10 744 465 415
+1282 2 2 2 10 602 748 410
+1283 2 2 2 10 602 718 748
+1284 2 2 2 10 734 532 651
+1285 2 2 2 10 675 532 734
+1286 2 2 2 10 337 737 388
+1287 2 2 2 10 737 433 359
+1288 2 2 2 10 745 751 610
+1289 2 2 2 10 745 658 751
+1290 2 2 2 10 732 691 735
+1291 2 2 2 10 730 736 661
+1292 2 2 2 10 747 350 719
+1293 2 2 2 10 739 403 675
+1294 2 2 2 10 725 739 675
+1295 2 2 2 10 351 742 347
+1296 2 2 2 10 742 573 347
+1297 2 2 2 10 573 742 699
+1298 2 2 2 10 750 733 475
+1299 2 2 2 10 733 645 656
+1300 2 2 2 10 645 733 653
+1301 2 2 2 10 653 733 750
+1302 2 2 2 10 697 347 573
+1303 2 2 2 10 347 697 604
+1304 2 2 2 10 604 697 711
+1305 2 2 2 10 711 697 570
+1306 2 2 2 10 624 731 381
+1307 2 2 2 10 731 646 381
+1308 2 2 2 10 646 731 375
+1309 2 2 2 10 638 721 366
+1310 2 2 2 10 721 638 496
+1311 2 2 2 10 510 721 496
+1312 2 2 2 10 544 79 722
+1313 2 2 2 10 524 391 386
+1314 2 2 2 10 386 391 624
+1315 2 2 2 10 624 391 731
+1316 2 2 2 10 453 361 723
+1317 2 2 2 10 361 732 723
+1318 2 2 2 10 732 730 723
+1319 2 2 2 10 435 607 362
+1320 2 2 2 10 607 452 362
+1321 2 2 2 10 607 658 452
+1322 2 2 2 10 686 739 534
+1323 2 2 2 10 739 686 403
+1324 2 2 2 10 739 749 534
+1325 2 2 2 10 750 346 540
+1326 2 2 2 10 346 750 475
+1327 2 2 2 10 525 750 540
+1328 2 2 2 10 562 116 558
+1329 2 2 2 10 116 562 115
+1330 2 2 2 10 499 668 367
+1331 2 2 2 10 692 499 367
+1332 2 2 2 10 668 499 375
+1333 2 2 2 10 652 714 523
+1334 2 2 2 10 715 662 652
+1335 2 2 2 10 652 662 714
+1336 2 2 2 10 340 498 721
+1337 2 2 2 10 476 366 721
+1338 2 2 2 10 476 721 498
+1339 2 2 2 10 104 380 103
+1340 2 2 2 10 517 103 380
+1341 2 2 2 10 692 594 589
+1342 2 2 2 10 389 580 725
+1343 2 2 2 10 725 683 389
+1344 2 2 2 10 725 541 683
+1345 2 2 2 10 725 675 541
+1346 2 2 2 10 377 717 705
+1347 2 2 2 10 515 717 377
+1348 2 2 2 10 707 692 589
+1349 2 2 2 10 746 729 74
+1350 2 2 2 10 557 729 746
+1351 2 2 2 10 740 67 66
+1352 2 2 2 10 707 67 740
+1353 2 2 2 10 707 68 67
+1354 2 2 2 10 589 68 707
+1355 2 2 2 10 428 752 339
+1356 2 2 2 10 452 752 450
+1357 2 2 2 10 752 452 339
+1358 2 2 2 10 752 428 450
+1359 2 2 2 10 753 85 84
+1360 2 2 2 10 753 717 383
+1361 2 2 2 10 85 753 383
+1362 2 2 2 10 418 754 594
+1363 2 2 2 10 754 589 594
+1364 2 2 2 10 754 418 649
+1365 2 2 2 10 754 69 589
+1366 2 2 2 10 649 69 754
+1367 2 2 2 10 705 753 84
+1368 2 2 2 10 705 717 753
+1369 2 2 2 10 722 79 78
+1370 2 2 2 10 730 732 736
+1371 2 2 2 10 732 735 736
+1372 2 2 2 10 574 550 534
+1373 2 2 2 10 550 686 534
+1374 2 2 2 10 664 550 574
+1375 2 2 2 10 749 725 580
+1376 2 2 2 10 739 725 749
+1377 2 2 2 10 458 738 459
+1378 2 2 2 10 738 458 609
+1379 2 2 2 10 648 667 738
+1380 2 2 2 10 648 738 609
+1381 2 2 2 10 558 117 590
+1382 2 2 2 10 558 116 117
+1383 2 2 2 10 744 337 465
+1384 2 2 2 10 337 744 737
+1385 2 2 2 10 744 433 737
+1386 2 2 2 10 755 442 362
+1387 2 2 2 10 755 450 431
+1388 2 2 2 10 450 755 362
+1389 2 2 2 10 442 755 431
+1390 2 2 2 10 339 756 472
+1391 2 2 2 10 512 756 425
+1392 2 2 2 10 756 512 472
+1393 2 2 2 10 756 339 425
+1394 2 2 2 10 664 644 330
+1395 2 2 2 10 330 611 664
+1396 2 2 2 10 664 611 538
+1397 2 2 2 10 556 757 77
+1398 2 2 2 10 757 556 543
+1399 2 2 2 10 664 758 550
+1400 2 2 2 10 758 747 550
+1401 2 2 2 10 758 664 538
+1402 2 2 2 10 350 758 538
+1403 2 2 2 10 350 747 758
+1404 2 2 2 10 757 722 78
+1405 2 2 2 10 722 757 543
+1406 2 2 2 10 77 757 78
+1407 2 2 2 10 102 759 6
+1408 2 2 2 10 759 126 6
+1409 2 2 2 10 760 30 3
+1410 2 2 2 10 760 103 517
+1411 2 2 2 10 103 760 3
+1412 2 2 2 10 30 760 517
+1413 2 2 2 10 759 125 126
+1414 2 2 2 10 759 518 382
+1415 2 2 2 10 518 759 102
+1416 2 2 2 10 382 125 759
+$EndElements
diff --git a/test/test_model/test_non_local_toolbox/plate.geo b/test/test_model/test_non_local_toolbox/plate.geo
new file mode 100644
index 000000000..f83107ac4
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/plate.geo
@@ -0,0 +1,15 @@
+h = 0.5;
+length = 2;
+
+Point(1) = {-length/2, -length/2, 0, h};
+Point(2) = {0, -length/2, 0, h};
+line1[] = Extrude{length/2, 0, 0}{ Point{1}; };
+line2[] = Extrude{length/2, 0, 0}{ Point{2}; };
+surface1[] = Extrude{0, length, 0}{ Line{line1[1]}; };
+surface2[] = Extrude{0, length, 0}{ Line{line2[1]}; };
+
+Transfinite Surface "*";
+Recombine Surface "*";
+
+Physical Surface("mat_1") = {surface1[1]};
+Physical Surface("mat_2") = {surface2[1]};
diff --git a/test/test_model/test_non_local_toolbox/plate.msh b/test/test_model/test_non_local_toolbox/plate.msh
new file mode 100644
index 000000000..0f57d5bc0
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/plate.msh
@@ -0,0 +1,55 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$PhysicalNames
+2
+2 1 "mat_1"
+2 2 "mat_2"
+$EndPhysicalNames
+$Nodes
+25
+1 -1 -1 0
+2 0 -1 0
+3 1 -1 0
+4 -1 1 0
+5 0 1 0
+6 1 1 0
+7 -0.5000000000020591 -1 0
+8 0.499999999998694 -1 0
+9 -0.5000000000020591 1 0
+10 -1 -0.5000000000013871 0
+11 -1 -2.752797989558076e-12 0
+12 -1 0.4999999999986129 0
+13 0 -0.5000000000013871 0
+14 0 -2.752797989558076e-12 0
+15 0 0.4999999999986129 0
+16 0.499999999998694 1 0
+17 1 -0.5000000000013871 0
+18 1 -2.752797989558076e-12 0
+19 1 0.4999999999986129 0
+20 -0.5000000000020591 -0.5000000000013871 0
+21 -0.5000000000020591 -2.752909011860538e-12 0
+22 -0.5000000000020591 0.4999999999986129 0
+23 0.4999999999986941 -0.5000000000013871 0
+24 0.499999999998694 -2.752909011860538e-12 0
+25 0.4999999999986939 0.4999999999986131 0
+$EndNodes
+$Elements
+16
+1 3 2 1 6 1 7 20 10
+2 3 2 1 6 10 20 21 11
+3 3 2 1 6 11 21 22 12
+4 3 2 1 6 12 22 9 4
+5 3 2 1 6 7 2 13 20
+6 3 2 1 6 20 13 14 21
+7 3 2 1 6 21 14 15 22
+8 3 2 1 6 22 15 5 9
+9 3 2 2 10 2 8 23 13
+10 3 2 2 10 13 23 24 14
+11 3 2 2 10 14 24 25 15
+12 3 2 2 10 15 25 16 5
+13 3 2 2 10 8 3 17 23
+14 3 2 2 10 23 17 18 24
+15 3 2 2 10 24 18 19 25
+16 3 2 2 10 25 19 6 16
+$EndElements
diff --git a/test/test_model/test_non_local_toolbox/plot_neighborhoods.py b/test/test_model/test_non_local_toolbox/plot_neighborhoods.py
new file mode 100644
index 000000000..981d92c92
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/plot_neighborhoods.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python2.7
+
+from matplotlib import rc
+import matplotlib.pyplot as plt
+import matplotlib.ticker as ticker
+import numpy as np
+import sys
+from matplotlib.backends.backend_pdf import PdfPages
+
+#--------------------------------------------------------------------------------
+def readFile(filename):
+ quad_x_coords = list()
+ quad_y_coords = list()
+ with open(filename) as fh:
+ for line in fh:
+ if line.strip().startswith("#"):
+ nb_quads = 0
+ line = fh.next()
+ x, y = [float(s) for s in line[1:-3].split(", ")]
+ quad_x_coords.append(float(x))
+ quad_y_coords.append(float(y))
+ return quad_x_coords, quad_y_coords
+
+#--------------------------------------------------------------------------------
+def readNeighborhoods(filename):
+ neighborhoods = dict()
+ with open(filename) as fh:
+ first_line = fh.readline()
+ key = int(first_line[0:-1].split(" ")[-1])
+ current_list = list()
+
+ for line in fh:
+ if line.strip().startswith("#"):
+ neighborhoods[key] = current_list
+ key = int(line[0:-1].split(" ")[-1])
+ current_list = list()
+ else:
+ coord = [float(s) for s in line[1:-3].split(", ")]
+ current_list.append(coord)
+ neighborhoods[key] = current_list
+ return neighborhoods
+
+#--------------------------------------------------------------------------------
+def plotNeighborhood(quad_x_coords, quad_y_coords, neighborhood, r):
+
+ nb_quads = len(quad_x_coords)
+ ax = plt.subplot(111)
+ plt.axis([-1,1,-1,1])
+ # plot all quads
+ ax.plot(quad_x_coords,quad_y_coords,label='free',linestyle='None',marker="+",markeredgewidth = 0.2, markersize = 4)
+
+ # plot center of neighborhood and circle
+ x = neighborhood[0][0]
+ y = neighborhood[0][1]
+ ax.plot(x,y,label='free',marker="+",markeredgewidth = 0.2, markersize = 4, color='r')
+ circ=plt.Circle((x,y), radius=r, color='g', fill=False)
+ ax.add_patch(circ)
+ formatter = ticker.ScalarFormatter()
+ formatter.set_powerlimits((-2,2))
+ ax.xaxis.set_major_formatter(formatter)
+
+ # plot all the neighbors
+ for i in range(1,len(neighborhood)):
+ ax.plot(neighborhood[i][0],neighborhood[i][1],label='free',linestyle='None',marker="x",markeredgewidth = 0.2, markersize = 4, color ='y')
+
+ ax.grid(b=True, which='major', color='0.75', linestyle='-',linewidth=0.5)
+ ax.grid(b=True, which='minor', color='0.75', linestyle='-',linewidth=0.5)
+
+
+#--------------------------------------------------------------------------------
+def main():
+ non_local_radius = 0.5
+ rc('text', usetex=True)
+ rc('font', family='serif', size=8, serif='Times')
+
+ neighborhood_file = sys.argv[1]
+
+ quad_x_coords, quad_y_coords = readFile(neighborhood_file)
+ nb_quads = len(quad_x_coords)
+
+ neighborhoods = readNeighborhoods(neighborhood_file)
+
+
+ with PdfPages('resulting_neighborhoods.pdf') as pdf:
+ for i in range(nb_quads):
+ plt.figure(1, figsize=(7/2.54, 7/2.54))
+ plotNeighborhood(quad_x_coords, quad_y_coords, neighborhoods[i], non_local_radius)
+ pdf.savefig()
+ plt.close()
+
+if __name__ == "__main__":
+ main()
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
new file mode 100644
index 000000000..c36cda52e
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
@@ -0,0 +1,187 @@
+/**
+ * @file test_build_neighborhood_parallel.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Nov 25 2015
+ *
+ * @brief test in parallel for the class NonLocalNeighborhood
+ *
+ * @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.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_build_neighborhood_parallel.sh b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.sh
new file mode 100755
index 000000000..0ad73b9e9
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+mpirun -np 2 ./test_build_neighborhood_parallel
diff --git a/test/test_model/test_non_local_toolbox/test_material.cc b/test/test_model/test_non_local_toolbox/test_material.cc
new file mode 100644
index 000000000..df021a8a2
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_material.cc
@@ -0,0 +1,125 @@
+/**
+ * @file test_material.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100644
index 000000000..e6883d764
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_material.hh
@@ -0,0 +1,73 @@
+/**
+ * @file test_material.hh
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @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 (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "material_damage.hh"
+#include "material_non_local.hh"
+
+#ifndef __TEST_MATERIAL_HH__
+#define __TEST_MATERIAL_HH__
+
+__BEGIN_AKANTU__
+
+template <UInt dim>
+class TestMaterial : public MaterialDamage<dim, MaterialElastic>,
+ public MaterialNonLocal<dim> {
+ /* ------------------------------------------------------------------------ */
+ /* Constructor/Destructor */
+ /* ------------------------------------------------------------------------ */
+public:
+ TestMaterial(SolidMechanicsModel & model, const ID & id);
+ virtual ~TestMaterial(){};
+ typedef MaterialNonLocal<dim> MyNonLocalParent;
+ typedef MaterialDamage<dim, MaterialElastic> MyLocalParent;
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ void initMaterial();
+
+ void computeNonLocalStresses(__attribute__((unused)) GhostType ghost_type){};
+
+ void insertQuadsInNeighborhoods(GhostType ghost_type);
+
+ virtual void registerNeighborhood();
+
+ /* ------------------------------------------------------------------------ */
+ /* Members */
+ /* ------------------------------------------------------------------------ */
+private:
+ InternalField<Real> grad_u_nl;
+};
+
+__END_AKANTU__
+
+#endif /* __TEST_MATERIAL_HH__ */
diff --git a/test/test_model/test_non_local_toolbox/test_material_damage.cc b/test/test_model/test_non_local_toolbox/test_material_damage.cc
new file mode 100644
index 000000000..b61c974c8
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_material_damage.cc
@@ -0,0 +1,116 @@
+/**
+ * @file test_material_damage.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Thu Oct 15 2015
+ *
+ * @brief Implementation of test material damage
+ *
+ * @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 "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
new file mode 100644
index 000000000..01d51bdf3
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_material_damage.hh
@@ -0,0 +1,72 @@
+/**
+ * @file test_material_damage.hh
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @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 (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "material_damage.hh"
+#include "material_non_local.hh"
+
+#ifndef __TEST_MATERIAL_DAMAGE_HH__
+#define __TEST_MATERIAL_DAMAGE_HH__
+
+__BEGIN_AKANTU__
+
+template <UInt dim>
+class TestMaterialDamage : public MaterialDamage<dim, MaterialElastic>,
+ public MaterialNonLocal<dim> {
+ /* ------------------------------------------------------------------------ */
+ /* Constructor/Destructor */
+ /* ------------------------------------------------------------------------ */
+public:
+ TestMaterialDamage(SolidMechanicsModel & model, const ID & id);
+ virtual ~TestMaterialDamage(){};
+ typedef MaterialNonLocal<dim> MyNonLocalParent;
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ void initMaterial();
+
+ // void computeNonLocalStress(ElementType type, GhostType ghost_type =
+ // _not_ghost);
+
+ void computeNonLocalStresses(__attribute__((unused)) GhostType ghost_type){};
+ void insertQuadsInNeighborhoods(GhostType ghost_type);
+
+ /* ------------------------------------------------------------------------ */
+ /* Members */
+ /* ------------------------------------------------------------------------ */
+private:
+ InternalField<Real> grad_u_nl;
+};
+
+__END_AKANTU__
+
+#endif /* __TEST_MATERIAL_DAMAGE_HH__ */
diff --git a/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc b/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
new file mode 100644
index 000000000..34a420635
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
@@ -0,0 +1,112 @@
+/**
+ * @file test_non_local_averaging.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Oct 07 2015
+ *
+ * @brief test for non-local averaging of strain
+ *
+ * @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.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
new file mode 100644
index 000000000..ee7fba659
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_non_local_neighborhood_base.cc
@@ -0,0 +1,89 @@
+/**
+ * @file test_non_local_neighborhood_base.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Sat Sep 26 2015
+ * @date last modification: Wed Oct 07 2015
+ *
+ * @brief test for the class NonLocalNeighborhoodBase
+ *
+ * @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.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_non_local_neighborhood_base.verified b/test/test_model/test_non_local_toolbox/test_non_local_neighborhood_base.verified
new file mode 100644
index 000000000..6c7b2f118
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_non_local_neighborhood_base.verified
@@ -0,0 +1,966 @@
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 0(0)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 0(0)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 0(0)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 1(1)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 0(0)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 2(2)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 0(0)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 0(0)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 0(16)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 0(0)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 1(1)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 1(1)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 1(1)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 2(2)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 1(1)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 1(1)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 0(16)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 1(1)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 1(1)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 2(2)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 2(2)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 2(2)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 2(2)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 2(2)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 2(2)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 2(2)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 2(6)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)] IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 0(16)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)]
+IntegrationPoint [Element [_quadrangle_4, 0, not_ghost], 3(3)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 2(6)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 0(4)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 0(8)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 2(6)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 1(5)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 2(6)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 2(6)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 2(6)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 2(6)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 2(6)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 0(8)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 2(6)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)] IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 0(8)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)]
+IntegrationPoint [Element [_quadrangle_4, 1, not_ghost], 3(7)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 0(8)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 0(8)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 0(8)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 0(8)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 2(10)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 0(8)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 0(8)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 2(10)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 1(9)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 2(10)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 2(10)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 2(10)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 2(10)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 2(10)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 0(12)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 2(10)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)] IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 0(12)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)]
+IntegrationPoint [Element [_quadrangle_4, 2, not_ghost], 3(11)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 0(12)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 0(12)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 0(12)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 0(12)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 2(14)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 0(12)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 3(15)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 0(12)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 2(14)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 3(15)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 1(13)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 2(30)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 2(14)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 2(14)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 2(14)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 3(15)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 2(14)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 2(30)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 3(15)] IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 3(15)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 3(15)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)]
+IntegrationPoint [Element [_quadrangle_4, 3, not_ghost], 3(15)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 2(30)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 0(16)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 0(16)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 0(16)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 1(17)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 0(16)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 0(16)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 0(16)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 1(17)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 1(17)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 1(17)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 1(17)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 1(17)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 0(32)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 1(17)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 1(33)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 1(17)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 1(17)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 2(18)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)] IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 0(32)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)]
+IntegrationPoint [Element [_quadrangle_4, 4, not_ghost], 3(19)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 0(20)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 1(21)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 2(22)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)] IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)]
+IntegrationPoint [Element [_quadrangle_4, 5, not_ghost], 3(23)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 0(24)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 1(25)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 2(26)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)] IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)]
+IntegrationPoint [Element [_quadrangle_4, 6, not_ghost], 3(27)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 2(30)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 0(28)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 3(31)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 2(30)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 3(31)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 1(29)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 2(46)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 2(30)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 2(30)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 2(30)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 3(31)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 3(31)] IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 3(31)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 3(31)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 3(31)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 2(46)]
+IntegrationPoint [Element [_quadrangle_4, 7, not_ghost], 3(31)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 3(47)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 0(32)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 0(32)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 0(32)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 1(33)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 0(32)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 0(32)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 0(32)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 0(48)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 0(32)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 1(33)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 1(33)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 1(33)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 1(33)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 1(33)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 0(48)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 1(33)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 1(33)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 2(34)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)] IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 0(48)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)]
+IntegrationPoint [Element [_quadrangle_4, 8, not_ghost], 3(35)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 0(36)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 1(37)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 2(38)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)] IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)]
+IntegrationPoint [Element [_quadrangle_4, 9, not_ghost], 3(39)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 0(40)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 1(41)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 2(42)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)] IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)]
+IntegrationPoint [Element [_quadrangle_4, 10, not_ghost], 3(43)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 2(46)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 3(47)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 0(44)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 2(46)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 3(47)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 1(45)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 2(62)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 2(46)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 2(46)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 2(46)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 3(47)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 2(46)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 2(62)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 3(47)] IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 3(47)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 3(47)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)]
+IntegrationPoint [Element [_quadrangle_4, 11, not_ghost], 3(47)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 2(62)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 0(48)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 0(48)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 0(48)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 1(49)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 0(48)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 0(48)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 3(51)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 0(48)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 1(49)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 1(49)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 1(49)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 1(49)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 3(51)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 1(49)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 1(53)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 3(51)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 1(53)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 2(50)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 3(51)] IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 3(51)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 3(51)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 3(51)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 1(53)]
+IntegrationPoint [Element [_quadrangle_4, 12, not_ghost], 3(51)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 3(55)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 1(53)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 3(55)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 0(52)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 1(53)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 1(53)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 1(53)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 1(53)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 3(55)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 1(53)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 1(57)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 3(55)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 2(54)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 1(57)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 3(55)] IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 3(55)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 3(55)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)]
+IntegrationPoint [Element [_quadrangle_4, 13, not_ghost], 3(55)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 1(57)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 1(57)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 0(56)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 3(59)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 1(57)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 1(57)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 1(57)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 1(57)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 3(59)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 3(59)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 2(58)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 1(61)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 3(59)] IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 3(59)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 3(59)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)]
+IntegrationPoint [Element [_quadrangle_4, 14, not_ghost], 3(59)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 1(61)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 1(61)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 2(62)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 0(60)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 3(63)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 1(61)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 1(61)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 1(61)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 2(62)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 1(61)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 3(63)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 2(62)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 2(62)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 2(62)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 3(63)]
+IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 3(63)] IntegrationPoint [Element [_quadrangle_4, 15, not_ghost], 3(63)]
+#neighbors for quad 0
+[-0.894338, -0.894338]
+[-0.605662, -0.894338]
+[-0.894338, -0.605662]
+[-0.605662, -0.605662]
+[-0.394338, -0.894338]
+[-0.894338, -0.394338]
+#neighbors for quad 1
+[-0.605662, -0.894338]
+[-0.894338, -0.894338]
+[-0.894338, -0.605662]
+[-0.605662, -0.605662]
+[-0.394338, -0.894338]
+[-0.394338, -0.605662]
+[-0.605662, -0.394338]
+#neighbors for quad 2
+[-0.894338, -0.605662]
+[-0.894338, -0.894338]
+[-0.605662, -0.894338]
+[-0.605662, -0.605662]
+[-0.394338, -0.605662]
+[-0.894338, -0.394338]
+[-0.605662, -0.394338]
+[-0.894338, -0.105662]
+#neighbors for quad 3
+[-0.605662, -0.605662]
+[-0.894338, -0.894338]
+[-0.605662, -0.894338]
+[-0.894338, -0.605662]
+[-0.394338, -0.894338]
+[-0.394338, -0.605662]
+[-0.894338, -0.394338]
+[-0.605662, -0.394338]
+[-0.605662, -0.105662]
+[-0.394338, -0.394338]
+#neighbors for quad 4
+[-0.894338, -0.394338]
+[-0.894338, -0.894338]
+[-0.894338, -0.605662]
+[-0.605662, -0.605662]
+[-0.605662, -0.394338]
+[-0.894338, -0.105662]
+[-0.605662, -0.105662]
+[-0.394338, -0.394338]
+[-0.894338, 0.105662]
+#neighbors for quad 5
+[-0.605662, -0.394338]
+[-0.605662, -0.894338]
+[-0.894338, -0.605662]
+[-0.605662, -0.605662]
+[-0.894338, -0.394338]
+[-0.394338, -0.605662]
+[-0.894338, -0.105662]
+[-0.605662, -0.105662]
+[-0.394338, -0.394338]
+[-0.394338, -0.105662]
+[-0.605662, 0.105662]
+#neighbors for quad 6
+[-0.894338, -0.105662]
+[-0.894338, -0.605662]
+[-0.894338, -0.394338]
+[-0.605662, -0.394338]
+[-0.605662, -0.105662]
+[-0.394338, -0.105662]
+[-0.894338, 0.105662]
+[-0.605662, 0.105662]
+#neighbors for quad 7
+[-0.605662, -0.105662]
+[-0.605662, -0.605662]
+[-0.894338, -0.394338]
+[-0.605662, -0.394338]
+[-0.894338, -0.105662]
+[-0.394338, -0.394338]
+[-0.394338, -0.105662]
+[-0.894338, 0.105662]
+[-0.605662, 0.105662]
+[-0.394338, 0.105662]
+#neighbors for quad 8
+[-0.894338, 0.105662]
+[-0.894338, -0.394338]
+[-0.894338, -0.105662]
+[-0.605662, -0.105662]
+[-0.605662, 0.105662]
+[-0.894338, 0.394338]
+[-0.605662, 0.394338]
+[-0.394338, 0.105662]
+#neighbors for quad 9
+[-0.605662, 0.105662]
+[-0.605662, -0.394338]
+[-0.894338, -0.105662]
+[-0.605662, -0.105662]
+[-0.894338, 0.105662]
+[-0.394338, -0.105662]
+[-0.894338, 0.394338]
+[-0.605662, 0.394338]
+[-0.394338, 0.105662]
+[-0.394338, 0.394338]
+#neighbors for quad 10
+[-0.894338, 0.394338]
+[-0.894338, 0.105662]
+[-0.605662, 0.105662]
+[-0.605662, 0.394338]
+[-0.394338, 0.394338]
+[-0.894338, 0.605662]
+[-0.605662, 0.605662]
+#neighbors for quad 11
+[-0.605662, 0.394338]
+[-0.894338, 0.105662]
+[-0.605662, 0.105662]
+[-0.894338, 0.394338]
+[-0.394338, 0.105662]
+[-0.394338, 0.394338]
+[-0.894338, 0.605662]
+[-0.605662, 0.605662]
+[-0.394338, 0.605662]
+#neighbors for quad 12
+[-0.894338, 0.605662]
+[-0.894338, 0.394338]
+[-0.605662, 0.394338]
+[-0.605662, 0.605662]
+[-0.894338, 0.894338]
+[-0.605662, 0.894338]
+[-0.394338, 0.605662]
+#neighbors for quad 13
+[-0.605662, 0.605662]
+[-0.894338, 0.394338]
+[-0.605662, 0.394338]
+[-0.894338, 0.605662]
+[-0.394338, 0.394338]
+[-0.894338, 0.894338]
+[-0.605662, 0.894338]
+[-0.394338, 0.605662]
+[-0.394338, 0.894338]
+#neighbors for quad 14
+[-0.894338, 0.894338]
+[-0.894338, 0.605662]
+[-0.605662, 0.605662]
+[-0.605662, 0.894338]
+[-0.394338, 0.894338]
+#neighbors for quad 15
+[-0.605662, 0.894338]
+[-0.894338, 0.605662]
+[-0.605662, 0.605662]
+[-0.894338, 0.894338]
+[-0.394338, 0.605662]
+[-0.394338, 0.894338]
+#neighbors for quad 16
+[-0.394338, -0.894338]
+[-0.894338, -0.894338]
+[-0.605662, -0.894338]
+[-0.605662, -0.605662]
+[-0.105662, -0.894338]
+[-0.394338, -0.605662]
+[-0.105662, -0.605662]
+[-0.394338, -0.394338]
+#neighbors for quad 17
+[-0.105662, -0.894338]
+[-0.394338, -0.894338]
+[-0.394338, -0.605662]
+[-0.105662, -0.605662]
+[0.105662, -0.894338]
+[0.394338, -0.894338]
+[0.105662, -0.605662]
+[-0.105662, -0.394338]
+#neighbors for quad 18
+[-0.394338, -0.605662]
+[-0.605662, -0.894338]
+[-0.894338, -0.605662]
+[-0.605662, -0.605662]
+[-0.605662, -0.394338]
+[-0.394338, -0.894338]
+[-0.105662, -0.894338]
+[-0.105662, -0.605662]
+[-0.394338, -0.394338]
+[-0.105662, -0.394338]
+[-0.394338, -0.105662]
+#neighbors for quad 19
+[-0.105662, -0.605662]
+[-0.394338, -0.894338]
+[-0.105662, -0.894338]
+[-0.394338, -0.605662]
+[0.105662, -0.894338]
+[0.105662, -0.605662]
+[0.394338, -0.605662]
+[-0.394338, -0.394338]
+[-0.105662, -0.394338]
+[-0.105662, -0.105662]
+[0.105662, -0.394338]
+#neighbors for quad 20
+[-0.394338, -0.394338]
+[-0.605662, -0.605662]
+[-0.894338, -0.394338]
+[-0.605662, -0.394338]
+[-0.605662, -0.105662]
+[-0.394338, -0.894338]
+[-0.394338, -0.605662]
+[-0.105662, -0.605662]
+[-0.105662, -0.394338]
+[-0.394338, -0.105662]
+[-0.105662, -0.105662]
+[-0.394338, 0.105662]
+#neighbors for quad 21
+[-0.105662, -0.394338]
+[-0.105662, -0.894338]
+[-0.394338, -0.605662]
+[-0.105662, -0.605662]
+[-0.394338, -0.394338]
+[0.105662, -0.605662]
+[-0.394338, -0.105662]
+[-0.105662, -0.105662]
+[0.105662, -0.394338]
+[0.394338, -0.394338]
+[0.105662, -0.105662]
+[-0.105662, 0.105662]
+#neighbors for quad 22
+[-0.394338, -0.105662]
+[-0.605662, -0.394338]
+[-0.894338, -0.105662]
+[-0.605662, -0.105662]
+[-0.605662, 0.105662]
+[-0.394338, -0.605662]
+[-0.394338, -0.394338]
+[-0.105662, -0.394338]
+[-0.105662, -0.105662]
+[-0.394338, 0.105662]
+[-0.105662, 0.105662]
+#neighbors for quad 23
+[-0.105662, -0.105662]
+[-0.105662, -0.605662]
+[-0.394338, -0.394338]
+[-0.105662, -0.394338]
+[-0.394338, -0.105662]
+[0.105662, -0.394338]
+[0.105662, -0.105662]
+[0.394338, -0.105662]
+[-0.394338, 0.105662]
+[-0.105662, 0.105662]
+[0.105662, 0.105662]
+#neighbors for quad 24
+[-0.394338, 0.105662]
+[-0.605662, -0.105662]
+[-0.894338, 0.105662]
+[-0.605662, 0.105662]
+[-0.605662, 0.394338]
+[-0.394338, -0.394338]
+[-0.394338, -0.105662]
+[-0.105662, -0.105662]
+[-0.105662, 0.105662]
+[-0.394338, 0.394338]
+[-0.105662, 0.394338]
+#neighbors for quad 25
+[-0.105662, 0.105662]
+[-0.105662, -0.394338]
+[-0.394338, -0.105662]
+[-0.105662, -0.105662]
+[-0.394338, 0.105662]
+[0.105662, -0.105662]
+[-0.394338, 0.394338]
+[-0.105662, 0.394338]
+[0.105662, 0.105662]
+[0.394338, 0.105662]
+[0.105662, 0.394338]
+#neighbors for quad 26
+[-0.394338, 0.394338]
+[-0.605662, 0.105662]
+[-0.894338, 0.394338]
+[-0.605662, 0.394338]
+[-0.605662, 0.605662]
+[-0.394338, 0.105662]
+[-0.105662, 0.105662]
+[-0.105662, 0.394338]
+[-0.394338, 0.605662]
+[-0.105662, 0.605662]
+#neighbors for quad 27
+[-0.105662, 0.394338]
+[-0.394338, 0.105662]
+[-0.105662, 0.105662]
+[-0.394338, 0.394338]
+[0.105662, 0.105662]
+[0.105662, 0.394338]
+[0.394338, 0.394338]
+[-0.394338, 0.605662]
+[-0.105662, 0.605662]
+[0.105662, 0.605662]
+#neighbors for quad 28
+[-0.394338, 0.605662]
+[-0.605662, 0.394338]
+[-0.894338, 0.605662]
+[-0.605662, 0.605662]
+[-0.605662, 0.894338]
+[-0.394338, 0.394338]
+[-0.105662, 0.394338]
+[-0.105662, 0.605662]
+[-0.394338, 0.894338]
+[-0.105662, 0.894338]
+#neighbors for quad 29
+[-0.105662, 0.605662]
+[-0.394338, 0.394338]
+[-0.105662, 0.394338]
+[-0.394338, 0.605662]
+[0.105662, 0.394338]
+[-0.394338, 0.894338]
+[-0.105662, 0.894338]
+[0.105662, 0.605662]
+[0.394338, 0.605662]
+[0.105662, 0.894338]
+#neighbors for quad 30
+[-0.394338, 0.894338]
+[-0.605662, 0.605662]
+[-0.894338, 0.894338]
+[-0.605662, 0.894338]
+[-0.394338, 0.605662]
+[-0.105662, 0.605662]
+[-0.105662, 0.894338]
+#neighbors for quad 31
+[-0.105662, 0.894338]
+[-0.394338, 0.605662]
+[-0.105662, 0.605662]
+[-0.394338, 0.894338]
+[0.105662, 0.605662]
+[0.105662, 0.894338]
+[0.394338, 0.894338]
+#neighbors for quad 32
+[0.105662, -0.894338]
+[-0.105662, -0.894338]
+[-0.105662, -0.605662]
+[0.394338, -0.894338]
+[0.105662, -0.605662]
+[0.394338, -0.605662]
+[0.605662, -0.894338]
+[0.105662, -0.394338]
+#neighbors for quad 33
+[0.394338, -0.894338]
+[-0.105662, -0.894338]
+[0.105662, -0.894338]
+[0.105662, -0.605662]
+[0.394338, -0.605662]
+[0.605662, -0.894338]
+[0.605662, -0.605662]
+[0.394338, -0.394338]
+#neighbors for quad 34
+[0.105662, -0.605662]
+[-0.105662, -0.894338]
+[-0.105662, -0.605662]
+[-0.105662, -0.394338]
+[0.105662, -0.894338]
+[0.394338, -0.894338]
+[0.394338, -0.605662]
+[0.605662, -0.605662]
+[0.105662, -0.394338]
+[0.394338, -0.394338]
+[0.105662, -0.105662]
+#neighbors for quad 35
+[0.394338, -0.605662]
+[-0.105662, -0.605662]
+[0.105662, -0.894338]
+[0.394338, -0.894338]
+[0.105662, -0.605662]
+[0.605662, -0.894338]
+[0.605662, -0.605662]
+[0.105662, -0.394338]
+[0.394338, -0.394338]
+[0.394338, -0.105662]
+[0.605662, -0.394338]
+#neighbors for quad 36
+[0.105662, -0.394338]
+[-0.105662, -0.605662]
+[-0.105662, -0.394338]
+[-0.105662, -0.105662]
+[0.105662, -0.894338]
+[0.105662, -0.605662]
+[0.394338, -0.605662]
+[0.394338, -0.394338]
+[0.105662, -0.105662]
+[0.394338, -0.105662]
+[0.605662, -0.394338]
+[0.105662, 0.105662]
+#neighbors for quad 37
+[0.394338, -0.394338]
+[-0.105662, -0.394338]
+[0.394338, -0.894338]
+[0.105662, -0.605662]
+[0.394338, -0.605662]
+[0.105662, -0.394338]
+[0.605662, -0.605662]
+[0.105662, -0.105662]
+[0.394338, -0.105662]
+[0.605662, -0.394338]
+[0.605662, -0.105662]
+[0.394338, 0.105662]
+#neighbors for quad 38
+[0.105662, -0.105662]
+[-0.105662, -0.394338]
+[-0.105662, -0.105662]
+[-0.105662, 0.105662]
+[0.105662, -0.605662]
+[0.105662, -0.394338]
+[0.394338, -0.394338]
+[0.394338, -0.105662]
+[0.605662, -0.105662]
+[0.105662, 0.105662]
+[0.394338, 0.105662]
+#neighbors for quad 39
+[0.394338, -0.105662]
+[-0.105662, -0.105662]
+[0.394338, -0.605662]
+[0.105662, -0.394338]
+[0.394338, -0.394338]
+[0.105662, -0.105662]
+[0.605662, -0.394338]
+[0.605662, -0.105662]
+[0.105662, 0.105662]
+[0.394338, 0.105662]
+[0.605662, 0.105662]
+#neighbors for quad 40
+[0.105662, 0.105662]
+[-0.105662, -0.105662]
+[-0.105662, 0.105662]
+[-0.105662, 0.394338]
+[0.105662, -0.394338]
+[0.105662, -0.105662]
+[0.394338, -0.105662]
+[0.394338, 0.105662]
+[0.105662, 0.394338]
+[0.394338, 0.394338]
+[0.605662, 0.105662]
+#neighbors for quad 41
+[0.394338, 0.105662]
+[-0.105662, 0.105662]
+[0.394338, -0.394338]
+[0.105662, -0.105662]
+[0.394338, -0.105662]
+[0.105662, 0.105662]
+[0.605662, -0.105662]
+[0.105662, 0.394338]
+[0.394338, 0.394338]
+[0.605662, 0.105662]
+[0.605662, 0.394338]
+#neighbors for quad 42
+[0.105662, 0.394338]
+[-0.105662, 0.105662]
+[-0.105662, 0.394338]
+[-0.105662, 0.605662]
+[0.105662, 0.105662]
+[0.394338, 0.105662]
+[0.394338, 0.394338]
+[0.605662, 0.394338]
+[0.105662, 0.605662]
+[0.394338, 0.605662]
+#neighbors for quad 43
+[0.394338, 0.394338]
+[-0.105662, 0.394338]
+[0.105662, 0.105662]
+[0.394338, 0.105662]
+[0.105662, 0.394338]
+[0.605662, 0.105662]
+[0.605662, 0.394338]
+[0.105662, 0.605662]
+[0.394338, 0.605662]
+[0.605662, 0.605662]
+#neighbors for quad 44
+[0.105662, 0.605662]
+[-0.105662, 0.394338]
+[-0.105662, 0.605662]
+[-0.105662, 0.894338]
+[0.105662, 0.394338]
+[0.394338, 0.394338]
+[0.394338, 0.605662]
+[0.105662, 0.894338]
+[0.394338, 0.894338]
+[0.605662, 0.605662]
+#neighbors for quad 45
+[0.394338, 0.605662]
+[-0.105662, 0.605662]
+[0.105662, 0.394338]
+[0.394338, 0.394338]
+[0.105662, 0.605662]
+[0.605662, 0.394338]
+[0.105662, 0.894338]
+[0.394338, 0.894338]
+[0.605662, 0.605662]
+[0.605662, 0.894338]
+#neighbors for quad 46
+[0.105662, 0.894338]
+[-0.105662, 0.605662]
+[-0.105662, 0.894338]
+[0.105662, 0.605662]
+[0.394338, 0.605662]
+[0.394338, 0.894338]
+[0.605662, 0.894338]
+#neighbors for quad 47
+[0.394338, 0.894338]
+[-0.105662, 0.894338]
+[0.105662, 0.605662]
+[0.394338, 0.605662]
+[0.105662, 0.894338]
+[0.605662, 0.605662]
+[0.605662, 0.894338]
+#neighbors for quad 48
+[0.605662, -0.894338]
+[0.105662, -0.894338]
+[0.394338, -0.894338]
+[0.394338, -0.605662]
+[0.894338, -0.894338]
+[0.605662, -0.605662]
+[0.894338, -0.605662]
+[0.605662, -0.394338]
+#neighbors for quad 49
+[0.894338, -0.894338]
+[0.605662, -0.894338]
+[0.605662, -0.605662]
+[0.894338, -0.605662]
+[0.894338, -0.394338]
+#neighbors for quad 50
+[0.605662, -0.605662]
+[0.394338, -0.894338]
+[0.105662, -0.605662]
+[0.394338, -0.605662]
+[0.394338, -0.394338]
+[0.605662, -0.894338]
+[0.894338, -0.894338]
+[0.894338, -0.605662]
+[0.605662, -0.394338]
+[0.894338, -0.394338]
+[0.605662, -0.105662]
+#neighbors for quad 51
+[0.894338, -0.605662]
+[0.605662, -0.894338]
+[0.894338, -0.894338]
+[0.605662, -0.605662]
+[0.605662, -0.394338]
+[0.894338, -0.394338]
+[0.894338, -0.105662]
+#neighbors for quad 52
+[0.605662, -0.394338]
+[0.394338, -0.605662]
+[0.105662, -0.394338]
+[0.394338, -0.394338]
+[0.394338, -0.105662]
+[0.605662, -0.894338]
+[0.605662, -0.605662]
+[0.894338, -0.605662]
+[0.894338, -0.394338]
+[0.605662, -0.105662]
+[0.894338, -0.105662]
+[0.605662, 0.105662]
+#neighbors for quad 53
+[0.894338, -0.394338]
+[0.894338, -0.894338]
+[0.605662, -0.605662]
+[0.894338, -0.605662]
+[0.605662, -0.394338]
+[0.605662, -0.105662]
+[0.894338, -0.105662]
+[0.894338, 0.105662]
+#neighbors for quad 54
+[0.605662, -0.105662]
+[0.394338, -0.394338]
+[0.105662, -0.105662]
+[0.394338, -0.105662]
+[0.394338, 0.105662]
+[0.605662, -0.605662]
+[0.605662, -0.394338]
+[0.894338, -0.394338]
+[0.894338, -0.105662]
+[0.605662, 0.105662]
+[0.894338, 0.105662]
+#neighbors for quad 55
+[0.894338, -0.105662]
+[0.894338, -0.605662]
+[0.605662, -0.394338]
+[0.894338, -0.394338]
+[0.605662, -0.105662]
+[0.605662, 0.105662]
+[0.894338, 0.105662]
+#neighbors for quad 56
+[0.605662, 0.105662]
+[0.394338, -0.105662]
+[0.105662, 0.105662]
+[0.394338, 0.105662]
+[0.394338, 0.394338]
+[0.605662, -0.394338]
+[0.605662, -0.105662]
+[0.894338, -0.105662]
+[0.894338, 0.105662]
+[0.605662, 0.394338]
+[0.894338, 0.394338]
+#neighbors for quad 57
+[0.894338, 0.105662]
+[0.894338, -0.394338]
+[0.605662, -0.105662]
+[0.894338, -0.105662]
+[0.605662, 0.105662]
+[0.605662, 0.394338]
+[0.894338, 0.394338]
+#neighbors for quad 58
+[0.605662, 0.394338]
+[0.394338, 0.105662]
+[0.105662, 0.394338]
+[0.394338, 0.394338]
+[0.394338, 0.605662]
+[0.605662, 0.105662]
+[0.894338, 0.105662]
+[0.894338, 0.394338]
+[0.605662, 0.605662]
+[0.894338, 0.605662]
+#neighbors for quad 59
+[0.894338, 0.394338]
+[0.605662, 0.105662]
+[0.894338, 0.105662]
+[0.605662, 0.394338]
+[0.605662, 0.605662]
+[0.894338, 0.605662]
+#neighbors for quad 60
+[0.605662, 0.605662]
+[0.394338, 0.394338]
+[0.105662, 0.605662]
+[0.394338, 0.605662]
+[0.394338, 0.894338]
+[0.605662, 0.394338]
+[0.894338, 0.394338]
+[0.894338, 0.605662]
+[0.605662, 0.894338]
+[0.894338, 0.894338]
+#neighbors for quad 61
+[0.894338, 0.605662]
+[0.605662, 0.394338]
+[0.894338, 0.394338]
+[0.605662, 0.605662]
+[0.605662, 0.894338]
+[0.894338, 0.894338]
+#neighbors for quad 62
+[0.605662, 0.894338]
+[0.394338, 0.605662]
+[0.105662, 0.894338]
+[0.394338, 0.894338]
+[0.605662, 0.605662]
+[0.894338, 0.605662]
+[0.894338, 0.894338]
+#neighbors for quad 63
+[0.894338, 0.894338]
+[0.605662, 0.605662]
+[0.894338, 0.605662]
+[0.605662, 0.894338]
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
new file mode 100644
index 000000000..72b7b04b9
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
@@ -0,0 +1,218 @@
+/**
+ * @file test_pair_computation.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Wed Nov 25 2015
+ *
+ * @brief test the weight computation with and without grid
+ *
+ * @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;
+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_pair_computation.sh b/test/test_model/test_non_local_toolbox/test_pair_computation.sh
new file mode 100755
index 000000000..689d8f180
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_pair_computation.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+./test_pair_computation
+
diff --git a/test/test_model/test_non_local_toolbox/test_pair_computation_parallel.sh b/test/test_model/test_non_local_toolbox/test_pair_computation_parallel.sh
new file mode 100755
index 000000000..7210fac46
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_pair_computation_parallel.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+mpirun -np 4 ./test_pair_computation
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
new file mode 100644
index 000000000..c033a2934
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc
@@ -0,0 +1,181 @@
+/**
+ * @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_remove_damage_weight_function.verified b/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.verified
new file mode 100644
index 000000000..41c36e09e
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.verified
@@ -0,0 +1,584 @@
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.152582
+w1: 0.222222 w2: 0.152582
+w1: 0.0555556 w2: 0.0262132
+w1: 1.13075e-23 w2: 7.76397e-24
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0381455
+w1: 0.152582 w2: 0.104853
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.03141e-23 w2: 1.03141e-23
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 7.08718e-24 w2: 7.08718e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.152582
+w1: 0.0381455 w2: 0.0262132
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 2.34707e-24 w2: 2.34707e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.152582
+w1: 0.0381455 w2: 0.0262132
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.222222
+w1: 0.0381455 w2: 0.0381455
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0555556
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.152582
+w1: 1.13075e-23 w2: 7.76397e-24
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.222222
+w1: 0.152582 w2: 0.104853
+w1: 0.0381455 w2: 0.0381455
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.5 w2: 0
+w1: 0.0555556 w2: 0.0262132
+w1: 0.222222 w2: 0.152582
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 7.08833e-24 w2: 7.08833e-24
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 1.03125e-23 w2: 1.03125e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0381455
+w1: 2.34707e-24 w2: 2.34707e-24
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.152582
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0381455
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.152582
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.152582
+w1: 0.0262132 w2: 0.0555556
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0381455
+w1: 0.152582 w2: 0.222222
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.222222
+w1: 0.5 w2: 0
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.152582
+w1: 0.222222 w2: 0.152582
+w1: 0.0555556 w2: 0.0262132
+w1: 4.54889e-24 w2: 3.12336e-24
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0381455
+w1: 0.152582 w2: 0.104853
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 3.12336e-24 w2: 2.14634e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.03141e-23 w2: 1.03141e-23
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 7.08718e-24 w2: 7.08718e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.152582
+w1: 0.0381455 w2: 0.0262132
+w1: 3.12336e-24 w2: 2.14634e-24
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 2.34673e-24 w2: 2.34673e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 3.12336e-24 w2: 2.14634e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.152582
+w1: 0.0381455 w2: 0.0262132
+w1: 3.12336e-24 w2: 2.14634e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 3.12382e-24 w2: 2.14665e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.222222
+w1: 0.0381455 w2: 0.0381455
+w1: 3.12382e-24 w2: 2.14665e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0555556
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.152582
+w1: 4.55023e-24 w2: 3.12428e-24
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.222222
+w1: 0.152582 w2: 0.104853
+w1: 0.0381455 w2: 0.0381455
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.5 w2: 0
+w1: 0.0555556 w2: 0.0262132
+w1: 0.222222 w2: 0.152582
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 7.08833e-24 w2: 7.08833e-24
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 1.03125e-23 w2: 1.03125e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0381455
+w1: 2.34673e-24 w2: 2.34673e-24
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.152582
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0381455
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.152582
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.152582
+w1: 0.0262132 w2: 0.0555556
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0381455
+w1: 0.152582 w2: 0.222222
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.222222
+w1: 0.5 w2: 0
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.152582
+w1: 0.222222 w2: 0.152582
+w1: 0.0555556 w2: 0.0262132
+w1: 1.13075e-23 w2: 7.76397e-24
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0381455
+w1: 0.152582 w2: 0.104853
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.03141e-23 w2: 1.03141e-23
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 7.08718e-24 w2: 7.08718e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.152582
+w1: 0.0381455 w2: 0.0262132
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 2.34707e-24 w2: 2.34707e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.222222
+w1: 0.0381455 w2: 0.0334075
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0555556
+w1: 0.104853 w2: 0.13363
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0622581
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.13363
+w1: 1.13075e-23 w2: 5.91144e-24
+w1: 0 w2: 0.352696
+w1: 0 w2: 0.0735398
+w1: 0.300668 w2: 0
+w1: 0.0716122 w2: 0.0561904
+w1: 0.202844 w2: 0.176348
+w1: 0 w2: 0.124516
+w1: 0 w2: 0.208304
+w1: 0.124208 w2: 0.124208
+w1: 0.522788 w2: 0
+w1: 0 w2: 0
+w1: 0 w2: 0
+w1: 0 w2: 0
+w1: 1.18229e-23 w2: 0
+w1: 0.127552 w2: 0
+w1: 0.308761 w2: 0
+w1: 0 w2: 0
+w1: 0 w2: 0
+w1: 0.208304 w2: 0
+w1: 0.0735398 w2: 0
+w1: 1 w2: 0
+w1: 0 w2: 0
+w1: 2.26151e-23 w2: 0
+w1: 0.522788 w2: 0
+w1: 0.124516 w2: 0
+w1: 0.352696 w2: 0
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.222222
+w1: 0.152582 w2: 0.104853
+w1: 0.0381455 w2: 0.0381455
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.5 w2: 0
+w1: 0.0555556 w2: 0.0262132
+w1: 0.222222 w2: 0.152582
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 7.08833e-24 w2: 7.08833e-24
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 1.03125e-23 w2: 1.03125e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0381455
+w1: 2.34707e-24 w2: 2.34707e-24
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.152582
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.116175
+w1: 0.0262132 w2: 0.0381455
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0290438
+w1: 0.152582 w2: 0.152582
+w1: 0.261394 w2: 0
+w1: 0.116175 w2: 0.152582
+w1: 0.176348 w2: 0.202844
+w1: 0.0622581 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0716122
+w1: 0.231612 w2: 0.231612
+w1: 0.300668 w2: 0
+w1: 0.13363 w2: 0.152582
+w1: 0.13363 w2: 0.222222
+w1: 0.0334075 w2: 0.0555556
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0555556
+w1: 0.152582 w2: 0.222222
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.222222
+w1: 0.5 w2: 0
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.152582
+w1: 0.222222 w2: 0.152582
+w1: 0.0555556 w2: 0.0262132
+w1: 4.54889e-24 w2: 3.12336e-24
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0381455
+w1: 0.152582 w2: 0.104853
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 3.12336e-24 w2: 2.14634e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.03141e-23 w2: 1.03141e-23
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 7.08718e-24 w2: 7.08718e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.152582
+w1: 0.0381455 w2: 0.0262132
+w1: 3.12336e-24 w2: 2.14634e-24
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 2.34673e-24 w2: 2.34673e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 3.12336e-24 w2: 2.14634e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.222222
+w1: 0.0381455 w2: 0.0334075
+w1: 3.12336e-24 w2: 2.14634e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0555556
+w1: 0.104853 w2: 0.13363
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0622581
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.13363
+w1: 4.54956e-24 w2: 2.37846e-24
+w1: 0 w2: 0.352696
+w1: 0 w2: 0.0735398
+w1: 0.300668 w2: 0
+w1: 0.0716122 w2: 0.0561904
+w1: 0.202844 w2: 0.176348
+w1: 0 w2: 0.124516
+w1: 0 w2: 0.208304
+w1: 0.124208 w2: 0.124208
+w1: 0.522788 w2: 0
+w1: 0 w2: 0
+w1: 0 w2: 0
+w1: 0 w2: 0
+w1: 4.75691e-24 w2: 0
+w1: 0.127552 w2: 0
+w1: 0.308761 w2: 0
+w1: 0 w2: 0
+w1: 0 w2: 0
+w1: 0.208304 w2: 0
+w1: 0.0735398 w2: 0
+w1: 1 w2: 0
+w1: 0 w2: 0
+w1: 9.10047e-24 w2: 0
+w1: 0.522788 w2: 0
+w1: 0.124516 w2: 0
+w1: 0.352696 w2: 0
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.222222
+w1: 0.152582 w2: 0.104853
+w1: 0.0381455 w2: 0.0381455
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.5 w2: 0
+w1: 0.0555556 w2: 0.0262132
+w1: 0.222222 w2: 0.152582
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 7.08833e-24 w2: 7.08833e-24
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 1.03125e-23 w2: 1.03125e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0381455
+w1: 2.34673e-24 w2: 2.34673e-24
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.152582
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.116175
+w1: 0.0262132 w2: 0.0381455
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0290438
+w1: 0.152582 w2: 0.152582
+w1: 0.261394 w2: 0
+w1: 0.116175 w2: 0.152582
+w1: 0.176348 w2: 0.202844
+w1: 0.0622581 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0716122
+w1: 0.231612 w2: 0.231612
+w1: 0.300668 w2: 0
+w1: 0.13363 w2: 0.152582
+w1: 0.13363 w2: 0.222222
+w1: 0.0334075 w2: 0.0555556
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0555556
+w1: 0.152582 w2: 0.222222
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.222222
+w1: 0.5 w2: 0
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
new file mode 100644
index 000000000..4df5771b2
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_weight_computation.cc
@@ -0,0 +1,75 @@
+/**
+ * @file test_weight_computation.cc
+ *
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_non_local_toolbox/test_weight_computation.verified b/test/test_model/test_non_local_toolbox/test_weight_computation.verified
new file mode 100644
index 000000000..f908441a3
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_weight_computation.verified
@@ -0,0 +1,322 @@
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.152582
+w1: 0.222222 w2: 0.152582
+w1: 0.0555556 w2: 0.0262132
+w1: 1.13075e-23 w2: 7.76397e-24
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0381455
+w1: 0.152582 w2: 0.104853
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.03141e-23 w2: 1.03141e-23
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 7.08718e-24 w2: 7.08718e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.152582
+w1: 0.0381455 w2: 0.0262132
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 2.34707e-24 w2: 2.34707e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.152582
+w1: 0.0381455 w2: 0.0262132
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.104853
+w1: 0.152582 w2: 0.222222
+w1: 0.0381455 w2: 0.0381455
+w1: 7.76397e-24 w2: 5.33531e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0555556
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.5 w2: 0
+w1: 0.222222 w2: 0.152582
+w1: 1.13075e-23 w2: 7.76397e-24
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.152582
+w1: 0.152582 w2: 0.104853
+w1: 0.0381455 w2: 0.0262132
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.104853
+w1: 0.231612 w2: 0.231612
+w1: 1.94408e-24 w2: 1.94408e-24
+w1: 0.0817685 w2: 0.0561904
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 7.08833e-24 w2: 7.08833e-24
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 1.3357e-24 w2: 1.3357e-24
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 7.08661e-24 w2: 7.08661e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0262132
+w1: 2.34707e-24 w2: 2.34707e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0262132
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 1.3357e-24 w2: 1.3357e-24
+w1: 0.0561904 w2: 0.0561904
+w1: 2.34673e-24 w2: 2.34673e-24
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 1.33595e-24 w2: 1.33595e-24
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0262132
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0262132
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 1.3362e-24 w2: 1.3362e-24
+w1: 0.0561904 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 1.3362e-24 w2: 1.3362e-24
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 0.104853 w2: 0.152582
+w1: 0.0262132 w2: 0.0381455
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 1.3362e-24 w2: 1.3362e-24
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.152582
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 1.94444e-24 w2: 1.94444e-24
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.152582
+w1: 0.152582 w2: 0.104853
+w1: 0.0381455 w2: 0.0262132
+w1: 3.12336e-24 w2: 3.12336e-24
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.104853
+w1: 0.231612 w2: 0.231612
+w1: 0.0817685 w2: 0.0561904
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 2.14634e-24 w2: 2.14634e-24
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 7.08776e-24 w2: 7.08776e-24
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0817685
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 7.08718e-24 w2: 7.08718e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0262132
+w1: 2.14634e-24 w2: 2.14634e-24
+w1: 2.34673e-24 w2: 2.34673e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0262132
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 2.34673e-24 w2: 2.34673e-24
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 2.14634e-24 w2: 2.14634e-24
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0262132
+w1: 2.14634e-24 w2: 2.14634e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0262132
+w1: 0.104853 w2: 0.104853
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 2.14665e-24 w2: 2.14665e-24
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.235919 w2: 0
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0561904
+w1: 0.159161 w2: 0.159161
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.104853
+w1: 0.104853 w2: 0.152582
+w1: 0.0262132 w2: 0.0381455
+w1: 2.14665e-24 w2: 2.14665e-24
+w1: 0.0974598 w2: 0.0974598
+w1: 0.235919 w2: 0
+w1: 0.0262132 w2: 0.0381455
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.152582
+w1: 3.12428e-24 w2: 3.12428e-24
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.222222
+w1: 0.152582 w2: 0.104853
+w1: 0.0381455 w2: 0.0381455
+w1: 1.05013e-23 w2: 7.2164e-24
+w1: 0.5 w2: 0
+w1: 0.0555556 w2: 0.0262132
+w1: 0.222222 w2: 0.152582
+w1: 1.52942e-23 w2: 1.05013e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 7.08833e-24 w2: 7.08833e-24
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 1.03125e-23 w2: 1.03125e-23
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0381455
+w1: 2.34673e-24 w2: 2.34673e-24
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.152582
+w1: 3.41498e-24 w2: 3.41498e-24
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.104853
+w1: 0.0262132 w2: 0.0381455
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0262132
+w1: 0.152582 w2: 0.152582
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.159161 w2: 0.159161
+w1: 0.0561904 w2: 0.0817685
+w1: 0.34331 w2: 0
+w1: 0.0817685 w2: 0.0561904
+w1: 0.231612 w2: 0.231612
+w1: 0.235919 w2: 0
+w1: 0.104853 w2: 0.152582
+w1: 0.104853 w2: 0.152582
+w1: 0.0262132 w2: 0.0555556
+w1: 0.34331 w2: 0
+w1: 0.0381455 w2: 0.0381455
+w1: 0.152582 w2: 0.222222
+w1: 0.34331 w2: 0
+w1: 0.152582 w2: 0.222222
+w1: 0.5 w2: 0
diff --git a/test/test_model/test_solid_mechanics_model/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/CMakeLists.txt
index fc14d4a6e..071a218de 100644
--- a/test/test_model/test_solid_mechanics_model/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/CMakeLists.txt
@@ -1,231 +1,221 @@
#===============================================================================
# @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_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
- DEPENDENCIES test_solid_mechanics_model_square_mesh
+ 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
- DEPENDENCIES test_solid_mechanics_model_circle_mesh2
+ 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
- DEPENDENCIES test_bar_traction_2d_mesh1 test_bar_traction_2d_mesh2
+ 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
- DEPENDENCIES test_bar_traction_2d_mesh_structured1
+ 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
- DEPENDENCIES test_bar_traction_2d_mesh2
+ 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
- DEPENDENCIES test_solid_mechanics_model_segment_mesh
+ DEPENDS test_solid_mechanics_model_segment_mesh
FILES_TO_COPY material.dat test_cst_energy.pl
DIRECTORIES_TO_CREATE paraview
PACKAGE parallel
)
#===============================================================================
#register_test(test_solid_mechanics_model_bar_traction2d_mass_not_lumped
# SOURCES test_solid_mechanics_model_bar_traction2d_mass_not_lumped.cc
-# DEPENDENCIES test_bar_traction_2d_mesh1 test_bar_traction_2d_mesh2
+# 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
- DEPENDENCIES test_solid_mechanics_model_segment_mesh1
+ 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
- DEPENDENCIES test_implicit_mesh1 test_implicit_mesh2
+ 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
- DEPENDENCIES test_implicit_beam_2d_1 test_implicit_beam_2d_2 test_implicit_beam_3d_2 test_implicit_beam_3d_1
+ 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
- DEPENDENCIES test_bar_traction_2d_mesh_structured1
+ 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
-# DEPENDENCIES test_pbc_parallel_mesh
+# 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
- DEPENDENCIES test_cube3d_mesh1
+ 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
- DEPENDENCIES test_cube3d_mesh2
+ 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
- DEPENDENCIES test_cube3d_mesh_structured
+ 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
- DEPENDENCIES test_cube3d_two_mat_mesh
+ 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_solid_mechanics_model_orthotropic
- SOURCES test_solid_mechanics_model_orthotropic.cc
- DEPENDENCIES test_solid_mechanics_model_square_mesh
- FILES_TO_COPY orthotropic.dat
- DIRECTORIES_TO_CREATE paraview
- 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/material_elastic_plane_strain.dat b/test/test_model/test_solid_mechanics_model/material_elastic_plane_strain.dat
index 15d295fca..b7297c018 100644
--- a/test/test_model/test_solid_mechanics_model/material_elastic_plane_strain.dat
+++ b/test/test_model/test_solid_mechanics_model/material_elastic_plane_strain.dat
@@ -1,9 +1,9 @@
-parser_permissive = true
+permissive_parser = true
material elastic [
name = steel
rho = 7800 # density
E = 2.1e11 # young's modulus
nu = 0.3 # poisson's ratio
Plane_Stress = 0 # plane strain
]
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 8d667acf1..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
- DEPENDENCIES test_weight_hexa_mesh test_weight_tetra_mesh
+ 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/_pentahedron_15.msh b/test/test_model/test_solid_mechanics_model/patch_tests/data/_pentahedron_15.msh
index 633346ddd..dae9d7e52 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/data/_pentahedron_15.msh
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/_pentahedron_15.msh
@@ -1,186 +1,182 @@
$MeshFormat
2.2 0 8
$EndMeshFormat
$Nodes
-97
+93
1 0 0 0
2 1 0 0
3 1 1 0
4 0 1 0
5 0 0 1
6 1 0 1
7 1 1 1
8 0 1 1
9 0.4000000004956805 0 1
10 0.2000000002478403 0 1
11 0.7000000002478403 0 1
12 1 0.4000000004956805 1
13 1 0.2000000002478403 1
14 1 0.7000000002478403 1
15 0.5999999995046822 1 1
16 0.799999999752341 1 1
17 0.2999999997523411 1 1
18 0 0.5999999995046822 1
19 0 0.799999999752341 1
20 0 0.2999999997523411 1
21 0.4000000004956805 0 0
22 0.2000000002478403 0 0
23 0.7000000002478403 0 0
24 1 0.4000000004956805 0
25 1 0.2000000002478403 0
26 1 0.7000000002478403 0
27 0.5999999995046822 1 0
28 0.799999999752341 1 0
29 0.2999999997523411 1 0
30 0 0.5999999995046822 0
31 0 0.799999999752341 0
32 0 0.2999999997523411 0
33 0 0 0.5999999995046822
34 0 0 0.799999999752341
35 0 0 0.2999999997523411
36 0 1 0.4000000004956805
37 0 1 0.2000000002478403
38 0 1 0.7000000002478403
39 1 0 0.5999999995046822
40 1 0 0.799999999752341
41 1 0 0.2999999997523411
42 1 1 0.4000000004956805
43 1 1 0.2000000002478403
44 1 1 0.7000000002478403
45 0.4800000001984172 0.5199999998019453 1
46 0.4400000003470489 0.2599999999009727 1
47 0.2400000000992086 0.5599999996533138 1
48 0.5399999998515497 0.7599999999009727 1
49 0.7400000000992086 0.4600000001488129 1
50 1 0.4000000004956805 0.5199999998019454
51 1 0.2000000002478403 0.5599999996533138
52 1 0.4000000004956805 0.7599999999009728
53 1 0.7000000002478403 0.460000000148813
54 1 0.4000000004956805 0.2599999999009727
55 0.5199999998020179 0.5199999998019454 0
56 0.55999999965335 0.7599999999009728 0
57 0.259999999901009 0.5599999996533138 0
58 0.759999999901009 0.460000000148813 0
59 0.4600000001488492 0.2599999999009727 0
60 0 0.5999999995046822 0.4800000001983448
61 0 0.799999999752341 0.4400000003470127
62 0 0.5999999995046822 0.7400000000991724
63 0 0.5999999995046822 0.2400000000991724
64 0 0.2999999997523411 0.5399999998515135
65 0.5999999995046822 1 0.4000000004956805
66 0.799999999752341 1 0.2000000002478403
67 0.5999999995046822 1 0.2000000002478403
68 0.799999999752341 1 0.4000000004956805
-69 0.2999999997523411 1 0.2000000002478403
-70 0.2999999997523411 1 0.4000000004956805
-71 0.799999999752341 1 0.7000000002478403
-72 0.5999999995046822 1 0.7000000002478403
-73 0.2999999997523411 1 0.7000000002478403
+69 0.2999999997523411 1 0.4000000004956805
+70 0.5999999995046822 1 0.7000000002478403
+71 0.2999999997523411 1 0.7000000002478403
+72 0.799999999752341 1 0.7000000002478403
+73 0.2999999997523411 1 0.2000000002478403
74 0.4000000004956805 0 0.5999999995046822
75 0.2000000002478403 0 0.799999999752341
76 0.2000000002478403 0 0.5999999995046822
77 0.4000000004956805 0 0.799999999752341
78 0.7000000002478403 0 0.5999999995046822
-79 0.7000000002478403 0 0.799999999752341
-80 0.2000000002478403 0 0.2999999997523411
-81 0.4000000004956805 0 0.2999999997523411
-82 0.7000000002478403 0 0.2999999997523411
+79 0.4000000004956805 0 0.2999999997523411
+80 0.7000000002478403 0 0.2999999997523411
+81 0.7000000002478403 0 0.799999999752341
+82 0.2000000002478403 0 0.2999999997523411
83 0.4960000000596703 0.5199999998019451 0.4960000000596124
84 0.2400000000992086 0.5599999996533138 0.7400000000991724
85 0.4480000002776754 0.2599999999009726 0.5479999997821473
86 0.4880000001290438 0.5199999998019452 0.7480000000298062
87 0.2480000000298352 0.5599999996533136 0.4880000001289786
88 0.5479999997821763 0.7599999999009726 0.4480000002776465
-89 0.7000000002478403 0 0.799999999752341
-90 0.7480000000298351 0.4600000001488128 0.7480000000298062
-91 0.7480000000298351 0.4600000001488128 0.5079999999307789
-92 0.799999999752341 1 0.7000000002478403
-93 0.2000000002478403 0 0.2999999997523411
-94 0.2480000000298352 0.5599999996533136 0.2480000000298062
-95 0.5079999999308441 0.5199999998019453 0.2480000000298062
-96 0.2999999997523411 1 0.2000000002478403
-97 0.759999999901009 0.460000000148813 0.2599999999009727
+89 0.7480000000298351 0.4600000001488128 0.7480000000298062
+90 0.7480000000298351 0.4600000001488128 0.5079999999307789
+91 0.2480000000298352 0.5599999996533136 0.2480000000298062
+92 0.5079999999308441 0.5199999998019453 0.2480000000298062
+93 0.759999999901009 0.460000000148813 0.2599999999009727
$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 8 2 0 1 5 9 10
10 8 2 0 1 9 6 11
11 8 2 0 2 6 12 13
12 8 2 0 2 12 7 14
13 8 2 0 3 7 15 16
14 8 2 0 3 15 8 17
15 8 2 0 4 8 18 19
16 8 2 0 4 18 5 20
17 8 2 0 5 1 21 22
18 8 2 0 5 21 2 23
19 8 2 0 6 2 24 25
20 8 2 0 6 24 3 26
21 8 2 0 7 3 27 28
22 8 2 0 7 27 4 29
23 8 2 0 8 4 30 31
24 8 2 0 8 30 1 32
25 8 2 0 9 5 33 34
26 8 2 0 9 33 1 35
27 8 2 0 10 4 36 37
28 8 2 0 10 36 8 38
29 8 2 0 11 6 39 40
30 8 2 0 11 39 2 41
31 8 2 0 12 3 42 43
32 8 2 0 12 42 7 44
33 9 2 0 22 3 27 42 28 66 43
34 9 2 0 22 27 65 42 67 68 66
-35 9 2 0 22 27 36 65 69 70 67
-36 9 2 0 22 36 27 4 69 29 37
-37 9 2 0 22 42 15 7 71 16 44
-38 9 2 0 22 15 42 65 71 68 72
-39 9 2 0 22 65 36 15 70 73 72
-40 9 2 0 22 36 8 15 38 17 73
+35 9 2 0 22 27 36 65 73 69 67
+36 9 2 0 22 36 27 4 73 29 37
+37 9 2 0 22 42 15 7 72 16 44
+38 9 2 0 22 15 42 65 72 68 70
+39 9 2 0 22 65 36 15 69 71 70
+40 9 2 0 22 36 8 15 38 17 71
41 9 2 0 24 5 33 9 34 75 10
42 9 2 0 24 9 33 74 75 76 77
-43 9 2 0 24 9 74 39 77 78 79
-44 9 2 0 24 39 6 9 40 11 79
-45 9 2 0 24 33 1 21 35 22 80
-46 9 2 0 24 21 74 33 81 76 80
-47 9 2 0 24 74 21 39 81 82 78
-48 9 2 0 24 39 21 2 82 23 41
+43 9 2 0 24 9 74 39 77 78 81
+44 9 2 0 24 39 6 9 40 11 81
+45 9 2 0 24 33 1 21 35 22 82
+46 9 2 0 24 21 74 33 79 76 82
+47 9 2 0 24 74 21 39 79 80 78
+48 9 2 0 24 39 21 2 80 23 41
49 16 2 0 14 5 9 45 18 10 46 47 20
50 16 2 0 14 18 45 15 8 47 48 17 19
51 16 2 0 14 9 6 12 45 11 13 49 46
52 16 2 0 14 45 12 7 15 49 14 16 48
53 16 2 0 16 6 39 50 12 40 51 52 13
54 16 2 0 16 12 50 42 7 52 53 44 14
55 16 2 0 16 39 2 24 50 41 25 54 51
56 16 2 0 16 50 24 3 42 54 26 43 53
57 16 2 0 18 4 27 55 30 29 56 57 31
58 16 2 0 18 27 3 24 55 28 26 58 56
59 16 2 0 18 30 55 21 1 57 59 22 32
60 16 2 0 18 55 24 2 21 58 25 23 59
61 16 2 0 20 8 36 60 18 38 61 62 19
62 16 2 0 20 36 4 30 60 37 31 63 61
63 16 2 0 20 18 60 33 5 62 64 34 20
64 16 2 0 20 60 30 1 33 63 32 35 64
65 18 2 0 26 33 5 9 60 18 45 34 75 64 10 20 46 62 84 47
66 18 2 0 26 9 74 33 45 83 60 77 75 46 76 85 64 86 84 87
-67 18 2 0 26 60 18 45 36 8 15 62 84 61 47 19 48 38 73 17
-68 18 2 0 26 45 83 60 15 65 36 86 84 48 87 88 61 72 73 70
-69 18 2 0 26 74 9 6 83 45 12 77 89 85 11 46 13 86 90 49
-70 18 2 0 26 6 39 74 12 50 83 40 89 13 78 51 85 52 90 91
-71 18 2 0 26 83 45 12 65 15 7 86 90 88 49 48 14 72 92 16
-72 18 2 0 26 12 50 83 7 42 65 52 90 14 91 53 88 44 92 68
-73 18 2 0 26 1 33 74 30 60 83 35 93 32 76 64 85 63 94 87
-74 18 2 0 26 74 21 1 83 55 30 81 93 85 22 59 32 95 94 57
-75 18 2 0 26 30 60 83 4 36 65 63 94 31 87 61 88 37 96 70
-76 18 2 0 26 83 55 30 65 27 4 95 94 88 57 56 31 67 96 29
-77 18 2 0 26 21 74 39 55 83 50 81 82 59 78 85 51 95 97 91
-78 18 2 0 26 39 2 21 50 24 55 41 82 51 23 25 59 54 97 58
-79 18 2 0 26 55 83 50 27 65 42 95 97 56 91 88 53 67 66 68
-80 18 2 0 26 50 24 55 42 3 27 54 97 53 58 26 56 43 66 28
+67 18 2 0 26 60 18 45 36 8 15 62 84 61 47 19 48 38 71 17
+68 18 2 0 26 45 83 60 15 65 36 86 84 48 87 88 61 70 71 69
+69 18 2 0 26 74 9 6 83 45 12 77 81 85 11 46 13 86 89 49
+70 18 2 0 26 6 39 74 12 50 83 40 81 13 78 51 85 52 89 90
+71 18 2 0 26 83 45 12 65 15 7 86 89 88 49 48 14 70 72 16
+72 18 2 0 26 12 50 83 7 42 65 52 89 14 90 53 88 44 72 68
+73 18 2 0 26 1 33 74 30 60 83 35 82 32 76 64 85 63 91 87
+74 18 2 0 26 74 21 1 83 55 30 79 82 85 22 59 32 92 91 57
+75 18 2 0 26 30 60 83 4 36 65 63 91 31 87 61 88 37 73 69
+76 18 2 0 26 83 55 30 65 27 4 92 91 88 57 56 31 67 73 29
+77 18 2 0 26 21 74 39 55 83 50 79 80 59 78 85 51 92 93 90
+78 18 2 0 26 39 2 21 50 24 55 41 80 51 23 25 59 54 93 58
+79 18 2 0 26 55 83 50 27 65 42 92 93 56 90 88 53 67 66 68
+80 18 2 0 26 50 24 55 42 3 27 54 93 53 58 26 56 43 66 28
$EndElements
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/data/material_check_stress_plane_strain.dat b/test/test_model/test_solid_mechanics_model/patch_tests/data/material_check_stress_plane_strain.dat
index 15d295fca..b7297c018 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/data/material_check_stress_plane_strain.dat
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/material_check_stress_plane_strain.dat
@@ -1,9 +1,9 @@
-parser_permissive = true
+permissive_parser = true
material elastic [
name = steel
rho = 7800 # density
E = 2.1e11 # young's modulus
nu = 0.3 # poisson's ratio
Plane_Stress = 0 # plane strain
]
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 7157865d5..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().getNbQuadraturePoints(TYPE);
+ 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 74ead292c..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().getNbQuadraturePoints(TYPE);
+ 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 3468c3771..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,231 +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().getNbQuadraturePoints(element_type);
+ 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;
+ 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 aa9e7bec0..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.getNbQuadraturePoints(type) * nb_element;
+ 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 38ee22977..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
- DEPENDENCIES test_cohesive_1d_element_mesh
+ 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/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/CMakeLists.txt
index b6f2b32aa..fdb27b9a1 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/CMakeLists.txt
@@ -1,40 +1,40 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
# @date Wed Jun 13 11:29:49 2012
#
# @brief configuration for build fragments tests
#
# @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
#
#===============================================================================
add_mesh(test_cohesive_buildfragments_mesh mesh.geo 2 1)
register_test(test_cohesive_buildfragments
SOURCES test_cohesive_buildfragments.cc
- DEPENDENCIES test_cohesive_buildfragments_mesh
+ DEPENDS test_cohesive_buildfragments_mesh
FILES_TO_COPY material.dat
DIRECTORIES_TO_CREATE paraview
PACKAGE cohesive_element
)
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 0ca1090a5..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").getNbQuadraturePoints(type_facet);
+ 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 1e2c3ea33..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
- DEPENDENCIES test_cohesive_extrinsic_mesh
+ 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
- DEPENDENCIES test_cohesive_extrinsic_quadrangle_mesh
+ DEPENDS test_cohesive_extrinsic_quadrangle_mesh
PACKAGE cohesive_element
)
register_test(test_cohesive_extrinsic_tetrahedron
SOURCES test_cohesive_extrinsic_tetrahedron.cc
- DEPENDENCIES test_cohesive_extrinsic_tetrahedron_mesh
+ 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 6fbdde134..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").getNbQuadraturePoints(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").interpolateOnQuadraturePoints(position,
+ 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().getNbQuadraturePoints(type);
+ 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().interpolateOnQuadraturePoints(position,
+ 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").getNormalsOnQuadPoints(type_facet);
+ 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 f4d9777b2..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_verified(j,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 d7e1d7000..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
- DEPENDENCIES 3d_spherical_inclusion
+ 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 13c5375b3..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
- DEPENDENCIES test_cohesive_intrinsic_mesh
+ 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
- DEPENDENCIES test_cohesive_intrinsic_quadrangle_mesh
+ DEPENDS test_cohesive_intrinsic_quadrangle_mesh
PACKAGE cohesive_element
)
register_test(test_cohesive_intrinsic_tetrahedron
SOURCES test_cohesive_intrinsic_tetrahedron.cc
- DEPENDENCIES test_cohesive_intrinsic_tetrahedron_mesh
+ 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
- DEPENDENCIES test_cohesive_intrinsic_tetrahedron_fragmentation_mesh
+ 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 30d64c941..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").getNbQuadraturePoints(type_cohesive);
+ = 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/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/CMakeLists.txt
new file mode 100644
index 000000000..6d6ed5e7f
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_linear_friction/CMakeLists.txt
@@ -0,0 +1,37 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @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/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+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 4e496b92e..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 QuadraturePoint & quad_point,
+ 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 c843b64f9..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,62 +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
- DEPENDENCIES test_local_material_barre_trou_mesh
+ 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
- DEPENDENCIES test_material_thermal_mesh
+ 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
- DEPENDENCIES test_interpolate_stress_mesh
+ 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 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")
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/material_mazars.dat b/test/test_model/test_solid_mechanics_model/test_materials/material_mazars.dat
new file mode 100644
index 000000000..a50a2fdbd
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/material_mazars.dat
@@ -0,0 +1,12 @@
+material mazars [
+ name = concrete
+ rho = 3000 # density
+ E = 32e9 # young's modulus
+ nu = 0.2 # poisson's ratio
+ K0 = 9.375e-5 # Damage threshold
+ At = 1.15 # Parameter damage traction 1
+ Bt = 10000 # Parameter damage traction 2
+ Ac = 0.8 # Parameter damage compression 1
+ Bc = 1391.3 # Parameter damage compression 2
+ beta = 1.00 # Parameter for shear
+]
diff --git a/test/test_model/test_solid_mechanics_model/orthotropic.dat b/test/test_model/test_solid_mechanics_model/test_materials/orthotropic.dat
similarity index 100%
rename from test/test_model/test_solid_mechanics_model/orthotropic.dat
rename to test/test_model/test_solid_mechanics_model/test_materials/orthotropic.dat
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/square.geo b/test/test_model/test_solid_mechanics_model/test_materials/square.geo
index 179d8e80d..feb1c1b04 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/square.geo
+++ b/test/test_model/test_solid_mechanics_model/test_materials/square.geo
@@ -1,43 +1,43 @@
// 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 Line("Edges") = {101};
+Physical Line("Edges") = {101, 102, 103, 104};
Physical Surface(6) = {101};
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 7a4626699..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").getNbQuadraturePoints(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").interpolateOnQuadraturePoints(position,
+ 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().getNbQuadraturePoints(type);
+ 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().interpolateOnQuadraturePoints(position,
+ 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 4fc8e7541..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().getNbQuadraturePoints(*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
new file mode 100644
index 000000000..6ee31ab1a
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/CMakeLists.txt
@@ -0,0 +1,47 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Jaehyun Cho <jaehyun.cho@epfl.ch>
+#
+# @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
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+#===============================================================================
+add_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
new file mode 100644
index 000000000..4d775351e
--- /dev/null
+++ 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
@@ -0,0 +1,127 @@
+/**
+ * @file test_material_elasto_plastic_linear_isotropic_hardening.cc
+ *
+ * @author Jaehyun Cho <jaehyun.cho@epfl.ch>
+ *
+ * @date creation: Thu Dec 03 2015
+ *
+ * @brief test for material type elasto plastic linear isotropic hardening using
+ * # tension-compression test
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <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_elasto_plastic_linear_isotropic_hardening/test_material_elasto_plastic_linear_isotropic_hardening.dat b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_elasto_plastic_linear_isotropic_hardening.dat
new file mode 100644
index 000000000..9c45d0213
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_elasto_plastic_linear_isotropic_hardening.dat
@@ -0,0 +1,8 @@
+material plastic_linear_isotropic_hardening [
+ name = hardening
+ rho = 1000 # density
+ E = 12e7 # young's modulus
+ nu = 0.3 # poisson's ratio
+ h = 1e7 # hardening modulus
+ sigma_y = 12e4 # yielding stress
+]
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.geo b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_elasto_plastic_linear_isotropic_hardening.geo
new file mode 100644
index 000000000..1c7c11834
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/test_material_elasto_plastic_linear_isotropic_hardening.geo
@@ -0,0 +1,34 @@
+h = 0.1;
+
+Lx = 10.0;
+Ly = 1.0;
+
+
+Point(1) = { 0.0, 0.0, 0.0, h};
+Point(2) = { Lx, 0.0, 0.0, h};
+Point(3) = { Lx, Ly, 0.0, h};
+Point(4) = { 0.0, Ly, 0.0, h};
+
+// Base Cube
+Line(12) = {1,2};
+Line(23) = {2,3};
+Line(34) = {3,4};
+Line(41) = {4,1};
+
+// Base Cube
+Line Loop(1234) = {12,23,34,41};
+Plane Surface(0) = {1234};
+
+Physical Surface("bulk") = {0};
+
+//Physical Point ("left1") = {4};
+//Physical Point ("left2") = {1};
+Physical Line ("left") = {41};
+Physical Line ("right") = {23};
+Physical Line ("bottom") = {12};
+
+//Physical Point ("right1") = {2};
+//Physical Point ("right2") = {3};
+
+//Physical Point ("bottom1") = {1};
+//Physical Point ("bottom2") = {2};
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
new file mode 100644
index 000000000..047865d5a
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_mazars.cc
@@ -0,0 +1,307 @@
+/**
+ * @file test_material_mazars.cc
+ *
+ * @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 (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
+ * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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 5014cfb25..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,59 +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_2 mesh.geo 2 2 OUTPUT mesh_2.msh)
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)
-add_mesh(test_two_materials_mesh two_materials.geo 2 1 OUTPUT two_materials.msh)
register_test(test_material_damage_non_local
SOURCES test_material_damage_non_local.cc
- DEPENDENCIES test_material_damage_non_local_mesh
+ 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_damage_non_local_two_materials
- SOURCES test_material_damage_non_local_two_materials.cc
- DEPENDENCIES test_two_materials_mesh
- FILES_TO_COPY two_materials_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
- DEPENDENCIES test_material_non_local_mesh
+ 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 581920785..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,80 +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);
- // register the variable Ynl, as the non local version of Y
- this->registerNonLocalVariable(this->local_damage, this->damage, 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 86108af58..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,105 +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, BaseWeightFunction> {
+ public MaterialNonLocal<dim> {
public:
- typedef MaterialNonLocal<dim, BaseWeightFunction> MyNonLocalParent;
+ typedef MaterialNonLocal<dim> MyNonLocalParent;
typedef MaterialElastic<dim> MyElasticParent;
CustomNonLocalTestMaterial(SolidMechanicsModel & model, const ID & id);
/* ------------------------------------------------------------------------ */
- virtual void initMaterial() {
- MyElasticParent::initMaterial();
- MyNonLocalParent::initMaterial();
- }
-
+ 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/material.dat b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material.dat
index bd6472d87..401f2491c 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material.dat
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material.dat
@@ -1,9 +1,11 @@
material custom_non_local_test_material [
name = test
rho = 1 # density
E = 1 # young's modulus
nu = 0 # poisson's ratio
- non_local weight_function [
- radius = 0.4
- ]
]
+
+
+non_local test base_wf [
+ radius = 0.4
+]
\ No newline at end of file
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material_damage_non_local.dat b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material_damage_non_local.dat
index d97958b96..2e3d958b3 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material_damage_non_local.dat
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material_damage_non_local.dat
@@ -1,15 +1,18 @@
Yd0 = 94e3
-material marigo_non_local remove_wf [
+material marigo_non_local [
name = concrete
rho = 3900 # density
E = 370e9 # young's modulus
nu = 0.22 # poisson's ratio
Yd = Yd0 uniform [ 0, 0.1 * Yd0 ]
Sd = 2.748e6
- non_local weight_function [
- update_rate = 10
- radius = 0.15
- damage_limit = 0.99
- ]
+]
+
+non_local concrete remove_wf [
+ radius = 0.15
+ weight_function weight_parameter [
+ damage_limit = 0.99
+ update_rate = 10
+ ]
]
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material_non_local.dat b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material_non_local.dat
deleted file mode 100644
index d9d63f682..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material_non_local.dat
+++ /dev/null
@@ -1,4 +0,0 @@
-material damage_non_local [
- name = non_local_test
- radius = 1e-1
-]
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 83d834ce1..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().getNbQuadraturePoints(*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_damage_non_local_two_materials.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local_two_materials.cc
deleted file mode 100644
index 131d03d3b..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_damage_non_local_two_materials.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-/**
- * @file test_material_damage_non_local_two_materials.cc
- * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
- * @date Fri Feb 20 15:30:27 2015
- *
- * @brief test to check if two non-local materials can be used together
- *
- * @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 "aka_common.hh"
-#include "mesh.hh"
-#include "mesh_io.hh"
-#include "solid_mechanics_model.hh"
-#include "material.hh"
-/* -------------------------------------------------------------------------- */
-
-using namespace akantu;
-
-int main(int argc, char *argv[]) {
- initialize("two_materials_non_local.dat", argc, argv);
- debug::setDebugLevel(akantu::dblWarning);
-
- const UInt spatial_dimension = 2;
- Mesh mesh(spatial_dimension);
- akantu::MeshPartition * partition = NULL;
-
- StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
- Int psize = comm.getNbProc();
- Int prank = comm.whoAmI();
-
- if(prank == 0) {
-
- mesh.read("two_materials.msh");
-
- /// partition the mesh
- partition = new MeshPartitionScotch(mesh, spatial_dimension);
-
- partition->partitionate(psize);
- }
-
- SolidMechanicsModel model(mesh);
- model.initParallel(partition);
- delete partition;
-
- model.setBaseName("damage_in_ASR_sample");
- model.addDumpField("partitions");
-
- model.dump();
- /// assign the materials
- MeshDataMaterialSelector<UInt> * mat_selector;
- mat_selector = new MeshDataMaterialSelector<UInt>("tag_0", model, 1);
-
- model.setMaterialSelector(*mat_selector);
- model.initFull(SolidMechanicsModelOptions(_static));
-
- /// displaying the material data
- if (prank == 0) {
- for (UInt m = 0; m < model.getNbMaterials(); ++m)
- std::cout << model.getMaterial(m) << std::endl;
- }
-
-
- // model.getFEEngine().getMesh().initElementTypeMapArray(quadrature_points_volumes, 1, 0);
- // const MaterialNonLocal<spatial_dimension, BaseWeightFunction> & mat =
- // dynamic_cast<const MaterialNonLocal<spatial_dimension, BaseWeightFunction> &>(model.getMaterial(0));
- // // mat.computeQuadraturePointsNeighborhoudVolumes(quadrature_points_volumes);
- // Real radius = mat.getRadius();
-
- // UInt nb_element = mesh.getNbElement(TYPE);
- // UInt nb_tot_quad = model.getFEEngine().getNbQuadraturePoints(TYPE) * nb_element;
-
- // std::cout << mat << std::endl;
-
- // Array<Real> quads(0, spatial_dimension);
- // quads.resize(nb_tot_quad);
-
- // model.getFEEngine().interpolateOnQuadraturePoints(mesh.getNodes(),
- // quads, spatial_dimension,
- // TYPE);
-
- // Array<Real>::iterator< Vector<Real> > first_quad_1 = quads.begin(spatial_dimension);
- // Array<Real>::iterator< Vector<Real> > last_quad_1 = quads.end(spatial_dimension);
-
- // std::ofstream pout;
- // pout.open("bf_pairs");
- // UInt q1 = 0;
-
- // Real R = mat.getRadius();
-
- // for(;first_quad_1 != last_quad_1; ++first_quad_1, ++q1) {
- // Array<Real>::iterator< Vector<Real> > first_quad_2 = quads.begin(spatial_dimension);
- // //Array<Real>::iterator< Vector<Real> > last_quad_2 = quads.end(spatial_dimension);
- // UInt q2 = 0;
- // for(;first_quad_2 != last_quad_1; ++first_quad_2, ++q2) {
- // Real d = first_quad_2->distance(*first_quad_1);
- // if(d <= radius) {
- // Real alpha = (1 - d*d/(R*R));
- // alpha = alpha*alpha;
- // pout << q1 << " " << q2 << " " << alpha << std::endl;
- // }
- // }
- // }
- // pout.close();
-
- // mat.savePairs("cl_pairs");
-
- // ElementTypeMapArray<Real> constant("constant_value", "test");
- // mesh.initElementTypeMapArray(constant, 1, 0);
- // Mesh::type_iterator it = mesh.firstType(spatial_dimension);
- // Mesh::type_iterator last_type = mesh.lastType(spatial_dimension);
- // for(; it != last_type; ++it) {
- // UInt nb_quadrature_points = model.getFEEngine().getNbQuadraturePoints(*it);
- // UInt _nb_element = mesh.getNbElement(*it);
-
- // Array<Real> & constant_vect = constant(*it);
- // constant_vect.resize(_nb_element * nb_quadrature_points);
-
- // std::fill_n(constant_vect.storage(), nb_quadrature_points * _nb_element, 1.);
- // }
-
- // ElementTypeMapArray<Real> constant_avg("constant_value_avg", "test");
- // mesh.initElementTypeMapArray(constant_avg, 1, 0);
-
- // mat.weightedAvergageOnNeighbours(constant, constant_avg, 1);
-
- // debug::setDebugLevel(akantu::dblTest);
- // std::cout << constant(TYPE) << std::endl;
- // std::cout << constant_avg(TYPE) << std::endl;
- // debug::setDebugLevel(akantu::dblWarning);
-
- 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 aa3988846..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,108 +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();
- mat.savePairs("pairs");
//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_non_local/two_materials.geo b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/two_materials.geo
deleted file mode 100644
index c9f459f12..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/two_materials.geo
+++ /dev/null
@@ -1,49 +0,0 @@
-// Mesh size
-h = 0.25; // 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/4, 0.0, 0.0, h};
-Point(103) = { Lx, 0.0, 0.0, h}; // Bottom Face
-Point(104) = { Lx, Ly, 0.0, h}; // Bottom Face
-Point(105) = { Lx/4, Ly, 0.0, h};
-Point(106) = { 0.0, Ly, 0.0, h}; // Bottom Face
-
-// Base Cube
-Line(101) = {101,102}; // Bottom Face
-Line(102) = {102,105}; // Bottom Face
-Line(103) = {105,106}; // Bottom Face
-Line(104) = {106,101}; // Bottom Face
-
-Line(105) = {102,103}; // Bottom Face
-Line(106) = {103,104}; // Bottom Face
-Line(107) = {104,105}; // Bottom Face
-// Line(108) = {105,102}; // Bottom Face
-//
-// // Base Cube
-// Line Loop(101) = {101:104};
-// Line Loop(102) = {105:108};
-//
-// Plane Surface(101) = {101};
-// Plane Surface(102) = {102};
-// Physical Surface(1) = {101};
-// Physical Surface(2) = {102};
-
-Line Loop(108) = {105, 106, 107, -102};
-Plane Surface(209) = {108};
-Line Loop(110) = {101, 102, 103, 104};
-Plane Surface(210) = {110};
-
-Physical Surface(1) = {209};
-Physical Surface(2) = {210};
-
-Transfinite Surface "*";
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/two_materials_non_local.dat b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/two_materials_non_local.dat
deleted file mode 100644
index fc50cb6a5..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/two_materials_non_local.dat
+++ /dev/null
@@ -1,21 +0,0 @@
-seed = 1
-
-material elastic [
- name = aggregate
- rho = 2.7e-9 # density
- E = 60e9 # young's modulus
- nu = 0.3 # poisson's ratio
-]
-
-material damage_iterative_non_local base_wf [
- name = mortar
- rho = 2.2e-9 # density
- E = 12e9 # young's modulus
- nu = 0.3 # poisson's ratio
- Sc = 9.6e6 weibull [2.4e6, 5.]
- prescribed_dam = 0.1
- max_damage = 0.95
- non_local weight_function [
- radius = 1.0
- ]
-]
\ No newline at end of file
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
new file mode 100644
index 000000000..b977ae637
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc
@@ -0,0 +1,104 @@
+/**
+ * @file test_material_orthotropic.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @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, 2015 EPFL (Ecole Polytechnique Fédérale de
+ * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+ * Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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 b7ae73649..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
- DEPENDENCIES test_material_standard_linear_solid_deviatoric_relaxation_mesh
+ 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
- DEPENDENCIES test_material_standard_linear_solid_deviatoric_relaxation_mesh
+ 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.dat b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_stiffness_proportional.dat
deleted file mode 100644
index 5eb98494a..000000000
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_stiffness_proportional.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 = 1e-6 # viscous ratio
-]
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_orthotropic.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_orthotropic.cc
deleted file mode 100644
index 5f53d0d36..000000000
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_orthotropic.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You 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_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 61e318ca2..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
- DEPENDENCIES complicated_mesh
+ 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
new file mode 100644
index 000000000..dead161f3
--- /dev/null
+++ b/test/test_python_interface/CMakeLists.txt
@@ -0,0 +1,36 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Fabian Barras <fabian.barras@epfl.ch>
+#
+# @date creation: Fri Sep 03 2010
+# @date last modification: Wed Jan 06 2016
+#
+# @brief Python Interface tests
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de
+# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
+# Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+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
new file mode 100644
index 000000000..91b0c3ec1
--- /dev/null
+++ b/test/test_python_interface/input_test.dat
@@ -0,0 +1,7 @@
+material elastic [
+ name = bulk
+ rho = 2500
+ nu = 0.22
+ E = 71e9
+# finite_deformation = 1
+]
diff --git a/test/test_python_interface/mesh_dcb_2d.geo b/test/test_python_interface/mesh_dcb_2d.geo
new file mode 100644
index 000000000..cf158c0b6
--- /dev/null
+++ b/test/test_python_interface/mesh_dcb_2d.geo
@@ -0,0 +1,26 @@
+
+//Mesh size
+dx = 57.8e-5;
+
+Point(1) = {0,0,0,dx};
+Point(2) = {0,0.00055,0,dx};
+Point(3) = {0,-0.00055,0,dx};
+Point(4) = {57.8e-3,0,0,dx};
+Point(5) = {57.8e-3,0.00055,0,dx};
+Point(6) = {57.8e-3,-0.00055,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/test/test_python_interface/test_multiple_init.py b/test/test_python_interface/test_multiple_init.py
new file mode 100755
index 000000000..709a9e0c7
--- /dev/null
+++ b/test/test_python_interface/test_multiple_init.py
@@ -0,0 +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
+import akantu as aka
+
+os.system('gmsh -order 2 -2 -o mesh_dcb_2d.msh mesh_dcb_2d.geo')
+
+aka.initialize('input_test.dat')
+
+print 'First initialisation'
+mesh = aka.Mesh(2)
+mesh.read('mesh_dcb_2d.msh')
+model = aka.SolidMechanicsModel(mesh)
+model.initFull(aka.SolidMechanicsModelOptions(aka._static))
+del model
+del mesh
+
+print 'Second initialisation'
+mesh = aka.Mesh(2)
+mesh.read('mesh_dcb_2d.msh')
+model = aka.SolidMechanicsModel(mesh)
+model.initFull(aka.SolidMechanicsModelOptions(aka._static))
+del model
+del mesh
+
+aka.finalize()
+print 'All right'
diff --git a/test/test_solver/CMakeLists.txt b/test/test_solver/CMakeLists.txt
index 61ee1e556..dffd68b09 100644
--- a/test/test_solver/CMakeLists.txt
+++ b/test/test_solver/CMakeLists.txt
@@ -1,84 +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
- DEPENDENCIES test_solver_mesh
+ DEPENDS test_solver_mesh
PACKAGE implicit
)
register_test(test_sparse_matrix_assemble
SOURCES test_sparse_matrix_assemble.cc
- DEPENDENCIES test_solver_mesh
+ 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
- DEPENDENCIES test_matrix_mesh
+ DEPENDS test_matrix_mesh
PACKAGE petsc
)
register_test(test_petsc_matrix_profile_parallel
SOURCES test_petsc_matrix_profile_parallel.cc
- DEPENDENCIES test_matrix_mesh
+ DEPENDS test_matrix_mesh
PACKAGE petsc
)
register_test(test_petsc_matrix_diagonal
SOURCES test_petsc_matrix_diagonal.cc
- DEPENDENCIES test_solver_mesh
+ DEPENDS test_solver_mesh
PACKAGE petsc
)
register_test(test_petsc_matrix_apply_boundary
SOURCES test_petsc_matrix_apply_boundary.cc
- DEPENDENCIES test_solver_mesh
+ DEPENDS test_solver_mesh
PACKAGE petsc
)
register_test(test_solver_petsc
SOURCES test_solver_petsc.cc
- DEPENDENCIES test_solver_petsc_mesh
+ DEPENDS test_solver_petsc_mesh
PACKAGE petsc
- )
\ No newline at end of file
+ )
+
+register_test(test_solver_petsc_parallel
+ SOURCES test_solver_petsc.cc
+ DEPENDS test_solver_petsc_mesh
+ PACKAGE petsc
+ )
diff --git a/test/test_solver/test_petsc_matrix_apply_boundary.cc b/test/test_solver/test_petsc_matrix_apply_boundary.cc
index 92e598bab..d691b159d 100644
--- a/test/test_solver/test_petsc_matrix_apply_boundary.cc
+++ b/test/test_solver/test_petsc_matrix_apply_boundary.cc
@@ -1,140 +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())
+ 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 e7fa90127..0441ab957 100644
--- a/test/test_solver/test_petsc_matrix_diagonal.cc
+++ b/test/test_solver/test_petsc_matrix_diagonal.cc
@@ -1,146 +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 2eb172f50..114be7dff 100644
--- a/test/test_solver/test_solver_petsc.cc
+++ b/test/test_solver/test_solver_petsc.cc
@@ -1,161 +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_solver_petsc.sh b/test/test_solver/test_solver_petsc.sh
index edcc7916c..af7d892a6 100755
--- a/test/test_solver/test_solver_petsc.sh
+++ b/test/test_solver/test_solver_petsc.sh
@@ -1,5 +1,6 @@
#! /bin/bash
# choose solver Mumps through the PETSc interface
./test_solver_petsc -ksp_type preonly -pc_type lu -pc_factor_mat_solver_package mumps -mat_mumps_icntl_7 2
-mpirun -np 4 ./test_solver_petsc -ksp_type preonly -pc_type lu -pc_factor_mat_solver_package mumps -mat_mumps_icntl_7 2
+
+
diff --git a/test/test_solver/test_solver_petsc_parallel.sh b/test/test_solver/test_solver_petsc_parallel.sh
new file mode 100644
index 000000000..45e13e819
--- /dev/null
+++ b/test/test_solver/test_solver_petsc_parallel.sh
@@ -0,0 +1,3 @@
+#! /bin/bash
+
+mpirun -np 4 ./test_solver_petsc -ksp_type preonly -pc_type lu -pc_factor_mat_solver_package mumps -mat_mumps_icntl_7 2
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 33461715c..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
- DEPENDENCIES test_synchronizer_communication_mesh
+ 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
- DEPENDENCIES test_synchronizer_communication_mesh test_grid_synchronizer_check_neighbors
+ 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
- DEPENDENCIES test_synchronizer_communication_mesh
+ 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/MUMPS_4.10.0_make.inc.cmake b/third-party/MUMPS_4.10.0_make.inc.cmake
index 74f85401e..a0fe5bd71 100644
--- a/third-party/MUMPS_4.10.0_make.inc.cmake
+++ b/third-party/MUMPS_4.10.0_make.inc.cmake
@@ -1,84 +1,84 @@
MUMPS_TYPE = @MUMPS_TYPE@
PLAT = @MUMPS_PREFIX@
LIBEXT = @CMAKE_STATIC_LIBRARY_SUFFIX@
SHLIBEXT = @CMAKE_SHARED_LIBRARY_SUFFIX@
OUTC = -o
OUTF = -o
ISCOTCH = -I@SCOTCH_INCLUDE_DIR@
LSCOTCH = @MUMPS_SCOTCH_LIBRARIES@
LPORDDIR = $(topdir)/PORD/lib/
IPORD = -I$(topdir)/PORD/include/
LPORD = -L$(LPORDDIR) -lpord$(PLAT)
ORDERINGSF = -Dpord -Dscotch
ORDERINGSC = $(ORDERINGSF)
LORDERINGS = $(LMETIS) $(LPORD) $(LSCOTCH)
IORDERINGSF = $(ISCOTCH)
IORDERINGSC = $(IMETIS) $(IPORD) $(ISCOTCH)
-RM = @CMAKE_COMMAND@ -E remove -f
-MKDIR = @CMAKE_COMMAND@ -E make_directory
+RM = '@CMAKE_COMMAND@' -E remove -f
+MKDIR = '@CMAKE_COMMAND@' -E make_directory
CP = cp -af
ifeq ($(MUMPS_TYPE),seq)
# CC : C compiler
-CC = @CMAKE_C_COMPILER@
+CC = '@CMAKE_C_COMPILER@'
# FC : Fortran 90 compiler
-FC = @CMAKE_Fortran_COMPILER@
+FC = '@CMAKE_Fortran_COMPILER@'
# FL : Fortran linker
-FL = @CMAKE_Fortran_COMPILER@
+FL = '@CMAKE_Fortran_COMPILER@'
else
# CC : C compiler
-CC = @MPI_C_COMPILER@
+CC = '@MPI_C_COMPILER@'
# FC : Fortran 90 compiler
-FC = @MPI_Fortran_COMPILER@
+FC = '@MPI_Fortran_COMPILER@'
# FL : Fortran linker
-FL = @MPI_Fortran_COMPILER@
+FL = '@MPI_Fortran_COMPILER@'
endif
# AR : Archive object in a library
-AR = @CMAKE_AR@ vr
+AR = '@CMAKE_AR@' vr
# RANLIB : generate index of an archive file
-RANLIB = @CMAKE_RANLIB@
+RANLIB = '@CMAKE_RANLIB@'
# SCALAP should define the SCALAPACK and BLACS libraries.
-SCALAP = @SCALAPACK_LIBRARIES@
+SCALAP = '@SCALAPACK_LIBRARIES@'
INCPAR =
LIBPAR = $(SCALAP)
# The parallel version is not concerned by the next two lines.
# They are related to the sequential library provided by MUMPS,
# to use instead of ScaLAPACK and MPI.
INCSEQ = -I$(topdir)/libseq
LIBSEQ = -L$(topdir)/libseq -lmpiseq$(PLAT)
LIBBLAS = @MUMPS_BLAS_LIBRARIES@
-LIBOTHERS = -lpthread
+LIBOTHERS = @AKANTU_MUMPS_PTHREAD@
# FORTRAN/C COMPATIBILITY:
# Use:
# -DAdd_ if your Fortran compiler adds an underscore at the end
# of symbols,
# -DAdd__ if your Fortran compiler adds 2 underscores,
#
# -DUPPER if your Fortran compiler uses uppercase symbols
#
# leave empty if your Fortran compiler does not change the symbols.
#
-CDEFS = -DAdd_
+CDEFS = @AKANTU_MUMPS_CDEFS@
#COMPILER OPTIONS
OPTF = -O -w -fPIC
OPTC = -O -I. -fPIC
OPTL = -O -fPIC
#Sequential:
ifeq ($(MUMPS_TYPE),seq)
INCS = $(INCSEQ)
LIBS = $(LIBSEQ)
LIBSEQNEEDED = libseqneeded
endif
#Parallel:
ifeq ($(MUMPS_TYPE),par)
INCS = $(INCPAR)
LIBS = $(LIBPAR)
LIBSEQNEEDED =
endif
prefix = ${INSTALL_DIR}
\ No newline at end of file
diff --git a/third-party/MUMPS_4.9.2_make.inc.cmake b/third-party/MUMPS_4.9.2_make.inc.cmake
index 4bd3bfd5d..dad937150 100644
--- a/third-party/MUMPS_4.9.2_make.inc.cmake
+++ b/third-party/MUMPS_4.9.2_make.inc.cmake
@@ -1,162 +1,162 @@
#
# This file is part of MUMPS 4.9.2, built on Thu Nov 5 07:05:08 UTC 2009
#
################################################################################
#
# Makefile.inc.generic
#
# This defines some parameters dependent on your platform; you should
# look for the approriate file in the directory ./Make.inc/ and copy it
# into a file called Makefile.inc. For example, from the MUMPS root
# directory, use
# "cp Make.inc/Makefile.inc.generic ./Makefile.inc"
# (see the main README file for details)
#
# If you do not find any suitable Makefile in Makefile.inc, use this file:
# "cp Make.inc/Makefile.inc.generic ./Makefile.inc" and modify it according
# to the comments given below. If you manage to build MUMPS on a new platform,
# and think that this could be useful to others, you may want to send us
# the corresponding Makefile.inc file.
#
################################################################################
# CHOOSE BETWEEN USING THE SEQUENTIAL OR THE PARALLEL VERSION.
MUMPS_TYPE = @MUMPS_TYPE@
########################################################################
#Begin orderings
#
# NOTE that PORD is distributed within MUMPS by default. If you would like to
# use other orderings, you need to obtain the corresponding package and modify
# the variables below accordingly.
# For example, to have Metis available within MUMPS:
# 1/ download Metis and compile it
# 2/ uncomment (suppress # in first column) lines
# starting with LMETISDIR, LMETIS
# 3/ add -Dmetis in line ORDERINGSF
# ORDERINGSF = -Dpord -Dmetis
# 4/ Compile and install MUMPS
# make clean; make (to clean up previous installation)
#
# Metis/ParMetis and SCOTCH/PT-SCOTCH (ver 5.1 and later) orderings are now available for MUMPS.
#
ISCOTCH = -I@SCOTCH_INCLUDE_DIR@
# You have to choose one among the following two lines depending on
# the type of analysis you want to perform. If you want to perform only
# sequential analysis choose the first (remember to add -Dscotch in the ORDERINGSF
# variable below); for both parallel and sequential analysis choose the second
# line (remember to add -Dptscotch in the ORDERINGSF variable below)
LSCOTCH = @SCOTCH_LIBRARIES@
LPORDDIR = $(topdir)/PORD/lib/
IPORD = -I$(topdir)/PORD/include/
LPORD = -L$(LPORDDIR) -lpord
#LMETISDIR = /local/metis/
#IMETIS = # Metis doesn't need include files (Fortran interface avail.)
# You have to choose one among the following two lines depending on
# the type of analysis you want to perform. If you want to perform only
# sequential analysis choose the first (remember to add -Dmetis in the ORDERINGSF
# variable below); for both parallel and sequential analysis choose the second
# line (remember to add -Dparmetis in the ORDERINGSF variable below)
#LMETIS = -L$(LMETISDIR) -lmetis
#LMETIS = -L$(LMETISDIR) -lparmetis -lmetis
# The following variables will be used in the compilation process.
# Please note that -Dptscotch and -Dparmetis imply -Dscotch and -Dmetis respectively.
#ORDERINGSF = -Dscotch -Dmetis -Dpord -Dptscotch -Dparmetis
ORDERINGSF = -Dpord -Dscotch
ORDERINGSC = $(ORDERINGSF)
LORDERINGS = $(LMETIS) $(LPORD) $(LSCOTCH)
IORDERINGSF = $(ISCOTCH)
IORDERINGSC = $(IMETIS) $(IPORD) $(ISCOTCH)
#End orderings
########################################################################
# DEFINE HERE SOME COMMON COMMANDS, THE COMPILER NAMES, ETC...
# PLAT : use it to add a default suffix to the generated libraries
PLAT = @MUMPS_PREFIX@
# RM : remove files
-RM = @CMAKE_COMMAND@ -E remove -f
+RM = '@CMAKE_COMMAND@' -E remove -f
ifeq ($(MUMPS_TYPE),seq)
# CC : C compiler
-CC = @CMAKE_C_COMPILER@
+CC = '@CMAKE_C_COMPILER@'
# FC : Fortran 90 compiler
-FC = @CMAKE_Fortran_COMPILER@
+FC = '@CMAKE_Fortran_COMPILER@'
# FL : Fortran linker
-FL = @CMAKE_Fortran_COMPILER@
+FL = '@CMAKE_Fortran_COMPILER@'
else
# CC : C compiler
-CC = @MPI_C_COMPILER@
+CC = '@MPI_C_COMPILER@'
# FC : Fortran 90 compiler
-FC = @MPI_Fortran_COMPILER@
+FC = '@MPI_Fortran_COMPILER@'
# FL : Fortran linker
-FL = @MPI_Fortran_COMPILER@
+FL = '@MPI_Fortran_COMPILER@'
endif
# AR : Archive object in a library
-AR = @CMAKE_AR@ vr
+AR = '@CMAKE_AR@' vr
# RANLIB : generate index of an archive file
# (optionnal use "RANLIB = echo" in case of problem)
-RANLIB = @CMAKE_RANLIB@
+RANLIB = '@CMAKE_RANLIB@'
#RANLIB = echo
# SCALAP should define the SCALAPACK and BLACS libraries.
SCALAP = @PROJECT_BINARY_DIR@/third-party/lib/libscalapack.a
# INCLUDE DIRECTORY FOR MPI
INCPAR =
#INCPAR = @MPI_Fortran_COMPILE_FLAGS@ @MUMPS_MPI_INCLUDE_PATH@
# LIBRARIES USED BY THE PARALLEL VERSION OF MUMPS: $(SCALAP) and MPI
#LIBPAR = $(SCALAP) @MPI_Fortran_LINK_FLAGS@ @MUMPS_MPI_Fortran_LIBRARIES@
LIBPAR = $(SCALAP)
# The parallel version is not concerned by the next two lines.
# They are related to the sequential library provided by MUMPS,
# to use instead of ScaLAPACK and MPI.
INCSEQ = -I$(topdir)/libseq
LIBSEQ = -L$(topdir)/libseq -lmpiseq
# DEFINE HERE YOUR BLAS LIBRARY
LIBBLAS = @BLAS_LIBRARIES@
# DEFINE YOUR PTHREAD LIBRARY
-LIBOTHERS = -lpthread
+LIBOTHERS = @AKANTU_MUMPS_PTHREAD@
# FORTRAN/C COMPATIBILITY:
# Use:
# -DAdd_ if your Fortran compiler adds an underscore at the end
# of symbols,
# -DAdd__ if your Fortran compiler adds 2 underscores,
#
# -DUPPER if your Fortran compiler uses uppercase symbols
#
# leave empty if your Fortran compiler does not change the symbols.
#
-CDEFS = -DAdd_
+CDEFS = @AKANTU_MUMPS_CDEFS@
#COMPILER OPTIONS
OPTF = -O -w -fPIC
OPTC = -O -I. -fPIC
OPTL = -O -fPIC
#Sequential:
ifeq ($(MUMPS_TYPE),seq)
INC = $(INCSEQ)
LIB = $(LIBSEQ)
LIBSEQNEEDED = libseqneeded
endif
#Parallel:
ifeq ($(MUMPS_TYPE),par)
INC = $(INCPAR)
LIB = $(LIBPAR)
LIBSEQNEEDED =
endif
diff --git a/third-party/blas_3.5.0_make.inc.cmake b/third-party/blas_3.5.0_make.inc.cmake
new file mode 100644
index 000000000..426e32598
--- /dev/null
+++ b/third-party/blas_3.5.0_make.inc.cmake
@@ -0,0 +1,38 @@
+####################################################################
+# BLAS make include file. #
+# March 2007 #
+####################################################################
+#
+SHELL = @CMAKE_SH@
+#
+# The machine (platform) identifier to append to the library names
+#
+PLAT = _@CMAKE_SYSTEM_NAME@
+#
+# Modify the FORTRAN and OPTS definitions to refer to the
+# compiler and desired compiler options for your machine. NOOPT
+# refers to the compiler options desired when NO OPTIMIZATION is
+# selected. Define LOADER and LOADOPTS to refer to the loader and
+# desired load options for your machine.
+#
+FORTRAN = '@CMAKE_Fortran_COMPILER@'
+OPTS = -O3
+DRVOPTS = $(OPTS)
+NOOPT =
+LOADER = '@CMAKE_Fortran_COMPILER@'
+LOADOPTS =
+#
+# The archiver and the flag(s) to use when building archive (library)
+# If you system has no ranlib, set RANLIB = echo.
+#
+ARCH = '@CMAKE_AR@'
+ARCHFLAGS= cr
+#
+# The location and name of the Reference BLAS library.
+#
+BLASLIB = blas$(PLAT).a
+
+RANLIB = '@CMAKE_Fortran_COMPILER@' @CMAKE_SHARED_LIBRARY_Fortran_FLAGS@ -shared \
+ -o @CMAKE_SHARED_LIBRARY_PREFIX@blas@CMAKE_SHARED_LIBRARY_SUFFIX@ \
+ -Wl,--whole-archive $(BLASLIB) -Wl,--no-whole-archive; \
+ '@CMAKE_COMMAND@' -E echo
diff --git a/third-party/cmake/blackdynamite.cmake b/third-party/cmake/blackdynamite.cmake
index 868a3c6e6..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
- SVN_REPOSITORY ${BLACKDYNAMITE_URL}
+ 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)
-package_set_include_dir(BLACKDYNAMITE_INCLUDE_DIR "${PROJECT_BINARY_DIR}/third-party/include/blackdynamite" CACHE PATH "")
+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
new file mode 100644
index 000000000..600d86c96
--- /dev/null
+++ b/third-party/cmake/blas.cmake
@@ -0,0 +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 b70daa7ca..a1e0d549c 100644
--- a/third-party/cmake/iohelper.cmake
+++ b/third-party/cmake/iohelper.cmake
@@ -1,40 +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
+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)
+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 03fd62c1a..8a2387e7a 100644
--- a/third-party/cmake/mumps.cmake
+++ b/third-party/cmake/mumps.cmake
@@ -1,148 +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_get_option_name(Scotch _scotch_option)
package_use_system(Scotch _scotch_use_system)
-if(NOT _scotch_use_system AND ${_scotch_option})
+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()
-configure_file(${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}_make.inc.cmake
- ${PROJECT_BINARY_DIR}/third-party/MUMPSmake.inc)
-
if(CMAKE_VERSION VERSION_GREATER 3.1)
- set(_extra_options
- UPDATE_DISCONNECTED 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 -p2 < ${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}.patch
- CONFIGURE_COMMAND cmake -E copy ${PROJECT_BINARY_DIR}/third-party/MUMPSmake.inc Makefile.inc
+ 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 prefix=<INSTALL_DIR> ${CMAKE_MAKE_PROGRAM} install
+ 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 62135df54..fe9f5e7ff 100644
--- a/third-party/cmake/scotch.cmake
+++ b/third-party/cmake/scotch.cmake
@@ -1,80 +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 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 (AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
- set (SCOTCH_TIMMING_OPTION -DCOMMON_TIMING_OLD)
+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(SCOTCH_ARCHITECTURE -DIDXSIZE64)
-else()
- set(SCOTCH_ARCHITECTURE)
+ set(_architecture_cflags -DIDXSIZE64)
endif()
math(EXPR _n "${AKANTU_INTEGER_SIZE} * 8")
-set(SCOTCH_NUM_SIZE "-DINTSIZE${_n}")
+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 -p1 < ${PROJECT_SOURCE_DIR}/third-party/scotch_${SCOTCH_VERSION}.patch
- CONFIGURE_COMMAND cmake -E copy ${SCOTCH_DIR}/scotch_make.inc src/Makefile.inc
+ 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)
diff --git a/third-party/scotch_5.1.12b.patch b/third-party/scotch_5.1.12b.patch
index 089d8854a..c18d53ba1 100644
--- a/third-party/scotch_5.1.12b.patch
+++ b/third-party/scotch_5.1.12b.patch
@@ -1,193 +1,193 @@
This patch change the makefiles of scotch to build shared libraries (It is based on the on from debian):
Index: scotch/src/Makefile
===================================================================
--- scotch.orig/src/Makefile
+++ scotch/src/Makefile
@@ -102,10 +102,10 @@
(cd esmumps ; $(MAKE) ptscotch && $(MAKE) ptinstall)
install : required $(bindir) $(includedir) $(libdir) $(mandir)/man1
- -$(CP) -f ../bin/[agm]*$(EXE) $(bindir)
- -$(CP) -f ../include/*scotch*.h $(includedir)
- -$(CP) -f ../lib/*scotch*$(LIB) $(libdir)
- -$(CP) -Rf ../man/* $(mandir)
+ -$(CP) -af ../include/* $(includedir)
+ -$(CP) -af ../bin/* $(bindir)
+ -$(CP) -af ../lib/* $(libdir)
+ -$(CP) -af ../man/* $(mandir)
clean : required
(cd libscotch ; $(MAKE) clean)
Index: scotch/src/libscotchmetis/Makefile
===================================================================
--- scotch.orig/src/libscotchmetis/Makefile
+++ scotch/src/libscotchmetis/Makefile
@@ -61,15 +61,15 @@
libptscotchparmetis$(LIB)
install : scotch
- -$(CP) metis.h $(includedir)
- -$(CP) libscotchmetis$(LIB) $(libdir)
+ $(CP) -a metis.h $(includedir)
+ $(CP) -a libscotchmetis$(LIB) libscotchmetis*$(SHLIB) $(libdir)
ptinstall : ptscotch
- -$(CP) parmetis.h $(includedir)
- -$(CP) libptscotchparmetis$(LIB) $(libdir)
+ $(CP) -a parmetis.h $(includedir)
+ $(CP) -a libptscotchparmetis$(LIB) libptscotchparmetis*$(SHLIB) $(libdir)
clean :
- -$(RM) *~ *$(OBJ) lib*$(LIB)
+ -$(RM) *~ *$(OBJ) lib*$(LIB) lib*$(SHLIB)
realclean : clean
@@ -129,6 +129,7 @@
parmetis_dgraph_order_f$(OBJ) \
parmetis_dgraph_part$(OBJ) \
parmetis_dgraph_part_f$(OBJ)
+ $(CC) -shared $^ -L../libscotch -lptscotch -lscotch -o libptscotchparmetis$(SHLIB)
$(AR) $(ARFLAGS) $(@) $(^)
-$(RANLIB) $(@)
@@ -136,5 +138,6 @@
metis_graph_order_f$(OBJ) \
metis_graph_part$(OBJ) \
metis_graph_part_f$(OBJ)
-+ $(CC) -shared $^ -L../libscotch -lscotch -o libscotchmetis$(SHLIB)
++ $(CC) -shared $^ -L../libscotch -lscotch -lscotcherr -o libscotchmetis$(SHLIB)
$(AR) $(ARFLAGS) $(@) $(^)
-$(RANLIB) $(@)
Index: scotch/src/libscotch/Makefile
===================================================================
--- scotch.orig/src/libscotch/Makefile
+++ scotch/src/libscotch/Makefile
@@ -69,16 +69,16 @@
libptscotcherrexit$(LIB)
install :
- -$(CP) scotch.h scotchf.h $(includedir)
- -$(CP) libscotch$(LIB) libscotcherr*$(LIB) $(libdir)
+ $(CP) -a scotch.h scotchf.h $(includedir)
+ $(CP) -a libscotch*$(LIB) libscotch*$(SHLIB) $(libdir)
ptinstall :
- -$(CP) scotch.h $(includedir)/ptscotch.h
- -$(CP) scotchf.h $(includedir)/ptscotchf.h
- -$(CP) libptscotch*$(LIB) $(libdir)
+ $(CP) -a scotch.h $(includedir)/ptscotch.h
+ $(CP) -a scotchf.h $(includedir)/ptscotchf.h
+ $(CP) -a libptscotch*$(LIB) libptscotch*$(SHLIB) $(libdir)
clean :
- -$(RM) *~ *$(OBJ) lib*$(LIB) parser_yy.c parser_ly.h parser_ll.c *scotch.h *scotchf.h y.output dummysizes$(EXE)
+ -$(RM) *~ *$(OBJ) lib*.a lib*$(SHLIB) lib*$(LIB) parser_yy.c parser_ly.h parser_ll.c *scotch.h *scotchf.h y.output dummysizes$(EXE)
realclean : clean
@@ -2553,26 +2553,32 @@
libraryf.h
./dummysizes$(EXE) libraryf.h scotchf.h
-libptscotch$(LIB) : $(LIBPTSCOTCHDEPS) $(LIBSCOTCHDEPS)
- $(AR) $(ARFLAGS) $(@) $(?)
+libptscotch$(LIB) : $(LIBPTSCOTCHDEPS) $(LIBSCOTCHDEPS) libptscotcherr$(LIB)
-+ $(CC) -shared $(LIBPTSCOTCHDEPS) $(LIBSCOTCHDEPS) -L. -lptscotcherr -lz -lpthread -lm -o libptscotch$(SHLIB)
++ $(CC) -shared $(LIBPTSCOTCHDEPS) $(LIBSCOTCHDEPS) -L. -lptscotcherr $(LDFLAGS) -o libptscotch$(SHLIB)
+ $(AR) $(ARFLAGS) $(@) $(LIBPTSCOTCHDEPS) $(LIBSCOTCHDEPS)
-$(RANLIB) $(@)
-libscotch$(LIB) : $(LIBSCOTCHDEPS)
- $(AR) $(ARFLAGS) $(@) $(?)
+libscotch$(LIB) : $(LIBSCOTCHDEPS) libscotcherr$(LIB)
-+ $(CC) -shared $(LIBSCOTCHDEPS) -L. -lscotcherr -lz -lpthread -lm -o libscotch$(SHLIB)
++ $(CC) -shared $(LIBSCOTCHDEPS) -L. -lscotcherr $(LDFLAGS) -o libscotch$(SHLIB)
+ $(AR) $(ARFLAGS) $(@) $(LIBSCOTCHDEPS)
-$(RANLIB) $(@)
libptscotcherr$(LIB) : library_error$(OBJ)
+ $(CC) -shared $^ -o libptscotcherr$(SHLIB)
$(AR) $(ARFLAGS) $(@) $(?)
-$(RANLIB) $(@)
libptscotcherrexit$(LIB) : library_error_exit$(OBJ)
+ $(CC) -shared $^ -o libptscotcherrexit$(SHLIB)
$(AR) $(ARFLAGS) $(@) $(?)
-$(RANLIB) $(@)
libscotcherr$(LIB) : library_error$(OBJ)
+ $(CC) -shared $^ -o libscotcherr$(SHLIB)
$(AR) $(ARFLAGS) $(@) $(?)
-$(RANLIB) $(@)
libscotcherrexit$(LIB) : library_error_exit$(OBJ)
+ $(CC) -shared $^ -o libscotcherrexit$(SHLIB)
$(AR) $(ARFLAGS) $(@) $(?)
-$(RANLIB) $(@)
Index: scotch/src/esmumps/Makefile
===================================================================
--- scotch.orig/src/esmumps/Makefile
+++ scotch/src/esmumps/Makefile
@@ -44,7 +44,7 @@
$(CC) $(CFLAGS) $(CLIBFLAGS) -I$(includedir) -c $(<) -o $(@)
%$(EXE) : %.c
- $(CC) $(CFLAGS) -I$(includedir) $(<) -o $(@) -L$(libdir) $(LDFLAGS) -L. -l$(ESMUMPSLIB) -l$(SCOTCHLIB) -l$(SCOTCHLIB)errexit
+ $(CC) $(CFLAGS) -I$(includedir) $(<) -o $(@) -L$(libdir) -L. -l$(ESMUMPSLIB) -l$(SCOTCHLIB) -l$(SCOTCHLIB)errexit $(LDFLAGS) -lscotch
##
## Project rules.
@@ -59,19 +59,21 @@
ptscotch : clean
$(MAKE) CFLAGS="$(CFLAGS) -DSCOTCH_PTSCOTCH" CC=$(CCP) SCOTCHLIB=ptscotch ESMUMPSLIB=ptesmumps \
- libesmumps$(LIB) \
+ libptesmumps$(LIB) \
main_esmumps$(EXE)
install :
-$(CP) esmumps.h $(includedir)
- -$(CP) libesmumps$(LIB) $(libdir)
+ -$(CP) -a libesmumps* $(libdir)
+ -$(CP) -a main_esmumps$(EXE) $(bindir)/scotch_esmumps
ptinstall :
-$(CP) esmumps.h $(includedir)
- -$(CP) libptesmumps$(LIB) $(libdir)
+ -$(CP) -a libptesmumps* $(libdir)
+ -$(CP) -a main_esmumps$(EXE) $(bindir)/ptscotch_esmumps
clean :
- -$(RM) *~ common.h *$(OBJ) lib*$(LIB) main_esmumps$(EXE)
+ -$(RM) *~ common.h *$(OBJ) lib*$(LIB) lib*$(SHLIB) main_esmumps$(EXE)
realclean : clean
@@ -142,7 +144,7 @@
common.h \
esmumps.h
-libesmumps$(LIB) : graph_graph$(OBJ) \
+lib$(ESMUMPSLIB)$(LIB) : graph_graph$(OBJ) \
order$(OBJ) \
order_scotch_graph$(OBJ) \
dof$(OBJ) \
@@ -151,6 +153,7 @@
esmumps$(OBJ) \
esmumps_f$(OBJ) \
esmumps_strats$(OBJ)
+ $(CC) -shared $^ -L../libscotch -lscotch -lscotcherr -o lib$(ESMUMPSLIB)$(SHLIB)
$(AR) $(ARFLAGS) lib$(ESMUMPSLIB)$(LIB) $(?)
-$(RANLIB) lib$(ESMUMPSLIB)$(LIB)
Index: scotch/src/scotch/Makefile
===================================================================
--- scotch.orig/src/scotch/Makefile
+++ scotch/src/scotch/Makefile
@@ -47,7 +47,7 @@
$(CC) $(CFLAGS) -I$(includedir) -I../libscotch -c $(<) -o $(@)
%$(EXE) : %.c
- $(CC) $(CFLAGS) -I$(includedir) -I../libscotch $(<) -o $(@) -L$(libdir) -l$(SCOTCHLIB) -l$(SCOTCHLIB)errexit $(LDFLAGS)
+ $(CC) $(CFLAGS) -I$(includedir) -I../libscotch $(<) -o $(@) -L$(libdir) -l$(SCOTCHLIB) -l$(SCOTCHLIB)errexit $(LDFLAGS) -lscotch
##
## Project rules.
diff --git a/third-party/scotch_5.1.12b_make.inc.cmake b/third-party/scotch_5.1.12b_make.inc.cmake
index f4dc2b670..4ccdbc966 100644
--- a/third-party/scotch_5.1.12b_make.inc.cmake
+++ b/third-party/scotch_5.1.12b_make.inc.cmake
@@ -1,22 +1,22 @@
EXE =
LIB = @CMAKE_STATIC_LIBRARY_SUFFIX@
SHLIB = @CMAKE_SHARED_LIBRARY_SUFFIX@
OBJ = @CMAKE_C_OUTPUT_EXTENSION@
-MAKE = @CMAKE_MAKE_PROGRAM@
-AR = @CMAKE_AR@
+MAKE = '@CMAKE_MAKE_PROGRAM@'
+AR = '@CMAKE_AR@'
ARFLAGS = -ruv
CAT = cat
-CCS = @CMAKE_C_COMPILER@
-CCP = @CMAKE_C_COMPILER@
-CCD = @CMAKE_C_COMPILER@
-CFLAGS = -O3 -DCOMMON_FILE_COMPRESS_GZ -DCOMMON_PTHREAD -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_RENAME_PARSER -DSCOTCH_PTHREAD -Drestrict=__restrict @SCOTCH_ARCHITECTURE@ -w -fPIC @SCOTCH_TIMMING_OPTION@ @SCOTCH_NUM_SIZE@
+CCS = '@CMAKE_C_COMPILER@'
+CCP = '@CMAKE_C_COMPILER@'
+CCD = '@CMAKE_C_COMPILER@'
+CFLAGS = @AKANTU_SCOTCH_CFLAGS@
CLIBFLAGS = -fPIC
-LDFLAGS = @ZLIB_LIBRARY@ -lm -lpthread
+LDFLAGS = @AKANTU_SCOTCH_LDFLAGS@
CP = cp
-LEX = @FLEX_EXECUTABLE@ -Pscotchyy -olex.yy.c
-LN = @CMAKE_COMMAND@ -E create_symlink
-MKDIR = @CMAKE_COMMAND@ -E make_directory
-MV = @CMAKE_COMMAND@ -E rename
-RANLIB = @CMAKE_RANLIB@
-YACC = @BISON_EXECUTABLE@ -pscotchyy -y -b y
+LEX = '@FLEX_EXECUTABLE@' -Pscotchyy -olex.yy.c
+LN = '@CMAKE_COMMAND@' -E create_symlink
+MKDIR = '@CMAKE_COMMAND@' -E make_directory
+MV = '@CMAKE_COMMAND@' -E rename
+RANLIB = '@CMAKE_RANLIB@'
+YACC = '@BISON_EXECUTABLE@' -pscotchyy -y -b y

Event Timeline