Page MenuHomec4science

No OneTemporary

File Metadata

Created
Thu, May 30, 22:13
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/.clang-format b/.clang-format
new file mode 100644
index 000000000..467ed8632
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,57 @@
+---
+Language: Cpp
+BasedOnStyle: LLVM
+Standard: Cpp03
+IndentWidth: 2
+TabWidth: 4
+UseTab: Never
+ColumnLimit: 80
+AccessModifierOffset: -2
+PointerAlignment: Middle
+NamespaceIndentation: Inner
+ContinuationIndentWidth: 4
+
+# ConstructorInitializerIndentWidth: 4
+# AlignEscapedNewlinesLeft: false
+# AlignTrailingComments: true
+# AllowAllParametersOfDeclarationOnNextLine: true
+# AllowShortBlocksOnASingleLine: false
+# AllowShortIfStatementsOnASingleLine: false
+# AllowShortLoopsOnASingleLine: false
+# AllowShortFunctionsOnASingleLine: All
+# AlwaysBreakTemplateDeclarations: false
+# AlwaysBreakBeforeMultilineStrings: false
+# BreakBeforeBinaryOperators: false
+# BreakBeforeTernaryOperators: true
+# BreakConstructorInitializersBeforeComma: false
+# BinPackParameters: true
+# ConstructorInitializerAllOnOneLineOrOnePerLine: false
+# DerivePointerAlignment: false
+# ExperimentalAutoDetectBinPacking: false
+# IndentCaseLabels: false
+# IndentWrappedFunctionNames: false
+# IndentFunctionDeclarationAfterType: false
+# MaxEmptyLinesToKeep: 1
+# KeepEmptyLinesAtTheStartOfBlocks: true
+# ObjCSpaceAfterProperty: false
+# ObjCSpaceBeforeProtocolList: true
+# PenaltyBreakBeforeFirstCallParameter: 19
+# PenaltyBreakComment: 300
+# PenaltyBreakString: 1000
+# PenaltyBreakFirstLessLess: 120
+# PenaltyExcessCharacter: 1000000
+# PenaltyReturnTypeOnItsOwnLine: 60
+# SpacesBeforeTrailingComments: 1
+# Cpp11BracedListStyle: true
+# BreakBeforeBraces: Attach
+# SpacesInParentheses: false
+# SpacesInAngles: false
+# SpaceInEmptyParentheses: false
+# SpacesInCStyleCastParentheses: false
+# SpacesInContainerLiterals: true
+# SpaceBeforeAssignmentOperators: true
+# CommentPragmas: '^ IWYU pragma:'
+# ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+# SpaceBeforeParens: ControlStatements
+# DisableFormat: false
+...
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..ecf6dd5cb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +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
new file mode 100644
index 000000000..b371272de
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,18 @@
+[submodule "extra_packages/extra-materials"]
+ path = extra_packages/extra-materials
+ url = git@lsmssrv1.epfl.ch:akantu-extra-materials.git
+[submodule "extra_packages/igfem"]
+ path = extra_packages/igfem
+ url = git@lsmssrv1.epfl.ch:akantu-igfem.git
+[submodule "extra_packages/parallel-cohesive-element"]
+ path = extra_packages/parallel-cohesive-element
+ url = git@lsmssrv1.epfl.ch:akantu-parallel-cohesive.git
+[submodule "extra_packages/traction-at-split-node-contact"]
+ path = extra_packages/traction-at-split-node-contact
+ url = git@lsmssrv1.epfl.ch:akantu-traction-at-split-node-contact.git
+[submodule "extra_packages/students-extra-package"]
+ path = extra_packages/students-extra-package
+ url = git@lsmssrv1.epfl.ch:students-extra-package.git
+[submodule "extra_packages/phase-field"]
+ path = extra_packages/phase-field
+ url = git@lsmssrv1.epfl.ch:akantu-phase-field.git
diff --git a/AUTHORS b/AUTHORS
index 4023cd3ac..0ba040dbf 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,47 +1,48 @@
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/>.
Authors :
- Nicolas Richart <nicolas.richart@epfl.ch>
- Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- Ramin Aghababaei <ramin.aghababaei@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>
- 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>
- Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
- Mathilde Radiguet <mathilde.radiguet@epfl.ch>
- Srinivasa Babu Ramisetti <srinivasa.ramisetti@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>
- Rui Wang <rui.wang@epfl.ch>
- Cyprien Wolff <cyprien.wolff@epfl.ch>
- Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
- Okan Yilmaz <okan.yilmaz@epfl.ch>
+ - Mauro Corrado <mauro.corrado@epfl.ch>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3eb6b972a..109ec76f3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,180 +1,186 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Jun 14 2010
# @date last modification: Mon Sep 15 2014
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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)
+cmake_minimum_required(VERSION 2.8.12)
# add this options before PROJECT keyword
-#set(CMAKE_DISABLE_SOURCE_CHANGES ON)
+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
-#option(AKANTU_DEBUG "Compiles akantu with the debug messages" ON)
-#mark_as_advanced(AKANTU_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")
-# if(NOT AKANTU_DEBUG)
-# set(AKANTU_NDEBUG ON)
-# else()
-# set(AKANTU_NDEBUG OFF)
-# endif()
-
#Profiling
-set(CMAKE_CXX_FLAGS_PROFILING "-g -pg" 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)
-mark_as_advanced(CMAKE_EXE_LINKER_FLAGS_PROFILING)
-mark_as_advanced(CMAKE_SHARED_LINKER_FLAGS_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)
-cmake_deactivate_debug_message(PackagesSystem)
#===============================================================================
# Dependencies
#===============================================================================
-set(AKANTU_BOOST_COMPONENT)
-set(AKANTU_EXTRA_TARGET_DEPENDENCIES)
-add_all_packages(${PROJECT_SOURCE_DIR}/packages ${PROJECT_SOURCE_DIR}/src)
+declare_akantu_types()
-include_boost()
+package_list_packages(${PROJECT_SOURCE_DIR}/packages
+ EXTRA_PACKAGES_FOLDER ${PROJECT_SOURCE_DIR}/extra_packages)
## meta option \todo better way to do it when multiple package give enable the
## same feature
if(AKANTU_SCOTCH)
set(AKANTU_PARTITIONER ON)
else()
set(AKANTU_PARTITIONER OFF)
endif()
if(AKANTU_MUMPS)
set(AKANTU_SOLVER ON)
else()
set(AKANTU_SOLVER OFF)
endif()
#===============================================================================
# Akantu library
#===============================================================================
add_subdirectory(src)
#===============================================================================
# Documentation
#===============================================================================
if(AKANTU_DOCUMENTATION_DOXYGEN OR AKANTU_DOCUMENTATION_MANUAL)
add_subdirectory(doc)
else()
set(AKANTU_DOC_EXCLUDE_FILES "${PROJECT_SOURCE_DIR}/doc/manual" CACHE INTERNAL "")
endif()
#===============================================================================
# Examples and tests
#===============================================================================
option(AKANTU_EXAMPLES "Activate examples" OFF)
option(AKANTU_TESTS "Activate tests" OFF)
+include(AkantuTestsMacros)
+include(AkantuExamplesMacros)
+
if(AKANTU_EXAMPLES OR AKANTU_TESTS)
- include(AkantuTestAndExamples)
+ option(AKANTU_BUILD_ALL_EXAMPLES "Build all examples")
+ option(AKANTU_BUILD_ALL_TESTS "Build all tests")
find_package(GMSH REQUIRED)
endif()
if(AKANTU_EXAMPLES)
add_subdirectory(examples)
endif()
-if(AKANTU_TESTS)
- enable_testing()
- include(CTest)
- mark_as_advanced(BUILD_TESTING)
- set(AKANTU_TESTS_EXCLUDE_FILES "" CACHE INTERNAL "")
- add_subdirectory(test)
-else()
- set(AKANTU_TESTS_EXCLUDE_FILES "${PROJECT_SOURCE_DIR}/test" CACHE INTERNAL "")
-endif()
+add_test_tree(test)
#===============================================================================
# Install and Packaging
#===============================================================================
include(AkantuInstall)
if(NOT AKANTU_DISABLE_CPACK)
include(AkantuCPack)
endif()
+
+#===============================================================================
+# Install and Packaging
+#===============================================================================
+package_is_activated(python_interface _python_act)
+if(_python_act)
+ add_subdirectory(python)
+# add_subdirectory(akantu4py)
+endif()
diff --git a/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/VERSION b/VERSION
index 8bbe6cf74..bb576dbde 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2
+2.3
diff --git a/cmake/AkantuCPack.cmake b/cmake/AkantuCPack.cmake
index 26e420b05..952fbf0f2 100644
--- a/cmake/AkantuCPack.cmake
+++ b/cmake/AkantuCPack.cmake
@@ -1,88 +1,121 @@
#===============================================================================
# @file AkantuCPack.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Wed Oct 17 2012
# @date last modification: Tue May 13 2014
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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")
+if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ set(CPACK_GENERATOR "TGZ")
+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
+ )
+ set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${_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")
+ 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()
+
+if(WIN32 AND MINGW)
+ set(_arch "mingw32")
endif()
+# General configuration
+set(CPACK_PACKAGE_VENDOR "LSMS")
+set(CPACK_PACKAGE_FILE_NAME "${PACKAGE_FILE_NAME}-${AKANTU_VERSION}-${_arch}")
+set(CPACK_PACKAGE_VERSION "${AKANTU_VERSION}")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A multipurpose finite element library, Akantu")
+set(CPACK_PACKAGE_NAME "akantu")
+#set(CMAKE_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/akantu.ico")
+
+# Debian config package
+set(CPACK_DEBIAN_PACKAGE_MAINTAINER "nicolas.richart@epfl.ch, guillaume.anciaux@epfl.ch")
+set(CPACK_DEBIAN_PACKAGE_SECTION "Science")
+set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${_arch}" CACHE STRING "Architecture of akantu's package")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${${_project}_PACKAGE_SYSTEM_DEBIAN_PACKAGE_DEPENDS}")
mark_as_advanced(CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
# RPM package configuration
#set(CPACK_RPM_PACKAGE_REQUIRES "${${_project}_PACKAGE_SYSTEM_DEBIAN_PACKAGE_DEPENDS}")
+# NSIS Windows installer
+#set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/akantu.ico")
+#set(CPACK_NSIS_CONTACT "akantu@akantu.ch")
+#set(CPACK_NSIS_MODIFY_PATH ON)
-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)
-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()
+unset(CPACK_SOURCE_IGNORE_FILES)
+package_get_all_deactivated_packages(_deactivated_packages)
+foreach(_pkg ${_deactivated_packages}})
+ _package_get_filename(${_pkg} _file_name)
+ list(APPEND CPACK_SOURCE_IGNORE_FILES ${_file_name})
+ _package_get_source_files(${_pkg} _srcs _pub_hdrs _priv_hdrs)
+ list(APPEND CPACK_SOURCE_IGNORE_FILES ${_srcs} ${_pub_hdrs} ${_priv_hdrs})
+endforeach()
list(APPEND CPACK_SOURCE_IGNORE_FILES "/.*build.*/;/CVS/;/\\\\.svn/;/\\\\.bzr/;/\\\\.hg/;/\\\\.hgignore;/\\\\.git/;\\\\.swp$;\\\\.#;/#;~")
include(CPack)
diff --git a/cmake/AkantuConfig.cmake.in b/cmake/AkantuConfig.cmake.in
index 85b95cc67..455433c99 100644
--- a/cmake/AkantuConfig.cmake.in
+++ b/cmake/AkantuConfig.cmake.in
@@ -1,63 +1,66 @@
#===============================================================================
# @file AkantuConfig.cmake.in
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date Thu Dec 01 18:00:05 2011
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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")
-else()
+ include(AkantuExamplesMacros)
+ else()
+ # In install tree
set(AKANTU_INCLUDE_DIR "${AKANTU_CMAKE_DIR}/../../include/akantu")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${AKANTU_CMAKE_DIR}/cmake")
+ include(AkantuExamplesMacros)
endif()
include("${AKANTU_CMAKE_DIR}/AkantuLibraryDepends.cmake")
# Dependencies
include("${AKANTU_CMAKE_DIR}/AkantuConfigInclude.cmake")
set(AKANTU_BUILD_TYPE @CMAKE_BUILD_TYPE@)
# find_akantu_dependencies()
set(AKANTU_LIBRARY akantu)
if(AKANTU_HAS_CORE_CXX11)
add_definitions(-std=c++0x)
endif()
list(APPEND AKANTU_LIBRARIES ${AKANTU_LIBRARY} ${AKANTU_EXTRA_LIBRARIES})
list(APPEND AKANTU_INCLUDE_DIR ${AKANTU_EXTRA_INCLUDE_DIR})
# set(AKANTU_VERSION @AKANTU_VERSION@)
# @PACKAGE_INIT@
# set_and_check(AKANTU_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
-# check_required_components(Akantu)
\ No newline at end of file
+# check_required_components(Akantu)
diff --git a/cmake/AkantuExamplesMacros.cmake b/cmake/AkantuExamplesMacros.cmake
new file mode 100644
index 000000000..940a083ed
--- /dev/null
+++ b/cmake/AkantuExamplesMacros.cmake
@@ -0,0 +1,175 @@
+#===============================================================================
+# @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 2b03cbba7..50cb50c72 100644
--- a/cmake/AkantuInstall.cmake
+++ b/cmake/AkantuInstall.cmake
@@ -1,143 +1,137 @@
#===============================================================================
# @file AkantuInstall.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Wed Oct 17 2012
# @date last modification: Fri Sep 19 2014
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
#
#===============================================================================
")
-foreach(_option ${AKANTU_PACKAGE_SYSTEM_PACKAGES_NAMES_LIST_ALL})
- list(FIND AKANTU_OPTION_LIST ${_option_name} _index)
- if (_index EQUAL -1)
- if(NOT "${_option}" STREQUAL "CORE")
- if(NOT AKANTU_${_option})
- set(AKANTU_${_option} OFF)
- endif()
- file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
-set(AKANTU_HAS_${_option} ${AKANTU_${_option}})")
- endif()
- endif()
-endforeach()
+package_get_all_packages(_package_list)
-file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake"
-"
+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)
-set(AKANTU_HAS_PARTITIONER ${AKANTU_PARTITIONER})
-set(AKANTU_HAS_SOLVER ${AKANTU_SOLVER})
-")
+ string(TOUPPER ${_real_name} _real_pkg_name)
-foreach(_option ${AKANTU_OPTION_LIST})
- package_pkg_name(${_option} _pkg_name)
file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
-list(APPEND AKANTU_OPTION_LIST ${_option})
-set(AKANTU_USE_${_option} ${AKANTU_${_option}})")
- if(${_pkg_name}_LIBRARIES)
+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(${_pkg_name}_LIBRARIES ${${_pkg_name}_LIBRARIES})")
+set(AKANTU_${_real_pkg_name}_INCLUDE_DIR ${_incs})
+")
endif()
- if(${_pkg_name}_INCLUDE_DIR)
+
+ _package_get_compile_flags(${_pkg_name} _compile_flags)
+ if(_compile_flags)
file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
-set(${_pkg_name}_INCLUDE_DIR ${${_pkg_name}_INCLUDE_DIR})
+set(AKANTU_${_real_pkg_name}_COMPILE_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})
")
-
# Create the AkantuConfig.cmake and AkantuConfigVersion files
get_filename_component(CONF_REL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}" ABSOLUTE)
configure_file(cmake/AkantuConfig.cmake.in "${PROJECT_BINARY_DIR}/AkantuConfig.cmake" @ONLY)
configure_file(cmake/AkantuConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/AkantuConfigVersion.cmake" @ONLY)
configure_file(cmake/AkantuUse.cmake "${PROJECT_BINARY_DIR}/AkantuUse.cmake" COPYONLY)
# include(CMakePackageConfigHelpers)
# configure_package_config_file(cmake/AkantuConfig.cmake.in ${PROJECT_BINARY_DIR}/AkantuConfig.cmake
# INSTALL_DESTINATION "${CONF_REL_INCLUDE_DIR}lib/akantu/cmake"
# PATH_VARS "${CONF_REL_INCLUDE_DIR}/include" )
# write_basic_package_version_file(${PROJECT_BINARY_DIR}/AkantuConfigVersion.cmake
# VERSION "${AKANTU_VERSION}"
# COMPATIBILITY SameMajorVersion)
# Install the export set for use with the install-tree
install(FILES ${PROJECT_BINARY_DIR}/AkantuConfig.cmake
${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake
${PROJECT_BINARY_DIR}/AkantuConfigVersion.cmake
${PROJECT_SOURCE_DIR}/cmake/AkantuUse.cmake
DESTINATION lib/akantu
COMPONENT dev)
install(FILES
${PROJECT_SOURCE_DIR}/cmake/Modules/FindIOHelper.cmake
${PROJECT_SOURCE_DIR}/cmake/Modules/FindQVIEW.cmake
${PROJECT_SOURCE_DIR}/cmake/Modules/FindMumps.cmake
${PROJECT_SOURCE_DIR}/cmake/Modules/FindScotch.cmake
${PROJECT_SOURCE_DIR}/cmake/Modules/FindGMSH.cmake
DESTINATION lib/akantu/cmake
COMPONENT dev)
diff --git a/cmake/AkantuMacros.cmake b/cmake/AkantuMacros.cmake
index ef296e420..822184445 100644
--- a/cmake/AkantuMacros.cmake
+++ b/cmake/AkantuMacros.cmake
@@ -1,168 +1,345 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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(check_for_isnan result)
- include(CheckFunctionExists)
- check_function_exists(std::isnan HAVE_STD_ISNAN)
- if(HAVE_STD_ISNAN)
- set(result "std::isnan(x)")
- else()
- check_function_exists(isnan HAVE_ISNAN)
- if(HAVE_ISNAN)
- set(result "(::isnan(x))")
- else()
- check_function_exists(_isnan HAVE_ISNAN_MATH_H)
- if(HAVE_ISNAN_MATH_H)
- set(result "(_isnan(x))")
+#===============================================================================
+function(set_third_party_shared_libirary_name _var _lib)
+ set(${_var}
+ ${PROJECT_BINARY_DIR}/third-party/lib/${CMAKE_SHARED_LIBRARY_PREFIX}${_lib}${CMAKE_SHARED_LIBRARY_SUFFIX}
+ CACHE FILEPATH "" FORCE)
+endfunction()
+
+#===============================================================================
+# Generate the list of currently loaded materials
+function(generate_material_list)
+ message(STATUS "Determining the list of recognized materials...")
+
+ package_get_all_include_directories(
+ AKANTU_LIBRARY_INCLUDE_DIRS
+ )
+
+ package_get_all_external_informations(
+ AKANTU_EXTERNAL_INCLUDE_DIR
+ AKANTU_EXTERNAL_LIBRARIES
+ )
+
+ set(_include_dirs ${AKANTU_INCLUDE_DIRS} ${AKANTU_EXTERNAL_INCLUDE_DIR})
+
+ try_run(_material_list_run _material_list_compile
+ ${CMAKE_BINARY_DIR}
+ ${PROJECT_SOURCE_DIR}/cmake/material_lister.cc
+ CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${_include_dirs}"
+ COMPILE_DEFINITIONS "-DAKANTU_CMAKE_LIST_MATERIALS"
+ COMPILE_OUTPUT_VARIABLE _compile_results
+ RUN_OUTPUT_VARIABLE _result_material_list)
+
+ if(_material_list_compile AND "${_material_list_run}" EQUAL 0)
+ message(STATUS "Materials included in Akantu:")
+ string(REPLACE "\n" ";" _material_list "${_result_material_list}")
+ foreach(_mat ${_material_list})
+ string(REPLACE ":" ";" _mat_key "${_mat}")
+ list(GET _mat_key 0 _key)
+ list(GET _mat_key 1 _class)
+ list(LENGTH _mat_key _l)
+
+ if("${_l}" GREATER 2)
+ list(REMOVE_AT _mat_key 0 1)
+ set(_opt " -- options: [")
+ foreach(_o ${_mat_key})
+ set(_opt "${_opt} ${_o}")
+ endforeach()
+ set(_opt "${_opt} ]")
else()
- set(result (x == std::numeric_limits<Real>::quiet_NAN()))
+ set(_opt "")
endif()
- endif()
+
+ message(STATUS " ${_class} -- key: ${_key}${_opt}")
+ endforeach()
+ else()
+ message(STATUS "Could not determine the list of materials.")
+ message("${_compile_results}")
endif()
-endmacro()
+endfunction()
#===============================================================================
-macro(copy_files target_depend)
- foreach(_file ${ARGN})
- set(_target ${CMAKE_CURRENT_BINARY_DIR}/${_file})
- set(_source ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
- add_custom_command(
- OUTPUT ${_target}
- COMMAND ${CMAKE_COMMAND} -E copy_if_different ${_source} ${_target}
- DEPENDS ${_source}
- )
- set(_target_name ${target_depend}_${_file})
- add_custom_target(${_target_name} DEPENDS ${_target})
- add_dependencies(${target_depend} ${_target_name})
- endforeach()
-endmacro()
+# Declare the options for the types and defines the approriate typedefs
+function(declare_akantu_types)
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag (-std=c++0x HAVE_CPP_0X)
-#===============================================================================
-macro(add_akantu_definitions)
- foreach(_definition ${AKANTU_DEFINITIONS})
- add_definitions(-D${_definition})
- endforeach()
-endmacro()
+ unset(_cpp_11_flag)
+ if(HAVE_CPP_0X)
+ set(_cpp_11_flag "-std=c++0x")
+ else()
+ check_cxx_compiler_flag (-std=c++11 HAVE_CPP_11)
+ if(HAVE_CPP_11)
+ set(_cpp_11_flag "-std=c++11")
+ endif()
+ endif()
+
+ set(AKANTU_CXX11_FLAGS "${_cpp_11_flag}" CACHE INTERNAL "")
+
+ set(AKANTU_TYPE_FLOAT "double (64bit)" CACHE STRING "Precision force floating point types")
+ mark_as_advanced(AKANTU_TYPE_FLOAT)
+ set_property(CACHE AKANTU_TYPE_FLOAT PROPERTY STRINGS
+ "quadruple (128bit)"
+ "double (64bit)"
+ "float (32bit)"
+ )
+ set(AKANTU_TYPE_INTEGER "int (32bit)" CACHE STRING "Size of the integer types")
+ mark_as_advanced(AKANTU_TYPE_INTEGER)
+ set_property(CACHE AKANTU_TYPE_INTEGER PROPERTY STRINGS
+ "int (32bit)"
+ "long int (64bit)"
+ )
-macro(include_boost)
- set(Boost_LIBRARIES)
- find_package(Boost REQUIRED)
- mark_as_advanced(Boost_DIR)
- if(Boost_FOUND)
- list(APPEND AKANTU_EXTERNAL_LIB_INCLUDE_DIR ${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIR})
+ 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()
- message(STATUS "Looking for Boost liraries")
- set(AKANTU_BOOST_COMPONENT_ALREADY_DONE)
- foreach(_comp ${AKANTU_BOOST_COMPONENTS})
- list(FIND AKANTU_BOOST_COMPONENT_ALREADY_DONE ${_comp} _res)
- if(_res EQUAL -1)
- find_package(Boost COMPONENTS ${_comp} QUIET)
- string(TOUPPER ${_comp} _u_comp)
- if(Boost_${_u_comp}_FOUND)
- message(STATUS " ${_comp}: FOUND")
- set(AKANTU_BOOST_${_u_comp} TRUE CACHE INTERNAL "" FORCE)
- list(APPEND Boost_LIBRARIES ${Boost_${_u_comp}_LIBRARY})
- list(APPEND AKANTU_EXTERNAL_LIBRARIES ${Boost_${_u_comp}_LIBRARY})
+
+ 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()
- message(STATUS " ${_comp}: NOT FOUND")
+ 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()
- list(APPEND AKANTU_BOOST_COMPONENT_ALREADY_DONE ${_comp})
endif()
- endforeach()
-endmacro()
+ else()
+ message(FATAL_ERROR "The integer type is not defined")
+ endif()
-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)
+ # ----------------------------------------------------------------------------
+ # unordered map type
+ # ----------------------------------------------------------------------------
+ check_include_file_cxx(unordered_map HAVE_UNORDERED_MAP)
+ set(AKANTU_UNORDERED_MAP_IS_CXX11 TRUE CACHE INTERNAL "")
+ if(HAVE_UNORDERED_MAP)
+ list(APPEND _extra_includes unordered_map)
+ set(AKANTU_UNORDERED_MAP_TYPE "std::unordered_map" CACHE INTERNAL "")
+ set(AKANTU_UNORDERED_MAP_NAMESPACE_BEGIN "namespace std {" CACHE INTERNAL "")
+ set(AKANTU_UNORDERED_MAP_NAMESPACE_END "}" CACHE INTERNAL "")
+ else()
+ check_include_file_cxx(tr1/unordered_map HAVE_TR1_UNORDERED_MAP)
+ if(HAVE_TR1_UNORDERED_MAP)
+ list(APPEND _extra_includes tr1/unordered_map)
+ set(AKANTU_UNORDERED_MAP_TYPE "std::tr1::unordered_map" CACHE INTERNAL "")
+ set(AKANTU_UNORDERED_MAP_NAMESPACE_BEGIN "namespace std { namespace tr1 {" CACHE INTERNAL "")
+ set(AKANTU_UNORDERED_MAP_NAMESPACE_END "}}" CACHE INTERNAL "")
+ else()
+ list(APPEND _extra_includes map)
+ set(AKANTU_UNORDERED_MAP_TYPE "std::map" CACHE INTERNAL "")
+ set(AKANTU_UNORDERED_MAP_IS_CXX11 FALSE CACHE INTERNAL "")
+ endif()
+ endif()
+
+ # ----------------------------------------------------------------------------
+ # hash function
+ # ----------------------------------------------------------------------------
+ unset(AKANTU_HASH_TYPE CACHE)
+ check_include_file_cxx(functional HAVE_FUNCTIONAL)
+ set(AKANTU_HASH_IS_CXX11 TRUE CACHE INTERNAL "")
+ if(HAVE_FUNCTIONAL AND AKANTU_CXX11_FLAGS)
+ list(APPEND _extra_includes functional)
+ check_cxx_source_compiles("
+#include <functional>
+template<class T>
+std::size_t hash(const T & t) {
+ typedef typename std::hash<T> hash_type;
+ return hash_type()(t);
+};
+
+int main() { return 0; }
+" HAVE_HASH)
+ if(HAVE_HASH)
+ set(AKANTU_HASH_TYPE "std::hash" CACHE INTERNAL "")
+ endif()
+ endif()
+
+ if(NOT AKANTU_HASH_TYPE)
+ check_include_file_cxx(tr1/functional HAVE_TR1_HASH)
+ if(HAVE_TR1_HASH)
+ list(APPEND _extra_includes tr1/functional)
+ set(AKANTU_HASH_TYPE "std::tr1::hash" CACHE INTERNAL "")
+ else()
+ check_include_file_cxx(boost/functional/hash.hpp HAVE_BOOST_HASH)
+ list(APPEND _extra_includes boost/functional/hash.hpp)
+ set(AKANTU_HASH_TYPE "boost::hash" CACHE INTERNAL "")
+ set(AKANTU_HASH_IS_CXX11 FALSE CACHE INTERNAL "")
+ endif()
+ endif()
+
+
+ # ----------------------------------------------------------------------------
+ # includes
+ # ----------------------------------------------------------------------------
+ foreach(_inc ${_extra_includes})
+ set(_incs "#include <${_inc}>\n${_incs}")
+ endforeach()
+ set(AKANTU_TYPES_EXTRA_INCLUDES ${_incs} CACHE INTERNAL "")
endfunction()
+
#===============================================================================
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
return()
endif()
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
# first set all result variables to empty/FALSE
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
set(${prefix}_${arg_name})
endforeach(arg_name)
foreach(option ${_optionNames})
set(${prefix}_${option} FALSE)
endforeach(option)
set(${prefix}_UNPARSED_ARGUMENTS)
set(insideValues FALSE)
set(currentArgName)
# now iterate over all arguments and fill the result variables
foreach(currentArg ${ARGN})
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
if(insideValues)
if("${insideValues}" STREQUAL "SINGLE")
set(${prefix}_${currentArgName} ${currentArg})
set(insideValues FALSE)
elseif("${insideValues}" STREQUAL "MULTI")
list(APPEND ${prefix}_${currentArgName} ${currentArg})
endif()
else(insideValues)
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
endif(insideValues)
else()
if(NOT ${optionIndex} EQUAL -1)
set(${prefix}_${currentArg} TRUE)
set(insideValues FALSE)
elseif(NOT ${singleArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "SINGLE")
elseif(NOT ${multiArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "MULTI")
endif()
endif()
endforeach(currentArg)
# propagate the result variables to the caller:
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
endforeach(arg_name)
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)
diff --git a/cmake/AkantuPackagesSystem.cmake b/cmake/AkantuPackagesSystem.cmake
new file mode 100644
index 000000000..40ad2d43b
--- /dev/null
+++ b/cmake/AkantuPackagesSystem.cmake
@@ -0,0 +1,283 @@
+#===============================================================================
+# @file CMakePackagesSystem.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+#===============================================================================
+# Element Types
+#===============================================================================
+#-------------------------------------------------------------------------------
+function(package_declare_elements pkg)
+ set(_options
+ KIND
+ ELEMENT_TYPES
+ GEOMETRICAL_TYPES
+ INTERPOLATION_TYPES
+ GEOMETRICAL_SHAPES
+ GAUSS_INTEGRATION_TYPES
+ INTERPOLATION_TYPES
+ INTERPOLATION_KIND
+ FE_ENGINE_LISTS
+ )
+
+ cmake_parse_arguments(_opt_pkg
+ ""
+ ""
+ "${_options}"
+ ${ARGN})
+
+ foreach(_opt ${_options})
+ if(_opt_pkg_${_opt})
+ package_set_variable(ET_${_opt} ${pkg} ${_opt_pkg_${_opt}})
+ endif()
+ endforeach()
+endfunction()
+
+#-------------------------------------------------------------------------------
+function(_transfer_list_to_enum types enum)
+ if(${enum})
+ set(_enum_tmp ${${enum}})
+ else()
+ unset(_enum_tmp)
+ endif()
+
+ foreach(_type ${${types}})
+ # defining the types for the enum
+ if(DEFINED _enum_tmp)
+ set(_enum_tmp "${_enum_tmp}
+ ${_type},")
+ else()
+ set(_enum_tmp "${_type},")
+ endif()
+ endforeach()
+
+ set(${enum} ${_enum_tmp} PARENT_SCOPE)
+endfunction()
+
+
+#-------------------------------------------------------------------------------
+function(_transfer_list_to_boost_seq types boost_seq)
+ if(${boost_seq})
+ set(_boost_seq_tmp ${${boost_seq}})
+ endif()
+
+ foreach(_type ${${types}})
+ if(DEFINED _boost_seq_tmp)
+ set(_boost_seq_tmp "${_boost_seq_tmp}${_tabs}\\
+ (${_type})")
+ else()
+ set(_boost_seq_tmp " (${_type})")
+ endif()
+
+ string(LENGTH "${_type}" _length)
+ if(_length LESS 13)
+ set(_tabs "\t\t\t\t")
+ elseif(_length LESS 28)
+ set(_tabs "\t\t\t")
+ else()
+ set(_tabs "\t\t")
+ endif()
+ endforeach()
+
+ set(${boost_seq} ${_boost_seq_tmp} PARENT_SCOPE)
+endfunction()
+
+#-------------------------------------------------------------------------------
+function(package_get_element_lists)
+ package_get_all_activated_packages(_activated_list)
+
+ set(_lists
+ KIND
+ ELEMENT_TYPES
+ GEOMETRICAL_TYPES
+ INTERPOLATION_TYPES
+ GEOMETRICAL_SHAPES
+ GAUSS_INTEGRATION_TYPES
+ INTERPOLATION_TYPES
+ INTERPOLATION_KIND
+ FE_ENGINE_LISTS
+ )
+
+ set(_element_kind "#define AKANTU_ELEMENT_KIND")
+ set(_all_element_types "#define AKANTU_ALL_ELEMENT_TYPE\t")
+
+ set(_inter_types_boost_seq "#define AKANTU_INTERPOLATION_TYPES\t\t")
+
+ foreach(_pkg_name ${_activated_list})
+ foreach(_list ${_lists})
+ string(TOLOWER "${_list}" _l_list)
+ _package_get_variable(ET_${_list} ${_pkg_name} _${_l_list})
+ _transfer_list_to_enum(_${_l_list} _${_l_list}_enum)
+ endforeach()
+
+ if(_interpolation_types)
+ _transfer_list_to_boost_seq(_interpolation_types _inter_types_boost_seq)
+ endif()
+
+ if(_kind)
+ string(TOUPPER "${_kind}" _u_kind)
+ if(_element_types)
+ set(_boosted_element_types "${_boosted_element_types}
+#define AKANTU_ek_${_kind}_ELEMENT_TYPE\t")
+ _transfer_list_to_boost_seq(_element_types _boosted_element_types)
+ set(_boosted_element_types "${_boosted_element_types}\n")
+
+ # defininf the kinds variables
+ set(_element_kinds "${_element_kinds}
+#define AKANTU_${_u_kind}_KIND\t(_ek_${_kind})")
+
+ # defining the full list of element
+ set(_all_element_types "${_all_element_types}\t\\
+ AKANTU_ek_${_kind}_ELEMENT_TYPE")
+ endif()
+
+ # defining the full list of kinds
+ set(_element_kind "${_element_kind}${_kind_tabs}\t\t\\
+ AKANTU_${_u_kind}_KIND")
+ set(_kind_tabs "\t")
+
+ # defining the macros
+ set(_boost_macros "${_boost_macros}
+#define AKANTU_BOOST_${_u_kind}_ELEMENT_SWITCH(macro) \\
+ AKANTU_BOOST_ELEMENT_SWITCH(macro, \\
+ AKANTU_ek_${_kind}_ELEMENT_TYPE)
+
+#define AKANTU_BOOST_${_u_kind}_ELEMENT_LIST(macro) \\
+ AKANTU_BOOST_APPLY_ON_LIST(macro, \\
+ AKANTU_ek_${_kind}_ELEMENT_TYPE)
+")
+
+ list(APPEND _aka_fe_lists ${_fe_engine_lists})
+ foreach(_fe_engine_list ${_fe_engine_lists})
+ if(NOT DEFINED _fe_engine_list_${_fe_engine_list})
+ string(TOUPPER "${_fe_engine_list}" _u_list)
+ string(LENGTH "#define AKANTU_FE_ENGINE_LIST_${_u_list}" _length)
+ math(EXPR _length "72 - ${_length}")
+ set(_space "")
+ while(_length GREATER 0)
+ if(CMAKE_VERSION VERSION_GREATER 3.0)
+ string(CONCAT _space "${_space}" " ")
+ else()
+ set(_space "${_space} ")
+ endif()
+ math(EXPR _length "${_length} - 1")
+ endwhile()
+
+ set(_fe_engine_list_${_fe_engine_list}
+ "#define AKANTU_FE_ENGINE_LIST_${_u_list}${_space}\\
+ AKANTU_GENERATE_KIND_LIST((_ek_${_kind})")
+ else()
+ set(_fe_engine_list_${_fe_engine_list}
+ "${_fe_engine_list_${_fe_engine_list}}\t\t\t\t\\
+ (_ek_${_kind})")
+ endif()
+ endforeach()
+ endif()
+ endforeach()
+
+ if(_aka_fe_lists)
+ list(REMOVE_DUPLICATES _aka_fe_lists)
+ foreach(_fe_list ${_aka_fe_lists})
+ set(_aka_fe_defines "${_fe_engine_list_${_fe_list}})\n${_aka_fe_defines}")
+ endforeach()
+ endif()
+
+# package_get_all_deactivated_packages(_deactivated_list)
+# foreach(_pkg_name ${_deactivated_list})
+# _package_get_variable(ET_KIND ${_pkg_name} _kind)
+# if(_kind)
+# string(TOUPPER "${_kind}" _u_kind)
+# set(_element_kinds "${_element_kinds}
+# #define AKANTU_${_u_kind}_KIND")
+# endif()
+# endforeach()
+
+ foreach(_list ${_lists})
+ string(TOLOWER "${_list}" _l_list)
+ set(AKANTU_${_list}_ENUM ${_${_l_list}_enum} PARENT_SCOPE)
+ endforeach()
+
+ set(AKANTU_INTERPOLATION_TYPES_BOOST_SEQ ${_inter_types_boost_seq} PARENT_SCOPE)
+ set(AKANTU_ELEMENT_TYPES_BOOST_SEQ ${_boosted_element_types} PARENT_SCOPE)
+ set(AKANTU_ELEMENT_KINDS_BOOST_SEQ ${_element_kinds} PARENT_SCOPE)
+ set(AKANTU_ELEMENT_KIND_BOOST_SEQ ${_element_kind} PARENT_SCOPE)
+ set(AKANTU_ALL_ELEMENT_BOOST_SEQ ${_all_element_types} PARENT_SCOPE)
+ set(AKANTU_ELEMENT_KINDS_BOOST_MACROS ${_boost_macros} PARENT_SCOPE)
+ set(AKANTU_FE_ENGINE_LISTS ${_aka_fe_defines} PARENT_SCOPE)
+endfunction()
+
+#-------------------------------------------------------------------------------
+function(package_get_element_types pkg list)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_variable(ET_ELEMENT_TYPES ${_pkg_name} _tmp_list)
+ set(${list} ${_tmp_list} PARENT_SCOPE)
+endfunction()
+
+#===============================================================================
+# Material specific
+#===============================================================================
+#-------------------------------------------------------------------------------
+function(package_declare_material_infos pkg)
+ cmake_parse_arguments(_opt_pkg
+ ""
+ ""
+ "LIST;INCLUDE"
+ ${ARGN})
+
+ package_set_variable(MATERIAL_LIST ${pkg} ${_opt_pkg_LIST})
+ package_set_variable(MATERIAL_INCLUDE ${pkg} ${_opt_pkg_INCLUDE})
+endfunction()
+
+#-------------------------------------------------------------------------------
+function(package_get_all_material_includes includes)
+ _package_get_variable_for_activated(MATERIAL_INCLUDE _includes)
+
+ foreach(_mat_inc ${_includes})
+ if(DEFINED _mat_includes)
+ set(_mat_includes "${_mat_includes}\n#include \"${_mat_inc}\"")
+ else()
+ set(_mat_includes "#include \"${_mat_inc}\"")
+ endif()
+ endforeach()
+
+ set(${includes} ${_mat_includes} PARENT_SCOPE)
+endfunction()
+
+#-------------------------------------------------------------------------------
+function(package_get_all_material_lists lists)
+ _package_get_variable_for_activated(MATERIAL_LIST _lists)
+
+ foreach(_mat_list ${_lists})
+ if(DEFINED _mat_lists)
+ set(_mat_lists "${_mat_lists}\n ${_mat_list}\t\t\t\\")
+ else()
+ set(_mat_lists " ${_mat_list}\t\t\t\\")
+ endif()
+ endforeach()
+
+ set(${lists} ${_mat_lists} PARENT_SCOPE)
+endfunction()
+
+#-------------------------------------------------------------------------------
diff --git a/cmake/AkantuTestAndExamples.cmake b/cmake/AkantuTestAndExamples.cmake
deleted file mode 100644
index d22919e33..000000000
--- a/cmake/AkantuTestAndExamples.cmake
+++ /dev/null
@@ -1,257 +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 tests and 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
-#
-#===============================================================================
-
-set(AKANTU_DIFF_SCRIPT ${AKANTU_CMAKE_DIR}/akantu_diff.sh)
-
-#===============================================================================
-function(manage_test_and_example et_name desc build_all label)
- string(TOUPPER ${et_name} upper_name)
-
- cmake_parse_arguments(manage_test_and_example
- ""
- "PACKAGE"
- ""
- ${ARGN}
- )
-
- set(_activated ON)
- if(manage_test_and_example_PACKAGE)
- list(FIND ${_project}_PACKAGE_SYSTEM_PACKAGES_ON ${manage_test_and_example_PACKAGE} _ret)
- if(_ret EQUAL -1)
- set(_activated OFF)
- 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 "")
- endif()
- endif()
-
- if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${et_name} AND _activated)
-# message("Example or test ${et_name} not present")
- return()
- endif()
-
- option(AKANTU_BUILD${label}${upper_name} "${desc}")
- mark_as_advanced(AKANTU_BUILD_${upper_name})
-
- if(${build_all} OR NOT _activated)
- set(AKANTU_BUILD${label}${upper_name}_OLD
- ${AKANTU_BUILD${label}${upper_name}}
- CACHE INTERNAL "${desc}" FORCE)
-
- set(AKANTU_BUILD${label}${upper_name} ${_activated}
- CACHE INTERNAL "${desc}" FORCE)
- else()
- if(DEFINED AKANTU_BUILD${label}${upper_name}_OLD)
- set(AKANTU_BUILD${label}${upper_name}
- ${AKANTU_BUILD${label}${upper_name}_OLD}
- CACHE BOOL "${desc}" FORCE)
-
- unset(AKANTU_BUILD${label}${upper_name}_OLD
- CACHE)
- endif(DEFINED AKANTU_BUILD${label}${upper_name}_OLD)
- endif()
-
- if(AKANTU_BUILD${label}${upper_name})
- add_subdirectory(${et_name})
- endif(AKANTU_BUILD${label}${upper_name})
-endfunction()
-
-#===============================================================================
-# Tests
-#===============================================================================
-if(AKANTU_TESTS)
- option(AKANTU_BUILD_ALL_TESTS "Build all tests")
-# mark_as_advanced(AKANTU_BUILD_ALL_TESTS)
-endif(AKANTU_TESTS)
-
-#===============================================================================
-macro(register_test_old test_name)
- add_executable(${test_name} ${ARGN})
- target_link_libraries(${test_name} akantu ${AKANTU_EXTERNAL_LIBRARIES})
-
- if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh)
- file(COPY ${test_name}.sh DESTINATION .)
- endif()
-
- if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.sh)
- add_test(${test_name} ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.sh)
- elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified)
- add_test(${test_name} ${AKANTU_DIFF_SCRIPT} ${test_name} ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified)
- else()
- add_test(${test_name} ${CMAKE_CURRENT_BINARY_DIR}/${test_name})
- endif()
-endmacro()
-
-#===============================================================================
-macro(add_akantu_test test_name desc)
- manage_test_and_example(${test_name} ${desc} AKANTU_BUILD_ALL_TESTS _ ${ARGN})
-endmacro()
-
-
-#===============================================================================
-# Examples
-#===============================================================================
-if(AKANTU_EXAMPLES)
- option(AKANTU_BUILD_ALL_EXAMPLES "Build all examples")
-# mark_as_advanced(AKANTU_BUILD_ALL_EXAMPLES)
-endif(AKANTU_EXAMPLES)
-
-#===============================================================================
-macro(register_example example_name)
- add_executable(${example_name} ${ARGN})
- target_link_libraries(${example_name} akantu ${AKANTU_EXTERNAL_LIBRARIES})
-endmacro()
-
-#===============================================================================
-macro(add_example example_name desc)
- manage_test_and_example(${example_name} ${desc} AKANTU_BUILD_ALL_EXAMPLES _EXAMPLE_ ${ARGN})
-endmacro()
-
-#===============================================================================
-function(register_test test_name)
- set(multi_variables
- SOURCES FILES_TO_COPY DEPENDENCIES DIRECTORIES_TO_CREATE COMPILE_OPTIONS EXTRA_FILES
- )
-
- cmake_parse_arguments(register_test
- ""
- "PACKAGE"
- "${multi_variables}"
- ${ARGN}
- )
-
- # add the test in a package if needed
- set(_test_define_package 0)
- set(_package_name AKANTU_CORE)
- if(register_test_PACKAGE)
- package_pkg_name(${register_test_PACKAGE} _package_name)
- set(_test_define_package 1)
- list(FIND ${_package_name}_TESTS ${test_name} _ret)
- if(_ret EQUAL -1)
- list(APPEND ${_package_name}_TESTS ${test_name})
- endif()
- endif()
-
- # check if the test should be activated
- set(_activate_test 0)
- foreach(_pkg ${${_project}_PACKAGE_SYSTEM_PACKAGES_ON})
- package_pkg_name(${_pkg} _package_name)
- list(FIND ${_package_name}_TESTS ${test_name} _ret)
- if(NOT _ret EQUAL -1)
- set(_activate_test 1)
- endif()
- endforeach()
-
- # check if the package is registered in at least a package
- set(_present_in_packages 0)
- foreach(_pkg ${${_project}_PACKAGE_SYSTEM_PACKAGES_NAMES_LIST_ALL})
- package_pkg_name(${_pkg} _package_name)
- list(FIND ${_package_name}_TESTS ${test_name} _ret)
- if(NOT _ret EQUAL -1)
- set(_present_in_packages 1)
- endif()
- endforeach()
-
- if(NOT _present_in_packages AND NOT _test_define_package)
- message("The test ${test_name} is not registered in any packages")
- endif()
-
- if(_activate_test)
- set(_source_file)
- foreach(_file ${register_test_SOURCES} ${register_test_UNPARSED_ARGUMENTS} ${register_test_EXTRA_FILES})
- if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
- list(APPEND _source_file ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
- else()
- message("The file \"${_file}\" registred by the test \"${test_name}\" does not exists")
- endif()
- endforeach()
-
- add_executable(${test_name} ${register_test_SOURCES} ${register_test_UNPARSED_ARGUMENTS})
- set_property(TARGET ${test_name} APPEND
- PROPERTY INCLUDE_DIRECTORIES ${AKANTU_INCLUDE_DIRS} ${AKANTU_EXTERNAL_LIB_INCLUDE_DIR})
- target_link_libraries(${test_name} akantu ${AKANTU_EXTERNAL_LIBRARIES})
-
- if(register_test_COMPILE_OPTIONS)
- set_target_properties(${test_name}
- PROPERTIES COMPILE_DEFINITIONS "${register_test_COMPILE_OPTIONS}")
- endif()
-
- if(register_test_FILES_TO_COPY)
- foreach(_file ${register_test_FILES_TO_COPY})
- file(COPY ${_file} DESTINATION .)
- list(APPEND _source_file ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
- endforeach()
- endif()
-
- if(register_test_DIRECTORIES_TO_CREATE)
- foreach(_dir ${register_test_DIRECTORIES_TO_CREATE})
- if(IS_ABSOLUTE ${dir})
- file(MAKE_DIRECTORY ${_dir})
- else()
- file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir})
- endif()
- endforeach()
- endif()
-
- foreach(_dep ${register_test_DEPENDENCIES})
- add_dependencies(${test_name} ${_dep})
- get_target_property(_dep_in_ressources ${_dep} RESSOURCES)
- if(_dep_in_ressources)
- list(APPEND _source_file ${_dep_in_ressources})
- endif()
- endforeach()
-
- if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh)
- file(COPY ${test_name}.sh DESTINATION .)
- list(APPEND _source_file ${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 _source_file ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified)
- add_test(${test_name}_run ${AKANTU_DIFF_SCRIPT} ${test_name} ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified)
- else()
- add_test(${test_name}_run ${CMAKE_CURRENT_BINARY_DIR}/${test_name})
- endif()
-
- set_tests_properties(${test_name}_run PROPERTIES DEPENDS ${test_name})
-
- 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 "")
- set(${_package_name}_TESTS_FILES ${_pkg_tmp} CACHE INTERNAL "")
- endif()
-endfunction()
\ No newline at end of file
diff --git a/cmake/AkantuTestsMacros.cmake b/cmake/AkantuTestsMacros.cmake
new file mode 100644
index 000000000..7f3edb406
--- /dev/null
+++ b/cmake/AkantuTestsMacros.cmake
@@ -0,0 +1,381 @@
+#===============================================================================
+# @file AkantuTestMacros.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Oct 25 2010
+# @date last modification: Tue Jun 24 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+
+#[=======================================================================[.rst:
+#AkantuTestsMacros
+#-----------------
+#
+#This modules provides the functions to helper to declare tests and folders
+#containing tests in akantu
+#
+#.. command:: add_test_tree
+#
+# add_test_tree(<test_direcotry>)
+#
+# ``<test_directory>`` is the entry direcroty of the full structure of
+# subfolders containing tests
+#
+#.. command:: add_akantu_test
+#
+# add_akantu_test(<dir> <desc>)
+#
+# This function add a subdirectory ``<dir>`` of tests that will be conditionnaly
+# activable and will be visible only if the parent folder as been activated An
+# option ``AKANTU_BUILD_TEST_<dir>`` will appear in ccmake with the description
+# ``<desc>``. The compilation of all tests can be forced with the option
+# ``AKANTU_BUILD_ALL_TESTS``
+#
+#.. command:: register_test
+#
+# register_test(<test_name>
+# SOURCES <sources>...
+# PACKAGE <akantu_packages>...
+# SCRIPT <scirpt>
+# [FILES_TO_COPY <filenames>...]
+# [DEPENDS <targets>...]
+# [DIRECTORIES_TO_CREATE <directories>...]
+# [COMPILE_OPTIONS <flags>...]
+# [EXTRA_FILES <filnames>...]
+# [UNSABLE]
+# [PARALLEL]
+# )
+#
+# This function defines a test ``<test_name>_run`` this test could be of
+# different nature depending on the context. If Just sources are provided the
+# test consist of running the executable generated. If a file ``<test_name>.sh``
+# is present the test will execute the script. And if a ``<test_name>.verified``
+# exists the output of the test will be compared to this reference file
+#
+# The options are:
+#
+# ``SOURCES <sources>...``
+# The list of source files to compile to generate the executable of the test
+#
+# ``PACKAGE <akantu_packages>...``
+# The list of package to which this test belongs. The test will be activable
+# only of all the packages listed are activated
+#
+# ``SCRIPT <script>``
+# The script to execute instead of the executable
+#
+# ``FILES_TO_COPY <filenames>...``
+# List of files to copy from the source directory to the build directory
+#
+# ``DEPENDS <targets>...``
+# List of targets the test depends on, for example if a mesh as to be generated
+#
+# ``DIRECTORIES_TO_CREATE <directories>...``
+# Obsolete. This specifies a list of directories that have to be created in
+# the build folder
+#
+# ``COMPILE_OPTIONS <flags>...``
+# List of extra compilations options to pass to the compiler
+#
+# ``EXTRA_FILES <filnames>...``
+# Files to consider when generating a package_source
+#
+# ``UNSABLE``
+# If this option is specified the test can be unacitivated by the glocal option
+# ``AKANTU_BUILD_UNSTABLE_TESTS``, this is mainly intendeed to remove test
+# under developement from the continious integration
+#
+# ``PARALLEL``
+# This specifies that this test should be run in parallel. It will generate a
+# series of test for different number of processors. This automaticaly adds a
+# dependency to the package ``AKANTU_PARALLEL``
+#
+#]=======================================================================]
+
+set(AKANTU_DRIVER_SCRIPT ${AKANTU_CMAKE_DIR}/akantu_test_driver.sh)
+configure_file(${AKANTU_CMAKE_DIR}/akantu_test_environement.sh.in
+ ${PROJECT_BINARY_DIR}/akantu_test_environement.sh
+ @ONLY)
+
+# ==============================================================================
+macro(add_test_tree dir)
+ if(AKANTU_TESTS)
+ enable_testing()
+ include(CTest)
+ mark_as_advanced(BUILD_TESTING)
+
+ set(AKANTU_TESTS_EXCLUDE_FILES "" CACHE INTERNAL "")
+
+ set(_akantu_current_parent_test ${dir} CACHE INTERNAL "Current test folder" FORCE)
+ set(_akantu_${dir}_tests_count 0 CACHE INTERNAL "" FORCE)
+
+ string(TOUPPER ${dir} _u_dir)
+ set(AKANTU_BUILD_${_u_dir} ON CACHE INTERNAL "${desc}" FORCE)
+
+ package_get_all_test_folders(_test_dirs)
+
+ foreach(_dir ${_test_dirs})
+ add_subdirectory(${_dir})
+ endforeach()
+ else()
+ set(AKANTU_TESTS_EXCLUDE_FILES "${CMAKE_CURRENT_BINARY_DIR}/${dir}" CACHE INTERNAL "")
+ endif()
+endmacro()
+
+# ==============================================================================
+function(add_akantu_test dir desc)
+ set(_my_parent_dir ${_akantu_current_parent_test})
+
+ # initialize variables
+ set(_akantu_current_parent_test ${dir} CACHE INTERNAL "Current test folder" FORCE)
+ set(_akantu_${dir}_tests_count 0 CACHE INTERNAL "" FORCE)
+
+ # set the option for this directory
+ string(TOUPPER ${dir} _u_dir)
+ option(AKANTU_BUILD_${_u_dir} "${desc}")
+ mark_as_advanced(AKANTU_BUILD_${_u_dir})
+
+ # add the sub-directory
+ add_subdirectory(${dir})
+
+ # if no test can be activated make the option disappear
+ set(_force_deactivate_count FALSE)
+ if(${_akantu_${dir}_tests_count} EQUAL 0)
+ set(_force_deactivate_count TRUE)
+ endif()
+
+ # if parent off make the option disappear
+ set(_force_deactivate_parent FALSE)
+ string(TOUPPER ${_my_parent_dir} _u_parent_dir)
+ if(NOT AKANTU_BUILD_${_u_parent_dir})
+ set(_force_deactivate_parent TRUE)
+ endif()
+
+ if(_force_deactivate_parent OR _force_deactivate_count OR AKANTU_BUILD_ALL_TESTS)
+ if(NOT DEFINED _AKANTU_BUILD_${_u_dir}_SAVE)
+ set(_AKANTU_BUILD_${_u_dir}_SAVE ${AKANTU_BUILD_${_u_dir}} CACHE INTERNAL "" FORCE)
+ endif()
+ unset(AKANTU_BUILD_${_u_dir} CACHE)
+ if(AKANTU_BUILD_ALL_TESTS AND NOT _force_deactivate_count)
+ set(AKANTU_BUILD_${_u_dir} ON CACHE INTERNAL "${desc}" FORCE)
+ else()
+ set(AKANTU_BUILD_${_u_dir} OFF CACHE INTERNAL "${desc}" FORCE)
+ endif()
+ else()
+ if(DEFINED _AKANTU_BUILD_${_u_dir}_SAVE)
+ unset(AKANTU_BUILD_${_u_dir} CACHE)
+ set(AKANTU_BUILD_${_u_dir} ${_AKANTU_BUILD_${_u_dir}_SAVE} CACHE BOOL "${desc}")
+ unset(_AKANTU_BUILD_${_u_dir}_SAVE CACHE)
+ endif()
+ endif()
+
+ # adding up to the parent count
+ math(EXPR _tmp_parent_count "${_akantu_${dir}_tests_count} + ${_akantu_${_my_parent_dir}_tests_count}")
+ set(_akantu_${_my_parent_dir}_tests_count ${_tmp_parent_count} CACHE INTERNAL "" FORCE)
+
+ # restoring the parent current dir
+ set(_akantu_current_parent_test ${_my_parent_dir} CACHE INTERNAL "Current test folder" FORCE)
+endfunction()
+
+
+# ==============================================================================
+function(register_test test_name)
+ set(multi_variables
+ SOURCES FILES_TO_COPY DEPENDS DIRECTORIES_TO_CREATE COMPILE_OPTIONS EXTRA_FILES PACKAGE
+ )
+
+ cmake_parse_arguments(_register_test
+ "UNSTABLE;PARALLEL"
+ "POSTPROCESS;SCRIPT"
+ "${multi_variables}"
+ ${ARGN}
+ )
+
+ if(NOT _register_test_PACKAGE)
+ message(FATAL_ERROR "No reference package was defined for the test ${test_name} in folder ${CMAKE_CURRENT_SOURCE_DIR}")
+ endif()
+
+ set(_test_act TRUE)
+ # Activate the test anly if all packages associated to the test are activated
+ foreach(_package ${_register_test_PACKAGE})
+ package_is_activated(${_package} _act)
+ if(NOT _act)
+ set(_test_act FALSE)
+ endif()
+ endforeach()
+
+ # check if the test is marked unstable and if the unstable test should be run
+ if(_register_test_UNSTABLE AND NOT AKANTU_BUILD_UNSTABLE_TESTS)
+ set(_test_act FALSE)
+ endif()
+
+ # check that the sources are files that need to be compiled
+ if(_register_test_SOURCES} OR _register_test_UNPARSED_ARGUMENTS)
+ set(_need_to_compile TRUE)
+ else()
+ set(_need_to_compile FALSE)
+ endif()
+
+ foreach(_file ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS})
+ if(NOT (_file MATCHES "\\.cc$" OR _file MATCHES "\\.hh$"))
+ set(_need_to_compile FALSE)
+ message("NO: ${test_name}")
+ endif()
+ endforeach()
+
+ # todo this should be checked for the build package_sources since the file will not be listed.
+ if(_test_act)
+ math(EXPR _tmp_parent_count "${_akantu_${_akantu_current_parent_test}_tests_count} + 1")
+ set(_akantu_${_akantu_current_parent_test}_tests_count ${_tmp_parent_count} CACHE INTERNAL "" FORCE)
+
+ string(TOUPPER ${_akantu_current_parent_test} _u_parent)
+
+ if(AKANTU_BUILD_${_u_parent} OR AKANTU_BUILD_ALL_TESTS)
+ set(_test_all_files)
+
+ if(_need_to_compile)
+ # get the include directories for sources in activated directories
+ package_get_all_include_directories(
+ AKANTU_LIBRARY_INCLUDE_DIRS
+ )
+
+ # get the external packages compilation and linking informations
+ package_get_all_external_informations(
+ AKANTU_EXTERNAL_INCLUDE_DIR
+ AKANTU_EXTERNAL_LIBRARIES
+ )
+
+ # set the proper includes to build most of the tests
+ include_directories(
+ ${AKANTU_INCLUDE_DIRS}
+ ${AKANTU_EXTERNAL_LIB_INCLUDE_DIR}
+ )
+
+ # Register the executable to compile
+ add_executable(${test_name} ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS})
+ set_property(TARGET ${test_name} APPEND
+ PROPERTY INCLUDE_DIRECTORIES ${AKANTU_LIBRARY_INCLUDE_DIRS} ${AKANTU_EXTERNAL_INCLUDE_DIR})
+ target_link_libraries(${test_name} akantu ${AKANTU_EXTERNAL_LIBRARIES})
+
+ # add the extra compilation options
+ if(_register_test_COMPILE_OPTIONS)
+ set_target_properties(${test_name}
+ PROPERTIES COMPILE_DEFINITIONS "${_register_test_COMPILE_OPTIONS}")
+ endif()
+
+ # add the different dependencies (meshes, local libraries, ...)
+ foreach(_dep ${_register_test_DEPENDS})
+ add_dependencies(${test_name} ${_dep})
+ get_target_property(_dep_in_ressources ${_dep} RESSOURCES)
+
+ if(_dep_in_ressources)
+ list(APPEND _test_all_files "${_dep_in_ressources}")
+ endif()
+ endforeach()
+
+ else()
+ if(_register_test_UNPARSED_ARGUMENTS AND NOT _register_test_SCRIPT)
+ set(_register_test_SCRIPT ${_register_test_UNPARSED_ARGUMENTS})
+ endif()
+ endif()
+
+ # copy the needed files to the build folder
+ if(_register_test_FILES_TO_COPY)
+ foreach(_file ${_register_test_FILES_TO_COPY})
+ file(COPY "${_file}" DESTINATION .)
+ list(APPEND _test_all_files "${CMAKE_CURRENT_SOURCE_DIR}/${_file}")
+ endforeach()
+ endif()
+
+ # create the needed folders in the build folder
+ if(_register_test_DIRECTORIES_TO_CREATE)
+ foreach(_dir ${_register_test_DIRECTORIES_TO_CREATE})
+ if(IS_ABSOLUTE ${dir})
+ file(MAKE_DIRECTORY "${_dir}")
+ else()
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_dir}")
+ endif()
+ endforeach()
+ endif()
+
+ # add the source files in the list of all files
+ foreach(_file ${_register_test_SOURCES} ${_register_test_UNPARSED_ARGUMENTS} ${_register_test_EXTRA_FILES})
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
+ list(APPEND _test_all_files "${CMAKE_CURRENT_SOURCE_DIR}/${_file}")
+ else()
+ message("The file \"${_file}\" registred by the test \"${test_name}\" does not exists")
+ endif()
+ endforeach()
+
+ set(_arguments -n "${test_name}")
+ # register the test for ctest
+ if(_register_test_SCRIPT)
+ file(COPY ${_register_test_SCRIPT}
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+ DESTINATION .)
+ list(APPEND _test_all_files "${CMAKE_CURRENT_SOURCE_DIR}/${_register_test_SCRIPT}")
+ list(APPEND _arguments -e "${_register_test_SCRIPT}")
+ elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh")
+ file(COPY ${test_name}.sh DESTINATION .)
+ list(APPEND _test_all_files "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.sh")
+ list(APPEND _arguments -e "${test_name}.sh")
+ else()
+ list(APPEND _arguments -e "${test_name}")
+ endif()
+
+ list(APPEND _arguments -E "${PROJECT_BINARY_DIR}/akantu_test_environement.sh")
+
+ if(_register_test_PARALLEL)
+ list(APPEND _arguments -p "${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG}")
+ endif()
+
+ if(_register_test_POSTPROCESS)
+ list(APPEND _arguments -s "${_register_test_POSTPROCESS}")
+ endif()
+
+ list(APPEND _arguments -w "${CMAKE_CURRENT_BINARY_DIR}")
+
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified")
+ list(APPEND _arguments -r "${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.verified")
+ endif()
+
+ string(REPLACE ";" " " _command "${_arguments}")
+
+ add_test(NAME ${test_name}_run
+ COMMAND ${AKANTU_DRIVER_SCRIPT} ${_arguments})
+
+ # add the executable as a dependency of the run
+ set_tests_properties(${test_name}_run PROPERTIES DEPENDS ${test_name})
+
+ # clean the list of all files for this test and add them in the total list
+ set(_tmp ${AKANTU_TESTS_FILES})
+ foreach(_file ${_source_file})
+ get_filename_component(_full ${_file} ABSOLUTE)
+ file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_full})
+ list(APPEND _tmp "${__file}")
+ list(APPEND _pkg_tmp "${__file}")
+ endforeach()
+ set(AKANTU_TESTS_FILES ${_tmp} CACHE INTERNAL "")
+ endif()
+ endif()
+endfunction()
diff --git a/cmake/AkantuUse.cmake b/cmake/AkantuUse.cmake
index b4221e8aa..00add8aa1 100644
--- a/cmake/AkantuUse.cmake
+++ b/cmake/AkantuUse.cmake
@@ -1,54 +1,49 @@
#===============================================================================
# @file AkantuUse.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Thu Dec 01 2011
# @date last modification: Tue Nov 06 2012
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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(include_package_if_needed PACKAGE)
- string(TOUPPER ${PACKAGE} _package)
- if(AKANTU_USE_${_package})
- if(${PACKAGE} MATCHES BLAS)
- enable_language(Fortran)
- endif()
- find_package(${PACKAGE} REQUIRED)
- if(${_package}_FOUND)
- if(DEFINED ${_package}_INCLUDE_DIR)
- list(APPEND AKANTU_EXTRA_INCLUDE_DIR ${${_package}_INCLUDE_DIR})
- else()
- list(APPEND AKANTU_EXTRA_INCLUDE_DIR ${${_package}_INCLUDE_PATH})
- endif()
- list(APPEND AKANTU_EXTRA_LIBRARIES ${${_package}_LIBRARIES})
- endif()
- endif()
-endmacro()
+function(package_is_activated pgk activated)
+ string(TOUPPER ${pkg} _u_pkg)
+ set(activated ${AKANTU_HAS_${_u_pkg}} PARENT_SCOPE)
+endfunction()
-macro(find_akantu_dependencies)
- include_package_if_needed(MPI)
- include_package_if_needed(Mumps)
- include_package_if_needed(Scotch)
- include_package_if_needed(BLAS)
-endmacro()
\ No newline at end of file
+function(package_get_include_dir pkg include_dir)
+ string(TOUPPER ${pkg} _u_pkg)
+ set(include_dir ${AKANTU_${_u_pkg}_INCLUDE_DIR} PARENT_SCOPE)
+endfunction()
+
+function(package_get_libraries pkg libs)
+ string(TOUPPER ${pkg} _u_pkg)
+ set(libs ${AKANTU_${_u_pkg}_LIBRARIES} PARENT_SCOPE)
+endfunction()
+
+function(package_get_compile_flags pkg flags)
+ string(TOUPPER ${pkg} _u_pkg)
+ set(flags ${AKANTU_${_u_pkg}_COMPILE_FLAGS} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/Modules/CMakePackagesSystem.cmake b/cmake/Modules/CMakePackagesSystem.cmake
index 461d03656..7f8fb6409 100644
--- a/cmake/Modules/CMakePackagesSystem.cmake
+++ b/cmake/Modules/CMakePackagesSystem.cmake
@@ -1,413 +1,861 @@
#===============================================================================
# @file CMakePackagesSystem.cmake
#
-# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
# @author Nicolas Richart <nicolas.richart@epfl.ch>
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Thu Dec 20 2012
# @date last modification: Wed Sep 10 2014
#
# @brief Set of macros used by akantu to handle the package system
#
+# @section DESCRIPTION
+#
+# 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:
+# 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
+#
+# 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> ]])
+#
+# It can also declare multiple informations:
+# source files:
+# package_declare_sources(<package real name>
+# <src1> <src2> ... <srcn>)
+#
+# a LaTeX documentation:
+# package_declare_documentation(<package real name>
+# <line1> <line2> ...<linen>)
+#
+# 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
+# package_get_name(<pkg> <retval>)
+# package_get_real_name(<pkg> <retval>)
+#
+# package_get_option_name(<pkg> <retval>)
+#
+# package_use_system(<pkg> <retval>)
+#
+# package_get_nature(<pkg> <retval>)
+#
+# package_get_description(<pkg> <retval>)
+#
+# package_get_filename(<pkg> <retval>)
+#
+# package_get_sources_folder(<pkg> <retval>)
+# package_get_tests_folder(<pkg> <retval>)
+# package_get_manual_folder(<pkg> <retval>)
+#
+# package_get_find_package_extra_options(<pkg> <retval>)
+#
+# package_get_compile_flags(<pkg> <retval>)
+# package_set_compile_flags(<pkg> <flag1> <flag2> ... <flagn>)
+#
+# package_get_include_dir(<pkg> <retval>)
+# package_set_include_dir(<pkg> <inc1> <inc2> ... <incn>)
+# package_add_include_dir(<pkg> <inc1> <inc2> ... <incn>)
+#
+# package_get_libraries(<pkg> <retval>)
+# package_set_libraries(<pkg> <lib1> <lib2> ... <libn>)
+#
+# package_add_extra_dependency(pkg <dep1> <dep2> ... <depn>)
+# package_rm_extra_dependency(<pkg> <dep>)
+# package_get_extra_dependencies(<pkg> <retval>)
+#
+# package_is_activated(<pkg> <retval>)
+# package_is_deactivated(<pkg> <retval>)
+#
+# package_get_dependencies(<pkg> <retval>)
+# package_add_dependencies(<pkg> <dep1> <dep2> ... <depn>)
+#
+# package_on_enabled_script(<pkg> <script>)
+#
+# package_get_all_source_files(<srcs> <public_headers> <private_headers>)
+# package_get_all_include_directories(<inc_dirs>)
+# package_get_all_external_informations(<include_dir> <libraries>)
+# package_get_all_definitions(<definitions>)
+# package_get_all_extra_dependencies(<dependencies>)
+# package_get_all_test_folders(<test_dirs>)
+# package_get_all_documentation_files(<doc_files>)
+# package_get_all_activated_packages(<activated_list>)
+# package_get_all_deactivated_packages(<deactivated_list>)
+# package_get_all_packages(<packages_list>)
+#
+#
# @section LICENSE
#
# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
#
#===============================================================================
include(CMakeParseArguments)
+
#===============================================================================
# Package Management
#===============================================================================
if(__CMAKE_PACKAGES_SYSTEM)
return()
endif()
set(__CMAKE_PACKAGES_SYSTEM TRUE)
-include(CMakeDebugMessages)
-cmake_register_debug_message_module(PackagesSystem)
+if(CMAKE_VERSION VERSION_GREATER 3.1.2)
+ cmake_policy(SET CMP0054 NEW)
+endif()
-macro(package_pkg_name PKG PKG_NAME)
- string(TOUPPER ${PROJECT_NAME} _project)
- string(TOUPPER ${PKG} _u_package)
- set(${PKG_NAME} ${_project}_${_u_package})
-endmacro()
+#===============================================================================
+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)
-macro(package_opt_name PKG OPT_NAME)
- string(TOUPPER ${PROJECT_NAME} _project)
- string(TOUPPER ${PKG} _u_package)
- set(${OPT_NAME} ${_project}_USE_${_u_package})
-endmacro()
-macro(package_nature PKG NATURE)
+include(CMakePackagesSystemGlobalFunctions)
+include(CMakePackagesSystemPrivateFunctions)
+
+# ==============================================================================
+# "Public" Accessors
+# ==============================================================================
+# ------------------------------------------------------------------------------
+# Package name
+# ------------------------------------------------------------------------------
+function(package_get_name pkg pkg_name)
string(TOUPPER ${PROJECT_NAME} _project)
- string(TOUPPER ${PKG} _u_package)
- set(${NATURE} ${_project}_${_u_package}_NATURE)
+ string(REPLACE "-" "_" _str_pkg "${pkg}")
+ string(TOUPPER ${_str_pkg} _u_package)
+ set(${pkg_name} ${_project}_PKG_${_u_package} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Real name
+# ------------------------------------------------------------------------------
+function(package_get_real_name pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_real_name(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Option name
+# ------------------------------------------------------------------------------
+function(package_get_option_name pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_option_name(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Set if system package or compile external lib
+# ------------------------------------------------------------------------------
+function(package_use_system pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_use_system(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+function(package_add_third_party_script_variable pkg var)
+ package_get_name(${pkg} _pkg_name)
+ _package_add_third_party_script_variable(${_pkg_name} ${var} ${ARGN})
+ set(${var} ${ARGN} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Set if system package or compile external lib
+# ------------------------------------------------------------------------------
+function(package_add_to_export_list pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_add_to_export_list(${_pkg_name} ${ARGN})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Nature
+# ------------------------------------------------------------------------------
+function(package_get_nature pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_nature(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Description
+# ------------------------------------------------------------------------------
+function(package_get_description pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_description(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Package file name
+# ------------------------------------------------------------------------------
+function(package_get_filename pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_filename(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Source files
+# ------------------------------------------------------------------------------
+function(package_get_source_files pkg ret_srcs ret_pub ret_priv)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_source_files(${_pkg_name} _tmp_srcs _tmp_pub _tmp_priv)
+ set(${ret_srcs} ${_tmp_srcs} PARENT_SCOPE)
+ set(${ret_pub} ${_tmp_pub} PARENT_SCOPE)
+ set(${ret_priv} ${_tmp_pric} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Source folder
+# ------------------------------------------------------------------------------
+function(package_get_sources_folder pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_sources_folder(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Test folder
+# ------------------------------------------------------------------------------
+function(package_get_tests_folder pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_tests_folder(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Manual folder
+# ------------------------------------------------------------------------------
+function(package_get_manual_folder pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_manual_folder(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Extra option for the find_package
+# ------------------------------------------------------------------------------
+function(package_get_find_package_extra_options pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_find_package_extra_options(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+function(package_set_find_package_extra_options pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_find_package_extra_options(${_pkg_name} ${ARGN})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Compilation flags
+# ------------------------------------------------------------------------------
+function(package_get_compile_flags pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_compile_flags(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+function(package_set_compile_flags pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_compile_flags(${_pkg_name} ${ARGN})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Include dir
+# ------------------------------------------------------------------------------
+function(package_get_include_dir pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_include_dir(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+function(package_set_include_dir pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_include_dir(${_pkg_name} ${ARGN})
+endfunction()
+
+function(package_add_include_dir pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_add_include_dir(${_pkg_name} ${ARGN})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Libraries
+# ------------------------------------------------------------------------------
+function(package_get_libraries pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_libraries(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+function(package_set_libraries pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_libraries(${_pkg_name} ${ARGN})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Extra dependencies like custom commands of ExternalProject
+# ------------------------------------------------------------------------------
+function(package_add_extra_dependency pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_add_extra_dependency(${_pkg_name} ${ARGN})
+endfunction()
+
+function(package_rm_extra_dependency pkg dep)
+ package_get_name(${pkg} _pkg_name)
+ _package_rm_extra_dependency(${_pkg_name} ${dep})
+endfunction()
+
+function(package_get_extra_dependencies pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_extra_dependencies(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Activate/deactivate
+# ------------------------------------------------------------------------------
+function(package_is_activated pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_is_activated(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+function(package_is_deactivated pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_is_deactivated(${_pkg_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Direct dependencies
+# ------------------------------------------------------------------------------
+function(package_get_dependencies pkg ret)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_dependencies(${_pkg_name} _tmp_name)
+ _package_get_real_name(${_tmp_name} _tmp)
+ set(${ret} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+function(package_add_dependencies pkg)
+ package_get_name(${pkg} _pkg_name)
+ foreach(_dep ${ARGN})
+ package_get_name(${_dep} _dep_pkg_name)
+ list(APPEND _tmp_deps ${_dep_pkg_name})
+ endforeach()
+
+ _package_add_dependencies(${_pkg_name} ${_tmp_deps})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Documentation related functions
+# ------------------------------------------------------------------------------
+function(package_declare_documentation pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_documentation(${_pkg_name} ${ARGN})
+endfunction()
+
+function(package_declare_documentation_files pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_documentation_files(${_pkg_name} ${ARGN})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Set any user variables needed
+# ------------------------------------------------------------------------------
+function(package_set_variable variable pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_variable(${variable} ${_pkg_name} ${ARGN})
+endfunction()
+
+macro(package_get_variable variable pkg value)
+ package_get_name(${pkg} _pkg_name)
+ _package_get_variable(${variable} ${_pkg_name} _value_tmp)
+ set(${value} ${_value_tmp} PARENT_SCOPE)
endmacro()
-macro(package_desc_name PKG DESC_NAME)
+# ==============================================================================
+# Global accessors
+# ==============================================================================
+# ------------------------------------------------------------------------------
+# get the list of source files
+# ------------------------------------------------------------------------------
+function(package_get_all_source_files SRCS PUBLIC_HEADERS PRIVATE_HEADERS)
string(TOUPPER ${PROJECT_NAME} _project)
- string(TOUPPER ${PKG} _u_package)
- set(${DESC_NAME} ${_project}_DESC_${_u_package})
-endmacro()
-#===============================================================================
-option(AUTO_MOVE_OLD_FILES "give cmake permission to move the unregistered files to ${PROJECT_SOURCE_DIR}/tmp directory" FALSE)
-mark_as_advanced(AUTO_MOVE_OLD_FILES)
+ unset(_tmp_srcs)
+ unset(_tmp_public_headers)
+ unset(_tmp_private_headers)
+
+ package_get_all_activated_packages(_activated_list)
+ foreach(_pkg_name ${_activated_list})
+ _package_get_source_files(${_pkg_name}
+ _pkg_srcs
+ _pkg_public_headers
+ _pkg_private_headers
+ )
+ list(APPEND _tmp_srcs ${_pkg_srcs})
+ list(APPEND _tmp_public_headers ${_pkg_public_headers})
+ list(APPEND _tmp_private_headers ${_pkg_private_headers})
+ endforeach()
-macro(add_all_packages package_dir src_dir)
- string(TOUPPER ${PROJECT_NAME} _project)
- cmake_debug_message(PackagesSystem "add_all_packages: PKG DIR : ${package_dir}")
- file(GLOB ${_project}_package_list "${package_dir}/*.cmake")
+ set(${SRCS} ${_tmp_srcs} PARENT_SCOPE)
+ set(${PUBLIC_HEADERS} ${_tmp_public_headers} PARENT_SCOPE)
+ set(${PRIVATE_HEADERS} ${_tmp_private_headers} PARENT_SCOPE)
+endfunction()
- set(_${_project}_src_dir ${src_dir})
- set(_package_files)
- foreach(_pkg ${${_project}_package_list})
- get_filename_component(_basename ${_pkg} NAME)
- list(APPEND _package_files ${_basename})
+# ------------------------------------------------------------------------------
+# 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(_package_files)
- list(SORT _package_files)
+ if(_tmp)
+ list(REMOVE_DUPLICATES _tmp)
endif()
- set(${_project}_PACKAGE_SYSTEM_PACKAGES_NAMES_LIST_ALL)
- foreach(_pkg ${_package_files})
- string(REGEX REPLACE "[0-9]+_" "" _pkg_name ${_pkg})
- string(REGEX REPLACE "\\.cmake" "" _option_name ${_pkg_name})
- string(TOUPPER "${_option_name}" _option_name)
- set(${_project}_${_option_name}_FILE ${_pkg} CACHE INTERNAL "" FORCE)
- list(APPEND ${_project}_PACKAGE_SYSTEM_PACKAGES_NAMES_LIST_ALL ${_option_name})
+ set(${inc_dirs} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Get external libraries informations
+# ------------------------------------------------------------------------------
+function(package_get_all_external_informations INCLUDE_DIR LIBRARIES)
+ _package_get_variable_for_activated(INCLUDE_DIR tmp_INCLUDE_DIR)
+ _package_get_variable_for_activated(LIBRARIES tmp_LIBRARIES)
+
+ set(${INCLUDE_DIR} ${tmp_INCLUDE_DIR} PARENT_SCOPE)
+ set(${LIBRARIES} ${tmp_LIBRARIES} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Get export list for all activated packages
+# ------------------------------------------------------------------------------
+function(package_get_all_export_list export_list)
+ _package_get_variable_for_activated(EXPORT_LIST _tmp)
+ set(${export_list} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Get definitions like external projects
+# ------------------------------------------------------------------------------
+function(package_get_all_definitions definitions)
+ _package_get_variable_for_activated(OPTION_NAME _tmp)
+ set(${definitions} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Get extra dependencies like external projects
+# ------------------------------------------------------------------------------
+function(package_get_all_extra_dependencies deps)
+ _package_get_variable_for_activated(EXTRA_DEPENDENCY _tmp)
+ set(${deps} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Get extra infos
+# ------------------------------------------------------------------------------
+function(package_get_all_test_folders TEST_DIRS)
+ _package_get_variable_for_activated(TEST_FOLDER _tmp)
+ set(${TEST_DIRS} ${_tmp} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Documentation informations
+# ------------------------------------------------------------------------------
+function(package_get_all_documentation_files doc_files)
+ set(_tmp_DOC_FILES)
+
+ package_get_all_activated_packages(_activated_list)
+ foreach(_pkg_name ${_activated_list})
+ _package_get_manual_folder(${_pkg_name} _doc_dir)
+ _package_get_documentation_files(${_pkg_name} _doc_files)
+
+ foreach(_doc_file ${_doc_files})
+ list(APPEND _tmp_DOC_FILES ${_doc_dir}/${_doc_file})
+ endforeach()
endforeach()
- cmake_debug_message(PackagesSystem "add_all_packages: PKG LIST : ${${_project}_PACKAGE_SYSTEM_PACKAGES_NAMES_LIST_ALL}")
+ if(_tmp_DOC_FILES)
+ list(REMOVE_DUPLICATES _tmp_DOC_FILES)
+ endif()
-# message("Packages: ${${_project}_PACKAGE_SYSTEM_PACKAGES_NAMES_LIST_ALL}")
+ set(${doc_files} ${_tmp_DOC_FILES} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# List packages
+# ------------------------------------------------------------------------------
+function(package_get_all_activated_packages activated_list)
+ package_get_project_variable(ACTIVATED_PACKAGE_LIST _activated_list)
+ set(${activated_list} ${_activated_list} PARENT_SCOPE)
+endfunction()
+
+function(package_get_all_deactivated_packages deactivated_list)
+ package_get_project_variable(DEACTIVATED_PACKAGE_LIST _deactivated_list)
+ set(${deactivated_list} ${_deactivated_list} PARENT_SCOPE)
+endfunction()
+
+function(package_get_all_packages packages_list)
+ package_get_project_variable(ALL_PACKAGES_LIST _packages_list)
+ set(${packages_list} ${_packages_list} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Callbacks
+# ------------------------------------------------------------------------------
+function(package_on_enabled_script pkg script)
+ package_get_name(${pkg} _pkg_name)
+ _package_on_enable_script(${_pkg_name} "${script}")
+endfunction()
+
+# ------------------------------------------------------------------------------
+# list all the packages in the PACKAGE_FOLDER
+# extra packages can be given with an EXTRA_PACKAGE_FOLDER
+# <package_folder>/<package>.cmake
+#
+# Extra packages folder structure
+# <extra_package_folder>/<package>/package.cmake
+# /src
+# /test
+# /manual
+#
+# ------------------------------------------------------------------------------
+function(package_list_packages PACKAGE_FOLDER)
+ cmake_parse_arguments(_opt_pkg
+ ""
+ "SOURCE_FOLDER;EXTRA_PACKAGES_FOLDER;TEST_FOLDER;MANUAL_FOLDER"
+ ""
+ ${ARGN})
- foreach(_pkg ${${_project}_PACKAGE_SYSTEM_PACKAGES_NAMES_LIST_ALL})
- cmake_debug_message(PackagesSystem "add_all_packages: including ${_pkg}")
- string(TOLOWER "${_pkg}" _l_pkg)
- include(${package_dir}/${${_project}_${_pkg}_FILE})
- package_pkg_name(${_l_pkg} _package_name)
- if (${_package_name})
- list(APPEND ${_project}_PACKAGE_SYSTEM_PACKAGES_ON ${_l_pkg})
- list(APPEND ${_project}_PACKAGE_LIST ${_pkg})
- else (${_package_name})
- list(APPEND ${_project}_PACKAGE_SYSTEM_PACKAGES_OFF ${_l_pkg})
- endif()
+ string(TOUPPER ${PROJECT_NAME} _project)
- foreach(_file ${${_package_name}_FILES})
- list(APPEND ${_project}_release_all_files ${_file})
- endforeach()
+ # 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()
- cmake_debug_message(PackagesSystem "add_all_packages: ON PKG : ${${_project}_PACKAGE_SYSTEM_PACKAGES_ON}")
- cmake_debug_message(PackagesSystem "add_all_packages: ALL RELEASE FILES LIST : ${_project}_release_all_files ${${_project}_release_all_files}")
- #check if there are some file in the release that are not registered in a package
- file(GLOB_RECURSE ${_project}_all_files "*.cc" "*.hh" "*.c" "*.h" "*.hpp")
- cmake_debug_message(PackagesSystem "add_all_packages: ALL FILES LIST : ${_project}_all_files ${${_project}_all_files}")
+ if(_opt_pkg_SOURCE_FOLDER)
+ set(_src_folder "${_opt_pkg_SOURCE_FOLDER}")
+ else()
+ set(_src_folder "src/")
+ endif()
- cmake_debug_message(PackagesSystem "add_all_packages: SOURCE DIR : ${_${_project}_src_dir}")
- foreach(_file ${${_project}_all_files})
- if("${_file}" MATCHES "${_${_project}_src_dir}")
- file(RELATIVE_PATH __file "${_${_project}_src_dir}" ${_file})
- list(APPEND ${_project}_all_files_relatives ${__file})
- endif()
- endforeach()
+ get_filename_component(_abs_src_folder ${_src_folder} ABSOLUTE)
- foreach(_file ${${_project}_all_files_relatives})
- if(NOT ${_file} MATCHES "test.*" AND NOT ${_file} MATCHES "third-party" AND NOT ${_file} MATCHES "doc")
- list(FIND ${_project}_release_all_files ${_file} _index)
- if (_index EQUAL -1)
- list(APPEND ${_project}_missing_files_in_packages ${_file})
- endif()
- endif()
- endforeach()
- if (${_project}_missing_files_in_packages)
- message("The files:")
- message("*****************")
- foreach(_file ${${_project}_missing_files_in_packages})
- message("${_file}")
- endforeach()
- message("*****************")
- message("are not registered in any package.")
- if (NOT AUTO_MOVE_OLD_FILES)
- message("Please append these files in one of the packages within directory
- ${PROJECT_SOURCE_DIR}/packages
-or remove the files if useless.
-")
- message(FATAL_ERROR "abort")
- else()
- message("These files are getting displaced to directory ${PROJECT_SOURCE_DIR}/tmp/")
- message("creating directory ${PROJECT_SOURCE_DIR}/tmp/")
- file(MAKE_DIRECTORY ${PROJECT_SOURCE_DIR}/tmp/)
- foreach(_file ${${_project}_missing_files_in_packages})
- get_filename_component(fname ${_file} NAME)
- message("renaming ${src_dir}/${_file} to ${PROJECT_SOURCE_DIR}/tmp/${fname}")
- file(RENAME ${src_dir}/${_file} ${PROJECT_SOURCE_DIR}/tmp/${fname})
- endforeach()
- endif()
+ if(_opt_pkg_TEST_FOLDER)
+ set(_test_folder "${_opt_pkg_TEST_FOLDER}")
+ else()
+ set(_test_folder "test/")
endif()
- if(${_project}_missing_files_in_packages)
- message("A complete list of files missing in the packages description can be found here: ${PROJECT_BINARY_DIR}/missing_files_in_packages")
- if(EXISTS ${PROJECT_BINARY_DIR}/missing_files_in_packages)
- file(REMOVE ${PROJECT_BINARY_DIR}/missing_files_in_packages)
- endif()
- foreach(_file ${${_project}_missing_files_in_packages})
- file(APPEND ${PROJECT_BINARY_DIR}/missing_files_in_packages "${_file}
-")
- endforeach()
+ if(_opt_pkg_MANUAL_FOLDER)
+ set(_manual_folder "${_opt_pkg_MANUAL_FOLDER}")
+ else()
+ set(_manual_folder "doc/manual")
endif()
- #check if there are some file in the package list that are not on the current directory
- foreach(_file ${${_project}_release_all_files})
- list(FIND ${_project}_all_files_relatives ${_file} _index)
- if (_index EQUAL -1)
- message("The file ${_file} is registered in packages but is not present in the source directory.")
- endif()
- endforeach()
+ get_filename_component(_abs_test_folder ${_test_folder} ABSOLUTE)
+ get_filename_component(_abs_manual_folder ${_manual_folder} ABSOLUTE)
- #construct list of files for unactivated packages
-# list(APPEND _tmp_${_project}_EXCLUDE_SOURCE_FILES ${${_project}_EXCLUDE_SOURCE_FILES})
- set(_tmp_${_project}_EXCLUDE_SOURCE_FILES "")
- foreach(_pkg ${${_project}_PACKAGE_SYSTEM_PACKAGES_OFF})
- package_pkg_name(${_pkg} _pkg_name)
- cmake_debug_message(PackagesSystem "add_all_packages: exlude ${_file}")
- list(APPEND _tmp_${_project}_EXCLUDE_SOURCE_FILES ${${_pkg_name}_FILES})
- endforeach()
+ # check all the packages in the <package_folder>
+ file(GLOB _package_list "${PACKAGE_FOLDER}/*.cmake")
- set(${_project}_EXCLUDE_SOURCE_FILES "${_tmp_${_project}_EXCLUDE_SOURCE_FILES}" CACHE INTERNAL "File to exclude in the project ${_project} package" FORCE)
- #check dependencies
- foreach(_pkg ${${_project}_PACKAGE_SYSTEM_PACKAGES_OFF})
- # differentiate the file types
- cmake_debug_message(PackagesSystem "add_all_packages: DEPENDS PKG : ${_pkg}")
- cmake_debug_message(PackagesSystem "add_all_packages: DEPENDS LST : ${${_pkg}_DEPENDS}")
- package_pkg_name(${_pkg} _pkg_name)
- if (NOT "${${_pkg_name}_DEB_DEPEND}" STREQUAL "")
- set(deb_depend "${deb_depend}, ${${_pkg}_DEB_DEPEND}")
+ set(_package_files)
+ foreach(_pkg ${_package_list})
+ get_filename_component(_basename ${_pkg} NAME)
+ if(NOT _basename MATCHES "^\\.#.*")
+ list(APPEND _package_files ${_basename})
endif()
endforeach()
- set(${_project}_PACKAGE_SYSTEM_DEBIAN_PACKAGE_DEPENDS "${deb_depend}")
-endmacro()
-#===============================================================================
-macro(generate_source_list_from_packages source_dir source_files inline_files headers_files include_dirs)
- string(TOUPPER ${PROJECT_NAME} _project)
+ if(_package_files)
+ list(SORT _package_files)
+ endif()
- cmake_debug_message(PackagesSystem "generate_source_list_from_packages: SRC DIR : ${source_dir}")
- foreach(_pkg ${${_project}_PACKAGE_SYSTEM_PACKAGES_ON})
- # differentiate the file types
- package_pkg_name(${_pkg} _package_name)
- cmake_debug_message(PackagesSystem "generate_source_list_from_packages: PKG ${_package_name} FILES : ${${_package_name}_FILES}")
- foreach(_file ${${_package_name}_FILES})
- if(${_file} MATCHES ".*inline.*\\.cc")
- list(APPEND ${_package_name}_inlines ${_file})
- elseif(${_file} MATCHES ".*\\.h+")
- list(APPEND ${_package_name}_headers ${_file})
- else()
- list(APPEND ${_package_name}_srcs ${_file})
- endif()
- endforeach()
+ # 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})
- # generates the include directory variable
- foreach(_file ${${_package_name}_headers})
- get_filename_component(_absolute_name ${_file} ABSOLUTE)
- get_filename_component(_include_dir ${_absolute_name} PATH)
- list(APPEND ${_package_name}_include_dirs ${_include_dir})
- list(REMOVE_DUPLICATES ${_package_name}_include_dirs)
- endforeach()
+ 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)
- # generate global lists for akantu to know what to build
- list(APPEND ${source_files} ${${_package_name}_srcs})
- list(APPEND ${inline_files} ${${_package_name}_inlines})
- list(APPEND ${headers_files} ${${_package_name}_headers})
- list(APPEND ${include_dirs} ${${_package_name}_include_dirs})
+ include("${PACKAGE_FOLDER}/${_pkg_file}")
- cmake_debug_message(PackagesSystem "generate_source_list_from_packages: PKG ${_package_name} SRCS : ${${_package_name}_srcs}")
- cmake_debug_message(PackagesSystem "generate_source_list_from_packages: PKG ${_package_name} INLINES : ${${_package_name}_inlines}")
- cmake_debug_message(PackagesSystem "generate_source_list_from_packages: PKG ${_package_name} HRDS : ${${_package_name}_headers}")
- cmake_debug_message(PackagesSystem "generate_source_list_from_packages: PKG ${_package_name} INCS : ${${_package_name}_include_dirs}")
+ unset(_current_src_folder CACHE)
+ unset(_current_test_folder CACHE)
+ unset(_current_manual_folder CACHE)
endforeach()
- cmake_debug_message(PackagesSystem "generate_source_list_from_packages: SRCS : ${${source_files}}")
- cmake_debug_message(PackagesSystem "generate_source_list_from_packages: HRDS : ${${headers_files}}")
- cmake_debug_message(PackagesSystem "generate_source_list_from_packages: INCS : ${${include_dirs}}")
-endmacro()
-
-#===============================================================================
-# macro to include optional packages
-macro(add_optional_external_package PACKAGE DESC DEFAULT)
- package_opt_name (${PACKAGE} _option_name)
- package_desc_name(${PACKAGE} _desc_name)
- set(${_desc_name} ${DESC})
- package_nature(${PACKAGE} _nature)
- set(${_nature} "external_optional")
- option(${_option_name} ${DESC} ${DEFAULT})
- _add_external_package(${PACKAGE} ${ARGN})
-endmacro()
-
-macro(add_external_package PACKAGE)
- package_opt_name (${PACKAGE} _option_name)
- set(${_option_name} ON)
- package_nature(${PACKAGE} _nature)
- set(${_nature} "external")
- _add_external_package(${PACKAGE} ${ARGN})
-endmacro()
+ # 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)
-macro(_add_external_package PACKAGE)
- string(TOUPPER ${PROJECT_NAME} _project)
- cmake_parse_arguments(_opt_pkg "" "LANGUAGE" "DEPENDS;PREFIX;FOUND;ARGS" ${ARGN})
+ _package_set_filename(${_pkg_name}
+ "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/package.cmake")
- package_pkg_name (${PACKAGE} _pkg_name)
- package_opt_name (${PACKAGE} _option_name)
+ set(_current_src_folder "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/src" CACHE INTERNAL "" FORCE)
- cmake_debug_message(PackagesSystem "add_optional_package: Registering ${PACKAGE} ${DESC} -> ${_option_name}")
+ if(EXISTS "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/test")
+ set(_current_test_folder "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/test" CACHE INTERNAL "" FORCE)
+ endif()
- if(_opt_pkg_PREFIX)
- set(_package_prefix ${_opt_pkg_PREFIX})
- else()
- string(TOUPPER ${PACKAGE} _u_package)
- set(_package_prefix ${_u_package})
- endif()
+ if(EXISTS "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/manual")
+ set(_current_manual_folder "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/manual" CACHE INTERNAL "" FORCE)
+ endif()
- if(${_option_name})
- if(_opt_pkg_LANGUAGE)
- foreach(_language ${_opt_pkg_LANGUAGE})
- cmake_debug_message(PackagesSystem "add_optional_package: Package ${PACKAGE} asked for language ${_language}")
- enable_language(${_language})
- endforeach()
- endif()
+ list(APPEND _extra_pkg_src_folders "${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/src")
- foreach(_dep ${_opt_pkg_DEPENDS})
- add_external_package_dependencies(${PACKAGE} ${_dep})
- endforeach()
+ include("${_opt_pkg_EXTRA_PACKAGES_FOLDER}/${_pkg}/package.cmake")
- find_package(${PACKAGE} REQUIRED ${_opt_pkg_ARGS})
-
- foreach(_prefix ${_package_prefix})
- if(${_prefix}_FOUND OR _opt_pkg_FOUND)
- list(APPEND ${_project}_DEFINITIONS ${_option_name})
- if(DEFINED ${_prefix}_INCLUDE_DIRS)
- list(APPEND ${_project}_EXTERNAL_LIB_INCLUDE_DIR ${${_prefix}_INCLUDE_DIRS})
- set(${_pkg_name}_INCLUDE_DIR ${${_prefix}_INCLUDE_DIRS})
- elseif(DEFINED ${_prefix}_INCLUDE_DIR)
- list(APPEND ${_project}_EXTERNAL_LIB_INCLUDE_DIR ${${_prefix}_INCLUDE_DIR})
- set(${_pkg_name}_INCLUDE_DIR ${${_prefix}_INCLUDE_DIR})
- elseif(DEFINED ${_prefix}_INCLUDE_PATH)
- list(APPEND ${_project}_EXTERNAL_LIB_INCLUDE_DIR ${${_prefix}_INCLUDE_PATH})
- set(${_pkg_name}_INCLUDE_DIR ${${_prefix}_INCLUDE_PATH})
- endif()
- list(APPEND ${_project}_EXTERNAL_LIBRARIES ${${_prefix}_LIBRARIES})
- set(${_pkg_name}_LIBRARIES ${${_prefix}_LIBRARIES})
- set(${_pkg_name} ON)
- string(TOUPPER ${PACKAGE} _u_package)
- list(APPEND ${_project}_OPTION_LIST ${_u_package})
- cmake_debug_message(PackagesSystem "add_optional_package: Package ${PACKAGE} found! (PREFIX: ${_prefix})")
- cmake_debug_message(PackagesSystem "add_optional_package: Package ${PACKAGE} includes : ${${_pkg_name}_INCLUDE_DIR}")
- cmake_debug_message(PackagesSystem "add_optional_package: Package ${PACKAGE} libraries: ${${_pkg_name}_LIBRARIES}")
- cmake_debug_message(PackagesSystem "add_optional_package: option list: ${${_project}_OPTION_LIST}")
- else(${_prefix}_FOUND)
- cmake_debug_message(PackagesSystem "add_optional_package: Package ${PACKAGE} not found! (PREFIX: ${_prefix})")
- set(${_pkg_name} OFF)
+ unset(_current_src_folder CACHE)
+ unset(_current_test_folder CACHE)
+ unset(_current_manual_folder CACHE)
endif()
endforeach()
- endif(${_option_name})
-endmacro()
+ endif()
-#===============================================================================
-# macro to add meta packages
-macro(add_meta_package PKG DESC DEFAULT)
- cmake_debug_message(PackagesSystem "add_meta_package: register meta option ${PKG} ${DESC} ${DEFAULT}")
- package_pkg_name (${PKG} _pkg_name)
- package_desc_name(${PKG} _desc_name)
+ _package_build_rdependencies()
+ _package_load_packages()
+ _package_check_files_exists()
+ _package_check_files_registered(${_abs_src_folder} ${_extra_pkg_src_folders})
- set(${_desc_name} ${DESC})
- option(${_pkg_name} ${DESC} ${DEFAULT})
+ # Load boost components if boost was loaded
+ package_is_activated(Boost _ret)
+ if(_ret)
+ _package_load_boost_components()
+ endif()
+endfunction()
+
+# ------------------------------------------------------------------------------
+# macro to include internal/external packages packages
+# package_declare(<package real name>
+# [EXTERNAL] [META] [ADVANCED] [NOT_OPTIONAL]
+# [DESCRIPTION <description>] [DEFAULT <default_value>]
+# [DEPENDS <pkg> ...]
+# [BOOST_COMPONENTS <pkg> ...]
+# [EXTRA_PACKAGE_OPTIONS <opt> ...]
+# [COMPILE_FLAGS <flags>]
+# [SYSTEM <bool> [ <script_to_compile> ]])
+# ------------------------------------------------------------------------------
+function(package_declare pkg)
+ package_get_name(${pkg} _pkg_name)
+ _package_set_real_name(${_pkg_name} ${pkg})
+ _package_set_filename(${_pkg_name} "${CMAKE_CURRENT_LIST_FILE}")
+
+ _package_set_sources_folder(${_pkg_name} "${_current_src_folder}")
+
+ if(_current_test_folder)
+ _package_set_tests_folder(${_pkg_name} "${_current_test_folder}")
+ endif()
- foreach(_dep ${ARGN})
- package_opt_name (${_dep} _dep_name)
- mark_as_advanced(${_dep_name})
- add_external_package_dependencies(${PKG} ${_dep})
- endforeach()
-endmacro()
+ if(_current_manual_folder)
+ _package_set_manual_folder(${_pkg_name} "${_current_manual_folder}")
+ endif()
-#===============================================================================
-macro(_add_package_dependencies PKG DEP _dep_name)
- package_pkg_name (${PKG} _opt_name)
- package_desc_name(${DEP} _var_dep_desc)
- package_pkg_name (${DEP} _dep_pkg_name)
+ 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})
- if (NOT ${_opt_name}_dependencies)
- set(${_opt_name}_dependencies)
- endif()
+ cmake_parse_arguments(_opt_pkg
+ "EXTERNAL;NOT_OPTIONAL;META;ADVANCED"
+ "DEFAULT;DESCRIPTION"
+ "DEPENDS;EXTRA_PACKAGE_OPTIONS;COMPILE_FLAGS;BOOST_COMPONENTS;SYSTEM"
+ ${ARGN})
- list(APPEND ${_opt_name}_dependencies ${_dep_pkg_name})
- list(REMOVE_DUPLICATES ${_opt_name}_dependencies)
+ if(_opt_pkg_UNPARSED_ARGUMENTS)
+ message("You gave to many arguments while registering the package ${pkg} \"${_opt_pkg_UNPARSED_ARGUMENTS}\"")
+ endif()
- set(${_opt_name}_dependencies ${${_opt_name}_dependencies} CACHE INTERNAL "List of dependencies for package ${_opt_name}" FORCE)
+ # 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()
- cmake_debug_message(PackagesSystem "add_package_dependecies: add dependence between ${_opt_name} and ${_dep_name}")
- set(_dep_desc ${_var_dep_desc})
+ _package_declare_option(${_pkg_name})
- cmake_debug_message(PackagesSystem "add_package_dependecies: ON dependencies of ${_dep_name} are: ${${_dep_name}_DEPS}")
- cmake_debug_message(PackagesSystem "add_package_dependecies: saved value for ${_dep_name} is: ${${_dep_name}_OLD}")
- if(${_opt_name})
- if("${${_dep_name}_DEPS}" STREQUAL "")
- cmake_debug_message(PackagesSystem "add_package_dependecies: Save dep state ${_dep_name}:${${_dep_name}}")
- set(${_dep_name}_OLD ${${_dep_name}} CACHE INTERNAL "${_dep_desc}" FORCE)
- endif()
+ # set description
+ if(_opt_pkg_DESCRIPTION)
+ _package_set_description(${_pkg_name} ${_opt_pkg_DESCRIPTION})
+ else()
+ _package_set_description(${_pkg_name} "")
+ endif()
- cmake_debug_message(PackagesSystem "add_package_dependecies: force value to ON ${_dep_name}")
- set(${_dep_name} ON CACHE BOOL "${_dep_desc}" FORCE)
+ _package_get_option_name(${_pkg_name} _option_name)
+ _package_get_description(${_pkg_name} _description)
- list(FIND ${_dep_name}_DEPS ${_opt_name} pos)
- if(pos EQUAL -1)
- list(APPEND ${_dep_name}_DEPS ${_opt_name})
- set(${_dep_name}_DEPS ${${_dep_name}_DEPS} CACHE INTERNAL "Dependencies ON with package ${_dep_name}" FORCE)
+ # 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()
- list(LENGTH ${_dep_name}_DEPS len)
- list(FIND ${_dep_name}_DEPS ${_opt_name} pos)
- if((len EQUAL 1) AND (NOT pos EQUAL -1))
- cmake_debug_message(PackagesSystem "add_package_dependecies: Restore state ${_dep_name}:${${_dep_name}} (${pos})")
- set(${_dep_name} ${${_dep_name}_OLD} CACHE BOOL "${_dep_desc}" FORCE)
- unset(${_dep_name}_OLD CACHE)
+ option(${_option_name} "${_description}" ${_default})
+ if(_opt_pkg_ADVANCED OR _opt_pkg_EXTERNAL)
+ mark_as_advanced(${_option_name})
endif()
+ endif()
- if(NOT pos EQUAL -1)
- list(REMOVE_AT ${_dep_name}_DEPS ${pos})
- set(${_dep_name}_DEPS ${${_dep_name}_DEPS} CACHE INTERNAL "Nb dependencies with package ${_dep_name}" FORCE)
+ # 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()
-endmacro()
+ # 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()
-#===============================================================================
-macro(add_internal_package_dependencies PKG DEP)
- package_pkg_name (${DEP} _dep_name)
- _add_package_dependencies(${PKG} ${DEP} ${_dep_name})
-endmacro()
+ # 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()
-#===============================================================================
-macro(add_external_package_dependencies PKG DEP)
- package_opt_name (${DEP} _dep_name)
- _add_package_dependencies(${PKG} ${DEP} ${_dep_name})
-endmacro()
+ # register the compilation flags
+ if(_opt_pkg_COMPILE_FLAGS)
+ _package_set_compile_flags(${_pkg_name} "${_opt_pkg_COMPILE_FLAGS}")
+ endif()
+
+ # set the boost dependencies
+ if(_opt_pkg_BOOST_COMPONENTS)
+ _package_set_boost_component_needed(${_pkg_name} "${_opt_pkg_BOOST_COMPONENTS}")
+ endif()
+
+endfunction()
+
+# ------------------------------------------------------------------------------
+# declare the source files of a given package
+#
+# package_declare_sources(<package> <list of sources>
+# SOURCES <source file> ...
+# PUBLIC_HEADER <header file> ...
+# PRIVATE_HEADER <header file> ...)
+# ------------------------------------------------------------------------------
+function(package_declare_sources pkg)
+ package_get_name(${pkg} _pkg_name)
+
+ # get 3 lists, if none of the options given try to distinguish the different lists
+ cmake_parse_arguments(_opt_pkg
+ ""
+ ""
+ "SOURCES;PUBLIC_HEADERS;PRIVATE_HEADERS"
+ ${ARGN})
+
+ set(_tmp_srcs ${_opt_pkg_SOURCES})
+ set(_tmp_pub_hdrs ${_opt_pkg_PUBLIC_HEADER})
+ set(_tmp_pri_hdrs ${_opt_pkg_PRIVATE_HEADERS})
+
+ foreach(_file ${_opt_pkg_UNPARSED_ARGUMENTS})
+ if(${_file} MATCHES ".*inline.*\\.cc")
+ list(APPEND _tmp_pub_hdrs ${_file})
+ elseif(${_file} MATCHES ".*\\.h+")
+ list(APPEND _tmp_pub_hdrs ${_file})
+ else()
+ list(APPEND _tmp_srcs ${_file})
+ endif()
+ endforeach()
+
+ _package_get_sources_folder(${_pkg_name} _src_folder)
+
+ foreach(_type _srcs _pub_hdrs _pri_hdrs)
+ set(${_type})
+ foreach(_file ${_tmp${_type}})
+ # get the full name
+ list(APPEND ${_type} "${_src_folder}/${_file}")
+ endforeach()
+ endforeach()
+
+ set(${_pkg_name}_SRCS "${_srcs}"
+ CACHE INTERNAL "List of sources files" FORCE)
+ set(${_pkg_name}_PUBLIC_HEADERS "${_pub_hdrs}"
+ CACHE INTERNAL "List of public header files" FORCE)
+ set(${_pkg_name}_PRIVATE_HEADERS "${_pri_hdrs}"
+ CACHE INTERNAL "List of private header files" FORCE)
+endfunction()
diff --git a/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake b/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
new file mode 100644
index 000000000..b457ccc27
--- /dev/null
+++ b/cmake/Modules/CMakePackagesSystemGlobalFunctions.cmake
@@ -0,0 +1,98 @@
+#===============================================================================
+# @file CMakePackagesSystem.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+
+# ==============================================================================
+# Package system meta functions
+# ==============================================================================
+function(package_set_project_variable variable)
+ string(TOUPPER ${PROJECT_NAME} _u_project)
+ set(${_u_project}_${variable} "${ARGN}" CACHE INTERNAL "" FORCE)
+endfunction()
+
+function(package_get_project_variable variable value_out)
+ string(TOUPPER ${PROJECT_NAME} _u_project)
+ set(${value_out} ${${_u_project}_${variable}} PARENT_SCOPE)
+endfunction()
+
+# ==============================================================================
+function(_package_set_variable variable pkg_name)
+ set(${pkg_name}_${variable} ${ARGN} CACHE INTERNAL "" FORCE)
+endfunction()
+
+function(_package_get_variable variable pkg_name value)
+ #unset(${value} PARENT_SCOPE)
+ if(DEFINED ${pkg_name}_${variable})
+ set(${value} ${${pkg_name}_${variable}} PARENT_SCOPE)
+ elseif(DEFINED ARGN)
+ set(${value} ${ARGN} PARENT_SCOPE)
+ else()
+ set(${value} PARENT_SCOPE)
+ endif()
+endfunction()
+
+# ==============================================================================
+function(_package_variable_unset variable pkg_name)
+ unset(${pkg_name}_${variable} CACHE)
+endfunction()
+
+# ==============================================================================
+function(_package_add_to_variable variable pkg_name)
+ _package_get_variable(${variable} ${pkg_name} _tmp_list)
+ list(APPEND _tmp_list ${ARGN})
+ if(_tmp_list)
+ list(REMOVE_DUPLICATES _tmp_list)
+ endif()
+ _package_set_variable(${variable} ${pkg_name} ${_tmp_list})
+endfunction()
+
+function(_package_remove_from_variable variable pkg_name value)
+ _package_get_variable(${variable} ${pkg_name} _tmp_list)
+ list(LENGTH _tmp_list _length)
+ if(_length GREATER 0)
+ list(REMOVE_ITEM _tmp_list ${value})
+ _package_set_variable(${variable} ${pkg_name} ${_tmp_list})
+ endif()
+endfunction()
+
+# ==============================================================================
+function(_package_get_variable_for_activated variable values)
+ set(_list_values)
+ package_get_all_activated_packages(_activated_list)
+ foreach(_pkg_name ${_activated_list})
+ _package_get_variable(${variable} ${_pkg_name} _value)
+ list(APPEND _list_values ${_value})
+ endforeach()
+
+ if (_list_values)
+ list(REMOVE_DUPLICATES _list_values)
+ endif()
+
+ set(${values} ${_list_values} PARENT_SCOPE)
+endfunction()
+
+# ==============================================================================
diff --git a/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake b/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
new file mode 100644
index 000000000..7f8ced8c8
--- /dev/null
+++ b/cmake/Modules/CMakePackagesSystemPrivateFunctions.cmake
@@ -0,0 +1,875 @@
+#===============================================================================
+# @file CMakePackagesSystem.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+# ==============================================================================
+# "Private" Accessors
+# ==============================================================================
+# ------------------------------------------------------------------------------
+# Real name
+# ------------------------------------------------------------------------------
+function(_package_get_real_name pkg_name real_name)
+ set(${real_name} ${${pkg_name}} PARENT_SCOPE)
+endfunction()
+
+function(_package_set_real_name pkg_name real_name)
+ set(${pkg_name} ${real_name} CACHE INTERNAL "" FORCE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Option name
+# ------------------------------------------------------------------------------
+function(_package_declare_option pkg_name)
+ string(TOUPPER "${PROJECT_NAME}" _project)
+ _package_get_real_name(${pkg_name} _real_name)
+ string(TOUPPER "${_real_name}" _u_package)
+
+ _package_get_nature(${pkg_name} _nature)
+
+ if(${_nature} MATCHES "internal" OR ${_nature} MATCHES "meta")
+ set(_opt_name ${_project}_${_u_package})
+ elseif(${_nature} MATCHES "external")
+ set(_opt_name ${_project}_USE_${_u_package})
+ else()
+ set(_opt_name UNKNOWN_NATURE_${_project}_${_u_package})
+ endif()
+
+ _package_set_variable(OPTION_NAME ${pkg_name} ${_opt_name})
+endfunction()
+
+function(_package_get_option_name pkg_name opt_name)
+ _package_get_variable(OPTION_NAME ${pkg_name} _opt_name)
+ set(${opt_name} ${_opt_name} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Set if system package or compile external lib
+# ------------------------------------------------------------------------------
+function(_package_set_system_option pkg_name default)
+ string(TOUPPER "${PROJECT_NAME}" _project)
+ _package_get_real_name(${pkg_name} _real_name)
+ string(TOUPPER "${_real_name}" _u_package)
+
+ option(${_project}_USE_SYSTEM_${_u_package}
+ "Should akantu compile the third-party: \"${_real_name}\"" ${default})
+ mark_as_advanced(${_project}_USE_SYSTEM_${_u_package})
+endfunction()
+
+function(_package_use_system pkg_name use)
+ string(TOUPPER "${PROJECT_NAME}" _project)
+ _package_get_real_name(${pkg_name} _real_name)
+ string(TOUPPER "${_real_name}" _u_package)
+ if(DEFINED ${_project}_USE_SYSTEM_${_u_package})
+ set(${use} ${${_project}_USE_SYSTEM_${_u_package}} PARENT_SCOPE)
+ else()
+ set(${use} TRUE PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_package_set_system_script pkg_name script)
+ _package_set_variable(COMPILE_SCRIPT ${pkg_name} "${script}")
+endfunction()
+
+function(_package_add_third_party_script_variable pkg_name var)
+ _package_set_variable(VARIABLE_${var} ${pkg_name} "${ARGN}")
+ set(${var} ${ARGN} PARENT_SCOPE)
+endfunction()
+
+function(_package_load_third_party_script pkg_name)
+ if(${pkg_name}_COMPILE_SCRIPT)
+ # set the stored variable
+ get_cmake_property(_all_vars VARIABLES)
+ foreach(_var ${_all_vars})
+ if(_var MATCHES "^${pkg_name}_VARIABLE_.*")
+ string(REPLACE "${pkg_name}_VARIABLE_" "" _orig_var "${_var}")
+ set(${_orig_var} ${${_var}})
+ endif()
+ endforeach()
+
+ _package_get_real_name(${pkg_name} _name)
+ string(TOUPPER "${_name}" _u_name)
+
+ _package_get_option_name(${pkg_name} _opt_name)
+ if(${_opt_name}_VERSION)
+ set(_version "${${_opt_name}_VERSION}")
+ set(${_u_name}_VERSION "${_version}" CACHE INTERNAL "" FORCE)
+ elseif(${_u_name}_VERSION)
+ set(_version "${${_u_name}_VERSION}")
+ endif()
+
+ # load the script
+ include(ExternalProject)
+ include(${${pkg_name}_COMPILE_SCRIPT})
+
+ if(${_u_name}_LIBRARIES)
+ _package_set_libraries(${pkg_name} ${${_u_name}_LIBRARIES})
+ list(APPEND _required_vars ${_u_name}_LIBRARIES)
+ endif()
+ if(${_u_name}_INCLUDE_DIR)
+ _package_set_include_dir(${pkg_name} ${${_u_name}_INCLUDE_DIR})
+ list(APPEND _required_vars ${_u_name}_INCLUDE_DIR)
+ endif()
+
+ include(FindPackageHandleStandardArgs)
+ if(CMAKE_VERSION VERSION_GREATER 2.8.12)
+ find_package_handle_standard_args(${_name}
+ REQUIRED_VARS ${_required_vars}
+ VERSION_VAR _version
+ FAIL_MESSAGE "Something was not configured by a the third-party script for ${_name}"
+ )
+ else()
+ find_package_handle_standard_args(${_name}
+ "Something was not configured by a the third-party script for ${_name}"
+ ${_required_vars}
+ )
+ endif()
+ endif()
+ set(${pkg_name}_USE_SYSTEM_PREVIOUS FALSE CACHE INTERNAL "" FORCE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Nature
+# ------------------------------------------------------------------------------
+function(_package_set_nature pkg_name nature)
+ _package_set_variable(NATURE ${pkg_name} ${nature})
+endfunction()
+
+function(_package_get_nature pkg_name nature)
+ _package_get_variable(NATURE ${pkg_name} _nature "unknown")
+ set(${nature} ${_nature} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Description
+# ------------------------------------------------------------------------------
+function(_package_set_description pkg_name desc)
+ _package_set_variable(DESC ${pkg_name} ${desc})
+endfunction()
+
+function(_package_get_description pkg_name desc)
+ _package_get_variable(DESC ${pkg_name} _desc "No description set for the package ${${pkg_name}} (${pkg_name})")
+ set(${desc} ${_desc} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Package file name
+# ------------------------------------------------------------------------------
+function(_package_set_filename pkg_name file)
+ _package_set_variable(FILE ${pkg_name} ${file})
+endfunction()
+
+function(_package_get_filename pkg_name file)
+ _package_get_variable(FILE ${pkg_name} _file "No filename set for the package ${${pkg_name}}")
+ set(${file} ${_file} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Source folder
+# ------------------------------------------------------------------------------
+function(_package_set_sources_folder pkg_name src_folder)
+ _package_set_variable(SRC_FOLDER ${pkg_name} ${src_folder})
+endfunction()
+
+function(_package_get_sources_folder pkg_name src_folder)
+ _package_get_variable(SRC_FOLDER ${pkg_name} _src_folder)
+ set(${src_folder} ${_src_folder} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Test folder
+# ------------------------------------------------------------------------------
+function(_package_set_tests_folder pkg_name test_folder)
+ _package_set_variable(TEST_FOLDER ${pkg_name} ${test_folder})
+endfunction()
+
+function(_package_get_tests_folder pkg_name test_folder)
+ _package_get_variable(TEST_FOLDER ${pkg_name} _test_folder)
+ set(${test_folder} ${_test_folder} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Manual folder
+# ------------------------------------------------------------------------------
+function(_package_set_manual_folder pkg_name manual_folder)
+ _package_set_variable(MANUAL_FOLDER ${pkg_name} ${manual_folder})
+endfunction()
+
+function(_package_get_manual_folder pkg_name manual_folder)
+ _package_get_variable(MANUAL_FOLDER ${pkg_name} _manual_folder)
+ set(${manual_folder} ${_manual_folder} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Extra option for the find_package
+# ------------------------------------------------------------------------------
+function(_package_set_find_package_extra_options pkg_name)
+ _package_set_variable(FIND_PKG_OPTIONS ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_find_package_extra_options pkg_name options)
+ _package_get_variable(FIND_PKG_OPTIONS ${pkg_name} _options)
+ set(${options} ${_options} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Compilation flags
+# ------------------------------------------------------------------------------
+function(_package_set_compile_flags pkg_name)
+ _package_set_variable(COMPILE_FLAGS ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_compile_flags pkg_name flags)
+ _package_get_variable(COMPILE_FLAGS ${pkg_name} _flags)
+ set(${flags} ${_flags} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Include dir
+# ------------------------------------------------------------------------------
+function(_package_set_include_dir pkg_name)
+ _package_set_variable(INCLUDE_DIR ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_include_dir pkg_name include_dir)
+ _package_get_variable(INCLUDE_DIR ${pkg_name} _include_dir "")
+ set(${include_dir} ${_include_dir} PARENT_SCOPE)
+endfunction()
+
+function(_package_add_include_dir pkg_name)
+ _package_add_to_variable(INCLUDE_DIR ${pkg_name} ${ARGN})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Libraries
+# ------------------------------------------------------------------------------
+function(_package_set_libraries pkg_name)
+ _package_set_variable(LIBRARIES ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_libraries pkg_name libraries)
+ _package_get_variable(LIBRARIES ${pkg_name} _libraries "")
+ set(${libraries} ${_libraries} PARENT_SCOPE)
+endfunction()
+
+function(_package_add_libraries pkg_name)
+ _package_add_to_variable(LIBRARIES ${pkg_name} ${ARGN})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Extra dependencies like custom commands of ExternalProject
+# ------------------------------------------------------------------------------
+function(_package_add_extra_dependency pkg_name)
+ _package_add_to_variable(EXTRA_DEPENDENCY ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_rm_extra_dependency pkg_name dep)
+ _package_remove_from_variable(EXTRA_DEPENDENCY ${pkg_name} ${dep})
+endfunction()
+
+function(_package_set_extra_dependencies pkg)
+ _package_set_variable(EXTRA_DEPENDENCY ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_extra_dependencies pkg deps)
+ _package_get_variable(EXTRA_DEPENDENCY ${pkg_name} _deps "")
+ set(${deps} ${_deps} PARENT_SCOPE)
+endfunction()
+
+function(_package_unset_extra_dependencies pkg_name)
+ _package_variable_unset(EXTRA_DEPENDENCY ${pkg_name})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Activate/deactivate
+# ------------------------------------------------------------------------------
+function(_package_activate pkg_name)
+ _package_set_variable(STATE ${pkg_name} ON)
+endfunction()
+
+function(_package_deactivate pkg_name)
+ _package_set_variable(STATE ${pkg_name} OFF)
+endfunction()
+
+function(_package_is_activated pkg_name act)
+ _package_get_variable(STATE ${pkg_name} _state OFF)
+ if(_state)
+ set(${act} TRUE PARENT_SCOPE)
+ else()
+ set(${act} FALSE PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_package_is_deactivated pkg_name act)
+ _package_get_variable(STATE ${pkg_name} _state OFF)
+ if(NOT _state)
+ set(${act} TRUE PARENT_SCOPE)
+ else()
+ set(${act} FALSE PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_package_unset_activated pkg_name)
+ _package_variable_unset(STATE ${pkg_name})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Callbacks
+# ------------------------------------------------------------------------------
+function(_package_on_enable_script pkg_name script)
+ string(TOLOWER "${pkg_name}" _l_pkg_name)
+ set(_output_file "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_l_pkg_name}.cmake")
+ file(WRITE "${_output_file}"
+ "${script}")
+ _package_set_variable(CALLBACK_SCRIPT ${pkg_name} "${_output_file}")
+endfunction()
+
+function(_package_get_callback_script pkg_name filename)
+ _package_get_variable(CALLBACK_SCRIPT ${pkg_name} _filename NOTFOUND)
+ set(${filename} ${_filename} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Export list
+# ------------------------------------------------------------------------------
+function(_package_add_to_export_list pkg_name)
+ _package_add_to_variable(EXPORT_LIST ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_export_list pkg_name export_list)
+ _package_get_variable(EXPORT_LIST ${pkg_name} _export_list)
+ set(${export_list} ${_export_list} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Direct dependencies
+# ------------------------------------------------------------------------------
+function(_package_add_dependencies pkg_name)
+ _package_add_to_variable(DEPENDENCIES ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_dependencies pkg_name dependencies)
+ _package_get_variable(DEPENDENCIES ${pkg_name} _dependencies)
+ set(${dependencies} ${_dependencies} PARENT_SCOPE)
+endfunction()
+
+function(_package_unset_dependencies pkg_name)
+ _package_variable_unset(DEPENDENCIES ${pkg_name})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Functions to handle reverse dependencies
+# ------------------------------------------------------------------------------
+function(_package_set_rdependencies pkg_name)
+ _package_set_variable(RDEPENDENCIES ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_rdependencies pkg_name rdependencies)
+ _package_get_variable(RDEPENDENCIES ${pkg_name} _rdependencies)
+ set(${rdependencies} ${_rdependencies} PARENT_SCOPE)
+endfunction()
+
+function(_package_add_rdependency pkg_name rdep)
+ # store the reverse dependency
+ _package_add_to_variable(RDEPENDENCIES ${pkg_name} ${rdep})
+endfunction()
+
+function(_package_remove_rdependency pkg_name rdep)
+ _package_remove_from_variable(RDEPENDENCIES ${pkg_name} ${rdep})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Function to handle forcing dependencies (Package turn ON that enforce their
+# dependencies ON)
+# ------------------------------------------------------------------------------
+function(_package_set_fdependencies pkg_name)
+ _package_set_variable(FDEPENDENCIES ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_fdependencies pkg_name fdependencies)
+ _package_get_variable(FDEPENDENCIES ${pkg_name} _fdependencies)
+ set(${fdependencies} ${_fdependencies} PARENT_SCOPE)
+endfunction()
+
+function(_package_add_fdependency pkg_name fdep)
+ # store the reverse dependency
+ _package_add_to_variable(FDEPENDENCIES ${pkg_name} ${fdep})
+endfunction()
+
+function(_package_remove_fdependency pkg_name fdep)
+ _package_remove_from_variable(FDEPENDENCIES ${pkg_name} ${fdep})
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Documentation related functions
+# ------------------------------------------------------------------------------
+function(_package_set_documentation_files pkg_name)
+ _package_set_variable(DOCUMENTATION_FILES ${pkg_name} ${ARGN})
+endfunction()
+
+function(_package_get_documentation_files pkg_name doc_files)
+ _package_get_variable(DOCUMENTATION_FILES ${pkg_name} _doc_files "")
+ set(${doc_files} ${_doc_files} PARENT_SCOPE)
+endfunction()
+
+function(_package_set_documentation pkg_name)
+ # \n replaced by && and \\ by ££ to avoid cache problems
+ set(_doc_str "")
+ foreach(_str ${ARGN})
+ set(_doc_str "${_doc_str}&&${_str}")
+ endforeach()
+
+ string(REPLACE "\\" "££" _doc_escaped "${_doc_str}")
+
+ _package_set_variable(DOCUMENTATION ${pkg_name} "${_doc_str}")
+endfunction()
+
+function(_package_get_documentation pkg_name _doc)
+ # \n replaced by && and \\ by ££ to avoid cache problems
+ _package_get_variable(DOCUMENTATION ${pkg_name} _doc_tmp "")
+
+ string(REPLACE "££" "\\" _doc_escaped "${_doc_tmp}")
+ string(REPLACE "&&" "\n" _doc_newlines "${_doc_escaped}")
+ set(${_doc} "${_doc_newlines}" PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Special boost thingy
+# ------------------------------------------------------------------------------
+function(_package_set_boost_component_needed pkg_name)
+ _package_add_to_variable(BOOST_COMPONENTS_NEEDED ${pkg_name} ${ARGN})
+ package_get_name(Boost _boost_pkg_name)
+ _package_add_dependencies(${pkg_name} ${_boost_pkg_name})
+endfunction()
+
+function(_package_get_boost_component_needed pkg_name needed)
+ _package_get_variable(BOOST_COMPONENTS_NEEDED ${pkg_name} _needed)
+ set(${needed} ${_needed} PARENT_SCOPE)
+endfunction()
+
+function(_package_load_boost_components)
+ string(TOUPPER ${PROJECT_NAME} _project)
+
+ _package_get_variable_for_activated(BOOST_COMPONENTS_NEEDED _boost_needed_components)
+ package_get_name(Boost _pkg_name)
+
+ if(_boost_needed_components)
+ message(STATUS "Looking for Boost liraries: ${_boost_needed_components}")
+ foreach(_comp ${_boost_needed_components})
+ find_package(Boost COMPONENTS ${_comp} QUIET)
+ string(TOUPPER ${_comp} _u_comp)
+ if(Boost_${_u_comp}_FOUND)
+ message(STATUS " ${_comp}: FOUND")
+ package_set_project_variable(BOOST_${_u_comp} TRUE)
+
+ # Generate the libraries for the package
+ _package_add_libraries(${_pkg_name} ${Boost_${_u_comp}_LIBRARY})
+ else()
+ message(STATUS " ${_comp}: NOT FOUND")
+ endif()
+ endforeach()
+ endif()
+endfunction()
+
+# ------------------------------------------------------------------------------
+# get the list of source files for a given package
+# ------------------------------------------------------------------------------
+function(_package_get_source_files pkg_name SRCS PUBLIC_HEADERS PRIVATE_HEADERS)
+ string(TOUPPER ${PROJECT_NAME} _project)
+
+ set(tmp_SRCS)
+ set(tmp_PUBLIC_HEADERS)
+ set(tmp_PRIVATE_HEADERS)
+
+ foreach(_type SRCS PUBLIC_HEADERS PRIVATE_HEADERS)
+ foreach(_file ${${pkg_name}_${_type}})
+ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" _rel_file "${_file}")
+ list(APPEND tmp_${_type} "${_rel_file}")
+ endforeach()
+ endforeach()
+
+ set(${SRCS} ${tmp_SRCS} PARENT_SCOPE)
+ set(${PUBLIC_HEADERS} ${tmp_PUBLIC_HEADERS} PARENT_SCOPE)
+ set(${PRIVATE_HEADERS} ${tmp_PRIVATE_HEADERS} PARENT_SCOPE)
+endfunction()
+
+# ==============================================================================
+# Internal functions
+# ==============================================================================
+# ------------------------------------------------------------------------------
+# Build the reverse dependencies from the dependencies
+# ------------------------------------------------------------------------------
+function(_package_build_rdependencies)
+ package_get_all_packages(_pkg_list)
+
+ # set empty lists
+ foreach(_pkg_name ${_pkg_list})
+ set(${_pkg_name}_rdeps)
+ endforeach()
+
+ # fill the dependencies list
+ foreach(_pkg_name ${_pkg_list})
+ _package_get_dependencies(${_pkg_name} _deps)
+ foreach(_dep_name ${_deps})
+ list(APPEND ${_dep_name}_rdeps ${_pkg_name})
+ endforeach()
+ endforeach()
+
+ # clean and set the reverse dependencies
+ foreach(_pkg_name ${_pkg_list})
+ if(${_pkg_name}_rdeps)
+ list(REMOVE_DUPLICATES ${_pkg_name}_rdeps)
+ _package_set_rdependencies(${_pkg_name} ${${_pkg_name}_rdeps})
+ endif()
+ endforeach()
+endfunction()
+
+# ------------------------------------------------------------------------------
+# This function resolve the dependance order run the needed find_packages
+# ------------------------------------------------------------------------------
+function(_package_load_packages)
+ package_get_all_packages(_pkg_list)
+
+ # Activate the dependencies of activated package and generate an ordered list
+ # of dependencies
+ set(ordered_loading_list)
+ foreach(_pkg_name ${_pkg_list})
+ _package_load_dependencies_package(${_pkg_name} ordered_loading_list)
+ endforeach()
+
+ # Load the packages in the propoer order
+ foreach(_pkg_name ${ordered_loading_list})
+ _package_get_option_name(${_pkg_name} _option_name)
+
+ if(${_option_name})
+ _package_load_package(${_pkg_name})
+ else()
+ # deactivate the packages than can already be deactivated
+ _package_deactivate(${_pkg_name})
+ endif()
+ endforeach()
+
+ # generates the activated and unactivated lists of packages
+ set(_packages_activated)
+ set(_packages_deactivated)
+ foreach(_pkg_name ${_pkg_list})
+ _package_is_activated(${_pkg_name} _active)
+ if(_active)
+ list(APPEND _packages_activated ${_pkg_name})
+ else()
+ list(APPEND _packages_deactivated ${_pkg_name})
+ endif()
+ endforeach()
+
+ # generate the list usable by the calling code
+ package_set_project_variable(ACTIVATED_PACKAGE_LIST "${_packages_activated}")
+ package_set_project_variable(DEACTIVATED_PACKAGE_LIST "${_packages_deactivated}")
+endfunction()
+
+
+
+# ------------------------------------------------------------------------------
+# This load an external package and recursively all its dependencies
+# ------------------------------------------------------------------------------
+function(_package_load_dependencies_package pkg_name loading_list)
+ # Get packages informations
+ _package_get_option_name(${pkg_name} _pkg_option_name)
+ _package_get_dependencies(${pkg_name} _dependencies)
+
+ # handle the dependencies
+ foreach(_dep_name ${_dependencies})
+ _package_get_description(${_dep_name} _dep_desc)
+ _package_get_option_name(${_dep_name} _dep_option_name)
+
+ _package_get_fdependencies(${_dep_name} _fdeps)
+ if(${_pkg_option_name})
+ if("${_fdeps}" STREQUAL "")
+ set(${_dep_name}_OLD ${${_dep_option_name}} CACHE INTERNAL "" FORCE)
+ endif()
+
+ # set the option to on
+ set(${_dep_option_name} ON CACHE BOOL "${_dep_desc}" FORCE)
+
+ # store the reverse dependency
+ _package_add_fdependency(${_dep_name} ${pkg_name})
+ else()
+ # check if this is the last reverse dependency
+ list(LENGTH _fdeps len)
+ list(FIND _fdeps ${pkg_name} pos)
+ if((len EQUAL 1) AND (NOT pos EQUAL -1))
+ set(${_dep_option_name} ${${_dep_name}_OLD} CACHE BOOL "${_dep_desc}" FORCE)
+ unset(${_dep_name}_OLD CACHE)
+ endif()
+
+ # remove the pkg_name form the reverse dependency
+ _package_remove_fdependency(${_dep_name} ${pkg_name})
+ endif()
+
+ # recusively load the dependencies
+ _package_load_dependencies_package(${_dep_name} ${loading_list})
+ endforeach()
+
+ # get the compile flags
+ _package_get_compile_flags(${pkg_name} _pkg_comile_flags)
+
+ # if package option is on add it in the list
+ if(${_pkg_option_name})
+ list(FIND ${loading_list} ${pkg_name} _pos)
+ if(_pos EQUAL -1)
+ set(_tmp_loading_list ${${loading_list}})
+ list(APPEND _tmp_loading_list ${pkg_name})
+ set(${loading_list} "${_tmp_loading_list}" PARENT_SCOPE)
+ endif()
+
+ #add the comilation flags if needed
+ if(_pkg_comile_flags)
+ add_flags(cxx ${_pkg_comile_flags})
+ endif()
+ else()
+ #remove the comilation flags if needed
+ if(_pkg_comile_flags)
+ remove_flags(cxx ${_pkg_comile_flags})
+ endif()
+ endif()
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Load the package if it is an external one
+# ------------------------------------------------------------------------------
+function(_package_load_package pkg_name)
+ # load the package if it is an external
+ _package_get_nature(${pkg_name} _nature)
+ if(${_nature} MATCHES "external")
+ _package_use_system(${pkg_name} _use_system)
+
+ set(_activated TRUE)
+ if(_use_system)
+ _package_load_external_package(${pkg_name} _activated)
+ else()
+ _package_load_third_party_script(${pkg_name})
+ endif()
+
+ if(_activated)
+ _package_activate(${pkg_name})
+ elseif()
+ _package_deactivate(${pkg_name})
+ endif()
+ else(${_nature})
+ _package_activate(${pkg_name})
+ endif()
+endfunction()
+
+
+# ------------------------------------------------------------------------------
+# Load external packages
+# ------------------------------------------------------------------------------
+function(_package_load_external_package pkg_name activate)
+ _package_get_real_name(${pkg_name} _real_name)
+ string(TOUPPER ${_real_name} _u_package)
+
+ if(NOT ${pkg_name}_USE_SYSTEM_PREVIOUS)
+ #if system was off before clear the cache of preset variables
+ get_cmake_property(_all_vars VARIABLES)
+ foreach(_var ${_all_vars})
+ if(_var MATCHES "^${_u_package}_.*")
+ unset(${_var} CACHE)
+ endif()
+ endforeach()
+ set(${pkg_name}_USE_SYSTEM_PREVIOUS TRUE CACHE INTERNAL "" FORCE)
+ endif()
+
+ _package_get_find_package_extra_options(${pkg_name} _options)
+ if(_options)
+ cmake_parse_arguments(_opt_pkg "" "LANGUAGE" "PREFIX;FOUND;ARGS" ${_options})
+ if(_opt_pkg_UNPARSED_ARGUMENTS)
+ message("You passed too many options for the find_package related to ${${pkg_name}} \"${_opt_pkg_UNPARSED_ARGUMENTS}\"")
+ endif()
+ endif()
+
+ if(_opt_pkg_LANGUAGE)
+ foreach(_language ${_opt_pkg_LANGUAGE})
+ enable_language(${_language})
+ endforeach()
+ endif()
+
+
+ # find the package
+ find_package(${_real_name} REQUIRED ${_opt_pkg_ARGS})
+
+ # check if the package is found
+ if(_opt_pkg_PREFIX)
+ set(_package_prefix ${_opt_pkg_PREFIX})
+ else()
+ set(_package_prefix ${_u_package})
+ endif()
+
+ set(_act FALSE)
+ set(_prefix_to_consider)
+ if(DEFINED _opt_pkg_FOUND)
+ if(${_opt_pkg_FOUND})
+ set(_act TRUE)
+ set(_prefix_to_consider ${_package_prefix})
+ endif()
+ else()
+ foreach(_prefix ${_package_prefix})
+ if(${_prefix}_FOUND)
+ set(_act TRUE)
+ list(APPEND _prefix_to_consider ${_prefix})
+ endif()
+ endforeach()
+ endif()
+
+ if(_act)
+ foreach(_prefix ${_prefix_to_consider})
+ # Generate the include dir for the package
+ if(DEFINED ${_prefix}_INCLUDE_DIRS)
+ _package_set_include_dir(${pkg_name} ${${_prefix}_INCLUDE_DIRS})
+ elseif(DEFINED ${_prefix}_INCLUDE_DIR)
+ _package_set_include_dir(${pkg_name} ${${_prefix}_INCLUDE_DIR})
+ elseif(DEFINED ${_prefix}_INCLUDE_PATH)
+ _package_set_include_dir(${pkg_name} ${${_prefix}_INCLUDE_PATH})
+ endif()
+
+ # Generate the libraries for the package
+ if(DEFINED ${_prefix}_LIBRARIES)
+ _package_set_libraries(${pkg_name} ${${_prefix}_LIBRARIES})
+ elseif(DEFINED ${_prefix}_LIBRARY)
+ _package_set_libraries(${pkg_name} ${${_prefix}_LIBRARY})
+ endif()
+ endforeach()
+
+ _package_get_callback_script(${pkg_name} _script_file)
+ if(_script_file)
+ include("${_script_file}")
+ endif()
+ endif()
+ set(${activate} ${_act} PARENT_SCOPE)
+endfunction()
+
+# ------------------------------------------------------------------------------
+# Sanity check functions
+# ------------------------------------------------------------------------------
+function(_package_check_files_exists)
+ set(_message FALSE)
+
+ package_get_all_packages(_pkg_list)
+ foreach(_pkg_name ${_pkg_list})
+ set(_pkg_files
+ ${${_pkg_name}_SRCS}
+ ${${_pkg_name}_PUBLIC_HEADERS}
+ ${${_pkg_name}_PRIVATE_HEADERS}
+ )
+
+ _package_get_real_name(${_pkg_name} _real_name)
+
+ foreach(_file ${_pkg_files})
+ if(NOT EXISTS "${_file}")
+ if(NOT _message)
+ set(_message TRUE)
+ message("This file(s) is(are) present in a package but are not present on disk.")
+ endif()
+
+ message(" PACKAGE ${_real_name} FILE ${_file}")
+ endif()
+ endforeach()
+ endforeach()
+
+ if(_message)
+ message(SEND_ERROR "Please check the content of your packages to correct this warnings")
+ endif()
+endfunction()
+
+# ------------------------------------------------------------------------------
+function(_package_check_files_registered)
+ set(_pkg_files)
+ package_get_all_packages(_pkg_list)
+ # generates a file list of registered files
+ foreach(_pkg_name ${_pkg_list})
+ list(APPEND _pkg_files
+ ${${_pkg_name}_SRCS}
+ ${${_pkg_name}_PUBLIC_HEADERS}
+ ${${_pkg_name}_PRIVATE_HEADERS}
+ )
+ endforeach()
+
+ # generates the list of files in the source folders
+ set(_all_src_files)
+ foreach(_src_folder ${ARGN})
+ foreach(_ext "cc" "hh" "c" "h" "hpp")
+ file(GLOB_RECURSE _src_files "${_src_folder}/*.${_ext}")
+ list(APPEND _all_src_files ${_src_files})
+ endforeach()
+ endforeach()
+
+ if(_all_src_files)
+ list(REMOVE_DUPLICATES _all_src_files)
+ endif()
+
+ set(_not_registerd_files)
+ # check only sources files ine the source folders
+ foreach(_src_folder ${ARGN})
+ foreach(_file ${_all_src_files})
+ if("${_file}" MATCHES "${_src_folder}")
+ list(FIND _pkg_files "${_file}" _index)
+ if (_index EQUAL -1)
+ list(APPEND _not_registerd_files ${_file})
+ endif()
+ endif()
+ endforeach()
+ endforeach()
+
+ if(AUTO_MOVE_UNKNOWN_FILES)
+ file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/unknown_files)
+ endif()
+
+ # warn the user and move the files if needed
+ if(_not_registerd_files)
+ if(EXISTS ${PROJECT_BINARY_DIR}/missing_files_in_packages)
+ file(REMOVE ${PROJECT_BINARY_DIR}/missing_files_in_packages)
+ endif()
+
+ message("This files are present in the source folders but are not registered in any package")
+ foreach(_file ${_not_registerd_files})
+ message(" ${_file}")
+ if(AUTO_MOVE_UNKNOWN_FILES)
+ get_filename_component(_file_name ${_file} NAME)
+ file(RENAME ${_file} ${PROJECT_BINARY_DIR}/unknown_files/${_file_name})
+ endif()
+
+ file(APPEND ${PROJECT_BINARY_DIR}/missing_files_in_packages "${_file}
+")
+ endforeach()
+
+ if(AUTO_MOVE_UNKNOWN_FILES)
+ message(SEND_ERROR "The files where moved in the followinf folder ${PROJECT_BINARY_DIR}/unknown_files\n
+Please register them in the good package or clean the sources")
+ else()
+ message(SEND_ERROR "Please register them in the good package or clean the sources")
+ endif()
+
+ endif()
+endfunction()
+
+# ------------------------------------------------------------------------------
diff --git a/cmake/Modules/FindGMSH.cmake b/cmake/Modules/FindGMSH.cmake
index 0f3722fd9..94f8d7305 100644
--- a/cmake/Modules/FindGMSH.cmake
+++ b/cmake/Modules/FindGMSH.cmake
@@ -1,81 +1,82 @@
#===============================================================================
# @file FindGMSH.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Fri Oct 15 2010
# @date last modification: Tue Sep 09 2014
#
# @brief Find gmsh and delacre the add_mesh macro
#
# @section LICENSE
#
# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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)
- string(REPLACE "${CMAKE_SOURCE_DIR}/" "" _r_geo_file "${_geo_file}")
- string(REPLACE "${CMAKE_BINARY_DIR}/" "" _r_msh_file "${_msh_file}")
-
if(EXISTS ${_geo_file})
add_custom_command(
OUTPUT ${_msh_file}
DEPENDS ${_geo_file}
COMMAND ${GMSH}
ARGS -${DIM} -order ${ORDER} -optimize -o ${_msh_file} ${_geo_file} 2>&1 > /dev/null
COMMENT "Generating the ${DIM}D mesh ${_r_msh_file} (order ${ORDER}) form the geometry ${_r_geo_file}"
)
add_custom_target(${MESH_TARGET}
DEPENDS ${_msh_file})
set_target_properties(${MESH_TARGET} PROPERTIES RESSOURCES ${_geo_file})
#else(EXISTS ${_geo_file})
# message("File ${_geo_file} not found")
endif(EXISTS ${_geo_file})
endif(GMSH_FOUND)
endmacro(ADD_MESH)
diff --git a/cmake/Modules/FindMumps.cmake b/cmake/Modules/FindMumps.cmake
index d5e2293fd..fc2d1b504 100644
--- a/cmake/Modules/FindMumps.cmake
+++ b/cmake/Modules/FindMumps.cmake
@@ -1,112 +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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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 MUMPS_TYPE)
- set(MUMPS_TYPE par)
+set(_MUMPS_COMPONENTS "sequential" "parallel")
+
+if(NOT Mumps_FIND_COMPONENTS)
+ set(Mumps_FIND_COMPONENTS "parallel")
endif()
+#===============================================================================
+enable_language(Fortran)
-if("${MUMPS_TYPE}" STREQUAL "seq")
+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_TYPE}" STREQUAL "par")
- 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_LIBRARIES 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)
- mark_as_advanced(SCALAPACK_LIBRARIES)
- 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/FindNumpy.cmake b/cmake/Modules/FindNumpy.cmake
new file mode 100644
index 000000000..cf839e573
--- /dev/null
+++ b/cmake/Modules/FindNumpy.cmake
@@ -0,0 +1,69 @@
+#===============================================================================
+# @file FindNumpy.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @brief The find_package file for numpy
+#
+# @section LICENSE
+#
+# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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 191a76fef..3c96349ab 100644
--- a/cmake/Modules/FindPETSc.cmake
+++ b/cmake/Modules/FindPETSc.cmake
@@ -1,345 +1,345 @@
# - Try to find PETSc
# Once done this will define
#
# PETSC_FOUND - system has PETSc
# PETSC_INCLUDES - the PETSc include directories
# PETSC_LIBRARIES - Link these to use PETSc
# PETSC_COMPILER - Compiler used by PETSc, helpful to find a compatible MPI
# PETSC_DEFINITIONS - Compiler switches for using PETSc
# PETSC_MPIEXEC - Executable for running MPI programs
# PETSC_VERSION - Version string (MAJOR.MINOR.SUBMINOR)
#
# Usage:
# find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0
# find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler
# find_package(PETSc) - same as above
#
# Setting these changes the behavior of the search
# PETSC_DIR - directory in which PETSc resides
# PETSC_ARCH - build architecture
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
set(PETSC_VALID_COMPONENTS
C
CXX)
if(NOT PETSc_FIND_COMPONENTS)
set(PETSC_LANGUAGE_BINDINGS "C")
else()
# Right now, this is designed for compatability with the --with-clanguage option, so
# only allow one item in the components list.
list(LENGTH ${PETSc_FIND_COMPONENTS} components_length)
if(${components_length} GREATER 1)
message(FATAL_ERROR "Only one component for PETSc is allowed to be specified")
endif()
# This is a stub for allowing multiple components should that time ever come. Perhaps
# to also test Fortran bindings?
foreach(component ${PETSc_FIND_COMPONENTS})
list(FIND PETSC_VALID_COMPONENTS ${component} component_location)
if(${component_location} EQUAL -1)
message(FATAL_ERROR "\"${component}\" is not a valid PETSc component.")
else()
list(APPEND PETSC_LANGUAGE_BINDINGS ${component})
endif()
endforeach()
endif()
function (petsc_get_version)
if (EXISTS "${PETSC_DIR}/include/petscversion.h")
file (STRINGS "${PETSC_DIR}/include/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(RELEASE|MAJOR|MINOR|SUBMINOR|PATCH) ")
foreach (line ${vstrings})
string (REGEX REPLACE " +" ";" fields ${line}) # break line into three fields (the first is always "#define")
list (GET fields 1 var)
list (GET fields 2 val)
set (${var} ${val} PARENT_SCOPE)
set (${var} ${val}) # Also in local scope so we have access below
endforeach ()
if (PETSC_VERSION_RELEASE)
set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}p${PETSC_VERSION_PATCH}" PARENT_SCOPE)
else ()
# make dev version compare higher than any patch level of a released version
set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}.99" PARENT_SCOPE)
endif ()
else ()
message (SEND_ERROR "PETSC_DIR can not be used, ${PETSC_DIR}/include/petscversion.h does not exist")
endif ()
endfunction ()
find_path (PETSC_DIR include/petsc.h
HINTS ENV PETSC_DIR
PATHS
# Debian paths
/usr/lib/petscdir/3.3 /usr/lib/petscdir/3.2 /usr/lib/petscdir/3.1
/usr/lib/petscdir/3.0.0 /usr/lib/petscdir/2.3.3 /usr/lib/petscdir/2.3.2
$ENV{HOME}/petsc
DOC "PETSc Directory")
find_program (MAKE_EXECUTABLE NAMES make gmake)
if (NOT PETSC_ARCH)
if (NOT ENV{PETSC_ARCH})
set(_petsc_arches
linux-gnu-c-debug linux-gnu-c-opt # Debian defaults
x86_64-unknown-linux-gnu i386-unknown-linux-gnu)
else()
set(_petsc_arches $ENV{PETSC_ARCH}) # If set, use environment variable first)
endif()
else()
set (_petsc_arches
${PETSC_ARCH})
endif()
if (NOT PETSC_DIR)
if (NOT ENV{PETSC_DIR})
set(PETSC_DIR /usr/lib/petsc)
else()
set(PETSC_DIR $ENV{PETSC_DIR}) # If set, use environment variable first)
endif()
endif()
foreach (arch ${_petsc_arches})
set (petscconf "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE)
find_path (petscconf petscconf.h
HINTS ${PETSC_DIR}
PATH_SUFFIXES ${arch}/include bmake/${arch}
NO_DEFAULT_PATH)
if(petscconf)
set (PETSC_ARCH "${arch}" CACHE STRING "PETSc build architecture")
set(_petsc_dir ${PETSC_DIR})
set (PETSC_DIR "${_petsc_dir}" CACHE STRING "PETSc build directory")
break()
endif()
endforeach()
set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS
INCLUDE_DIR INCLUDE_CONF)
include (FindPackageMultipass)
#find_package_multipass (PETSc petsc_config_current
# STATES DIR ARCH
# DEPENDENTS INCLUDES LIBRARIES COMPILER MPIEXEC EXECUTABLE_RUNS ${petsc_slaves})
#
# Determine whether the PETSc layout is old-style (through 2.3.3) or
# new-style (>= 3.0.0)
if (EXISTS "${PETSC_DIR}/${PETSC_ARCH}/include/petscconf.h") # > 2.3.3
set (petsc_conf_rules "${PETSC_DIR}/conf/rules")
set (petsc_conf_variables "${PETSC_DIR}/conf/variables")
elseif (EXISTS "${PETSC_DIR}/bmake/${PETSC_ARCH}/petscconf.h") # <= 2.3.3
set (petsc_conf_rules "${PETSC_DIR}/bmake/common/rules")
set (petsc_conf_variables "${PETSC_DIR}/bmake/common/variables")
elseif (PETSC_DIR)
message (SEND_ERROR "The pair PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSc installation")
endif ()
message(petsc_conf_rules ${petsc_conf_rules})
message(petsc_conf_variables ${petsc_conf_variables})
message(petsc_config_current ${petsc_config_current})
if (petsc_conf_rules AND petsc_conf_variables AND NOT petsc_config_current)
petsc_get_version()
# Put variables into environment since they are needed to get
# configuration (petscvariables) in the PETSc makefile
set (ENV{PETSC_DIR} "${PETSC_DIR}")
set (ENV{PETSC_ARCH} "${PETSC_ARCH}")
# A temporary makefile to probe the PETSc configuration
set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc")
file (WRITE "${petsc_config_makefile}"
"## This file was autogenerated by FindPETSc.cmake
# PETSC_DIR = ${PETSC_DIR}
# PETSC_ARCH = ${PETSC_ARCH}
include ${petsc_conf_rules}
include ${petsc_conf_variables}
show :
-@echo -n \${\${VARIABLE}}
")
macro (PETSC_GET_VARIABLE name var)
set (${var} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE)
execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} show VARIABLE=${name}
OUTPUT_VARIABLE ${var}
RESULT_VARIABLE petsc_return)
endmacro (PETSC_GET_VARIABLE)
petsc_get_variable (PETSC_LIB_DIR petsc_lib_dir)
petsc_get_variable (PETSC_EXTERNAL_LIB_BASIC petsc_libs_external)
petsc_get_variable (PETSC_CCPPFLAGS petsc_cpp_line)
petsc_get_variable (PETSC_INCLUDE petsc_include)
petsc_get_variable (PCC petsc_cc)
petsc_get_variable (PCC_FLAGS petsc_cc_flags)
petsc_get_variable (MPIEXEC petsc_mpiexec)
# We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid!
file (REMOVE ${petsc_config_makefile})
include (ResolveCompilerPaths)
# Extract include paths and libraries from compile command line
resolve_includes (petsc_includes_all "${petsc_cpp_line}")
#on windows we need to make sure we're linking against the right
#runtime library
if (WIN32)
if (petsc_cc_flags MATCHES "-MT")
set(using_md False)
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
set(using_md True)
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
if(${using_md} MATCHES "True")
message(WARNING "PETSc was built with /MT, but /MD is currently set.
See http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F")
endif(${using_md} MATCHES "True")
endif (petsc_cc_flags MATCHES "-MT")
endif (WIN32)
include (CorrectWindowsPaths)
convert_cygwin_path(petsc_lib_dir)
message (STATUS "petsc_lib_dir ${petsc_lib_dir}")
macro (PETSC_FIND_LIBRARY suffix name)
set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) # Clear any stale value, if we got here, we need to find it again
if (WIN32)
set (libname lib${name}) #windows expects "libfoo", linux expects "foo"
else (WIN32)
set (libname ${name})
endif (WIN32)
find_library (PETSC_LIBRARY_${suffix} NAMES ${libname} HINTS ${petsc_lib_dir} NO_DEFAULT_PATH)
set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}")
mark_as_advanced (PETSC_LIBRARY_${suffix})
endmacro (PETSC_FIND_LIBRARY suffix name)
# Look for petscvec first, if it doesn't exist, we must be using single-library
petsc_find_library (VEC petscvec)
if (PETSC_LIBRARY_VEC)
petsc_find_library (SYS "petscsys;petsc") # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced)
petsc_find_library (MAT petscmat)
petsc_find_library (DM petscdm)
petsc_find_library (KSP petscksp)
petsc_find_library (SNES petscsnes)
petsc_find_library (TS petscts)
macro (PETSC_JOIN libs deps)
list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}})
endmacro (PETSC_JOIN libs deps)
petsc_join (VEC SYS)
petsc_join (MAT VEC)
petsc_join (DM MAT)
petsc_join (KSP DM)
petsc_join (SNES KSP)
petsc_join (TS SNES)
petsc_join (ALL TS)
else ()
- 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 ()
+ set (PETSC_LIBRARY_VEC "${PETSC_LIBRARY_SINGLE}" CACHE INTERNAL "Cleared" FORCE) # There is no libpetscvec
endif ()
if (PETSC_LIBRARY_TS)
message (STATUS "Recognized PETSc install with separate libraries for each package")
else ()
message (STATUS "Recognized PETSc install with single library for all packages")
endif ()
include(Check${PETSC_LANGUAGE_BINDINGS}SourceRuns)
macro (PETSC_TEST_RUNS includes libraries runs)
if(${PETSC_LANGUAGE_BINDINGS} STREQUAL "C")
set(_PETSC_ERR_FUNC "CHKERRQ(ierr)")
elseif(${PETSC_LANGUAGE_BINDINGS} STREQUAL "CXX")
set(_PETSC_ERR_FUNC "CHKERRXX(ierr)")
endif()
if (PETSC_VERSION VERSION_GREATER 3.1)
set (_PETSC_TSDestroy "TSDestroy(&ts)")
else ()
set (_PETSC_TSDestroy "TSDestroy(ts)")
endif ()
set(_PETSC_TEST_SOURCE "
static const char help[] = \"PETSc test program.\";
#include <petscts.h>
int main(int argc,char *argv[]) {
PetscErrorCode ierr;
TS ts;
ierr = PetscInitialize(&argc,&argv,0,help);${_PETSC_ERR_FUNC};
ierr = TSCreate(PETSC_COMM_WORLD,&ts);${_PETSC_ERR_FUNC};
ierr = TSSetFromOptions(ts);${_PETSC_ERR_FUNC};
ierr = ${_PETSC_TSDestroy};${_PETSC_ERR_FUNC};
ierr = PetscFinalize();${_PETSC_ERR_FUNC};
return 0;
}
")
multipass_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs} "${PETSC_LANGUAGE_BINDINGS}")
if (${${runs}})
set (PETSC_EXECUTABLE_RUNS "YES" CACHE BOOL
"Can the system successfully run a PETSc executable? This variable can be manually set to \"YES\" to force CMake to accept a given PETSc configuration, but this will almost always result in a broken build. If you change PETSC_DIR, PETSC_ARCH, or PETSC_CURRENT you would have to reset this variable." FORCE)
endif (${${runs}})
endmacro (PETSC_TEST_RUNS)
find_path (PETSC_INCLUDE_DIR petscts.h HINTS "${PETSC_DIR}" PATH_SUFFIXES include NO_DEFAULT_PATH)
find_path (PETSC_INCLUDE_CONF petscconf.h HINTS "${PETSC_DIR}" PATH_SUFFIXES "${PETSC_ARCH}/include" "bmake/${PETSC_ARCH}" NO_DEFAULT_PATH)
mark_as_advanced (PETSC_INCLUDE_DIR PETSC_INCLUDE_CONF)
set (petsc_includes_minimal ${PETSC_INCLUDE_CONF} ${PETSC_INCLUDE_DIR})
petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_minimal)
if (petsc_works_minimal)
message (STATUS "Minimal PETSc includes and libraries work. This probably means we are building with shared libs.")
set (petsc_includes_needed "${petsc_includes_minimal}")
else (petsc_works_minimal) # Minimal includes fail, see if just adding full includes fixes it
petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_allincludes)
if (petsc_works_allincludes) # It does, we just need all the includes (
message (STATUS "PETSc requires extra include paths, but links correctly with only interface libraries. This is an unexpected configuration (but it seems to work fine).")
set (petsc_includes_needed ${petsc_includes_all})
else (petsc_works_allincludes) # We are going to need to link the external libs explicitly
resolve_libraries (petsc_libraries_external "${petsc_libs_external}")
foreach (pkg SYS VEC MAT DM KSP SNES TS ALL)
list (APPEND PETSC_LIBRARIES_${pkg} ${petsc_libraries_external})
endforeach (pkg)
petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_alllibraries)
if (petsc_works_alllibraries)
message (STATUS "PETSc only need minimal includes, but requires explicit linking to all dependencies. This is expected when PETSc is built with static libraries.")
set (petsc_includes_needed ${petsc_includes_minimal})
else (petsc_works_alllibraries)
# It looks like we really need everything, should have listened to Matt
set (petsc_includes_needed ${petsc_includes_all})
petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_all)
if (petsc_works_all) # We fail anyways
message (STATUS "PETSc requires extra include paths and explicit linking to all dependencies. This probably means you have static libraries and something unexpected in PETSc headers.")
else (petsc_works_all) # We fail anyways
message (STATUS "PETSc could not be used, maybe the install is broken.")
endif (petsc_works_all)
endif (petsc_works_alllibraries)
endif (petsc_works_allincludes)
endif (petsc_works_minimal)
# We do an out-of-source build so __FILE__ will be an absolute path, hence __INSDIR__ is superfluous
if (${PETSC_VERSION} VERSION_LESS 3.1)
set (PETSC_DEFINITIONS "-D__SDIR__=\"\"" CACHE STRING "PETSc definitions" FORCE)
else ()
set (PETSC_DEFINITIONS "-D__INSDIR__=" CACHE STRING "PETSc definitions" FORCE)
endif ()
# Sometimes this can be used to assist FindMPI.cmake
set (PETSC_MPIEXEC ${petsc_mpiexec} CACHE FILEPATH "Executable for running PETSc MPI programs" FORCE)
set (PETSC_INCLUDES ${petsc_includes_needed} CACHE STRING "PETSc include path" FORCE)
set (PETSC_LIBRARIES ${PETSC_LIBRARIES_ALL} CACHE STRING "PETSc libraries" FORCE)
set (PETSC_COMPILER ${petsc_cc} CACHE FILEPATH "PETSc compiler" FORCE)
# Note that we have forced values for all these choices. If you
# change these, you are telling the system to trust you that they
# work. It is likely that you will end up with a broken build.
mark_as_advanced (PETSC_INCLUDES PETSC_LIBRARIES PETSC_COMPILER PETSC_DEFINITIONS PETSC_MPIEXEC PETSC_EXECUTABLE_RUNS)
endif ()
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (PETSc
"PETSc could not be found. Be sure to set PETSC_DIR and PETSC_ARCH."
PETSC_INCLUDES PETSC_LIBRARIES PETSC_EXECUTABLE_RUNS)
diff --git a/cmake/Modules/FindPTScotch.cmake b/cmake/Modules/FindPTScotch.cmake
index 0daeffc97..4099b7a33 100644
--- a/cmake/Modules/FindPTScotch.cmake
+++ b/cmake/Modules/FindPTScotch.cmake
@@ -1,87 +1,108 @@
#===============================================================================
# @file FindPTScotch.cmake
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Tue Apr 05 2011
# @date last modification: Fri Jan 04 2013
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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)
-mark_as_advanced(PTSCOTCH_LIBRARY_ERR)
-mark_as_advanced(PTSCOTCH_LIBRARY_ESMUMPS)
-mark_as_advanced(PTSCOTCH_INCLUDE_PATH)
+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/FindScaLAPACK.cmake b/cmake/Modules/FindScaLAPACK.cmake
new file mode 100644
index 000000000..41cecee48
--- /dev/null
+++ b/cmake/Modules/FindScaLAPACK.cmake
@@ -0,0 +1,116 @@
+#===============================================================================
+# @file FindMumps.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Dec 13 2010
+# @date last modification: Tue Sep 09 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+find_library(SCALAPACK_LIBRARY NAME scalapack
+ HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib)
+
+mark_as_advanced(SCALAPACK_LIBRARY)
+
+#===============================================================================
+if(NOT SCALAPACK_FOUND)
+ set(SCALAPACK_DIR "" CACHE PATH "Prefix of MUMPS library.")
+ mark_as_advanced(SCALAPACK_DIR)
+endif()
+
+#===============================================================================
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ScaLAPACK DEFAULT_MSG
+ SCALAPACK_LIBRARY)
+
+if(SCALAPACK_FOUND AND NOT TARGET ScaLAPACK)
+ set(SCALAPACK_LIBRARIES_ALL ${SCALAPACK_LIBRARY})
+ set(_blacs_dep)
+ if(SCALAPACK_LIBRARY MATCHES ".*scalapack.*${CMAKE_STATIC_LIBRARY_SUFFIX}")
+ # Assuming scalapack was compiled as a static library
+ set(SCALAPACK_LIBRARY_TYPE STATIC CACHE INTERNAL "" FORCE)
+
+ find_library(BLACS_LIBRARY_C NAME blacsC
+ HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib)
+ find_library(BLACS_LIBRARY_F77 NAME blacsF77
+ HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib)
+ find_library(BLACS_LIBRARY NAME blacs
+ HINTS ${SCALAPACK_DIR} PATH_SUFFIXES lib)
+
+ mark_as_advanced(
+ BLACS_LIBRARY_C
+ BLACS_LIBRARY_F77
+ BLACS_LIBRARY
+ )
+
+ find_package_handle_standard_args(BLACS DEFAULT_MSG
+ BLACS_LIBRARY BLACS_LIBRARY_C BLACS_LIBRARY_F77)
+
+ add_library(blacs::common ${SCALAPACK_LIBRARY_TYPE} IMPORTED GLOBAL)
+ add_library(blacs::F77 ${SCALAPACK_LIBRARY_TYPE} IMPORTED GLOBAL)
+ add_library(blacs::C ${SCALAPACK_LIBRARY_TYPE} IMPORTED GLOBAL)
+
+ set_target_properties(blacs::F77 PROPERTIES
+ IMPORTED_LOCATION "${BLACS_LIBRARY_F77}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "Fortran"
+ INTERFACE_LINK_LIBRARIES blacs::common
+ )
+ set_target_properties(blacs::C PROPERTIES
+ IMPORTED_LOCATION "${BLACS_LIBRARY_C}"
+ INTERFACE_INCLUDE_DIRECTORIES "${SCALAPACK_INCLUDE_DIR}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ INTERFACE_LINK_LIBRARIES blacs::common
+ )
+
+ set_target_properties(blacs::common PROPERTIES
+ IMPORTED_LOCATION "${BLACS_LIBRARY}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C Fortran"
+ INTERFACE_LINK_LIBRARIES "blacs::C;blacs::F77"
+ )
+
+ find_package(LAPACK REQUIRED)
+ find_package(BLAS REQUIRED)
+
+ list(APPEND SCALAPACK_LIBRARIES_ALL
+ ${BLACS_LIBRARY}
+ ${BLACS_LIBRARY_C}
+ ${BLACS_LIBRARY_F77}
+ ${BLACS_LIBRARY}
+ ${BLAS_LIBRARIES}
+ ${LAPACK_LIBRARIES})
+
+ set(_blacs_dep "blacs::common;${BLAS_LIBRARIES};${LAPACK_LIBRAIES}")
+ else()
+ set(SCALAPACK_LIBRARY_TYPE SHARED)
+ endif()
+
+ add_library(ScaLAPACK ${SCALAPACK_LIBRARY_TYPE} IMPORTED GLOBAL)
+ set_target_properties(ScaLAPACK PROPERTIES
+ IMPORTED_LOCATION "${SCALAPACK_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${SCALAPACK_INCLUDE_DIR}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C Fortran"
+ INTERFACE_LINK_LIBRARIES "${_blacs_dep}")
+
+ set(SCALAPACK_LIBRARIES ${SCALAPACK_LIBRARIES_ALL} CACHE INTERNAL "Libraries for ScaLAPACK" FORCE)
+endif()
diff --git a/cmake/Modules/FindScotch.cmake b/cmake/Modules/FindScotch.cmake
index 88a733c7d..b937c97d0 100644
--- a/cmake/Modules/FindScotch.cmake
+++ b/cmake/Modules/FindScotch.cmake
@@ -1,87 +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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
- )
+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_ESMUMPS esmumps
- HINTS ${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)
-mark_as_advanced(SCOTCH_LIBRARY_ERR)
-mark_as_advanced(SCOTCH_LIBRARY_ERREXIT)
-mark_as_advanced(SCOTCH_LIBRARY_ESMUMPS)
-mark_as_advanced(SCOTCH_INCLUDE_DIR)
+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()
-set(SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES_ALL} CACHE INTERNAL "Libraries for scotch" FORCE)
+if(SCOTCH_LIBRARY_METIS)
+ set(SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY_METIS} ${SCOTCH_LIBRARIES_ALL})
+endif()
-#===============================================================================
-if(NOT SCOTCH_FOUND)
- set(SCOTCH_DIR "" CACHE PATH "Location of Scotch library.")
- mark_as_advanced(SCOTCH_DIR)
+if(SCOTCH_LIBRARY_PARMETIS)
+ set(SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY_PARMETIS} ${SCOTCH_LIBRARIES_ALL})
endif()
-#===============================================================================
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Scotch DEFAULT_MSG
- SCOTCH_LIBRARY SCOTCH_LIBRARY_ERR SCOTCH_INCLUDE_DIR)
+set(SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES_ALL} CACHE INTERNAL "Libraries for scotch" FORCE)
+#===============================================================================
+include(FindPackageHandleStandardArgs)
+if(CMAKE_VERSION VERSION_GREATER 2.8.12)
+ if(SCOTCH_INCLUDE_DIR)
+ file(STRINGS ${SCOTCH_INCLUDE_DIR}/scotch.h _versions
+ REGEX "^#define\ +SCOTCH_(VERSION|RELEASE|PATCHLEVEL) .*")
+ foreach(_ver ${_versions})
+ string(REGEX MATCH "SCOTCH_(VERSION|RELEASE|PATCHLEVEL) *([0-9.]+)" _tmp "${_ver}")
+ set(_scotch_${CMAKE_MATCH_1} ${CMAKE_MATCH_2})
+ endforeach()
+ set(SCOTCH_VERSION "${_scotch_VERSION}.${_scotch_PATCHLEVEL}" CACHE INTERNAL "")
+ endif()
+ find_package_handle_standard_args(Scotch
+ REQUIRED_VARS SCOTCH_LIBRARIES SCOTCH_INCLUDE_DIR
+ VERSION_VAR SCOTCH_VERSION)
+else()
+ find_package_handle_standard_args(Scotch DEFAULT_MSG
+ SCOTCH_LIBRARIES SCOTCH_INCLUDE_DIR)
+endif()
diff --git a/cmake/akantu_diff.sh b/cmake/akantu_diff.sh
index 789f0f0f5..3bd325126 100755
--- a/cmake/akantu_diff.sh
+++ b/cmake/akantu_diff.sh
@@ -1,13 +1,13 @@
#!/bin/bash
./$1 > $1.lastout 2> $1.errout
ret=$?
if [ $ret -eq 0 ]
then
- diff -q $1.lastout $2 && echo "Test passed!!!"
+ diff $1.lastout $2 && echo "Test passed!!!"
else
echo "Test Failed!!"
exit $ret
fi
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/akantu_test_environement.sh.in b/cmake/akantu_test_environement.sh.in
new file mode 100644
index 000000000..13dcc6f7d
--- /dev/null
+++ b/cmake/akantu_test_environement.sh.in
@@ -0,0 +1 @@
+export PYTHONPATH=$PYTHONPATH:@PROJECT_BINARY_DIR@/python
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 68dbb9c51..aab050d43 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -1,99 +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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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/coding_convention/akantu-input-mode.el b/doc/coding_convention/akantu-input-mode.el
new file mode 100644
index 000000000..d3d8ef5a0
--- /dev/null
+++ b/doc/coding_convention/akantu-input-mode.el
@@ -0,0 +1,100 @@
+(defconst akantu-input-regex-section-opening "^[ \t]*\\([_A-Za-z]+\\)[ \t]+\\([_A-Za-z][_A-Za-z0-9]+\\)\\([ \t]+[_A-Za-z][_A-Za-z0-9]*\\)?[ \t]*\\[\\(#.*\\)?$")
+(defconst akantu-input-regex-section-closing "^[ \t]*\\][ \t]*$")
+(defconst akantu-input-regex-multiline "^.*\\\\[ \t]*\\(#.*\\)?$")
+(defconst akantu-input-regex-variable-assign "^[ \t]*\\([A-Za-z][_A-Za-z0-9]*\\)[ \t]*=")
+
+(defvar akantu-intput-mode-hook nil)
+(defvar akantu-intput-mode-map
+ (let ((map (make-keymap)))
+ (define-key map "\C-j" 'newline-and-indent)
+ map)
+ "Keymap for Akantu input files major mode")
+
+(defun akantu-input-indent-line ()
+ "Indent current line as akantu input file."
+ (interactive)
+ (if (bobp) ; Check for rule 1
+ (indent-line-to 0)
+ (let ((not-indented t) cur-indent)
+ (setq cur-column nil)
+ (setq cur-indent 0)
+ (save-restriction
+ (widen)
+ (save-excursion
+ (if (not (or (looking-back "^\\s-+") (bolp)))
+ (progn
+ (setq cur-column (+ (current-column) 1))
+ (beginning-of-line)
+ (search-forward-regexp "\\S-")
+ (setq cur-column (- cur-column (current-column))))))
+ (save-excursion
+ (beginning-of-line)
+ (forward-line -1)
+ (if (looking-at akantu-input-regex-multiline)
+ (progn
+ (setq not_assignment t)
+ (while not_assignment
+ (if (looking-at akantu-input-regex-variable-assign)
+ (setq not_assignment nil)
+ (progn
+ (forward-line -1)
+ (message "toto"))))
+ (search-forward "=")
+ (setq cur-indent (+ (+ cur-indent (current-column)) 1)))))
+ (save-excursion
+ (beginning-of-line)
+ (if (looking-at akantu-input-regex-section-opening)
+ (setq cur-indent (- cur-indent tab-width)))
+ (while not-indented
+ (if (looking-at akantu-input-regex-section-opening)
+ (setq cur-indent (+ cur-indent tab-width))
+ (if (looking-at akantu-input-regex-section-closing)
+ (setq cur-indent (- cur-indent tab-width))))
+ (if (bobp)
+ (setq not-indented nil))
+ (forward-line -1))))
+ (if (< cur-indent 0)
+ (setq cur-indent 0))
+ (indent-line-to cur-indent)
+ (if cur-column
+ (move-to-column (+ cur-column cur-indent))))))
+
+(defconst akantu-input-font-lock-buffer
+ (list
+ '("\\<\\(global\\|material\\|model\\|mesh\\|heat\\|contact\\|friction\\|embedded_interface\\|rules\\|non_local\\|user\\)\\>"
+ 1 font-lock-keyword-face) ;; include definition
+ '("^[ \t]*\\([A-Za-z][_A-Za-z0-9]*\\)[ \t]*=" 1 font-lock-variable-face)
+ '("^[ \t]*\\([_A-Za-z]+\\)[ \t]+\\([_A-Za-z][_A-Za-z0-9]+\\)\\([ \t]+[_A-Za-z][_A-Za-z0-9]*\\)?[ \t]*\\[" 2 font-lock-reference-face)
+ '("^[ \t]*\\([_A-Za-z]+\\)[ \t]+\\([_A-Za-z][_A-Za-z0-9]+\\)\\([ \t]+[_A-Za-z][_A-Za-z0-9]*\\)?[ \t]*\\[" 3 font-lock-type-face))
+ "akantu-input mode syntax highlighting."
+ )
+
+(defvar akantu-input-mode-syntax-table nil "Syntax table for akantu-input-mode.")
+(setq akantu-input-mode-syntax-table nil)
+
+(defun akantu-input-mode ()
+ "Major mode for editing Akantu input files"
+
+ (interactive)
+ (kill-all-local-variables)
+ (setq major-mode 'akantu-input-mode)
+ (setq mode-name "akantu-input")
+
+ ;; Create the syntax table
+ (setq akantu-input-mode-syntax-table (make-syntax-table))
+ (set-syntax-table akantu-input-mode-syntax-table)
+ (modify-syntax-entry ?_ "w" akantu-input-mode-syntax-table)
+ (modify-syntax-entry ?# "<" akantu-input-mode-syntax-table)
+ (modify-syntax-entry ?\n ">" akantu-input-mode-syntax-table)
+
+ ;; Setup font-lock mode, indentation and comment highlighting
+ (set (make-local-variable 'indent-line-function) 'akantu-input-indent-line)
+
+ (make-local-variable 'font-lock-defaults)
+ (setq font-lock-defaults '(akantu-input-font-lock-buffer))
+
+ (make-local-variable 'comment-start)
+ (setq comment-start "#")
+ (run-hooks 'akantu-input-mode-hook))
+
+(provide 'akantu-input-mode)
diff --git a/doc/doxygen/akantu.dox.in b/doc/doxygen/akantu.dox.in
index 7d397ee62..dd00b4ae5 100644
--- a/doc/doxygen/akantu.dox.in
+++ b/doc/doxygen/akantu.dox.in
@@ -1,1818 +1,1818 @@
# 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
# 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 =
# 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
# 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 be3299374..5348490e2 100644
--- a/doc/manual/CMakeLists.txt
+++ b/doc/manual/CMakeLists.txt
@@ -1,136 +1,155 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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 LABEL)
- string(REPLACE "_" "-" _pkg_tex_label_dash ${PKG})
+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)
+ 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 FILENAME LEVEL)
- string(REPLACE "_" "\\_" _pkg_tex "${PKG}")
- get_doc_label(${PKG} _pkg_tex_label)
+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}}")
+ file(APPEND ${FILENAME} "\\AkantuPackageNameWithLabel{${_pkg_tex}}{${_pkg_tex_label}}{${LEVEL}}\\xspace")
math(EXPR _sub_level "${LEVEL}+1")
- foreach(_pkg ${${PKG}_dependencies})
- generate_package_dependency_tex_doc(${_pkg} ${FILENAME} ${_sub_level})
+ _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 FILENAME)
- string(REPLACE "_" "\\_" _pkg_tex "${PKG}")
- get_doc_label(${PKG} _pkg_tex_label)
+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} "
-\\begin{AkantuPackage}{${_pkg_tex}}{${_pkg_tex_label}}")
+ file(APPEND ${FILENAME} "\n\\begin{AkantuPackage}{${_pkg_tex}}{${_pkg_tex_label}}")
- if (${PKG}_DOCUMENTATION)
- file(APPEND ${FILENAME} "${${PKG}_DOCUMENTATION}")
+ _package_get_documentation(${pkg_name} _doc)
+
+ if (_doc)
+ file(APPEND ${FILENAME} "${_doc}")
else()
- string(TOLOWER "${PKG}" _l_pkg)
- string(REPLACE "akantu_" "" _l_pkg_short ${_l_pkg})
- string(REPLACE "_" "\\_" _l_pkg_tex ${_l_pkg_short})
+ _package_get_filename(${pkg_name} _file_path)
+ _package_get_real_name(${pkg_name} _pkg)
+ get_filename_component(_file ${_file_path} NAME)
+ string(REPLACE "_" "\\_" _escaped_file "${_file}")
+ string(REPLACE "_" "\\_" _escaped_pkg "${_pkg}")
+
+ set(_missing_doc
+ "{\\color{red} TODO}: No Documentation in {\\color{blue} \\href{${_file_path}}{${_escaped_file}}}"
+ ""
+ "looking for the sequence: "
+ "\\begin{cmake}"
+ "\\package_declare_documentation("
+ " ${_escaped_pkg}"
+ " \"documentation text\""
+ " )"
+ "\\end{cmake}")
+
+ set(_missing_doc_str "")
+ foreach(_str ${_missing_doc})
+ set(_missing_doc_str "${_missing_doc_str}\n${_str}")
+ endforeach()
- file(GLOB _file_path "${PROJECT_SOURCE_DIR}/packages/*_${_l_pkg_short}.cmake")
- file(APPEND ${FILENAME} "{\\color{red} TODO}: No Documentation in {\\color{blue} \\href{${_file_path}}{${_l_pkg_tex}.cmake}}\\\\")
- file(APPEND ${FILENAME} "looking for the sequence: \\\\set(${_pkg_tex}\\_DOCUMENTATION \" documentation text \" )\\\\" )
+ file(APPEND ${FILENAME} "${_missing_doc_str}")
endif()
- set(_n_dependencies 0)
- if (${PKG}_dependencies)
- list(LENGTH ${PKG}_dependencies _n_dependencies)
- endif()
+ _package_get_dependencies(${pkg_name} _dependencies)
- if(_n_dependencies GREATER 0)
- file(APPEND ${FILENAME} "
-\\begin{AkantuPackageDependencies}")
- foreach(_pkg ${${PKG}_dependencies})
- generate_package_dependency_tex_doc(${_pkg} ${FILENAME} 1)
+ 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} "
-\\end{AkantuPackageDependencies}")
+ file(APPEND ${FILENAME} "\n\\end{AkantuPackageDependencies}")
endif()
- file(APPEND ${FILENAME} "
-\\end{AkantuPackage}
+ file(APPEND ${FILENAME} "\n\\end{AkantuPackage}
")
endfunction()
#------------------------------------------------------------------------------#
#------------------------------------------------------------------------------#
set(DOC_DEPS_TEX_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/manual-packages-doc.tex")
file(WRITE ${DOC_DEPS_TEX_FILENAME} "")
find_program(RUBBER_EXECUTABLE rubber)
if (NOT RUBBER_EXECUTABLE)
message(ERROR "Manual cannot be built without rubber latex compiler")
endif()
mark_as_advanced(RUBBER_EXECUTABLE)
+package_get_all_documentation_files(_manual_files)
set(AKANTU_MANUAL_FILES_DEPEND)
set(AKANTU_MANUAL_FILES_COPY_COMMAND)
-
-set(_relative_manual_files)
-foreach(_f ${AKANTU_MANUAL_FILES})
- file(RELATIVE_PATH _rel_f ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_SOURCE_DIR}/${_f}")
- list(APPEND _relative_manual_files ${_rel_f})
- list(APPEND AKANTU_MANUAL_FILES_DEPEND ${_rel_f})
+foreach(_f ${_manual_files})
+ file(RELATIVE_PATH _rel_f ${CMAKE_CURRENT_SOURCE_DIR} "${_f}")
+ list(APPEND AKANTU_MANUAL_FILES_DEPEND ${_f})
list(APPEND AKANTU_MANUAL_FILES_COPY_COMMAND
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${_rel_f} ${_rel_f})
endforeach()
set(MANUAL_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/manual.pdf)
add_custom_command(
OUTPUT ${MANUAL_OUTPUT}
DEPENDS ${AKANTU_MANUAL_FILES_DEPEND} ${DOC_DEPS_TEX_FILENAME}
${AKANTU_MANUAL_FILES_COPY_COMMAND}
COMMAND ${RUBBER_EXECUTABLE} -dfq -Wall manual
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Compiling the user's manual"
)
add_custom_target(manual ALL DEPENDS ${MANUAL_OUTPUT})
install(FILES ${MANUAL_OUTPUT} DESTINATION share/akantu/doc)
-foreach (_pkg ${AKANTU_PACKAGE_LIST})
- generate_package_tex_doc(AKANTU_${_pkg} ${DOC_DEPS_TEX_FILENAME})
+package_get_all_activated_packages(_package_list)
+foreach (_pkg_name ${_package_list})
+ generate_package_tex_doc(${_pkg_name} ${DOC_DEPS_TEX_FILENAME})
endforeach()
+
+configure_file(version-definition.tex.in "${CMAKE_CURRENT_BINARY_DIR}/version-definition.tex" @ONLY)
\ No newline at end of file
diff --git a/doc/manual/manual-appendix-elements.tex b/doc/manual/manual-appendix-elements.tex
index 90a80280c..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)} \\
+ 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)} \\
+ 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)} \\
+ 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 f125deb12..568c0c691 100644
--- a/doc/manual/manual-appendix-materials-cohesive.tex
+++ b/doc/manual/manual-appendix-materials-cohesive.tex
@@ -1,30 +1,49 @@
\section{Cohesive linear}
\begin{MaterialDesc}{cohesive\_linear}{ssect:smm:cl:coh-snozzi}
-\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}
-\matparam{beta}{Real}{$\beta$ parameter}
-\matparam{G\_cI}{Real}{Mode I fracture energy}
-\matparam{G\_cII}{Real}{Mode II fracture energy}
-\matparam{kappa}{Real}{$\kappa$ parameter}
-\matparam{penalty}{Real}{penalty coefficient $\alpha$}
+\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}\\
+Either G\_c and kappa or, G\_cI and G\_cII or delta\_c have to be specified
+\matparam{G\_c}{Real}{Mode I fracture energy}
+\matparam{kappa}{Real}{$\kappa = G\_cI / G\_cII$ parameter (default 1)}
+\matparam{G\_cI (G\_cII)}{Real}{Mode I (II) fracture energy}
+\matparam{delta\_c}{Real}{Critical displacement $\delta_\mathrm{c}$}
+\matparam{beta}{Real}{$\beta$ parameter (default 1)}
+\matparam{penalty}{Real}{penalty coefficient $\alpha$ (optional; default 0)}
+\matparam{volume\_s \& m\_s}{Reals}{optional; to adapt statistical distribution following~\cite{Zhou_Molinari_2004}}
\end{MaterialDesc}
\section{Cohesive bilinear}
\begin{MaterialDesc}{cohesive\_bilinear}{ssect:smm:cl:coh-snozzi}
\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}
-\matparam{beta}{Real}{$\beta$ parameter}
-\matparam{G\_cI}{Real}{Mode I fracture energy}
-\matparam{G\_cII}{Real}{Mode II fracture energy}
-\matparam{kappa}{Real}{$\kappa$ parameter}
-\matparam{penalty}{Real}{Penalty coefficient $\alpha$}
-\matparam{delta\_0}{Real}{Elastic limit displacement $\delta_0$}
+\matparam{delta\_0}{Real}{Elastic limit displacement $\delta_0$}\\
+Either G\_c and kappa or, G\_cI and G\_cII or delta\_c have to be specified
+\matparam{G\_c}{Real}{Mode I fracture energy}
+\matparam{kappa}{Real}{$\kappa = G\_cI / G\_cII$ parameter (default 1)}
+\matparam{G\_cI (G\_cII)}{Real}{Mode I (II) fracture energy}
+\matparam{delta\_c}{Real}{Critical displacement $\delta_\mathrm{c}$}
+\matparam{beta}{Real}{$\beta$ parameter (default 1)}
+\matparam{penalty}{Real}{Penalty coefficient $\alpha$ (optional; default 0)}
\end{MaterialDesc}
\section{Cohesive exponential}
\begin{MaterialDesc}{cohesive\_exponential}{ssect:smm:cl:coh-exponential}
\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}
-\matparam{beta}{Real}{$\beta$ parameter}
+\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}
+
+\section{Cohesive linear fatigue}
+
+\begin{MaterialDesc}{cohesive\_linear\_fatigue}{ssect:smm:cl:coh-fatigue}
+\matparam{sigma\_c}{Real}{Critical stress $\sigma_\mathrm{c}$}
\matparam{delta\_c}{Real}{Critical displacement $\delta_\mathrm{c}$}
+\matparam{beta}{Real}{$\beta$ parameter (default 1)}
+\matparam{G\_c}{Real}{Mode I fracture energy}
+\matparam{kappa}{Real}{$\kappa$ parameter (default 1)}
+\matparam{penalty}{Real}{penalty coefficient $\alpha$ (optional, default 0)}
+\matparam{delta\_f}{Real}{Characteristic opening displacement $\delta_\mathrm{f}$ (see~\cite{vocialta15})}
\end{MaterialDesc}
diff --git a/doc/manual/manual-appendix-materials.tex b/doc/manual/manual-appendix-materials.tex
index d08383490..5d9a81922 100644
--- a/doc/manual/manual-appendix-materials.tex
+++ b/doc/manual/manual-appendix-materials.tex
@@ -1,110 +1,111 @@
\chapter{Material parameters}
\label{app:material-parameters}
\section{Linear elastic isotropic}
\begin{MaterialDesc}{elastic}{ssect:smm:linear-elastic-isotropic}
\matparam{rho}{Real}{Density}
\matparam{E}{Real}{Young's modulus}
\matparam{nu}{Real}{Poisson's ratio}
\matparam{Plane\_Stress}{bool}{Plane stress simplification (only 2D problems)}
\end{MaterialDesc}
\section{Linear elastic anisotropic}
\begin{MaterialDesc}{elastic\_anisotropic}{ssect:smm:linear-elastic-anisotropic}
\matparam{rho}{Real}{Density}
\matparam{n1}{Vector<Real>}{Direction of the main material axis}
\matparam{n2}{Vector<Real>}{Direction of the second material axis (if
applicable)}
\matparam{n3}{Vector<Real>}{Direction of the third material axis (if
applicable)}
\matparam{C..}{Real}{Coefficient ij of the material tensor C (all the 36 values
in Voigt notation can be entered .)}
+% \matparam{alpha}{Real}{Viscous proportion (default value is 0)}
\end{MaterialDesc}
\section{Linear elastic orthotropic}
\begin{MaterialDesc}{elastic\_orthotropic}{ssect:smm:linear-elastic-orthotropic}
\matparam{rho}{Real}{Density}
\matparam{n1}{Vector<Real>}{Direction of the main material axis}
\matparam{n2}{Vector<Real>}{Direction of the second material axis (if
applicable)}
\matparam{n3}{Vector<Real>}{Direction of the third material axis (if
applicable)}
\matparam{E1 }{Real}{Young's modulus (n1)}
\matparam{E2 }{Real}{Young's modulus (n2)}
\matparam{E3 }{Real}{Young's modulus (n3)}
\matparam{nu12}{Real}{Poisson's ratio (12)}
\matparam{nu13}{Real}{Poisson's ratio (13)}
\matparam{nu23}{Real}{Poisson's ratio (23)}
\matparam{G12 }{Real}{Shear modulus (12)}
\matparam{G13 }{Real}{Shear modulus (13)}
\matparam{G23 }{Real}{Shear modulus (23)}
\end{MaterialDesc}
\section{Neohookean (finite strains)}
\begin{MaterialDesc}{neohookean}{ssect:smm:cl:neohookean}
\matparam{rho}{Real}{Density}
\matparam{E}{Real}{Young's modulus}
\matparam{nu}{Real}{Poisson's ratio}
-\matparam{Plane\_Stress}{bool}{Plane stress simplification (only 2D problems)}
+\matparam{Plane\_Stress}{bool}{Plane stress simplification : false = plane strain, true = plane stress (default: false) (only 2D problems)}
\end{MaterialDesc}
\section{Standard linear solid}
\begin{MaterialDesc}{sls\_deviatoric}{ssect:smm:cl:sls}
\matparam{rho}{Real}{Density}
\matparam{E}{Real}{Young's modulus}
\matparam{nu}{Real}{Poisson's ratio}
\matparam{Plane\_Stress}{bool}{Plane stress simplification (only 2D problems)}
\matparam{Eta}{Real}{Viscosity}
\matparam{Ev}{Real}{Stiffness of the viscous element}
\end{MaterialDesc}
\section{Elasto-plastic linear isotropic hardening}
\begin{MaterialDesc}{plastic\_linear\_isotropic\_hardening}{ssect:smm:cl:plastic}
\matparam{rho}{Real}{Density}
\matparam{E}{Real}{Young's modulus}
\matparam{nu}{Real}{Poisson's ratio}
\matparam{h}{Real}{Hardening modulus}
\matparam{sigma\_y}{Real}{Yielding stress}
\end{MaterialDesc}
\section{Damage: Marigo}
\begin{MaterialDesc}{marigo}{ssect:smm:cl:damage-marigo}
\matparam{rho}{Real}{Density}
\matparam{E}{Real}{Young's modulus}
\matparam{nu}{Real}{Poisson's ratio}
\matparam{Plane\_Stress}{bool}{Plane stress simplification (only 2D problems)}
\matparam{Yd}{Random}{Rupture criterion}
-\matparam{S}{Real}{Damage Energy}
+\matparam{Sd}{Real}{Damage Energy}
\end{MaterialDesc}
\section{Damage: Mazars}
\begin{MaterialDesc}{mazars}{ssect:smm:cl:damage-mazars}
\matparam{rho}{Real}{Density}
\matparam{E}{Real}{Young's modulus}
\matparam{nu}{Real}{Poisson's ratio}
\matparam{At}{Real}{Traction post-peak asymptotic value}
\matparam{Bt}{Real}{Traction decay shape}
\matparam{Ac}{Real}{Compression post-peak asymptotic value}
\matparam{Bc}{Real}{Compression decay shape}
\matparam{K0}{Real}{Damage threshold}
\matparam{beta}{Real}{Shear parameter}
\end{MaterialDesc}
\IfFileExists{manual-appendix-materials-extra-materials.tex}{\input{manual-appendix-materials-extra-materials}}{}
\IfFileExists{manual-appendix-materials-cohesive.tex}{\input{manual-appendix-materials-cohesive}}{}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual-bibliography.bib b/doc/manual/manual-bibliography.bib
index 21b8a3a96..4ebe2f8ff 100644
--- a/doc/manual/manual-bibliography.bib
+++ b/doc/manual/manual-bibliography.bib
@@ -1,464 +1,582 @@
-%% This BibTeX bibliography file was created using BibDesk.
-%% http://bibdesk.sourceforge.net/
-
-
-%% Created for Alejandro Marcos Aragón at 2014-09-16 15:21:18 +0200
-
-
-%% Saved with string encoding Unicode (UTF-8)
-
-
-
-@phdthesis{Pietrzak:1997,
- Author = {Pietrzak, Grzegorz},
- Date-Added = {2014-09-16 12:23:01 +0000},
- Date-Modified = {2014-09-16 12:41:09 +0000},
- Doi = {10.5075/epfl-thesis-1656},
- School = {{\'E}cole {P}olytechnique {F}{\'e}d{\'e}rale de {L}ausanne},
- Title = {Continuum mechanics modelling and augmented Lagrangian formulation of large deformation frictional contact problems},
- Year = {1997}}
-
-@techreport{Omohundro:1989,
- Author = {Stephen M. Omohundro},
- Date-Added = {2014-05-22 09:47:58 +0000},
- Date-Modified = {2014-05-22 09:47:58 +0000},
- Institution = {International Computer Science Institute, University of California at Berkeley},
- Number = {TR-89-063},
- Title = {Five Balltree Construction Algorithms},
- Type = {Technical Report},
- Url = {http://ftp.icsi.berkeley.edu/ftp/pub/techreports/1989/tr-89-063.pdf},
- Year = {1989},
- Bdsk-Url-1 = {http://ftp.icsi.berkeley.edu/ftp/pub/techreports/1989/tr-89-063.pdf}}
-
-@article{Aragon:2013d,
- Author = {Alejandro M. Arag{\'o}n and Jean-Fran{\c c}ois Molinari},
- 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},
- Journal = {Computer Methods in Applied Mechanics and Engineering},
- Number = {0},
- Pages = {574 - 588},
- Title = {A hierarchical detection framework for computational contact mechanics},
- Url = {http://dx.doi.org/10.1016/j.cma.2013.10.001},
- Volume = {268},
- Year = {2014},
- 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}}
-
-@book{Belytschko:2000,
- Author = {Ted Belytschko, Wing Kam Liu, Brian Moran},
- Publisher = {Wiley},
- Title = {Nonlinear Finite Elements for Continua and Structures},
- Year = {2000}}
-
-@book{Laursen:2002,
- Author = {Laursen, T.A.},
- Date-Added = {2014-03-21 13:24:56 +0000},
- Date-Modified = {2014-03-21 13:24:56 +0000},
- Isbn = {9783540429067},
- Lccn = {2002511027},
- Publisher = {Springer},
- Series = {Engineering online library},
- Title = {Computational Contact and Impact Mechanics: Fundamentals of Modeling Interfacial Phenomena in Nonlinear Finite Element Analysis},
- Year = {2002},
- Bdsk-Url-1 = {http://books.google.ch/books?id=umzsErNuyFgC}}
-
-@book{curnier92a,
- Author = {Curnier, A. and Curnier, A. and Curnier, A.},
- Publisher = {EPFL},
- Title = {M{\'e}thodes num{\'e}riques en m{\'e}canique des solides},
- Url = {http://books.google.ch/books?id=-Z2zygAACAAJ},
- Year = {1992},
- Bdsk-Url-1 = {http://books.google.ch/books?id=-Z2zygAACAAJ}}
-
-@article{hughes-83a,
- Author = {Hughes, T.J.R. and Belytschko, T.},
- Journal = {Journal. of Applied Mechanics (ASME)},
- Pages = {1033-1041},
- Title = {A precis of developments in computational methods for transient analysis},
- Volume = {50},
- Year = {1983}}
-
-@book{simo92,
- Author = {Simo, J.C. and Hughes, T.J.R.},
- Publisher = {Springer},
- Title = {Computational Inelasticity},
- Year = {1992}}
-
-@book{frey2009,
- Author = {Frey, F. and Jirousek, J.},
- Isbn = {9782880748524},
- Publisher = {PPUR},
- Series = {Trait{\'e} de g{\'e}nie civil de l'Ecole Polytechnique F{\'e}d{\'e}rale de Lausanne},
- Title = {M{\'e}thodes des {\'e}l{\'e}ments finis: Analyse des structures et milieux continus},
- Url = {http://books.google.fr/books?id=bCBtQgAACAAJ},
- Year = {2009},
- Bdsk-Url-1 = {http://books.google.fr/books?id=bCBtQgAACAAJ}}
-
-@article{ortiz1999,
- Author = {Ortiz, M. and Pandolfi, A.},
- Journal = {International Journal for Numerical Methods in Engineering (IJNME)},
- Pages = {1267-1282},
- Title = {Finite-deformation irreversible cohesive elements for three-dimensional crack-propagation analysis},
- Volume = {44},
- Year = {1999}}
-
-@article{gmsh,
- Author = {Geuzaine, Christophe and Remacle, Jean-Fran{\c c}ois},
- Doi = {10.1002/nme.2579},
- Issn = {1097-0207},
- Journal = {International Journal for Numerical Methods in Engineering},
- Keywords = {computer-aided design, mesh generation, post-processing, finite element method, open-source software},
- Number = {11},
- Pages = {1309--1331},
- Publisher = {John Wiley & Sons, Ltd.},
- Title = {Gmsh: A 3-D finite element mesh generator with built-in pre- and post-processing facilities},
- Url = {http://dx.doi.org/10.1002/nme.2579},
- Volume = {79},
- Year = {2009},
- Bdsk-Url-1 = {http://dx.doi.org/10.1002/nme.2579}}
-
-@misc{abaqus,
- Key = {Unified FEA},
- Title = {Simulia ABAQUS FEA},
- Url = {\url{http://www.3ds.com/products-services/simulia/portfolio/abaqus/}},
- Bdsk-Url-1 = {http://www.3ds.com/products-services/simulia/portfolio/abaqus/}}
-
-@misc{diana,
- Key = {FEM},
- Title = {TNO DIANA},
- Url = {\url{http://tnodiana.com/content/DIANA}},
- Bdsk-Url-1 = {http://tnodiana.com/content/DIANA}}
-
-@misc{mumps,
- Key = {sparse matrix, direct solver, parallelisme},
- Title = {MUMPS : a parallel sparse direct solver},
- Url = {\url{http://graal.ens-lyon.fr/MUMPS/}},
- Bdsk-Url-1 = {http://graal.ens-lyon.fr/MUMPS/}}
-
-@misc{cmake,
- Title = {CMake - Cross Platform Make},
- Url = {\url{http://www.cmake.org/}},
- Bdsk-Url-1 = {http://www.cmake.org/}}
-
-@misc{paraview,
- Title = {ParaView - Open Source Scientific Visualization},
- Url = {\url{http://www.paraview.org/}},
- Bdsk-Url-1 = {http://www.paraview.org/}}
-
-@misc{visit,
- Title = {VisIt Visualization Tool},
- Url = {\url{http://wci.llnl.gov/codes/visit/}},
- Bdsk-Url-1 = {http://wci.llnl.gov/codes/visit/}}
-
-@misc{mayavi,
- Title = {The MayaVi Data Visualizer},
- Url = {\url{http://mayavi.sourceforge.net/}},
- Bdsk-Url-1 = {http://mayavi.sourceforge.net/}}
-
-@misc{scotch,
- Title = {SCOTCH: Static Mapping, Graph, Mesh and Hypergraph Partitioning},
- Url = {\url{http://www.labri.fr/perso/pelegrin/scotch/}},
- Bdsk-Url-1 = {http://www.labri.fr/perso/pelegrin/scotch/}}
-
-@article{camacho_computational_1996,
- Author = {Camacho, {G.T.} and Ortiz, M.},
- Journal = {International Journal of Solids and Structures},
- Month = aug,
- Number = {20{\textendash}22},
- Pages = {2899--2938},
- Title = {Computational modelling of impact damage in brittle materials},
- Urldate = {2012-01-17},
- Volume = {33},
- Year = {1996}}
-
-@article{snozzi_cohesive_2013,
- Author = {Snozzi, Leonardo and Molinari, Jean-Francois},
- Journal = {International Journal for Numerical Methods in Engineering},
- Month = feb,
- Number = {5},
- Pages = {510--526},
- Title = {A cohesive element model for mixed mode loading with frictional contact capability},
- Volume = {93},
- Year = {2013}}
-
-@article{bazant76a,
- Author = {Zden\v{e}k P. Ba\v{z}ant},
- Journal = {Journal of the Engineering Mechanics Division},
- Number = 5,
- Pages = {331 - 344},
- Title = {Instability, Ductility, and Size Effect in Strain-Softening Concrete},
- Volume = 102,
- Year = 1976}
-
-@article{bazant85a,
- Author = {Zden\v{e}k P. Ba\v{z}ant and Ted Belytschko},
- Journal = {Journal of Engineering Mechanics},
- Number = 3,
- Pages = {381 - 389},
- Title = {Wave Propagation in a Strain-Softening Bar: Exact Solution},
- Volume = 111,
- Year = 1985}
-
-@article{bazant86a,
- Author = {Zden\v{e}k P. Ba\v{z}ant},
- Journal = {Applied Mechanics Reviews},
- Number = 5,
- Pages = {675 - 705},
- Title = {Mechanics of distributed cracking},
- Volume = 39,
- Year = 1986}
-
-@article{bazant88a,
- Author = {Zden\v{e}k P. Ba\v{z}ant and Gilles Pijaudier-Cabot},
- Journal = {Journal of Applied Mechanics},
- Number = {2},
- Optdoi = {10.1115/1.3173674},
- Pages = {287-293},
- Publisher = {ASME},
- Title = {{Nonlocal Continuum Damage, Localization Instability and Convergence}},
- Volume = {55},
- Year = {1988}}
-
-@article{devree95,
- Author = {J.H.P. de Vree and W.A.M. Brekelmans and M.A.J. van Gils},
- Issn = {0045-7949},
- Journal = {Computers \&; Structures},
- Number = 4,
- Optdoi = {10.1016/0045-7949(94)00501-S},
- Pages = {581 - 588},
- Title = {Comparison of nonlocal approaches in continuum damage mechanics},
- Volume = 55,
- Year = 1995}
-
-@article{giry11a,
- Author = {C. Giry and F. Dufour and J. Mazars},
- Journal = {International Journal of Solids and Structures},
- Pages = {3431 - 3443},
- Title = {Stress-based nonlocal damage model},
- Volume = 48,
- Year = 2011}
-
-@article{hughes83a,
- Author = {{Hughes}, T.~J.~R. and {Belytschko}, T.},
- Journal = {Journal of Applied Mechanics},
- Month = {December},
- Optdoi = {10.1115/1.3167186},
- Pages = {1033},
- Title = {{A Pr{\'e}cis of Developments in Computational Methods for Transient Analysis}},
- Volume = 50,
- Year = 1983}
-
-@article{jirasek98a,
- Author = {Milan Jir\'asek},
- Journal = {International Journal of Solids and Structures},
- Pages = {4133 - 4145},
- Title = {Nonlocal models for damage and fracture: comparison of approaches},
- Volume = 35,
- Year = 1998}
-
-@article{jirasek03a,
- Author = {Milan Jir\'asek and Simon Rolshoven},
- Journal = {International Journal of Engineering Science},
- Pages = {1553-1602},
- Title = {Comparison of integral-type nonlocal plasticity models for strain-softening materials},
- Volume = 41,
- Year = 2003}
-
-@article{jirasek04a,
- Author = {Milan Jir\'asek and S Rolshoven and P Grassl},
- Journal = {International Journal for numerical and analytical methods in geomechanics},
- Pages = {653 - 670},
- Title = {Size effect on fracture energy induced by non-locality},
- Volume = 28,
- Year = 2004}
-
-@articlel{jirasek07a,
- Author = {Milan Jir\'asek},
- Journal = {Revue Europeenne de Genie Civil},
- Pages = {977 - 991},
- Title = {Mathematical analysis of strain localization},
- Volume = 11,
- Year = 2007}
-
-@article{jirasek07b,
- Author = {Milan Jir\'asek},
- Journal = {Revue Europeenne de Genie Civil},
- Pages = {993 - 1021},
- Title = {Nonlocal damage mechanics},
- Volume = 11,
- Year = 2007}
-
-@article{marigo81a,
- Author = {Marigo, Jean-Jacques},
- Issn = {0249-6305},
- Journal = {{C. R. Acad. Sci., Paris, S\'er. II}},
- Number = 19,
- Pages = {1309-1312},
- Title = {{Formulation d'une loi d'endommagement d'un mat\'eriau \'elastique}},
- Volume = 292,
- Year = {1981}}
-
-@phdthesis{mazars84a,
- Author = {Mazars, Jacky},
- School = {Universit\'e Paris 6},
- Title = {{Application de la m\'ecanique de l'endommagement au comportement non lin\'eaire et \`a la rupture du b\'eton de structure}},
- Year = 1984}
-
-@article{needleman88a,
- Author = {A. Needleman},
- Issn = {0045-7825},
- Journal = {Computer Methods in Applied Mechanics and Engineering},
- Number = 1,
- Optdoi = {10.1016/0045-7825(88)90069-2},
- Pages = {69 - 85},
- Title = {Material rate dependence and mesh sensitivity in localization problems},
- Volume = 67,
- Year = 1988}
-
-@article{newmark59a,
- Author = {Nathan M. Newmark},
- Editor = {ASCE},
- Journal = {Journal of the Engineering Mechanics Division},
- Month = {July},
- Number = {3},
- Pages = {67-94},
- Title = {{A Method of Computation for Structural Dynamics}},
- Volume = {85},
- Year = {1959}}
-
-@article{pijaudier87a,
- Author = {Gilles Pijaudier-Cabot and Zden\v{e}k P. Ba\v{z}ant},
- Journal = {Journal of Engineering Mechanics},
- Number = 10,
- Pages = {1512 - 1533},
- Title = {Nonlocal damage theory},
- Volume = 113,
- Year = 1987}
-
-@article{rice76a,
- Author = {James R. Rice},
- Journal = {Theoretical and Applied Mechanics (14th International Congress on Theoretical and Applied Mechanics, Delft, 1976, ed. W.T. Koiter)},
- Pages = {207 - 220},
- Title = {The Localisation of Plastic Deformation},
- Volume = 1,
- Year = 1976}
-
-@article{sharon96a,
- Author = {Eran Sharon and Jay Fineberg},
- Journal = {Physical Review B},
- Number = 10,
- Pages = {7128 - 7139},
- Title = {Microbranching instability and the dynamic fracture of brittle materials},
- Volume = 54,
- Year = 1996}
-
-@article{aifantis84a,
- Author = {E. C. Aifantis},
- Journal = {Journal of Engineering Materials and Technology},
- Pages = {326 - 330},
- Title = {On the microstructural origin of certain inelastic models},
- Volume = {106},
- Year = 1984}
-
-@article{ladeveze92a,
- Author = {P. Ladeveze},
- Journal = {Computational \& Structures},
- Pages = {79-87},
- Title = {A damage computational method for composite structures},
- Volume = {44},
- Year = {1992}}
-
-@phdthesis{levy10a,
- Address = {Lausanne},
- Affiliation = {EPFL},
- Author = {Levy, Sarah},
- Doctoral = {EDME},
- Institute = {IIC},
- Original-Unit = {LSMS},
- Publisher = {EPFL},
- School = {ENAC},
- Title = {Exploring the {P}hysics behind {D}ynamic {F}ragmentation through {P}arallel {S}imulations},
- Unit = {LSMS},
- Year = 2010}
-
-@article{pandolfi12a,
- Author = {A Pandolfi and M Ortiz},
- Journal = {International Journal for Numerical Methods in Engineering},
- Pages = {694-714},
- Title = {An eigenerosion approach to brittle fracture},
- Volume = 92,
- Year = 2012}
-
-@article{belytschko03a,
- Author = {T Belytschko and H Chen and J Xu and G Zi},
- Journal = {International Journal for Numerical Methods in Engineering},
- Pages = {1875-1905},
- Title = {Dynamic crack propagation based on loss of hyperbolicity and a new discontinuous enrichment},
- Volume = 58,
- Year = 2003}
-
-@article{silling00a,
- Author = {S A Silling},
- Journal = {Journal of the Mechanics and Physics of Solids},
- Pages = {175-209},
- Title = {Reformulation of elasticity theory for discontinuities and long-range forces},
- Volume = 48,
- Year = 2000}
-
-@article{youn10a,
- Author = {Youn Doh-Ha and Florin Bobaru},
- Journal = {International Journal of Fracture},
- Pages = {229-1244},
- Title = {Studies of dynamic crack propagation and crack branching with peridynamics},
- Volume = 162,
- Year = 2010}
-
-@article{ortiz99a,
- Author = {M Ortiz and A Pandolfi},
- Journal = {International Journal for Numerical Methods in Engineering},
- Pages = {1267-1282},
- Title = {Finite-deformation irreversible cohesive elements for three-dimensional crack-propagation analysis},
- Volume = {44},
- Year = 1999}
-
-@article{patzak01a,
- Author = {B. Patz{\'a}k and D. Rypl and Z. Bittnar},
- Issn = {0045-7949},
- Journal = {{Computers \& Structures}},
- Number = {26--28},
- Pages = {2287 - 2297},
- Title = {Parallel explicit finite element dynamics with nonlocal constitutive models},
- Volume = 79,
- Year = 2001}
-
-@book{lemaitre96a,
- Author = {Lemaitre, Jean},
- Isbn = {978-3-540-60980-3},
- Publisher = {Springer Berlin Heidelberg},
- Title = {A Course on Damage Mechanics},
- Year = {1996}}
-
-@book{courant56a,
- Address = {New York},
- Author = {Courant, Richard and Friedrichs, Kurt Otto and Lewy, H.},
- Publisher = {Courant Institute of Mathematical Sciences, New York University},
- Title = {On the partial difference equations of mathematical physics},
- Year = {1956}}
-
-@unpublished{wolff14a,
- Author = {C. Wolff and N. Richart and JF Molinari},
- Note = {Submitted to IJNME},
- Title = {A non-local continuum damage approach to model dynamic crack branching},
- Year = {2014}}
-
-@article{caughey1960,
- Author = {Caughey, TK},
- Journal = {Journal of Applied Mechanics},
- Number = {2},
- Pages = {269--271},
- Publisher = {American Society of Mechanical Engineers},
- Title = {Classical normal modes in damped linear dynamic systems},
- Volume = {27},
- Year = {1960}}
+% 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 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 8c727993c..20e251bab 100644
--- a/doc/manual/manual-cohesive_elements_insertion.tex
+++ b/doc/manual/manual-cohesive_elements_insertion.tex
@@ -1,67 +1,81 @@
+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}
-\subsubsection{Dynamics}
-As far as dynamic simulations are concerned, cohesive elements are
-currently compatible only with the 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. Intrinsic cohesive elements can be introduced at the
-beginning of the simulation as follows:
+<<<<<<< Updated upstream
+Cohesive elements are currently compatible only with static simulation
+and dynamic simulation with an explicit time integration scheme (see
+section~\ref{ssect:smm:expl-time-integr}). They do not have to be inserted when the mesh is generated (intrinsic) but can be added during the simulation (extrinsic). At any time during the simulation, it is possible to access the following energies with the relative function:
\begin{cpp}
- SolidMechanicsModelCohesive model(mesh);
- model.initFull();
- model.limitInsertion(_x, -1, 1);
- model.insertIntrinsicElements();
+ Real Ed = model.getEnergy("dissipated");
+ Real Er = model.getEnergy("reversible");
+ Real Ec = model.getEnergy("contact");
\end{cpp}
-where the insertion is limited to the facets whose barycenter's $x$
-coordinate is in the range $[-1,1]$. Additional restrictions with
-respect to $y$ and $z$ directions can be added as well. Similarly the
-dynamic insertion of extrinsic cohesive elements can be utilized in
-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.limitInsertion(_x, -1, 1);
+\end{cpp}
+
+
+\subsubsection{Extrinsic approach}
+The dynamic insertion of extrinsic cohesive elements should be initialized
+in the following way:
+\begin{cpp}
model.updateAutomaticInsertion();
-\end{cpp}
-in which this time the method \code{limitInsertion} prevents the
-cohesive elements to be inserted out of the range $[-1,1]$ in the $x$
-direction. In order to check stress and automatically insert elements,
-it is necessary to call the function \code{checkCohesiveStress} in the
-main loop where \code{solveStep} is:
+\end{cpp}
+During the simulation, stress has to be checked along each facet in order to insert cohesive elements where thestress criterion is reached.
+This check is performed by calling the method \code{checkCohesiveStress}, as
+example before each step resolution:
\begin{cpp}
model.checkCohesiveStress();
model.solveStep();
\end{cpp}
-
-At any time during the simulation, it is possible to access the
-following energies with the relative function:
+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}
- Real Ed = model.getEnergy("dissipated");
- Real Er = model.getEnergy("reversible");
- Real Ec = model.getEnergy("contact");
-\end{cpp}
+ model.limitInsertion(_x, -1.5, 1.5);
+ model.updateAutomaticInsertion();
+\end{cpp}
+Additional restrictions with respect to $y$ and $z$ directions can be added as well.
-\subsubsection{Statics}
-The only cohesive law that is applicable in this case is the
-exponential one (see
-section~\ref{ssect:smm:cl:coh-exponential}). However
-unloading-reloading cycles are not supported yet. In this case
-cohesive elements have to be inserted before creating the
-\code{SolidMechanicsModelCohesive} model:
+\subsubsection{Intrinsic approach \label{intrinsic_insertion}}
+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}
- Mesh mesh(spatial_dimension);
- mesh.read("implicit_mesh.msh");
-
- CohesiveElementInserter inserter(mesh);
- inserter.setLimit(_y, 0.9, 1.1);
- inserter.insertIntrinsicElements();
-
- 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. To do so, cohesive elements can be inserted along a
+specific group of surface elements identified in a GMSH geometry file. This can
+be achieved with the material selector (see section~\ref{sect:smm:materialselector}), in the input file specify the name of these physical groups in the corresponding cohesive materials, and call these material in the \textit{mesh parameters} section. As example, with two physical surfaces named
+\textit{weak\_interface} and \textit{strong\_interface} defined in the GMSH
+geometry file:
+\begin{cpp}
+...
+ material %\emph{cohesive\_constitutive\_law}% [
+ name = weak_interface
+ sigma_c = $value$
+ ...
+ ]
+ material %\emph{cohesive\_constitutive\_law}% [
+ name = strong_interface
+ sigma_c = $value$
+ ...
+ ]
+ mesh parameters [
+ cohesive_surfaces = weak_interface,strong_interface
+ ]
\end{cpp}
-Also in this case the element insertion can be limited to a given
-range thanks to the method \code{setLimit}. The first input parameter
-of this method indicates the direction while the other two indicate
-the extreme values of the range $[0.9, 1.1]$. In order to compute the
-energies, the same functions illustrated for dynamics in the last
-section can be used.
+
+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 4185d9645..dc88f7437 100644
--- a/doc/manual/manual-cohesive_laws.tex
+++ b/doc/manual/manual-cohesive_laws.tex
@@ -1,150 +1,205 @@
\subsection{Cohesive laws}
\label{sec:cohesive-laws}
-\subsubsection{Snozzi-Molinari Law\matlabel{ssect:smm:cl:coh-snozzi}}
+\subsubsection{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\_cI}: 0
-\item \code{G\_cII}: 0
+\item \code{G\_c}: 0
\item \code{kappa}: 1
\item \code{penalty}: 0
\end{itemize}
-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}).
+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}}
+
+This law represents a variation of the linear irreversible cohesive
+law of the previous section, that removes the hypothesis of elastic
+unloading-reloading cycles. With this law, some energy is dissipated
+also during unloading and reloading with hysteresis. The
+implementation follows the work of~\cite{nguyen2001}. During the
+unloading-reloading cycle, the traction increment is computed as
+\begin{equation}
+ \dot{T} =
+ \begin{cases}
+ K^- \, \dot{\delta} & \text{if $\dot{\delta} < 0$} \\
+ K^+ \, \dot{\delta} & \text{if $\dot{\delta} > 0$} \\
+ \end{cases}
+\end{equation}
+where $\dot{\delta}$ and $\dot{T}$ are respectively the effective
+opening displacement and the cohesive traction increments with respect
+to time, while $K^-$ and $K^+$ are respectively the unloading and
+reloading incremental stiffness. The unloading path is linear and
+results in an unloading stiffness
+\begin{equation}
+ K^- = \frac{T_\mathrm{max}}{\delta_\mathrm{max}}
+\end{equation}
+where $T_\mathrm{max}$ and $\delta_\mathrm{max}$ are the maximum
+cohesive traction and the effective opening displacement reached
+during the precedent loading phase. The unloading stiffness remains
+constant during the unloading phase. On the other hand the reloading
+stiffness increment $\dot{K}^+$ is calculated as
+\begin{equation}
+ \dot{K}^+ =
+ \begin{cases}
+ - K^+ \, \dot{\delta} / \delta_\mathrm{f} & \text{if $\dot{\delta}
+ > 0$} \\
+ \left( K^+ - K^- \right) \, \dot{\delta} / \delta_\mathrm{f} &
+ \text{if $\dot{\delta} < 0$}
+ \end{cases}
+\end{equation}
+where $\delta_\mathrm{f}$ is a material parameter (refer
+to~\cite{vocialta15} for more details). During unloading the stiffness
+$K^+$ tends to $K^-$, while during reloading $K^+$ gets decreased at
+every time step. If the cohesive traction during reloading exceeds the
+upper limit given by equation~\eqref{eq:smm:coh:tractions}, it is
+recomputed following the behavior of the linear decreasing cohesive
+law for crack opening.
+
\subsubsection{Exponential Cohesive Law\matlabel{ssect:smm:cl:coh-exponential}}
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 23a8f9eb6..d9e95716c 100644
--- a/doc/manual/manual-constitutive-laws.tex
+++ b/doc/manual/manual-constitutive-laws.tex
@@ -1,529 +1,528 @@
\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:
+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.
+which depends on $m$ and $\lambda$, which are the shape parameter and
+the scale parameter. These random distributions are different each
+time the code is executed. In order to obtain always the same one, it
+possible to manually set the \emph{seed} that is the number from which
+these pseudo-random distributions are created. This can be done by
+adding the following line to the input file \emph{outside} the
+material parameters environments:
+\begin{cpp}
+ seed = 1.0
+\end{cpp}
+where the value 1.0 can be substituted with any number. Currently
+\akantu can reproduce always the same distribution when the seed is
+specified \emph{only} in serial. The value of the \emph{seed} can be
+also specified directly in the code (for instance in the main file)
+with the command:
+\begin{cpp}
+ RandGenerator:: seed(1.0)
+\end{cpp}
+The same command, with empty brackets, can be used to check the value
+of the \emph{seed} used in the simulation.
The following sections describe the constitutive models implemented in
\akantu. In Appendix~\ref{app:material-parameters} a summary of the
parameters for all materials of \akantu is provided.
\subsection{Elasticity}\index{Material!Elastic}
The elastic law is a commonly used constitutive relationship that can be used
for a wide range of engineering materials (\eg metals, concrete, rock, wood,
glass, rubber, etc.) provided that the strains remain small (\ie small
deformation and stress lower than yield strength).
The elastic laws are often expressed as $\mat{\sigma} =
\mat{C}:\mat{\varepsilon}$ with where $\mat{\sigma}$ is the Cauchy stress tensor,
$\mat{\varepsilon}$ represents the infinitesimal strain tensor and $\mat{C}$ is the
elastic modulus tensor.
\subsubsection{Linear isotropic\matlabel{ssect:smm:linear-elastic-isotropic}}
The linear isotropic elastic behavior is described by Hooke's law, which states
that the stress is linearly proportional to the applied strain (material behaves
like an ideal spring), as illustrated in Figure~\ref{fig:smm:cl:elastic}.
\begin{figure}[!htb]
\begin{center}
\subfloat[]{
\begin{tikzpicture}
\draw[thick,latex-latex] (0,5) node[left] {$\sigma$} |- (5,0) node (x) [right, below] {$\varepsilon$};
\draw[thin] (1.5,1.5) -- (2.5,1.5) -- (2.5,2.5) node [midway, right] {E};
\draw[very thick,color=red] (0,0) -- (4,4);
\draw[very thick,latex-latex,color=red] (1,1) -- (3,3);
\end{tikzpicture}
\label{fig:smm:cl:elastic:stress_strain} }
\hspace{0.05\textwidth} \subfloat[]{
\raisebox{0.125\textwidth}{\includegraphics[width=0.25\textwidth,keepaspectratio=true]{figures/hooke_law.pdf}}
\label{fig:smm:cl:elastic:hooke} }
\caption{(a) Stress-strain curve for elastic material and (b)
schematic representation of Hooke's law, denoted as a spring.}
\label{fig:smm:cl:elastic}
\end{center}
\end{figure}
The equation that relates the strains to the
displacements is: % First the strain is computed (at every gauss
point) from the displacements as follows:
\begin{equation}
\label{eqn:smm:strain_inf}
\mat{\varepsilon} =
\frac{1}{2} \left[ \nabla_0 \vec{u}+\nabla_0 \vec{u}^T \right]
\end{equation}
where $\mat{\varepsilon}$ represents the infinitesimal strain tensor,
$\nabla_{0}\vec{u}$ the displacement gradient
tensor according to the initial configuration. The constitutive equation
for isotropic homogeneous media can be expressed as:
\begin{equation}
\label{eqn:smm:material:constitutive_elastic}
\mat{\sigma } =\lambda\mathrm{tr}(\mat{\varepsilon})\mat{I}+2 \mu\mat{\varepsilon}
\end{equation}
where $\mat{\sigma}$ is the Cauchy stress tensor
($\lambda$ and $\mu$ are the the first and second Lame's
coefficients).
In Voigt notation this correspond to
\begin{align}
\left[\begin{array}{c}
\sigma_{11}\\
\sigma_{22}\\
\sigma_{33}\\
\sigma_{23}\\
\sigma_{13}\\
\sigma_{12}\\
\end{array}\right]
&= \frac{E}{(1+\nu)(1-2\nu)}\left[
\begin{array}{cccccc}
1-\nu & \nu & \nu & 0 & 0 & 0\\
\nu & 1-\nu & \nu & 0 & 0 & 0\\
\nu & \nu & 1-\nu & 0 & 0 & 0\\
0 & 0 & 0 & \frac{1-2\nu}{2} & 0 & 0 \\
0 & 0 & 0 & 0 & \frac{1-2\nu}{2} & 0 \\
0 & 0 & 0 & 0 & 0 & \frac{1-2\nu}{2} \\
\end{array}\right]
\left[\begin{array}{c}
\varepsilon_{11}\\
\varepsilon_{22}\\
\varepsilon_{33}\\
2\varepsilon_{23}\\
2\varepsilon_{13}\\
2\varepsilon_{12}\\
\end{array}\right]
\end{align}
\subsubsection{Linear anisotropic\matlabel{ssect:smm:linear-elastic-anisotropic}}
This formulation is not sufficient to represent all elastic material
behavior. Some materials have characteristic orientation that have to be taken
into account. To represent this anisotropy a more general stress-strain law has
to be used. For this we define the elastic modulus tensor as follow:
\begin{align}
\left[\begin{array}{c}
\sigma_{11}\\
\sigma_{22}\\
\sigma_{33}\\
\sigma_{23}\\
\sigma_{13}\\
\sigma_{12}\\
\end{array}\right]
&= \left[
\begin{array}{cccccc}
c_{11} & c_{12} & c_{13} & c_{14} & c_{15} & c_{16}\\
c_{21} & c_{22} & c_{23} & c_{24} & c_{25} & c_{26}\\
c_{31} & c_{32} & c_{33} & c_{34} & c_{35} & c_{36}\\
c_{41} & c_{42} & c_{43} & c_{44} & c_{45} & c_{46}\\
c_{51} & c_{52} & c_{53} & c_{54} & c_{55} & c_{56}\\
c_{61} & c_{62} & c_{63} & c_{64} & c_{65} & c_{66}\\
\end{array}\right]
\left[\begin{array}{c}
\varepsilon_{11}\\
\varepsilon_{22}\\
\varepsilon_{33}\\
2\varepsilon_{23}\\
2\varepsilon_{13}\\
2\varepsilon_{12}\\
\end{array}\right]
\end{align}
\begin{figure}[h]
\centering
\begin{tikzpicture}
\draw[thick,latex-latex] (90:3) node[left] {$\vec{e_2}$} |- (0:3) node [right, below] {$\vec{e_1}$};
\draw[ultra thick,latex-latex] (150:3) node[left] {$\vec{n_2}$} -- (0,0) -- (20:3) node [right] {$\vec{n_1}$};
\end{tikzpicture}
\caption{Material basis}
\end{figure}
To simplify the writing of input files the \mat{C} tensor is expressed in the
material basis. And this basis as to be given too. This basis $\Omega_{\st{mat}}
= \{\vec{n_1}, \vec{n_2}, \vec{n_3}\}$ is used to define the rotation $R_{ij} =
\vec{n_j} . \vec{e_i}$. And $\mat{C}$ can be rotated in the global basis $\Omega
= \{\vec{e_1}, \vec{e_2}, \vec{e_3}\}$ as follow:
\begin{align}
\mat{C}_{\Omega} &= \mat{R}_1 \mat{C}_{\Omega_{\st{mat}}} \mat{R}_2\\
\mat{R}_1 &= \left[
\begin{array}{cccccc}
R_{11} R_{11} & R_{12} R_{12} & R_{13} R_{13} & R_{12} R_{13} & R_{11} R_{13} & R_{11} R_{12}\\
R_{21} R_{21} & R_{22} R_{22} & R_{23} R_{23} & R_{22} R_{23} & R_{21} R_{23} & R_{21} R_{22}\\
R_{31} R_{31} & R_{32} R_{32} & R_{33} R_{33} & R_{32} R_{33} & R_{31} R_{33} & R_{31} R_{32}\\
R_{21} R_{31} & R_{22} R_{32} & R_{23} R_{33} & R_{22} R_{33} & R_{21} R_{33} & R_{21} R_{32}\\
R_{11} R_{31} & R_{12} R_{32} & R_{13} R_{33} & R_{12} R_{33} & R_{11} R_{33} & R_{11} R_{32}\\
R_{11} R_{21} & R_{12} R_{22} & R_{13} R_{23} & R_{12} R_{23} & R_{11} R_{23} & R_{11} R_{22}\\
\end{array}\right]\\
\mat{R}_2 &= \left[
\begin{array}{cccccc}
R_{11} R_{11} & R_{21} R_{21} & R_{31} R_{31} & R_{21} R_{31} & R_{11} R_{31} & R_{11} R_{21}\\
R_{12} R_{12} & R_{22} R_{22} & R_{32} R_{32} & R_{22} R_{32} & R_{12} R_{32} & R_{12} R_{22}\\
R_{13} R_{13} & R_{23} R_{23} & R_{33} R_{33} & R_{23} R_{33} & R_{13} R_{33} & R_{13} R_{23}\\
R_{12} R_{13} & R_{22} R_{23} & R_{32} R_{33} & R_{22} R_{33} & R_{12} R_{33} & R_{12} R_{23}\\
R_{11} R_{13} & R_{21} R_{23} & R_{31} R_{33} & R_{21} R_{33} & R_{11} R_{33} & R_{11} R_{23}\\
R_{11} R_{12} & R_{21} R_{22} & R_{31} R_{32} & R_{21} R_{32} & R_{11} R_{32} & R_{11} R_{22}\\
\end{array}\right]\\
\end{align}
\subsubsection{Linear orthotropic\matlabel{ssect:smm:linear-elastic-orthotropic}}
A particular case of anisotropy is when the material basis is orthogonal in which case the elastic modulus tensor can be simplified and rewritten in terms of 9 independents material parameters.
\begin{align}
\left[\begin{array}{c}
\sigma_{11}\\
\sigma_{22}\\
\sigma_{33}\\
\sigma_{23}\\
\sigma_{13}\\
\sigma_{12}\\
\end{array}\right]
&= \left[
\begin{array}{cccccc}
c_{11} & c_{12} & c_{13} & 0 & 0 & 0 \\
& c_{22} & c_{23} & 0 & 0 & 0 \\
& & c_{33} & 0 & 0 & 0 \\
& & & c_{44} & 0 & 0 \\
& \multicolumn{2}{l}{\text{sym.}} & & c_{55} & 0 \\
& & & & & c_{66}\\
\end{array}\right]
\left[\begin{array}{c}
\varepsilon_{11}\\
\varepsilon_{22}\\
\varepsilon_{33}\\
2\varepsilon_{23}\\
2\varepsilon_{13}\\
2\varepsilon_{12}\\
\end{array}\right]
\end{align}
\begin{align}
c_{11} &= E_1 (1 - \nu_{23}\nu_{32})\Gamma \qquad c_{22} = E_2 (1 - \nu_{13}\nu_{31})\Gamma \qquad c_{33} = E_3 (1 - \nu_{12}\nu_{21})\Gamma\\
c_{12} &= E_1 (\nu_{21} - \nu_{31}\nu_{23})\Gamma = E_2 (\nu_{12} - \nu_{32}\nu_{13})\Gamma\\
c_{13} &= E_1 (\nu_{31} - \nu_{21}\nu_{32})\Gamma = E_2 (\nu_{13} - \nu_{21}\nu_{23})\Gamma\\
c_{23} &= E_2 (\nu_{32} - \nu_{12}\nu_{31})\Gamma = E_3 (\nu_{23} - \nu_{21}\nu_{13})\Gamma\\
c_{44} &= \mu_{23} \qquad c_{55} = \mu_{13} \qquad c_{66} = \mu_{12} \\
\Gamma &= \frac{1}{1 - \nu_{12} \nu_{21} - \nu_{13} \nu_{31} - \nu_{32} \nu_{23} - 2 \nu_{21} \nu_{32} \nu_{13}}
\end{align}
-The 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. The governing variable in this damage
+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.
-The damage the is defined as:
+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-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-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-heattransfermodel.tex b/doc/manual/manual-heattransfermodel.tex
index 473878c24..bde83668d 100644
--- a/doc/manual/manual-heattransfermodel.tex
+++ b/doc/manual/manual-heattransfermodel.tex
@@ -1,166 +1,167 @@
\chapter{Heat Transfer Model}
The heat transfer model is a specific implementation of the \code{Model} interface
dedicated to handle the dynamic heat equation.
\section{Theory}
The strong form of the dynamic heat equation
can be expressed as
\begin{equation}
\rho c_v \dot{T} + \nabla \cdot \vec{\kappa} \nabla T = b
\end{equation}
with $T$ the scalar temperature field,
$c_v$ the specific heat capacity,
$\rho$ the mass density,
$\mat{\kappa}$ the conductivity tensor, and $b$ the heat generation per unit of volume.
The discretized weak form with a finite number of elements is
\begin{equation}
\forall i \quad
\sum_j \left( \int_\Omega \rho c_v N_j N_i d\Omega \right) \dot{T}_j
- \sum_j \left( \int_\Omega \vec{\kappa} \nabla N_j \nabla N_i d\Omega \right) T_j =
- \int_{\Gamma} N_i \vec{q} \cdot \vec{n} d\Gamma + \int_\Omega b N_i d\Omega
\end{equation}
with $i$ and $j$ the node indices, $\vec{n}$ the normal field to the surface
$\Gamma = \partial \Omega$.
To simplify, we can define the capacity and the conductivity matrices as
\begin{equation}
C_{ij} = \int_\Omega \rho c_v N_j N_i d\Omega \qquad \textrm{and} \qquad
K_{ij} = - \int_\Omega \vec{\kappa} \nabla N_j \nabla N_i d\Omega
\end{equation}
and the system to solve can be written
\begin{equation}
\mat{C} \cdot \vec{\dot{T}} = \vec{Q}^{\text{ext}} -\mat{K} \cdot \vec{T}~,
\end{equation}
with $\vec{Q}^{\text{ext}}$ the consistent heat generated.
\section{Using the Heat Transfer Model}
+A material file name has to be provided during initialization.
Currently, the \code{HeatTransferModel} object uses dynamic analysis
with an explicit time integration scheme. It can simply be created
like this
\begin{cpp}
HeatTransferModel model(mesh, spatial_dimension);
\end{cpp}
while an existing mesh has been used (see \ref{sect:common:mesh}).
Then the model object can be initialized with:
\begin{cpp}
model.initFull()
\end{cpp}
-where a material file name has to be provided. This function will load the material
+This function will load the material
properties, and allocate / initialize the nodes and element \code{Array}s
More precisely, the heat transfer model contains 4 \code{Arrays}:
\begin{description}
\item[temperature] contains the nodal temperature $T$ (zero by default after the
initialization).
\item[temperature\_rate] contains the variations of temperature $\dot{T}$
(zero by default after the
initialization).
\item[blocked\_dofs] contains a Boolean value for each degree of
freedom specifying whether the degree is blocked or not. A Dirichlet
- boundary condition can be prescribed by setting the
+ boundary condition ($T_d$) can be prescribed by setting the
\textbf{blocked\_dofs} value of a degree of freedom to \code{true}.
The \textbf{temperature} and the \textbf{temperature\_rate} are
computed for all degrees of freedom where 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[residual] contains the difference between external and internal heat generations.
The \textbf{residual} contains the supported heat reactions ($\vec{R} = \vec{Q^{ext}} -\mat{K} \cdot \vec{T}$) on
the nodes that the temperature imposed.
\end{description}
Only a single material can be specified on the domain.
A material text file (\eg material.dat) provides the material properties as follows:
\begin{cpp}
heat %\emph{name\_material}% [
capacity = %\emph{XXX}%
density = %\emph{XXX}%
conductivity = [%\emph{XXX}% ... %\emph{XXX}%]
]
\end{cpp}
where the \code{capacity} and \code{density} are scalars, and the \code{conductivity} is specified as a $3\times 3$ tensor.
\subsection{Explicit Dynamic}
The explicit time integration scheme in \akantu uses a lumped capacity
matrix $\mat{C}$ (reducing the computational cost, see Chapter \ref{sect:smm}).
This matrix is assembled by
distributing the capacity of each element onto its nodes. Therefore, the resulting $\mat{C}$ is a diagonal matrix stored in the \code{capacity} \code{Array} of the model.
\begin{cpp}
model.assembleCapacityLumped();
\end{cpp}
\index{HeatTransferModel!assembleCapacityLumped}
\note{Currently, only the explicit time integration with lumped capacity matrix
-is implemented within \akantu.} \\
+is implemented within \akantu.}
The explicit integration scheme is \index{Forward Euler} \emph{Forward Euler}
\cite{curnier92a}.
\begin{itemize}
\item Predictor: $\vec{T}_{n+1} = \vec{T}_{n} + \Delta t \dot{\vec{T}}_{n}$
\item Update residual: $\vec{R}_{n+1} = \left( \vec{Q^{ext}_{n+1}} - \vec{K}\vec{T}_{n+1} \right)$
\item Corrector : $\dot{\vec{T}}_{n+1} = \mat{C}^{-1} \vec{R}_{n+1}$
\end{itemize}
The explicit integration scheme is conditionally stable. The time step has to be smaller than the stable time step,
and it can be obtained in \akantu as follows:
\begin{cpp}
time_step = model.getStableTimeStep();
\end{cpp}
\index{HeatTransferModel!StableTimeStep}
The stable time step is defined as:
\begin{equation}\label{eqn:htm:explicit:stabletime}
\Delta t_{\st{crit}} = 2 \Delta x^2 \frac{\rho c_v}{\mid\mid \mat{\kappa} \mid\mid^\infty}
\end{equation}
where $\Delta x$ is the characteristic length (\eg the inradius in the
case of linear triangle element), $\rho$ is the density,
$\mat{\kappa}$ is the conductivity tensor, and $c_v$ is the specific
heat capacity. It is necessary to impose a time step which 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.1;
Real applied_time_step = time_step * safety_time_factor;
model.setTimeStep(applied_time_step);
\end{cpp}
The following loop allows, for each time step, to update the \code{temperature}, \code{residual} and
\code{temperature\_rate} fields following the previously described integration scheme.
\begin{cpp}
for (UInt s = 1; (s-1)*applied_time_step < total_time; ++s) {
model.explicitPred();
model.updateResidual();
model.explicitCorr();
}
\end{cpp}
\index{HeatTransferModel!explicitPred}
\index{HeatTransferModel!explicitCorr}
\index{HeatTransferModel!updateResidual}
\index{HeatTransferModel!solveExplicitLumped}
An example of explicit dynamic heat propagation is presented in \\
\shellcode{\examplesdir/heat\_transfer/explicit\_heat\_transfer.cc}. \\
This example consists of a square 2D plate of \SI{1}{\metre^2}
having an initial temperature of \SI{100}{\kelvin} everywhere but a
none centered hot point maintained at
\SI{300}{\kelvin}. Figure~\ref{fig:htm:explicit:dynamic} presents
the geometry of this case. The material used is a linear fictitious
elastic material with a density of
\SI{8940}{\kilo\gram\per\metre^3}, a conductivity of
\SI{401}{\watt\per\metre\per\kelvin} and a specific heat capacity of
\SI{385}{\joule\per\kelvin\per\kilogram}. The time step used is
\SI{0.12}{\second}.
\begin{figure}[!htb]
\centering
\includegraphics[width=.4\textwidth]{figures/hot-point-1}
\hfill
\includegraphics[width=.4\textwidth]{figures/hot-point-2}
\caption{Initial temperature field (left) and after 15000 time steps = 30 minutes (right). The lines represent iso-surfaces.}
\label{fig:htm:explicit:dynamic}
\end{figure}
diff --git a/doc/manual/manual-io.tex b/doc/manual/manual-io.tex
index 51584d692..a053b08f8 100644
--- a/doc/manual/manual-io.tex
+++ b/doc/manual/manual-io.tex
@@ -1,105 +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 \\
- boundary & Vector<bool> & nodes \\
- mass & Vector<Real> & nodes \\
+ increment & Vector<Real> & nodes \\
+ {blocked\_dofs} & Vector<bool> & nodes \\
partitions & Real & elements \\
- stress & Matrix<Real> & quadrature points \\
+ material\_index & variable & elements\\
strain & Matrix<Real> & quadrature points \\
- \textit{material internals} & variable & 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);
- Field field = new DumperIOHelper::NodalField<T>(vect));
- model.addDumpFieldExternal("my_field", field);
-\end{cpp}
-
-\item For elemental fields :
-\begin{cpp}
- ElementTypeMapArray<T> arr;
- Field field = new DumperIOHelper::ElementalField<T>(arr, spatial_displacement));
- 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}
-%%% Local Variables:
+\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:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual-parallel.tex b/doc/manual/manual-parallel.tex
index 588a6aa49..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.\\
+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.}\\
+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-solidmechanicsmodel.tex b/doc/manual/manual-solidmechanicsmodel.tex
index d265c744d..5c3073d47 100644
--- a/doc/manual/manual-solidmechanicsmodel.tex
+++ b/doc/manual/manual-solidmechanicsmodel.tex
@@ -1,1040 +1,1101 @@
\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 the following six \code{Arrays}:
+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}. Boundary conditions can also be
+\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}
-mesh.createGroupsFromMeshData<std::string>("physical_names");
+model.applyBC(BC::Dirichlet::FixedValue(13.0, _y), "Top");
-model.applyBC(BC::Dirichlet::FixedValue(13.0, BC::_y), "Top");
+model.applyBC(BC::Dirichlet::FlagOnly(_x), "Bottom");
-model.applyBC(BC::Dirichlet::FlagOnly(BC::_x), "Bottom");
-
-model.applyBC(BC::Dirichlet::IncrementValue(13.0, BC::_x), "Side");
+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;
-Array<Real> surface_stress(3, 3, 0.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 the different
-finite elements of choice in \akantu, a material selector has to be
+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 pyhsical names can be
+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:
+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);
+ mat_selector = new MeshDataMaterialSelector<UInt>("tag_1", model, first_index);
model.setMaterialSelector(*mat_selector);
\end{cpp}
-where \code{tag\_1} of the mesh file is used as the classifier index
-and the elements that have index value equal to one will be assigned
-to the second material in the material file.
+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. However, for cohesive elements, it is
-not possible to assign multiple cohesive materials automatically and
-user has to write a custom class. \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}. This material selector first
-checks if an element is a cohesive element or a facet. If there is,
-then the first cohesive material in the material file is assigned to
-that element. Otherwise, this material is assigned to the element
-facet, to which, a cohesive element might be inserted later. Hence,
-this material selector works for the extrinsic cohesive elements which
-are dynamically inserted throughout the analysis. If the element of
-interest is not a cohesive element or an element facet, then
-\code{DefaultMaterialSelector} is used by default.
+materials to different elements.
Apart from the \akantu's default material selectors, users can always
develop their own classes in the main code to tackle various
multi-material assignment situations.
% An application of \code{DefaultMaterialCohesiveSelector} and usage in
% a customly generated material selector class can be seen in
% \shellcode{\examplesdir/cohesive\_element/cohesive\_extrinsic\_IG\_TG/cohesive\_extrinsic\_IG\_TG.cc}.
\IfFileExists{manual-cohesive_elements_insertion.tex}{\input{manual-cohesive_elements_insertion}}{}
\section{Static Analysis\label{sect:smm:static}}
The \code{SolidMechanicsModel} class can handle different analysis
methods, the first one being presented is the static case. In this
case, the equation to solve is
\begin{equation}
\label{eqn:smm:static} \mat{K} \vec{u} =
\vec{f}_{\st{ext}}
\end{equation}
where $\mat{K}$ is the global stiffness matrix, $\vec{u}$ the
displacement vector and $\vec{f}_{\st{ext}}$ the vector of external
forces applied to the system.
To solve such a problem, the static solver of the
\code{SolidMechanicsModel}\index{SolidMechanicsModel} object is used.
First, a model has to be created and initialized. To create the
model, a mesh (which can be read from a file) is needed, as explained
in Section~\ref{sect:common:mesh}. Once an instance of a
\code{SolidMechanicsModel} is obtained, the easiest way to initialize
it is to use the \code{initFull}\index{SolidMechanicsModel!initFull}
method by giving the \code{SolidMechanicsModelOptions}. These options
specify the type of analysis to be performed and whether the materials
-should be initialized or not.
+should be initialized with \code{initMaterials} or not.
\begin{cpp}
SolidMechanicsModel model(mesh);
-model.initFull(SolidMechanicsModelOptions(_static));
+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, which are $\num{1e-4}$ and $1$ for this example. The
+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}
\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, the
+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}
-time_step = model.getStableTimeStep();
+critical_time_step = model.getStableTimeStep();
\end{cpp} \index{SolidMechanicsModel!StableTimeStep}
-The stable time step is defined as:
+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}} = \Delta x \sqrt{\frac{\rho}{2 \mu + \lambda}}
+\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), $\mu$ and $\lambda$ are the first
-and second Lame's coefficients and $\rho$ is the density. The stable
-time step corresponds to the time the fastest wave (the compressive
-wave) needs to travel the characteristic length of the mesh.
-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 = time_step * safety_time_factor;
+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{getStableTimeStep}:~ The stable time step should be
- calculated based on \eqref{eqn:smm:explicit:stabletime} for the
- conditionally stable methods. This function depends on the longitudinal wave
- speed which changes for different materials and strains. Therefore,
- the value of this velocity should be defined in this method for
- each new material.
-
- \note {In case of need, the calculation of the longitudinal and
- shear wave speeds can be done in separate functions
- (\code{getPushWaveSpeed} and \code{getShearWaveSpeed}).
- Therefore, the first function can be called for calculation of the
- stable time step.}
+\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-structuralmechanicsmodel.tex b/doc/manual/manual-structuralmechanicsmodel.tex
index 1c73c6712..9e080e27a 100644
--- a/doc/manual/manual-structuralmechanicsmodel.tex
+++ b/doc/manual/manual-structuralmechanicsmodel.tex
@@ -1,251 +1,252 @@
\chapter{Structural Mechanics Model}
Static structural mechanics problems can be handled using the
-\code{StructuralMechanicsModel}. So far, \akantu\ provides 2D and 3D
-Bernoulli beam elements \cite{frey2009}. Just as for the
-\code{SolidMechanicsModel}, this model is created for a given
-\code{Mesh}. The model will create its own \code{FEEngine} object to
+class \code{StructuralMechanicsModel}. So far, \akantu provides 2D and 3D
+Bernoulli beam elements \cite{frey2009}. This model is instantiated for a given
+\code{Mesh}, as for the \code{SolidMechanicsModel}. The model will create its own \code{FEEngine} object to
compute the interpolation, gradient, integration and assembly
operations. The \code{StructuralMechanicsModel} constructor is called
in the following way:
\begin{cpp}
StructuralMechanicsModel model(mesh, spatial_dimension);
\end{cpp}
where \code{mesh} is a \code{Mesh} object defining the structure for
which the equations of statics are to be solved, and
\code{spatial\_dimension} is the dimensionality of the problem. If
\code{spatial\_dimension} is omitted, the problem is assumed to have
the same dimensionality as the one specified by the mesh.
\note[\ 1]{Dynamic computations are not supported to date.}
\note[\ 2]{Structural meshes are created and loaded as described in
- Section~\ref{sect:common:mesh} with \code{MeshIOMSHStruct} instead of \code{MeshIOMSH}.}
+ Section~\ref{sect:common:mesh} with \code{MeshIOMSHStruct} instead of \code{MeshIOMSH}:}
+\begin{cpp}
+ akantu::MeshIOMSHStruct mesh_io;
+ mesh_io.read("structural_mesh.msh", beams);
+\end{cpp}
\vspace{1cm}
This model contains at least the following \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}. The \textbf{displacement} is 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\_rotation] contains the generalized displacements
(\textit{i.e.} displacements and rotations) 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[force\_moment] contains the generalized external forces (forces
and moments) applied to the nodes ($\vec{f_{\st{ext}}}$ in the
following).
\item[residual] contains the difference between the generalized external and internal
forces and moments. On the 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 the free degrees of freedom.
\end{description}
An example to help understand how to use this model will be presented in the
next section.
\section{Model Setup}
\label{sec:structMechMod:setup}
\subsection{Initialization}
The easiest way to initialize the structural mechanics model is:
-
\begin{cpp}
model.initFull();
\end{cpp}
The method \code{initFull} computes the shape functions, initializes
the internal vectors mentioned above and allocates the memory for the
-stiffness matrix.
+stiffness matrix, unlike the solid mechanics model, its default argument is \code{\_static}.
Material properties are defined using the \code{StructuralMaterial}
structure described in
Table~\ref{tab:structMechMod:strucMaterial}. Such a definition could,
for instance, look like
\begin{cpp}
StructuralMaterial mat1;
mat.E=3e10;
mat.I=0.0025;
mat.A=0.01;
\end{cpp}
\begin{table}[htb] \centering
\begin{tabular}{cl}
\toprule
Field & Description \\
\midrule
\code{E} & Young's modulus \\
\code{A} & Cross section area \\
\code{I} & Second cross sectional moment of inertia (for 2D elements)\\
\code{Iy} & \code{I} around beam $y$--axis (for 3D elements)\\
\code{Iz} & \code{I} around beam $z$--axis (for 3D elements)\\
\code{GJ} & Polar moment of inertia of beam cross section (for 3D elements)\\
\bottomrule
\end{tabular}
- \caption{Material properties for structural elements as defined by
-the structure \code{StructuralMaterial}.}
+ \caption{Material properties for structural elements defined in
+the class \code{StructuralMaterial}.}
\label{tab:structMechMod:strucMaterial}
\end{table}
Materials can be added to the model's \code{element\_material} vector using
\begin{cpp}
model.addMaterial(mat1);
\end{cpp}
They are successively numbered and then assigned to specific elements.
\begin{cpp}
for (UInt i = 0; i < nb_element_mat_1; ++i) {
model.getElementMaterial(_bernoulli_beam_2)(i,0) = 1;
}
\end{cpp}
\subsection{Setting Boundary Conditions}\label{sect:structMechMod:boundary}
-As explained before, the Dirichlet boundary conditions are applied
-through the array \textbf{blocked\_dofs}. Two options exist to define
-Neumann conditions. If a nodal force is applied, it has to be
-directly set in the array \textbf{force\_momentum}. For loads
-distributed along the beam length, the method
-\code{computeForcesFromFunction} integrates them into nodal forces.
-The method takes as input a function describing the distribution of
-loads along the beam and a \code{BoundaryFunctionType} specifing if
-the function is expressed in the local coordinates
-(\code{\_bft\_traction\_local}) or in the global system of coordinates
-(\code{\_bft\_traction}).
+
+As explained before, the Dirichlet boundary conditions are applied through the
+array \textbf{blocked\_dofs}. Two options exist to define Neumann conditions.
+If a nodal force is applied, it has to be directly set in the array
+\textbf{force\_momentum}. For loads distributed along the beam length, the
+method \code{computeForcesFromFunction} integrates them into nodal forces. The
+method takes as input a function describing the distribution of loads along the
+beam and a functor \code{BoundaryFunctionType} specifing if the function is
+expressed in the local coordinates (\code{\_bft\_traction\_local}) or in the
+global system of coordinates (\code{\_bft\_traction}).
\begin{cpp}
static void lin_load(double * position, double * load,
Real * normal, UInt surface_id){
memset(load,0,sizeof(Real)*3);
load[1] = position[0]*position[0]-250;
}
int main(int argc, char *argv[]){
...
model.computeForcesFromFunction<_bernoulli_beam_2>(lin_load,
_bft_traction_local);
...}
\end{cpp}
\section{Static Analysis\label{sect:structMechMod:static}}
The \code{StructuralMechanicsModel} class can perform static analyses
of structures. In this case, the equation to solve is the same as for
the \code{SolidMechanicsModel} used for static analyses
\begin{equation}\label{eqn:structMechMod:static}
\mat{K} \vec{u} = \vec{f_{\st{ext}}}~,
\end{equation}
where $\mat{K}$ is the global stiffness matrix, $\vec{u}$ the
generalized displacement vector and $\vec{f_{\st{ext}}}$ the vector of
generalized external forces applied to the system.
To solve such a problem, the static solver of the
\code{StructuralMechanicsModel}\index{StructuralMechanicsModel} object
is used. First a model has to be created and initialized.
\begin{cpp}
StructuralMechanicsModel model(mesh);
model.initFull();
\end{cpp}
\begin{itemize}
\item \code{model.initFull} initializes all internal vectors to zero.
\end{itemize}
Once the model is created and initialized, the boundary conditions can
be set as explained in Section~\ref{sect:structMechMod:boundary}.
Boundary conditions will prescribe the external forces or moments for
the free degrees of freedom $\vec{f_{\st{ext}}}$ and displacements or
rotations for the others. To completely define the system represented
by equation (\ref{eqn:structMechMod:static}), the global stiffness
matrix $\mat{K}$ must be assembled.
\index{StructuralMechanicsModel!assembleStiffnessMatrix}
\begin{cpp}
model.assembleStiffnessMatrix();
\end{cpp}
The computation of the static equilibrium is performed using the same
Newton-Raphson algorithm as described in
Section~\ref{sect:smm:static}.
\note{To date,
\code{StructuralMechanicsModel} handles only constitutively and
geometrically linear problems, the algorithm is therefore guaranteed
to converge in two iterations.}
\begin{cpp}
model.updateResidual();
model.solve();
\end{cpp}
\index{StructuralMechanicsModel!updateResidual}
\index{StructuralMechanicsModel!solve}
\begin{itemize}
\item \code{model.updateResidual} assembles the internal forces and
removes them from the external forces.
\item \code{model.solve} solves the Equation (\ref{eqn:structMechMod:static}).
The \textbf{increment} vector of the model will contain the new
increment of displacements, and the \textbf{displacement\_rotation}
vector is also updated to the new displacements.
\end{itemize}
%At the end of the analysis, the final solution is stored in the
%\textbf{displacement} vector. A full example of how to solve a
%structural mechanics problem is presented in the code
%\shellcode{\examplesdir/structural\_mechanics/test\_structural\_mechanics\_model\_bernoulli\_beam\_2\_exemple\_1\_1.cc}.
%This example is composed of a 2D beam, clamped at the left end and
%supported by two rollers as shown in Figure
%\ref{fig:structMechMod:exem1_1}. The problem is defined by the
%applied load $q=\SI{6}{\kilo\newton\per\metre}$, moment $\bar{M} =
%\SI{3.6}{\kilo\newton\metre}$, moments of inertia $I_1 =
%\SI{250\,000}{\power{\centi\metre}{4}}$ and $I_2 =
%\SI{128\,000}{\power{\centi\metre}{4}}$ and lengths $L_1 =
%\SI{10}{\metre}$ and $L_2 = \SI{8}{\metre}$. The resulting
%rotations at node two and three are $ \varphi_2 = 0.001\,167\
%\mbox{and}\ \varphi_3 = -0.000\,771.$
At the end of the analysis, the final solution is stored in the
\textbf{displacement\_rotation} vector. A full example of how to
solve a structural mechanics problem is presented in the code
\shellcode{\examplesdir/structural\_mechanics/bernoulli\_beam\_2\_example.cc}.
This example is composed of a 2D beam, clamped at the left end and
supported by two rollers as shown in Figure
\ref{fig:structMechMod:exem1_1}. The problem is defined by the
applied load $q=\SI{6}{\kilo\newton\per\metre}$, moment $\bar{M} =
\SI{3.6}{\kilo\newton\metre}$, moments of inertia $I_1 =
\SI{250\,000}{\centi\metre\tothe{4}}$ and $I_2 =
\SI{128\,000}{\centi\metre\tothe{4}}$ and lengths $L_1 =
\SI{10}{\metre}$ and $L_2 = \SI{8}{\metre}$. The resulting
rotations at node two and three are $ \varphi_2 = 0.001\,167\
\mbox{and}\ \varphi_3 = -0.000\,771.$
\begin{figure}[htb]
\centering
\includegraphics[scale=1.1]{figures/beam_example}
\caption{2D beam example}
\label{fig:structMechMod:exem1_1}
\end{figure}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "manual"
%%% End:
diff --git a/doc/manual/manual.sty b/doc/manual/manual.sty
index 6855a85ab..3e4be3cfd 100644
--- a/doc/manual/manual.sty
+++ b/doc/manual/manual.sty
@@ -1,312 +1,372 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
%% 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 a new list style for C++
-\lstdefinestyle{C++}{
- language=C++, % the language of the code
+% 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,
- keywordstyle=\color{DarkOrchid}\bfseries,
% 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,
- mathescape=true,
escapechar=\%,
- morekeywords={Real, UInt, Int},
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 new list style for the shell
\lstdefinestyle{shell}{
language=bash, % the language of the code
- basicstyle=\scriptsize\ttfamily, % Without beramono, we'd get cmtt, the teletype font.
- 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,
- xleftmargin=1cm,
- xrightmargin=1cm,
- escapechar=\%,
+ style=lstDefaultStyle,
morekeywords={mkdir, make, ccmake, cmake},
- columns=flexible,
- keepspaces=true,
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{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
diff --git a/doc/manual/manual.tex b/doc/manual/manual.tex
index f9cd426e9..956881ab4 100644
--- a/doc/manual/manual.tex
+++ b/doc/manual/manual.tex
@@ -1,47 +1,52 @@
\documentclass[openright,a4paper,11pt,fleqn]{manual}
\usepackage{manual}
\usepackage{manual-macros}
-\newcommand{\version}{}
+
+\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}}{}
% 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/doc/manual/version-definition.tex.in b/doc/manual/version-definition.tex.in
new file mode 100644
index 000000000..48c821d8b
--- /dev/null
+++ b/doc/manual/version-definition.tex.in
@@ -0,0 +1 @@
+\newcommand{\version}{@AKANTU_VERSION@}
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 2c5184d22..b6a1e7ac7 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,51 +1,53 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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(static "Example on how to run a static simulation" PACKAGE implicit)
add_example(parallel_2d "Example of how to write a parallel code with Akantu" PACKAGE parallel)
add_example(cohesive_element "Cohesive element examples" PACKAGE cohesive_element)
add_example(contact "Examples on how to use contact within Akantu" PACKAGE contact)
add_example(optimization "Optimization examples" PACKAGE optimization)
add_example(structural_mechanics "Structural mechanics model examples" PACKAGE structural_mechanics)
add_example(heat_transfer "Example on how to run heat transfer simulation" PACKAGE heat_transfer)
-#===============================================================================
\ No newline at end of file
+add_example(embedded "Example on how to run embedded model simulation" PACKAGE embedded)
+#===============================================================================
diff --git a/examples/boundary_conditions/CMakeLists.txt b/examples/boundary_conditions/CMakeLists.txt
index aa209f7a6..2914073ce 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: Fri Jun 21 2013
+# @date last modification: Fri Jun 21 2013
#
-# @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)
+# 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(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")
+add_example(user_defined_BC "Example of user defined boundary condition" PACKAGE implicit)
\ No newline at end of file
diff --git a/examples/boundary_conditions/CMakeLists.txt b/examples/boundary_conditions/predefined_BC/CMakeLists.txt
similarity index 100%
copy from examples/boundary_conditions/CMakeLists.txt
copy to examples/boundary_conditions/predefined_BC/CMakeLists.txt
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/plate.cc b/examples/boundary_conditions/predefined_BC/plate.cc
similarity index 100%
rename from examples/boundary_conditions/plate.cc
rename to examples/boundary_conditions/predefined_BC/plate.cc
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..3bb958d10
--- /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: Fri May 11 2012
+# @date last modification: Thu Nov 01 2012
+#
+# @brief boundary condition example configuration
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+add_mesh(mesh fine_mesh.geo 2 1)
+
+register_example(complex_boundary_condition complex_boundary_condition.cc)
+add_dependencies(complex_boundary_condition mesh)
+
+file(COPY material.dat DESTINATION .)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
\ No newline at end of file
diff --git a/examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc b/examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc
new file mode 100644
index 000000000..f31c4e3c3
--- /dev/null
+++ b/examples/boundary_conditions/user_defined_BC/complex_boundary_condition.cc
@@ -0,0 +1,97 @@
+/**
+ * @file complex_boundary_condition.cc
+ *
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date creation: Wed Dec 16 2015
+ *
+ * @brief user-defined boundary condition example
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "solid_mechanics_model.hh"
+/* -------------------------------------------------------------------------- */
+#include <iostream>
+#include <math.h>
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+class SineBoundary : public BC::Dirichlet::DirichletFunctor {
+public:
+ SineBoundary(Real amp, Real phase, BC::Axis ax = _x) : DirichletFunctor(ax), amplitude(amp), phase(phase) {}
+
+public:
+ inline void operator()(UInt node,
+ Vector<bool> & flags,
+ Vector<Real> & primal,
+ const Vector<Real> & coord) const {
+ DIRICHLET_SANITY_CHECK;
+ flags(axis) = true;
+ primal(axis) = -amplitude * sin(phase * coord(1));
+ }
+
+protected:
+ Real amplitude;
+ Real phase;
+};
+
+int main(int argc, char *argv[]) {
+ initialize("material.dat", argc, argv);
+
+ UInt spatial_dimension = 2;
+
+ Mesh mesh(spatial_dimension);
+ mesh.read("fine_mesh.msh");
+
+ SolidMechanicsModel model(mesh);
+
+ /// model initialization
+ model.initFull(SolidMechanicsModelOptions(_static));
+
+ std::cout << model.getMaterial(0) << std::endl;
+ model.assembleMassLumped();
+
+ /// boundary conditions
+ mesh.createGroupsFromMeshData<std::string>("physical_names");
+ Vector<Real> traction(2, 0.2);
+ model.applyBC(SineBoundary(.2, 10., _x), "Fixed_x");
+ model.applyBC(BC::Dirichlet::FixedValue(0., _y), "Fixed_y");
+ model.applyBC(BC::Neumann::FromTraction(traction), "Traction");
+
+
+ model.setBaseName("plate");
+ model.addDumpFieldVector("displacement");
+ model.addDumpField("blocked_dofs");
+ model.dump();
+
+ /// solve the system
+ model.assembleStiffnessMatrix();
+ Real error = 0;
+ Real converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-10, error, 2, false);
+ AKANTU_DEBUG_ASSERT(converged, "Did not converge");
+
+ model.dump();
+
+ finalize();
+ return EXIT_SUCCESS;
+}
diff --git a/examples/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/cohesive_element/CMakeLists.txt b/examples/cohesive_element/CMakeLists.txt
index 019d7d074..feff3d67f 100644
--- a/examples/cohesive_element/CMakeLists.txt
+++ b/examples/cohesive_element/CMakeLists.txt
@@ -1,33 +1,34 @@
#===============================================================================
# @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 last modification: Tue Jan 07 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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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 )
\ No newline at end of file
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..82e96a5f2
--- /dev/null
+++ b/examples/cohesive_element/cohesive_extrinsic_implicit/CMakeLists.txt
@@ -0,0 +1,42 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Mauro Corrado <mauro.corrado@epfl.ch>
+#
+# @date creation: Tue Jan 07 2016
+#
+# @brief Example for extrinsic cohesive elements in implicit
+#
+# @section LICENSE
+#
+# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+add_mesh(cohesive_extrinsic_implicit_mesh dcb_2d.geo 2 2)
+
+register_example(cohesive_extrinsic_implicit
+ cohesive_extrinsic_implicit.cc)
+
+add_dependencies(cohesive_extrinsic_implicit
+ cohesive_extrinsic_implicit_mesh)
+
+ #===============================================================================
+file(COPY material.dat DESTINATION .)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
diff --git a/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc b/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc
new file mode 100644
index 000000000..7b7eae030
--- /dev/null
+++ b/examples/cohesive_element/cohesive_extrinsic_implicit/cohesive_extrinsic_implicit.cc
@@ -0,0 +1,171 @@
+/**
+ * @file cohesive_extrinsic_implicit.cc
+ *
+ * @author Mauro Corrado
+ *
+ * @date creation: Tue Jan 07 2016
+ *
+ * @brief Example for extrinsic cohesive elements in implicit
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <limits>
+#include <fstream>
+#include <iostream>
+
+/* -------------------------------------------------------------------------- */
+#include "solid_mechanics_model_cohesive.hh"
+#include "material_cohesive.hh"
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+ initialize("material.dat", argc, argv);
+
+ debug::setDebugLevel(dblError);
+
+ const UInt spatial_dimension = 2;
+ const UInt max_steps = 20;
+ const Real final_opening = 1e-4;
+
+ Mesh mesh(spatial_dimension);
+ mesh.read("dcb_2d.msh");
+
+ SolidMechanicsModelCohesive model(mesh);
+
+ /// model initialization
+ model.initFull(SolidMechanicsModelCohesiveOptions(_static, true));
+
+ // CohesiveElementInserter inserter(mesh);
+ model.limitInsertion(_y, -0.000001, 0.000001);
+ model.updateAutomaticInsertion();
+
+ Real eps = 1e-11;
+ Array<bool> & boundary = model.getBlockedDOFs();
+ Array<Real> & position = mesh.getNodes();
+ Array<Real> & displacement = model.getDisplacement();
+
+ /// boundary conditions
+ mesh.computeBoundingBox();
+ const Vector<Real> & lower = mesh.getLowerBounds();
+ const Vector<Real> & upper = mesh.getUpperBounds();
+ const Real left = lower[0];
+ const Real right = upper[0];
+
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (std::abs(position(n,0) - left) < eps){
+ boundary(n,1) = true;
+ boundary(n,0) = true;
+ }
+ if (std::abs(position(n,0) - right) < eps && position(n,1) < 0.0)
+ boundary(n,1) = true;
+ if (std::abs(position(n,0) - right) < eps && position(n,1) > 0.0)
+ boundary(n,1) = true;
+ }
+
+ model.setBaseName("extr_impl");
+ model.addDumpFieldVector("displacement");
+ model.addDumpField("force");
+ model.addDumpField("residual");
+ model.addDumpField("stress");
+ model.addDumpField("partitions");
+ model.dump();
+
+ // Dumping cohesive elements
+ model.setBaseNameToDumper("cohesive elements", "cohe_elem_extr_impl");
+ model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
+ model.addDumpFieldToDumper("cohesive elements", "damage");
+ model.dump("cohesive elements");
+
+ // model.updateResidual();
+
+ Real increment = final_opening/max_steps;
+ Real tolerance = 1e-13;
+ Real error;
+ bool load_reduction = false;
+ Real tol_increase_factor = 1.0e8;
+
+ /// Main loop
+ for (UInt nstep = 0; nstep < max_steps; ++nstep){
+ std::cout << "step no. " << nstep << std::endl;
+
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (std::abs(position(n,0) - right) < eps && position(n,1) > 0.0)
+ displacement(n,1) += increment;
+
+ if (std::abs(position(n,0) - right) < eps && position(n,1) < 0.0)
+ displacement(n,1) -= increment;
+ }
+
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+
+ // If convergence has not been reached, the load is reduced and
+ // the incremental step is solved again.
+ while (!load_reduction && error > tolerance) {
+ load_reduction = true;
+
+ std::cout << "LOAD STEP REDUCTION" << std::endl;
+ increment = increment / 2.0;
+
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (std::abs(position(n,0) - right) < eps && position(n,1) > 0.0)
+ displacement(n,1) -= increment;
+
+ if (std::abs(position(n,0) - right) < eps && position(n,1) < 0.0)
+ displacement(n,1) += increment;
+ }
+
+ UInt nb_cohesive_elements = mesh.getNbElement(spatial_dimension, _not_ghost, _ek_cohesive);
+
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(tolerance, error, 25, load_reduction, tol_increase_factor);
+
+ UInt new_nb_cohesive_elements = mesh.getNbElement(spatial_dimension, _not_ghost, _ek_cohesive);
+
+ UInt nb_cohe[2];
+ nb_cohe[0] = nb_cohesive_elements;
+ nb_cohe[1] = new_nb_cohesive_elements;
+
+ // Every time a new cohesive element is introduced, the variable
+ // load_reduction is set to false, so that it is possible to
+ // further iterate in the loop of load reduction. If no new
+ // cohesive elements are introduced, usually there is no gain in
+ // further reducing the load, even if convergence is not reached
+ if(nb_cohe[0] == nb_cohe[1])
+ load_reduction = true;
+ else
+ load_reduction = false;
+ }
+
+ model.dump();
+ model.dump("cohesive elements");
+
+ UInt nb_cohe_elems[1];
+ nb_cohe_elems[0] = mesh.getNbElement(spatial_dimension, _not_ghost, _ek_cohesive);
+ std::cout << "No. of cohesive elements: " << nb_cohe_elems[0] << std::endl;
+
+ }
+
+ finalize();
+
+ return EXIT_SUCCESS;
+}
diff --git a/examples/cohesive_element/cohesive_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/embedded/CMakeLists.txt b/examples/embedded/CMakeLists.txt
new file mode 100644
index 000000000..db215aa62
--- /dev/null
+++ b/examples/embedded/CMakeLists.txt
@@ -0,0 +1,42 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Lucas Frérot <lucas.frerot@epfl.ch>
+#
+# @date creation: Wed Jul 22 2015
+# @date last modification: Wed Jul 22 2015
+#
+# @brief configuration for embedded example
+#
+# @section LICENSE
+#
+# Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+register_example(embedded embedded.cc USE CGAL)
+
+add_mesh(concrete_mesh concrete.geo 2 1)
+add_mesh(reinforcement_mesh reinforcement.geo 1 1)
+add_dependencies(embedded concrete_mesh)
+add_dependencies(embedded reinforcement_mesh)
+
+#===============================================================================
+file(COPY material.dat DESTINATION .)
+
diff --git a/examples/embedded/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..3bf33542b
--- /dev/null
+++ b/examples/embedded/embedded.cc
@@ -0,0 +1,108 @@
+/**
+ * @file embedded.cc
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Wed Jul 22 2015
+ * @date last modification: Wed Jul 22 2015
+ *
+ * @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/explicit_dynamic.cc b/examples/explicit/explicit_dynamic.cc
index 314317be3..b3865a8bb 100644
--- a/examples/explicit/explicit_dynamic.cc
+++ b/examples/explicit/explicit_dynamic.cc
@@ -1,109 +1,109 @@
/**
* @file explicit_dynamic.cc
*
* @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
*
* @date creation: Mon Apr 16 2012
* @date last modification: Tue Jun 10 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include <iostream>
using namespace akantu;
int main(int argc, char *argv[]) {
initialize("material.dat", argc, argv);
const UInt spatial_dimension = 3;
const Real pulse_width = 2.;
const Real A = 0.01;
Real time_step;
Real time_factor = 0.8;
UInt max_steps = 1000;
Mesh mesh(spatial_dimension);
mesh.computeBoundingBox();
mesh.read("bar.msh");
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull();
time_step = model.getStableTimeStep();
std::cout << "Time Step = " << time_step * time_factor << "s ("<< time_step << "s)" << std::endl;
model.setTimeStep(time_step * time_factor);
/// boundary and initial conditions
Array<Real> & displacement = model.getDisplacement();
const Array<Real> & nodes = mesh.getNodes();
for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
Real x = nodes(n);
// Sinus * Gaussian
Real L = pulse_width;
Real k = 0.1 * 2 * M_PI * 3 / L;
displacement(n) = A * sin(k * x) * exp(-(k * x) * (k * x) / (L * L));
}
std::ofstream energy;
energy.open("energy.csv");
energy << "id,rtime,epot,ekin,tot" << std::endl;
model.setBaseName("explicit_dynamic");
model.addDumpField("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("stress" );
model.dump();
for(UInt s = 1; s <= max_steps; ++s) {
model.solveStep();
- Real epot = model.getPotentialEnergy();
- Real ekin = model.getKineticEnergy();
+ Real epot = model.getEnergy("potential");
+ Real ekin = model.getEnergy("kinetic");
energy << s << "," << s*time_step << ","
<< epot << ","
<< ekin << ","
<< epot + ekin << ","
<< std::endl;
if(s % 10 == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
model.dump();
}
energy.close();
finalize();
return EXIT_SUCCESS;
}
diff --git a/examples/io/CMakeLists.txt b/examples/io/CMakeLists.txt
new file mode 100644
index 000000000..fdbbc040b
--- /dev/null
+++ b/examples/io/CMakeLists.txt
@@ -0,0 +1,30 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Fabian Barras <fabian.barras@epfl.ch>
+#
+# @date creation: Fri Aug 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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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
new file mode 100644
index 000000000..35579da1c
--- /dev/null
+++ b/examples/io/dumper/CMakeLists.txt
@@ -0,0 +1,51 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Fabian Barras <fabian.barras@epfl.ch>
+#
+# @date creation: Fri Aug 14 2015
+#
+# @brief CMakeLists for DumperIOHelper examples
+#
+# @section LICENSE
+#
+# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+add_mesh(swiss_train swiss_train.geo 2 1)
+
+add_library(locomotive_tools
+ locomotive_tools.cc
+ locomotive_tools.hh
+ )
+
+register_example(dumper_low_level
+ dumper_low_level.cc
+ USE IOHelper
+ DEPENDS swiss_train locomotive_tools
+ DIRECTORIES_TO_CREATE paraview
+ )
+
+register_example(dumpable_interface
+ dumpable_interface.cc
+ USE IOHelper
+ DEPENDS swiss_train locomotive_tools
+ DIRECTORIES_TO_CREATE paraview
+ )
+
diff --git a/examples/io/dumper/dumpable_interface.cc b/examples/io/dumper/dumpable_interface.cc
new file mode 100644
index 000000000..456bdd55d
--- /dev/null
+++ b/examples/io/dumper/dumpable_interface.cc
@@ -0,0 +1,185 @@
+/**
+ * @file example_dumpable_interface.cc
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @date Thu Jul 2 14:34:41 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "mesh.hh"
+#include "element_group.hh"
+#include "dumper_paraview.hh"
+#include "dumpable_inline_impl.hh"
+#include "group_manager_inline_impl.cc"
+/* -------------------------------------------------------------------------- */
+#include "locomotive_tools.hh"
+/* -------------------------------------------------------------------------- */
+using namespace akantu;
+
+int main(int argc, char * argv[]) {
+
+ /*
+ In this example, we present dumper::Dumpable which is an interface
+ for other classes who want to dump themselves.
+ Several classes of Akantu inheritate from Dumpable (Model, Mesh, ...).
+ In this example we reproduce the same tasks as example_dumper_low_level.cc
+ using this time Dumpable interface inherted by Mesh, NodeGroup and
+ ElementGroup.
+ It is then advised to read first example_dumper_low_level.cc.
+ */
+
+ initialize(argc, argv);
+
+ // To start let us load the swiss train mesh and its mesh data information.
+ UInt spatial_dimension = 2;
+ Mesh mesh(spatial_dimension);
+ mesh.read("swiss_train.msh");
+ mesh.createGroupsFromMeshData<std::string>("physical_names");
+
+ /*
+ swiss_train.msh has the following physical groups that can be viewed with
+ GMSH:
+ "$MeshFormat
+ 2.2 0 8
+ $EndMeshFormat
+ $PhysicalNames
+ 6
+ 2 1 "red"
+ 2 2 "white"
+ 2 3 "lwheel_1"
+ 2 4 "lwheel_2"
+ 2 5 "rwheel_2"
+ 2 6 "rwheel_1"
+ $EndPhysicalNames
+ ..."
+ */
+
+ // Grouping nodes and elements belonging to train wheels (=four mesh data).
+ ElementGroup & wheels_elements =
+ mesh.createElementGroup("wheels", spatial_dimension);
+ wheels_elements.append(mesh.getElementGroup("lwheel_1"));
+ wheels_elements.append(mesh.getElementGroup("lwheel_2"));
+ wheels_elements.append(mesh.getElementGroup("rwheel_1"));
+ wheels_elements.append(mesh.getElementGroup("rwheel_2"));
+
+ const Array<UInt> & lnode_1 = (mesh.getElementGroup("lwheel_1")).getNodes();
+ const Array<UInt> & lnode_2 = (mesh.getElementGroup("lwheel_2")).getNodes();
+ const Array<UInt> & rnode_1 = (mesh.getElementGroup("rwheel_1")).getNodes();
+ const Array<UInt> & rnode_2 = (mesh.getElementGroup("rwheel_2")).getNodes();
+
+ Array<Real> & node = mesh.getNodes();
+ UInt nb_nodes = mesh.getNbNodes();
+
+ // This time a 2D Array is created and a padding size of 3 is passed to
+ // NodalField in order to warp train deformation on Paraview.
+ Array<Real> displacement(nb_nodes, spatial_dimension);
+
+ // Create an ElementTypeMapArray for the colour
+ ElementTypeMapArray<UInt> colour("colour");
+ mesh.initElementTypeMapArray(colour, 1, spatial_dimension, false, _ek_regular,
+ true);
+
+ /* ------------------------------------------------------------------------ */
+ /* Creating dumpers */
+ /* ------------------------------------------------------------------------ */
+
+ // Create dumper for the complete mesh and register it as default dumper.
+ DumperParaview dumper("train", "./paraview/dumpable", false);
+ mesh.registerExternalDumper(dumper, "train", true);
+ mesh.addDumpMesh(mesh);
+
+ // The dumper for the filtered mesh can be directly taken from the
+ // ElementGroup and then registered as "wheels_elements" dumper.
+ DumperIOHelper & wheels =
+ mesh.getGroupDumper("paraview_wheels", "wheels");
+
+ mesh.registerExternalDumper(wheels, "wheels");
+ mesh.setDirectoryToDumper("wheels", "./paraview/dumpable");
+
+ // Arrays and ElementTypeMapArrays can be added as external fields directly
+ mesh.addDumpFieldExternal("displacement", displacement);
+
+ ElementTypeMapArrayFilter<UInt> filtered_colour(
+ colour, wheels_elements.getElements());
+
+ dumper::Field * colour_field_wheel =
+ new dumper::ElementalField<UInt, Vector, true>(filtered_colour);
+ mesh.addDumpFieldExternal("color", colour_field_wheel);
+
+ mesh.addDumpFieldExternalToDumper("wheels", "displacement",
+ displacement);
+ mesh.addDumpFieldExternalToDumper("wheels", "colour", colour);
+
+ // For some specific cases the Fields should be created, as when you want to
+ // pad an array
+ dumper::Field * displacement_vector_field =
+ mesh.createNodalField(&displacement, "all", 3);
+ mesh.addDumpFieldExternal("displacement_as_paraview_vector",
+ displacement_vector_field);
+ mesh.addDumpFieldExternalToDumper("wheels",
+ "displacement_as_paraview_vector",
+ displacement_vector_field);
+
+ /* ------------------------------------------------------------------------ */
+ /* ------------------------------------------------------------------------ */
+
+ // Fill the ElementTypeMapArray colour.
+ fillColour(mesh, colour);
+
+ /// Apply displacement and wheels rotation.
+ Real tot_displacement = 50.;
+ Real radius = 1.;
+ UInt nb_steps = 100;
+ Real theta = tot_displacement / radius;
+
+ Vector<Real> l_center(spatial_dimension);
+ Vector<Real> r_center(spatial_dimension);
+
+ for (UInt i = 0; i < spatial_dimension; ++i) {
+ l_center(i) = node(14, i);
+ r_center(i) = node(2, i);
+ }
+
+ for (UInt i = 0; i < nb_steps; ++i) {
+ displacement.clear();
+
+ Real step_ratio = Real(i) / Real(nb_steps);
+ Real angle = step_ratio * theta;
+
+ applyRotation(l_center, angle, node, displacement, lnode_1);
+ applyRotation(l_center, angle, node, displacement, lnode_2);
+ applyRotation(r_center, angle, node, displacement, rnode_1);
+ applyRotation(r_center, angle, node, displacement, rnode_2);
+
+ for (UInt j = 0; j < nb_nodes; ++j) {
+ displacement(j, _x) += step_ratio * tot_displacement;
+ }
+ /// Dump call is finally made through Dumpable interface.
+ mesh.dump();
+ mesh.dump("wheels");
+ }
+
+ finalize();
+
+ return 0;
+}
diff --git a/examples/io/dumper/dumper_low_level.cc b/examples/io/dumper/dumper_low_level.cc
new file mode 100644
index 000000000..d7a25c6e5
--- /dev/null
+++ b/examples/io/dumper/dumper_low_level.cc
@@ -0,0 +1,192 @@
+/**
+ * @file dumper_low_level.cc
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @date Thu Jul 2 14:34:41 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100644
index 000000000..19971cf22
--- /dev/null
+++ b/examples/io/dumper/locomotive_tools.cc
@@ -0,0 +1,87 @@
+/**
+ * @file locomotive_tools.cc
+ *
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ *
+ * @date Mon Aug 17 14:23:22 2015
+ *
+ * @brief Common functions for the dumper examples
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "mesh.hh"
+#include "aka_types.hh"
+
+using namespace akantu;
+
+/* -------------------------------------------------------------------------- */
+void applyRotation(const Vector<Real> & center, Real angle,
+ const Array<Real> & nodes, Array<Real> & displacement,
+ const Array<UInt> & node_group) {
+ Array<Real>::const_vector_iterator nodes_it =
+ nodes.begin(nodes.getNbComponent());
+ Array<Real>::vector_iterator disp_it = displacement.begin(center.size());
+ Array<UInt>::const_scalar_iterator node_num_it = node_group.begin();
+ Array<UInt>::const_scalar_iterator node_num_end = node_group.end();
+
+ Vector<Real> pos_rel(center.size());
+
+ for (; node_num_it != node_num_end; ++node_num_it) {
+ const Vector<Real> pos = nodes_it[*node_num_it];
+ for (UInt i = 0; i < pos.size(); ++i)
+ pos_rel(i) = pos(i);
+
+ Vector<Real> dis = disp_it[*node_num_it];
+
+ pos_rel -= center;
+ Real radius = pos_rel.norm();
+
+ if (std::abs(radius) < Math::getTolerance()) continue;
+
+ Real phi_i = std::acos(pos_rel(_x) / radius);
+ if (pos_rel(_y) < 0) phi_i *= -1;
+
+ dis(_x) = std::cos(phi_i - angle) * radius - pos_rel(_x);
+ dis(_y) = std::sin(phi_i - angle) * radius - pos_rel(_y);
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void fillColour(const Mesh & mesh,
+ ElementTypeMapArray<UInt> & colour) {
+ const ElementTypeMapArray<std::string> & phys_data =
+ mesh.getData<std::string>("physical_names");
+ const Array<std::string> & txt_colour = phys_data(_triangle_3);
+ Array<UInt> & id_colour = colour(_triangle_3);
+
+ for (UInt i = 0; i < txt_colour.getSize(); ++i) {
+ std::string phy_name = txt_colour(i);
+
+ if (phy_name == "red")
+ id_colour(i) = 3;
+ else if (phy_name == "white" || phy_name == "lwheel_1" ||
+ phy_name == "rwheel_1")
+ id_colour(i) = 2;
+ else
+ id_colour(i) = 1;
+ }
+}
diff --git a/examples/io/dumper/locomotive_tools.hh b/examples/io/dumper/locomotive_tools.hh
new file mode 100644
index 000000000..38cb70a80
--- /dev/null
+++ b/examples/io/dumper/locomotive_tools.hh
@@ -0,0 +1,38 @@
+/**
+ * @file locomotive_tools.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date Mon Aug 17 14:25:25 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * 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/dumper/swiss_train.geo b/examples/io/dumper/swiss_train.geo
new file mode 100644
index 000000000..7564e4010
--- /dev/null
+++ b/examples/io/dumper/swiss_train.geo
@@ -0,0 +1,94 @@
+lc = 0.1;
+Point(1) = { 0, 0, 0, lc};
+Point(2) = { 3, 0, 0, lc};
+Point(3) = { 4, 0, 0, lc};
+Point(4) = { 4, 1, 0, lc};
+Point(5) = { 4, 6, 0, lc};
+Point(6) = { 0, 6, 0, lc};
+Point(7) = { 3.05, 0, 0, lc};
+Point(8) = { 4.95, 0, 0, lc};
+Point(9) = { 4, 0.95, 0, lc};
+Point(10) = { 4, -0.95, 0, lc};
+Point(11) = {-2, 6, 0, lc};
+Point(12) = {-6, 6, 0, lc};
+Point(13) = {-6, 1, 0, lc};
+Point(14) = {-6, 0.95, 0, lc};
+Point(15) = {-6, 0, 0, lc};
+Point(16) = {-6.95, 0, 0, lc};
+Point(17) = {-6, -0.95, 0, lc};
+Point(18) = {-5.05, 0, 0, lc};
+Point(19) = {-5, 0, 0, lc};
+Point(20) = {-2, 0, 0, lc};
+Point(21) = { 0, 2, 0, lc};
+Point(22) = { 2, 2, 0, lc};
+Point(23) = { 2, 4, 0, lc};
+Point(24) = { 0, 4, 0, lc};
+Point(25) = {-2, 2, 0, lc};
+Point(26) = {-4, 2, 0, lc};
+Point(27) = {-4, 4, 0, lc};
+Point(28) = {-2, 4, 0, lc};
+Line(1) = {19, 20};
+Line(2) = {20, 25};
+Line(3) = {25, 26};
+Line(4) = {26, 27};
+Line(5) = {27, 28};
+Line(6) = {28, 11};
+Line(7) = {11, 12};
+Line(8) = {12, 13};
+Circle(9) = {13, 15, 19};
+Circle(10) = {18, 15, 14};
+Circle(11) = {14, 15, 16};
+Circle(12) = {16, 15, 17};
+Circle(13) = {17, 15, 18};
+Circle(14) = {9, 3, 7};
+Circle(15) = {7, 3, 10};
+Circle(16) = {10, 3, 8};
+Circle(17) = {8, 3, 9};
+Line(18) = {7, 3};
+Line(19) = {3, 9};
+Line(20) = {3, 8};
+Line(21) = {3, 10};
+Line(22) = {15, 18};
+Line(23) = {14, 15};
+Line(24) = {16, 15};
+Line(25) = {15, 17};
+Circle(26) = {2, 3, 4};
+Line(27) = {1, 2};
+Line(28) = {4, 5};
+Line(29) = {5, 6};
+Line(30) = {6, 24};
+Line(31) = {24, 23};
+Line(32) = {23, 22};
+Line(33) = {22, 21};
+Line(34) = {21, 1};
+Line(35) = {20, 1};
+Line(36) = {6, 11};
+Line Loop(37) = {20, 17, -19};
+Plane Surface(38) = {37};
+Line Loop(39) = {19, 14, 18};
+Plane Surface(40) = {39};
+Line Loop(41) = {18, 21, -15};
+Plane Surface(42) = {41};
+Line Loop(43) = {21, 16, -20};
+Plane Surface(44) = {43};
+Line Loop(45) = {22, 10, 23};
+Plane Surface(46) = {45};
+Line Loop(47) = {24, -23, 11};
+Plane Surface(48) = {47};
+Line Loop(49) = {24, 25, -12};
+Plane Surface(50) = {49};
+Line Loop(51) = {25, 13, -22};
+Plane Surface(52) = {51};
+Line Loop(53) = {9, 1, 2, 3, 4, 5, 6, 7, 8};
+Plane Surface(54) = {53};
+Line Loop(55) = {27, 26, 28, 29, 30, 31, 32, 33, 34};
+Plane Surface(56) = {55};
+Line Loop(57) = {31, 32, 33, 34, -35, 2, 3, 4, 5, 6, -36, 30};
+Plane Surface(58) = {57};
+
+Physical Surface("red") = {54, 56};
+Physical Surface("white") = {58};
+Physical Surface("lwheel_1") = {46, 50};
+Physical Surface("lwheel_2") = {48, 52};
+Physical Surface("rwheel_1") = {38, 42};
+Physical Surface("rwheel_2") = {40, 44};
diff --git a/examples/io/parser/CMakeLists.txt b/examples/io/parser/CMakeLists.txt
new file mode 100644
index 000000000..b304736f0
--- /dev/null
+++ b/examples/io/parser/CMakeLists.txt
@@ -0,0 +1,44 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Fabian Barras <fabian.barras@epfl.ch>
+#
+# @date creation: Mon Dec 14 09:07:44 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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+add_mesh(swiss_cheese swiss_cheese.geo 2 2)
+
+register_example(example_parser
+ example_parser.cc
+ USE IOHelper
+ DEPENDS swiss_cheese
+ DIRECTORIES_TO_CREATE paraview
+ )
+
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/input_file.dat
+ ${CMAKE_CURRENT_BINARY_DIR}/input_file.dat
+ COPYONLY
+ )
diff --git a/examples/io/parser/example_parser.cc b/examples/io/parser/example_parser.cc
new file mode 100644
index 000000000..b431faf80
--- /dev/null
+++ b/examples/io/parser/example_parser.cc
@@ -0,0 +1,80 @@
+/**
+ * @file example_parser.cc
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ * @date Mon Dec 14 09:45:20 2015
+ *
+ * @brief Example on how to parse input text file
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------------- */
+#include <limits>
+#include <fstream>
+#include <iostream>
+/* -------------------------------------------------------------------------- */
+#include "aka_common.hh"
+#include "mesh.hh"
+#include "solid_mechanics_model.hh"
+/* -------------------------------------------------------------------------- */
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+
+ // Precise in initialize the name of the text input file to parse.
+ initialize("input_file.dat", argc, argv);
+
+ // Get the user ParserSection.
+ const ParserSection & usersect = getUserParser();
+
+ // getParameterValue() allows to extract data associated to a given parameter name
+ // and cast it in the desired type set as template paramter.
+ Mesh mesh(usersect.getParameterValue<UInt>("spatial_dimension"));
+ mesh.read(usersect.getParameterValue<std::string>("mesh_file"));
+
+ // getParameter() can be used with variable declaration (destination type is explicitly known).
+ UInt max_iter = usersect.getParameter("max_nb_iterations");
+ Real precision = usersect.getParameter("precision");
+
+ // Following NumPy convention, data can be interpreted as Vector or Matrix structures.
+ Matrix<Real> eigen_stress = usersect.getParameter("stress");
+
+ SolidMechanicsModel model(mesh);
+ mesh.createGroupsFromMeshData<std::string>("physical_names");
+ model.initFull(SolidMechanicsModelOptions(_static));
+
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), usersect.getParameterValue<std::string>("outter_crust"));
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), usersect.getParameterValue<std::string>("outter_crust"));
+ model.applyBC(BC::Neumann::FromStress(eigen_stress), usersect.getParameterValue<std::string>("inner_holes"));
+
+ model.setDirectory("./paraview");
+ model.setBaseName("swiss_cheese");
+ model.addDumpFieldVector("displacement");
+
+ model.solveStep<_scm_newton_raphson_tangent, _scc_increment>(precision, max_iter);
+
+ model.dump();
+
+ finalize();
+
+ return EXIT_SUCCESS;
+}
diff --git a/examples/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/local_material_damage.hh b/examples/new_material/local_material_damage.hh
index dabfcdae3..06d28dea7 100644
--- a/examples/new_material/local_material_damage.hh
+++ b/examples/new_material/local_material_damage.hh
@@ -1,128 +1,128 @@
/**
* @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>
*
* @date creation: Fri Nov 26 2010
* @date last modification: Fri May 16 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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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
+ /// compute the celerity of the fastest wave in the material
inline Real getCelerity(const Element & element) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real);
private:
/// the young modulus
Real E;
/// Poisson coefficient
Real nu;
/// First Lamé coefficient
Real lambda;
/// Second Lamé coefficient (shear modulus)
Real mu;
/// resistance to damage
Real Yd;
/// damage threshold
Real Sd;
/// Bulk modulus
Real kpa;
/// damage internal variable
InternalField<Real> damage;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "local_material_damage_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_LOCAL_MATERIAL_DAMAGE_HH__ */
diff --git a/examples/new_material/local_material_damage_inline_impl.cc b/examples/new_material/local_material_damage_inline_impl.cc
index 2d8d5ccf0..3bddbbd03 100644
--- a/examples/new_material/local_material_damage_inline_impl.cc
+++ b/examples/new_material/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>
*
* @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 {
- return (std::sqrt(E/rho));
+ // 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 ef503e9b5..9b9bebf22 100644
--- a/examples/new_material/new_local_material.cc
+++ b/examples/new_material/new_local_material.cc
@@ -1,109 +1,109 @@
/**
* @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>
*
* @date creation: Fri Apr 20 2012
* @date last modification: Mon Apr 07 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"
#include "local_material_damage.hh"
using namespace akantu;
#define bar_length 10.
#define bar_height 4.
akantu::Real eps = 1e-10;
int main(int argc, char *argv[]) {
akantu::initialize("material.dat", argc, argv);
UInt max_steps = 10000;
Real epot, ekin;
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
mesh.read("barre_trou.msh");
mesh.createGroupsFromMeshData<std::string>("physical_names");
/// model creation
SolidMechanicsModel model(mesh);
/// model initialization
model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass, true));
model.registerNewCustomMaterials<LocalMaterialDamage>("local_damage");
model.initMaterials();
std::cout << model.getMaterial(0) << std::endl;
Real time_step = model.getStableTimeStep();
model.setTimeStep(time_step/10.);
/// Dirichlet boundary conditions
model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "Fixed_x");
model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed_y");
// Neumann boundary condition
Matrix<Real> stress(2,2);
stress.eye(3e2);
model.applyBC(BC::Neumann::FromStress(stress), "Traction");
model.setBaseName("local_material");
model.addDumpField("displacement");
model.addDumpField("velocity" );
model.addDumpField("acceleration");
model.addDumpField("force" );
model.addDumpField("residual" );
model.addDumpField("grad_u" );
model.addDumpField("stress" );
model.addDumpField("damage" );
model.dump();
for(UInt s = 0; s < max_steps; ++s) {
model.explicitPred();
model.updateResidual();
model.updateAcceleration();
model.explicitCorr();
- epot = model.getPotentialEnergy();
- ekin = model.getKineticEnergy();
+ epot = model.getEnergy("potential");
+ ekin = model.getEnergy("kinetic");
if(s % 100 == 0) std::cout << s << " " << epot << " " << ekin << " " << epot + ekin
<< std::endl;
if(s % 100 == 0) model.dump();
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/extra_packages/extra-materials b/extra_packages/extra-materials
new file mode 160000
index 000000000..413cd3016
--- /dev/null
+++ b/extra_packages/extra-materials
@@ -0,0 +1 @@
+Subproject commit 413cd301657897dbf57f36e0250da810fd81eb7a
diff --git a/extra_packages/igfem b/extra_packages/igfem
new file mode 160000
index 000000000..fcacdece3
--- /dev/null
+++ b/extra_packages/igfem
@@ -0,0 +1 @@
+Subproject commit fcacdece31fc1c406208b3780b50b623939e8656
diff --git a/extra_packages/parallel-cohesive-element b/extra_packages/parallel-cohesive-element
new file mode 160000
index 000000000..4e4270f3c
--- /dev/null
+++ b/extra_packages/parallel-cohesive-element
@@ -0,0 +1 @@
+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/students-extra-package b/extra_packages/students-extra-package
new file mode 160000
index 000000000..812be966e
--- /dev/null
+++ b/extra_packages/students-extra-package
@@ -0,0 +1 @@
+Subproject commit 812be966ef21047b32e735a9e79d5474bbc98d29
diff --git a/extra_packages/traction-at-split-node-contact b/extra_packages/traction-at-split-node-contact
new file mode 160000
index 000000000..95926b0cf
--- /dev/null
+++ b/extra_packages/traction-at-split-node-contact
@@ -0,0 +1 @@
+Subproject commit 95926b0cfda429a6c2adde41924aa2081892a7ad
diff --git a/packages/00_core.cmake b/packages/00_core.cmake
deleted file mode 100644
index b8e823857..000000000
--- a/packages/00_core.cmake
+++ /dev/null
@@ -1,434 +0,0 @@
-#===============================================================================
-# @file 00_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
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_CORE ON CACHE INTERNAL "core package for Akantu" FORCE)
-
-set(AKANTU_CORE_FILES
- 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_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_pentahedron_6_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_data_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/shape_functions.hh
- fe_engine/shape_functions_inline_impl.cc
- fe_engine/shape_lagrange.cc
- fe_engine/shape_lagrange.hh
- fe_engine/shape_lagrange_inline_impl.cc
- fe_engine/shape_linked.cc
- fe_engine/shape_linked.hh
- fe_engine/shape_linked_inline_impl.cc
- fe_engine/element.hh
-
- io/dumper/dumpable.hh
- io/dumper/dumpable.cc
- io/dumper/dumpable_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.hh
- io/parser/parser_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_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.cc
- mesh_utils/mesh_utils.hh
- mesh_utils/mesh_utils_inline_impl.cc
-
- model/boundary_condition.hh
- model/boundary_condition_functor.hh
- model/boundary_condition_functor_inline_impl.cc
- model/boundary_condition_tmpl.hh
- model/integration_scheme/generalized_trapezoidal.hh
- model/integration_scheme/generalized_trapezoidal_inline_impl.cc
- model/integration_scheme/integration_scheme_1st_order.hh
- model/integration_scheme/integration_scheme_2nd_order.hh
- model/integration_scheme/newmark-beta.hh
- model/integration_scheme/newmark-beta_inline_impl.cc
- model/model.cc
- model/model.hh
- model/model_inline_impl.cc
-
- model/solid_mechanics/material.cc
- model/solid_mechanics/material.hh
- model/solid_mechanics/material_inline_impl.cc
- model/solid_mechanics/material_list.hh
- model/solid_mechanics/material_random_internal.hh
- 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_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
-
-
-
- solver/solver.cc
- solver/solver.hh
- solver/sparse_matrix.cc
- solver/sparse_matrix.hh
- solver/sparse_matrix_inline_impl.cc
- solver/static_solver.hh
- solver/static_solver.cc
-
- synchronizer/communication_buffer.hh
- synchronizer/communication_buffer_inline_impl.cc
- synchronizer/data_accessor.cc
- synchronizer/data_accessor.hh
- synchronizer/data_accessor_inline_impl.cc
- synchronizer/distributed_synchronizer.cc
- synchronizer/distributed_synchronizer.hh
- synchronizer/distributed_synchronizer_tmpl.hh
- synchronizer/dof_synchronizer.cc
- synchronizer/dof_synchronizer.hh
- synchronizer/dof_synchronizer_inline_impl.cc
- synchronizer/filtered_synchronizer.cc
- synchronizer/filtered_synchronizer.hh
- synchronizer/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
- )
-
-
-set(AKANTU_CORE_DEB_DEPEND
- libboost-dev
- )
-
-set(AKANTU_CORE_TESTS
- test_csr
- test_facet_element_mapping
- test_facet_extraction_tetrahedron_4
- test_facet_extraction_triangle_3
- test_grid
- test_interpolate_stress
- test_local_material
- test_material_damage_non_local
- test_material_thermal
- test_matrix
- test_mesh_boundary
- test_mesh_data
- test_mesh_io_msh
- test_mesh_io_msh_physical_names
- test_mesh_partitionate_mesh_data
- test_parser
- test_dumper
- test_pbc_tweak
- test_purify_mesh
- test_solid_mechanics_model_bar_traction2d
- test_solid_mechanics_model_bar_traction2d_structured
- test_solid_mechanics_model_bar_traction2d_structured_pbc
- test_solid_mechanics_model_boundary_condition
- test_solid_mechanics_model_circle_2
- test_solid_mechanics_model_cube3d
- test_solid_mechanics_model_cube3d_pbc
- test_solid_mechanics_model_cube3d_tetra10
- test_solid_mechanics_model_square
- test_solid_mechanics_model_material_eigenstrain
- test_static_memory
- test_surface_extraction_tetrahedron_4
- test_surface_extraction_triangle_3
- test_vector
- test_vector_iterator
- test_weight
- test_math
- test_material_standard_linear_solid_deviatoric_relaxation
- test_material_standard_linear_solid_deviatoric_relaxation_tension
- test_material_plasticity
- )
-
-set(AKANTU_CORE_MANUAL_FILES
- manual.sty
- manual.cls
- manual.tex
- manual-macros.sty
- manual-titlepages.tex
- manual-introduction.tex
- manual-gettingstarted.tex
- manual-io.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
- )
-
-find_program(READLINK_COMMAND readlink)
-find_program(ADDR2LINE_COMMAND addr2line)
-mark_as_advanced(READLINK_COMMAND)
-mark_as_advanced(ADDR2LINE_COMMAND)
-
-include(CheckFunctionExists)
-
-check_function_exists(clock_gettime _clock_gettime)
-
-if(NOT _clock_gettime)
- set(AKANTU_USE_OBSOLETE_GETTIMEOFDAY ON)
-else()
- set(AKANTU_USE_OBSOLETE_GETTIMEOFDAY OFF)
-endif()
-
-set(AKANTU_CORE_DOCUMENTATION
-"
-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 build-essential cmake-curses-gui libboost-dev zlib1g-dev
-\\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}
-")
\ No newline at end of file
diff --git a/packages/00_core_cxx11.cmake b/packages/00_core_cxx11.cmake
deleted file mode 100644
index 63fa5d402..000000000
--- a/packages/00_core_cxx11.cmake
+++ /dev/null
@@ -1,80 +0,0 @@
-#===============================================================================
-# @file 00_core_cxx11.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Mon May 06 2013
-# @date last modification: Thu Jul 03 2014
-#
-# @brief C++11 addition to the core package
-#
-# @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(CheckCXXCompilerFlag)
-check_cxx_compiler_flag (-std=c++0x HAVE_NEW_STD)
-
-set(AKANTU_CORE_CXX11_FILES
- 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_NEW_STD)
- option(AKANTU_CORE_CXX11 "C++ 11 additions for Akantu core" ON)
-
- 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)
- elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.8")
- if(AKANTU_CORE_CXX11)
- add_flags(cxx -DBOOST_RESULT_OF_USE_TR1)
- else()
- remove_flags(cxx -DBOOST_RESULT_OF_USE_TR1)
- endif()
- endif()
- endif()
-
- if(AKANTU_CORE_CXX11)
- add_flags(cxx "-std=c++0x")
- else()
- remove_flags(cxx "-std=c++0x")
- endif()
-else()
- set(AKANTU_CORE_CXX11 OFF CACHE BOOL "core package for Akantu" FORCE)
- remove_flags(cxx "-std=c++0x")
-endif()
-
-mark_as_advanced(AKANTU_CORE_CXX11)
-
-set(AKANTU_CORE_CXX11_DOCUMENTATION "
-This option activates some features of the C++11 standard. This is usable with GCC>=4.7 or Intel>=13.")
-
diff --git a/packages/00_documentation_doxygen.cmake b/packages/00_documentation_doxygen.cmake
deleted file mode 100644
index 0e3380df8..000000000
--- a/packages/00_documentation_doxygen.cmake
+++ /dev/null
@@ -1,47 +0,0 @@
-#===============================================================================
-# @file 00_documentation_doxygen.cmake
-#
-# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
-#
-# @date creation: Tue Jun 10 2014
-# @date last modification: Tue Jun 24 2014
-#
-# @brief Doxygen documentation of the code
-#
-# @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/>.
-#
-#===============================================================================
-
-option(AKANTU_DOCUMENTATION_DOXYGEN "Build source documentation using Doxygen." OFF)
-
-set(AKANTU_DOCUMENTATION_DOXYGEN_DOCUMENTATION
-"
-This generates the Doxygen documantation of the source code.
-It depends on:
-\\begin{itemize}
-\\item \\href{http://www.stack.nl/~dimitri/doxygen/}{Doxygen} an automated source code documentations system.
-\\item Optional: \\href{http://www.graphviz.org/}{Graphviz} to generate the dependencies graph
-\\end{itemize}
-
-Under Ubuntu (14.04 LTS), the installation of the dependencies can be performed using the following command:
-\\begin{command}
- > sudo apt-get install doxygen
- > sudo apt-get install graphviz
-\\end{command}
-")
\ No newline at end of file
diff --git a/packages/00_documentation_manual.cmake b/packages/00_documentation_manual.cmake
deleted file mode 100644
index eeef47666..000000000
--- a/packages/00_documentation_manual.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-#===============================================================================
-# @file 00_documentation_manual.cmake
-#
-# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
-#
-# @date creation: Tue Jun 10 2014
-# @date last modification: Thu Jul 03 2014
-#
-# @brief Akantu's manual package
-#
-# @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/>.
-#
-#===============================================================================
-
-option(AKANTU_DOCUMENTATION_MANUAL "Build manual." OFF)
-
-set(AKANTU_DOCUMENTATION_MANUAL_DOCUMENTATION "
-This package alows to compile the user manual in the build folder \\shellcode{build/doc/manual/manual.pdf}.
-
-Under Ubuntu (14.04 LTS), the installation of the dependencies can be performed using the following command:
-\\begin{command}
- > sudo apt-get install install rubber texlive texlive-science texlive-latex-extra
-\\end{command}")
\ No newline at end of file
diff --git a/packages/10_heat_transfer.cmake b/packages/10_heat_transfer.cmake
deleted file mode 100644
index 4b24506b4..000000000
--- a/packages/10_heat_transfer.cmake
+++ /dev/null
@@ -1,59 +0,0 @@
-#===============================================================================
-# @file 10_heat_transfer.cmake
-#
-# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
-#
-# @date creation: Mon Nov 21 2011
-# @date last modification: Thu Jun 12 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
-#
-#===============================================================================
-
-option(AKANTU_HEAT_TRANSFER "Use Heat Transfer package of Akantu" OFF)
-
-set(AKANTU_HEAT_TRANSFER_FILES
- model/heat_transfer/heat_transfer_model.cc
- model/heat_transfer/heat_transfer_model.hh
- model/heat_transfer/heat_transfer_model_inline_impl.cc
- )
-
-set(AKANTU_HEAT_TRANSFER_DOC
- manual/manual-heattransfermodel.tex
- )
-
-set(AKANTU_HEAT_TRANSFER_TESTS
- test_heat_transfer_model_cube3d
- test_heat_transfer_model_cube3d_pbc
- test_heat_transfer_model_square2d_pbc
- test_heat_transfer_model_square2d
- test_heat_transfer_model_cube3d_istropic_conductivity
- )
-
-set(AKANTU_HEAT_TRANSFER_MANUAL_FILES
- manual-heattransfermodel.tex
-)
-
-set(AKANTU_HEAT_TRANSFER_DOCUMENTATION
-"
-This package activates the heat transfer model within Akantu.
-It has no additional dependencies.
-")
\ No newline at end of file
diff --git a/packages/10_structural_mechanics.cmake b/packages/10_structural_mechanics.cmake
deleted file mode 100644
index 3578e4930..000000000
--- a/packages/10_structural_mechanics.cmake
+++ /dev/null
@@ -1,80 +0,0 @@
-#===============================================================================
-# @file 10_structural_mechanics.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Mon Nov 21 2011
-# @date last modification: Mon Jul 07 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
-#
-#===============================================================================
-
-option(AKANTU_STRUCTURAL_MECHANICS "Use Structural mechanics model package of Akantu" OFF)
-
-add_internal_package_dependencies(STRUCTURAL_MECHANICS IMPLICIT)
-
-set(AKANTU_STRUCTURAL_MECHANICS_FILES
- 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
- )
-
-set(AKANTU_STRUCTURAL_MECHANICS_DOC
- manual/manual-structuralmechanicsmodel.tex
- )
-
-set(AKANTU_STRUCTURAL_MECHANICS_TESTS
- test_structural_mechanics_model_bernoulli_beam_2
- test_structural_mechanics_model_boundary_bernoulli_beam_2
- test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1
- test_structural_mechanics_model_bernoulli_beam_2_complicated
- test_structural_mechanics_model_bernoulli_beam_2_exemple_1_1_y
- test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_xy
- test_structural_mechanics_model_bernoulli_beam_3_exemple_1_1_zy
- test_structural_mechanics_model_bernoulli_beam_3_local_force
- test_structural_mechanics_model_bernoulli_beam_3_exercice_12_10_13
- test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5
- test_structural_mechanics_model_bernoulli_beam_dynamics
- )
-
-set(AKANTU_STRUCTURAL_MECHANICS_MANUAL_FILES
- manual-structuralmechanicsmodel.tex
- manual-structuralmechanicsmodel-elements.tex
-
- figures/beam_example.pdf
- figures/elements/bernoulli_2.pdf
- figures/elements/bernoulli_2.svg
- )
-
-set(AKANTU_STRUCTURAL_MECHANICS_DOCUMENTATION "
-This package activates the compilation for the Structural Mechanics engine of Akantu
-")
diff --git a/packages/20_cohesive_element.cmake b/packages/20_cohesive_element.cmake
deleted file mode 100644
index 66198a823..000000000
--- a/packages/20_cohesive_element.cmake
+++ /dev/null
@@ -1,109 +0,0 @@
-#===============================================================================
-# @file 20_cohesive_element.cmake
-#
-# @author Marco Vocialta <marco.vocialta@epfl.ch>
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Tue Oct 16 2012
-# @date last modification: Tue Sep 02 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
-#
-#===============================================================================
-
-option(AKANTU_COHESIVE_ELEMENT "Use cohesive_element package of Akantu" OFF)
-add_external_package_dependencies(cohesive_element lapack)
-
-set(AKANTU_COHESIVE_ELEMENT_FILES
- 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_inline_impl.cc
-
- model/solid_mechanics/materials/material_cohesive/cohesive_internal_field_tmpl.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/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_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_linear.hh
- model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.hh
-
-# io/dumper/dumper_iohelper_tmpl_connectivity_field.hh
- )
-
-
-set(AKANTU_COHESIVE_ELEMENT_TESTS
- test_cohesive_buildfacets_tetrahedron
- test_cohesive_buildfacets_hexahedron
- test_cohesive_intrinsic
- test_cohesive_intrinsic_quadrangle
- test_cohesive_extrinsic
- test_cohesive_extrinsic_quadrangle
- test_cohesive_buildfragments
- test_cohesive_intrinsic_impl
- )
-
-set(AKANTU_COHESIVE_ELEMENT_DOC
- manual/manual-cohesive_elements.tex
- manual/manual-cohesive_elements_insertion.tex
- manual/manual-cohesive_laws.tex
- manual/manual-appendix-materials-cohesive.tex
- )
-
-set(AKANTU_COHESIVE_ELEMENT_MANUAL_FILES
- 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
- )
-
-
-set(AKANTU_COHESIVE_ELEMENT_DOCUMENTATION
-"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/20_contact.cmake b/packages/20_contact.cmake
deleted file mode 100644
index 53bbac44b..000000000
--- a/packages/20_contact.cmake
+++ /dev/null
@@ -1,99 +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/>.
-#
-#===============================================================================
-
-option(AKANTU_CONTACT "Use Contact package of Akantu" OFF)
-
-set(AKANTU_CONTACT_FILES
- #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
- )
-
-add_external_package_dependencies(contact cpparray)
-add_internal_package_dependencies(contact implicit)
-add_internal_package_dependencies(contact optimization)
-
-if(AKANTU_CONTACT)
- list(APPEND AKANTU_BOOST_COMPONENTS
- chrono
- system
- )
-endif()
-
-mark_as_advanced(AKANTU_USE_CPPARRAY)
-
-set(AKANTU_CONTACT_TESTS
- test_hertz_2D
- test_hertz_3D
- test_offset_1slave
- test_offset_2slaves
- test_acurnier_2D_1
- test_acurnier_2D_2
- test_acurnier_2D_3
- test_acurnier_3D_1
- test_acurnier_3D_2
- test_acurnier_3D_3
- )
-
-set(AKANTU_CONTACT_MANUAL_FILES
- manual-contact.tex
-
- figures/hertz_3D.png
-)
-
-set(AKANTU_CONTACT_DOCUMENTATION
-"
-This package enables the contact mechanics engine for Akantu
-")
\ No newline at end of file
diff --git a/packages/25_damage_non_local.cmake b/packages/25_damage_non_local.cmake
deleted file mode 100644
index 75be7965f..000000000
--- a/packages/25_damage_non_local.cmake
+++ /dev/null
@@ -1,65 +0,0 @@
-#===============================================================================
-# @file 25_damage_non_local.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Fri Jun 15 2012
-# @date last modification: Fri Jun 13 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
-#
-#===============================================================================
-
-option(AKANTU_DAMAGE_NON_LOCAL "Package for Non-local damage constitutives laws Akantu" OFF)
-
-add_external_package_dependencies(damage_non_local lapack)
-
-set(AKANTU_DAMAGE_NON_LOCAL_FILES
- 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/weight_function.cc
- model/solid_mechanics/materials/weight_function.hh
- model/solid_mechanics/materials/weight_function_tmpl.hh
-
- synchronizer/grid_synchronizer.cc
- synchronizer/grid_synchronizer.hh
- )
-
-set(AKANTU_DAMAGE_NON_LOCAL_TESTS
- test_material_damage_non_local
- test_grid_synchronizer
- )
-
-set(AKANTU_DAMAGE_NON_LOCAL_MANUAL_FILES
- manual-constitutive-laws-non_local.tex
- manual-appendix-materials-non-local.tex)
-
-set(AKANTU_DAMAGE_NON_LOCAL_DOCUMENTATION "
-This package activates the non local damage feature of AKANTU
-")
diff --git a/packages/40_optimization.cmake b/packages/40_optimization.cmake
deleted file mode 100644
index 90e1bd75d..000000000
--- a/packages/40_optimization.cmake
+++ /dev/null
@@ -1,44 +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/>.
-#
-#===============================================================================
-
-option(AKANTU_OPTIMIZATION "Use optimization package in Akantu" OFF)
-
-set(AKANTU_OPTIMIZATION_FILES
- common/aka_optimize.hh
- common/aka_optimize.cc
- )
-
-add_external_package_dependencies(optimization nlopt)
-mark_as_advanced(AKANTU_OPTIMIZATION)
-
-set(AKANTU_OPTIMIZATION_DOCUMENTATION "
-This activates the optimization routines of Akantu. This is currently needed by the
-contact detection algorithms.
-" )
diff --git a/packages/50_implicit.cmake b/packages/50_implicit.cmake
deleted file mode 100644
index de84fd7e9..000000000
--- a/packages/50_implicit.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-#===============================================================================
-# @file 50_implicit.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Tue Oct 16 2012
-# @date last modification: Thu Jun 12 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_meta_package(IMPLICIT "Add support for implicit time scheme" OFF SCOTCH MUMPS)
-
-set(AKANTU_IMPLICIT_TESTS
- test_solid_mechanics_model_bar_traction2d_mass_not_lumped
- test_solid_mechanics_model_implicit_1d
- test_solid_mechanics_model_implicit_2d
- test_solid_mechanics_model_implicit_dynamic_2d
- )
-
-set(AKANTU_IMPLICIT_DOCUMENTATION
-"
-This package activates the sparse solver necessary to solve implicitely static/dynamic finite element problems.
-It depends on:
-\\begin{itemize}
-\\item \\href{http://mumps.enseeiht.fr/}{MUMPS}, a parallel sparse direct solver.
-\\item \\href{http://www.labri.fr/perso/pelegrin/scotch/}{Scotch}, a graph partitioner.
-\\end{itemize}
-")
\ No newline at end of file
diff --git a/packages/50_parallel.cmake b/packages/50_parallel.cmake
deleted file mode 100644
index 2a91df104..000000000
--- a/packages/50_parallel.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-#===============================================================================
-# @file 50_parallel.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Tue Oct 16 2012
-# @date last modification: Wed Jun 11 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_meta_package(PARALLEL "Add parallel support in Akantu" OFF 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_solid_mechanics_model_reassign_material
- )
-
-set(AKANTU_PARALLEL_MANUAL_FILES
- manual-parallel.tex
- )
-
-set(AKANTU_PARALLEL_DOCUMENTATION "
-This option activates the parallel features of AKANTU.
-" )
diff --git a/packages/80_cpparray.cmake b/packages/80_cpparray.cmake
deleted file mode 100644
index 74717a60f..000000000
--- a/packages/80_cpparray.cmake
+++ /dev/null
@@ -1,83 +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/>.
-#
-#===============================================================================
-option(AKANTU_USE_CPPARRAY "Use cpp-array library" OFF)
-option(AKANTU_USE_THIRD_PARTY_CPPARRAY "Automatic download of the CPP-ARRAY library" ON)
-mark_as_advanced(AKANTU_USE_THIRD_PARTY_CPPARRAY AKANTU_USE_CPPARRAY)
-
-if(AKANTU_USE_CPPARRAY AND AKANTU_USE_THIRD_PARTY_CPPARRAY)
- find_package(Git)
-
- if(GIT_FOUND)
- if(EXISTS ${PROJECT_SOURCE_DIR}/third-party/cpp-array)
- execute_process(
- COMMAND ${GIT_EXECUTABLE} pull
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/third-party/cpp-array
- OUTPUT_VARIABLE _revision)
- message(STATUS "Updating Cpp-Array")
- else()
- message(STATUS "Cloning Cpp-Array")
- execute_process(
- COMMAND ${GIT_EXECUTABLE} clone https://code.google.com/p/cpp-array.git ${PROJECT_SOURCE_DIR}/third-party/cpp-array
- OUTPUT_QUIET)
- endif()
- endif()
-
- if(EXISTS ${PROJECT_SOURCE_DIR}/third-party/cpp-array/)
- set(cpp-array_TESTS OFF CACHE BOOL "cpparray tests" FORCE)
- add_subdirectory(${PROJECT_SOURCE_DIR}/third-party/cpp-array/)
- set(cpp-array_TESTS OFF CACHE BOOL "cpparray tests" FORCE)
-
- mark_as_advanced(cpp-array_DEV)
- mark_as_advanced(cpp-array_DOCUMENTATION)
- mark_as_advanced(cpp-array_TESTS)
- mark_as_advanced(CUDA)
- mark_as_advanced(ARRAY_USER_LIB_PATH)
-
- list(APPEND AKANTU_EXTERNAL_LIB_INCLUDE_DIR ${cpp-array_INCLUDE_DIRS} ${CPP-ARRAY_INCLUDE_DIRS})
- list(APPEND AKANTU_EXTERNAL_LIBRARIES ${CPP-ARRAY_LIBRARIES})
- list(APPEND AKANTU_EXTERNAL_LIB_INCLUDE_DIR ${CPP-ARRAY_INCLUDE_DIRS})
- list(APPEND CPACK_SOURCE_IGNORE_FILES ${PROJECT_SOURCE_DIR}/third-party/cpp-array/)
- set(AKANTU_CPPARRAY_INCLUDE_DIR ${cpp-array_INCLUDE_DIRS} ${CPP-ARRAY_INCLUDE_DIRS})
-
-
- set(AKANTU_CPPARRAY ON)
- list(APPEND AKANTU_OPTION_LIST CPPARRAY)
- set(AKANTU_CPPARRAY ${AKANTU_CPPARRAY} CACHE INTERNAL "Use cpp-array library" FORCE)
- else()
- message(STATUS "Cpp-Array could not be found! Please install git and/or place cpp-array in the third-party folder of Akantu")
- endif()
-else()
- add_optional_external_package(CppArray "Use cpp-array library" OFF)
-endif()
-
-
-set(AKANTU_CPPARRAY_DOCUMENTATION "
-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/80_mpi.cmake b/packages/80_mpi.cmake
deleted file mode 100644
index 07fe38fb2..000000000
--- a/packages/80_mpi.cmake
+++ /dev/null
@@ -1,57 +0,0 @@
-#===============================================================================
-# @file 80_mpi.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Mon Nov 21 2011
-# @date last modification: Sat Jun 14 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
-#
-#===============================================================================
-
-if(AKANTU_USE_THIRD_PARTY_MUMPS)
- enable_language(Fortran)
-endif()
-
-add_optional_external_package(MPI "Add MPI support in akantu" OFF PREFIX MPI_C MPI DEPENDS SCOTCH)
-set(AKANTU_MPI_FILES
- synchronizer/static_communicator_mpi.cc
- synchronizer/static_communicator_mpi_inline_impl.hh
- synchronizer/static_communicator_mpi.hh
- )
-
-mark_as_advanced(MPI_EXTRA_LIBRARY MPI_LIBRARY)
-
-set(AKANTU_MPI_DOCUMENTATION
-"
-This is a meta package providing access to MPI.
-
-Under Ubuntu (14.04 LTS) the installation can be performed using the commands:
-\\begin{command}
- > sudo apt-get install libopenmpi-dev
-\\end{command}
-
-Under Mac OS X the installation requires the following steps:
-\\begin{command}
- > sudo port install mpich-devel
-\\end{command}
-")
diff --git a/packages/80_nlopt.cmake b/packages/80_nlopt.cmake
deleted file mode 100644
index fa223e4f9..000000000
--- a/packages/80_nlopt.cmake
+++ /dev/null
@@ -1,82 +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/>.
-#
-#===============================================================================
-
-option(AKANTU_USE_THIRD_PARTY_NLOPT "Automatic download of the NLOPT library" ON)
-option(AKANTU_USE_NLOPT "Use NLOPT library" OFF)
-mark_as_advanced(AKANTU_USE_THIRD_PARTY_NLOPT AKANTU_USE_NLOPT)
-
-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()
-
-if (AKANTU_USE_THIRD_PARTY_NLOPT AND AKANTU_USE_NLOPT)
- set(NLOPT_CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --enable-shared --with-cxx)
- 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(NLOPT_LIBRARIES ${NLOPT_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}nlopt_cxx${CMAKE_SHARED_LIBRARY_SUFFIX} CACHE PATH "Libraries for NLopt" FORCE)
- set(NLOPT_INCLUDE_DIR ${NLOPT_DIR}/include CACHE PATH "Include directories for NLopt" FORCE)
-
- mark_as_advanced(NLOPT_INCLUDE_DIR NLOPT_LIBRARIES)
-
- list(APPEND AKANTU_EXTERNAL_LIBRARIES ${NLOPT_LIBRARIES})
- list(APPEND AKANTU_EXTERNAL_LIB_INCLUDE_DIR ${NLOPT_INCLUDE_DIR})
- set(AKANTU_NLOPT_INCLUDE_DIR ${NLOPT_INCLUDE_DIR})
- set(AKANTU_NLOPT_LIBRARIES ${NLOPT_LIBRARIES})
- list(APPEND AKANTU_OPTION_LIST NLOPT)
- set(NLOPT_FOUND TRUE CACHE INTERNAL "" FORCE)
- set(AKANTU_NLOPT ON)
-
- list(APPEND AKANTU_EXTRA_TARGET_DEPENDENCIES NLopt)
-else()
- add_optional_external_package(NLopt "Use NLOPT library" OFF)
-endif()
-
-
-set(AKANTU_NLOPT_DOCUMENTATION "
-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/85_mumps.cmake b/packages/85_mumps.cmake
deleted file mode 100644
index 7b59c554d..000000000
--- a/packages/85_mumps.cmake
+++ /dev/null
@@ -1,203 +0,0 @@
-#===============================================================================
-# @file 85_mumps.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Mon Nov 21 2011
-# @date last modification: Mon Sep 15 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_MUMPS_FILES
- solver/solver_mumps.cc
- solver/solver_mumps.hh
- )
-
-option(AKANTU_USE_THIRD_PARTY_MUMPS "Use the third-party Mumps instead of the one from the system" OFF)
-option(AKANTU_USE_MUMPS "Add Mumps support in akantu")
-
-
-mark_as_advanced(AKANTU_USE_THIRD_PARTY_MUMPS)
-if(AKANTU_USE_THIRD_PARTY_MUMPS AND AKANTU_USE_MUMPS)
- set(MUMPS_DEPENDS)
- enable_language(Fortran)
-
- include(AkantuMacros)
- include(ExternalProject)
- if(AKANTU_USE_MPI)
- set(SCALAPACK_VERSION "2.0.2")
- set(SCALAPACK_ARCHIVE "http://www.netlib.org/scalapack/scalapack-${SCALAPACK_VERSION}.tgz")
- set(SCALAPACK_ARCHIVE_HASH "MD5=2f75e600a2ba155ed9ce974a1c4b536f")
-
- ExternalProject_Add(ScaLAPACK
- PREFIX ${PROJECT_BINARY_DIR}/third-party
- URL ${SCALAPACK_ARCHIVE}
- URL_HASH ${SCALAPACK_ARCHIVE_HASH}
- PATCH_COMMAND patch -p1 < ${PROJECT_SOURCE_DIR}/third-party/scalapack_${SCALAPACK_VERSION}.patch
- CMAKE_ARGS <SOURCE_DIR>/ScaLAPACK
- CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_C_FLAGS:STRING=-fPIC -DCMAKE_Fortran_FLAGS:STRING=-fPIC -DBUILD_SHARED_LIBS:BOOL=ON
- )
-
- set_third_party_shared_libirary_name(SCALAPACK_LIBRARIES scalapack)
- mark_as_advanced(SCALAPACK_LIBRARIES)
-
- install(FILES ${SCALAPACK_LIBRARIES}
- DESTINATION lib
- COMPONENT lib)
-
- list(APPEND MUMPS_DEPENDS ScaLAPACK)
- set(MUMPS_TYPE par)
- unset(MUMPS_PREFIX)
- else()
- set(MUMPS_TYPE seq)
- set(MUMPS_PREFIX _seq)
- endif()
-
- if(AKANTU_USE_THIRD_PARTY_SCOTCH)
- include(${PROJECT_SOURCE_DIR}/packages/90_scotch.cmake)
- list(APPEND MUMPS_DEPENDS Scotch)
- else()
- find_package(Scotch REQUIRED)
- endif()
- string(REPLACE ";" " " MUMPS_SCOTCH_LIBRARIES "${SCOTCH_LIBRARIES};${SCOTCH_LIBRARY_ESMUMPS}")
-
- find_package(BLAS REQUIRED)
- 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()
-
- set(MUMPS_VERSION "4.10.0")
- set(MUMPS_ARCHIVE "${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}.tar.gz")
- set(MUMPS_ARCHIVE_HASH "MD5=959e9981b606cd574f713b8422ef0d9f")
- if(NOT EXISTS ${MUMPS_ARCHIVE})
- set(MUMPS_VERSION "4.9.2")
- set(MUMPS_ARCHIVE "${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}.tar.gz")
- set(MUMPS_ARCHIVE_HASH "MD5=d0b8f139a4acf29b76dbae69ade8ac54")
- if(NOT EXISTS ${MUMPS_ARCHIVE})
- MESSAGE(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
-
-Supported version for automated compilation in Akantu are 4.9.2 and 4.10.0")
- endif()
- endif()
-
- configure_file(${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}_make.inc.cmake
- ${PROJECT_BINARY_DIR}/third-party/MUMPSmake.inc)
-
- ExternalProject_Add(MUMPS
- DEPENDS ${MUMPS_DEPENDS}
- PREFIX ${PROJECT_BINARY_DIR}/third-party
- URL ${MUMPS_ARCHIVE}
- URL_HASH ${MUMPS_ARCHIVE_HASH}
- 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
- BUILD_COMMAND make d
- INSTALL_COMMAND prefix=<INSTALL_DIR> make install
- )
-
- 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})
- set(MUMPS_INCLUDE_DIR ${PROJECT_BINARY_DIR}/third-party/include CACHE PATH "" FORCE)
- set(MUMPS_LIBRARIES_ALL)
-
- mark_as_advanced(MUMPS_LIBRARY_COMMON MUMPS_LIBRARY_DMUMPS MUMPS_LIBRARY_PORD MUMPS_INCLUDE_DIR)
-
- list(APPEND MUMPS_LIBRARIES_ALL ${MPI_Fortran_LIBRARIES} ${MUMPS_LIBRARY_COMMON} ${MUMPS_LIBRARY_DMUMPS} ${MUMPS_LIBRARY_PORD} ${MUMPS_LIBRARY_MPI})
- set(MUMPS_LIBRARIES ${MUMPS_LIBRARIES_ALL} CACHE INTERNAL "Libraries for MUMPS" FORCE)
-
- install(FILES ${MUMPS_LIBRARIES}
- DESTINATION lib
- COMPONENT lib)
- install(DIRECTORY ${PROJECT_BINARY_DIR}/third-party/include/ DESTINATION include/mumps
- COMPONENT dev
- FILES_MATCHING PATTERN "*mumps*.h")
-
- list(APPEND AKANTU_EXTERNAL_LIBRARIES ${MUMPS_LIBRARIES})
- list(APPEND AKANTU_EXTERNAL_LIB_INCLUDE_DIR ${MUMPS_INCLUDE_DIR})
-
- set(AKANTU_MUMPS_INCLUDE_DIR ${MUMPS_INCLUDE_DIR})
- set(AKANTU_MUMPS_LIBRARIES ${MUMPS_LIBRARIES})
-
- list(APPEND AKANTU_OPTION_LIST MUMPS)
-
- set(MUMPS_FOUND TRUE CACHE INTERNAL "" FORCE)
- set(AKANTU_MUMPS ON)
-
- list(APPEND AKANTU_EXTRA_TARGET_DEPENDENCIES MUMPS)
-else()
- if(AKANTU_USE_MPI)
- set(MUMPS_TYPE par)
- set(AKANTU_MUMPS_DEB_DEPEND
- libmumps-dev
- )
- else()
- set(MUMPS_TYPE seq)
- set(AKANTU_MUMPS_DEB_DEPEND
- libmumps-seq-dev
- )
- endif()
-
- add_optional_external_package(Mumps "Add Mumps support in akantu" OFF)
-
-endif()
-
-set(AKANTU_MUMPS_TESTS
- test_sparse_matrix_profile
- test_sparse_matrix_assemble
- test_solver_mumps
- test_sparse_matrix_product
- )
-
-set(AKANTU_MUMPS_DOCUMENTATION "
-This package enables the \\href{http://mumps.enseeiht.fr/}{MUMPS} parallel direct solver for sparce matrices.
-This is necessary to solve static or implicit problems.
-
-Under Ubuntu (14.04 LTS) the installation can be performed using the commands:
-
-\\begin{command}
- > sudo apt-get install libmumps-seq-dev # for sequential
- > sudo apt-get install libmumps-dev # for parallel
-\\end{command}
-
-Under Mac OS X the installation requires the following steps:
-\\begin{command}
- > sudo port install mumps
-\\end{command}
-
-If you activate the advanced option AKANTU\\_USE\\_THIRD\\_PARTY\\_MUMPS the make system of akantu can automatically compile MUMPS. For this you will have to download MUMPS from \\url{http://mumps.enseeiht.fr/} or \\url{http://graal.ens-lyon.fr/MUMPS} and place it in \\shellcode{<akantu source>/third-party}
-")
diff --git a/packages/89_lapack.cmake b/packages/89_lapack.cmake
deleted file mode 100644
index 04db24fc1..000000000
--- a/packages/89_lapack.cmake
+++ /dev/null
@@ -1,41 +0,0 @@
-#===============================================================================
-# @file 89_lapack.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Fri Oct 19 2012
-# @date last modification: Thu Jun 12 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_optional_external_package(LAPACK "Use LAPACK for arithmetic operations" OFF LANGUAGE Fortran)
-mark_as_advanced(AKANTU_USE_LAPACK)
-
-set(AKANTU_LAPACK_DOCUMENTATION "
-This package provides access to a LAPACK implementation.
-
-Under Ubuntu (14.04 LTS), the installation can be performed using the following command:
-\\begin{command}
- > sudo apt-get install libatlas-base-dev
-\\end{command}
-" )
diff --git a/packages/90_blas.cmake b/packages/90_blas.cmake
deleted file mode 100644
index 6571f7d8a..000000000
--- a/packages/90_blas.cmake
+++ /dev/null
@@ -1,45 +0,0 @@
-#===============================================================================
-# @file 90_blas.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Fri Oct 19 2012
-# @date last modification: Tue Jun 24 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_optional_external_package(BLAS "Use BLAS for arithmetic operations" OFF LANGUAGE Fortran)
-mark_as_advanced(AKANTU_USE_BLAS)
-
-if(BLAS_mkl_core_LIBRARY)
- set(AKANTU_USE_BLAS_MKL)
-endif()
-
-set(AKANTU_BLAS_DOCUMENTATION "
-This package provides access to a BLAS implementation.
-
-Under Ubuntu (14.04 LTS), the installation can be performed using the following command:
-\\begin{command}
- > sudo apt-get install libatlas-base-dev
-\\end{command}
-" )
diff --git a/packages/90_iohelper.cmake b/packages/90_iohelper.cmake
deleted file mode 100644
index 4a69ab0df..000000000
--- a/packages/90_iohelper.cmake
+++ /dev/null
@@ -1,90 +0,0 @@
-#===============================================================================
-# @file 90_iohelper.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Tue Nov 29 2011
-# @date last modification: Tue Sep 02 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
-#
-#===============================================================================
-
-option(AKANTU_USE_THIRD_PARTY_IOHELPER "Automatic download of the IOHelper library" ON)
-option(AKANTU_USE_IOHELPER "Add IOHelper support in akantu" ON)
-
-mark_as_advanced(AKANTU_USE_IOHELPER)
-mark_as_advanced(AKANTU_USE_THIRD_PARTY_IOHELPER)
-
-if (AKANTU_USE_THIRD_PARTY_IOHELPER AND AKANTU_USE_IOHELPER)
- set(IOHELPER_VERSION "1.1")
- set(IOHELPER_GIT "https://git.epfl.ch/repo/iohelper.git")
-
- include(ExternalProject)
-
- ExternalProject_Add(IOHelper
- PREFIX ${PROJECT_BINARY_DIR}/third-party
- GIT_REPOSITORY ${IOHELPER_GIT}
- 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
- )
-
- set_third_party_shared_libirary_name(IOHELPER_LIBRARIES iohelper)
- list(APPEND AKANTU_EXTERNAL_LIBRARIES ${IOHELPER_LIBRARIES})
- list(APPEND AKANTU_EXTERNAL_LIB_INCLUDE_DIR ${PROJECT_BINARY_DIR}/third-party/include/iohelper)
-
- list(APPEND AKANTU_EXTRA_TARGET_DEPENDENCIES IOHelper)
- set(AKANTU_IOHELPER_INCLUDE_DIR ${PROJECT_BINARY_DIR}/third-party/include/iohelper)
- set(AKANTU_IOHELPER ON)
-else()
- add_optional_external_package(IOHelper "Add IOHelper support in akantu" ON)
-endif()
-
-
-set(AKANTU_IOHELPER_FILES
- 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_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_generic_elemental_field.hh
- io/dumper/dumper_generic_elemental_field_tmpl.hh
- )
-
-set(AKANTU_IOHELPER_DOCUMENTATION "
-This package activates the IOHelper facilities withing Akantu. This is mandatory if you want to be able to output Paraview files
-as well as any Dumper within Akantu.
-")
diff --git a/packages/90_scotch.cmake b/packages/90_scotch.cmake
deleted file mode 100644
index 6dcdb6405..000000000
--- a/packages/90_scotch.cmake
+++ /dev/null
@@ -1,148 +0,0 @@
-#===============================================================================
-# @file 90_scotch.cmake
-#
-# @author Nicolas Richart <nicolas.richart@epfl.ch>
-#
-# @date creation: Mon Nov 21 2011
-# @date last modification: Thu Jul 10 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_SCOTCH_FILES
- mesh_utils/mesh_partition/mesh_partition_scotch.cc
- )
-
-if(AKANTU_SCOTCH_ON OR AKANTU_PTSCOTCH_ON)
- set(AKANTU_PARTITIONER_ON ON)
-else()
- set(AKANTU_PARTITIONER_ON OFF)
-endif()
-
-set(AKANTU_SCOTCH_TESTS
- test_mesh_partitionate_scotch
- test_mesh_partitionate_scotch_advanced
- )
-
-
-option(AKANTU_USE_SCOTCH "Add Scotch support in akantu" OFF)
-option(AKANTU_USE_THIRD_PARTY_SCOTCH "Use the third-party Scotch instead of the one from the system" OFF)
-mark_as_advanced(AKANTU_USE_THIRD_PARTY_SCOTCH)
-
-set(SCOTCH_VERSION "5.1.12b")
-set(SCOTCH_ARCHIVE_HASH "MD5=e13b49be804755470b159d7052764dc0")
-set(SCOTCH_ARCHIVE ${PROJECT_SOURCE_DIR}/third-party/scotch_${SCOTCH_VERSION}_esmumps.tar.gz)
-if(NOT EXISTS ${SCOTCH_ARCHIVE})
- set(SCOTCH_ARCHIVE https://gforge.inria.fr/frs/download.php/28978/scotch_${SCOTCH_VERSION}_esmumps.tar.gz)
-endif()
-
-
-if(AKANTU_USE_THIRD_PARTY_SCOTCH AND AKANTU_USE_SCOTCH)
- if(TARGET Scotch)
- return()
- endif()
-
- find_package(BISON)
- find_package(FLEX)
- find_package(ZLIB)
-
- if (AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
- set (SCOTCH_TIMMING_OPTION -DCOMMON_TIMING_OLD)
- endif()
-
- if(CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(SCOTCH_ARCHITECTURE -DIDXSIZE64)
- else()
- set(SCOTCH_ARCHITECTURE)
- endif()
-
- 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}
- URL ${SCOTCH_ARCHIVE}
- URL_HASH ${SCOTCH_ARCHIVE_HASH}
- TLS_VERIFY FALSE
- 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
- BUILD_IN_SOURCE 1
- BUILD_COMMAND make -C src
- INSTALL_COMMAND prefix=<INSTALL_DIR> make -C src install
- )
-
- 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)
-
- list(APPEND AKANTU_EXTERNAL_LIBRARIES ${SCOTCH_LIBRARIES})
- list(APPEND AKANTU_EXTERNAL_LIB_INCLUDE_DIR ${SCOTCH_INCLUDE_DIR})
-
- set(AKANTU_SCOTCH_INCLUDE_DIR ${SCOTCH_INCLUDE_DIR})
- set(AKANTU_SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES})
-
- list(APPEND AKANTU_OPTION_LIST SCOTCH)
- set(SCOTCH_FOUND TRUE CACHE INTERNAL "" FORCE)
- set(AKANTU_SCOTCH ON)
-
- list(APPEND AKANTU_EXTRA_TARGET_DEPENDENCIES Scotch)
-else()
- add_optional_external_package(Scotch "Add Scotch support in akantu" OFF)
-
- 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()
-endif()
-
-set(AKANTU_SCOTCH_DOCUMENTATION "
-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{https://gforge.inria.fr/frs/download.php/28978/scotch\\_${SCOTCH_VERSION}\\_esmumps.tar.gz}{scotch\\_${SCOTCH_VERSION}\\_esmumps.tar.gz} and then place it in the directory \\shellcode{<akantu source>/third-party}
-" )
diff --git a/packages/blackdynamite.cmake b/packages/blackdynamite.cmake
new file mode 100644
index 000000000..b4ef8ee38
--- /dev/null
+++ b/packages/blackdynamite.cmake
@@ -0,0 +1,41 @@
+#===============================================================================
+# @file blackdynamite.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date Tue Nov 29 15:16:35 2011
+#
+# @brief package description for BlackDynamite support
+#
+# @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(BlackDynamite EXTERNAL
+ DESCRIPTION "Use BlackDynamite library"
+ SYSTEM OFF third-party/cmake/blackdynamite.cmake
+ EXTRA_PACKAGE_OPTIONS FOUND BlackDynamite_FOUND)
+
+set(_version master)
+
+package_add_third_party_script_variable(BlackDynamite
+ BLACKDYNAMITE_VERSION "${_version}")
+package_add_third_party_script_variable(BlackDynamite
+ BLACKDYNAMITE_GIT "git@lsmssrv1.epfl.ch:blackdynamite.git")
+package_add_third_party_script_variable(BlackDynamite
+ BLACKDYNAMITE_ARCHIVE "blackdynamite-${_version}.tar.gz")
diff --git a/packages/blas.cmake b/packages/blas.cmake
new file mode 100644
index 000000000..ac1c90bfd
--- /dev/null
+++ b/packages/blas.cmake
@@ -0,0 +1,81 @@
+#===============================================================================
+# @file 90_blas.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Fri Oct 19 2012
+# @date last modification: Tue Jun 24 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(BLAS EXTERNAL
+ DESCRIPTION "Use BLAS for arithmetic operations"
+ EXTRA_PACKAGE_OPTIONS LANGUAGE Fortran
+ SYSTEM ON third-party/cmake/blas.cmake)
+
+package_add_third_party_script_variable(BLAS BLAS_ARCHIVE "http://www.netlib.org/blas/blas-3.5.0.tgz")
+package_add_third_party_script_variable(BLAS BLAS_VERSION "3.5.0")
+
+set(_default_blas $ENV{BLA_VENDOR})
+if(NOT _default_blas)
+ set(_default_blas Generic)
+endif()
+
+set(AKANTU_USE_BLAS_VENDOR "${_default_blas}" CACHE STRING "Version of blas to use")
+mark_as_advanced(AKANTU_USE_BLAS_VENDOR)
+set_property(CACHE AKANTU_USE_BLAS_VENDOR PROPERTY STRINGS
+ Goto
+ ATLAS
+ PhiPACK
+ CXML
+ DXML
+ SunPerf
+ SCSL
+ SGIMATH
+ IBMESSL
+ Intel10_32
+ Intel10_64lp
+ Intel10_64lp_seq
+ Intel
+ ACML
+ ACML_MP
+ ACML_GPU
+ Apple
+ NAS
+ Generic
+ )
+
+set(ENV{BLA_VENDOR} ${AKANTU_USE_BLAS_VENDOR})
+
+if(BLAS_mkl_core_LIBRARY)
+ set(AKANTU_USE_BLAS_MKL CACHE INTERNAL "" FORCE)
+endif()
+
+package_declare_documentation(BLAS
+ "This package provides access to a BLAS implementation."
+ ""
+ "Under Ubuntu (14.04 LTS), the installation can be performed using the following command:"
+ "\\begin{command}"
+ " > sudo apt-get install libatlas-base-dev"
+ "\\end{command}"
+ )
diff --git a/packages/boost.cmake b/packages/boost.cmake
new file mode 100644
index 000000000..a2b62ea41
--- /dev/null
+++ b/packages/boost.cmake
@@ -0,0 +1,49 @@
+#===============================================================================
+# @file boost.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Wed Jan 14 2015
+#
+# @brief package handling the dependencies to boost
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+set(Boost_NO_BOOST_CMAKE ON CACHE BOOL "" FORCE)
+
+package_declare(Boost EXTERNAL
+ NOT_OPTIONAL
+ DESCRIPTION "Package handling boost components"
+ EXTRA_PACKAGE_OPTIONS PREFIX Boost
+ )
+
+mark_as_advanced(Boost_DIR)
+
+package_on_enabled_script(Boost
+ "if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER \"4.8\")
+ set(_boost_version \${Boost_MAJOR_VERSION}.\${Boost_MINOR_VERSION})
+ if(AKANTU_CORE_CXX11 AND _boost_version VERSION_LESS 1.58 AND _boost_version VERSION_GREATER 1.53)
+ add_flags(cxx -DBOOST_SPIRIT_USE_PHOENIX_V3)
+ else()
+ remove_flags(cxx -DBOOST_SPIRIT_USE_PHOENIX_V3)
+ endif()
+endif()
+")
diff --git a/packages/cgal.cmake b/packages/cgal.cmake
new file mode 100644
index 000000000..0b13d94a6
--- /dev/null
+++ b/packages/cgal.cmake
@@ -0,0 +1,72 @@
+#===============================================================================
+# @file cgal.cmake
+#
+# @author Lucas Frérot <lucas.frerot@epfl.ch>
+#
+# @date creation: Thu Feb 19 2015
+# @date last modification: Mon Mar 2 2015
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(CGAL EXTERNAL
+ DESCRIPTION "Add CGAL support in akantu"
+ COMPILE_FLAGS "-frounding-math"
+ BOOST_COMPONENTS system
+ )
+
+package_declare_sources(CGAL
+ geometry/mesh_geom_common.hh
+
+ geometry/mesh_geom_abstract.hh
+
+ geometry/mesh_geom_factory.hh
+ geometry/mesh_geom_factory_tmpl.hh
+
+ geometry/mesh_abstract_intersector.hh
+ geometry/mesh_abstract_intersector_tmpl.hh
+
+ geometry/mesh_geom_intersector.hh
+ geometry/mesh_geom_intersector_tmpl.hh
+
+ geometry/mesh_segment_intersector.hh
+ geometry/mesh_segment_intersector_tmpl.hh
+
+ geometry/mesh_sphere_intersector.hh
+ geometry/mesh_sphere_intersector_tmpl.hh
+
+ geometry/tree_type_helper.hh
+ geometry/geom_helper_functions.hh
+
+ geometry/aabb_primitives/triangle.hh
+ geometry/aabb_primitives/line_arc.hh
+ geometry/aabb_primitives/tetrahedron.hh
+
+ geometry/aabb_primitives/aabb_primitive.hh
+ geometry/aabb_primitives/aabb_primitive.cc
+ )
+
+package_declare_documentation(CGAL
+ "This package allows the use of CGAL's geometry algorithms in Akantu. Note that it needs a version of CGAL $\\geq$ 4.5 and needs activation of boost's system component."
+ ""
+ "CGAL checks with an assertion that the compilation flag \\shellcode{-frounding-math} is activated, which forbids the use of Valgrind on any code compilated with the package."
+ )
diff --git a/packages/cohesive_element.cmake b/packages/cohesive_element.cmake
new file mode 100644
index 000000000..b3b99a8bd
--- /dev/null
+++ b/packages/cohesive_element.cmake
@@ -0,0 +1,123 @@
+#===============================================================================
+# @file 20_cohesive_element.cmake
+#
+# @author Marco Vocialta <marco.vocialta@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Tue Oct 16 2012
+# @date last modification: Tue Sep 02 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(cohesive_element
+ DESCRIPTION "Use cohesive_element package of Akantu"
+ DEPENDS lapack)
+
+package_declare_sources(cohesive_element
+ fe_engine/cohesive_element.cc
+ fe_engine/cohesive_element.hh
+ fe_engine/fe_engine_template_cohesive.cc
+ fe_engine/shape_cohesive.hh
+ fe_engine/shape_cohesive_inline_impl.cc
+ mesh_utils/cohesive_element_inserter.cc
+ mesh_utils/cohesive_element_inserter.hh
+ model/solid_mechanics/materials/material_cohesive/cohesive_internal_field.hh
+ model/solid_mechanics/materials/material_cohesive/cohesive_internal_field_tmpl.hh
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.hh
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.cc
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_exponential.hh
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.cc
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear.hh
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.cc
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.hh
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.cc
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
+ model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc
+ model/solid_mechanics/materials/material_cohesive/material_cohesive.cc
+ model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
+ model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc
+ model/solid_mechanics/materials/material_cohesive_includes.hh
+ model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
+ model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.hh
+ model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
+ model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
+ model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
+ model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
+ model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
+ )
+
+
+package_declare_elements(cohesive_element
+ ELEMENT_TYPES
+ _cohesive_2d_4
+ _cohesive_2d_6
+ _cohesive_1d_2
+ _cohesive_3d_6
+ _cohesive_3d_12
+ _cohesive_3d_8
+ _cohesive_3d_16
+ KIND cohesive
+ GEOMETRICAL_TYPES
+ _gt_cohesive_2d_4
+ _gt_cohesive_2d_6
+ _gt_cohesive_1d_2
+ _gt_cohesive_3d_6
+ _gt_cohesive_3d_12
+ _gt_cohesive_3d_8
+ _gt_cohesive_3d_16
+ FE_ENGINE_LISTS
+ gradient_on_integration_points
+ interpolate_on_integration_points
+ compute_normals_on_integration_points
+ inverse_map
+ contains
+ get_shapes_derivatives
+ )
+
+package_declare_material_infos(cohesive_element
+ LIST AKANTU_COHESIVE_MATERIAL_LIST
+ INCLUDE material_cohesive_includes.hh
+ )
+
+
+package_declare_documentation_files(cohesive_element
+ manual-cohesive_elements.tex
+ manual-cohesive_elements_insertion.tex
+ manual-cohesive_laws.tex
+ manual-appendix-materials-cohesive.tex
+
+ figures/cohesive2d.pdf
+ figures/cohesive_exponential.pdf
+ figures/linear_cohesive_law.pdf
+ figures/bilinear_cohesive_law.pdf
+ )
+
+package_declare_documentation(cohesive_element
+ "This package activates the cohesive elements engine within Akantu."
+ "It depends on:"
+ "\\begin{itemize}"
+ " \\item A fortran compiler."
+ " \\item An implementation of BLAS/LAPACK."
+ "\\end{itemize}"
+ )
diff --git a/packages/contact.cmake b/packages/contact.cmake
new file mode 100644
index 000000000..6d7bd8ec9
--- /dev/null
+++ b/packages/contact.cmake
@@ -0,0 +1,79 @@
+#===============================================================================
+# @file 20_contact.cmake
+#
+# @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Nov 21 2011
+# @date last modification: Mon Sep 15 2014
+#
+# @brief package description for contact
+#
+# @section LICENSE
+#
+# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(contact
+ DESCRIPTION "Use Contact package of Akantu"
+ DEPENDS cpparray implicit optimization)
+
+
+package_declare_sources(contact
+ #cc files
+ contact/discretization.cc
+ contact/element.cc
+ contact/friction.cc
+ contact/resolution/resolution_augmented_lagrangian.cc
+ contact/scheme.cc
+ contact/search.cc
+ contact/surface.cc
+ contact/zone.cc
+ contact/contact_impl.cc
+
+ # include files
+ contact/contact_common.hh
+ contact/contact_manager.hh
+ contact/discretization.hh
+ contact/element.hh
+ contact/friction.hh
+ contact/resolution.hh
+ contact/resolution/resolution_augmented_lagrangian.hh
+ contact/scheme.hh
+ contact/search.hh
+ contact/surface.hh
+ contact/zone.hh
+ contact/contact_impl.hh
+ )
+
+
+if(AKANTU_CONTACT)
+ list(APPEND AKANTU_BOOST_COMPONENTS
+ chrono
+ system
+ )
+endif()
+
+package_declare_documentation_files(contact
+ manual-contact.tex
+ figures/hertz_3D.png
+ )
+
+package_declare_documentation(contact
+ "This package enables the contact mechanics engine for Akantu"
+ )
\ No newline at end of file
diff --git a/packages/core.cmake b/packages/core.cmake
new file mode 100644
index 000000000..3cb5a046e
--- /dev/null
+++ b/packages/core.cmake
@@ -0,0 +1,484 @@
+#===============================================================================
+# @file 00_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
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(core NOT_OPTIONAL DESCRIPTION "core package for Akantu")
+
+package_declare_sources(core
+ common/aka_array.cc
+ common/aka_array.hh
+ common/aka_array_tmpl.hh
+ common/aka_blas_lapack.hh
+ common/aka_circular_array.hh
+ common/aka_circular_array_inline_impl.cc
+ common/aka_common.cc
+ common/aka_common.hh
+ common/aka_common_inline_impl.cc
+ common/aka_csr.hh
+ common/aka_element_classes_info_inline_impl.cc
+ common/aka_error.cc
+ common/aka_error.hh
+ common/aka_event_handler_manager.hh
+ common/aka_extern.cc
+ common/aka_fwd.hh
+ common/aka_grid_dynamic.hh
+ common/aka_math.cc
+ common/aka_math.hh
+ common/aka_math_tmpl.hh
+ common/aka_memory.cc
+ common/aka_memory.hh
+ common/aka_memory_inline_impl.cc
+ common/aka_random_generator.hh
+ common/aka_safe_enum.hh
+ common/aka_static_memory.cc
+ common/aka_static_memory.hh
+ common/aka_static_memory_inline_impl.cc
+ common/aka_static_memory_tmpl.hh
+ common/aka_typelist.hh
+ common/aka_types.hh
+ common/aka_visitor.hh
+ common/aka_voigthelper.hh
+ common/aka_voigthelper.cc
+
+ fe_engine/element_class.cc
+ fe_engine/element_class.hh
+ fe_engine/element_class_tmpl.hh
+ fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
+ fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
+ fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
+ fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
+ fe_engine/element_classes/element_class_point_1_inline_impl.cc
+ fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
+ fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
+ fe_engine/element_classes/element_class_segment_2_inline_impl.cc
+ fe_engine/element_classes/element_class_segment_3_inline_impl.cc
+ fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
+ fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
+ fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
+ fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
+
+ fe_engine/fe_engine.cc
+ fe_engine/fe_engine.hh
+ fe_engine/fe_engine_inline_impl.cc
+ fe_engine/fe_engine_template.hh
+ fe_engine/fe_engine_template_tmpl.hh
+ fe_engine/geometrical_element.cc
+ fe_engine/integration_element.cc
+ fe_engine/integrator.hh
+ fe_engine/integrator_gauss.hh
+ fe_engine/integrator_gauss_inline_impl.cc
+ fe_engine/interpolation_element.cc
+ fe_engine/interpolation_element_tmpl.hh
+ fe_engine/integration_point.hh
+ fe_engine/shape_functions.hh
+ fe_engine/shape_functions_inline_impl.cc
+ fe_engine/shape_lagrange.cc
+ fe_engine/shape_lagrange.hh
+ fe_engine/shape_lagrange_inline_impl.cc
+ fe_engine/shape_linked.cc
+ fe_engine/shape_linked.hh
+ fe_engine/shape_linked_inline_impl.cc
+ fe_engine/element.hh
+
+ io/dumper/dumpable.hh
+ io/dumper/dumpable.cc
+ io/dumper/dumpable_dummy.hh
+ io/dumper/dumpable_inline_impl.hh
+ io/dumper/dumper_field.hh
+ io/dumper/dumper_material_padders.hh
+ io/dumper/dumper_filtered_connectivity.hh
+ io/dumper/dumper_element_partition.hh
+
+ io/mesh_io.cc
+ io/mesh_io.hh
+ io/mesh_io/mesh_io_abaqus.cc
+ io/mesh_io/mesh_io_abaqus.hh
+ io/mesh_io/mesh_io_diana.cc
+ io/mesh_io/mesh_io_diana.hh
+ io/mesh_io/mesh_io_msh.cc
+ io/mesh_io/mesh_io_msh.hh
+ io/model_io.cc
+ io/model_io.hh
+
+ io/parser/algebraic_parser.hh
+ io/parser/input_file_parser.hh
+ io/parser/parsable.cc
+ io/parser/parsable.hh
+ io/parser/parsable_tmpl.hh
+ io/parser/parser.cc
+ io/parser/parser_real.cc
+ io/parser/parser_random.cc
+ io/parser/parser_types.cc
+ io/parser/parser_input_files.cc
+ io/parser/parser.hh
+ io/parser/parser_tmpl.hh
+ io/parser/parser_grammar_tmpl.hh
+ io/parser/cppargparse/cppargparse.hh
+ io/parser/cppargparse/cppargparse.cc
+ io/parser/cppargparse/cppargparse_tmpl.hh
+
+ mesh/element_group.cc
+ mesh/element_group.hh
+ mesh/element_group_inline_impl.cc
+ mesh/element_type_map.hh
+ mesh/element_type_map_tmpl.hh
+ mesh/element_type_map_filter.hh
+ mesh/group_manager.cc
+ mesh/group_manager.hh
+ mesh/group_manager_inline_impl.cc
+ mesh/mesh.cc
+ mesh/mesh.hh
+ mesh/mesh_accessor.hh
+ mesh/mesh_events.hh
+ mesh/mesh_filter.hh
+ mesh/mesh_data.cc
+ mesh/mesh_data.hh
+ mesh/mesh_data_tmpl.hh
+ mesh/mesh_inline_impl.cc
+ mesh/node_group.cc
+ mesh/node_group.hh
+ mesh/node_group_inline_impl.cc
+
+ mesh_utils/mesh_partition.cc
+ mesh_utils/mesh_partition.hh
+ mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
+ mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
+ mesh_utils/mesh_partition/mesh_partition_scotch.hh
+ mesh_utils/mesh_utils_pbc.cc
+ mesh_utils/mesh_utils.cc
+ mesh_utils/mesh_utils.hh
+ mesh_utils/mesh_utils_inline_impl.cc
+ mesh_utils/global_ids_updater.hh
+ mesh_utils/global_ids_updater.cc
+ mesh_utils/global_ids_updater_inline_impl.cc
+
+ model/boundary_condition.hh
+ model/boundary_condition_functor.hh
+ model/boundary_condition_functor_inline_impl.cc
+ model/boundary_condition_tmpl.hh
+ model/integration_scheme/generalized_trapezoidal.hh
+ model/integration_scheme/generalized_trapezoidal_inline_impl.cc
+ model/integration_scheme/integration_scheme_1st_order.hh
+ model/integration_scheme/integration_scheme_2nd_order.hh
+ model/integration_scheme/newmark-beta.hh
+ model/integration_scheme/newmark-beta_inline_impl.cc
+ model/model.cc
+ model/model.hh
+ model/model_inline_impl.cc
+
+ model/solid_mechanics/material.cc
+ model/solid_mechanics/material.hh
+ model/solid_mechanics/material_inline_impl.cc
+ model/solid_mechanics/material_selector.hh
+ model/solid_mechanics/material_selector_tmpl.hh
+ model/solid_mechanics/materials/internal_field.hh
+ model/solid_mechanics/materials/internal_field_tmpl.hh
+ model/solid_mechanics/materials/random_internal_field.hh
+ model/solid_mechanics/materials/random_internal_field_tmpl.hh
+ model/solid_mechanics/solid_mechanics_model.cc
+ model/solid_mechanics/solid_mechanics_model.hh
+ model/solid_mechanics/solid_mechanics_model_inline_impl.cc
+ model/solid_mechanics/solid_mechanics_model_mass.cc
+ model/solid_mechanics/solid_mechanics_model_material.cc
+ model/solid_mechanics/solid_mechanics_model_tmpl.hh
+ model/solid_mechanics/solid_mechanics_model_event_handler.hh
+ model/solid_mechanics/materials/plane_stress_toolbox.hh
+ model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
+
+
+ model/solid_mechanics/materials/material_core_includes.hh
+ model/solid_mechanics/materials/material_elastic.cc
+ model/solid_mechanics/materials/material_elastic.hh
+ model/solid_mechanics/materials/material_elastic_inline_impl.cc
+ model/solid_mechanics/materials/material_thermal.cc
+ model/solid_mechanics/materials/material_thermal.hh
+ model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
+ model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
+ model/solid_mechanics/materials/material_elastic_orthotropic.cc
+ model/solid_mechanics/materials/material_elastic_orthotropic.hh
+ model/solid_mechanics/materials/material_damage/material_damage.hh
+ model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
+ model/solid_mechanics/materials/material_damage/material_marigo.cc
+ model/solid_mechanics/materials/material_damage/material_marigo.hh
+ model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
+ model/solid_mechanics/materials/material_damage/material_mazars.cc
+ model/solid_mechanics/materials/material_damage/material_mazars.hh
+ model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
+ model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
+ model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
+ model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
+ model/solid_mechanics/materials/material_plastic/material_plastic.cc
+ model/solid_mechanics/materials/material_plastic/material_plastic.hh
+ model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
+ model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
+ model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
+ model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
+ model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
+ model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
+
+ model/common/neighborhood_base.hh
+ model/common/neighborhood_base.cc
+ model/common/neighborhood_base_inline_impl.cc
+
+ model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
+ model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
+ model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
+
+ solver/solver.cc
+ solver/solver.hh
+ solver/solver_inline_impl.cc
+ solver/sparse_matrix.cc
+ solver/sparse_matrix.hh
+ solver/sparse_matrix_inline_impl.cc
+ solver/static_solver.hh
+ solver/static_solver.cc
+
+ synchronizer/communication_buffer.hh
+ synchronizer/communication_buffer_inline_impl.cc
+ synchronizer/data_accessor.cc
+ synchronizer/data_accessor.hh
+ synchronizer/data_accessor_inline_impl.cc
+ synchronizer/distributed_synchronizer.cc
+ synchronizer/distributed_synchronizer.hh
+ synchronizer/distributed_synchronizer_tmpl.hh
+ synchronizer/dof_synchronizer.cc
+ synchronizer/dof_synchronizer.hh
+ synchronizer/dof_synchronizer_inline_impl.cc
+ synchronizer/filtered_synchronizer.cc
+ synchronizer/filtered_synchronizer.hh
+ synchronizer/pbc_synchronizer.cc
+ synchronizer/pbc_synchronizer.hh
+ synchronizer/real_static_communicator.hh
+ synchronizer/static_communicator.cc
+ synchronizer/static_communicator.hh
+ synchronizer/static_communicator_dummy.hh
+ synchronizer/static_communicator_inline_impl.hh
+ synchronizer/synchronizer.cc
+ synchronizer/synchronizer.hh
+ synchronizer/synchronizer_registry.cc
+ synchronizer/synchronizer_registry.hh
+ synchronizer/grid_synchronizer.cc
+ synchronizer/grid_synchronizer.hh
+
+ )
+
+package_declare_elements(core
+ ELEMENT_TYPES
+ _point_1
+ _segment_2
+ _segment_3
+ _triangle_3
+ _triangle_6
+ _quadrangle_4
+ _quadrangle_8
+ _tetrahedron_4
+ _tetrahedron_10
+ _pentahedron_6
+ _pentahedron_15
+ _hexahedron_8
+ _hexahedron_20
+ KIND regular
+ GEOMETRICAL_TYPES
+ _gt_point
+ _gt_segment_2
+ _gt_segment_3
+ _gt_triangle_3
+ _gt_triangle_6
+ _gt_quadrangle_4
+ _gt_quadrangle_8
+ _gt_tetrahedron_4
+ _gt_tetrahedron_10
+ _gt_hexahedron_8
+ _gt_hexahedron_20
+ _gt_pentahedron_6
+ _gt_pentahedron_15
+ INTERPOLATION_TYPES
+ _itp_lagrange_point_1
+ _itp_lagrange_segment_2
+ _itp_lagrange_segment_3
+ _itp_lagrange_triangle_3
+ _itp_lagrange_triangle_6
+ _itp_lagrange_quadrangle_4
+ _itp_serendip_quadrangle_8
+ _itp_lagrange_tetrahedron_4
+ _itp_lagrange_tetrahedron_10
+ _itp_lagrange_hexahedron_8
+ _itp_serendip_hexahedron_20
+ _itp_lagrange_pentahedron_6
+ _itp_lagrange_pentahedron_15
+ GEOMETRICAL_SHAPES
+ _gst_point
+ _gst_triangle
+ _gst_square
+ _gst_prism
+ GAUSS_INTEGRATION_TYPES
+ _git_point
+ _git_segment
+ _git_triangle
+ _git_tetrahedron
+ _git_pentahedron
+ INTERPOLATION_KIND _itk_lagrangian
+ FE_ENGINE_LISTS
+ gradient_on_integration_points
+ interpolate_on_integration_points
+ interpolate
+ compute_normals_on_integration_points
+ inverse_map
+ contains
+ compute_shapes
+ compute_shapes_derivatives
+ get_shapes_derivatives
+ )
+
+package_declare_material_infos(core
+ LIST AKANTU_CORE_MATERIAL_LIST
+ INCLUDE material_core_includes.hh
+ )
+
+package_declare_documentation_files(core
+ manual.sty
+ manual.cls
+ manual.tex
+ manual-macros.sty
+ manual-titlepages.tex
+ manual-introduction.tex
+ manual-gettingstarted.tex
+ manual-io.tex
+ manual-feengine.tex
+ manual-solidmechanicsmodel.tex
+ manual-constitutive-laws.tex
+ manual-lumping.tex
+ manual-elements.tex
+ manual-appendix-elements.tex
+ manual-appendix-materials.tex
+ manual-appendix-packages.tex
+ manual-backmatter.tex
+ manual-bibliography.bib
+ manual-bibliographystyle.bst
+
+ figures/bc_and_ic_example.pdf
+ figures/boundary.pdf
+ figures/boundary.svg
+ figures/dirichlet.pdf
+ figures/dirichlet.svg
+ figures/doc_wheel.pdf
+ figures/doc_wheel.svg
+ figures/dynamic_analysis.png
+ figures/explicit_dynamic.pdf
+ figures/explicit_dynamic.svg
+ figures/static.pdf
+ figures/static.svg
+ figures/hooke_law.pdf
+ figures/hot-point-1.png
+ figures/hot-point-2.png
+ figures/implicit_dynamic.pdf
+ figures/implicit_dynamic.svg
+ figures/insertion.pdf
+ figures/interpolate.pdf
+ figures/interpolate.svg
+ figures/problemDomain.pdf_tex
+ figures/problemDomain.pdf
+ figures/static_analysis.png
+ figures/stress_strain_el.pdf
+ figures/tangent.pdf
+ figures/tangent.svg
+ figures/vectors.pdf
+ figures/vectors.svg
+
+ figures/stress_strain_neo.pdf
+ figures/visco_elastic_law.pdf
+ figures/isotropic_hardening_plasticity.pdf
+ figures/stress_strain_visco.pdf
+
+ figures/elements/hexahedron_8.pdf
+ figures/elements/hexahedron_8.svg
+ figures/elements/quadrangle_4.pdf
+ figures/elements/quadrangle_4.svg
+ figures/elements/quadrangle_8.pdf
+ figures/elements/quadrangle_8.svg
+ figures/elements/segment_2.pdf
+ figures/elements/segment_2.svg
+ figures/elements/segment_3.pdf
+ figures/elements/segment_3.svg
+ figures/elements/tetrahedron_10.pdf
+ figures/elements/tetrahedron_10.svg
+ figures/elements/tetrahedron_4.pdf
+ figures/elements/tetrahedron_4.svg
+ figures/elements/triangle_3.pdf
+ figures/elements/triangle_3.svg
+ figures/elements/triangle_6.pdf
+ figures/elements/triangle_6.svg
+ figures/elements/xtemp.pdf
+ )
+
+package_declare_documentation(core
+ "This package is the core engine of \\akantu. It depends on:"
+ "\\begin{itemize}"
+ "\\item A C++ compiler (\\href{http://gcc.gnu.org/}{GCC} >= 4, or \\href{https://software.intel.com/en-us/intel-compilers}{Intel})."
+ "\\item The cross-platform, open-source \\href{http://www.cmake.org/}{CMake} build system."
+ "\\item The \\href{http://www.boost.org/}{Boost} C++ portable libraries."
+ "\\item The \\href{http://www.zlib.net/}{zlib} compression library."
+ "\\end{itemize}"
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ "\\begin{command}"
+ " > sudo apt-get install cmake libboost-dev zlib1g-dev g++"
+ "\\end{command}"
+ ""
+ "Under Mac OS X the installation requires the following steps:"
+ "\\begin{itemize}"
+ "\\item Install Xcode"
+ "\\item Install the command line tools."
+ "\\item Install the MacPorts project which allows to automatically"
+ "download and install opensource packages."
+ "\\end{itemize}"
+ "Then the following commands should be typed in a terminal:"
+ "\\begin{command}"
+ " > sudo port install cmake gcc48 boost"
+ "\\end{command}"
+ )
+
+find_program(READLINK_COMMAND readlink)
+find_program(ADDR2LINE_COMMAND addr2line)
+find_program(PATCH_COMMAND patch)
+mark_as_advanced(READLINK_COMMAND)
+mark_as_advanced(ADDR2LINE_COMMAND)
+
+include(CheckFunctionExists)
+check_function_exists(clock_gettime _clock_gettime)
+
+include(CheckCXXSymbolExists)
+check_cxx_symbol_exists(strdup cstring AKANTU_HAS_STRDUP)
+
+if(NOT _clock_gettime)
+ set(AKANTU_USE_OBSOLETE_GETTIMEOFDAY ON CACHE INTERNAL "" FORCE)
+else()
+ set(AKANTU_USE_OBSOLETE_GETTIMEOFDAY OFF CACHE INTERNAL "" FORCE)
+endif()
diff --git a/packages/core_cxx11.cmake b/packages/core_cxx11.cmake
new file mode 100644
index 000000000..95964b330
--- /dev/null
+++ b/packages/core_cxx11.cmake
@@ -0,0 +1,67 @@
+#===============================================================================
+# @file 00_core_cxx11.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon May 06 2013
+# @date last modification: Thu Jul 03 2014
+#
+# @brief C++11 addition to the core package
+#
+# @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(AKANTU_CXX11_FLAGS)
+ package_declare(core_cxx11 ADVANCED
+ DESCRIPTION "C++ 11 additions for Akantu core" DEFAULT ON
+ COMPILE_FLAGS "${AKANTU_CXX11_FLAGS}")
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.6")
+ set(AKANTU_CORE_CXX11 OFF CACHE BOOL "C++ 11 additions for Akantu core - not supported by the selected compiler" FORCE)
+ endif()
+ endif()
+else()
+ package_declare(core_cxx11 ADVANCED
+ DESCRIPTION "C++ 11 additions for Akantu core"
+ DEFAULT OFF
+ NOT_OPTIONAL
+ COMPILE_FLAGS "")
+endif()
+
+package_declare_sources(core_cxx11
+ common/aka_point.hh
+ common/aka_ball.cc
+ common/aka_plane.hh
+ common/aka_polytope.hh
+ common/aka_ball.hh
+ common/aka_timer.hh
+ common/aka_tree.hh
+ common/aka_bounding_box.hh
+ common/aka_bounding_box.cc
+ common/aka_geometry.hh
+ common/aka_geometry.cc
+ model/solid_mechanics/solid_mechanics_model_element.hh
+ )
+
+
+package_declare_documentation(core_cxx11
+ "This option activates some features of the C++11 standard. This is usable with GCC>=4.7 or Intel>=13.")
+
diff --git a/packages/cpparray.cmake b/packages/cpparray.cmake
new file mode 100644
index 000000000..c5805141a
--- /dev/null
+++ b/packages/cpparray.cmake
@@ -0,0 +1,64 @@
+#===============================================================================
+# @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
new file mode 100644
index 000000000..d58ff002c
--- /dev/null
+++ b/packages/damage_non_local.cmake
@@ -0,0 +1,81 @@
+#===============================================================================
+# @file 25_damage_non_local.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Fri Jun 15 2012
+# @date last modification: Fri Jun 13 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(damage_non_local
+ DESCRIPTION "Package for Non-local damage constitutives laws Akantu"
+ DEPENDS lapack)
+
+package_declare_sources(damage_non_local
+ model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
+ model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
+ model/solid_mechanics/materials/material_damage/material_marigo_non_local_inline_impl.cc
+ model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
+ model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
+
+ model/solid_mechanics/materials/material_non_local.hh
+ model/solid_mechanics/materials/material_non_local_includes.hh
+ model/solid_mechanics/materials/material_non_local_inline_impl.cc
+ model/solid_mechanics/materials/material_non_local.cc
+
+ model/solid_mechanics/materials/weight_functions/base_weight_function.hh
+ model/solid_mechanics/materials/weight_functions/base_weight_function_inline_impl.cc
+ model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
+ model/solid_mechanics/materials/weight_functions/damaged_weight_function_inline_impl.cc
+ model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
+ model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function_inline_impl.cc
+ model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
+ model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function_inline_impl.cc
+ model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
+ model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
+ model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
+
+ model/common/non_local_toolbox/non_local_manager.hh
+ model/common/non_local_toolbox/non_local_manager.cc
+ model/common/non_local_toolbox/non_local_manager_inline_impl.cc
+ model/common/non_local_toolbox/non_local_neighborhood_base.hh
+ model/common/non_local_toolbox/non_local_neighborhood_base.cc
+ model/common/non_local_toolbox/non_local_neighborhood.hh
+ model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
+ model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
+
+ )
+
+package_declare_material_infos(damage_non_local
+ LIST AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST
+ INCLUDE material_non_local_includes.hh
+ )
+
+package_declare_documentation_files(damage_non_local
+ manual-constitutive-laws-non_local.tex
+ manual-appendix-materials-non-local.tex)
+
+package_declare_documentation(damage_non_local
+"This package activates the non local damage feature of AKANTU"
+"")
diff --git a/packages/documentation_doxygen.cmake b/packages/documentation_doxygen.cmake
new file mode 100644
index 000000000..2ba19d387
--- /dev/null
+++ b/packages/documentation_doxygen.cmake
@@ -0,0 +1,47 @@
+#===============================================================================
+# @file 00_documentation_doxygen.cmake
+#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+#
+# @date creation: Tue Jun 10 2014
+# @date last modification: Tue Jun 24 2014
+#
+# @brief Doxygen documentation of the code
+#
+# @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(documentation_doxygen
+ DESCRIPTION "Build source documentation using Doxygen.")
+
+package_declare_documentation(documentation_doxygen
+ "This generates the Doxygen documantation of the source code."
+ "It depends on:"
+ "\\begin{itemize}"
+ "\\item \\href{http://www.stack.nl/~dimitri/doxygen/}{Doxygen} an automated source code documentations system."
+ "\\item Optional: \\href{http://www.graphviz.org/}{Graphviz} to generate the dependencies graph"
+ "\\end{itemize}"
+ ""
+ "Under Ubuntu (14.04 LTS), the installation of the dependencies can be performed using the following command:"
+ "\\begin{command}"
+ " > sudo apt-get install doxygen"
+ " > sudo apt-get install graphviz"
+ "\\end{command}"
+)
\ No newline at end of file
diff --git a/packages/documentation_manual.cmake b/packages/documentation_manual.cmake
new file mode 100644
index 000000000..a649049a7
--- /dev/null
+++ b/packages/documentation_manual.cmake
@@ -0,0 +1,40 @@
+#===============================================================================
+# @file 00_documentation_manual.cmake
+#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+#
+# @date creation: Tue Jun 10 2014
+# @date last modification: Thu Jul 03 2014
+#
+# @brief Akantu's manual package
+#
+# @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(documentation_manual
+ DESCRIPTION "Build the user manual.")
+
+package_declare_documentation(documentation_manual
+"This package alows to compile the user manual in the build folder \\shellcode{build/doc/manual/manual.pdf}."
+""
+"Under Ubuntu (14.04 LTS), the installation of the dependencies can be performed using the following command:"
+"\\begin{command}"
+" > sudo apt-get install install rubber texlive texlive-science texlive-latex-extra"
+"\\end{command}")
\ No newline at end of file
diff --git a/packages/embedded.cmake b/packages/embedded.cmake
new file mode 100644
index 000000000..920125ff1
--- /dev/null
+++ b/packages/embedded.cmake
@@ -0,0 +1,56 @@
+#===============================================================================
+# @file embedded.cmake
+#
+# @author Lucas Frérot <lucas.frerot@epfl.ch>
+#
+# @date creation: Tue Oct 16 2012
+# @date last modification: Thu Jun 12 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(embedded
+ DESCRIPTION "Add support for the embedded solid mechanics model"
+ DEPENDS CGAL)
+
+package_declare_sources(embedded
+ model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc
+ model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.hh
+ model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.cc
+ model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
+ model/solid_mechanics/materials/material_embedded/embedded_internal_field.hh
+ model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
+ model/solid_mechanics/materials/material_embedded/material_reinforcement.cc
+ model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
+ model/solid_mechanics/materials/material_embedded/material_reinforcement_inline_impl.cc
+ model/solid_mechanics/materials/material_embedded/material_reinforcement_template.hh
+ model/solid_mechanics/materials/material_embedded/material_reinforcement_template_tmpl.hh
+ )
+
+package_declare_material_infos(embedded
+ LIST AKANTU_EMBEDDED_MATERIAL_LIST
+ INCLUDE material_embedded_includes.hh
+ )
+
+package_declare_documentation(embedded
+"This package allows the use of the embedded model in solid mechanics. This package depends on the CGAL package."
+)
diff --git a/packages/heat_transfer.cmake b/packages/heat_transfer.cmake
new file mode 100644
index 000000000..4961e2a2a
--- /dev/null
+++ b/packages/heat_transfer.cmake
@@ -0,0 +1,47 @@
+#===============================================================================
+# @file 10_heat_transfer.cmake
+#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+#
+# @date creation: Mon Nov 21 2011
+# @date last modification: Thu Jun 12 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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
new file mode 100644
index 000000000..30211029c
--- /dev/null
+++ b/packages/implicit.cmake
@@ -0,0 +1,43 @@
+#===============================================================================
+# @file 50_implicit.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Tue Oct 16 2012
+# @date last modification: Thu Jun 12 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(implicit META
+ DESCRIPTION "Add support for implicit time scheme"
+ DEPENDS scotch mumps)
+
+package_declare_documentation(implicit
+ "This package activates the sparse solver necessary to solve implicitely static/dynamic"
+ "finite element problems."
+ "It depends on:"
+ "\\begin{itemize}"
+ " \\item \\href{http://mumps.enseeiht.fr/}{MUMPS}, a parallel sparse direct solver."
+ " \\item \\href{http://www.labri.fr/perso/pelegrin/scotch/}{Scotch}, a graph partitioner."
+ "\\end{itemize}"
+ )
\ No newline at end of file
diff --git a/packages/iohelper.cmake b/packages/iohelper.cmake
new file mode 100644
index 000000000..62e0b7248
--- /dev/null
+++ b/packages/iohelper.cmake
@@ -0,0 +1,69 @@
+#===============================================================================
+# @file 90_iohelper.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Tue Nov 29 2011
+# @date last modification: Tue Sep 02 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(IOHelper EXTERNAL
+ DESCRIPTION "Add IOHelper support in akantu"
+ SYSTEM OFF third-party/cmake/iohelper.cmake
+ DEFAULT ON)
+
+set(_version "master")
+package_add_third_party_script_variable(IOHelper
+ IOHELPER_VERSION ${_version})
+package_add_third_party_script_variable(IOHelper
+ IOHELPER_GIT "https://git.epfl.ch/repo/iohelper.git")
+package_add_third_party_script_variable(Scotch
+ IOHELPER_ARCHIVE "iohelper_${_version}.tar.gz")
+
+package_declare_sources(IOHelper
+ io/dumper/dumpable_iohelper.hh
+ io/dumper/dumper_iohelper.hh
+ io/dumper/dumper_iohelper.cc
+ io/dumper/dumper_paraview.hh
+ io/dumper/dumper_text.cc
+ io/dumper/dumper_text.hh
+ io/dumper/dumper_paraview.cc
+ io/dumper/dumper_homogenizing_field.hh
+ io/dumper/dumper_type_traits.hh
+ io/dumper/dumper_compute.hh
+ io/dumper/dumper_nodal_field.hh
+ io/dumper/dumper_quadrature_point_iterator.hh
+ io/dumper/dumper_variable.hh
+ io/dumper/dumper_padding_helper.hh
+ io/dumper/dumper_elemental_field.hh
+ io/dumper/dumper_element_iterator.hh
+ io/dumper/dumper_internal_material_field.hh
+ io/dumper/dumper_generic_elemental_field.hh
+ io/dumper/dumper_generic_elemental_field_tmpl.hh
+ )
+
+package_declare_documentation(IOHelper
+ "This package activates the IOHelper facilities withing Akantu. This is mandatory if you want to be able to output Paraview files"
+ "as well as any Dumper within Akantu."
+ )
diff --git a/packages/lapack.cmake b/packages/lapack.cmake
new file mode 100644
index 000000000..41e92649b
--- /dev/null
+++ b/packages/lapack.cmake
@@ -0,0 +1,42 @@
+#===============================================================================
+# @file 89_lapack.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Fri Oct 19 2012
+# @date last modification: Thu Jun 12 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(LAPACK EXTERNAL
+ DESCRIPTION "Use LAPACK for arithmetic operations"
+ EXTRA_PACKAGE_OPTIONS LANGUAGE Fortran)
+
+package_declare_documentation(LAPACK
+ "This package provides access to a LAPACK implementation."
+ ""
+ "Under Ubuntu (14.04 LTS), the installation can be performed using the following command:"
+ "\\begin{command}"
+ " > sudo apt-get install libatlas-base-dev"
+ "\\end{command}"
+ )
diff --git a/packages/mpi.cmake b/packages/mpi.cmake
new file mode 100644
index 000000000..9fcbab90a
--- /dev/null
+++ b/packages/mpi.cmake
@@ -0,0 +1,164 @@
+#===============================================================================
+# @file 80_mpi.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Nov 21 2011
+# @date last modification: Sat Jun 14 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(MPI EXTERNAL
+ DESCRIPTION "Add MPI support in akantu"
+ EXTRA_PACKAGE_OPTIONS PREFIX MPI_C MPI
+ DEPENDS scotch)
+
+package_declare_sources(MPI
+ synchronizer/mpi_type_wrapper.hh
+ synchronizer/static_communicator_mpi.cc
+ synchronizer/static_communicator_mpi_inline_impl.hh
+ synchronizer/static_communicator_mpi.hh
+ )
+
+
+function(add_extra_mpi_options)
+ unset(MPI_ID CACHE)
+ package_get_include_dir(MPI _include_dir)
+ foreach(_inc_dir ${_include_dir})
+ if(EXISTS "${_inc_dir}/mpi.h")
+ if(NOT MPI_ID)
+ file(STRINGS "${_inc_dir}/mpi.h" _mpi_version REGEX "#define MPI_(SUB)?VERSION .*")
+ foreach(_ver ${_mpi_version})
+ string(REGEX MATCH "MPI_(VERSION|SUBVERSION) *([0-9]+)" _tmp "${_ver}")
+ set(_mpi_${CMAKE_MATCH_1} ${CMAKE_MATCH_2})
+ endforeach()
+ set(MPI_STD_VERSION "${_mpi_VERSION}.${_mpi_SUBVERSION}" CACHE INTERNAL "")
+ endif()
+
+ if(NOT MPI_ID)
+ # check if openmpi
+ file(STRINGS "${_inc_dir}/mpi.h" _ompi_version REGEX "#define OMPI_.*_VERSION .*")
+ if(_ompi_version)
+ set(MPI_ID "OpenMPI" CACHE INTERNAL "")
+ foreach(_version ${_ompi_version})
+ string(REGEX MATCH "OMPI_(.*)_VERSION (.*)" _tmp "${_version}")
+ if(_tmp)
+ set(MPI_VERSION_${CMAKE_MATCH_1} ${CMAKE_MATCH_2})
+ endif()
+ endforeach()
+ set(MPI_ID_VERSION "${MPI_VERSION_MAJOR}.${MPI_VERSION_MINOR}.${MPI_VERSION_RELEASE}" CACHE INTERNAL "")
+ endif()
+ endif()
+
+ if(NOT MPI_ID)
+ # check if intelmpi
+ file(STRINGS "${_inc_dir}/mpi.h" _impi_version REGEX "#define I_MPI_VERSION .*")
+ if(_impi_version)
+ set(MPI_ID "IntelMPI" CACHE INTERNAL "")
+ string(REGEX MATCH "I_MPI_VERSION \"(.*)\"" _tmp "${_impi_version}")
+ if(_tmp)
+ set(MPI_ID_VERSION "${CMAKE_MATCH_1}" CACHE INTERNAL "")
+ endif()
+ endif()
+ endif()
+
+ if(NOT MPI_ID)
+ # check if mvapich2
+ file(STRINGS "${_inc_dir}/mpi.h" _mvapich2_version REGEX "#define MVAPICH2_VERSION .*")
+ if(_mvapich2_version)
+ set(MPI_ID "MPVAPICH2" CACHE INTERNAL "")
+ string(REGEX MATCH "MVAPICH2_VERSION \"(.*)\"" _tmp "${_mvapich2_version}")
+ if(_tmp)
+ set(MPI_ID_VERSION "${CMAKE_MATCH_1}" CACHE INTERNAL "")
+ endif()
+ endif()
+ endif()
+
+ if(NOT MPI_ID)
+ # check if mpich (mpich as to be checked after all the mpi that derives from it)
+ file(STRINGS "${_inc_dir}/mpi.h" _mpich_version REGEX "#define MPICH_VERSION .*")
+ if(_mpich_version)
+ set(MPI_ID "MPICH" CACHE INTERNAL "")
+ string(REGEX MATCH "I_MPI_VERSION \"(.*)\"" _tmp "${_mpich_version}")
+ if(_tmp)
+ set(MPI_ID_VERSION "${CMAKE_MATCH_1}" CACHE INTERNAL "")
+ endif()
+ endif()
+ endif()
+ endif()
+ endforeach()
+
+ if(MPI_ID STREQUAL "IntelMPI" OR
+ MPI_ID STREQUAL "MPICH" OR
+ MPI_ID STREQUAL "MVAPICH2")
+ set(_flags "-DMPICH_IGNORE_CXX_SEEK")
+ elseif(MPI_ID STREQUAL "OpenMPI")
+ set(_flags "-DOMPI_SKIP_MPICXX")
+
+ package_is_activated(core_cxx11 _act)
+ if(_act)
+ set( _flags "${_flags} -Wno-literal-suffix")
+ endif()
+ endif()
+
+ include(FindPackageMessage)
+ if(MPI_FOUND)
+ find_package_message(MPI "MPI ID: ${MPI_ID} ${MPI_ID_VERSION} (MPI standard ${MPI_STD_VERSION})" "${MPI_STD_VERSION}")
+ endif()
+
+ set(MPI_EXTRA_COMPILE_FLAGS "${_flags}" CACHE STRING "Extra flags for MPI" FORCE)
+ mark_as_advanced(MPI_EXTRA_COMPILE_FLAGS)
+
+ #package_get_source_files(MPI _srcs _pub _priv)
+ #list(APPEND _srcs "common/aka_error.cc")
+
+ #set_property(SOURCE ${_srcs} PROPERTY COMPILE_FLAGS "${_flags}")
+ package_set_compile_flags(MPI ${_flags})
+endfunction()
+
+package_on_enabled_script(MPI
+ "
+add_extra_mpi_options()
+
+get_cmake_property(_all_vars VARIABLES)
+foreach(_var \${_all_vars})
+ if(_var MATCHES \"^MPI_.*\")
+ mark_as_advanced(\${_var})
+ endif()
+endforeach()
+"
+)
+
+package_declare_documentation(MPI
+ "This is a meta package providing access to MPI."
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ "\\begin{command}"
+ " > sudo apt-get install libopenmpi-dev"
+ "\\end{command}"
+ ""
+ "Under Mac OS X the installation requires the following steps:"
+ "\\begin{command}"
+ " > sudo port install mpich-devel"
+ "\\end{command}"
+ )
diff --git a/packages/mumps.cmake b/packages/mumps.cmake
new file mode 100644
index 000000000..7c47c5056
--- /dev/null
+++ b/packages/mumps.cmake
@@ -0,0 +1,82 @@
+#===============================================================================
+# @file 85_mumps.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Nov 21 2011
+# @date last modification: Mon Sep 15 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+package_declare(Mumps EXTERNAL
+ DESCRIPTION "Add Mumps support in akantu"
+ SYSTEM ON third-party/cmake/mumps.cmake
+ )
+
+package_declare_sources(Mumps
+ solver/solver_mumps.cc
+ solver/solver_mumps.hh
+ )
+
+package_get_option_name(parallel _par_option)
+if(${_par_option})
+ package_set_find_package_extra_options(Mumps ARGS COMPONENTS "parallel")
+ package_add_third_party_script_variable(Mumps MUMPS_TYPE "par")
+else()
+ package_set_find_package_extra_options(Mumps ARGS COMPONENTS "sequential")
+ package_add_third_party_script_variable(Mumps MUMPS_TYPE "seq")
+endif()
+
+package_use_system(Mumps _use_system)
+if(NOT _use_system)
+ enable_language(Fortran)
+
+ set(AKANTU_USE_MUMPS_VERSION "4.10.0" CACHE STRING "Default Mumps version to compile")
+ mark_as_advanced(AKANTU_USE_MUMPS_VERSION)
+ set_property(CACHE AKANTU_USE_MUMPS_VERSION PROPERTY STRINGS "4.9.2" "4.10.0" "5.0.0")
+
+ package_get_option_name(MPI _mpi_option)
+ if(${_mpi_option})
+ package_add_dependencies(Mumps ScaLAPACK MPI)
+ endif()
+
+ package_add_dependencies(Mumps Scotch BLAS)
+endif()
+
+package_declare_documentation(Mumps
+ "This package enables the \\href{http://mumps.enseeiht.fr/}{MUMPS} parallel direct solver for sparce matrices."
+ "This is necessary to solve static or implicit problems."
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ ""
+ "\\begin{command}"
+ " > sudo apt-get install libmumps-seq-dev # for sequential"
+ " > sudo apt-get install libmumps-dev # for parallel"
+ "\\end{command}"
+ ""
+ "Under Mac OS X the installation requires the following steps:"
+ "\\begin{command}"
+ " > sudo port install mumps"
+ "\\end{command}"
+ ""
+ "If you activate the advanced option AKANTU\\_USE\\_THIRD\\_PARTY\\_MUMPS the make system of akantu can automatically compile MUMPS. For this you will have to download MUMPS from \\url{http://mumps.enseeiht.fr/} or \\url{http://graal.ens-lyon.fr/MUMPS} and place it in \\shellcode{<akantu source>/third-party}"
+ )
diff --git a/packages/nlopt.cmake b/packages/nlopt.cmake
new file mode 100644
index 000000000..bb397f123
--- /dev/null
+++ b/packages/nlopt.cmake
@@ -0,0 +1,83 @@
+#===============================================================================
+# @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..8be2ea82a
--- /dev/null
+++ b/packages/numpy.cmake
@@ -0,0 +1,27 @@
+# @file pythonlibs.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @brief package description for the python library
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(Numpy EXTERNAL DESCRIPTION "Akantu's numpy dependance check")
diff --git a/packages/optimization.cmake b/packages/optimization.cmake
new file mode 100644
index 000000000..1f331dbc1
--- /dev/null
+++ b/packages/optimization.cmake
@@ -0,0 +1,46 @@
+#===============================================================================
+# @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
new file mode 100644
index 000000000..cd5f985a5
--- /dev/null
+++ b/packages/parallel.cmake
@@ -0,0 +1,50 @@
+#===============================================================================
+# @file 50_parallel.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Tue Oct 16 2012
+# @date last modification: Wed Jun 11 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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
new file mode 100644
index 000000000..6e226adf7
--- /dev/null
+++ b/packages/petsc.cmake
@@ -0,0 +1,46 @@
+#===============================================================================
+# @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>
+#
+# @date Mon Nov 21 18:19:15 2011
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(PETSc EXTERNAL
+ DESCRIPTION "Add PETSc support in akantu"
+ EXTRA_PACKAGE_OPTIONS ARGS COMPONENTS C
+ DEPENDS parallel)
+
+
+package_declare_sources(petsc
+ solver/petsc_matrix.hh
+ solver/petsc_matrix.cc
+ solver/petsc_matrix_inline_impl.cc
+ solver/solver_petsc.hh
+ solver/solver_petsc.cc
+ solver/petsc_wrapper.hh
+ )
+
diff --git a/packages/python_interface.cmake b/packages/python_interface.cmake
new file mode 100644
index 000000000..f42968306
--- /dev/null
+++ b/packages/python_interface.cmake
@@ -0,0 +1,30 @@
+#===============================================================================
+# @file python_interface.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @brief package description for the python interface
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(python_interface
+ DESCRIPTION "Akantu's python interface"
+ DEPENDS PythonLibs)
diff --git a/packages/pythonlibs.cmake b/packages/pythonlibs.cmake
new file mode 100644
index 000000000..5b9c22444
--- /dev/null
+++ b/packages/pythonlibs.cmake
@@ -0,0 +1,42 @@
+#===============================================================================
+# @file pythonlibs.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @brief package description for the python library
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+set(Python_ADDITIONAL_VERSIONS 2.7)
+
+package_declare(PythonLibs EXTERNAL DESCRIPTION "Akantu's python interface"
+ DEPENDS numpy
+ EXTRA_PACKAGE_OPTIONS PREFIX PYTHON FOUND PYTHONLIBS_FOUND
+ )
+
+package_declare_sources(Pythonlibs
+ python/python_functor.cc
+ python/python_functor.hh
+ python/python_functor_inline_impl.cc
+ model/boundary_condition_python_functor.hh
+ model/boundary_condition_python_functor.cc
+ model/solid_mechanics/materials/material_python/material_python.cc
+ model/solid_mechanics/materials/material_python/material_python.hh
+ )
diff --git a/packages/qview.cmake b/packages/qview.cmake
new file mode 100644
index 000000000..81a3b4890
--- /dev/null
+++ b/packages/qview.cmake
@@ -0,0 +1,35 @@
+#===============================================================================
+# @file qview.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date Tue Nov 29 15:16:35 2011
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+package_declare(QVIEW EXTERNAL
+ DESCRIPTION "Add QView support in akantu")
+
+set(AKANTU_QVIEW_DEB_DEPEND
+ qview-client
+ )
diff --git a/packages/scalapack.cmake b/packages/scalapack.cmake
new file mode 100644
index 000000000..db263c4e5
--- /dev/null
+++ b/packages/scalapack.cmake
@@ -0,0 +1,42 @@
+#===============================================================================
+# @file scalapack.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Nov 21 2011
+# @date last modification: Mon Sep 15 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+package_declare(ScaLAPACK EXTERNAL
+ DESCRIPTION "Add ScaLAPACK support in akantu"
+ SYSTEM OFF third-party/cmake/scalapack.cmake
+ DEPENDS MPI
+ )
+
+
+package_add_third_party_script_variable(ScaLAPACK
+ SCALAPACK_VERSION "2.0.2")
+package_add_third_party_script_variable(ScaLAPACK
+ SCALAPACK_ARCHIVE "http://www.netlib.org/scalapack/scalapack-${SCALAPACK_VERSION}.tgz")
+package_add_third_party_script_variable(ScaLAPACK
+ SCALAPACK_ARCHIVE_HASH_2.0.2 "MD5=2f75e600a2ba155ed9ce974a1c4b536f")
diff --git a/packages/scotch.cmake b/packages/scotch.cmake
new file mode 100644
index 000000000..dad1b0ca6
--- /dev/null
+++ b/packages/scotch.cmake
@@ -0,0 +1,95 @@
+#===============================================================================
+# @file 90_scotch.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Nov 21 2011
+# @date last modification: Thu Jul 10 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+package_declare(Scotch EXTERNAL
+ DESCRIPTION "Add Scotch support in akantu"
+ SYSTEM ON third-party/cmake/scotch.cmake)
+
+package_declare_sources(Scotch
+ mesh_utils/mesh_partition/mesh_partition_scotch.cc
+ )
+
+package_add_third_party_script_variable(Scotch
+ SCOTCH_VERSION "5.1.12b")
+package_add_third_party_script_variable(Scotch
+ SCOTCH_ARCHIVE_HASH "MD5=e13b49be804755470b159d7052764dc0")
+package_add_third_party_script_variable(Scotch
+ SCOTCH_ARCHIVE "scotch_${SCOTCH_VERSION}_esmumps.tar.gz")
+package_add_third_party_script_variable(Scotch
+ SCOTCH_URL "https://gforge.inria.fr/frs/download.php/28978/scotch_${SCOTCH_VERSION}_esmumps.tar.gz")
+
+
+package_get_option_name(Scotch _opt_name)
+package_use_system(Scotch _system)
+if(${_opt_name} AND _system)
+ include(CheckTypeSize)
+
+ package_get_include_dir(Scotch _include_dir)
+ if(_include_dir)
+ set(CMAKE_EXTRA_INCLUDE_FILES stdio.h scotch.h)
+ set(CMAKE_REQUIRED_INCLUDES ${_include_dir})
+ check_type_size("SCOTCH_Num" SCOTCH_NUM)
+
+ if(SCOTCH_NUM AND NOT SCOTCH_NUM EQUAL AKANTU_INTEGER_SIZE)
+ math(EXPR _n "${AKANTU_INTEGER_SIZE} * 8")
+ message(SEND_ERROR "This version of Scotch cannot be used, it is compiled with the wrong size for SCOTCH_Num."
+ "Recompile Scotch with the define -DINTSIZE${_n}. The current scotch integer size is ${SCOTCH_NUM}")
+ endif()
+ endif()
+endif()
+
+package_declare_documentation(Scotch
+ "This package enables the use the \\href{http://www.labri.fr/perso/pelegrin/scotch/}{Scotch}"
+ "library in order to perform a graph partitioning leading to the domain"
+ "decomposition used within \\akantu"
+ ""
+ "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
+ "\\begin{command}"
+ " > sudo apt-get install libscotch-dev"
+ "\\end{command}"
+ ""
+ "If you activate the advanced option AKANTU\\_USE\\_THIRD\\_PARTY\\_SCOTCH"
+ "the make system of akantu can automatically compile Scotch."
+ ""
+ "If the automated download fails due to a SSL access not supported by your"
+ "version of CMake please download the file"
+ "\\href{${SCOTCH_ARCHIVE}}{scotch\\_${SCOTCH_VERSION}\\_esmumps.tar.gz}"
+ "and then place it in the directory \\shellcode{<akantu source>/third-party}"
+ )
+
+# if(SCOTCH_INCLUDE_DIR)
+# file(STRINGS ${SCOTCH_INCLUDE_DIR}/scotch.h SCOTCH_INCLUDE_CONTENT)
+# string(REGEX MATCH "_cplusplus" _match ${SCOTCH_INCLUDE_CONTENT})
+# if(_match)
+# set(AKANTU_SCOTCH_NO_EXTERN ON)
+# list(APPEND AKANTU_DEFINITIONS AKANTU_SCOTCH_NO_EXTERN)
+# else()
+# set(AKANTU_SCOTCH_NO_EXTERN OFF)
+# endif()
+# endif()
diff --git a/packages/structural_mechanics.cmake b/packages/structural_mechanics.cmake
new file mode 100644
index 000000000..aa1946fc3
--- /dev/null
+++ b/packages/structural_mechanics.cmake
@@ -0,0 +1,75 @@
+#===============================================================================
+# @file 10_structural_mechanics.cmake
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date creation: Mon Nov 21 2011
+# @date last modification: Mon Jul 07 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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
new file mode 100644
index 000000000..30aca6401
--- /dev/null
+++ b/python/CMakeLists.txt
@@ -0,0 +1,243 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date Wed Jul 9 17:22:12 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+#===============================================================================
+# Configuration
+#===============================================================================
+package_get_all_definitions(AKANTU_DEFS)
+list(REMOVE_ITEM AKANTU_DEFS AKANTU_CORE_CXX11)
+#message(${AKANTU_DEFS})
+set(AKA_DEFS "")
+foreach (def ${AKANTU_DEFS})
+ list(APPEND AKA_DEFS "-D${def}")
+endforeach()
+
+set(AKANTU_SWIG_FLAGS -w309,325,401,317,509,503,383,384 ${AKA_DEFS})
+set(AKANTU_SWIG_OUTDIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(AKANTU_SWIG_MODULES swig/akantu.i)
+
+#===============================================================================
+# Swig wrapper
+#===============================================================================
+
+set(SWIG_REQURIED_VERISON 3.0)
+find_package(SWIG ${SWIG_REQURIED_VERISON})
+mark_as_advanced(SWIG_EXECUTABLE)
+
+package_get_all_include_directories(
+ AKANTU_LIBRARY_INCLUDE_DIRS
+ )
+
+package_get_all_external_informations(
+ AKANTU_EXTERNAL_INCLUDE_DIR
+ AKANTU_EXTERNAL_LIBRARIES
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/swig
+ ${AKANTU_LIBRARY_INCLUDE_DIRS}
+ ${PROJECT_BINARY_DIR}/src
+ ${AKANTU_EXTERNAL_INCLUDE_DIR}
+ )
+
+include(CMakeParseArguments)
+
+function(swig_generate_dependencies _module _depedencies)
+ set(_dependencies_script "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/_swig_generate_dependencies.cmake")
+ file(WRITE ${_dependencies_script} "
+set(_include_directories ${_include_directories})
+list(APPEND _include_directories \"./\")
+
+set(_dep)
+set(_files_to_process \${_module})
+while(_files_to_process)
+ list(GET _files_to_process 0 _file)
+ list(REMOVE_AT _files_to_process 0)
+ file(STRINGS \${_file} _file_content REGEX \"^%include *\\\"(.*)\\\"\")
+
+ set(_includes)
+ foreach(_line \${_file_content})
+ string(REGEX REPLACE \"^%include *\\\"(.*)\\\"\" \"\\\\1\" _inc \${_line})
+ if(_inc)
+ list(APPEND _includes \${_inc})
+ endif()
+ endforeach()
+
+ foreach(_include \${_includes})
+ unset(_found)
+ foreach(_inc_dir \${_include_directories})
+ if(EXISTS \${_inc_dir}/\${_include})
+ set(_found \${_inc_dir}/\${_include})
+ break()
+ endif()
+ endforeach()
+
+ if(_found)
+ list(APPEND _files_to_process \${_found})
+ list(APPEND _dep \${_found})
+ endif()
+ endforeach()
+endwhile()
+
+get_filename_component(_module_we \"\${_module}\" NAME_WE)
+set(_dependencies_file \${CMAKE_CURRENT_BINARY_DIR}\${CMAKE_FILES_DIRECTORY}/_swig_\${_module_we}_depends.cmake)
+file(WRITE \"\${_dependencies_file}\"
+ \"set(_swig_\${_module_we}_depends\")
+foreach(_d \${_dep})
+ file(APPEND \"\${_dependencies_file}\" \"
+ \${_d}\")
+endforeach()
+file(APPEND \"\${_dependencies_file}\" \"
+ )\")
+")
+
+ get_directory_property(_include_directories INCLUDE_DIRECTORIES)
+ get_filename_component(_module_absolute "${_module}" ABSOLUTE)
+ get_filename_component(_module_we "${_module}" NAME_WE)
+
+ set(_dependencies_file ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/_swig_${_module_we}_depends.cmake)
+
+ if(EXISTS ${_dependencies_file})
+ include(${_dependencies_file})
+ else()
+ execute_process(COMMAND ${CMAKE_COMMAND}
+ -D_module=${_module_absolute}
+ -P ${_dependencies_script}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+ include(${_dependencies_file})
+ endif()
+
+ add_custom_command(OUTPUT ${_dependencies_file}
+ COMMAND ${CMAKE_COMMAND}
+ -D_module=${_module_absolute}
+ -P ${_dependencies_script}
+ COMMENT "Scanning dependencies for swig module ${_module_we}"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ MAIN_DEPENDENCY ${_module_absolute}
+ DEPENDS ${_swig_${_module_we}_depends}
+ )
+
+ set(${_depedencies} ${_dependencies_file} PARENT_SCOPE)
+endfunction()
+
+function(swig_generate_wrappers project _wrappers_cpp _wrappers_py)
+ cmake_parse_arguments(_swig_opt "" "OUTPUT_DIR" "EXTRA_FLAGS" ${ARGN})
+
+ if(_swig_opt_OUTPUT_DIR)
+ set(_output_dir ${_swig_opt_OUTPUT_DIR})
+ else()
+ set(_output_dir ${CMAKE_CURRENT_BINARY_DIR})
+ endif()
+
+ set(_swig_wrappers)
+ get_directory_property(_include_directories INCLUDE_DIRECTORIES)
+ if(_include_directories)
+ string(REPLACE ";" ";-I" _swig_include_directories "${_include_directories}")
+ endif()
+
+ foreach(_module ${_swig_opt_UNPARSED_ARGUMENTS})
+ swig_generate_dependencies(${_module} _module_dependencies)
+
+ get_filename_component(_module_absolute "${_module}" ABSOLUTE)
+ get_filename_component(_module_path "${_module_absolute}" PATH)
+ get_filename_component(_module_name "${_module}" NAME)
+ get_filename_component(_module_we "${_module}" NAME_WE)
+ set(_wrapper "${_output_dir}/${_module_we}_wrapper.cc")
+ set(_extra_wrapper "${_output_dir}/${_module_we}.py")
+ set(_extra_wrapper_bin "${CMAKE_CURRENT_BINARY_DIR}/${_module_we}.py")
+
+ if(SWIG_FOUND)
+ set_source_files_properties("${_wrapper}" PROPERTIES GENERATED 1)
+ set_source_files_properties("${_extra_wrapper}" PROPERTIES GENERATED 1)
+
+ set(_dependencies_file ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/_swig_${_module_we}_depends.cmake)
+
+ set(_ouput "${_wrapper}" "${_extra_wrapper}")
+ add_custom_command(
+ OUTPUT ${_ouput}
+ COMMAND "${SWIG_EXECUTABLE}"
+ ARGS -python -c++
+ ${_swig_opt_EXTRA_FLAGS}
+ -outdir ${_output_dir}
+ -I${_swig_include_directories} -I${_module_path}
+ -o "${_wrapper}"
+ "${_module_absolute}"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${_extra_wrapper} ${_extra_wrapper_bin}
+ # MAIN_DEPENDENCY "${_module_absolute}"
+ DEPENDS ${_module_dependencies}
+ COMMENT "Generating swig wrapper ${_module} -> ${_wrapper}"
+ )
+
+ list(APPEND _swig_wrappers ${_wrapper})
+ list(APPEND _swig_wrappers_py "${_extra_wrapper_bin}")
+ else()
+ if(NOT EXISTS ${_wrapper} OR NOT EXISTS "${_extra_wrapper}")
+ message(FATAL_ERROR "The file ${_wrapper} and/or ${_extra_wrapper} does "
+ "not exists and they cannot be generated. Install swig ${SWIG_REQURIED_VERISON} "
+ " in order to generate them. Or get them from a different machine, "
+ "in order to be able to compile the python interface")
+ else()
+ list(APPEND _swig_wrappers "${_wrapper}")
+ list(APPEND _swig_wrappers_py "${_extra_wrapper_bin}")
+ endif()
+ endif()
+ endforeach()
+
+ add_custom_target(${project}_generate_swig_wrappers DEPENDS ${_swig_wrappers})
+
+ set(${_wrappers_cpp} ${_swig_wrappers} PARENT_SCOPE)
+ set(${_wrappers_py} ${_swig_wrappers_py} PARENT_SCOPE)
+endfunction()
+
+
+swig_generate_wrappers(akantu AKANTU_SWIG_WRAPPERS_CPP AKANTU_WRAPPERS_PYTHON
+ ${AKANTU_SWIG_MODULES}
+ EXTRA_FLAGS ${AKANTU_SWIG_FLAGS})
+
+if(AKANTU_SWIG_WRAPPERS_CPP)
+ add_library(_akantu MODULE ${AKANTU_SWIG_WRAPPERS_CPP})
+ target_link_libraries(_akantu akantu)
+
+ set_target_properties(_akantu PROPERTIES PREFIX "")
+
+ list(APPEND AKANTU_EXPORT_LIST _akantu)
+
+ install(TARGETS _akantu
+ EXPORT ${AKANTU_TARGETS_EXPORT}
+ LIBRARY DESTINATION lib COMPONENT python NAMELINK_SKIP # for real systems
+ ARCHIVE DESTINATION lib COMPONENT python
+ RUNTIME DESTINATION bin COMPONENT python # for windows ...
+ )
+
+ install(FILES ${AKANTU_WRAPPERS_PYTHON}
+ DESTINATION lib COMPONENT python
+ )
+
+endif()
+
diff --git a/python/swig/aka_array.i b/python/swig/aka_array.i
new file mode 100644
index 000000000..3f220cb6d
--- /dev/null
+++ b/python/swig/aka_array.i
@@ -0,0 +1,187 @@
+%{
+#define SWIG_FILE_WITH_INIT
+#include "aka_array.hh"
+%}
+
+%include "typemaps.i"
+
+namespace akantu {
+ %ignore Array::operator=;
+ %ignore Array::operator[];
+ %ignore Array::operator();
+ %ignore Array::set;
+ %ignore Array::begin;
+ %ignore Array::end;
+ %ignore Array::begin_reinterpret;
+ %ignore Array::end_reinterpret;
+};
+
+%include "aka_array.hh"
+
+namespace akantu {
+ %template(RArray) Array<akantu::Real, true>;
+ %template(UArray) Array<akantu::UInt, true>;
+ %template(BArray) Array<bool, true>;
+}
+
+
+
+%include "numpy.i"
+%init %{
+ import_array();
+%}
+
+%inline %{
+ namespace akantu{
+ template <typename T>
+ class ArrayForPython : public Array<T>{
+
+ public:
+ ArrayForPython(T * wrapped_memory,
+ UInt size = 0,
+ UInt nb_component = 1,
+ const ID & id = "")
+ : Array<T>(0,nb_component,id){
+ this->values = wrapped_memory;
+ this->size = size;
+ };
+
+ ~ArrayForPython(){
+ this->values = NULL;
+ };
+
+ void resize(UInt new_size){
+ AKANTU_DEBUG_ASSERT(this->size == new_size,"cannot resize a temporary vector");
+ }
+ };
+ }
+ template <typename T> int getPythonDataTypeCode(){ AKANTU_EXCEPTION("undefined type");}
+ template <> int getPythonDataTypeCode<bool>(){
+ int data_typecode = NPY_NOTYPE;
+ size_t s = sizeof(bool);
+ switch(s) {
+ case 1: data_typecode = NPY_BOOL; break;
+ case 2: data_typecode = NPY_UINT16; break;
+ case 4: data_typecode = NPY_UINT32; break;
+ case 8: data_typecode = NPY_UINT64; break;
+ }
+ return data_typecode;
+ }
+
+ template <> int getPythonDataTypeCode<double>(){return NPY_DOUBLE;}
+ template <> int getPythonDataTypeCode<long double>(){return NPY_LONGDOUBLE;}
+ template <> int getPythonDataTypeCode<float>(){return NPY_FLOAT;}
+ template <> int getPythonDataTypeCode<unsigned long>(){
+ int data_typecode = NPY_NOTYPE;
+ size_t s = sizeof(unsigned long);
+ switch(s) {
+ case 2: data_typecode = NPY_UINT16; break;
+ case 4: data_typecode = NPY_UINT32; break;
+ case 8: data_typecode = NPY_UINT64; break;
+ }
+ return data_typecode;
+ }
+ template <> int getPythonDataTypeCode<akantu::UInt>(){
+ int data_typecode = NPY_NOTYPE;
+ size_t s = sizeof(akantu::UInt);
+ switch(s) {
+ case 2: data_typecode = NPY_UINT16; break;
+ case 4: data_typecode = NPY_UINT32; break;
+ case 8: data_typecode = NPY_UINT64; break;
+ }
+ return data_typecode;
+ }
+ template <> int getPythonDataTypeCode<int>(){
+ int data_typecode = NPY_NOTYPE;
+ size_t s = sizeof(int);
+ switch(s) {
+ case 2: data_typecode = NPY_INT16; break;
+ case 4: data_typecode = NPY_INT32; break;
+ case 8: data_typecode = NPY_INT64; break;
+ }
+ return data_typecode;
+ }
+
+ int getSizeOfPythonType(int type_num){
+ switch (type_num){
+ case NPY_INT16 : return 2;break;
+ case NPY_UINT16: return 2;break;
+ case NPY_INT32 : return 4;break;
+ case NPY_UINT32: return 4;break;
+ case NPY_INT64 : return 8;break;
+ case NPY_UINT64: return 8;break;
+ case NPY_FLOAT: return sizeof(float);break;
+ case NPY_DOUBLE: return sizeof(double);break;
+ case NPY_LONGDOUBLE: return sizeof(long double);break;
+ }
+ return 0;
+ }
+
+ std::string getPythonTypeName(int type_num){
+ switch (type_num){
+ case NPY_INT16 : return "NPY_INT16" ;break;
+ case NPY_UINT16: return "NPY_UINT16";break;
+ case NPY_INT32 : return "NPY_INT32" ;break;
+ case NPY_UINT32: return "NPY_UINT32";break;
+ case NPY_INT64 : return "NPY_INT64" ;break;
+ case NPY_UINT64: return "NPY_UINT64";break;
+ case NPY_FLOAT: return "NPY_FLOAT" ;break;
+ case NPY_DOUBLE: return "NPY_DOUBLE";break;
+ case NPY_LONGDOUBLE: return "NPY_LONGDOUBLE";break;
+ }
+ return 0;
+ }
+
+ template <typename T> void checkDataType(int type_num){
+ AKANTU_DEBUG_ASSERT(type_num == getPythonDataTypeCode<T>(),
+ "incompatible types between numpy and input function: " <<
+ type_num << " != " << getPythonDataTypeCode<T>() << std::endl <<
+ getSizeOfPythonType(type_num) << " != " << sizeof(T) <<
+ std::endl <<
+ "The numpy array is of type " << getPythonTypeName(type_num));
+ }
+
+ %}
+
+
+%define %akantu_array_typemaps(DATA_TYPE)
+
+%typemap(out, fragment="NumPy_Fragments") (akantu::Array< DATA_TYPE > &)
+{
+
+ int data_typecode = getPythonDataTypeCode< DATA_TYPE >();
+ npy_intp dims[2] = {npy_intp($1->getSize()), npy_intp($1->getNbComponent())};
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, data_typecode, $1->storage());
+ PyArrayObject* array = (PyArrayObject*) obj;
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result, obj);
+}
+
+%typemap(in) akantu::Array< DATA_TYPE > &
+{
+ if (!PyArray_Check($input)) {
+ AKANTU_EXCEPTION("incompatible input which is not a numpy");
+ }
+ else {
+ PyArray_Descr * numpy_type = (PyArray_Descr*)PyArray_DESCR((PyArrayObject*)$input);
+ int type_num = numpy_type->type_num;
+ checkDataType< DATA_TYPE >(type_num);
+ UInt _n = PyArray_NDIM((PyArrayObject*)$input);
+ if (_n != 2) AKANTU_EXCEPTION("incompatible numpy dimension " << _n);
+ npy_intp * ndims = PyArray_DIMS((PyArrayObject*)$input);
+ akantu::UInt sz = ndims[0];
+ akantu::UInt nb_components = ndims[1];
+ PyArrayIterObject *iter = (PyArrayIterObject *)PyArray_IterNew($input);
+ if (iter == NULL) AKANTU_EXCEPTION("Python internal error");
+ $1 = new akantu::ArrayForPython< DATA_TYPE >((DATA_TYPE*)(iter->dataptr),sz,nb_components,"tmp_array_for_python");
+ }
+}
+%enddef
+
+
+%akantu_array_typemaps(double )
+%akantu_array_typemaps(float )
+%akantu_array_typemaps(unsigned int)
+%akantu_array_typemaps(unsigned long)
+%akantu_array_typemaps(int )
+%akantu_array_typemaps(bool )
diff --git a/python/swig/aka_common.i b/python/swig/aka_common.i
new file mode 100644
index 000000000..3f457e370
--- /dev/null
+++ b/python/swig/aka_common.i
@@ -0,0 +1,92 @@
+%{
+ #include "aka_common.hh"
+ #include "aka_csr.hh"
+ #include "element.hh"
+%}
+
+namespace akantu {
+ %ignore getStaticParser;
+ %ignore getUserParser;
+ %ignore initialize(int & argc, char ** & argv);
+ %ignore initialize(const std::string & input_file, int & argc, char ** & argv);
+ extern const Array<UInt> empty_filter;
+
+}
+
+%typemap(in) (int argc, char *argv[]) {
+ int i = 0;
+ if (!PyList_Check($input)) {
+ PyErr_SetString(PyExc_ValueError, "Expecting a list");
+ return NULL;
+ }
+
+ $1 = PyList_Size($input);
+ $2 = new char *[$1+1];
+
+ for (i = 0; i < $1; i++) {
+ PyObject *s = PyList_GetItem($input,i);
+ if (!PyString_Check(s)) {
+ free($2);
+ PyErr_SetString(PyExc_ValueError, "List items must be strings");
+ return NULL;
+ }
+ $2[i] = PyString_AsString(s);
+ }
+ $2[i] = 0;
+}
+
+%typemap(freearg) (int argc, char *argv[]) {
+%#if defined(__INTEL_COMPILER)
+//#pragma warning ( disable : 383 )
+%#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
+%#elif (defined(__GNUC__) || defined(__GNUG__))
+%# if __cplusplus > 199711L
+%# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+%# endif
+%#endif
+
+ delete [] $2;
+
+%#if defined(__INTEL_COMPILER)
+//#pragma warning ( disable : 383 )
+%#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
+%#elif (defined(__GNUC__) || defined(__GNUG__))
+%# if __cplusplus > 199711L
+%# pragma GCC diagnostic pop
+%# endif
+%#endif
+}
+
+%inline %{
+ namespace akantu {
+#if defined(AKANTU_USE_MPI)
+ const int MPI=1;
+#else
+ const int MPI=0;
+#endif
+ void _initializeWithArgv(const std::string & input_file, int argc, char *argv[]) {
+ initialize(input_file, argc, argv);
+ }
+ }
+%}
+
+%pythoncode %{
+ import sys as _aka_sys
+ def initialize(input_file="", argv=_aka_sys.argv):
+ if _aka_sys.modules[__name__].MPI == 1:
+ try:
+ from mpi4py import MPI
+ except ImportError:
+ pass
+
+ _initializeWithArgv(input_file, argv)
+
+%}
+
+%include "aka_config.hh"
+%include "aka_common.hh"
+%include "aka_element_classes_info.hh"
+%include "element.hh"
+
+
+
diff --git a/python/swig/aka_csr.i b/python/swig/aka_csr.i
new file mode 100644
index 000000000..9258a10c5
--- /dev/null
+++ b/python/swig/aka_csr.i
@@ -0,0 +1,69 @@
+%{
+ #include "aka_csr.hh"
+%}
+
+namespace akantu {
+ %ignore CSR::begin;
+}
+
+%inline %{
+namespace akantu {
+ template <typename T>
+ class CSRIterator{
+
+ public:
+ CSRIterator(CSR<T> & csr,UInt row) {
+ this->it = csr.begin(row);
+ this->end = csr.end(row);
+ };
+
+ ~CSRIterator(){
+ };
+
+ T & __next_cpp(){
+ if (this->it == this->end) AKANTU_SILENT_EXCEPTION("StopIteration");
+ T & ref = *(this->it);
+ ++this->it;
+ return ref;
+ }
+
+ private:
+
+ typename CSR<T>::iterator it;
+ typename CSR<T>::iterator end;
+ };
+}
+%}
+
+%extend akantu::CSRIterator<akantu::Element>
+{
+ %insert("python") %{
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ try:
+ return self.__next_cpp()
+ except Exception as e:
+ raise StopIteration
+
+
+ def next(self):
+ return self.__next__()
+
+%}
+}
+
+%extend akantu::CSR<akantu::Element>
+{
+ akantu::CSRIterator<akantu::Element> row(akantu::UInt row){
+ return akantu::CSRIterator<akantu::Element>(*$self,row);
+ }
+}
+
+%include "aka_csr.hh"
+namespace akantu {
+ %template (CSRUInt) CSR<UInt>;
+ %template (CSRElement) CSR<Element>;
+ %template (CSRIteratorElement) CSRIterator<Element>;
+ }
diff --git a/python/swig/akantu.i b/python/swig/akantu.i
new file mode 100644
index 000000000..1272c7c39
--- /dev/null
+++ b/python/swig/akantu.i
@@ -0,0 +1,48 @@
+%module akantu
+
+%exception {
+ try {
+ $action
+ } catch (akantu::debug::Exception e) {
+ PyErr_SetString(PyExc_IndexError,e.what());
+ return NULL;
+ }
+ }
+
+%include "stl.i"
+
+#define __attribute__(x)
+
+%ignore akantu::operator <<;
+
+%include "aka_common.i"
+%include "aka_csr.i"
+%include "aka_array.i"
+
+%define print_self(MY_CLASS)
+ %extend akantu::MY_CLASS {
+ std::string __str__() {
+ std::stringstream sstr;
+ sstr << *($self);
+ return sstr.str();
+ }
+ }
+%enddef
+
+%include "mesh.i"
+%include "mesh_utils.i"
+%include "model.i"
+%include "solid_mechanics_model.i"
+#if defined(AKANTU_COHESIVE_ELEMENT)
+%include "solid_mechanics_model_cohesive.i"
+#endif
+
+#if defined(AKANTU_HEAT_TRANSFER)
+%include "heat_transfer_model.i"
+#endif
+
+
+#if defined(AKANTU_STRUCTURAL_MECHANICS)
+%include "load_functions.i"
+%include "structural_mechanics_model.i"
+#endif
diff --git a/python/swig/heat_transfer_model.i b/python/swig/heat_transfer_model.i
new file mode 100644
index 000000000..d42cff43e
--- /dev/null
+++ b/python/swig/heat_transfer_model.i
@@ -0,0 +1,27 @@
+%{
+ #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
new file mode 100644
index 000000000..046c3bfe0
--- /dev/null
+++ b/python/swig/load_functions.i
@@ -0,0 +1,14 @@
+%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
new file mode 100644
index 000000000..d3064cd94
--- /dev/null
+++ b/python/swig/mesh.i
@@ -0,0 +1,138 @@
+%{
+#include "mesh.hh"
+#include "node_group.hh"
+#include "solid_mechanics_model.hh"
+#include "dumpable_inline_impl.hh"
+
+using akantu::IntegrationPoint;
+using akantu::Vector;
+using akantu::ElementTypeMapArray;
+using akantu::MatrixProxy;
+using akantu::Matrix;
+using akantu::UInt;
+using akantu::Real;
+using akantu::Array;
+using akantu::SolidMechanicsModel;
+
+%}
+
+
+namespace akantu {
+ %ignore NewNodesEvent;
+ %ignore RemovedNodesEvent;
+ %ignore NewElementsEvent;
+ %ignore RemovedElementsEvent;
+ %ignore MeshEventHandler;
+ %ignore MeshEvent< UInt >;
+ %ignore MeshEvent< Element >;
+ %ignore Mesh::extractNodalCoordinatesFromPBCElement;
+ %ignore Mesh::getGroupDumer;
+ %ignore Mesh::getFacetLocalConnectivity;
+ %ignore Mesh::getAllFacetTypes;
+}
+
+print_self(Mesh)
+
+
+%extend akantu::Mesh {
+ void resizeMesh(UInt nb_nodes, UInt nb_element, const ElementType & type) {
+ Array<Real> & nodes = const_cast<Array<Real> &>($self->getNodes());
+ nodes.resize(nb_nodes);
+
+ $self->addConnectivityType(type);
+ Array<UInt> & connectivity = const_cast<Array<UInt> &>($self->getConnectivity(type));
+ connectivity.resize(nb_element);
+ }
+
+#if defined(AKANTU_COHESIVE_ELEMENT)
+ Array<Real> & getCohesiveBarycenter(SpacialDirection dir) {
+ UInt spatial_dimension = $self->getSpatialDimension();
+ ElementTypeMapArray<Real> & barycenter =
+ $self->registerData<Real>("barycenter");
+ $self->initElementTypeMapArray(barycenter, 1, spatial_dimension, false,
+ akantu::_ek_cohesive, true);
+ akantu::ElementType type = *($self->firstType(
+ spatial_dimension, akantu::_not_ghost, akantu::_ek_cohesive));
+
+ Vector<Real> bary(spatial_dimension);
+ Array<Real> & bary_coh = barycenter(type);
+ for (UInt i = 0; i < $self->getNbElement(type); ++i) {
+ bary.clear();
+ $self->getBarycenter(i, type, bary.storage());
+ bary_coh(i) = bary(dir);
+ }
+ return bary_coh;
+ }
+#endif
+}
+
+%extend akantu::GroupManager {
+ void createGroupsFromStringMeshData(const std::string & dataset_name) {
+ $self->createGroupsFromMeshData<std::string>(dataset_name);
+ }
+
+ void createGroupsFromUIntMeshData(const std::string & dataset_name) {
+ $self->createGroupsFromMeshData<akantu::UInt>(dataset_name);
+ }
+}
+
+%extend akantu::NodeGroup {
+ akantu::Array<akantu::Real> & getGroupedNodes(akantu::Array<akantu::Real, true> & surface_array, Mesh & mesh) {
+ akantu::Array<akantu::UInt> group_node = $self->getNodes();
+ akantu::Array<akantu::Real> & full_array = mesh.getNodes();
+ surface_array.resize(group_node.getSize());
+
+ for (UInt i = 0; i < group_node.getSize(); ++i) {
+ for (UInt cmp = 0; cmp < full_array.getNbComponent(); ++cmp) {
+
+ surface_array(i,cmp) = full_array(group_node(i),cmp);
+ }
+ }
+
+ akantu::Array<akantu::Real> & res(surface_array);
+ return res;
+ }
+
+ akantu::Array<akantu::Real> & getGroupedArray(akantu::Array<akantu::Real, true> & surface_array, akantu::SolidMechanicsModel & model, int type) {
+ akantu::Array<akantu::Real> * full_array;
+
+ switch (type) {
+
+ case 0 : full_array = new akantu::Array<akantu::Real>(model.getDisplacement());
+ break;
+ case 1 : full_array = new akantu::Array<akantu::Real>(model.getVelocity());
+ break;
+ case 2 : full_array = new akantu::Array<akantu::Real>(model.getForce());
+ break;
+ }
+ akantu::Array<akantu::UInt> group_node = $self->getNodes();
+ surface_array.resize(group_node.getSize());
+
+ for (UInt i = 0; i < group_node.getSize(); ++i) {
+ for (UInt cmp = 0; cmp < full_array->getNbComponent(); ++cmp) {
+
+ surface_array(i,cmp) = (*full_array)(group_node(i),cmp);
+ }
+ }
+
+ akantu::Array<akantu::Real> & res(surface_array);
+ return res;
+ }
+}
+
+%include "group_manager.hh"
+
+%include "element_group.hh"
+%include "node_group.hh"
+%include "dumper_iohelper.hh"
+%include "dumpable_iohelper.hh"
+%include "mesh.hh"
+
+namespace akantu{
+%extend Dumpable {
+ void addDumpFieldExternalReal(const std::string & field_id,
+ const Array<Real> & field){
+ $self->addDumpFieldExternal<Real>(field_id,field);
+ }
+ }
+ }
diff --git a/python/swig/mesh_utils.i b/python/swig/mesh_utils.i
new file mode 100644
index 000000000..a20d0590b
--- /dev/null
+++ b/python/swig/mesh_utils.i
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 000000000..170d177dc
--- /dev/null
+++ b/python/swig/model.i
@@ -0,0 +1,48 @@
+%{
+ #include "boundary_condition_python_functor.hh"
+%}
+
+
+namespace akantu {
+ %ignore Model::createSynchronizerRegistry;
+ %ignore Model::createParallelSynch;
+ %ignore Model::getDOFSynchronizer;
+ //%ignore Model::getSynchronizerRegistry;
+ %ignore Model::registerFEEngineObject;
+ %ignore Model::unregisterFEEngineObject;
+ %ignore Model::getFEEngineBoundary;
+ // %ignore Model::getFEEngine;
+ %ignore Model::getFEEngineClass;
+ %ignore Model::getFEEngineClassBoundary;
+ %ignore Model::setParser;
+
+ %ignore IntegrationPoint::operator=;
+
+ %ignore FEEngine::getNbIntegrationPoints;
+ %ignore FEEngine::getShapes;
+ %ignore FEEngine::getShapesDerivatives;
+ %ignore FEEngine::getIntegrationPoints;
+ %ignore FEEngine::getIGFEMElementTypes;
+ %ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,ElementTypeMapArray<Real> &,const ElementTypeMapArray<UInt> *) const;
+ %ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,ElementTypeMapArray<Real> &) const;
+ %ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,Array<Real> &,UInt,const ElementType&,const GhostType &,const Array< UInt > &) const;
+ %ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,Array<Real> &,UInt,const ElementType&,const GhostType &) const;
+
+}
+
+%include "sparse_matrix.hh"
+%include "fe_engine.hh"
+
+%rename(FreeBoundaryDirichlet) akantu::BC::Dirichlet::FreeBoundary;
+%rename(FreeBoundaryNeumann) akantu::BC::Neumann::FreeBoundary;
+%rename(PythonBoundary) akantu::BC::Dirichlet::PythonFunctor;
+
+%include "boundary_condition_functor.hh"
+%include "boundary_condition.hh"
+%include "boundary_condition_python_functor.hh"
+%include "communication_buffer.hh"
+%include "data_accessor.hh"
+%include "synchronizer.hh"
+%include "synchronizer_registry.hh"
+%include "model.hh"
+
diff --git a/python/swig/numpy.i b/python/swig/numpy.i
new file mode 100644
index 000000000..f2714cc34
--- /dev/null
+++ b/python/swig/numpy.i
@@ -0,0 +1,3085 @@
+/* -*- C -*- (not really, but good for syntax highlighting) */
+#ifdef SWIGPYTHON
+
+%{
+#ifndef SWIG_FILE_WITH_INIT
+#define NO_IMPORT_ARRAY
+#endif
+#include "stdio.h"
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#include <numpy/arrayobject.h>
+%}
+
+/**********************************************************************/
+
+%fragment("NumPy_Backward_Compatibility", "header")
+{
+%#if NPY_API_VERSION < 0x00000007
+%#define NPY_ARRAY_DEFAULT NPY_DEFAULT
+%#define NPY_ARRAY_FARRAY NPY_FARRAY
+%#define NPY_FORTRANORDER NPY_FORTRAN
+%#endif
+}
+
+/**********************************************************************/
+
+/* The following code originally appeared in
+ * enthought/kiva/agg/src/numeric.i written by Eric Jones. It was
+ * translated from C++ to C by John Hunter. Bill Spotz has modified
+ * it to fix some minor bugs, upgrade from Numeric to numpy (all
+ * versions), add some comments and functionality, and convert from
+ * direct code insertion to SWIG fragments.
+ */
+
+%fragment("NumPy_Macros", "header")
+{
+/* Macros to extract array attributes.
+ */
+%#if NPY_API_VERSION < 0x00000007
+%#define is_array(a) ((a) && PyArray_Check((PyArrayObject*)a))
+%#define array_type(a) (int)(PyArray_TYPE((PyArrayObject*)a))
+%#define array_numdims(a) (((PyArrayObject*)a)->nd)
+%#define array_dimensions(a) (((PyArrayObject*)a)->dimensions)
+%#define array_size(a,i) (((PyArrayObject*)a)->dimensions[i])
+%#define array_strides(a) (((PyArrayObject*)a)->strides)
+%#define array_stride(a,i) (((PyArrayObject*)a)->strides[i])
+%#define array_data(a) (((PyArrayObject*)a)->data)
+%#define array_descr(a) (((PyArrayObject*)a)->descr)
+%#define array_flags(a) (((PyArrayObject*)a)->flags)
+%#define array_enableflags(a,f) (((PyArrayObject*)a)->flags) = f
+%#else
+%#define is_array(a) ((a) && PyArray_Check(a))
+%#define array_type(a) PyArray_TYPE((PyArrayObject*)a)
+%#define array_numdims(a) PyArray_NDIM((PyArrayObject*)a)
+%#define array_dimensions(a) PyArray_DIMS((PyArrayObject*)a)
+%#define array_strides(a) PyArray_STRIDES((PyArrayObject*)a)
+%#define array_stride(a,i) PyArray_STRIDE((PyArrayObject*)a,i)
+%#define array_size(a,i) PyArray_DIM((PyArrayObject*)a,i)
+%#define array_data(a) PyArray_DATA((PyArrayObject*)a)
+%#define array_descr(a) PyArray_DESCR((PyArrayObject*)a)
+%#define array_flags(a) PyArray_FLAGS((PyArrayObject*)a)
+%#define array_enableflags(a,f) PyArray_ENABLEFLAGS((PyArrayObject*)a,f)
+%#endif
+%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS((PyArrayObject*)a))
+%#define array_is_native(a) (PyArray_ISNOTSWAPPED((PyArrayObject*)a))
+%#define array_is_fortran(a) (PyArray_ISFORTRAN((PyArrayObject*)a))
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Utilities",
+ "header")
+{
+ /* Given a PyObject, return a string describing its type.
+ */
+ const char* pytype_string(PyObject* py_obj)
+ {
+ if (py_obj == NULL ) return "C NULL value";
+ if (py_obj == Py_None ) return "Python None" ;
+ if (PyCallable_Check(py_obj)) return "callable" ;
+ if (PyString_Check( py_obj)) return "string" ;
+ if (PyInt_Check( py_obj)) return "int" ;
+ if (PyFloat_Check( py_obj)) return "float" ;
+ if (PyDict_Check( py_obj)) return "dict" ;
+ if (PyList_Check( py_obj)) return "list" ;
+ if (PyTuple_Check( py_obj)) return "tuple" ;
+%#if PY_MAJOR_VERSION < 3
+ if (PyFile_Check( py_obj)) return "file" ;
+ if (PyModule_Check( py_obj)) return "module" ;
+ if (PyInstance_Check(py_obj)) return "instance" ;
+%#endif
+
+ return "unkown type";
+ }
+
+ /* Given a NumPy typecode, return a string describing the type.
+ */
+ const char* typecode_string(int typecode)
+ {
+ static const char* type_names[25] = {"bool",
+ "byte",
+ "unsigned byte",
+ "short",
+ "unsigned short",
+ "int",
+ "unsigned int",
+ "long",
+ "unsigned long",
+ "long long",
+ "unsigned long long",
+ "float",
+ "double",
+ "long double",
+ "complex float",
+ "complex double",
+ "complex long double",
+ "object",
+ "string",
+ "unicode",
+ "void",
+ "ntypes",
+ "notype",
+ "char",
+ "unknown"};
+ return typecode < 24 ? type_names[typecode] : type_names[24];
+ }
+
+ /* Make sure input has correct numpy type. This now just calls
+ PyArray_EquivTypenums().
+ */
+ int type_match(int actual_type,
+ int desired_type)
+ {
+ return PyArray_EquivTypenums(actual_type, desired_type);
+ }
+
+%#ifdef SWIGPY_USE_CAPSULE
+ void free_cap(PyObject * cap)
+ {
+ void* array = (void*) PyCapsule_GetPointer(cap,SWIGPY_CAPSULE_NAME);
+ if (array != NULL) free(array);
+ }
+%#endif
+
+
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Object_to_Array",
+ "header",
+ fragment="NumPy_Backward_Compatibility",
+ fragment="NumPy_Macros",
+ fragment="NumPy_Utilities")
+{
+ /* Given a PyObject pointer, cast it to a PyArrayObject pointer if
+ * legal. If not, set the python error string appropriately and
+ * return NULL.
+ */
+ PyArrayObject* obj_to_array_no_conversion(PyObject* input,
+ int typecode)
+ {
+ PyArrayObject* ary = NULL;
+ if (is_array(input) && (typecode == NPY_NOTYPE ||
+ PyArray_EquivTypenums(array_type(input), typecode)))
+ {
+ ary = (PyArrayObject*) input;
+ }
+ else if is_array(input)
+ {
+ const char* desired_type = typecode_string(typecode);
+ const char* actual_type = typecode_string(array_type(input));
+ PyErr_Format(PyExc_TypeError,
+ "Array of type '%s' required. Array of type '%s' given",
+ desired_type, actual_type);
+ ary = NULL;
+ }
+ else
+ {
+ const char* desired_type = typecode_string(typecode);
+ const char* actual_type = pytype_string(input);
+ PyErr_Format(PyExc_TypeError,
+ "Array of type '%s' required. A '%s' was given",
+ desired_type,
+ actual_type);
+ ary = NULL;
+ }
+ return ary;
+ }
+
+ /* Convert the given PyObject to a NumPy array with the given
+ * typecode. On success, return a valid PyArrayObject* with the
+ * correct type. On failure, the python error string will be set and
+ * the routine returns NULL.
+ */
+ PyArrayObject* obj_to_array_allow_conversion(PyObject* input,
+ int typecode,
+ int* is_new_object)
+ {
+ PyArrayObject* ary = NULL;
+ PyObject* py_obj;
+ if (is_array(input) && (typecode == NPY_NOTYPE ||
+ PyArray_EquivTypenums(array_type(input),typecode)))
+ {
+ ary = (PyArrayObject*) input;
+ *is_new_object = 0;
+ }
+ else
+ {
+ py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_ARRAY_DEFAULT);
+ /* If NULL, PyArray_FromObject will have set python error value.*/
+ ary = (PyArrayObject*) py_obj;
+ *is_new_object = 1;
+ }
+ return ary;
+ }
+
+ /* Given a PyArrayObject, check to see if it is contiguous. If so,
+ * return the input pointer and flag it as not a new object. If it is
+ * not contiguous, create a new PyArrayObject using the original data,
+ * flag it as a new object and return the pointer.
+ */
+ PyArrayObject* make_contiguous(PyArrayObject* ary,
+ int* is_new_object,
+ int min_dims,
+ int max_dims)
+ {
+ PyArrayObject* result;
+ if (array_is_contiguous(ary))
+ {
+ result = ary;
+ *is_new_object = 0;
+ }
+ else
+ {
+ result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
+ array_type(ary),
+ min_dims,
+ max_dims);
+ *is_new_object = 1;
+ }
+ return result;
+ }
+
+ /* Given a PyArrayObject, check to see if it is Fortran-contiguous.
+ * If so, return the input pointer, but do not flag it as not a new
+ * object. If it is not Fortran-contiguous, create a new
+ * PyArrayObject using the original data, flag it as a new object
+ * and return the pointer.
+ */
+ PyArrayObject* make_fortran(PyArrayObject* ary,
+ int* is_new_object)
+ {
+ PyArrayObject* result;
+ if (array_is_fortran(ary))
+ {
+ result = ary;
+ *is_new_object = 0;
+ }
+ else
+ {
+ Py_INCREF(array_descr(ary));
+ result = (PyArrayObject*) PyArray_FromArray(ary,
+ array_descr(ary),
+ NPY_FORTRANORDER);
+ *is_new_object = 1;
+ }
+ return result;
+ }
+
+ /* Convert a given PyObject to a contiguous PyArrayObject of the
+ * specified type. If the input object is not a contiguous
+ * PyArrayObject, a new one will be created and the new object flag
+ * will be set.
+ */
+ PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
+ int typecode,
+ int* is_new_object)
+ {
+ int is_new1 = 0;
+ int is_new2 = 0;
+ PyArrayObject* ary2;
+ PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
+ typecode,
+ &is_new1);
+ if (ary1)
+ {
+ ary2 = make_contiguous(ary1, &is_new2, 0, 0);
+ if ( is_new1 && is_new2)
+ {
+ Py_DECREF(ary1);
+ }
+ ary1 = ary2;
+ }
+ *is_new_object = is_new1 || is_new2;
+ return ary1;
+ }
+
+ /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the
+ * specified type. If the input object is not a Fortran-ordered
+ * PyArrayObject, a new one will be created and the new object flag
+ * will be set.
+ */
+ PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input,
+ int typecode,
+ int* is_new_object)
+ {
+ int is_new1 = 0;
+ int is_new2 = 0;
+ PyArrayObject* ary2;
+ PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
+ typecode,
+ &is_new1);
+ if (ary1)
+ {
+ ary2 = make_fortran(ary1, &is_new2);
+ if (is_new1 && is_new2)
+ {
+ Py_DECREF(ary1);
+ }
+ ary1 = ary2;
+ }
+ *is_new_object = is_new1 || is_new2;
+ return ary1;
+ }
+} /* end fragment */
+
+/**********************************************************************/
+
+%fragment("NumPy_Array_Requirements",
+ "header",
+ fragment="NumPy_Backward_Compatibility",
+ fragment="NumPy_Macros")
+{
+ /* Test whether a python object is contiguous. If array is
+ * contiguous, return 1. Otherwise, set the python error string and
+ * return 0.
+ */
+ int require_contiguous(PyArrayObject* ary)
+ {
+ int contiguous = 1;
+ if (!array_is_contiguous(ary))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "Array must be contiguous. A non-contiguous array was given");
+ contiguous = 0;
+ }
+ return contiguous;
+ }
+
+ /* Require that a numpy array is not byte-swapped. If the array is
+ * not byte-swapped, return 1. Otherwise, set the python error string
+ * and return 0.
+ */
+ int require_native(PyArrayObject* ary)
+ {
+ int native = 1;
+ if (!array_is_native(ary))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "Array must have native byteorder. "
+ "A byte-swapped array was given");
+ native = 0;
+ }
+ return native;
+ }
+
+ /* Require the given PyArrayObject to have a specified number of
+ * dimensions. If the array has the specified number of dimensions,
+ * return 1. Otherwise, set the python error string and return 0.
+ */
+ int require_dimensions(PyArrayObject* ary,
+ int exact_dimensions)
+ {
+ int success = 1;
+ if (array_numdims(ary) != exact_dimensions)
+ {
+ PyErr_Format(PyExc_TypeError,
+ "Array must have %d dimensions. Given array has %d dimensions",
+ exact_dimensions,
+ array_numdims(ary));
+ success = 0;
+ }
+ return success;
+ }
+
+ /* Require the given PyArrayObject to have one of a list of specified
+ * number of dimensions. If the array has one of the specified number
+ * of dimensions, return 1. Otherwise, set the python error string
+ * and return 0.
+ */
+ int require_dimensions_n(PyArrayObject* ary,
+ int* exact_dimensions,
+ int n)
+ {
+ int success = 0;
+ int i;
+ char dims_str[255] = "";
+ char s[255];
+ for (i = 0; i < n && !success; i++)
+ {
+ if (array_numdims(ary) == exact_dimensions[i])
+ {
+ success = 1;
+ }
+ }
+ if (!success)
+ {
+ for (i = 0; i < n-1; i++)
+ {
+ sprintf(s, "%d, ", exact_dimensions[i]);
+ strcat(dims_str,s);
+ }
+ sprintf(s, " or %d", exact_dimensions[n-1]);
+ strcat(dims_str,s);
+ PyErr_Format(PyExc_TypeError,
+ "Array must have %s dimensions. Given array has %d dimensions",
+ dims_str,
+ array_numdims(ary));
+ }
+ return success;
+ }
+
+ /* Require the given PyArrayObject to have a specified shape. If the
+ * array has the specified shape, return 1. Otherwise, set the python
+ * error string and return 0.
+ */
+ int require_size(PyArrayObject* ary,
+ npy_intp* size,
+ int n)
+ {
+ int i;
+ int success = 1;
+ int len;
+ char desired_dims[255] = "[";
+ char s[255];
+ char actual_dims[255] = "[";
+ for(i=0; i < n;i++)
+ {
+ if (size[i] != -1 && size[i] != array_size(ary,i))
+ {
+ success = 0;
+ }
+ }
+ if (!success)
+ {
+ for (i = 0; i < n; i++)
+ {
+ if (size[i] == -1)
+ {
+ sprintf(s, "*,");
+ }
+ else
+ {
+ sprintf(s, "%ld,", (long int)size[i]);
+ }
+ strcat(desired_dims,s);
+ }
+ len = strlen(desired_dims);
+ desired_dims[len-1] = ']';
+ for (i = 0; i < n; i++)
+ {
+ sprintf(s, "%ld,", (long int)array_size(ary,i));
+ strcat(actual_dims,s);
+ }
+ len = strlen(actual_dims);
+ actual_dims[len-1] = ']';
+ PyErr_Format(PyExc_TypeError,
+ "Array must have shape of %s. Given array has shape of %s",
+ desired_dims,
+ actual_dims);
+ }
+ return success;
+ }
+
+ /* Require the given PyArrayObject to to be Fortran ordered. If the
+ * the PyArrayObject is already Fortran ordered, do nothing. Else,
+ * set the Fortran ordering flag and recompute the strides.
+ */
+ int require_fortran(PyArrayObject* ary)
+ {
+ int success = 1;
+ int nd = array_numdims(ary);
+ int i;
+ npy_intp * strides = array_strides(ary);
+ if (array_is_fortran(ary)) return success;
+ /* Set the Fortran ordered flag */
+ array_enableflags(ary,NPY_ARRAY_FARRAY);
+ /* Recompute the strides */
+ strides[0] = strides[nd-1];
+ for (i=1; i < nd; ++i)
+ strides[i] = strides[i-1] * array_size(ary,i-1);
+ return success;
+ }
+}
+
+/* Combine all NumPy fragments into one for convenience */
+%fragment("NumPy_Fragments",
+ "header",
+ fragment="NumPy_Backward_Compatibility",
+ fragment="NumPy_Macros",
+ fragment="NumPy_Utilities",
+ fragment="NumPy_Object_to_Array",
+ fragment="NumPy_Array_Requirements")
+{
+}
+
+/* End John Hunter translation (with modifications by Bill Spotz)
+ */
+
+/* %numpy_typemaps() macro
+ *
+ * This macro defines a family of 74 typemaps that allow C arguments
+ * of the form
+ *
+ * 1. (DATA_TYPE IN_ARRAY1[ANY])
+ * 2. (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ * 3. (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ *
+ * 4. (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ * 5. (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * 6. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ * 7. (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * 8. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ *
+ * 9. (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ * 10. (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 11. (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 12. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+ * 13. (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 14. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+ *
+ * 15. (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ * 16. (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 17. (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 18. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+ * 19. (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 20. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+ *
+ * 21. (DATA_TYPE INPLACE_ARRAY1[ANY])
+ * 22. (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ * 23. (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ *
+ * 24. (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ * 25. (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * 26. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ * 27. (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ * 28. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ *
+ * 29. (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ * 30. (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 31. (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 32. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+ * 33. (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ * 34. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+ *
+ * 35. (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ * 36. (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 37. (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 38. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+ * 39. (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ * 40. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+ *
+ * 41. (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ * 42. (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ * 43. (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ *
+ * 44. (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ *
+ * 45. (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *
+ * 46. (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+ *
+ * 47. (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ * 48. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ *
+ * 49. (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * 50. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ * 51. (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * 52. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ *
+ * 53. (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * 54. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ * 55. (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * 56. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ *
+ * 57. (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ * 58. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
+ * 59. (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ * 60. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ *
+ * 61. (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+ * 62. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ *
+ * 63. (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * 64. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+ * 65. (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ * 66. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+ *
+ * 67. (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * 68. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+ * 69. (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ * 70. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+ *
+ * 71. (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ * 72. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ * 73. (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ * 74. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ *
+ * where "DATA_TYPE" is any type supported by the NumPy module, and
+ * "DIM_TYPE" is any int-like type suitable for specifying dimensions.
+ * The difference between "ARRAY" typemaps and "FARRAY" typemaps is
+ * that the "FARRAY" typemaps expect Fortran ordering of
+ * multidimensional arrays. In python, the dimensions will not need
+ * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1"
+ * typemaps). The IN_ARRAYs can be a numpy array or any sequence that
+ * can be converted to a numpy array of the specified type. The
+ * INPLACE_ARRAYs must be numpy arrays of the appropriate type. The
+ * ARGOUT_ARRAYs will be returned as new numpy arrays of the
+ * appropriate type.
+ *
+ * These typemaps can be applied to existing functions using the
+ * %apply directive. For example:
+ *
+ * %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)};
+ * double prod(double* series, int length);
+ *
+ * %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2)
+ * {(int rows, int cols, double* matrix )};
+ * void floor(int rows, int cols, double* matrix, double f);
+ *
+ * %apply (double IN_ARRAY3[ANY][ANY][ANY])
+ * {(double tensor[2][2][2] )};
+ * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ * {(double low[2][2][2] )};
+ * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ * {(double upp[2][2][2] )};
+ * void luSplit(double tensor[2][2][2],
+ * double low[2][2][2],
+ * double upp[2][2][2] );
+ *
+ * or directly with
+ *
+ * double prod(double* IN_ARRAY1, int DIM1);
+ *
+ * void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f);
+ *
+ * void luSplit(double IN_ARRAY3[ANY][ANY][ANY],
+ * double ARGOUT_ARRAY3[ANY][ANY][ANY],
+ * double ARGOUT_ARRAY3[ANY][ANY][ANY]);
+ */
+
+%define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE)
+
+/************************/
+/* Input Array Typemaps */
+/************************/
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY1[ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY1[ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[1] = { $1_dim0 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 1) ||
+ !require_size(array, size, 1)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY1[ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[1] = { -1 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 1) ||
+ !require_size(array, size, 1)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[1] = {-1};
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 1) ||
+ !require_size(array, size, 1)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { $1_dim0, $1_dim1 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[2] = { -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 2) ||
+ !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ /* for now, only concerned with lists */
+ $1 = PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
+{
+ npy_intp size[2] = { -1, -1 };
+ PyArrayObject* temp_array;
+ Py_ssize_t i;
+ int is_new_object;
+
+ /* length of the list */
+ $2 = PyList_Size($input);
+
+ /* the arrays */
+ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+ object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+ is_new_object_array = (int *)calloc($2,sizeof(int));
+
+ if (array == NULL || object_array == NULL || is_new_object_array == NULL)
+ {
+ SWIG_fail;
+ }
+
+ for (i=0; i<$2; i++)
+ {
+ temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
+
+ /* the new array must be stored so that it can be destroyed in freearg */
+ object_array[i] = temp_array;
+ is_new_object_array[i] = is_new_object;
+
+ if (!temp_array || !require_dimensions(temp_array, 2)) SWIG_fail;
+
+ /* store the size of the first array in the list, then use that for comparison. */
+ if (i == 0)
+ {
+ size[0] = array_size(temp_array,0);
+ size[1] = array_size(temp_array,1);
+ }
+
+ if (!require_size(temp_array, size, 2)) SWIG_fail;
+
+ array[i] = (DATA_TYPE*) array_data(temp_array);
+ }
+
+ $1 = (DATA_TYPE**) array;
+ $3 = (DIM_TYPE) size[0];
+ $4 = (DIM_TYPE) size[1];
+}
+%typemap(freearg)
+ (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ Py_ssize_t i;
+
+ if (array$argnum!=NULL) free(array$argnum);
+
+ /*freeing the individual arrays if needed */
+ if (object_array$argnum!=NULL)
+ {
+ if (is_new_object_array$argnum!=NULL)
+ {
+ for (i=0; i<$2; i++)
+ {
+ if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
+ { Py_DECREF(object_array$argnum[i]); }
+ }
+ free(is_new_object_array$argnum);
+ }
+ free(object_array$argnum);
+ }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* IN_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* IN_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input,
+ DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 3) ||
+ !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3};
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+ (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { -1, -1, -1, -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+ $5 = (DIM_TYPE) array_size(array,3);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ /* for now, only concerned with lists */
+ $1 = PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ PyArrayObject* temp_array;
+ Py_ssize_t i;
+ int is_new_object;
+
+ /* length of the list */
+ $2 = PyList_Size($input);
+
+ /* the arrays */
+ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+ object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+ is_new_object_array = (int *)calloc($2,sizeof(int));
+
+ if (array == NULL || object_array == NULL || is_new_object_array == NULL)
+ {
+ SWIG_fail;
+ }
+
+ for (i=0; i<$2; i++)
+ {
+ temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
+
+ /* the new array must be stored so that it can be destroyed in freearg */
+ object_array[i] = temp_array;
+ is_new_object_array[i] = is_new_object;
+
+ if (!temp_array || !require_dimensions(temp_array, 3)) SWIG_fail;
+
+ /* store the size of the first array in the list, then use that for comparison. */
+ if (i == 0)
+ {
+ size[0] = array_size(temp_array,0);
+ size[1] = array_size(temp_array,1);
+ size[2] = array_size(temp_array,2);
+ }
+
+ if (!require_size(temp_array, size, 3)) SWIG_fail;
+
+ array[i] = (DATA_TYPE*) array_data(temp_array);
+ }
+
+ $1 = (DATA_TYPE**) array;
+ $3 = (DIM_TYPE) size[0];
+ $4 = (DIM_TYPE) size[1];
+ $5 = (DIM_TYPE) size[2];
+}
+%typemap(freearg)
+ (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ Py_ssize_t i;
+
+ if (array$argnum!=NULL) free(array$argnum);
+
+ /*freeing the individual arrays if needed */
+ if (object_array$argnum!=NULL)
+ {
+ if (is_new_object_array$argnum!=NULL)
+ {
+ for (i=0; i<$2; i++)
+ {
+ if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
+ { Py_DECREF(object_array$argnum[i]); }
+ }
+ free(is_new_object_array$argnum);
+ }
+ free(object_array$argnum);
+ }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ * DATA_TYPE* IN_ARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { -1, -1, -1 , -1};
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DIM_TYPE) array_size(array,3);
+ $5 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { -1, -1, -1, -1 };
+ array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4) | !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+ $5 = (DIM_TYPE) array_size(array,3);
+}
+%typemap(freearg)
+ (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ * DATA_TYPE* IN_FARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+{
+ $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+ (PyArrayObject* array=NULL, int is_new_object=0)
+{
+ npy_intp size[4] = { -1, -1, -1 , -1 };
+ array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
+ if (!array || !require_dimensions(array, 4) ||
+ !require_size(array, size, 4) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DIM_TYPE) array_size(array,3);
+ $5 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+{
+ if (is_new_object$argnum && array$argnum)
+ { Py_DECREF(array$argnum); }
+}
+
+/***************************/
+/* In-Place Array Typemaps */
+/***************************/
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY1[ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY1[ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[1] = { $1_dim0 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ (PyArrayObject* array=NULL, int i=1)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = 1;
+ for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ (PyArrayObject* array=NULL, int i=0)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = 1;
+ for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i);
+ $2 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[2] = { $1_dim0, $1_dim1 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+ !require_native(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+ || !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+ !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+ !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
+{
+ npy_intp size[2] = { -1, -1 };
+ PyArrayObject* temp_array;
+ Py_ssize_t i;
+
+ /* length of the list */
+ $2 = PyList_Size($input);
+
+ /* the arrays */
+ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+ object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+
+ if (array == NULL || object_array == NULL)
+ {
+ SWIG_fail;
+ }
+
+ for (i=0; i<$2; i++)
+ {
+ temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
+
+ /* the new array must be stored so that it can be destroyed in freearg */
+ object_array[i] = temp_array;
+
+ if ( !temp_array || !require_dimensions(temp_array, 2) ||
+ !require_contiguous(temp_array) ||
+ !require_native(temp_array) ||
+ !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
+ ) SWIG_fail;
+
+ /* store the size of the first array in the list, then use that for comparison. */
+ if (i == 0)
+ {
+ size[0] = array_size(temp_array,0);
+ size[1] = array_size(temp_array,1);
+ }
+
+ if (!require_size(temp_array, size, 2)) SWIG_fail;
+
+ array[i] = (DATA_TYPE*) array_data(temp_array);
+ }
+
+ $1 = (DATA_TYPE**) array;
+ $3 = (DIM_TYPE) size[0];
+ $4 = (DIM_TYPE) size[1];
+}
+%typemap(freearg)
+ (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ if (array$argnum!=NULL) free(array$argnum);
+ if (object_array$argnum!=NULL) free(object_array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* INPLACE_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+ !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* INPLACE_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+ || !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ (PyArrayObject* array=NULL)
+{
+ npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3 };
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_size(array, size, 4) ||
+ !require_contiguous(array) || !require_native(array)) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
+ !require_native(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+ $5 = (DIM_TYPE) array_size(array,3);
+}
+
+/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = PySequence_Check($input);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
+{
+ npy_intp size[3] = { -1, -1, -1 };
+ PyArrayObject* temp_array;
+ Py_ssize_t i;
+
+ /* length of the list */
+ $2 = PyList_Size($input);
+
+ /* the arrays */
+ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+ object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+
+ if (array == NULL || object_array == NULL)
+ {
+ SWIG_fail;
+ }
+
+ for (i=0; i<$2; i++)
+ {
+ temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
+
+ /* the new array must be stored so that it can be destroyed in freearg */
+ object_array[i] = temp_array;
+
+ if ( !temp_array || !require_dimensions(temp_array, 3) ||
+ !require_contiguous(temp_array) ||
+ !require_native(temp_array) ||
+ !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
+ ) SWIG_fail;
+
+ /* store the size of the first array in the list, then use that for comparison. */
+ if (i == 0)
+ {
+ size[0] = array_size(temp_array,0);
+ size[1] = array_size(temp_array,1);
+ size[2] = array_size(temp_array,2);
+ }
+
+ if (!require_size(temp_array, size, 3)) SWIG_fail;
+
+ array[i] = (DATA_TYPE*) array_data(temp_array);
+ }
+
+ $1 = (DATA_TYPE**) array;
+ $3 = (DIM_TYPE) size[0];
+ $4 = (DIM_TYPE) size[1];
+ $5 = (DIM_TYPE) size[2];
+}
+%typemap(freearg)
+ (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ if (array$argnum!=NULL) free(array$argnum);
+ if (object_array$argnum!=NULL) free(object_array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ * DATA_TYPE* INPLACE_ARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_contiguous(array)
+ || !require_native(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DIM_TYPE) array_size(array,3);
+ $5 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ * DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
+ !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+ $2 = (DIM_TYPE) array_size(array,0);
+ $3 = (DIM_TYPE) array_size(array,1);
+ $4 = (DIM_TYPE) array_size(array,2);
+ $5 = (DIM_TYPE) array_size(array,3);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ * DATA_TYPE* INPLACE_FARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+ fragment="NumPy_Macros")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+{
+ $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+ DATA_TYPECODE);
+}
+%typemap(in,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+ (PyArrayObject* array=NULL)
+{
+ array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+ if (!array || !require_dimensions(array,4) || !require_contiguous(array)
+ || !require_native(array) || !require_fortran(array)) SWIG_fail;
+ $1 = (DIM_TYPE) array_size(array,0);
+ $2 = (DIM_TYPE) array_size(array,1);
+ $3 = (DIM_TYPE) array_size(array,2);
+ $4 = (DIM_TYPE) array_size(array,3);
+ $5 = (DATA_TYPE*) array_data(array);
+}
+
+/*************************/
+/* Argout Array Typemaps */
+/*************************/
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ (PyObject* array = NULL)
+{
+ npy_intp dims[1] = { $1_dim0 };
+ array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY1[ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ */
+%typemap(in,numinputs=1,
+ fragment="NumPy_Fragments")
+ (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ (PyObject* array = NULL)
+{
+ npy_intp dims[1];
+ if (!PyInt_Check($input))
+ {
+ const char* typestring = pytype_string($input);
+ PyErr_Format(PyExc_TypeError,
+ "Int dimension expected. '%s' given.",
+ typestring);
+ SWIG_fail;
+ }
+ $2 = (DIM_TYPE) PyInt_AsLong($input);
+ dims[0] = (npy_intp) $2;
+ array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ */
+%typemap(in,numinputs=1,
+ fragment="NumPy_Fragments")
+ (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ (PyObject* array = NULL)
+{
+ npy_intp dims[1];
+ if (!PyInt_Check($input))
+ {
+ const char* typestring = pytype_string($input);
+ PyErr_Format(PyExc_TypeError,
+ "Int dimension expected. '%s' given.",
+ typestring);
+ SWIG_fail;
+ }
+ $1 = (DIM_TYPE) PyInt_AsLong($input);
+ dims[0] = (npy_intp) $1;
+ array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+ (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ (PyObject* array = NULL)
+{
+ npy_intp dims[2] = { $1_dim0, $1_dim1 };
+ array = PyArray_SimpleNew(2, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ (PyObject* array = NULL)
+{
+ npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 };
+ array = PyArray_SimpleNew(3, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+ fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+ (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+ (PyObject* array = NULL)
+{
+ npy_intp dims[4] = { $1_dim0, $1_dim1, $1_dim2, $1_dim3 };
+ array = PyArray_SimpleNew(4, dims, DATA_TYPECODE);
+ if (!array) SWIG_fail;
+ $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+ (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+{
+ $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/*****************************/
+/* Argoutview Array Typemaps */
+/*****************************/
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+{
+ npy_intp dims[1] = { *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim_temp;
+ $2 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+{
+ npy_intp dims[1] = { *$1 };
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+ npy_intp dims[2] = { *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+{
+ npy_intp dims[2] = { *$1, *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+ npy_intp dims[2] = { *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+{
+ npy_intp dims[2] = { *$1, *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+ npy_intp dims[3] = { *$2, *$3, *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+ DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL)
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+{
+ npy_intp dims[3] = { *$1, *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+ npy_intp dims[3] = { *$2, *$3, *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+ DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+{
+ npy_intp dims[3] = { *$1, *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+ $5 = &dim4_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+ npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+ DATA_TYPE** ARGOUTVIEW_ARRAY4)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_ARRAY4)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &dim4_temp;
+ $5 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
+{
+ npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+ $5 = &dim4_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+ npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+ DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &dim4_temp;
+ $5 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
+{
+ npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/*************************************/
+/* Managed Argoutview Array Typemaps */
+/*************************************/
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+{
+ npy_intp dims[1] = { *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim_temp;
+ $2 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+{
+ npy_intp dims[1] = { *$1 };
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+ npy_intp dims[2] = { *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+{
+ npy_intp dims[2] = { *$1, *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+ npy_intp dims[2] = { *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+{
+ npy_intp dims[2] = { *$1, *$2 };
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+ npy_intp dims[3] = { *$2, *$3, *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+ DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+{
+ npy_intp dims[3] = { *$1, *$2, *$3 };
+ PyObject* obj= PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+ npy_intp dims[3] = { *$2, *$3, *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+ DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+{
+ npy_intp dims[3] = { *$1, *$2, *$3 };
+ PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+ $5 = &dim4_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+ npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+ DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &dim4_temp;
+ $5 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+{
+ npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+ $5 = &dim4_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+ npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+ DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &dim4_temp;
+ $5 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+{
+ npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+ $5 = &dim4_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+ npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+ DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &dim4_temp;
+ $5 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+{
+ npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+ DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+ (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
+ (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+ $1 = &data_temp;
+ $2 = &dim1_temp;
+ $3 = &dim2_temp;
+ $4 = &dim3_temp;
+ $5 = &dim4_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+ npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+ DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+ (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
+{
+ $1 = &dim1_temp;
+ $2 = &dim2_temp;
+ $3 = &dim3_temp;
+ $4 = &dim4_temp;
+ $5 = &data_temp;
+}
+%typemap(argout,
+ fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+ (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+{
+ npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+ PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+ PyArrayObject* array = (PyArrayObject*) obj;
+
+ if (!array || require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+ PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+ PyArray_BASE(array) = cap;
+%#else
+ PyArray_SetBaseObject(array,cap);
+%#endif
+
+ $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+%enddef /* %numpy_typemaps() macro */
+/* *************************************************************** */
+
+/* Concrete instances of the %numpy_typemaps() macro: Each invocation
+ * below applies all of the typemaps above to the specified data type.
+ */
+%numpy_typemaps(signed char , NPY_BYTE , int)
+%numpy_typemaps(unsigned char , NPY_UBYTE , int)
+%numpy_typemaps(short , NPY_SHORT , int)
+%numpy_typemaps(unsigned short , NPY_USHORT , int)
+%numpy_typemaps(int , NPY_INT , int)
+%numpy_typemaps(unsigned int , NPY_UINT , int)
+%numpy_typemaps(long , NPY_LONG , int)
+%numpy_typemaps(unsigned long , NPY_ULONG , int)
+%numpy_typemaps(long long , NPY_LONGLONG , int)
+%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
+%numpy_typemaps(float , NPY_FLOAT , int)
+%numpy_typemaps(double , NPY_DOUBLE , int)
+
+/* ***************************************************************
+ * The follow macro expansion does not work, because C++ bool is 4
+ * bytes and NPY_BOOL is 1 byte
+ *
+ * %numpy_typemaps(bool, NPY_BOOL, int)
+ */
+
+/* ***************************************************************
+ * On my Mac, I get the following warning for this macro expansion:
+ * 'swig/python detected a memory leak of type 'long double *', no destructor found.'
+ *
+ * %numpy_typemaps(long double, NPY_LONGDOUBLE, int)
+ */
+
+/* ***************************************************************
+ * Swig complains about a syntax error for the following macro
+ * expansions:
+ *
+ * %numpy_typemaps(complex float, NPY_CFLOAT , int)
+ *
+ * %numpy_typemaps(complex double, NPY_CDOUBLE, int)
+ *
+ * %numpy_typemaps(complex long double, NPY_CLONGDOUBLE, int)
+ */
+
+#endif /* SWIGPYTHON */
diff --git a/python/swig/solid_mechanics_model.i b/python/swig/solid_mechanics_model.i
new file mode 100644
index 000000000..c9ed3632b
--- /dev/null
+++ b/python/swig/solid_mechanics_model.i
@@ -0,0 +1,179 @@
+%{
+ #include "solid_mechanics_model.hh"
+ #include "sparse_matrix.hh"
+ #include "boundary_condition.hh"
+ #include "boundary_condition_functor.hh"
+ #include "boundary_condition_python_functor.hh"
+
+ #include "material_python.hh"
+%}
+
+namespace akantu {
+ %ignore SolidMechanicsModel::initFEEngineBoundary;
+ %ignore SolidMechanicsModel::initParallel;
+ %ignore SolidMechanicsModel::initArrays;
+ %ignore SolidMechanicsModel::initModel;
+ %ignore SolidMechanicsModel::initPBC;
+
+
+ %ignore SolidMechanicsModel::initExplicit;
+ %ignore SolidMechanicsModel::isExplicit;
+ %ignore SolidMechanicsModel::updateCurrentPosition;
+ %ignore SolidMechanicsModel::updateAcceleration;
+ %ignore SolidMechanicsModel::updateIncrement;
+ %ignore SolidMechanicsModel::updatePreviousDisplacement;
+ %ignore SolidMechanicsModel::saveStressAndStrainBeforeDamage;
+ %ignore SolidMechanicsModel::updateEnergiesAfterDamage;
+ %ignore SolidMechanicsModel::solveLumped;
+ %ignore SolidMechanicsModel::explicitPred;
+ %ignore SolidMechanicsModel::explicitCorr;
+
+ %ignore SolidMechanicsModel::initSolver;
+ %ignore SolidMechanicsModel::initImplicit;
+ %ignore SolidMechanicsModel::initialAcceleration;
+
+
+ %ignore SolidMechanicsModel::testConvergence;
+ %ignore SolidMechanicsModel::testConvergenceIncrement;
+ %ignore SolidMechanicsModel::testConvergenceResidual;
+ %ignore SolidMechanicsModel::initVelocityDampingMatrix;
+
+ %ignore SolidMechanicsModel::getNbDataForElements;
+ %ignore SolidMechanicsModel::packElementData;
+ %ignore SolidMechanicsModel::unpackElementData;
+ %ignore SolidMechanicsModel::getNbDataToPack;
+ %ignore SolidMechanicsModel::getNbDataToUnpack;
+ %ignore SolidMechanicsModel::packData;
+ %ignore SolidMechanicsModel::unpackData;
+
+ %ignore SolidMechanicsModel::setMaterialSelector;
+ %ignore SolidMechanicsModel::getSolver;
+ %ignore SolidMechanicsModel::getSynchronizer;
+
+ %ignore Dumpable::registerExternalDumper;
+
+}
+
+%template(SolidMechanicsBoundaryCondition) akantu::BoundaryCondition<akantu::SolidMechanicsModel>;
+
+%include "dumpable.hh"
+
+print_self(SolidMechanicsModel)
+
+%include "solid_mechanics_model.hh"
+
+%extend akantu::SolidMechanicsModel {
+ /* ------------------------------------------------------------------------ */
+ bool testConvergenceSccRes(Real tolerance) {
+ Real error = 0;
+ bool res = self->testConvergence<akantu::_scc_residual>(tolerance, error);
+ return res;
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void solveStaticDisplacement(Real tolerance, UInt max_iteration) {
+ $self->solveStatic<akantu::_scm_newton_raphson_tangent_not_computed,
+ akantu::_scc_residual>(tolerance, max_iteration);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ /// register an empty material of a given type
+ void registerNewPythonMaterial(PyObject * obj, const akantu::ID & mat_type) {
+ std::pair<akantu::Parser::const_section_iterator,
+ akantu::Parser::const_section_iterator>
+ sub_sect = akantu::getStaticParser().getSubSections(akantu::_st_material);
+
+ akantu::Parser::const_section_iterator it = sub_sect.first;
+ for (; it != sub_sect.second; ++it) {
+ if (it->getName() == mat_type) {
+
+ AKANTU_DEBUG_ASSERT($self->materials_names_to_id.find(mat_type) ==
+ $self->materials_names_to_id.end(),
+ "A material with this name '"
+ << mat_type << "' has already been registered. "
+ << "Please use unique names for materials");
+
+ UInt mat_count = $self->materials.size();
+ $self->materials_names_to_id[mat_type] = mat_count;
+
+ std::stringstream sstr_mat;
+ sstr_mat << $self->getID() << ":" << mat_count << ":" << mat_type;
+ akantu::ID mat_id = sstr_mat.str();
+
+ akantu::Material * material = new akantu::MaterialPython(*$self, obj, mat_id);
+ $self->materials.push_back(material);
+
+ material->parseSection(*it);
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void applyDirichletBC(PyObject * func_obj, const std::string & group_name) {
+ akantu::BC::PythonFunctorDirichlet functor(func_obj);
+ $self->applyBC(functor, group_name);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void applyNeumannBC(PyObject * func_obj, const std::string & group_name) {
+ akantu::BC::PythonFunctorNeumann functor(func_obj);
+ $self->applyBC(functor, group_name);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void solveDisplCorr(bool need_factorize, bool has_profile_changed) {
+ akantu::Array<akantu::Real> & increment = $self->getIncrement();
+
+ $self->solve<akantu::IntegrationScheme2ndOrder::_displacement_corrector>(
+ increment, 1., need_factorize, has_profile_changed);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void clearDispl() {
+ akantu::Array<akantu::Real> & displ = $self->getDisplacement();
+ displ.clear();
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void solveStep_TgModifIncr(Real tolerance, UInt max_iteration) {
+ $self->solveStep<akantu::_scm_newton_raphson_tangent_modified,
+ akantu::_scc_increment>(tolerance, max_iteration);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void solveStep_TgIncr(Real tolerance, Real & error, UInt max_iteration) {
+
+ $self->solveStep<akantu::_scm_newton_raphson_tangent,
+ akantu::_scc_increment>(tolerance, error, max_iteration);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void clearDisplVeloAcc() {
+ akantu::Array<akantu::Real> & displ = $self->getDisplacement();
+ akantu::Array<akantu::Real> & velo = $self->getVelocity();
+ akantu::Array<akantu::Real> & acc = $self->getAcceleration();
+
+ displ.clear();
+ velo.clear();
+ acc.clear();
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void applyUniformPressure(Real pressure, const std::string surface_name) {
+ UInt spatial_dimension = $self->getSpatialDimension();
+ akantu::Matrix<akantu::Real> surface_stress(spatial_dimension,
+ spatial_dimension, 0.0);
+
+ for (UInt i = 0; i < spatial_dimension; ++i) {
+ surface_stress(i, i) = -pressure;
+ }
+ $self->applyBC(akantu::BC::Neumann::FromStress(surface_stress),
+ surface_name);
+ }
+
+ /* ------------------------------------------------------------------------ */
+ void blockDOF(const std::string surface_name, SpacialDirection direction) {
+ $self->applyBC(akantu::BC::Dirichlet::FixedValue(0.0, direction),
+ surface_name);
+ }
+}
diff --git a/python/swig/solid_mechanics_model_cohesive.i b/python/swig/solid_mechanics_model_cohesive.i
new file mode 100644
index 000000000..c92801f82
--- /dev/null
+++ b/python/swig/solid_mechanics_model_cohesive.i
@@ -0,0 +1,24 @@
+%{
+#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
new file mode 100644
index 000000000..c6f45e515
--- /dev/null
+++ b/python/swig/structural_mechanics_model.i
@@ -0,0 +1,40 @@
+%{
+ #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 b9ede9f2e..7570d8d50 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,159 +1,160 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
#===============================================================================
-generate_source_list_from_packages(${CMAKE_CURRENT_BINARY_DIR}
+package_get_all_source_files(
AKANTU_LIBRARY_SRCS
- AKANTU_LIBRARY_INLINE_HDRS
- AKANTU_LIBRARY_HDRS
- AKANTU_LIBRARY_INCLUDE_DIRS)
+ AKANTU_LIBRARY_PUBLIC_HDRS
+ AKANTU_LIBRARY_PRIVATE_HDRS
+ )
+
+package_get_all_include_directories(
+ AKANTU_LIBRARY_INCLUDE_DIRS
+ )
+
+package_get_all_external_informations(
+ AKANTU_EXTERNAL_INCLUDE_DIR
+ AKANTU_EXTERNAL_LIBRARIES
+)
#===========================================================================
# header for blas/lapack (any other fortran libraries)
#===========================================================================
-if(AKANTU_LAPACK OR AKANTU_BLAS)
+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_HDRS ${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh)
+ list(APPEND AKANTU_LIBRARY_PUBLIC_HDRS
+ ${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh)
endif()
-configure_file(common/aka_config.hh.in "${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh" @ONLY)
-list(APPEND AKANTU_LIBRARY_HDRS ${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh)
+
+#===========================================================================
+# configurations
+#===========================================================================
+package_get_all_material_includes(AKANTU_MATERIAL_INCLUDES)
+package_get_all_material_lists(AKANTU_MATERIAL_LISTS)
+configure_file(model/solid_mechanics/material_list.hh.in
+ "${CMAKE_CURRENT_BINARY_DIR}/material_list.hh" @ONLY)
+
+package_get_element_lists()
+configure_file(common/aka_element_classes_info.hh.in
+ "${CMAKE_CURRENT_BINARY_DIR}/aka_element_classes_info.hh" @ONLY)
+
+configure_file(common/aka_config.hh.in
+ "${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh" @ONLY)
+
+list(APPEND AKANTU_LIBRARY_PUBLIC_HDRS
+ ${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh
+ ${CMAKE_CURRENT_BINARY_DIR}/material_list.hh)
+list(APPEND AKANTU_LIBRARY_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
#===========================================================================
# header precompilation
#===========================================================================
set(AKANTU_COMMON_HDR_TO_PRECOMPILE
common/aka_vector.hh
common/aka_math.hh
common/aka_types.hh
fem/element_class.hh
)
set(AKANTU_PRECOMPILE_HDR_INCLUDE_DIRS
${CMAKE_CURRENT_BINARY_DIR}/common/
${CMAKE_CURRENT_BINARY_DIR}/fem/
)
set(AKANTU_INCLUDE_DIRS
${CMAKE_CURRENT_BINARY_DIR} ${AKANTU_LIBRARY_INCLUDE_DIRS} ${AKANTU_PRECOMPILE_HDR_INCLUDE_DIRS}
CACHE INTERNAL "Internal include directories to link with Akantu as a subproject")
-include_directories(${AKANTU_INCLUDE_DIRS} ${AKANTU_EXTERNAL_LIB_INCLUDE_DIR})
-
-function(generate_material_list)
- message(STATUS "Determining the list of recognized materials...")
-
- set(_include_dirs ${AKANTU_INCLUDE_DIRS} ${AKANTU_EXTERNAL_LIB_INCLUDE_DIR})
-
- try_run(_material_list_run _material_list_compile
- ${CMAKE_BINARY_DIR}
- ${PROJECT_SOURCE_DIR}/cmake/material_lister.cc
- CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${_include_dirs}"
- COMPILE_DEFINITIONS "-DAKANTU_CMAKE_LIST_MATERIALS"
- COMPILE_OUTPUT_VARIABLE _compile_results
- RUN_OUTPUT_VARIABLE _result_material_list)
-
- if(_material_list_compile AND "${_material_list_run}" EQUAL 0)
- message(STATUS "Materials included in Akantu:")
- string(REPLACE "\n" ";" _material_list "${_result_material_list}")
- foreach(_mat ${_material_list})
- string(REPLACE ":" ";" _mat_key "${_mat}")
- list(GET _mat_key 0 _key)
- list(GET _mat_key 1 _class)
- list(LENGTH _mat_key _l)
-
- if("${_l}" GREATER 2)
- list(REMOVE_AT _mat_key 0 1)
- set(_opt " -- options: [")
- foreach(_o ${_mat_key})
- set(_opt "${_opt} ${_o}")
- endforeach()
- set(_opt "${_opt} ]")
- else()
- set(_opt "")
- endif()
-
- message(STATUS " ${_class} -- key: ${_key}${_opt}")
- endforeach()
- else()
- message(STATUS "Could not determine the list of materials.")
- message("${_compile_results}")
- endif()
-endfunction()
+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})
-if(AKANTU_EXTRA_TARGET_DEPENDENCIES)
- add_dependencies(akantu ${AKANTU_EXTRA_TARGET_DEPENDENCIES})
+# the repetition is ugly but works for static libraries
+target_link_libraries(akantu ${AKANTU_EXTERNAL_LIBRARIES} ${AKANTU_EXTERNAL_LIBRARIES})
+
+set_target_properties(akantu PROPERTIES LINK_INTERFACE_MULTIPLICITY 0)
+package_get_all_extra_dependencies(_extra_target_dependencies)
+if(_extra_target_dependencies)
+ # This only adding todo: find a solution for when a dependency was add the is removed...
+ add_dependencies(akantu ${_extra_target_dependencies})
endif()
-list(APPEND AKANTU_PUBLIC_HDRS ${AKANTU_LIBRARY_HDRS} ${AKANTU_LIBRARY_INLINE_HDRS})
set_target_properties(akantu PROPERTIES ${AKANTU_LIBRARY_PROPERTIES})
-set_target_properties(akantu PROPERTIES PUBLIC_HEADER "${AKANTU_PUBLIC_HDRS}")
+set_target_properties(akantu PROPERTIES PUBLIC_HEADER "${AKANTU_LIBRARY_PUBLIC_HDRS}")
list(APPEND AKANTU_EXPORT_LIST akantu)
+# TODO separate public from private headers
install(TARGETS akantu
EXPORT ${AKANTU_TARGETS_EXPORT}
LIBRARY DESTINATION lib COMPONENT lib
ARCHIVE DESTINATION lib COMPONENT lib
+ RUNTIME DESTINATION bin COMPONENT bin
PUBLIC_HEADER DESTINATION include/akantu/ COMPONENT dev
)
if("${AKANTU_TARGETS_EXPORT}" STREQUAL "AkantuLibraryDepends")
install(EXPORT AkantuLibraryDepends DESTINATION lib/akantu
COMPONENT dev)
endif()
#Export for build tree
export(TARGETS ${AKANTU_EXPORT_LIST}
FILE "${CMAKE_BINARY_DIR}/AkantuLibraryDepends.cmake")
export(PACKAGE Akantu)
diff --git a/src/common/aka_array.hh b/src/common/aka_array.hh
index 0f9de47ea..d369d83e3 100644
--- a/src/common/aka_array.hh
+++ b/src/common/aka_array.hh
@@ -1,372 +1,368 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 <cstring>
-
#include <vector>
-
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/// class that afford to store vectors in static memory
class ArrayBase {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ArrayBase(const ID & id = "");
virtual ~ArrayBase();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// get the amount of space allocated in bytes
inline UInt getMemorySize() const;
/// set the size to zero without freeing the allocated space
inline void empty();
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// Get the real size allocated in memory
AKANTU_GET_MACRO(AllocatedSize, allocated_size, UInt);
/// Get the Size of the Array
AKANTU_GET_MACRO(Size, size, UInt);
/// Get the number of components
AKANTU_GET_MACRO(NbComponent, nb_component, UInt);
/// Get the name of th array
AKANTU_GET_MACRO(ID, id, const ID &);
+ /// Set the name of th array
+ AKANTU_SET_MACRO(ID, id, const ID &);
// AKANTU_GET_MACRO(Tag, tag, const std::string &);
// AKANTU_SET_MACRO(Tag, tag, const std::string &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// id of the vector
ID id;
/// the size allocated
UInt allocated_size;
/// the size used
UInt size;
/// number of components
UInt nb_component;
/// size of the stored type
UInt size_of_type;
// /// User defined tag
// std::string tag;
};
/* -------------------------------------------------------------------------- */
-/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<typename T, bool is_scal>
class Array : public ArrayBase {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef T value_type;
typedef value_type & reference;
typedef value_type * pointer_type;
typedef const value_type & const_reference;
/// Allocation of a new vector
inline Array(UInt size = 0, UInt nb_component = 1,
const ID & id = "");
/// Allocation of a new vector with a default value
Array(UInt size, UInt nb_component,
const value_type def_values[], const ID & id = "");
/// Allocation of a new vector with a default value
Array(UInt size, UInt nb_component,
const_reference value, const ID & id = "");
/// Copy constructor (deep copy if deep=true)
Array(const Array<value_type, is_scal>& vect, bool deep = true, const ID & id = "");
+#ifndef SWIG
/// Copy constructor (deep copy)
Array(const std::vector<value_type> & vect);
-
+#endif
virtual inline ~Array();
Array & operator=(const Array & a) {
/// this is to let STL allocate and copy arrays in the case of std::vector::resize
AKANTU_DEBUG_ASSERT(this->size == 0,"Cannot copy akantu::Array");
return const_cast<Array&>(a);
}
/* ------------------------------------------------------------------------ */
/* Iterator */
/* ------------------------------------------------------------------------ */
/// \todo protected: does not compile with intel check why
public:
template <class R, class IR = R, bool issame = is_same<IR, T>::value >
class iterator_internal;
public:
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
template<typename R = T> class const_iterator;
template<typename R = T> class iterator;
/* ------------------------------------------------------------------------ */
/// iterator for Array of nb_component = 1
typedef iterator< T > scalar_iterator;
/// const_iterator for Array of nb_component = 1
typedef const_iterator< T > const_scalar_iterator;
/// iterator rerturning Vectors of size n on entries of Array with nb_component = n
typedef iterator< Vector<T> > vector_iterator;
/// const_iterator rerturning Vectors of n size on entries of Array with nb_component = n
typedef const_iterator< Vector<T> > const_vector_iterator;
/// iterator rerturning Matrices of size (m, n) on entries of Array with nb_component = m*n
typedef iterator< Matrix<T> > matrix_iterator;
/// const iterator rerturning Matrices of size (m, n) on entries of Array with nb_component = m*n
typedef const_iterator< Matrix<T> > const_matrix_iterator;
/* ------------------------------------------------------------------------ */
/// Get an iterator that behaves like a pointer T * to the first entry
- inline iterator<T> begin();
+ inline scalar_iterator begin();
/// Get an iterator that behaves like a pointer T * to the end of the Array
- inline iterator<T> end();
+ inline scalar_iterator end();
/// Get a const_iterator to the beginging of an Array of scalar
- inline const_iterator<T> begin() const;
+ inline const_scalar_iterator begin() const;
/// Get a const_iterator to the end of an Array of scalar
- inline const_iterator<T> end() const;
+ inline const_scalar_iterator end() const;
/* ------------------------------------------------------------------------ */
/// Get a vector_iterator on the begining of the Array
inline vector_iterator begin(UInt n);
/// Get a vector_iterator on the end of the Array
inline vector_iterator end(UInt n);
/// Get a vector_iterator on the begining of the Array
inline const_vector_iterator begin(UInt n) const;
/// Get a vector_iterator on the end of the Array
inline const_vector_iterator end(UInt n) const;
/// Get a vector_iterator on the begining of the Array considered of shape (new_size, n)
inline vector_iterator begin_reinterpret(UInt n, UInt new_size);
/// Get a vector_iterator on the end of the Array considered of shape (new_size, n)
inline vector_iterator end_reinterpret(UInt n, UInt new_size);
/// Get a const_vector_iterator on the begining of the Array considered of shape (new_size, n)
inline const_vector_iterator begin_reinterpret(UInt n, UInt new_size) const;
/// Get a const_vector_iterator on the end of the Array considered of shape (new_size, n)
inline const_vector_iterator end_reinterpret(UInt n, UInt new_size) const;
/* ------------------------------------------------------------------------ */
/// Get a matrix_iterator on the begining of the Array (Matrices of size (m, n))
inline matrix_iterator begin(UInt m, UInt n);
/// Get a matrix_iterator on the end of the Array (Matrices of size (m, n))
inline matrix_iterator end(UInt m, UInt n);
/// Get a const_matrix_iterator on the begining of the Array (Matrices of size (m, n))
inline const_matrix_iterator begin(UInt m, UInt n) const;
/// Get a const_matrix_iterator on the end of the Array (Matrices of size (m, n))
inline const_matrix_iterator end(UInt m, UInt n) const;
/// Get a matrix_iterator on the begining of the Array considered of shape (new_size, m*n)
inline matrix_iterator begin_reinterpret(UInt m, UInt n, UInt size);
/// Get a matrix_iterator on the end of the Array considered of shape (new_size, m*n)
inline matrix_iterator end_reinterpret(UInt m, UInt n, UInt size);
/// Get a const_matrix_iterator on the begining of the Array considered of shape (new_size, m*n)
inline const_matrix_iterator begin_reinterpret(UInt m, UInt n, UInt size) const;
/// Get a const_matrix_iterator on the end of the Array considered of shape (new_size, m*n)
inline const_matrix_iterator end_reinterpret(UInt m, UInt n, UInt size) const;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// append a tuple of size nb_component containing value
inline void push_back(const_reference value);
/// append a vector
inline void push_back(const value_type new_elem[]);
/// append a Vector or a Matrix
template<template<typename> class C>
inline void push_back(const C<T> & new_elem);
/// append the value of the iterator
template<typename Ret>
inline void push_back(const iterator<Ret> & it);
/// erase the value at position i
inline void erase(UInt i);
/// ask Nico, clarify
template<typename R>
inline iterator<R> erase(const iterator<R> & it);
/// change the size of the Array
- void resize(UInt size);
+ virtual void resize(UInt size);
/// change the number of components by interlacing data
+ /// @param multiplicator number of interlaced components add
+ /// @param block_size blocks of data in the array
+ /// Examaple for block_size = 2, multiplicator = 2
+ /// array = oo oo oo -> new array = oo nn nn oo nn nn oo nn nn
void extendComponentsInterlaced(UInt multiplicator, UInt stride);
/// search elem in the vector, return the position of the first occurrence or -1 if not found
Int find(const_reference elem) const;\
/// @see Array::find(const_reference elem) const
Int find(T elem[]) const;
/// set all entries of the array to 0
inline void clear() { std::fill_n(values, size*nb_component, T()); }
/// set all entries of the array to the value t
/// @param t value to fill the array with
inline void set(T t) { std::fill_n(values, size*nb_component, t); }
/// set all tuples of the array to a given vector or matrix
/// @param vm Matrix or Vector to fill the array with
template<template<typename> class C>
inline void set(const C<T> & vm);
/// copy another Array in the current Array, the no_sanity_check allows you to
/// force the copy in cases where you know what you do with two non matching
/// Arrays in terms of n
void copy(const Array<T, is_scal> & other, bool no_sanity_check = false);
/// give the address of the memory allocated for this vector
T * storage() const { return values; };
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
/// perform the allocation for the constructors
void allocate(UInt size, UInt nb_component = 1);
/// resize without initializing the memory
void resizeUnitialized(UInt new_size);
/* ------------------------------------------------------------------------ */
/* Operators */
/* ------------------------------------------------------------------------ */
public:
/// substraction entry-wise
Array<T, is_scal> & operator-=(const Array<T, is_scal> & other);
/// addition entry-wise
Array<T, is_scal> & operator+=(const Array<T, is_scal> & other);
/// multiply evry entry by alpha
Array<T, is_scal> & operator*=(const T & alpha);
/// check if the array are identical entry-wise
bool operator==(const Array<T, is_scal> & other) const;
/// @see Array::operator==(const Array<T, is_scal> & other) const
bool operator!=(const Array<T, is_scal> & other) const;
/// return a reference to the j-th entry of the i-th tuple
inline reference operator()(UInt i, UInt j = 0);
/// return a const reference to the j-th entry of the i-th tuple
inline const_reference operator()(UInt i, UInt j = 0) const;
/// return a reference to the ith component of the 1D array
inline reference operator[](UInt i);
/// return a const reference to the ith component of the 1D array
inline const_reference operator[](UInt i) const;
-
- /* ------------------------------------------------------------------------ */
- /* 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)
{
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
/* Inline Functions ArrayBase */
/* -------------------------------------------------------------------------- */
inline std::ostream & operator<<(std::ostream & stream, const ArrayBase & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_VECTOR_HH__ */
diff --git a/src/common/aka_array_tmpl.hh b/src/common/aka_array_tmpl.hh
index aef0c181d..5b5091e88 100644
--- a/src/common/aka_array_tmpl.hh
+++ b/src/common/aka_array_tmpl.hh
@@ -1,1278 +1,1298 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* Inline Functions Array<T> */
/* -------------------------------------------------------------------------- */
__END_AKANTU__
#include <memory>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline T & Array<T, is_scal>::operator()(UInt i, UInt j) {
AKANTU_DEBUG_ASSERT(size > 0,
"The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size) && (j < nb_component),
"The value at position [" << i << "," << j
<< "] is out of range in array \"" << id << "\"");
return values[i*nb_component + j];
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline const T & Array<T, is_scal>::operator()(UInt i, UInt j) const {
AKANTU_DEBUG_ASSERT(size > 0,
"The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size) && (j < nb_component),
"The value at position [" << i << "," << j
<< "] is out of range in array \"" << id << "\"");
return values[i*nb_component + j];
}
template <class T, bool is_scal>
inline T & Array<T, is_scal>::operator[](UInt i) {
AKANTU_DEBUG_ASSERT(size > 0,
"The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size*nb_component),
"The value at position [" << i << "] is out of range in array \"" << id << "\"");
return values[i];
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
inline const T & Array<T, is_scal>::operator[](UInt i) const {
AKANTU_DEBUG_ASSERT(size > 0,
"The array \"" << id << "\" is empty");
AKANTU_DEBUG_ASSERT((i < size*nb_component),
"The value at position [" << i << "] is out of range in array \"" << id << "\"");
return values[i];
}
/* -------------------------------------------------------------------------- */
/**
- * append a tuple to the array with the value value for all
- * components
+ * append a tuple to the array with the value value for all components
* @param value the new last tuple or the array will contain nb_component copies of value
*/
template <class T, bool is_scal>
inline void Array<T, is_scal>::push_back(const T & value) {
UInt pos = size;
resizeUnitialized(size+1);
std::uninitialized_fill_n(values + pos * nb_component, nb_component, value);
}
/* -------------------------------------------------------------------------- */
/**
* append a tuple to the array
* @param new_elem a C-array containing the values to be copied to the end of the array */
template <class T, bool is_scal>
inline void Array<T, is_scal>::push_back(const T new_elem[]) {
UInt pos = size;
resizeUnitialized(size+1);
T * tmp = values + nb_component * pos;
std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
}
/* -------------------------------------------------------------------------- */
/**
* append a matrix or a vector to the array
* @param new_elem a reference to a Matrix<T> or Vector<T> */
template <class T, bool is_scal>
template<template<typename> class C>
inline void Array<T, is_scal>::push_back(const C<T> & new_elem) {
AKANTU_DEBUG_ASSERT(nb_component == new_elem.size(),
"The vector("<< new_elem.size() <<") as not a size compatible with the Array (nb_component=" << nb_component << ").");
UInt pos = size;
resizeUnitialized(size+1);
T * tmp = values + nb_component * pos;
std::uninitialized_copy(new_elem.storage(), new_elem.storage() + nb_component, tmp);
}
/* -------------------------------------------------------------------------- */
/**
* append a tuple to the array
* @param it an iterator to the tuple to be copied to the end of the array */
template <class T, bool is_scal>
template<class Ret>
inline void Array<T, is_scal>::push_back(const Array<T, is_scal>::iterator<Ret> & it) {
UInt pos = size;
resizeUnitialized(size+1);
T * tmp = values + nb_component * pos;
T * new_elem = it.data();
std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
}
/* -------------------------------------------------------------------------- */
/**
* erase an element. If the erased element is not the last of the array, the
* last element is moved into the hole in order to maintain contiguity. This
* may invalidate existing iterators (For instance an iterator obtained by
* Array::end() is no longer correct) and will change the order of the
* elements.
* @param i index of element to erase
*/
template <class T, bool is_scal>
inline void Array<T, is_scal>::erase(UInt i){
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT((size > 0),
"The array is empty");
AKANTU_DEBUG_ASSERT((i < size),
"The element at position [" << i << "] is out of range (" << i << ">=" << size << ")");
if(i != (size - 1)) {
for (UInt j = 0; j < nb_component; ++j) {
values[i*nb_component + j] = values[(size-1)*nb_component + j];
}
}
resize(size - 1);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Subtract another array entry by entry from this array in place. Both arrays must
* have the same size and nb_component. If the arrays have different shapes,
* code compiled in debug mode will throw an expeption and optimised code
* will behave in an unpredicted manner
* @param other array to subtract from this
* @return reference to modified this
*/
template <class T, bool is_scal>
Array<T, is_scal> & Array<T, is_scal>::operator-=(const Array<T, is_scal> & vect) {
AKANTU_DEBUG_ASSERT((size == vect.size) && (nb_component == vect.nb_component),
"The too array don't have the same sizes");
T * a = values;
T * b = vect.storage();
for (UInt i = 0; i < size*nb_component; ++i) {
*a -= *b;
++a;++b;
}
return *this;
}
/* -------------------------------------------------------------------------- */
/**
* Add another array entry by entry to this array in place. Both arrays must
* have the same size and nb_component. If the arrays have different shapes,
* code compiled in debug mode will throw an expeption and optimised code
* will behave in an unpredicted manner
* @param other array to add to this
* @return reference to modified this
*/
template <class T, bool is_scal>
Array<T, is_scal> & Array<T, is_scal>::operator+=(const Array<T, is_scal> & vect) {
AKANTU_DEBUG_ASSERT((size == vect.size) && (nb_component == vect.nb_component),
"The too array don't have the same sizes");
T * a = values;
T * b = vect.storage();
for (UInt i = 0; i < size*nb_component; ++i) {
*a++ += *b++;
}
return *this;
}
/* -------------------------------------------------------------------------- */
/**
* Multiply all entries of this array by a scalar in place
* @param alpha scalar multiplicant
* @return reference to modified this
*/
template <class T, bool is_scal>
Array<T, is_scal> & Array<T, is_scal>::operator*=(const T & alpha) {
T * a = values;
for (UInt i = 0; i < size*nb_component; ++i) {
*a++ *= alpha;
}
return *this;
}
/* -------------------------------------------------------------------------- */
/**
* Compare this array element by element to another.
* @param other array to compare to
* @return true it all element are equal and arrays have the same shape, else false
*/
template <class T, bool is_scal>
bool Array<T, is_scal>::operator==(const Array<T, is_scal> & array) const {
bool equal = nb_component == array.nb_component && size == array.size && id == array.id;
if(!equal) return false;
if(values == array.storage()) return true;
else return std::equal(values, values + size*nb_component,
array.storage());
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
bool Array<T, is_scal>::operator!=(const Array<T, is_scal> & array) const {
return !operator==(array);
}
/* -------------------------------------------------------------------------- */
+/**
+ * set all tuples of the array to a given vector or matrix
+ * @param vm Matrix or Vector to fill the array with
+ */
template <class T, bool is_scal>
template<template<typename> class C>
inline void Array<T, is_scal>::set(const C<T> & vm) {
AKANTU_DEBUG_ASSERT(nb_component == vm.size(),
"The size of the object does not match the number of components");
for (T * it = values;
it < values + nb_component * size;
it += nb_component) {
std::copy(vm.storage(), vm.storage() + nb_component, it);
}
}
/* -------------------------------------------------------------------------- */
/* Functions Array<T, is_scal> */
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array (UInt size,
UInt nb_component,
const ID & id) :
ArrayBase(id), values(NULL) {
AKANTU_DEBUG_IN();
allocate(size, nb_component);
if(!is_scal) {
T val = T();
std::uninitialized_fill(values, values + size*nb_component, val);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array (UInt size,
UInt nb_component,
const T def_values[],
const ID & id) :
ArrayBase(id), values(NULL) {
AKANTU_DEBUG_IN();
allocate(size, nb_component);
T * tmp = values;
for (UInt i = 0; i < size; ++i) {
tmp = values + nb_component * i;
std::uninitialized_copy(def_values, def_values + nb_component, tmp);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array (UInt size,
UInt nb_component,
const T & value,
const ID & id) :
ArrayBase(id), values(NULL) {
AKANTU_DEBUG_IN();
allocate(size, nb_component);
std::uninitialized_fill_n(values, size*nb_component, value);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::Array(const Array<T, is_scal> & vect,
bool deep,
const ID & id) {
AKANTU_DEBUG_IN();
this->id = (id == "") ? vect.id : id;
if (deep) {
allocate(vect.size, vect.nb_component);
T * tmp = values;
std::uninitialized_copy(vect.storage(), vect.storage() + size * nb_component, tmp);
} else {
this->values = vect.storage();
this->size = vect.size;
this->nb_component = vect.nb_component;
this->allocated_size = vect.allocated_size;
this->size_of_type = vect.size_of_type;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
+#ifndef SWIG
template <class T, bool is_scal>
Array<T, is_scal>::Array(const std::vector<T>& vect) {
AKANTU_DEBUG_IN();
this->id = "";
allocate(vect.size(), 1);
T * tmp = values;
std::uninitialized_copy(&(vect[0]), &(vect[size-1]), tmp);
AKANTU_DEBUG_OUT();
}
-
+#endif
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Array<T, is_scal>::~Array () {
AKANTU_DEBUG_IN();
AKANTU_DEBUG(dblAccessory, "Freeing "
<< printMemorySize<T>(allocated_size*nb_component)
<< " (" << id <<")");
if(values){
if(!is_scal)
for (UInt i = 0; i < size * nb_component; ++i) {
T * obj = values+i;
obj->~T();
}
free(values);
}
size = allocated_size = 0;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
+/**
+ * perform the allocation for the constructors
+ * @param size is the size of the array
+ * @param nb_component is the number of component of the array
+ */
template <class T, bool is_scal>
void Array<T, is_scal>::allocate(UInt size,
UInt nb_component) {
AKANTU_DEBUG_IN();
if (size == 0){
values = NULL;
} else {
values = static_cast<T*>(malloc(nb_component * size * sizeof(T)));
AKANTU_DEBUG_ASSERT(values != NULL,
"Cannot allocate "
<< printMemorySize<T>(size*nb_component)
<< " (" << id <<")");
}
if (values == NULL) {
this->size = this->allocated_size = 0;
} else {
AKANTU_DEBUG(dblAccessory, "Allocated "
<< printMemorySize<T>(size*nb_component)
<< " (" << id <<")");
this->size = this->allocated_size = size;
}
this->size_of_type = sizeof(T);
this->nb_component = nb_component;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* change the size of the array and allocate or free memory if needed. If the
* size increases, the new tuples are filled with zeros
- * @param size new number of tuples contained in the array */
+ * @param new_size new number of tuples contained in the array */
template <class T, bool is_scal>
void Array<T, is_scal>::resize(UInt new_size) {
UInt old_size = size;
T * old_values = values;
if(new_size < size) {
for (UInt i = new_size * nb_component; i < size * nb_component; ++i) {
T * obj = old_values+i;
obj->~T();
}
}
resizeUnitialized(new_size);
T val = T();
if(size > old_size)
std::uninitialized_fill(values + old_size*nb_component, values + size*nb_component, val);
}
/* -------------------------------------------------------------------------- */
+/**
+ * change the size of the array and allocate or free memory if needed.
+ * @param new_size new number of tuples contained in the array */
template <class T, bool is_scal>
void Array<T, is_scal>::resizeUnitialized(UInt new_size) {
// AKANTU_DEBUG_IN();
// free some memory
if(new_size <= allocated_size) {
if(allocated_size - new_size > AKANTU_MIN_ALLOCATION) {
AKANTU_DEBUG(dblAccessory, "Freeing "
<< printMemorySize<T>((allocated_size - size)*nb_component)
<< " (" << id <<")");
// Normally there are no allocation problem when reducing an array
T * tmp_ptr = static_cast<T*>(realloc(values, new_size * nb_component * sizeof(T)));
if(new_size != 0 && tmp_ptr == NULL) {
AKANTU_DEBUG_ERROR("Cannot free data (" << id << ")"
<< " [current allocated size : " << allocated_size << " | "
<< "requested size : " << new_size << "]");
}
values = tmp_ptr;
allocated_size = new_size;
}
size = new_size;
// AKANTU_DEBUG_OUT();
return;
}
// allocate more memory
UInt size_to_alloc = (new_size - allocated_size < AKANTU_MIN_ALLOCATION) ?
allocated_size + AKANTU_MIN_ALLOCATION : new_size;
T *tmp_ptr = static_cast<T*>(realloc(values, size_to_alloc * nb_component * sizeof(T)));
AKANTU_DEBUG_ASSERT(tmp_ptr != NULL,
"Cannot allocate "
<< printMemorySize<T>(size_to_alloc * nb_component));
if (tmp_ptr == NULL) {
AKANTU_DEBUG_ERROR("Cannot allocate more data (" << id << ")"
<< " [current allocated size : " << allocated_size << " | "
<< "requested size : " << new_size << "]");
}
AKANTU_DEBUG(dblAccessory, "Allocating "
<< printMemorySize<T>((size_to_alloc - allocated_size)*nb_component));
allocated_size = size_to_alloc;
size = new_size;
values = tmp_ptr;
// AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
+/**
+ * change the number of components by interlacing data
+ * @param multiplicator number of interlaced components add
+ * @param block_size blocks of data in the array
+ * Examaple for block_size = 2, multiplicator = 2
+ * array = oo oo oo -> new array = oo nn nn oo nn nn oo nn nn */
template <class T, bool is_scal>
void Array<T, is_scal>::extendComponentsInterlaced(UInt multiplicator,
UInt block_size) {
AKANTU_DEBUG_IN();
if (multiplicator == 1) return;
AKANTU_DEBUG_ASSERT(multiplicator > 1,
"invalid multiplicator");
AKANTU_DEBUG_ASSERT(nb_component%block_size == 0,
"stride must divide actual number of components");
values = static_cast<T*>(realloc(values, nb_component*multiplicator*size* sizeof(T)));
UInt new_component = nb_component/block_size * multiplicator;
for (UInt i = 0,k=size-1; i < size; ++i,--k) {
for (UInt j = 0; j < new_component; ++j) {
UInt m = new_component - j -1;
UInt n = m/multiplicator;
for (UInt l = 0,p=block_size-1; l < block_size; ++l,--p) {
values[k*nb_component*multiplicator+m*block_size+p] =
values[k*nb_component+n*block_size+p];
}
}
}
nb_component = nb_component * multiplicator;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* search elem in the array, return the position of the first occurrence or
* -1 if not found
* @param elem the element to look for
* @return index of the first occurrence of elem or -1 if elem is not present
*/
template <class T, bool is_scal>
Int Array<T, is_scal>::find(const T & elem) const {
AKANTU_DEBUG_IN();
UInt i = 0;
for (; (i < size) && (values[i] != elem); ++i);
AKANTU_DEBUG_OUT();
return (i == size) ? -1 : (Int) i;
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
Int Array<T, is_scal>::find(T elem[]) const {
AKANTU_DEBUG_IN();
T * it = values;
UInt i = 0;
for (;i < size; ++i) {
if(*it == elem[0]) {
T * cit = it;
UInt c = 0;
for(; (c < nb_component) && (*cit == elem[c]); ++c, ++cit);
if(c == nb_component) {
AKANTU_DEBUG_OUT();
return i;
}
}
it += nb_component;
}
return -1;
}
/* -------------------------------------------------------------------------- */
/**
* copy the content of another array. This overwrites the current content.
* @param other Array to copy into this array. It has to have the same
* nb_component as this. If compiled in debug mode, an incorrect other will
* result in an exception being thrown. Optimised code may result in
* unpredicted behaviour.
*/
template <class T, bool is_scal>
void Array<T, is_scal>::copy(const Array<T, is_scal>& vect, bool no_sanity_check) {
AKANTU_DEBUG_IN();
if(!no_sanity_check)
if(vect.nb_component != nb_component)
AKANTU_DEBUG_ERROR("The two arrays do not have the same number of components");
resize((vect.size * vect.nb_component) / nb_component);
T * tmp = values;
std::uninitialized_copy(vect.storage(), vect.storage() + size * nb_component, tmp);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<bool is_scal>
class ArrayPrintHelper {
public:
template<typename T>
static void print_content(const Array<T> & vect, std::ostream & stream, int indent) {
- if(AKANTU_DEBUG_TEST(dblDump)) {
+ if(AKANTU_DEBUG_TEST(dblDump) || AKANTU_DEBUG_LEVEL_IS_TEST()) {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << " + values : {";
for (UInt i = 0; i < vect.getSize(); ++i) {
stream << "{";
for (UInt j = 0; j < vect.getNbComponent(); ++j) {
stream << vect(i, j);
if(j != vect.getNbComponent() - 1) stream << ", ";
}
stream << "}";
if(i != vect.getSize() - 1) stream << ", ";
}
stream << "}" << std::endl;
}
}
};
template<>
class ArrayPrintHelper<false> {
public:
template<typename T>
static void print_content(__attribute__((unused)) const Array<T> & vect,
__attribute__((unused)) std::ostream & stream,
__attribute__((unused)) int indent) { }
};
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
void Array<T, is_scal>::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
std::streamsize prec = stream.precision();
std::ios_base::fmtflags ff = stream.flags();
stream.setf (std::ios_base::showbase);
stream.precision(2);
stream << space << "Array<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
stream << space << " + id : " << this->id << std::endl;
stream << space << " + size : " << this->size << std::endl;
stream << space << " + nb_component : " << this->nb_component << std::endl;
stream << space << " + allocated size : " << this->allocated_size << std::endl;
stream << space << " + memory size : "
<< printMemorySize<T>(allocated_size*nb_component) << std::endl;
if(!AKANTU_DEBUG_LEVEL_IS_TEST())
stream << space << " + address : " << std::hex << this->values
<< std::dec << std::endl;
stream.precision(prec);
stream.flags(ff);
ArrayPrintHelper<is_scal>::print_content(*this, stream, indent);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
/* Inline Functions ArrayBase */
/* -------------------------------------------------------------------------- */
inline UInt ArrayBase::getMemorySize() const {
return allocated_size * nb_component * size_of_type;
}
inline void ArrayBase::empty() {
size = 0;
}
/* -------------------------------------------------------------------------- */
/* Iterators */
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template<class R, class IR, bool is_r_scal>
class Array<T, is_scal>::iterator_internal {
public:
typedef R value_type;
typedef R* pointer;
typedef R& reference;
+ typedef typename R::proxy proxy;
+ typedef const typename R::proxy const_proxy;
typedef const R& const_reference;
typedef IR internal_value_type;
typedef IR* internal_pointer;
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
public:
iterator_internal() : _offset(0), initial(NULL), ret(NULL), ret_ptr(NULL) {};
iterator_internal(pointer_type data, UInt _offset) :
_offset(_offset),
initial(data),
ret(NULL),
ret_ptr(data) {
AKANTU_DEBUG_ERROR("The constructor should never be called it is just an ugly trick...");
}
iterator_internal(pointer wrapped) : _offset(wrapped->size()),
initial(wrapped->storage()),
ret(const_cast<internal_pointer>(wrapped)),
ret_ptr(wrapped->storage()) {
}
iterator_internal(const iterator_internal & it) {
if(this != &it) {
this->_offset = it._offset;
this->initial = it.initial;
this->ret_ptr = it.ret_ptr;
this->ret = new internal_value_type(*it.ret, false);
}
}
virtual ~iterator_internal() { delete ret; };
inline iterator_internal & operator=(const iterator_internal & it) {
if(this != &it) {
this->_offset = it._offset;
this->initial = it.initial;
this->ret_ptr = it.ret_ptr;
if(this->ret) this->ret->shallowCopy(*it.ret);
else this->ret = new internal_value_type(*it.ret, false);
}
return *this;
}
UInt getCurrentIndex(){return (this->ret_ptr - this->initial)/this->_offset;};
inline reference operator*() { ret->values = ret_ptr; return *ret; };
inline const_reference operator*() const { ret->values = ret_ptr; return *ret; };
inline pointer operator->() { ret->values = ret_ptr; return ret; };
inline iterator_internal & operator++() { ret_ptr += _offset; return *this; };
inline iterator_internal & operator--() { ret_ptr -= _offset; return *this; };
inline iterator_internal & operator+=(const UInt n) { ret_ptr += _offset * n; return *this; }
inline iterator_internal & operator-=(const UInt n) { ret_ptr -= _offset * n; return *this; }
- inline reference operator[](const UInt n) { ret->values = ret_ptr + n*_offset; return *ret; }
- inline const_reference operator[](const UInt n) const { ret->values = ret_ptr + n*_offset; return *ret; }
+ inline proxy operator[](const UInt n) { ret->values = ret_ptr + n*_offset; return proxy(*ret); }
+ inline const_proxy operator[](const UInt n) const { ret->values = ret_ptr + n*_offset; return const_proxy(*ret); }
inline bool operator==(const iterator_internal & other) const { return this->ret_ptr == other.ret_ptr; }
inline bool operator!=(const iterator_internal & other) const { return this->ret_ptr != other.ret_ptr; }
inline bool operator <(const iterator_internal & other) const { return this->ret_ptr < other.ret_ptr; }
inline bool operator<=(const iterator_internal & other) const { return this->ret_ptr <= other.ret_ptr; }
inline bool operator> (const iterator_internal & other) const { return this->ret_ptr > other.ret_ptr; }
inline bool operator>=(const iterator_internal & other) const { return this->ret_ptr >= other.ret_ptr; }
inline iterator_internal operator+(difference_type n) { iterator_internal tmp(*this); tmp += n; return tmp; }
inline iterator_internal operator-(difference_type n) { iterator_internal tmp(*this); tmp -= n; return tmp; }
inline difference_type operator-(const iterator_internal & b) { return (this->ret_ptr - b.ret_ptr) / _offset; }
inline pointer_type data() const { return ret_ptr; }
inline difference_type offset() const { return _offset; }
protected:
UInt _offset;
pointer_type initial;
internal_pointer ret;
pointer_type ret_ptr;
};
/* -------------------------------------------------------------------------- */
/**
* Specialization for scalar types
*/
template <class T, bool is_scal>
template <class R, class IR>
class Array<T, is_scal>::iterator_internal<R, IR, true> {
public:
typedef R value_type;
typedef R* pointer;
typedef R& reference;
typedef const R& const_reference;
typedef IR internal_value_type;
typedef IR* internal_pointer;
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
public:
iterator_internal(pointer data = NULL, __attribute__ ((unused)) UInt _offset = 1) : _offset(_offset), ret(data), initial(data) { };
iterator_internal(const iterator_internal & it) {
if(this != &it) { this->ret = it.ret; this->initial = it.initial; }
}
virtual ~iterator_internal() { };
inline iterator_internal & operator=(const iterator_internal & it)
{ if(this != &it) { this->ret = it.ret; this->initial = it.initial; } return *this; }
UInt getCurrentIndex(){return (this->ret - this->initial)/this->_offset;};
inline reference operator*() { return *ret; };
inline const_reference operator*() const { return *ret; };
inline pointer operator->() { return ret; };
inline iterator_internal & operator++() { ++ret; return *this; };
inline iterator_internal & operator--() { --ret; return *this; };
inline iterator_internal & operator+=(const UInt n) { ret += n; return *this; }
inline iterator_internal & operator-=(const UInt n) { ret -= n; return *this; }
inline reference operator[](const UInt n) { return ret[n]; }
inline bool operator==(const iterator_internal & other) const { return ret == other.ret; }
inline bool operator!=(const iterator_internal & other) const { return ret != other.ret; }
inline bool operator< (const iterator_internal & other) const { return ret < other.ret; }
inline bool operator<=(const iterator_internal & other) const { return ret <= other.ret; }
inline bool operator> (const iterator_internal & other) const { return ret > other.ret; }
inline bool operator>=(const iterator_internal & other) const { return ret >= other.ret; }
inline iterator_internal operator-(difference_type n) { return iterator_internal(ret - n); }
inline iterator_internal operator+(difference_type n) { return iterator_internal(ret + n); }
inline difference_type operator-(const iterator_internal & b) { return ret - b.ret; }
inline pointer data() const { return ret; }
inline difference_type offset() const { return _offset; }
protected:
difference_type _offset;
pointer ret;
pointer initial;
};
/* -------------------------------------------------------------------------- */
/* Begin/End functions implementation */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Vector<T> * to the
* first tuple of the array.
* @param n vector size. Has to be equal to nb_component. This unfortunate
* redundancy is necessary to distinguish it from ::begin() which it
* overloads. If compiled in debug mode, an incorrect value of n will result
* in an exception being thrown. Optimized code will fail in an unpredicted
* manner.
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::vector_iterator Array<T, is_scal>::begin(UInt n) {
AKANTU_DEBUG_ASSERT(nb_component == n,
"The iterator is not compatible with the type Array("
<< n<< ")");
return vector_iterator(new Vector<T>(values, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Vector<T> * pointing
* *past* the last tuple of the array.
* @param n vector size. see Array::begin(UInt n) for more
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::vector_iterator Array<T, is_scal>::end(UInt n) {
AKANTU_DEBUG_ASSERT(nb_component == n,
"The iterator is not compatible with the type Array("
<< n<< ")");
return vector_iterator(new Vector<T>(values + nb_component * size,
n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Vector<T> * to the
* first tuple of the array.
* @param n vector size. see Array::begin(UInt n) for more
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_vector_iterator Array<T, is_scal>::begin(UInt n) const {
AKANTU_DEBUG_ASSERT(nb_component == n,
"The iterator is not compatible with the type Array("
<< n<< ")");
return const_vector_iterator(new Vector<T>(values, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Vector<T> * pointing
* *past* the last tuple of the array.
* @param n vector size. see Array::begin(UInt n) for more
* @return a const_vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_vector_iterator Array<T, is_scal>::end(UInt n) const {
AKANTU_DEBUG_ASSERT(nb_component == n,
"The iterator is not compatible with the type Array("
<< n<< ")");
return const_vector_iterator(new Vector<T>(values + nb_component * size,
n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Vector<T> * to the
* first tuple of the array.
*
* The reinterpret iterators allow to iterate over an array in any way that
* preserves the number of entries of the array. This can for instance be use
* full if the shape of the data in an array is not initially known.
* @param n vector size.
* @param size number of tuples in array. n times size must match the number
* of entries of the array. If compiled in debug mode, an incorrect
* combination of n and size will result
* in an exception being thrown. Optimized code will fail in an unpredicted
* manner.
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::vector_iterator
Array<T, is_scal>::begin_reinterpret(UInt n, __attribute__((unused)) UInt size) {
AKANTU_DEBUG_ASSERT(n * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return vector_iterator(new Vector<T>(values, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Vector<T> * pointing
* *past* the last tuple of the array.
* @param n vector size.
* @param size number of tuples in array. See Array::begin_reinterpret(UInt n, UInt size)
* @return a vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::vector_iterator
Array<T, is_scal>::end_reinterpret(UInt n, UInt size) {
AKANTU_DEBUG_ASSERT(n * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return vector_iterator(new Vector<T>(values + n * size, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Vector<T> * to the
* first tuple of the array.
* @param n vector size.
* @param size number of tuples in array. See Array::begin_reinterpret(UInt n, UInt size)
* @return a const_vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_vector_iterator
Array<T, is_scal>::begin_reinterpret(UInt n, __attribute__((unused)) UInt size) const {
AKANTU_DEBUG_ASSERT(n * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_vector_iterator(new Vector<T>(values, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Vector<T> * pointing
* *past* the last tuple of the array.
* @param n vector size.
* @param size number of tuples in array. See Array::begin_reinterpret(UInt n, UInt size)
* @return a const_vector_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_vector_iterator
Array<T, is_scal>::end_reinterpret(UInt n, UInt size) const {
AKANTU_DEBUG_ASSERT(n * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << n
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_vector_iterator(new Vector<T>(values + n * size, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Matrix<T> * to the
* first tuple of the array.
* @param m number of rows
* @param n number of columns. m times n has to equal nb_component.
* If compiled in debug mode, an incorrect combination of m and n will result
* in an exception being thrown. Optimized code will fail in an unpredicted
* manner.
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::matrix_iterator Array<T, is_scal>::begin(UInt m, UInt n) {
AKANTU_DEBUG_ASSERT(nb_component == n*m,
"The iterator is not compatible with the type Matrix("
<< m << "," << n<< ")");
return matrix_iterator(new Matrix<T>(values, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Matrix<T> * pointing
* *past* the last tuple of the array.
* @param m number of rows
* @param n number of columns. See Array::begin(UInt m, UInt n)
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::matrix_iterator Array<T, is_scal>::end(UInt m, UInt n) {
AKANTU_DEBUG_ASSERT(nb_component == n*m,
"The iterator is not compatible with the type Matrix("
<< m << "," << n<< ")");
return matrix_iterator(new Matrix<T>(values + nb_component * size, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Matrix<T> * to the
* first tuple of the array.
* @param m number of rows
* @param n number of columns. See Array::begin(UInt m, UInt n)
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_matrix_iterator Array<T, is_scal>::begin(UInt m, UInt n) const {
AKANTU_DEBUG_ASSERT(nb_component == n*m,
"The iterator is not compatible with the type Matrix("
<< m << "," << n<< ")");
return const_matrix_iterator(new Matrix<T>(values, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Matrix<T> * pointing
* *past* the last tuple of the array.
* @param m number of rows
* @param n number of columns. See Array::begin(UInt m, UInt n)
* @return a const_matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_matrix_iterator Array<T, is_scal>::end(UInt m, UInt n) const {
AKANTU_DEBUG_ASSERT(nb_component == n*m,
"The iterator is not compatible with the type Matrix("
<< m << "," << n<< ")");
return const_matrix_iterator(new Matrix<T>(values + nb_component * size, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Matrix<T> * to the
* first tuple of the array.
*
* The reinterpret iterators allow to iterate over an array in any way that
* preserves the number of entries of the array. This can for instance be use
* full if the shape of the data in an array is not initially known.
* @param m number of rows
* @param n number of columns
* @param size number of tuples in array. m times n times size must match the number
* of entries of the array. If compiled in debug mode, an incorrect
* combination of m, n and size will result
* in an exception being thrown. Optimized code will fail in an unpredicted
* manner.
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::matrix_iterator
Array<T, is_scal>::begin_reinterpret(UInt m, UInt n, __attribute__((unused)) UInt size) {
AKANTU_DEBUG_ASSERT(n * m * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << m << "," << n << " = " << n * m
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return matrix_iterator(new Matrix<T>(values, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get an iterator that behaves like a pointer akantu::Matrix<T> * pointing
* *past* the last tuple of the array.
* @param m number of rows
* @param n number of columns
* @param size number of tuples in array. See Array::begin_reinterpret(UInt m, UInt n, UInt size)
* @return a matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::matrix_iterator
Array<T, is_scal>::end_reinterpret(UInt m, UInt n, UInt size) {
AKANTU_DEBUG_ASSERT(n * m * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << m << "," << n << " = " << n * m
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return matrix_iterator(new Matrix<T>(values + n * m * size, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Matrix<T> * to the
* first tuple of the array.
* @param m number of rows
* @param n number of columns
* @param size number of tuples in array. See Array::begin_reinterpret(UInt m, UInt n, UInt size)
* @return a const_matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_matrix_iterator
Array<T, is_scal>::begin_reinterpret(UInt m, UInt n, __attribute__((unused)) UInt size) const {
AKANTU_DEBUG_ASSERT(n * m * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << m << "," << n << " = " << n * m
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_matrix_iterator(new Matrix<T>(values, m, n));
}
/* -------------------------------------------------------------------------- */
/**
* Get a const iterator that behaves like a pointer akantu::Matrix<T> * pointing
* *past* the last tuple of the array.
* @param m number of rows
* @param n number of columns
* @param size number of tuples in array. See Array::begin_reinterpret(UInt m, UInt n, UInt size)
* @return a const_matrix_iterator
*/
template <class T, bool is_scal>
inline typename Array<T, is_scal>::const_matrix_iterator
Array<T, is_scal>::end_reinterpret(UInt m, UInt n, UInt size) const {
AKANTU_DEBUG_ASSERT(n * m * size == this->nb_component * this->size,
"The new values for size (" << size
<< ") and nb_component (" << m << "," << n << " = " << n * m
<< ") are not compatible with the one of this array("
<< this->size << "," << this->nb_component << ")");
return const_matrix_iterator(new Matrix<T>(values + n * m * size, m, n));
}
/* -------------------------------------------------------------------------- */
/** Get an iterator that behaves like a pointer T * to the
* first entry in the member array values
* @return a scalar_iterator
*/
template <class T, bool is_scal>
inline Array<T, is_scal>::iterator<T> Array<T, is_scal>::begin() {
AKANTU_DEBUG_ASSERT(nb_component == 1, "this iterator cannot be used on a vector which has nb_component != 1");
return iterator<T>(values);
}
/* -------------------------------------------------------------------------- */
/*! Get an iterator that behaves like a pointer T * that points *past* the
* last entry in the member array values
* @return a scalar_iterator
*/
template <class T, bool is_scal>
inline Array<T, is_scal>::iterator<T> Array<T, is_scal>::end() {
AKANTU_DEBUG_ASSERT(nb_component == 1, "this iterator cannot be used on a array which has nb_component != 1");
return iterator<T>(values + size);
}
/* -------------------------------------------------------------------------- */
/*! Get a const iterator that behaves like a pointer T * to the
* first entry in the member array values
* @return a const_scalar_iterator
*/
template <class T, bool is_scal>
inline Array<T, is_scal>::const_iterator<T> Array<T, is_scal>::begin() const {
AKANTU_DEBUG_ASSERT(nb_component == 1, "this iterator cannot be used on a array which has nb_component != 1");
return const_iterator<T>(values);
}
/* -------------------------------------------------------------------------- */
/*! Get a const iterator that behaves like a pointer T * that points *past* the
* last entry in the member array values
* @return a const_scalar_iterator
*/
template <class T, bool is_scal>
inline Array<T, is_scal>::const_iterator<T> Array<T, is_scal>::end() const {
AKANTU_DEBUG_ASSERT(nb_component == 1, "this iterator cannot be used on a array which has nb_component != 1");
return const_iterator<T>(values + size);
}
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template<typename R>
class Array<T, is_scal>::const_iterator : public iterator_internal<const R, R> {
public:
typedef iterator_internal<const R, R> parent;
typedef typename parent::value_type value_type;
typedef typename parent::pointer pointer;
typedef typename parent::reference reference;
typedef typename parent::difference_type difference_type;
typedef typename parent::iterator_category iterator_category;
public:
const_iterator() : parent() {};
const_iterator(pointer_type data, UInt offset) : parent(data, offset) {}
const_iterator(pointer warped) : parent(warped) {}
const_iterator(const parent & it) : parent(it) {}
// const_iterator(const const_iterator<R> & it) : parent(it) {}
inline const_iterator operator+(difference_type n)
{ return parent::operator+(n); }
inline const_iterator operator-(difference_type n)
{ return parent::operator-(n); }
inline difference_type operator-(const const_iterator & b)
{ return parent::operator-(b); }
inline const_iterator & operator++()
{ parent::operator++(); return *this; };
inline const_iterator & operator--()
{ parent::operator--(); return *this; };
inline const_iterator & operator+=(const UInt n)
{ parent::operator+=(n); return *this; }
};
// #endif
// #if defined(AKANTU_CORE_CXX11)
// template<class R> using iterator = iterator_internal<R>;
// #else
template < class T, class R, bool issame = is_same<T, R>::value >
struct ConstConverterIteratorHelper {
typedef typename Array<T>::template const_iterator<R> const_iterator;
typedef typename Array<T>::template iterator<R> iterator;
static inline const_iterator convert(const iterator & it) {
return const_iterator(new R(*it, false));
}
};
template < class T, class R >
struct ConstConverterIteratorHelper<T, R, true> {
typedef typename Array<T>::template const_iterator<R> const_iterator;
typedef typename Array<T>::template iterator<R> iterator;
static inline const_iterator convert(const iterator & it) {
return const_iterator(it.data(), it.offset());
}
};
template <class T, bool is_scal>
template<typename R>
class Array<T, is_scal>::iterator : public iterator_internal<R> {
public:
typedef iterator_internal<R> parent;
typedef typename parent::value_type value_type;
typedef typename parent::pointer pointer;
typedef typename parent::reference reference;
typedef typename parent::difference_type difference_type;
typedef typename parent::iterator_category iterator_category;
public:
iterator() : parent() {};
iterator(pointer_type data, UInt offset) : parent(data, offset) {};
iterator(pointer warped) : parent(warped) {}
iterator(const parent & it) : parent(it) {}
// iterator(const iterator<R> & it) : parent(it) {}
operator const_iterator<R>() {
return ConstConverterIteratorHelper<T, R>::convert(*this);
}
inline iterator operator+(difference_type n)
{ return parent::operator+(n);; }
inline iterator operator-(difference_type n)
{ return parent::operator-(n);; }
inline difference_type operator-(const iterator & b)
{ return parent::operator-(b); }
inline iterator & operator++()
{ parent::operator++(); return *this; };
inline iterator & operator--()
{ parent::operator--(); return *this; };
inline iterator & operator+=(const UInt n)
{ parent::operator+=(n); return *this; }
};
/* -------------------------------------------------------------------------- */
template <class T, bool is_scal>
template<typename R>
inline Array<T, is_scal>::iterator<R> Array<T, is_scal>::erase(const iterator<R> & it) {
T * curr = it.data();
UInt pos = (curr - values) / nb_component;
erase(pos);
iterator<R> rit = it;
return --rit;
}
// #endif
diff --git a/src/common/aka_blas_lapack.hh b/src/common/aka_blas_lapack.hh
index 47aecc9c9..201a5b95f 100644
--- a/src/common/aka_blas_lapack.hh
+++ b/src/common/aka_blas_lapack.hh
@@ -1,317 +1,324 @@
/**
* @file aka_blas_lapack.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Mar 06 2013
* @date last modification: Tue Jun 24 2014
*
* @brief Interface of the Fortran BLAS/LAPACK libraries
*
* @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_BLAS_LAPACK_HH__
#define __AKANTU_AKA_BLAS_LAPACK_HH__
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_USE_BLAS) || defined(AKANTU_USE_LAPACK)
# include "aka_fortran_mangling.hh"
#endif //AKANTU_USE_BLAS
#ifdef AKANTU_USE_BLAS
extern "C" {
/* ------------------------------------------------------------------------ */
/* Double precision */
/* ------------------------------------------------------------------------ */
//LEVEL 1
double AKA_FC_GLOBAL(ddot, DDOT)(int *, double *, int *, double *, int *);
//LEVEL 2
void AKA_FC_GLOBAL(dgemv, DGEMV)(char *, int *, int *, double *, double *, int *,
double *, int *, double *, double *, int *);
//LEVEL 3
void AKA_FC_GLOBAL(dgemm, DGEMM)(char *, char *, int *, int *, int *, double *,
double *, int *, double *, int *, double *,
double *, int *);
/* ------------------------------------------------------------------------ */
/* Simple precision */
/* ------------------------------------------------------------------------ */
//LEVEL 1
float AKA_FC_GLOBAL(sdot, SDOT)(int *, float *, int *, float *, int *);
//LEVEL 2
void AKA_FC_GLOBAL(sgemv, SGEMV)(char *, int *, int *, float *, float *, int *,
float *, int *, float *, float *, int *);
//LEVEL 3
void AKA_FC_GLOBAL(sgemm, SGEMM)(char *, char *, int *, int *, int *, float *,
float *, int *, float *, int *, float *,
float *, int *);
}
#endif
__BEGIN_AKANTU__
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
#elif (defined(__GNUC__) || defined(__GNUG__))
# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
# if GCC_VERSION > 40600
# pragma GCC diagnostic push
# endif
# pragma GCC diagnostic ignored "-Wunused"
#endif
+/// Wrapper around the S/DDOT BLAS function that returns the dot product of two vectors
template<typename T>
inline T aka_dot(int *n, T *x, int *incx, T *y, int *incy) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated BLAS in the compilation options!");
}
+/// Wrapper around the S/DGEMV BLAS function that computes matrix-vector product \f$y := \alpha A^{(T)}x + \beta y \f$
template<typename T>
inline void aka_gemv(char *trans, int *m, int *n, T *
alpha, T *a, int *lda, T *x, int *incx,
T *beta, T *y, int *incy) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated BLAS in the compilation options!");
}
+/// Wrapper around the S/DGEMM BLAS function that computes the product of two matrices \f$C := \alpha A^{(T)} B^{(T)} + \beta C \f$
template<typename T>
inline void aka_gemm(char *transa, char *transb,
int *m, int *n, int *k,
T *alpha, T *a, int *lda,
T *b, int *ldb,
T *beta, T *c, int *ldc) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated BLAS in the compilation options!");
}
#if defined(AKANTU_USE_BLAS)
template<>
inline double aka_dot<double>(int *n, double *x, int *incx, double *y, int *incy) {
return AKA_FC_GLOBAL(ddot, DDOT)(n, x, incx, y, incy);
}
template<>
inline void aka_gemv<double>(char *trans, int *m, int *n, double *
alpha, double *a, int *lda, double *x, int *incx,
double *beta, double *y, int *incy) {
return AKA_FC_GLOBAL(dgemv, DGEMV)(trans, m, n, alpha, a, lda, x, incx,
beta, y, incy);
}
template<>
inline void aka_gemm<double>(char *transa, char *transb,
int *m, int *n, int *k,
double *alpha, double *a, int *lda,
double *b, int *ldb,
double *beta, double *c, int *ldc) {
AKA_FC_GLOBAL(dgemm, DGEMM)(transa, transb, m, n, k, alpha, a, lda,
b, ldb, beta, c, ldc);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<>
inline float aka_dot<float>(int *n, float *x, int *incx, float *y, int *incy) {
return AKA_FC_GLOBAL(sdot, SDOT)(n, x, incx, y, incy);
}
template<>
inline void aka_gemv<float>(char *trans, int *m, int *n, float *
alpha, float *a, int *lda, float *x, int *incx,
float *beta, float *y, int *incy) {
AKA_FC_GLOBAL(sgemv, SGEMV)(trans, m, n, alpha, a, lda, x, incx,
beta, y, incy);
}
template<>
inline void aka_gemm<float>(char *transa, char *transb,
int *m, int *n, int *k,
float *alpha, float *a, int *lda,
float *b, int *ldb,
float *beta, float *c, int *ldc) {
AKA_FC_GLOBAL(sgemm, SGEMM)(transa, transb, m, n, k, alpha, a, lda,
b, ldb, beta, c, ldc);
}
#endif
__END_AKANTU__
#ifdef AKANTU_USE_LAPACK
extern "C" {
/* ------------------------------------------------------------------------ */
/* Double general matrix */
/* ------------------------------------------------------------------------ */
/// compute the eigenvalues/vectors
void AKA_FC_GLOBAL(dgeev, DGEEV)(char* jobvl, char* jobvr, int* n, double* a,
int* lda, double* wr, double* wi, double* vl, int* ldvl,
double* vr, int* ldvr, double* work, int* lwork, int* info);
/// LU decomposition of a general matrix
void AKA_FC_GLOBAL(dgetrf, DGETRF)(int* m, int *n,
double* a, int* lda,
int* ipiv, int* info);
/// generate inverse of a matrix given its LU decomposition
void AKA_FC_GLOBAL(dgetri, DGETRI)(int* n, double* a, int* lda,
int* ipiv, double* work, int* lwork, int* info);
/// solving A x = b using a LU factorization
void AKA_FC_GLOBAL(dgetrs, DGETRS)(char * trans, int * n, int * nrhs,
double * A, int * lda, int * ipiv,
double * b, int * ldb, int * info);
/* ------------------------------------------------------------------------ */
/* Simple general matrix */
/* ------------------------------------------------------------------------ */
/// compute the eigenvalues/vectors
void AKA_FC_GLOBAL(sgeev, SGEEV)(char* jobvl, char* jobvr, int* n, float* a,
int* lda, float* wr, float* wi, float* vl, int* ldvl,
float* vr, int* ldvr, float* work, int* lwork, int* info);
/// LU decomposition of a general matrix
void AKA_FC_GLOBAL(sgetrf, SGETRF)(int* m, int *n,
float* a, int* lda,
int* ipiv, int* info);
/// generate inverse of a matrix given its LU decomposition
void AKA_FC_GLOBAL(sgetri, SGETRI)(int* n, float* a, int* lda,
int* ipiv, float* work, int* lwork, int* info);
/// solving A x = b using a LU factorization
void AKA_FC_GLOBAL(sgetrs, SGETRS)(char * trans, int * n, int * nrhs,
float * A, int * lda, int * ipiv,
float * b, int * ldb, int * info);
}
#endif //AKANTU_USE_LAPACK
__BEGIN_AKANTU__
+/// Wrapper around the S/DGEEV BLAS function that computes the eigenvalues and eigenvectors of a matrix
template<typename T>
inline void aka_geev(char* jobvl, char* jobvr, int* n, T* a,
int* lda, T* wr, T* wi, T* vl, int* ldvl,
T* vr, int* ldvr, T* work, int* lwork, int* info) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated LAPACK in the compilation options!");
}
+/// Wrapper around the S/DGETRF BLAS function that computes the LU decomposition of a matrix
template<typename T>
inline void aka_getrf(int* m, int *n,
T* a, int* lda,
int* ipiv, int* info) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated LAPACK in the compilation options!");
}
+/// Wrapper around the S/DGETRI BLAS function that computes the inverse of a matrix given its LU decomposition
template<typename T>
inline void aka_getri(int* n, T* a, int* lda,
int* ipiv, T* work, int* lwork, int* info) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated LAPACK in the compilation options!");
}
+/// Wrapper around the S/DGETRS BLAS function that solves \f$A^{(T)}x = b\f$ using LU decomposition
template<typename T>
inline void aka_getrs(char *trans, int * n, int * nrhs,
T * A, int * lda, int * ipiv,
T * b, int * ldb, int * info) {
AKANTU_DEBUG_ERROR(debug::demangle(typeid(T).name()) << "is not a type recognized, or you didn't activated LAPACK in the compilation options!");
}
#if defined(__INTEL_COMPILER)
//#pragma warning ( disable : 383 )
#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
#elif defined(__GNUG__)
# if GCC_VERSION > 40600
# pragma GCC diagnostic pop
# else
# pragma GCC diagnostic warning "-Wunused"
# endif
#endif
#ifdef AKANTU_USE_LAPACK
template<>
inline void aka_geev<double>(char* jobvl, char* jobvr, int* n, double* a,
int* lda, double* wr, double* wi, double* vl, int* ldvl,
double* vr, int* ldvr, double* work, int* lwork, int* info) {
AKA_FC_GLOBAL(dgeev, DGEEV)(jobvl, jobvr, n, a,
lda, wr, wi, vl, ldvl,
vr, ldvr, work, lwork, info);
}
template<>
inline void aka_getrf<double>(int* m, int *n,
double* a, int* lda,
int* ipiv, int* info) {
AKA_FC_GLOBAL(dgetrf, DGETRF)(m, n, a, lda, ipiv, info);
}
template<>
inline void aka_getri<double>(int* n, double* a, int* lda,
int* ipiv, double* work, int* lwork, int* info) {
AKA_FC_GLOBAL(dgetri, DGETRI)(n, a, lda, ipiv, work, lwork, info);
}
template<>
inline void aka_getrs<double>(char *trans, int * n, int * nrhs,
double * A, int * lda, int * ipiv,
double * b, int * ldb, int * info) {
AKA_FC_GLOBAL(dgetrs, DGETRS)(trans, n, nrhs, A, lda, ipiv, b, ldb, info);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
template<>
inline void aka_geev<float>(char* jobvl, char* jobvr, int* n, float* a,
int* lda, float* wr, float* wi, float* vl, int* ldvl,
float* vr, int* ldvr, float* work, int* lwork, int* info) {
AKA_FC_GLOBAL(sgeev, SGEEV)(jobvl, jobvr, n, a,
lda, wr, wi, vl, ldvl,
vr, ldvr, work, lwork, info);
}
template<>
inline void aka_getrf<float>(int* m, int *n,
float* a, int* lda,
int* ipiv, int* info) {
AKA_FC_GLOBAL(sgetrf, SGETRF)(m, n, a, lda, ipiv, info);
}
template<>
inline void aka_getri<float>(int* n, float* a, int* lda,
int* ipiv, float* work, int* lwork, int* info) {
AKA_FC_GLOBAL(sgetri, SGETRI)(n, a, lda, ipiv, work, lwork, info);
}
template<>
inline void aka_getrs<float>(char *trans, int * n, int * nrhs,
float * A, int * lda, int * ipiv,
float * b, int * ldb, int * info) {
AKA_FC_GLOBAL(sgetrs, SGETRS)(trans, n, nrhs, A, lda, ipiv, b, ldb, info);
}
#endif
__END_AKANTU__
#endif /* __AKANTU_AKA_BLAS_LAPACK_HH__ */
diff --git a/src/common/aka_bounding_box.cc b/src/common/aka_bounding_box.cc
index 4f78be2be..cc7597f1e 100644
--- a/src/common/aka_bounding_box.cc
+++ b/src/common/aka_bounding_box.cc
@@ -1,83 +1,83 @@
/**
* @file aka_bounding_box.cc
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Fri Mar 21 2014
*
* @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);
+ //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_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_common.cc b/src/common/aka_common.cc
index d5240f3aa..77ceeb4d4 100644
--- a/src/common/aka_common.cc
+++ b/src/common/aka_common.cc
@@ -1,145 +1,149 @@
/**
* @file aka_common.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Mon Sep 15 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_static_memory.hh"
#include "static_communicator.hh"
#include "static_solver.hh"
#include "aka_random_generator.hh"
#include "parser.hh"
#include "cppargparse.hh"
-
+/* -------------------------------------------------------------------------- */
+#include <ctime>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-void initialize(int & argc, char ** & argv) {
+void initialize(int & argc, char **& argv) {
AKANTU_DEBUG_IN();
initialize("", argc, argv);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void initialize(const std::string & input_file, int & argc, char ** & argv) {
+void initialize(const std::string & input_file, int & argc, char **& argv) {
AKANTU_DEBUG_IN();
StaticMemory::getStaticMemory();
- StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator(argc, argv);
+ StaticCommunicator & comm =
+ StaticCommunicator::getStaticCommunicator(argc, argv);
debug::debugger.setParallelContext(comm.whoAmI(), comm.getNbProc());
debug::initSignalHandler();
static_argparser.setParallelContext(comm.whoAmI(), comm.getNbProc());
static_argparser.setExternalExitFunction(debug::exit);
- static_argparser.addArgument("--aka_input_file", "Akantu's input file",
- 1, cppargparse::_string, std::string());
- static_argparser.addArgument("--aka_debug_level", std::string("Akantu's overall debug level") +
- std::string(" (0: error, 1: exceptions, 4: warnings, 5: info, ..., 100: dump,") +
- std::string(" more info on levels can be foind in aka_error.hh)"),
- 1,
- cppargparse::_integer, int(dblWarning));
-
- static_argparser.addArgument("--aka_print_backtrace",
- "Should Akantu print a backtrace in case of error",
- 0,
- cppargparse::_boolean, false, true);
+ static_argparser.addArgument("--aka_input_file", "Akantu's input file", 1,
+ cppargparse::_string, std::string());
+ static_argparser.addArgument(
+ "--aka_debug_level",
+ std::string("Akantu's overall debug level") +
+ std::string(" (0: error, 1: exceptions, 4: warnings, 5: info, ..., "
+ "100: dump,") +
+ std::string(" more info on levels can be foind in aka_error.hh)"),
+ 1, cppargparse::_integer, int(dblWarning));
+
+ static_argparser.addArgument(
+ "--aka_print_backtrace",
+ "Should Akantu print a backtrace in case of error", 0,
+ cppargparse::_boolean, false, true);
static_argparser.parse(argc, argv, cppargparse::_remove_parsed);
-
std::string infile = static_argparser["aka_input_file"];
- if(infile == "") infile = input_file;
+ if (infile == "")
+ infile = input_file;
debug::setDebugLevel(dblError);
if ("" != infile) {
- static_parser.parse(infile);
+ readInputFile(infile);
}
long int seed;
try {
seed = static_parser.getParameter("seed", _ppsc_current_scope);
} catch (debug::Exception &) {
seed = time(NULL);
}
int dbl_level = static_argparser["aka_debug_level"];
debug::setDebugLevel(DebugLevel(dbl_level));
debug::debugger.printBacktrace(static_argparser["aka_print_backtrace"]);
seed *= (comm.whoAmI() + 1);
+#if not defined(_WIN32)
Rand48Generator<Real>::seed(seed);
+#endif
RandGenerator<Real>::seed(seed);
AKANTU_DEBUG_INFO("Random seed set to " << seed);
- /// initialize external solvers
+ /// initialize external solvers
StaticSolver::getStaticSolver().initialize(argc, argv);
AKANTU_DEBUG_OUT();
-
}
/* -------------------------------------------------------------------------- */
void finalize() {
AKANTU_DEBUG_IN();
- /// finalize external solvers
- StaticSolver::getStaticSolver().finalize();
-
- if(StaticMemory::isInstantiated()) delete &(StaticMemory::getStaticMemory());
- if(StaticCommunicator::isInstantiated()) {
+ if (StaticMemory::isInstantiated())
+ delete &(StaticMemory::getStaticMemory());
+ if (StaticCommunicator::isInstantiated()) {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- comm.barrier();
delete &comm;
}
-
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
+void readInputFile(const std::string & input_file) {
+ static_parser.parse(input_file);
+}
+
/* -------------------------------------------------------------------------- */
cppargparse::ArgumentParser & getStaticArgumentParser() {
return static_argparser;
}
/* -------------------------------------------------------------------------- */
-Parser & getStaticParser() {
- return static_parser;
-}
+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 0f5da70bc..1fbd72097 100644
--- a/src/common/aka_common.hh
+++ b/src/common/aka_common.hh
@@ -1,697 +1,489 @@
/**
* @file aka_common.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Mon Sep 15 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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>
-#include <boost/preprocessor.hpp>
/* -------------------------------------------------------------------------- */
#define __BEGIN_AKANTU__ namespace akantu {
#define __END_AKANTU__ };
/* -------------------------------------------------------------------------- */
#define __BEGIN_AKANTU_DUMPER__ namespace dumper {
#define __END_AKANTU_DUMPER__ }
/* -------------------------------------------------------------------------- */
#if defined(WIN32)
# define __attribute__(x)
#endif
/* -------------------------------------------------------------------------- */
#include "aka_config.hh"
#include "aka_error.hh"
#include "aka_safe_enum.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* Common types */
/* -------------------------------------------------------------------------- */
-
-typedef double Real;
-typedef unsigned int UInt;
-typedef unsigned long long UInt64;
-typedef signed int Int;
-
typedef std::string ID;
-static const Real UINT_INIT_VALUE = 0;
+static const Real UINT_INIT_VALUE = Real(0.);
#ifdef AKANTU_NDEBUG
- static const Real REAL_INIT_VALUE = 0;
+ 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;
-/* -------------------------------------------------------------------------- */
-/* Mesh/FEM/Model types */
-/* -------------------------------------------------------------------------- */
typedef std::string Surface;
typedef std::pair<Surface, Surface> SurfacePair;
typedef std::list< SurfacePair > SurfacePairList;
/* -------------------------------------------------------------------------- */
-
extern const UInt _all_dimensions;
-/// @boost sequence of element to loop on in global tasks
-#define AKANTU_ek_regular_ELEMENT_TYPE \
- (_point_1) \
- (_segment_2) \
- (_segment_3) \
- (_triangle_3) \
- (_triangle_6) \
- (_quadrangle_4) \
- (_quadrangle_8) \
- (_tetrahedron_4) \
- (_tetrahedron_10) \
- (_pentahedron_6) \
- (_hexahedron_8)
-
-#if defined(AKANTU_STRUCTURAL_MECHANICS)
-#define AKANTU_ek_structural_ELEMENT_TYPE \
- (_bernoulli_beam_2) \
- (_bernoulli_beam_3) \
- (_kirchhoff_shell)
-#else
-#define AKANTU_ek_structural_ELEMENT_TYPE
-#endif
-#if defined(AKANTU_COHESIVE_ELEMENT)
-# define AKANTU_ek_cohesive_ELEMENT_TYPE \
- (_cohesive_2d_4) \
- (_cohesive_2d_6) \
- (_cohesive_1d_2) \
- (_cohesive_3d_6) \
- (_cohesive_3d_12)
-#else
-# define AKANTU_ek_cohesive_ELEMENT_TYPE
-#endif
-
-#if defined(AKANTU_IGFEM)
-#define AKANTU_ek_igfem_ELEMENT_TYPE \
- (_igfem_triangle_3)
-#else
-#define AKANTU_ek_igfem_ELEMENT_TYPE
-#endif
-
-#define AKANTU_ALL_ELEMENT_TYPE \
- AKANTU_ek_regular_ELEMENT_TYPE \
- AKANTU_ek_cohesive_ELEMENT_TYPE \
- AKANTU_ek_structural_ELEMENT_TYPE \
- AKANTU_ek_igfem_ELEMENT_TYPE
-
-#define AKANTU_NOT_STRUCTURAL_ELEMENT_TYPE \
- AKANTU_ek_regular_ELEMENT_TYPE \
- AKANTU_ek_cohesive_ELEMENT_TYPE \
- AKANTU_ek_igfem_ELEMENT_TYPE
-
-/// @enum ElementType type of elements
-enum ElementType {
- _not_defined,
- _point_1,
- _segment_2, ///< first order segment
- _segment_3, ///< second order segment
- _triangle_3, ///< first order triangle
- _triangle_6, ///< second order triangle
- _tetrahedron_4, ///< first order tetrahedron
- _tetrahedron_10, ///< second order tetrahedron
- _quadrangle_4, ///< first order quadrangle
- _quadrangle_8, ///< second order quadrangle
- _hexahedron_8, ///< first order hexahedron
- _pentahedron_6, ///< first order pentahedron
-#if defined (AKANTU_STRUCTURAL_MECHANICS)
- _bernoulli_beam_2, ///< Bernoulli beam 2D
- _bernoulli_beam_3, ///< Bernoulli beam 3D
- _kirchhoff_shell, ///< Kirchhoff shell
-#endif
-
-#if defined(AKANTU_COHESIVE_ELEMENT)
- _cohesive_2d_4, ///< first order 2D cohesive
- _cohesive_2d_6, ///< second order 2D cohesive
- _cohesive_1d_2, ///< first order 1D cohesive
- _cohesive_3d_6, ///< first order 3D cohesive
- _cohesive_3d_12, ///< second order 3D cohesive
-#endif
-#if defined(AKANTU_IGFEM)
- _igfem_triangle_3, ///< first order triangle for IGFEM
-#endif
- _max_element_type
-};
-
-/// @enum GeometricalType type of element potentially contained in a Mesh
-enum GeometricalType {
- _gt_point, ///< point @remark only for some algorithm to be generic like mesh partitioning */
- _gt_segment_2, ///< 2 nodes segment
- _gt_segment_3, ///< 3 nodes segment
- _gt_triangle_3, ///< 3 nodes triangle
- _gt_triangle_6, ///< 6 nodes triangle
- _gt_quadrangle_4, ///< 4 nodes quadrangle
- _gt_quadrangle_8, ///< 8 nodes quadrangle
- _gt_tetrahedron_4, ///< 4 nodes tetrahedron
- _gt_tetrahedron_10, ///< 10 nodes tetrahedron
- _gt_hexahedron_8, ///< 8 nodes hexahedron
- _gt_pentahedron_6, ///< 6 nodes pentahedron
-#if defined(AKANTU_COHESIVE_ELEMENT)
- _gt_cohesive_2d_4, ///< 4 nodes 2D cohesive
- _gt_cohesive_2d_6, ///< 6 nodes 2D cohesive
- _gt_cohesive_1d_2, ///< 2 nodes 1D cohesive
- _gt_cohesive_3d_6, ///< 6 nodes 3D cohesive
- _gt_cohesive_3d_12, ///< 12 nodes 3D cohesive
-#endif
- _gt_not_defined
-};
-
-/// @enum InterpolationType type of elements
-enum InterpolationType {
- _itp_lagrange_point_1, ///< zeroth (!) order lagrangian point (for compatibility purposes)
- _itp_lagrange_segment_2, ///< first order lagrangian segment
- _itp_lagrange_segment_3, ///< second order lagrangian segment
- _itp_lagrange_triangle_3, ///< first order lagrangian triangle
- _itp_lagrange_triangle_6, ///< second order lagrangian triangle
- _itp_lagrange_quadrangle_4, ///< first order lagrangian quadrangle
- _itp_serendip_quadrangle_8, /**< second order serendipian quadrangle
- @remark used insted of the 9 node
- lagrangian element */
- _itp_lagrange_tetrahedron_4, ///< first order lagrangian tetrahedron
- _itp_lagrange_tetrahedron_10, ///< second order lagrangian tetrahedron
- _itp_lagrange_hexahedron_8, ///< first order lagrangian hexahedron
- _itp_lagrange_pentahedron_6, ///< first order lagrangian pentahedron
-#if defined(AKANTU_STRUCTURAL_MECHANICS)
- _itp_bernoulli_beam, ///< Bernoulli beam
- _itp_kirchhoff_shell, ///< Kirchhoff shell
-#endif
-
- _itp_not_defined
-};
-
-//! standard output stream operator for ElementType
-inline std::ostream & operator <<(std::ostream & stream, ElementType type);
-
-
-#define AKANTU_REGULAR_KIND (_ek_regular)
-
-#ifdef AKANTU_COHESIVE_ELEMENT
-# define AKANTU_COHESIVE_KIND (_ek_cohesive)
-#else
-# define AKANTU_COHESIVE_KIND
-#endif
-
-#ifdef AKANTU_STRUCTURAL_MECHANICS
-# define AKANTU_STRUCTURAL_KIND (_ek_structural)
-#else
-# define AKANTU_STRUCTURAL_KIND
-#endif
+/* -------------------------------------------------------------------------- */
+/* Mesh/FEM/Model types */
+/* -------------------------------------------------------------------------- */
+__END_AKANTU__
-#ifdef AKANTU_IGFEM
-# define AKANTU_IGFEM_KIND (_ek_igfem)
-#else
-# define AKANTU_IGFEM_KIND
-#endif
+#include "aka_element_classes_info.hh"
-#define AKANTU_ELEMENT_KIND \
- AKANTU_REGULAR_KIND \
- AKANTU_COHESIVE_KIND \
- AKANTU_STRUCTURAL_KIND \
- AKANTU_IGFEM_KIND
+__BEGIN_AKANTU__
-enum ElementKind {
- BOOST_PP_SEQ_ENUM(AKANTU_ELEMENT_KIND),
- _ek_not_defined
-};
/// small help to use names for directions
enum SpacialDirection {
_x = 0,
_y = 1,
_z = 2
};
/// enum MeshIOType type of mesh reader/writer
enum MeshIOType {
_miot_auto, ///< Auto guess of the reader to use based on the extension
_miot_gmsh, ///< Gmsh files
_miot_gmsh_struct, ///< Gsmh reader with reintpretation of elements has structures elements
_miot_diana, ///< TNO Diana mesh format
_miot_abaqus ///< Abaqus mesh format
};
/// enum AnalysisMethod type of solving method used to solve the equation of motion
enum AnalysisMethod {
_static,
_implicit_dynamic,
_explicit_lumped_mass,
_explicit_lumped_capacity,
_explicit_consistent_mass
};
//! enum ContactResolutionMethod types of solving for the contact
enum ContactResolutionMethod {
_penalty,
_lagrangian,
_augmented_lagrangian,
_nitsche,
_mortar
};
//! enum ContactImplementationMethod types for different contact implementations
enum ContactImplementationMethod {
_none,
_uzawa,
_generalized_newton
};
-
-
-
/// enum SolveConvergenceMethod different resolution algorithms
enum SolveConvergenceMethod {
_scm_newton_raphson_tangent, ///< Newton-Raphson with tangent matrix
_scm_newton_raphson_tangent_modified, ///< Newton-Raphson with constant tangent matrix
_scm_newton_raphson_tangent_not_computed ///< Newton-Raphson with constant tangent matrix (user has to assemble it)
};
/// enum SolveConvergenceCriteria different convergence criteria
enum SolveConvergenceCriteria {
_scc_residual, ///< Use residual to test the convergence
_scc_increment, ///< Use increment to test the convergence
_scc_residual_mass_wgh ///< Use residual weighted by inv. nodal mass to testb
};
/// enum CohesiveMethod type of insertion of cohesive elements
enum CohesiveMethod {
_intrinsic,
_extrinsic
};
/// myfunction(double * position, double * stress/force, double * normal, unsigned int material_id)
typedef void (*BoundaryFunction)(double *,double *, double*, unsigned int);
/// @enum BoundaryFunctionType type of function passed for boundary conditions
enum BoundaryFunctionType {
_bft_stress,
_bft_traction,
_bft_traction_local
};
/// @enum SparseMatrixType type of sparse matrix used
enum SparseMatrixType {
_unsymmetric,
_symmetric
};
/* -------------------------------------------------------------------------- */
/* Contact */
/* -------------------------------------------------------------------------- */
typedef ID ContactID;
typedef ID ContactSearchID;
typedef ID ContactNeighborStructureID;
enum ContactType {
_ct_not_defined = 0,
_ct_2d_expli = 1,
_ct_3d_expli = 2,
_ct_rigid = 3
};
enum ContactSearchType {
_cst_not_defined = 0,
_cst_2d_expli = 1,
_cst_expli = 2
};
enum ContactNeighborStructureType {
_cnst_not_defined = 0,
_cnst_regular_grid = 1,
_cnst_2d_grid = 2
};
/* -------------------------------------------------------------------------- */
/* Friction */
/* -------------------------------------------------------------------------- */
typedef ID FrictionID;
/* -------------------------------------------------------------------------- */
/* Ghosts handling */
/* -------------------------------------------------------------------------- */
typedef ID SynchronizerID;
/// @enum CommunicatorType type of communication method to use
enum CommunicatorType {
_communicator_mpi,
_communicator_dummy
};
/// @enum SynchronizationTag type of synchronizations
enum SynchronizationTag {
//--- SolidMechanicsModel tags ---
_gst_smm_mass, //< synchronization of the SolidMechanicsModel.mass
_gst_smm_for_gradu, //< synchronization of the SolidMechanicsModel.displacement
_gst_smm_boundary, //< synchronization of the boundary, forces, velocities and displacement
_gst_smm_uv, //< synchronization of the nodal velocities and displacement
_gst_smm_res, //< synchronization of the nodal residual
_gst_smm_init_mat, //< synchronization of the data to initialize materials
_gst_smm_stress, //< synchronization of the stresses to compute the internal forces
_gst_smmc_facets, //< synchronization of facet data to setup facet synch
_gst_smmc_facets_conn, //< synchronization of facet global connectivity
_gst_smmc_facets_stress, //< synchronization of facets' stress to setup facet synch
_gst_smmc_damage, //< synchronization of damage
+ //--- GlobalIdsUpdater tags ---
+ _gst_giu_global_conn, //< synchronization of global connectivities
//--- CohesiveElementInserter tags ---
- _gst_ce_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
+ _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__
-/* -------------------------------------------------------------------------- */
-// 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_REGULAR_ELEMENT_SWITCH(macro) \
- AKANTU_BOOST_ELEMENT_SWITCH(macro, \
- AKANTU_ek_regular_ELEMENT_TYPE)
-
-#define AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(macro) \
- AKANTU_BOOST_ELEMENT_SWITCH(macro, \
- AKANTU_ek_cohesive_ELEMENT_TYPE)
-
-#define AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(macro) \
- AKANTU_BOOST_ELEMENT_SWITCH(macro, \
- AKANTU_ek_structural_ELEMENT_TYPE)
-
-#define AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(macro) \
- AKANTU_BOOST_ELEMENT_SWITCH(macro, \
- AKANTU_ek_igfem_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_BOOST_REGULAR_ELEMENT_LIST(macro) \
- AKANTU_BOOST_APPLY_ON_LIST(macro, \
- AKANTU_ek_regular_ELEMENT_TYPE)
-
-#define AKANTU_BOOST_STRUCTURAL_ELEMENT_LIST(macro) \
- AKANTU_BOOST_APPLY_ON_LIST(macro, \
- AKANTU_ek_structural_ELEMENT_TYPE)
-
-#define AKANTU_BOOST_COHESIVE_ELEMENT_LIST(macro) \
- AKANTU_BOOST_APPLY_ON_LIST(macro, \
- AKANTU_ek_cohesive_ELEMENT_TYPE)
-
-#define AKANTU_BOOST_IGFEM_ELEMENT_LIST(macro) \
- AKANTU_BOOST_APPLY_ON_LIST(macro, \
- AKANTU_ek_igfem_ELEMENT_TYPE)
-
-#define AKANTU_GET_ELEMENT_LIST(kind) \
- AKANTU##kind##_ELEMENT_TYPE
+#include "aka_common_inline_impl.cc"
-#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))
+#if defined(AKANTU_UNORDERED_MAP_IS_CXX11)
-#define AKANTU_ELEMENT_KIND_BOOST_LIST AKANTU_GENERATE_KIND_LIST(AKANTU_ELEMENT_KIND)
+__BEGIN_AKANTU_UNORDERED_MAP__
-#define AKANTU_BOOST_ALL_KIND_LIST(macro, list) \
- BOOST_PP_LIST_FOR_EACH(AKANTU_BOOST_LIST_MACRO, macro, list)
+#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
-#define AKANTU_BOOST_ALL_KIND(macro) \
- AKANTU_BOOST_ALL_KIND_LIST(macro, AKANTU_ELEMENT_KIND_BOOST_LIST)
+/**
+ * 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);
+ }
-#define AKANTU_BOOST_ALL_KIND_SWITCH(macro) \
- AKANTU_BOOST_LIST_SWITCH(macro, \
- AKANTU_ELEMENT_KIND, \
- kind)
+private:
+ const hash<a> ah;
+ const hash<b> bh;
+};
-/// 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
+__END_AKANTU_UNORDERED_MAP__
+#endif
-#include "aka_common_inline_impl.cc"
#endif /* __AKANTU_COMMON_HH__ */
diff --git a/src/common/aka_common_inline_impl.cc b/src/common/aka_common_inline_impl.cc
index 98f333536..159d45f87 100644
--- a/src/common/aka_common_inline_impl.cc
+++ b/src/common/aka_common_inline_impl.cc
@@ -1,233 +1,179 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 ElementType
-inline std::ostream & operator <<(std::ostream & stream, ElementType type)
-{
-#define STRINGIFY(type) \
- stream << BOOST_PP_STRINGIZE(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;
- }
-
-
-
-#undef STRINGIFY
- return stream;
-}
-
-/* -------------------------------------------------------------------------- */
-//! standard output stream operator for ElementType
-inline std::ostream & operator <<(std::ostream & stream, ElementKind kind )
-{
-#define STRINGIFY(kind) \
- stream << BOOST_PP_STRINGIZE(kind)
-
- AKANTU_BOOST_ALL_KIND_SWITCH(STRINGIFY);
-#undef STRINGIFY
- return stream;
-}
-
-/* -------------------------------------------------------------------------- */
-/// standard output stream operator for InterpolationType
-inline std::ostream & operator <<(std::ostream & stream, InterpolationType type)
-{
- switch(type)
- {
- case _itp_lagrange_point_1 : stream << "_itp_lagrange_point_1" ; break;
- case _itp_lagrange_segment_2 : stream << "_itp_lagrange_segment_2" ; break;
- case _itp_lagrange_segment_3 : stream << "_itp_lagrange_segment_3" ; break;
- case _itp_lagrange_triangle_3 : stream << "_itp_lagrange_triangle_3" ; break;
- case _itp_lagrange_triangle_6 : stream << "_itp_lagrange_triangle_6" ; break;
- case _itp_lagrange_quadrangle_4 : stream << "_itp_lagrange_quadrangle_4" ; break;
- case _itp_serendip_quadrangle_8 : stream << "_itp_serendip_quadrangle_8" ; break;
- case _itp_lagrange_tetrahedron_4 : stream << "_itp_lagrange_tetrahedron_4" ; break;
- case _itp_lagrange_tetrahedron_10 : stream << "_itp_lagrange_tetrahedron_10"; break;
- case _itp_lagrange_hexahedron_8 : stream << "_itp_lagrange_hexahedron_8" ; break;
- case _itp_lagrange_pentahedron_6 : stream << "_itp_lagrange_pentahedron_6" ; break;
-#if defined(AKANTU_STRUCTURAL_MECHANICS)
- case _itp_bernoulli_beam : stream << "_itp_bernoulli_beam" ; break;
- case _itp_kirchhoff_shell : stream << "_itp_kirchhoff_shell" ; break;
-#endif
- case _itp_not_defined : stream << "_itp_not_defined" ; break;
- }
- return stream;
-}
-
/* -------------------------------------------------------------------------- */
/// 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_increment: stream << "_scc_increment"; break;
case _scc_residual_mass_wgh: stream << "_scc_residual_mass_wgh"; break;
}
return stream;
}
/* -------------------------------------------------------------------------- */
inline std::string to_lower(const std::string & str) {
std::string lstr = str;
std::transform(lstr.begin(),
lstr.end(),
lstr.begin(),
(int(*)(int))tolower);
return lstr;
}
/* -------------------------------------------------------------------------- */
inline std::string trim(const std::string & to_trim) {
std::string trimed = to_trim;
//left trim
trimed.erase(trimed.begin(),
std::find_if(trimed.begin(),
trimed.end(),
std::not1(std::ptr_fun<int, int>(isspace))));
// right trim
trimed.erase(std::find_if(trimed.rbegin(),
trimed.rend(),
std::not1(std::ptr_fun<int, int>(isspace))).base(),
trimed.end());
return trimed;
}
__END_AKANTU__
#include <cmath>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<typename T>
std::string printMemorySize(UInt size) {
Real real_size = size * sizeof(T);
UInt mult = (std::log(real_size) / std::log(2)) / 10;
std::stringstream sstr;
real_size /= Real(1 << (10 * mult));
sstr << std::setprecision(2) << std::fixed << real_size;
std::string size_prefix;
switch(mult) {
case 0: sstr << ""; break;
case 1: sstr << "Ki"; break;
case 2: sstr << "Mi"; break;
case 3: sstr << "Gi"; break; // I started on this type of machines
// (32bit computers) (Nicolas)
case 4: sstr << "Ti"; break;
case 5: sstr << "Pi"; break;
case 6: sstr << "Ei"; break; // theoritical limit of RAM of the current
// computers in 2014 (64bit computers) (Nicolas)
case 7: sstr << "Zi"; break;
case 8: sstr << "Yi"; break;
default:
AKANTU_DEBUG_ERROR("The programmer in 2014 didn't thought so far (even wikipedia does not go further)."
<< " You have at least 1024 times more than a yobibit of RAM!!!"
<< " Just add the prefix corresponding in this switch case.");
}
sstr << "Byte";
return sstr.str();
}
__END_AKANTU__
diff --git a/src/common/aka_config.hh.in b/src/common/aka_config.hh.in
index 248cf67da..94ea058bb 100644
--- a/src/common/aka_config.hh.in
+++ b/src/common/aka_config.hh.in
@@ -1,88 +1,125 @@
/**
* @file aka_config.hh.in
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Fri Jan 13 12:34:54 2012
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 @AKANTU_VERSION@
#define AKANTU_VERSION_MAJOR @AKANTU_MAJOR_VERSION@
#define AKANTU_VERSION_MINOR @AKANTU_MINOR_VERSION@
#define AKANTU_VERSION_PATCH @AKANTU_PATCH_VERSION@
+#define AKANTU_VERSION (AKANTU_VERSION_MAJOR * 100000 \
+ + AKANTU_VERSION_MINOR * 1000 \
+ + AKANTU_VERSION_PATCH)
+
+@AKANTU_TYPES_EXTRA_INCLUDES@
+namespace akantu {
+ typedef @AKANTU_FLOAT_TYPE@ Real;
+ typedef @AKANTU_SIGNED_INTEGER_TYPE@ Int;
+ typedef @AKANTU_UNSIGNED_INTEGER_TYPE@ UInt;
+
+ template<class Key, class Ty>
+ struct unordered_map {
+ typedef typename @AKANTU_UNORDERED_MAP_TYPE@<Key, Ty> type;
+ };
+
+ template<class T>
+ std::size_t hash(const T & t) {
+ typedef typename @AKANTU_HASH_TYPE@<T> hash_type;
+ return hash_type()(t);
+ };
+}
+
+#define AKANTU_INTEGER_SIZE @AKANTU_INTEGER_SIZE@
+#define AKANTU_FLOAT_SIZE @AKANTU_FLOAT_SIZE@
+
+#cmakedefine AKANTU_UNORDERED_MAP_IS_CXX11
+#define __BEGIN_AKANTU_UNORDERED_MAP__ \
+ @AKANTU_UNORDERED_MAP_NAMESPACE_BEGIN@
+#define __END_AKANTU_UNORDERED_MAP__ \
+ @AKANTU_UNORDERED_MAP_NAMESPACE_END@
+
+#cmakedefine AKANTU_HAS_STRDUP
#cmakedefine AKANTU_USE_BLAS
#cmakedefine AKANTU_USE_LAPACK
#cmakedefine AKANTU_PARALLEL
#cmakedefine AKANTU_USE_MPI
#cmakedefine AKANTU_USE_SCOTCH
#cmakedefine AKANTU_USE_PTSCOTCH
#cmakedefine AKANTU_SCOTCH_NO_EXTERN
#cmakedefine AKANTU_USE_MUMPS
#cmakedefine AKANTU_USE_PETSC
#cmakedefine AKANTU_USE_IOHELPER
#cmakedefine AKANTU_USE_QVIEW
#cmakedefine AKANTU_USE_BLACKDYNAMITE
#cmakedefine AKANTU_USE_NLOPT
#cmakedefine AKANTU_USE_CPPARRAY
#cmakedefine AKANTU_USE_OBSOLETE_GETTIMEOFDAY
+
#cmakedefine AKANTU_EXTRA_MATERIALS
+#cmakedefine AKANTU_STUDENTS_EXTRA_PACKAGE
#cmakedefine AKANTU_DAMAGE_NON_LOCAL
#cmakedefine AKANTU_STRUCTURAL_MECHANICS
#cmakedefine AKANTU_HEAT_TRANSFER
+#cmakedefine AKANTU_PYTHON_INTERFACE
#cmakedefine AKANTU_COHESIVE_ELEMENT
#cmakedefine AKANTU_PARALLEL_COHESIVE_ELEMENT
#cmakedefine AKANTU_IGFEM
+#cmakedefine AKANTU_USE_CGAL
+#cmakedefine AKANTU_EMBEDDED
+
// BOOST Section
#cmakedefine AKANTU_BOOST_CHRONO
#cmakedefine AKANTU_BOOST_SYSTEM
// Experimental part
#cmakedefine AKANTU_CORE_CXX11
// Debug tools
//#cmakedefine AKANTU_NDEBUG
#cmakedefine AKANTU_DEBUG_TOOLS
#cmakedefine READLINK_COMMAND @READLINK_COMMAND@
#cmakedefine ADDR2LINE_COMMAND @ADDR2LINE_COMMAND@
#define __aka_inline__ inline
#endif /* __AKANTU_AKA_CONFIG_HH__ */
diff --git a/src/common/aka_element_classes_info.hh.in b/src/common/aka_element_classes_info.hh.in
new file mode 100644
index 000000000..5670dff70
--- /dev/null
+++ b/src/common/aka_element_classes_info.hh.in
@@ -0,0 +1,195 @@
+/**
+ * @file aka_element_classes_info.hh
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Tue May 19 11:43:07 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100644
index 000000000..b160d5e3c
--- /dev/null
+++ b/src/common/aka_element_classes_info_inline_impl.cc
@@ -0,0 +1,92 @@
+/**
+ * @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
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * 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 51e6661b8..a595a4cf4 100644
--- a/src/common/aka_error.cc
+++ b/src/common/aka_error.cc
@@ -1,338 +1,354 @@
/**
* @file aka_error.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Sep 06 2010
* @date last modification: Tue Jul 29 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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>
-#include <execinfo.h>
+
+#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>
#else
# include <time.h>
#endif
#ifdef AKANTU_USE_MPI
# include <mpi.h>
#endif
#define __BEGIN_AKANTU_DEBUG__ namespace akantu { namespace debug {
#define __END_AKANTU_DEBUG__ } }
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU_DEBUG__
static void printBacktraceAndExit(int sig) {
printBacktrace(sig);
debugger.exit(-50);
}
/* ------------------------------------------------------------------------ */
void initSignalHandler() {
+#if not defined(_WIN32)
struct sigaction action;
action.sa_handler = &printBacktraceAndExit;
sigemptyset(&(action.sa_mask));
action.sa_flags = SA_RESETHAND;
sigaction(SIGSEGV, &action, NULL);
sigaction(SIGABRT, &action, NULL);
+#else
+ std::signal(SIGSEGV, &printBacktraceAndExit);
+ std::signal(SIGABRT, &printBacktraceAndExit);
+#endif
}
/* ------------------------------------------------------------------------ */
std::string demangle(const char *symbol) {
int status;
std::string result;
char *demangled_name;
if ((demangled_name = abi::__cxa_demangle(symbol, NULL, 0, &status)) != NULL) {
result = demangled_name;
free(demangled_name);
} else {
result = symbol;
}
return result;
}
/* ------------------------------------------------------------------------ */
+#if (defined(READLINK_COMMAND) || defined(ADDR2LINK_COMMAND)) && (not defined(_WIN32))
std::string exec(std::string cmd) {
FILE *pipe = popen(cmd.c_str(), "r");
if (!pipe) return "";
char buffer[1024];
std::string result = "";
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
result = result.substr(0, result.size() - 1);
pclose(pipe);
return result;
}
+#endif
/* ------------------------------------------------------------------------ */
void printBacktrace(__attribute__((unused)) int sig) {
AKANTU_DEBUG_INFO("Caught signal " << sig << "!");
+#if not defined(_WIN32)
#if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
std::string me = "";
char buf[1024];
/* The manpage says it won't null terminate. Let's zero the buffer. */
memset(buf, 0, sizeof(buf));
/* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */
if (readlink("/proc/self/exe", buf, sizeof(buf) - 1))
me = std::string(buf);
std::ifstream inmaps;
inmaps.open("/proc/self/maps");
std::map <std::string, size_t> addr_map;
std::string line;
while (inmaps.good()) {
std::getline(inmaps, line);
std::stringstream sstr(line);
size_t first = line.find('-');
std::stringstream sstra(line.substr(0, first));
size_t addr; sstra >> std::hex >> addr;
std::string lib;
sstr >> lib;
sstr >> lib;
sstr >> lib;
sstr >> lib;
sstr >> lib;
sstr >> lib;
if (lib != "" && addr_map.find(lib) == addr_map.end()) {
addr_map[lib] = addr;
}
}
if (me != "") addr_map[me] = 0;
#endif
+ /// \todo for windows this part could be coded using CaptureStackBackTrace and SymFromAddr
+
const size_t max_depth = 100;
size_t stack_depth;
void *stack_addrs[max_depth];
char **stack_strings;
size_t i;
stack_depth = backtrace(stack_addrs, max_depth);
stack_strings = backtrace_symbols(stack_addrs, stack_depth);
std::cerr << "BACKTRACE : " << stack_depth << " stack frames." << std::endl;
size_t w = size_t(std::floor(log(double(stack_depth)) / std::log(10.)) + 1);
/// -1 to remove the call to the printBacktrace function
for (i = 1; i < stack_depth; i++) {
std::cerr << std::dec << " [" << std::setw(w) << i << "] ";
std::string bt_line(stack_strings[i]);
size_t first, second;
if ((first = bt_line.find('(')) != std::string::npos && (second = bt_line.find('+')) != std::string::npos) {
std::string location = bt_line.substr(0, first);
#if defined(READLINK_COMMAND)
location = exec(std::string(BOOST_PP_STRINGIZE(READLINK_COMMAND)) + std::string(" -f ") + location);
#endif
std::string call = demangle(bt_line.substr(first + 1, second - first - 1).c_str());
size_t f = bt_line.find('[');
size_t s = bt_line.find(']');
std::string address = bt_line.substr(f + 1, s - f - 1);
std::stringstream sstra(address);
size_t addr; sstra >> std::hex >> addr;
std::cerr << location << " [" << call << "]";
#if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
std::map <std::string, size_t>::iterator it = addr_map.find(location);
if (it != addr_map.end()) {
std::stringstream syscom;
syscom << BOOST_PP_STRINGIZE(ADDR2LINE_COMMAND) << " 0x" << std::hex << (addr - it->second) << " -i -e " << location;
std::string line = exec(syscom.str());
std::cerr << " (" << line << ")" << std::endl;
} else {
#endif
std::cerr << " (0x" << std::hex << addr << ")" << std::endl;
#if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
}
#endif
} else {
std::cerr << bt_line << std::endl;
}
}
free(stack_strings);
std::cerr << "END BACKTRACE" << std::endl;
+#endif
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
Debugger::Debugger() {
cout = &std::cerr;
level = dblWarning;
parallel_context = "";
file_open = false;
print_backtrace = false;
}
/* ------------------------------------------------------------------------ */
Debugger::~Debugger() {
if (file_open) {
dynamic_cast <std::ofstream *>(cout)->close();
delete cout;
}
}
/* ------------------------------------------------------------------------ */
void Debugger::exit(int status) {
if (status != EXIT_SUCCESS && status != -50) {
#ifndef AKANTU_NDEBUG
int * a = NULL;
*a = 1;
#endif
if(this->print_backtrace)
akantu::debug::printBacktrace(15);
}
#ifdef AKANTU_USE_MPI
if (status != EXIT_SUCCESS)
MPI_Abort(MPI_COMM_WORLD, MPI_ERR_UNKNOWN);
#endif
std::exit(status); // not called when compiled with MPI due to MPI_Abort, but
// MPI_Abort does not have the noreturn attribute
}
/*------------------------------------------------------------------------- */
void Debugger::throwException(const std::string & info,
const std::string & file,
unsigned int line,
__attribute__((unused)) bool silent,
__attribute__((unused)) const std::string & location) const
throw(akantu::debug::Exception) {
#if !defined(AKANTU_NDEBUG)
if (!silent) {
printMessage("###", dblWarning, info + location);
}
#endif
debug::Exception ex(info, file, line);
throw ex;
}
/* ------------------------------------------------------------------------ */
void Debugger::printMessage(const std::string & prefix,
const DebugLevel & level,
const std::string & info) const {
if (this->level >= level) {
#if defined(AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
struct timeval time;
gettimeofday(&time, NULL);
double timestamp = time.tv_sec * 1e6 + time.tv_usec; /*in us*/
#else
struct timespec time;
clock_gettime(CLOCK_REALTIME_COARSE, &time);
double timestamp = time.tv_sec * 1e6 + time.tv_nsec * 1e-3; /*in us*/
#endif
*(cout) << parallel_context
<< "{" << (unsigned int)timestamp << "} "
<< prefix << " " << info
<< std::endl;
}
}
/* ------------------------------------------------------------------------ */
void Debugger::setDebugLevel(const DebugLevel & level) {
this->level = level;
}
/* ------------------------------------------------------------------------ */
const DebugLevel & Debugger::getDebugLevel() const {
return level;
}
/* ------------------------------------------------------------------------ */
void Debugger::setLogFile(const std::string & filename) {
if (file_open) {
dynamic_cast <std::ofstream *>(cout)->close();
delete cout;
}
std::ofstream *fileout = new std::ofstream(filename.c_str());
file_open = true;
cout = fileout;
}
std::ostream & Debugger::getOutputStream() {
return *cout;
}
/* ------------------------------------------------------------------------ */
void Debugger::setParallelContext(int rank, int size) {
std::stringstream sstr;
UInt pad = std::ceil(std::log10(size));
sstr << "<" << getpid() << ">[R" << std::setfill(' ') << std::right << std::setw(pad)
<< rank << "|S" << size << "] ";
parallel_context = sstr.str();
}
void setDebugLevel(const DebugLevel & level) {
debugger.setDebugLevel(level);
}
const DebugLevel & getDebugLevel() {
return debugger.getDebugLevel();
}
/* -------------------------------------------------------------------------- */
void exit(int status) {
debugger.exit(status);
}
-
__END_AKANTU_DEBUG__
diff --git a/src/common/aka_error.hh b/src/common/aka_error.hh
index 48ce45355..2e3992faa 100644
--- a/src/common/aka_error.hh
+++ b/src/common/aka_error.hh
@@ -1,295 +1,295 @@
/**
* @file aka_error.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Tue Jul 08 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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() (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_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..5cd15cf8f 100644
--- a/src/common/aka_event_handler_manager.hh
+++ b/src/common/aka_event_handler_manager.hh
@@ -1,90 +1,95 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 b2648381c..c9230ee0c 100644
--- a/src/common/aka_extern.cc
+++ b/src/common/aka_extern.cc
@@ -1,101 +1,103 @@
/**
* @file aka_extern.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jun 14 2010
* @date last modification: Thu Apr 03 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_array.hh"
#include "aka_math.hh"
#include "aka_random_generator.hh"
#include "parser.hh"
#include "cppargparse.hh"
#include "static_solver.hh"
/* -------------------------------------------------------------------------- */
#include <iostream>
#include <limits>
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_DEBUG_TOOLS)
# include "aka_debug_tools.hh"
#endif
__BEGIN_AKANTU__
/** \todo write function to get this
* values from the environment or a config file
*/
/* -------------------------------------------------------------------------- */
/* error.hpp variables */
/* -------------------------------------------------------------------------- */
namespace debug {
/// standard output for debug messages
std::ostream *_akantu_debug_cout = &std::cerr;
/// standard output for normal messages
std::ostream & _akantu_cout = std::cout;
/// parallel context used in debug messages
std::string _parallel_context = "";
Debugger debugger;
#if defined(AKANTU_DEBUG_TOOLS)
DebugElementManager element_manager;
#endif
}
/// Paser for commandline arguments
::cppargparse::ArgumentParser static_argparser;
/// Parser containing the information parsed by the input file given to initFull
Parser static_parser;
-bool Parser::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
/* -------------------------------------------------------------------------- */
UInt StaticSolver::nb_references = 0;
StaticSolver * StaticSolver::static_solver = NULL;
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/common/aka_fwd.hh b/src/common/aka_fwd.hh
index c452445fa..d5c0c4a99 100644
--- a/src/common/aka_fwd.hh
+++ b/src/common/aka_fwd.hh
@@ -1,71 +1,70 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_FWD_HH__
#define __AKANTU_FWD_HH__
namespace cppargparse {
class ArgumentParser;
}
namespace akantu {
-
// forward declaration
template <int dim, class model_type>
struct ContactData;
-
+
template<typename T> class Matrix;
template<typename T> class Vector;
template<typename T> class Tensor3;
template<typename T, bool is_scal = is_scalar<T>::value > class Array;
template <class T> class SpatialGrid;
// Model element
template <class ModelPolicy> class ModelElement;
extern const Array<UInt> empty_filter;
class Parser;
class ParserSection;
extern Parser static_parser;
extern cppargparse::ArgumentParser static_argparser;
}
#endif /* __AKANTU_FWD_HH__ */
diff --git a/src/common/aka_geometry.hh b/src/common/aka_geometry.hh
index 65fecf371..c95ff0de4 100644
--- a/src/common/aka_geometry.hh
+++ b/src/common/aka_geometry.hh
@@ -1,382 +1,365 @@
/**
* @file aka_geometry.hh
*
* @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
*
* @date creation: Fri Jan 04 2013
* @date last modification: Tue Sep 02 2014
*
* @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 8914b5cd1..7bf69449c 100644
--- a/src/common/aka_grid_dynamic.hh
+++ b/src/common/aka_grid_dynamic.hh
@@ -1,459 +1,506 @@
/**
* @file aka_grid_dynamic.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 21 2013
* @date last modification: Fri Mar 21 2014
*
* @brief Grid that is auto balanced
*
* @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_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
+// #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
+// #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)
+// #if defined(AKANTU_NDEBUG)
Cell & tmp = (cells[cell_id] = cell).add(d);
-#else
- Cell & tmp = (cells[cell_id] = cell).add(d, position);
-#endif
+// #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)
+// #if defined(AKANTU_NDEBUG)
return it->second.add(d);
-#else
- return it->second.add(d, position);
-#endif
+// #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
+// #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 51342067f..71aedd3de 100644
--- a/src/common/aka_math.cc
+++ b/src/common/aka_math.cc
@@ -1,189 +1,233 @@
/**
* @file aka_math.cc
*
* @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
* @author Peter Spijker <peter.spijker@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Guillaume Anciaux <guillaume.anciaux@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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 806f2ec80..2b73f641a 100644
--- a/src/common/aka_math.hh
+++ b/src/common/aka_math.hh
@@ -1,303 +1,301 @@
/**
* @file aka_math.hh
*
* @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 Nicolas Richart <nicolas.richart@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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 {
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-public:
-
/* ------------------------------------------------------------------------ */
/* 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);
- /// 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);
-
/// 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 034dc0565..7028c1e8e 100644
--- a/src/common/aka_math_tmpl.hh
+++ b/src/common/aka_math_tmpl.hh
@@ -1,774 +1,776 @@
/**
* @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 Alejandro M. Aragón <alejandro.aragon@epfl.ch>
* @author Nicolas Richart <nicolas.richart@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 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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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));
- if (abs_max < tolerance) return true;
- else return ( std::abs(x - y) / abs_max < tolerance);
+ 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_random_generator.hh b/src/common/aka_random_generator.hh
index 6127bb27f..a05f4ca13 100644
--- a/src/common/aka_random_generator.hh
+++ b/src/common/aka_random_generator.hh
@@ -1,351 +1,351 @@
/**
* @file aka_random_generator.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Jan 16 2013
* @date last modification: Wed Jun 25 2014
*
* @brief generic random generator
*
* @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_array.hh"
#if defined(AKANTU_USE_CXX11)
# define __CONST_EXPR constexpr
#else
# define __CONST_EXPR
#endif
#ifndef __AKANTU_AKA_RANDOM_GENERATOR_HH__
#define __AKANTU_AKA_RANDOM_GENERATOR_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* List of available distributions */
/* -------------------------------------------------------------------------- */
#define AKANTU_RANDOM_DISTRIBUTION_TYPES \
((uniform, UniformDistribution)) \
((weibull, WeibullDistribution))
#define AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_rdt_, elem)
#define AKANTU_RANDOM_DISTRIBUTION_PREFIX(s, data, elem) \
AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))
enum RandomDistributionType {
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_RANDOM_DISTRIBUTION_PREFIX,
_,
AKANTU_RANDOM_DISTRIBUTION_TYPES)),
_rdt_not_defined
};
/* -------------------------------------------------------------------------- */
/* Distribution */
/* -------------------------------------------------------------------------- */
/// Empty base to be able to store a distribution
template<typename T>
class RandomDistributionBase {
public:
virtual ~RandomDistributionBase() {}
virtual void printself(std::ostream & stream, int indent = 0) const = 0;
};
/* -------------------------------------------------------------------------- */
/* Uniform distribution */
/* -------------------------------------------------------------------------- */
template<typename T>
class UniformDistribution : public RandomDistributionBase<T> {
public:
UniformDistribution(T min = T(0.), T max = T(1.)) : min(min), max(max) { };
/* ------------------------------------------------------------------------ */
template<template<class> class RandomGenerator>
T operator() (RandomGenerator<T> & generator) {
T x = generator() / (RandomGenerator<T>::max() - RandomGenerator<T>::min());
return (x * (max - min) + min);
}
virtual void setParams(std::string value) {
std::stringstream sstr(value);
sstr >> min;
sstr >> max;
}
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << "Uniform [ min=" << min << ", max=" << max << " ]";
};
/* ------------------------------------------------------------------------ */
private:
T min;
T max;
};
/* -------------------------------------------------------------------------- */
/* Weibull distribution */
/* -------------------------------------------------------------------------- */
template<typename T>
class WeibullDistribution : public RandomDistributionBase<T> {
public:
WeibullDistribution(T scale, T shape) : m(shape), lambda(scale) { };
/* ------------------------------------------------------------------------ */
template<template<class> class RandomGenerator>
T operator()(RandomGenerator<T> & generator) {
T x = generator() / (RandomGenerator<T>::max() - RandomGenerator<T>::min());
T e = T(1) / m;
return lambda * std::pow(- std::log(1. - x), e);
}
virtual void setParams(std::string value) {
std::stringstream sstr(value);
sstr >> m;
sstr >> lambda;
}
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << "Weibull [ shape=" << m << ", scale=" << lambda << "]";
}
/* ------------------------------------------------------------------------ */
private:
/// shape parameter or Weibull modulus
T m;
/// scale parameter
T lambda;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Generator */
/* -------------------------------------------------------------------------- */
-
+#if not defined(_WIN32)
template<typename T>
class Rand48Generator {
/* ------------------------------------------------------------------------ */
public:
inline T operator()() { AKANTU_DEBUG_TO_IMPLEMENT(); }
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << "Rand48Generator [seed=" << seed << "]";
}
/* ------------------------------------------------------------------------ */
public:
static void seed(long int s) { _seed = s; srand48(_seed); }
static long int seed() { return _seed; }
static __CONST_EXPR T min() { return 0.; }
static __CONST_EXPR T max() { return 1.; }
/* ------------------------------------------------------------------------ */
private:
static long int _seed;
};
template<>
inline double Rand48Generator<double>::operator()() {
return drand48();
}
-
+#endif
/* -------------------------------------------------------------------------- */
template<typename T>
class RandGenerator {
/* ------------------------------------------------------------------------ */
public:
inline T operator()() { return rand(); }
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << "RandGenerator [seed=" << _seed << "]";
}
/* ------------------------------------------------------------------------ */
public:
static void seed(long int s) { _seed = s; srand(_seed); }
static long int seed() { return _seed; }
static __CONST_EXPR T min() { return 0.; }
static __CONST_EXPR T max() { return RAND_MAX; }
/* ------------------------------------------------------------------------ */
private:
static long int _seed;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#undef AKANTU_RANDOM_DISTRIBUTION_PREFIX
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE(r, data, elem) \
case AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem)): { \
stream << BOOST_PP_STRINGIZE(AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))); \
break; \
}
inline std::ostream & operator <<(std::ostream & stream, RandomDistributionType type) {
switch(type) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
default: stream << UInt(type) << " not a RandomDistributionType"; break;
}
return stream;
}
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_PRINT_CASE
/* -------------------------------------------------------------------------- */
/* Some Helper */
/* -------------------------------------------------------------------------- */
template<typename T, template<typename> class Distribution>
class RandomDistributionTypeHelper {
enum { value = _rdt_not_defined };
};
/* -------------------------------------------------------------------------- */
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE(r, data, elem) \
template<typename T> \
struct RandomDistributionTypeHelper<T, BOOST_PP_TUPLE_ELEM(2, 1, elem)> { \
enum { \
value = AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem)) \
}; \
};
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_GET_TYPE
/* -------------------------------------------------------------------------- */
/* RandomParameter */
/* -------------------------------------------------------------------------- */
template<typename T>
class RandomParameter {
public:
RandomParameter(T base_value) :
base_value(base_value), type(_rdt_not_defined), distribution(NULL) { }
template<template <typename> class Distribution>
RandomParameter(T base_value, const Distribution<T> & distribution) :
base_value(base_value),
type((RandomDistributionType)RandomDistributionTypeHelper<T, Distribution>::value),
distribution(new Distribution<T>(distribution)) { }
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_NEW(r, data, elem) \
else if(type == AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))){ \
typedef BOOST_PP_TUPLE_ELEM(2, 1, elem)<T> Dist; \
distribution = new Dist(*static_cast<Dist *>(other.distribution)); \
}
RandomParameter(const RandomParameter & other) :
base_value(other.base_value),
type(other.type) {
if(type == _rdt_not_defined) distribution = NULL;
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_NEW, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
}
inline void setBaseValue(const T & value) { this->base_value = value; }
inline T getBaseValue() const { return this->base_value; }
RandomParameter & operator=(const RandomParameter & other) {
if(this != &other) {
base_value = other.base_value;
type = other.type;
delete distribution;
if(type == _rdt_not_defined) distribution = NULL;
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_NEW, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
}
return *this;
}
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_NEW
/* ------------------------------------------------------------------------ */
#define AKANTU_RANDOM_DISTRIBUTION_TYPE_SET(r, data, elem) \
else if(type == AKANTU_RANDOM_DISTRIBUTION_TYPES_PREFIX(BOOST_PP_TUPLE_ELEM(2, 0, elem))){ \
this->set<BOOST_PP_TUPLE_ELEM(2, 1, elem), Generator>(it, end); \
}
template<template<typename> class Generator, class iterator>
void setValues(iterator it, iterator end) {
if(type == _rdt_not_defined) {
for (; it != end; ++it) *it = this->base_value;
}
BOOST_PP_SEQ_FOR_EACH(AKANTU_RANDOM_DISTRIBUTION_TYPE_SET, _, AKANTU_RANDOM_DISTRIBUTION_TYPES)
}
#undef AKANTU_RANDOM_DISTRIBUTION_TYPE_SET
virtual void printself(std::ostream & stream, int indent = 0) const {
stream << base_value;
if(type != _rdt_not_defined) stream << " " << *distribution;
}
private:
template<template<typename> class Distribution, template<typename> class Generator,
class iterator>
void set(iterator it, iterator end) {
typedef Distribution<T> Dist;
Dist & dist = *(static_cast<Dist *>(this->distribution));
Generator<T> gen;
for (; it != end; ++it) *it = this->base_value + dist(gen);
}
private:
/// Value with no random variations
T base_value;
/// Random distribution type
RandomDistributionType type;
/// Random distribution to use
RandomDistributionBase<T> * distribution;
};
/* -------------------------------------------------------------------------- */
template<typename T>
inline std::ostream & operator <<(std::ostream & stream, RandomDistributionBase<T> & _this) {
_this.printself(stream);
return stream;
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline std::ostream & operator <<(std::ostream & stream, RandomParameter<T> & _this) {
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_AKA_RANDOM_GENERATOR_HH__ */
diff --git a/src/common/aka_static_memory.cc b/src/common/aka_static_memory.cc
index 1767be826..62231fb45 100644
--- a/src/common/aka_static_memory.cc
+++ b/src/common/aka_static_memory.cc
@@ -1,154 +1,155 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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_inline_impl.cc b/src/common/aka_static_memory_inline_impl.cc
index 30f8f0fbf..f90f4ce09 100644
--- a/src/common/aka_static_memory_inline_impl.cc
+++ b/src/common/aka_static_memory_inline_impl.cc
@@ -1,63 +1,63 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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_EXCEPTION("StaticMemory as no memory with ID " << memory_id);
+ 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_EXCEPTION("StaticMemory as no array named " << name
- << " for the Memory " << memory_id);
+ 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_types.hh b/src/common/aka_types.hh
index d73dcb9e2..5a8c18c9f 100644
--- a/src/common/aka_types.hh
+++ b/src/common/aka_types.hh
@@ -1,977 +1,1118 @@
/**
* @file aka_types.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 17 2011
* @date last modification: Tue Aug 19 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 __INTEL_COMPILER
-#include <tr1/unordered_map>
-#else
-#include <map>
-#endif
-
/* -------------------------------------------------------------------------- */
+
#ifndef __AKANTU_AKA_TYPES_HH__
#define __AKANTU_AKA_TYPES_HH__
__BEGIN_AKANTU__
-/* -------------------------------------------------------------------------- */
-/* maps */
-/* -------------------------------------------------------------------------- */
-#ifndef __INTEL_COMPILER
-template<class Key, class Ty>
-struct unordered_map { typedef typename std::tr1::unordered_map<Key, Ty> type; };
-#else
-template<class Key, class Ty>
-struct unordered_map { typedef typename std::map<Key, Ty> type; };
-#endif
-
enum NormType {
L_1 = 1,
L_2 = 2,
L_inf = UInt(-1)
};
-
+/**
+ * DimHelper is a class to generalize the setup of a dim array from 3
+ * values. This gives a common interface in the TensorStorage class
+ * independently of its derived inheritance (Vector, Matrix, Tensor3)
+ */
template<UInt dim>
struct DimHelper {
static inline void setDims(UInt m, UInt n, UInt p, UInt dims[dim]);
};
+/* -------------------------------------------------------------------------- */
template<>
struct DimHelper<1> {
static inline void setDims(UInt m,
__attribute__((unused)) UInt n,
__attribute__((unused)) UInt p,
UInt dims[1]) {
dims[0] = m;
}
};
+/* -------------------------------------------------------------------------- */
template<>
struct DimHelper<2> {
static inline void setDims(UInt m,
UInt n,
__attribute__((unused)) UInt p,
UInt dims[2]) {
dims[0] = m;
dims[1] = n;
}
};
+/* -------------------------------------------------------------------------- */
template<>
struct DimHelper<3> {
static inline void setDims(UInt m,
UInt n,
UInt p,
UInt dims[3]) {
dims[0] = m;
dims[1] = n;
dims[2] = p;
}
};
/* -------------------------------------------------------------------------- */
-template<typename T, UInt ndim>
+template<typename T, UInt ndim, class RetType>
+class TensorStorage;
+
+/* -------------------------------------------------------------------------- */
+/* Proxy classes */
+/* -------------------------------------------------------------------------- */
+
+/**
+ * The TensorProxy class is a proxy class to the TensorStorage it handles the
+ * wrapped case. That is to say if an accessor should give access to a Tensor
+ * wrapped on some data, like the Array<T>::iterator they can return a
+ * TensorProxy that will be automatically transformed as a TensorStorage wrapped
+ * on the same data
+ */
+template<typename T, UInt ndim, class RetType>
class TensorProxy {
protected:
TensorProxy(T * data, UInt m, UInt n, UInt p) {
DimHelper<ndim>::setDims(m, n, p, this->n);
this->values = data;
}
TensorProxy(const TensorProxy & other) {
this->values = other.storage();
for (UInt i = 0; i < ndim; ++i)
this->n[i] = other.n[i];
}
+ inline TensorProxy(const TensorStorage<T, ndim, RetType> & other);
+
public:
UInt size(UInt i) const {
AKANTU_DEBUG_ASSERT(i < ndim,
"This tensor has only "
<< ndim << " dimensions, not " << (i + 1));
return n[i];
}
inline UInt size() const{
UInt _size = 1;
for (UInt d = 0; d < ndim; ++d) _size *= this->n[d];
return _size;
}
T * storage() const { return values; }
-// TensorProxy operator=(const TensorProxy & other) {
-// UInt _size = this->size();
-// #ifndef AKANTU_NDEBUG
-// UInt _size_other = other.size();
-// AKANTU_DEBUG_ASSERT(_size == _size_other, "The two tensor are not compatible in size");
-// #endif
-// memcpy(this->values, other.storage(), _size * sizeof(T));
-// return *this;
-// }
+ 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> {
- typedef TensorProxy<T, 1> parent;
+class VectorProxy : public TensorProxy<T, 1, Vector<T> > {
+ typedef TensorProxy<T, 1, Vector<T> > parent;
+ typedef Vector<T> type;
public:
- VectorProxy(T * data = NULL, UInt n = 0) : parent(data, n, 0, 0) { }
+ VectorProxy(T * data, UInt n) : parent(data, n, 0, 0) { }
VectorProxy(const VectorProxy & src) : parent(src) { }
- // VectorProxy & operator=(const VectorProxy & other) {
- // parent::operator=(other);
- // return *this;
- // }
+ 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> {
- typedef TensorProxy<T, 2> parent;
+class MatrixProxy : public TensorProxy<T, 2, Matrix<T> > {
+ typedef TensorProxy<T, 2, Matrix<T> > parent;
+ typedef Matrix<T> type;
public:
- MatrixProxy(T * data = NULL, UInt m = 0, UInt n = 0) : parent(data, m, n, 0) { }
+ MatrixProxy(T * data, UInt m, UInt n) : parent(data, m, n, 0) { }
MatrixProxy(const MatrixProxy & src) : parent(src) { }
- // MatrixProxy & operator=(const MatrixProxy & other) {
- // parent::operator=(other);
- // return *this;
- // }
-
+ 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> {
- typedef TensorProxy<T, 3> parent;
+class Tensor3Proxy : public TensorProxy<T, 3, Tensor3<T> > {
+ typedef TensorProxy<T, 3, Tensor3<T> > parent;
+ typedef Tensor3<T> type;
public:
- Tensor3Proxy(T * data = NULL, UInt m = 0, UInt n = 0, UInt k = 0) :
+ Tensor3Proxy(T * data, UInt m, UInt n, UInt k) :
parent(data, m, n, k) { }
Tensor3Proxy(const Tensor3Proxy & src) : parent(src) { }
- // Tensor3Proxy & operator=(const Tensor3Proxy & other) {
- // parent::operator=(other);
- // return *this;
- // }
+ 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> & proxy) {
+ 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) {
- AKANTU_DEBUG_ASSERT(this->_size == src.size(), "vectors of different size");
- memcpy(this->values, src.storage(), this->_size * sizeof(T));
+ // this test is not sufficient for Tensor of order higher than 1
+ AKANTU_DEBUG_ASSERT(this->_size == src.size(), "Tensors of different size");
+ memcpy((void*)this->values, (void*)src.storage(), this->_size * sizeof(T));
} else {
deepCopy(src);
}
}
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) { return *(this->values + i); };
- inline const T& operator()(UInt i) const { 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) {
+ AKANTU_DEBUG_ASSERT((i < this->n[0]),
+ "Access out of the vector! "
+ << "Index (" << i << ") is out of the vector of size ("
+ << this->n[0] << ")");
+ return *(this->values + i);
+ }
+
+ inline const T& operator()(UInt i) const {
+ AKANTU_DEBUG_ASSERT((i < this->n[0]),
+ "Access out of the vector! "
+ << "Index (" << i << ") is out of the vector of size ("
+ << this->n[0] << ")");
+ return *(this->values + i);
+ }
+
+ inline T& operator[](UInt i) { return *(this->values + i); }
+ inline const T& operator[](UInt i) const { return *(this->values + i); }
/* ------------------------------------------------------------------------ */
inline Vector<T> & operator*=(Real x) { return parent::operator*=(x); }
inline Vector<T> & operator/=(Real x) { return parent::operator/=(x); }
+
/* ------------------------------------------------------------------------ */
inline Vector<T> & operator*=(const Vector<T> & vect) {
T * a = this->storage();
T * b = vect.storage();
for (UInt i = 0; i < this->_size; ++i) *(a++) *= *(b++);
return *this;
}
/* ------------------------------------------------------------------------ */
inline Real dot(const Vector<T> & vect) const {
return Math::vectorDot(this->values, vect.storage(), this->_size);
}
+ /* ------------------------------------------------------------------------ */
+ inline Real mean() const {
+ Real mean = 0;
+ T * a = this->storage();
+ for (UInt i = 0; i < this->_size; ++i) mean += *(a++);
+ return mean / this->_size;
+ }
+
/* ------------------------------------------------------------------------ */
inline Vector & crossProduct(const Vector<T> & v1,
const Vector<T> & v2) {
AKANTU_DEBUG_ASSERT(this->size() == 3,
"crossProduct is only defined in 3D (n=" << this->size() << ")");
AKANTU_DEBUG_ASSERT(this->size() == v1.size() && this->size() == v2.size(),
"crossProduct is not a valid operation non matching size vectors");
Math::vectorProduct3(v1.storage(), v2.storage(), this->values);
return *this;
}
/* ------------------------------------------------------------------------ */
inline void solve(Matrix<T> & A, const Vector<T> & b) {
AKANTU_DEBUG_ASSERT(this->size() == A.rows() && this->_size = A.cols(),
- "The solution vector as a mismatch in size with the matrix");
- AKANTU_DEBUG_ASSERT(this->_size == b._size, "The rhs vector as a mismatch in size with the matrix");
+ "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 (((*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 << space << "Vector<" << debug::demangle(typeid(T).name()) << ">(" << this->_size <<") : [";
+ 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;
-/* -------------------------------------------------------------------------- */
-// support operations for the creation of other vectors
-template <typename T> Vector<T> operator*(T scalar, const Vector<T> & a);
-template <typename T> Vector<T> operator+(const Vector<T> & a, const Vector<T> & b);
-template <typename T> Vector<T> operator-(const Vector<T> & a, const Vector<T> & b);
-
-/* -------------------------------------------------------------------------- */
-template <typename T>
-Vector<T> operator*(T scalar, const Vector<T> & a) {
- Vector<T> r(a.size());
- r = a;
- r *= scalar;
- return r;
-}
-
-template <typename T>
-Vector<T> operator+(const Vector<T> & a, const Vector<T> & b) {
- Vector<T> r(a.size());
- r = a;
- r += b;
- return r;
-}
-
-template <typename T>
-Vector<T> operator-(const Vector<T>& a, const Vector<T>& b) {
- Vector<T> r(a.size());
- r = a;
- r -= b;
- return r;
-}
-
-template <typename T>
-Matrix<T> operator*(T scalar, const Matrix<T>& a) {
- Matrix<T> r(a.rows(), a.cols());
- r = a;
- r *= scalar;
- return r;
-}
-
-template <typename T>
-Matrix<T> operator+(const Matrix<T>& a, const Matrix<T>& b) {
- Matrix<T> r(a.rows(), a.cols());
- r = a;
- r += b;
- return r;
-}
-
-template <typename T>
-Matrix<T> operator-(const Matrix<T>& a, const Matrix<T>& b) {
- Matrix<T> r(a.rows(), a.cols());
- r = a;
- r -= b;
- return r;
-}
-
/* ------------------------------------------------------------------------ */
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& operator()(UInt i, UInt j) {
+ inline T& at(UInt i, UInt j) {
+ AKANTU_DEBUG_ASSERT(((i < this->n[0]) && (j < this->n[1])),
+ "Access out of the matrix! "
+ << "Index (" << i << ", " << j
+ << ") is out of the matrix of size ("
+ << this->n[0] << ", " << this->n[1] << ")");
return *(this->values + i + j*this->n[0]);
}
- inline const T& operator()(UInt i, UInt j) const {
+
+ 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");
+ 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");
+ 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.");
+ << " 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 << space << "Matrix<" << debug::demangle(typeid(T).name())
- << ">(" << this->n[0] << "," << this->n[1] <<") :" << "[";
+ 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)
- { return *(this->values + (k*this->n[0] + i)*this->n[1] + j); };
- inline const T& operator()(UInt i, UInt j, UInt k) const
- { return *(this->values + (k*this->n[0] + i)*this->n[1] + j); };
-
- inline MatrixProxy<T> operator()(UInt k)
- { return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]); }
- inline const MatrixProxy<T> operator()(UInt k) const
- { return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]); }
-
- inline MatrixProxy<T> operator[](UInt k)
- { return Matrix<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]); }
+ inline T& operator()(UInt i, UInt j, UInt k) {
+ AKANTU_DEBUG_ASSERT((i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
+ "Access out of the tensor3! "
+ << "You are trying to access the element "
+ << "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
+ << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
+ return *(this->values + (k*this->n[0] + i)*this->n[1] + j);
+ }
+
+ inline const T& operator()(UInt i, UInt j, UInt k) const {
+ AKANTU_DEBUG_ASSERT((i < this->n[0]) && (j < this->n[1]) && (k < this->n[2]),
+ "Access out of the tensor3! "
+ << "You are trying to access the element "
+ << "(" << i << ", " << j << ", " << k << ") in a tensor of size ("
+ << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
+ return *(this->values + (k*this->n[0] + i)*this->n[1] + j);
+ }
+
+ inline MatrixProxy<T> operator()(UInt k) {
+ AKANTU_DEBUG_ASSERT((k < this->n[2]),
+ "Access out of the tensor3! "
+ << "You are trying to access the slice "
+ << k << " in a tensor3 of size ("
+ << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
+ return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]);
+ }
+
+ inline const MatrixProxy<T> operator()(UInt k) const {
+ AKANTU_DEBUG_ASSERT((k < this->n[2]),
+ "Access out of the tensor3! "
+ << "You are trying to access the slice "
+ << k << " in a tensor3 of size ("
+ << this->n[0] << ", " << this->n[1] << ", " << this->n[2] << ")");
+ return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]);
+ }
+
+ inline MatrixProxy<T> operator[](UInt k) {
+ return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]);
+ }
+
+ inline const MatrixProxy<T> operator[](UInt k) const {
+ return MatrixProxy<T>(this->values + k*this->n[0]*this->n[1], this->n[0], this->n[1]);
+ }
};
+
+/* -------------------------------------------------------------------------- */
+// support operations for the creation of other vectors
+/* -------------------------------------------------------------------------- */
+template <typename T>
+Vector<T> operator*(const T & scalar, const Vector<T> & a) {
+ Vector<T> r(a);
+ r *= scalar;
+ return r;
+}
+
+template <typename T>
+Vector<T> operator*(const Vector<T> & a, const T & scalar) {
+ Vector<T> r(a);
+ r *= scalar;
+ return r;
+}
+
+template <typename T>
+Vector<T> operator/(const Vector<T> & a, const T & scalar) {
+ Vector<T> r(a);
+ r /= scalar;
+ return r;
+}
+
+template <typename T>
+Vector<T> operator+(const Vector<T> & a, const Vector<T> & b) {
+ Vector<T> r(a);
+ r += b;
+ return r;
+}
+
+template <typename T>
+Vector<T> operator-(const Vector<T>& a, const Vector<T>& b) {
+ Vector<T> r(a);
+ r -= b;
+ return r;
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
+Matrix<T> operator*(const T & scalar, const Matrix<T>& a) {
+ Matrix<T> r(a);
+ r *= scalar;
+ return r;
+}
+
+template <typename T>
+Matrix<T> operator*(const Matrix<T>& a, const T & scalar) {
+ Matrix<T> r(a);
+ r *= scalar;
+ return r;
+}
+
+template <typename T>
+Matrix<T> operator/(const Matrix<T>& a, const T & scalar) {
+ Matrix<T> r(a);
+ r /= scalar;
+ return r;
+}
+
+template <typename T>
+Matrix<T> operator+(const Matrix<T>& a, const Matrix<T>& b) {
+ Matrix<T> r(a);
+ r += b;
+ return r;
+}
+
+template <typename T>
+Matrix<T> operator-(const Matrix<T>& a, const Matrix<T>& b) {
+ Matrix<T> r(a);
+ r -= b;
+ return r;
+}
+
+
+
__END_AKANTU__
#endif /* __AKANTU_AKA_TYPES_HH__ */
diff --git a/src/fe_engine/cohesive_element.cc b/src/fe_engine/cohesive_element.cc
index 2033731cb..f02c0cbfb 100644
--- a/src/fe_engine/cohesive_element.cc
+++ b/src/fe_engine/cohesive_element.cc
@@ -1,111 +1,148 @@
/**
* @file cohesive_element.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Feb 03 2012
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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..39bc5086b 100644
--- a/src/fe_engine/cohesive_element.hh
+++ b/src/fe_engine/cohesive_element.hh
@@ -1,65 +1,72 @@
/**
* @file cohesive_element.hh
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Feb 03 2012
* @date last modification: Fri Jun 13 2014
*
- * @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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_class.cc b/src/fe_engine/element_class.cc
index 76f1ca88c..c31cf9e7e 100644
--- a/src/fe_engine/element_class.cc
+++ b/src/fe_engine/element_class.cc
@@ -1,78 +1,84 @@
/**
* @file element_class.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Peter Spijker <peter.spijker@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Jul 20 2010
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 3ec418788..106f81ffe 100644
--- a/src/fe_engine/element_class.hh
+++ b/src/fe_engine/element_class.hh
@@ -1,371 +1,370 @@
/**
* @file element_class.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Jul 04 2014
*
- * @brief Declaration of the ElementClass main class and the
+ * @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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__
-
-/* -------------------------------------------------------------------------- */
-enum GaussIntergrationType {
- _git_not_defined,
- _git_point,
- _git_segment,
- _git_triangle,
- _git_tetrahedron,
- _git_pentahedron
-};
-
-/* -------------------------------------------------------------------------- */
-/* -------------------------------------------------------------------------- */
-
-
/* -------------------------------------------------------------------------- */
+/// default element class structure
template<ElementType element_type>
struct ElementClassProperty {
static const GeometricalType geometrical_type = _gt_not_defined;
static const InterpolationType interpolation_type = _itp_not_defined;
static const ElementKind element_kind = _ek_regular;
static const UInt spatial_dimension = 0;
static const GaussIntergrationType gauss_integration_type = _git_not_defined;
static const UInt minimal_integration_order = 0;
};
+/// Macro to generate the element class structures for different element types
#define AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(elem_type, geom_type, \
interp_type, \
elem_kind, \
sp, \
gauss_int_type, \
min_int_order) \
template<> \
struct ElementClassProperty<elem_type> { \
static const GeometricalType geometrical_type = geom_type; \
static const InterpolationType interpolation_type = interp_type; \
static const ElementKind element_kind = elem_kind; \
static const UInt spatial_dimension = sp; \
static const GaussIntergrationType gauss_integration_type = gauss_int_type; \
static const UInt minimal_integration_order = min_int_order; \
}
/* -------------------------------------------------------------------------- */
/* Geometry */
/* -------------------------------------------------------------------------- */
-enum GeometricalShapeType {
- _gst_not_defined,
- _gst_point,
- _gst_triangle,
- _gst_square,
- _gst_prism
-};
-
+/// Default GeometricalShape structure
template<GeometricalType geometrical_type>
struct GeometricalShape {
static const GeometricalShapeType shape = _gst_point;
};
+/// Templated GeometricalShape with function contains
template<GeometricalShapeType shape>
struct GeometricalShapeContains {
+ /// Check if the point (vector in 2 and 3D) at natural coordinate coor
template <class vector_type>
static inline bool contains(const vector_type & coord);
};
+/// Macro to generate the GeometricalShape structures for different geometrical types
#define AKANTU_DEFINE_SHAPE(geom_type, geom_shape) \
template<> \
struct GeometricalShape<geom_type> { \
static const GeometricalShapeType shape = geom_shape; \
}
/* -------------------------------------------------------------------------- */
+/// Templated GeometricalElement with function getInradius
template< GeometricalType geometrical_type,
GeometricalShapeType shape = GeometricalShape<geometrical_type>::shape >
class GeometricalElement {
public:
/// compute the in-radius
static inline Real getInradius(__attribute__((unused)) const Matrix<Real> & coord) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// true if the natural coordinates are in the element
template <class vector_type>
static inline bool contains(const vector_type & coord);
public:
static AKANTU_GET_MACRO_NOT_CONST(SpatialDimension, spatial_dimension, UInt);
static AKANTU_GET_MACRO_NOT_CONST(NbNodesPerElement, nb_nodes_per_element, UInt);
static AKANTU_GET_MACRO_NOT_CONST(NbFacetTypes, nb_facet_types, UInt);
- static inline UInt getNbFacetsPerElement(UInt t = 0);
+ static inline UInt getNbFacetsPerElement(UInt t);
+ static inline UInt getNbFacetsPerElement();
static inline const MatrixProxy<UInt> getFacetLocalConnectivityPerElement(UInt t = 0);
protected:
/// Number of nodes per element
static UInt nb_nodes_per_element;
/// spatial dimension of the element
static UInt spatial_dimension;
/// number of different facet types
static UInt nb_facet_types;
/// number of facets for element
static UInt nb_facets[];
/// storage of the facet local connectivity
static UInt facet_connectivity_vect[];
/// local connectivity of facets
static UInt * facet_connectivity[];
private:
/// Type of the facet elements
static UInt nb_nodes_per_facet[];
};
/* -------------------------------------------------------------------------- */
/* Interpolation */
/* -------------------------------------------------------------------------- */
-/// @enum InterpolationKind the family of interpolation types
-enum InterpolationKind {
- _itk_not_defined,
- _itk_lagrangian,
- _itk_structural
-};
-
-
+/// default InterpolationPorperty structure
template<InterpolationType interpolation_type>
struct InterpolationPorperty {
static const InterpolationKind kind = _itk_not_defined;
static const UInt nb_nodes_per_element = 0;
static const UInt natural_space_dimension = 0;
};
+/// Macro to generate the InterpolationPorperty structures for different interpolation types
#define AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(itp_type, \
itp_kind, \
nb_nodes, \
ndim) \
template<> \
struct InterpolationPorperty<itp_type> { \
static const InterpolationKind kind = itp_kind; \
static const UInt nb_nodes_per_element = nb_nodes; \
static const UInt natural_space_dimension = ndim; \
};
#include "interpolation_element_tmpl.hh"
/* -------------------------------------------------------------------------- */
+/// Generic (templated by the enum InterpolationType which specifies the order and the dimension of the interpolation) class handling the elemental interpolation
template<InterpolationType interpolation_type,
InterpolationKind kind = InterpolationPorperty<interpolation_type>::kind>
class InterpolationElement {
public:
typedef InterpolationPorperty<interpolation_type> interpolation_property;
/// compute the shape values for a given set of points in natural coordinates
static inline void computeShapes(const Matrix<Real> & natural_coord,
Matrix<Real> & N);
/// compute the shape values for a given point in natural coordinates
template <class vector_type>
static inline void computeShapes(__attribute__((unused)) const vector_type & natural_coord,
__attribute__((unused)) vector_type & N) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of
* shape functions along with variation of natural coordinates on a given set
* of points in natural coordinates
*/
static inline void computeDNDS(const Matrix<Real> & natural_coord,
Tensor3<Real> & dnds);
/**
* compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of shape functions along with
* variation of natural coordinates on a given point in natural
* coordinates
*/
template <class vector_type, class matrix_type>
static inline void computeDNDS(__attribute__((unused)) const vector_type & natural_coord,
__attribute__((unused)) matrix_type & dnds) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// compute jacobian (or integration variable change factor) for a given point
/// in the case of spatial_dimension != natural_space_dimension
static inline void computeSpecialJacobian(__attribute__((unused)) const Matrix<Real> & J,
__attribute__((unused)) Real & jacobians) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// interpolate a field given (arbitrary) natural coordinates
static inline void interpolateOnNaturalCoordinates(const Vector<Real> & natural_coords,
const Matrix<Real> & nodal_values,
Vector<Real> & interpolated);
+ /// interpolate a field given the shape functions on the interpolation point
+ static inline void interpolate(const Matrix<Real> & nodal_values,
+ const Vector<Real> & shapes,
+ Vector<Real> & interpolated);
+
+ /// interpolate a field given the shape functions on the interpolations points
+ static inline void interpolate(const Matrix<Real> & nodal_values,
+ const Matrix<Real> & shapes,
+ Matrix<Real> & interpolated);
+
/// compute the gradient of a given field on the given natural coordinates
static inline void gradientOnNaturalCoordinates(const Vector<Real> & natural_coords,
const Matrix<Real> & f,
Matrix<Real> & gradient);
public:
static AKANTU_GET_MACRO_NOT_CONST(ShapeSize, InterpolationPorperty<interpolation_type>::nb_nodes_per_element, UInt);
static AKANTU_GET_MACRO_NOT_CONST(ShapeDerivativesSize, (InterpolationPorperty<interpolation_type>::nb_nodes_per_element * InterpolationPorperty<interpolation_type>::natural_space_dimension), UInt);
static AKANTU_GET_MACRO_NOT_CONST(NaturalSpaceDimension, InterpolationPorperty<interpolation_type>::natural_space_dimension, UInt);
static AKANTU_GET_MACRO_NOT_CONST(NbNodesPerInterpolationElement, InterpolationPorperty<interpolation_type>::nb_nodes_per_element, UInt);
};
/* -------------------------------------------------------------------------- */
/* Integration */
/* -------------------------------------------------------------------------- */
template<GaussIntergrationType git_class, UInt max_order>
struct GaussIntegrationTypeData {
/// quadrature points in natural coordinates
static Real quad_positions[];
/// weights for the Gauss integration
static Real quad_weights[];
/// Number of quadrature points per element
static UInt nb_quadrature_points;
};
template<ElementType type, UInt order = ElementClassProperty<type>::minimal_integration_order>
class GaussIntegrationElement {
public:
static UInt getNbQuadraturePoints();
static const Matrix<Real> getQuadraturePoints();
static const Vector<Real> getWeights();
};
/* -------------------------------------------------------------------------- */
/* ElementClass */
/* -------------------------------------------------------------------------- */
template<ElementType element_type,
ElementKind element_kind = ElementClassProperty<element_type>::element_kind>
class ElementClass :
public GeometricalElement<ElementClassProperty<element_type>::geometrical_type>,
public InterpolationElement<ElementClassProperty<element_type>::interpolation_type> {
protected:
typedef GeometricalElement<ElementClassProperty<element_type>::geometrical_type> geometrical_element;
typedef InterpolationElement<ElementClassProperty<element_type>::interpolation_type> interpolation_element;
typedef ElementClassProperty<element_type> element_property;
typedef typename interpolation_element::interpolation_property interpolation_property;
public:
/**
* compute @f$ J = \frac{\partial x_j}{\partial s_i} @f$ the variation of real
* coordinates along with variation of natural coordinates on a given point in
* natural coordinates
*/
static inline void computeJMat(const Matrix<Real> & dnds,
const Matrix<Real> & node_coords,
Matrix<Real> & J);
/**
* compute the Jacobian matrix by computing the variation of real coordinates
* along with variation of natural coordinates on a given set of points in
* natural coordinates
*/
static inline void computeJMat(const Tensor3<Real> & dnds,
const Matrix<Real> & node_coords,
Tensor3<Real> & J);
/// compute the jacobians of a serie of natural coordinates
static inline void computeJacobian(const Matrix<Real> & natural_coords,
const Matrix<Real> & node_coords,
Vector<Real> & jacobians);
/// compute jacobian (or integration variable change factor) for a set of points
static inline void computeJacobian(const Tensor3<Real> & J,
Vector<Real> & jacobians);
/// compute jacobian (or integration variable change factor) for a given point
static inline void computeJacobian(const Matrix<Real> & J,
Real & jacobians);
/// compute shape derivatives (input is dxds) for a set of points
static inline void computeShapeDerivatives(const Tensor3<Real> & J,
const Tensor3<Real> & dnds,
Tensor3<Real> & shape_deriv);
/// compute shape derivatives (input is dxds) for a given point
static inline void computeShapeDerivatives(const Matrix<Real> & J,
const Matrix<Real> & dnds,
Matrix<Real> & shape_deriv);
/// compute the normal of a surface defined by the function f
static inline void computeNormalsOnNaturalCoordinates(const Matrix<Real> & coord,
Matrix<Real> & f,
Matrix<Real> & normals);
/// get natural coordinates from real coordinates
static inline void inverseMap(const Vector<Real> & real_coords,
const Matrix<Real> & node_coords,
Vector<Real> & natural_coords,
Real tolerance = 1e-8);
+
+ /// get natural coordinates from real coordinates
+ static inline void inverseMap(const Matrix<Real> & real_coords,
+ const Matrix<Real> & node_coords,
+ Matrix<Real> & natural_coords,
+ Real tolerance = 1e-8);
public:
static AKANTU_GET_MACRO_NOT_CONST(Kind, element_kind, ElementKind);
static AKANTU_GET_MACRO_NOT_CONST(SpatialDimension, ElementClassProperty<element_type>::spatial_dimension, UInt);
static AKANTU_GET_MACRO_NOT_CONST(P1ElementType, p1_type, const ElementType &);
static const ElementType & getFacetType(UInt t = 0) { return facet_type[t]; }
- static const ElementType * getFacetTypeInternal() { return facet_type; }
+ 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_classes/element_class_bernoulli_beam_inline_impl.cc"
-# include "element_classes/element_class_kirchhoff_shell_inline_impl.cc"
#endif
-// #if defined(AKANTU_IGFEM)
-// # include "element_class_igfem.hh"
-// #endif
+#if defined(AKANTU_IGFEM)
+# include "element_class_igfem.hh"
+#endif
+
-__END_AKANTU__
#endif /* __AKANTU_ELEMENT_CLASS_HH__ */
diff --git a/src/fe_engine/element_class_structural.hh b/src/fe_engine/element_class_structural.hh
index 4fcbd772c..2774662d4 100644
--- a/src/fe_engine/element_class_structural.hh
+++ b/src/fe_engine/element_class_structural.hh
@@ -1,229 +1,243 @@
/**
* @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>
*
* @date creation: Wed Jan 16 2013
* @date last modification: Fri Jul 04 2014
*
- * @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)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
+__BEGIN_AKANTU__
+
/* -------------------------------------------------------------------------- */
template<InterpolationType interpolation_type>
class InterpolationElement<interpolation_type, _itk_structural> {
public:
typedef InterpolationPorperty<interpolation_type> interpolation_property;
/// compute the shape values for a given set of points in natural coordinates
static inline void computeShapes(const Matrix<Real> & natural_coord,
Matrix<Real> & N,
const Matrix<Real> & real_nodal_coord,
UInt n = 0) {
UInt nb_points = natural_coord.cols();
for (UInt p = 0; p < nb_points; ++p) {
Vector<Real> Np = N(p);
computeShapes(natural_coord(p), Np, real_nodal_coord, n);
}
}
/// compute the shape values for a given point in natural coordinates
static inline void computeShapes(const Vector<Real> & natural_coord,
Vector<Real> & N,
const Matrix<Real> & real_nodal_coord,
UInt n = 0);
/**
* compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of
* shape functions along with variation of natural coordinates on a given set
* of points in natural coordinates
*/
static inline void computeDNDS(const Matrix<Real> & natural_coord,
Tensor3<Real> & dnds,
const Matrix<Real> & real_nodal_coord,
UInt n = 0) {
for (UInt i = 0; i < natural_coord.cols(); ++i) {
Matrix<Real> dnds_t = dnds(i);
computeDNDS(natural_coord(i), dnds_t, real_nodal_coord, n);
}
}
/**
* compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of shape functions along with
* variation of natural coordinates on a given point in natural
* coordinates
*/
static inline void computeDNDS(const Vector<Real> & natural_coord,
Matrix<Real> & dnds,
const Matrix<Real> & real_nodal_coord,
UInt n = 0);
public:
static AKANTU_GET_MACRO_NOT_CONST(NbShapeFunctions, nb_shape_functions, UInt);
static AKANTU_GET_MACRO_NOT_CONST(NbShapeDerivatives, nb_shape_derivatives, UInt);
static AKANTU_GET_MACRO_NOT_CONST(ShapeSize, interpolation_property::nb_nodes_per_element, UInt);
static AKANTU_GET_MACRO_NOT_CONST(ShapeDerivativesSize, (interpolation_property::nb_nodes_per_element * interpolation_property::natural_space_dimension), UInt);
static AKANTU_GET_MACRO_NOT_CONST(NaturalSpaceDimension, interpolation_property::natural_space_dimension, UInt);
protected:
/// nb shape functions
static const UInt nb_shape_functions;
static const UInt nb_shape_derivatives;
};
+
+/// Macro to generate the element class structures for different structural element types
/* -------------------------------------------------------------------------- */
#define AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(elem_type, \
geom_type, \
interp_type, \
parent_el_type, \
elem_kind, \
sp, \
gauss_int_type, \
min_int_order) \
template<> \
struct ElementClassProperty<elem_type> { \
static const GeometricalType geometrical_type = geom_type; \
static const InterpolationType interpolation_type = interp_type; \
static const ElementType parent_element_type = parent_el_type; \
static const ElementKind element_kind = elem_kind; \
static const UInt spatial_dimension = sp; \
static const GaussIntergrationType gauss_integration_type = gauss_int_type; \
static const UInt minimal_integration_order = min_int_order; \
}
+/* -------------------------------------------------------------------------- */
+/* ElementClass for structural elements */
/* -------------------------------------------------------------------------- */
template<ElementType element_type>
class ElementClass<element_type, _ek_structural> :
public GeometricalElement<ElementClassProperty<element_type>::geometrical_type>,
public InterpolationElement<ElementClassProperty<element_type>::interpolation_type> {
protected:
typedef GeometricalElement<ElementClassProperty<element_type>::geometrical_type> geometrical_element;
typedef InterpolationElement<ElementClassProperty<element_type>::interpolation_type> interpolation_element;
typedef ElementClass<ElementClassProperty<element_type>::parent_element_type> parent_element;
public:
/// compute shape derivatives (input is dxds) for a set of points
static inline void computeShapeDerivatives(const Matrix<Real> & natural_coord,
Tensor3<Real> & shape_deriv,
const Matrix<Real> & real_nodal_coord,
UInt n = 0) {
UInt nb_points = natural_coord.cols();
-
- if (element_type ==_kirchhoff_shell) {
- /// TO BE CONTINUED
+
+ if (element_type ==_kirchhoff_shell) {
+ /// TO BE CONTINUED and moved in a _tmpl.hh
UInt spatial_dimension = real_nodal_coord.cols();
UInt nb_nodes = real_nodal_coord.rows();
const UInt projected_dim = natural_coord.rows();
Matrix<Real> rotation_matrix(real_nodal_coord);
Matrix<Real> rotated_nodal_coord(real_nodal_coord);
Matrix<Real> projected_nodal_coord(natural_coord);
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Matrix<Real> Pe (real_nodal_coord);
Matrix<Real> Pg (real_nodal_coord);
Matrix<Real> inv_Pg(real_nodal_coord);
/// compute matrix Pe
Pe.eye();
-
+
/// compute matrix Pg
Vector<Real> Pg_col_1(spatial_dimension);
Pg_col_1(0) = real_nodal_coord(0,1) - real_nodal_coord(0,0);
Pg_col_1(1) = real_nodal_coord(1,1) - real_nodal_coord(1,0);
Pg_col_1(2) = real_nodal_coord(2,1) - real_nodal_coord(2,0);
Vector<Real> Pg_col_2(spatial_dimension);
Pg_col_2(0) = real_nodal_coord(0,2) - real_nodal_coord(0,0);
Pg_col_2(1) = real_nodal_coord(1,2) - real_nodal_coord(1,0);
Pg_col_2(2) = real_nodal_coord(2,2) - real_nodal_coord(2,0);
Vector<Real> Pg_col_3(spatial_dimension);
Pg_col_3.crossProduct(Pg_col_1, Pg_col_2);
-
-
+
+
for (UInt i = 0; i < nb_points; ++i) {
Pg(i,0) = Pg_col_1(i);
Pg(i,1) = Pg_col_2(i);
Pg(i,2) = Pg_col_3(i);
}
-
+
/// compute inverse of Pg
inv_Pg.inverse(Pg);
/// compute rotation matrix
// rotation_matrix=Pe*inv_Pg;
rotation_matrix.eye();
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
rotated_nodal_coord.mul<false, false>(rotation_matrix, real_nodal_coord);
-
+
for (UInt i = 0; i < projected_dim ; ++i) {
for (UInt j = 0; j < nb_points; ++j) {
projected_nodal_coord(i,j) = rotated_nodal_coord(i,j);
}
}
Tensor3<Real> dnds(projected_dim, nb_nodes, natural_coord.cols());
Tensor3<Real> J (projected_dim, projected_dim, natural_coord.cols());
parent_element::computeDNDS(natural_coord, dnds);
-
+
parent_element::computeJMat(dnds, projected_nodal_coord, J);
-
+
for (UInt p = 0; p < nb_points; ++p) {
Matrix<Real> shape_deriv_p = shape_deriv(p);
-
+
interpolation_element::computeDNDS(natural_coord(p), shape_deriv_p, projected_nodal_coord, n);
-
+
Matrix<Real> dNdS = shape_deriv_p;
Matrix<Real> inv_J(projected_dim, projected_dim);
inv_J.inverse(J(p));
shape_deriv_p.mul<false, false>(inv_J, dNdS);
}
}
else {
for (UInt p = 0; p < nb_points; ++p) {
Matrix<Real> shape_deriv_p = shape_deriv(p);
interpolation_element::computeDNDS(natural_coord(p), shape_deriv_p, real_nodal_coord, n);
}
}
}
/// compute jacobian (or integration variable change factor) for a given point
static inline void computeJacobian(const Matrix<Real> & natural_coords,
const Matrix<Real> & nodal_coords,
Vector<Real> & jacobians) {
parent_element::computeJacobian(natural_coords, nodal_coords, jacobians);
}
public:
static AKANTU_GET_MACRO_NOT_CONST(Kind, _ek_structural, ElementKind);
- static AKANTU_GET_MACRO_NOT_CONST(P1ElementType, _not_defined, const ElementType);
- static AKANTU_GET_MACRO_NOT_CONST(FacetType, _not_defined, const ElementType);
+ static AKANTU_GET_MACRO_NOT_CONST(P1ElementType, _not_defined, ElementType);
+ static AKANTU_GET_MACRO_NOT_CONST(FacetType, _not_defined, ElementType);
+ static const ElementType getFacetType(UInt t = 0) { return _not_defined; }
static AKANTU_GET_MACRO_NOT_CONST(SpatialDimension, ElementClassProperty<element_type>::spatial_dimension, UInt);
+ static ElementType * getFacetTypeInternal() { return NULL; }
};
+
+#include "element_classes/element_class_bernoulli_beam_inline_impl.cc"
+#include "element_classes/element_class_kirchhoff_shell_inline_impl.cc"
+
+__END_AKANTU__
diff --git a/src/fe_engine/element_class_tmpl.hh b/src/fe_engine/element_class_tmpl.hh
index 7f39a8d32..65cfd8b0e 100644
--- a/src/fe_engine/element_class_tmpl.hh
+++ b/src/fe_engine/element_class_tmpl.hh
@@ -1,516 +1,582 @@
/**
* @file element_class_tmpl.hh
*
* @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
*
* @brief Implementation of the inline templated function of the element class
* descriptions
*
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* 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.) && (coords(i) <= 1.));
+ 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) >= 0) && (coords(i) <= 1.));
+ in &= ((coords(i) >= - (Math::getTolerance())) && (coords(i) <= (1. + Math::getTolerance())));
sum += coords(i);
}
- if(in) return (in && (sum <= 1));
+ 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);
-
- 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(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());
+ 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_hexahedron_20_inline_impl.cc b/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
new file mode 100644
index 000000000..715fe3387
--- /dev/null
+++ b/src/fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
@@ -0,0 +1,239 @@
+/**
+ * @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;
+}
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..d56b54db5 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,214 @@
/**
* @file element_class_hexahedron_8_inline_impl.cc
*
* @author Peter Spijker <peter.spijker@epfl.ch>
*
* @date creation: Mon Mar 14 2011
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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_pentahedron_15_inline_impl.cc b/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
new file mode 100644
index 000000000..40fbc9504
--- /dev/null
+++ b/src/fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
@@ -0,0 +1,171 @@
+/**
+ * @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);
+}
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..e279cb18c 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 Thomas Menouillard <tmenouillard@stucky.ch>
*
* @date creation: Wed Jun 12 2013
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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_quadrangle_4_inline_impl.cc b/src/fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
index f396e2459..29e8cef18 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,151 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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) = .25 * (1 - c(0)) * (1 - c(1)); /// N1(q_0)
- N(1) = .25 * (1 + c(0)) * (1 - c(1)); /// N2(q_0)
- N(2) = .25 * (1 + c(0)) * (1 + c(1)); /// N3(q_0)
- N(3) = .25 * (1 - c(0)) * (1 + c(1)); /// N4(q_0)
+ 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) = - .25 * (1 - c(1));
- dnds(0, 1) = .25 * (1 - c(1));
- dnds(0, 2) = .25 * (1 + c(1));
- dnds(0, 3) = - .25 * (1 + c(1));
+ 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) = - .25 * (1 - c(0));
- dnds(1, 1) = - .25 * (1 + c(0));
- dnds(1, 2) = .25 * (1 + c(0));
- dnds(1, 3) = .25 * (1 - c(0));
+ 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 454a15642..2dad01b1d 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,177 +1,188 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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/fe_engine.cc b/src/fe_engine/fe_engine.cc
index 753c477cf..a64268b6f 100644
--- a/src/fe_engine/fe_engine.cc
+++ b/src/fe_engine/fe_engine.cc
@@ -1,241 +1,276 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "fe_engine.hh"
#include "mesh.hh"
#include "element_class.hh"
#include "static_communicator.hh"
#include "aka_math.hh"
#include "dof_synchronizer.hh"
-
-
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
FEEngine::FEEngine(Mesh & mesh, UInt element_dimension, ID id, MemoryID memory_id) :
- Memory(id, memory_id), mesh(mesh), normals_on_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::assembleArray(const Array<Real> & elementary_vect,
- Array<Real> & nodal_values,
- const Array<Int> & equation_number,
- UInt nb_degree_of_freedom,
- const ElementType & type,
- const GhostType & ghost_type,
- const Array<UInt> & filter_elements,
- Real scale_factor) const {
+ Array<Real> & nodal_values,
+ const Array<Int> & equation_number,
+ UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type,
+ const Array<UInt> & filter_elements,
+ Real scale_factor) const {
AKANTU_DEBUG_IN();
UInt nb_element;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
Array<UInt>::const_iterator< Vector<UInt> > conn_it;
Array<UInt> * filtered_connectivity = NULL;
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
filtered_connectivity = new Array<UInt>(0, nb_nodes_per_element);
FEEngine::filterElementalData(mesh,
- mesh.getConnectivity(type, ghost_type),
- *filtered_connectivity,
- type, ghost_type,
- filter_elements);
+ mesh.getConnectivity(type, ghost_type),
+ *filtered_connectivity,
+ type, ghost_type,
+ filter_elements);
const Array<UInt> & cfiltered = *filtered_connectivity; // \todo temporary patch
conn_it = cfiltered.begin(nb_nodes_per_element);
} else {
nb_element = mesh.getNbElement(type, ghost_type);
conn_it = mesh.getConnectivity(type, ghost_type).begin(nb_nodes_per_element);
}
AKANTU_DEBUG_ASSERT(elementary_vect.getSize() == nb_element,
- "The vector elementary_vect(" << elementary_vect.getID()
- << ") has not the good size.");
+ "The vector elementary_vect(" << elementary_vect.getID()
+ << ") has not the good size.");
AKANTU_DEBUG_ASSERT(elementary_vect.getNbComponent()
- == nb_degree_of_freedom*nb_nodes_per_element,
- "The vector elementary_vect(" << elementary_vect.getID()
- << ") has not the good number of component."
- << "(" << elementary_vect.getNbComponent()
- << " != " << nb_degree_of_freedom*nb_nodes_per_element << ")");
+ == nb_degree_of_freedom*nb_nodes_per_element,
+ "The vector elementary_vect(" << elementary_vect.getID()
+ << ") has not the good number of component."
+ << "(" << elementary_vect.getNbComponent()
+ << " != " << nb_degree_of_freedom*nb_nodes_per_element << ")");
AKANTU_DEBUG_ASSERT(nodal_values.getNbComponent() == nb_degree_of_freedom,
- "The vector nodal_values(" << nodal_values.getID()
- << ") has not the good number of component."
- << "(" << nodal_values.getNbComponent()
- << " != " << nb_degree_of_freedom << ")");
+ "The vector nodal_values(" << nodal_values.getID()
+ << ") has not the good number of component."
+ << "(" << nodal_values.getNbComponent()
+ << " != " << nb_degree_of_freedom << ")");
nodal_values.resize(mesh.getNbNodes());
Real * nodal_it = nodal_values.storage();
Array<Real>::const_matrix_iterator elem_it = elementary_vect.begin(nb_degree_of_freedom,
- nb_nodes_per_element);
+ nb_nodes_per_element);
for (UInt el = 0; el < nb_element; ++el, ++elem_it, ++conn_it) {
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = (*conn_it)(n);
UInt offset_node = node * nb_degree_of_freedom;
const Vector<Real> & elem_data = (*elem_it)(n);
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
nodal_it[equation_number(offset_node + d)]
+= scale_factor * elem_data(d);
}
}
}
delete filtered_connectivity;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FEEngine::assembleMatrix(const Array<Real> & elementary_mat,
- SparseMatrix & matrix,
- UInt nb_degree_of_freedom,
- const ElementType & type,
- const GhostType & ghost_type,
- const Array<UInt> & filter_elements) const {
+ SparseMatrix & matrix,
+ UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt nb_element;
if(ghost_type == _not_ghost) {
nb_element = mesh.getNbElement(type);
} else {
AKANTU_DEBUG_TO_IMPLEMENT();
}
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
}
AKANTU_DEBUG_ASSERT(elementary_mat.getSize() == nb_element,
- "The vector elementary_mat(" << elementary_mat.getID()
- << ") has not the good size.");
+ "The vector elementary_mat(" << elementary_mat.getID()
+ << ") has not the good size.");
AKANTU_DEBUG_ASSERT(elementary_mat.getNbComponent()
- == nb_degree_of_freedom * nb_nodes_per_element * nb_degree_of_freedom * nb_nodes_per_element,
- "The vector elementary_mat(" << elementary_mat.getID()
- << ") has not the good number of component.");
+ == nb_degree_of_freedom * nb_nodes_per_element * nb_degree_of_freedom * nb_nodes_per_element,
+ "The vector elementary_mat(" << elementary_mat.getID()
+ << ") has not the good number of component.");
+
+ UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
+ UInt size = mesh.getNbGlobalNodes() * nb_degree_of_freedom;
Real * elementary_mat_val = elementary_mat.storage();
UInt offset_elementary_mat = elementary_mat.getNbComponent();
+ Array<Real>::const_matrix_iterator el_mat_it = elementary_mat.begin(size_mat,size_mat);
UInt * connectivity_val = mesh.getConnectivity(type, ghost_type).storage();
- UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
- UInt size = mesh.getNbGlobalNodes() * nb_degree_of_freedom;
-
Int * eq_nb_val = matrix.getDOFSynchronizer().getGlobalDOFEquationNumbers().storage();
Int * local_eq_nb_val = new Int[size_mat];
- for (UInt e = 0; e < nb_element; ++e) {
+ for (UInt e = 0; e < nb_element; ++e, ++el_mat_it) {
UInt el = e;
if(filter_elements != empty_filter) el = filter_elements(e);
+ const Matrix<Real> & el_mat = *el_mat_it;
+
Int * tmp_local_eq_nb_val = local_eq_nb_val;
UInt * conn_val = connectivity_val + el * nb_nodes_per_element;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
UInt n = conn_val[i];
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
*tmp_local_eq_nb_val++ = eq_nb_val[n * nb_degree_of_freedom + d];
}
// memcpy(tmp_local_eq_nb_val, eq_nb_val + n * nb_degree_of_freedom, nb_degree_of_freedom * sizeof(Int));
// tmp_local_eq_nb_val += nb_degree_of_freedom;
}
- for (UInt i = 0; i < size_mat; ++i) {
- UInt c_irn = local_eq_nb_val[i];
- if(c_irn < size) {
- UInt j_start = (matrix.getSparseMatrixType() == _symmetric) ? i : 0;
- for (UInt j = j_start; j < size_mat; ++j) {
- UInt c_jcn = local_eq_nb_val[j];
- if(c_jcn < size) {
- matrix(c_irn, c_jcn) += elementary_mat_val[j * size_mat + i];
+ /// The matrix assembling for cohesive elements with degenerated nodes
+ /// (i.e. elements in correspondence of the crack tips) has to be done
+ /// without considering symmetry
+
+
+#if defined(AKANTU_COHESIVE_ELEMENT)
+ if (mesh.getKind(type) == _ek_cohesive){
+
+ /// matrix assembling procedure for cohesive elements
+ for (UInt i = 0; i < size_mat; ++i) {
+ UInt c_irn = local_eq_nb_val[i];
+ if(c_irn < size) {
+ for (UInt j = 0; j < size_mat; ++j) {
+ UInt c_jcn = local_eq_nb_val[j];
+ if(c_jcn < size) {
+ if (matrix.getSparseMatrixType() == _symmetric){
+ if (c_jcn >= c_irn){
+ matrix(c_irn, c_jcn) += el_mat(i, j);
+ }
+ }else{
+ matrix(c_irn, c_jcn) += el_mat(i, j);
+ }
+ }
+ }
+ }
+ }
+ elementary_mat_val += offset_elementary_mat;
+
+ }else{
+#endif
+ /// matrix assembling procedure for all the elements except cohesive ones
+ for (UInt i = 0; i < size_mat; ++i) {
+ UInt c_irn = local_eq_nb_val[i];
+ if(c_irn < size) {
+ UInt j_start = (matrix.getSparseMatrixType() == _symmetric) ? i : 0;
+ for (UInt j = j_start; j < size_mat; ++j) {
+ UInt c_jcn = local_eq_nb_val[j];
+ if(c_jcn < size) {
+ matrix(c_irn, c_jcn) += el_mat(i, j);
+ }
}
}
}
+ elementary_mat_val += offset_elementary_mat;
}
- elementary_mat_val += offset_elementary_mat;
+#if defined(AKANTU_COHESIVE_ELEMENT)
}
+#endif
delete [] local_eq_nb_val;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void FEEngine::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "FEEngine [" << std::endl;
stream << space << " + id : " << id << std::endl;
stream << space << " + element dimension : " << element_dimension << std::endl;
stream << space << " + mesh [" << std::endl;
mesh.printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/fe_engine/fe_engine.hh b/src/fe_engine/fe_engine.hh
index 3ded5a8a2..aeb6e5c4f 100644
--- a/src/fe_engine/fe_engine.hh
+++ b/src/fe_engine/fe_engine.hh
@@ -1,395 +1,403 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_FE_ENGINE_HH__
#define __AKANTU_FE_ENGINE_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_memory.hh"
#include "mesh.hh"
#include "element_class.hh"
#include "sparse_matrix.hh"
-
+#include "integration_point.hh"
/* -------------------------------------------------------------------------- */
-namespace akantu {
- class Integrator;
- class ShapeFunctions;
-}
-
__BEGIN_AKANTU__
-
-class QuadraturePoint : public Element {
-public:
- typedef Vector<Real> position_type;
-public:
- 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);
- };
-
- 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);
- }
-
- /// 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 << "]";
- }
-
-public:
- UInt num_point;
- UInt global_num;
-private:
- position_type position;
-};
+/* -------------------------------------------------------------------------- */
+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:
- /// build the profile of the sparse matrix corresponding to the mesh
- void initSparseMatrixProfile(SparseMatrixType sparse_matrix_type = _unsymmetric);
-
/// 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 */
/* ------------------------------------------------------------------------ */
- /// get the number of quadrature points
- virtual UInt getNbQuadraturePoints(const ElementType & type,
- const GhostType & ghost_type = _not_ghost) const = 0;
+#ifndef SWIG
+ /// get the number of integration points
+ virtual UInt getNbIntegrationPoints(const ElementType & type,
+ const GhostType & ghost_type = _not_ghost) const = 0;
/// get the precomputed shapes
const virtual Array<Real> & getShapes(const ElementType & type,
const GhostType & ghost_type = _not_ghost,
UInt id = 0) const = 0;
/// get the derivatives of shapes
const virtual Array<Real> & getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type = _not_ghost,
UInt id = 0) const = 0;
- /// get 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 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 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 computeIntegrationPointsCoordinates(ElementTypeMapArray<Real> & integration_points_coordinates,
+ const ElementTypeMapArray<UInt> * filter_elements = NULL) const = 0;
+ /// Compute the interpolation point position in the global coordinates for an element type
+ virtual
+ void computeIntegrationPointsCoordinates(Array<Real> & integration_points_coordinates,
+ const ElementType & type,
+ const GhostType & ghost_type = _not_ghost,
+ const Array<UInt> & filter_elements = empty_filter) const = 0;
+
+ /// Build pre-computed matrices for interpolation of field form integration points at other given positions (interpolation_points)
virtual
- void 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 initElementalFieldInterpolationFromIntegrationPoints(const ElementTypeMapArray<Real> & interpolation_points_coordinates,
+ ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
+ ElementTypeMapArray<Real> & integration_points_coordinates_inv_matrices,
+ const ElementTypeMapArray<UInt> * element_filter) const = 0;
+ /// interpolate field at given position (interpolation_points) from given values of this field at integration points (field)
+ virtual
+ void interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates,
+ ElementTypeMapArray<Real> & result,
+ const GhostType ghost_type,
+ const ElementTypeMapArray<UInt> * element_filter) const = 0;
+
+ /// Interpolate field at given position from given values of this field at integration points (field)
+ /// using matrices precomputed with initElementalFieldInterplationFromIntegrationPoints
virtual
- void interpolateOnQuadraturePoints(const Array<Real> & u,
- ElementTypeMapArray<Real> & uq,
- const ElementTypeMapArray<UInt> * filter_elements = NULL) const = 0;
+ 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
+ /// assemble vectors at nodes from elementary vectors
void assembleArray(const Array<Real> & elementary_vect,
Array<Real> & nodal_values,
const Array<Int> & equation_number,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter,
Real scale_factor = 1) const;
/// assemble matrix in the complete sparse matrix
void assembleMatrix(const Array<Real> & elementary_mat,
SparseMatrix & matrix,
UInt nb_degree_of_freedom,
const ElementType & type,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// assemble a field as a lumped matrix (ex. rho in lumped mass)
virtual void assembleFieldLumped(__attribute__ ((unused)) const Array<Real> & field_1,
__attribute__ ((unused)) UInt nb_degree_of_freedom,
__attribute__ ((unused)) Array<Real> & lumped,
__attribute__ ((unused)) const Array<Int> & equation_number,
__attribute__ ((unused)) ElementType type,
__attribute__ ((unused)) const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
};
/// assemble a field as a matrix (ex. rho to mass matrix)
virtual void assembleFieldMatrix(__attribute__ ((unused)) const Array<Real> & field_1,
__attribute__ ((unused)) UInt nb_degree_of_freedom,
__attribute__ ((unused)) SparseMatrix & matrix,
__attribute__ ((unused)) ElementType type,
__attribute__ ((unused)) const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
#ifdef AKANTU_STRUCTURAL_MECHANICS
+ /// assemble a field as a matrix for structural elements (ex. rho to mass matrix)
virtual void assembleFieldMatrix(__attribute__ ((unused)) const Array<Real> & field_1,
__attribute__ ((unused)) UInt nb_degree_of_freedom,
__attribute__ ((unused)) SparseMatrix & M,
__attribute__ ((unused)) Array<Real> * n,
__attribute__ ((unused)) ElementTypeMapArray<Real> & rotation_mat,
__attribute__ ((unused)) ElementType type,
__attribute__ ((unused)) const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
-
+ /// compute shapes function in a matrix for structural elements
virtual void computeShapesMatrix(__attribute__ ((unused))const ElementType & type,
__attribute__ ((unused))UInt nb_degree_of_freedom,
__attribute__ ((unused))UInt nb_nodes_per_element,
__attribute__ ((unused))Array<Real> * n,
__attribute__ ((unused))UInt id,
__attribute__ ((unused))UInt degree_to_interpolate,
__attribute__ ((unused))UInt degree_interpolated,
__attribute__ ((unused))const bool sign,
__attribute__ ((unused))const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
#endif
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
private:
/// initialise the class
void init();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get the dimension of the element handeled by this fe_engine object
AKANTU_GET_MACRO(ElementDimension, element_dimension, UInt);
/// get the mesh contained in the fem object
AKANTU_GET_MACRO(Mesh, mesh, const Mesh &);
/// get the mesh contained in the fem object
AKANTU_GET_MACRO_NOT_CONST(Mesh, mesh, Mesh &);
/// get the in-radius of an element
static inline Real getElementInradius(const Matrix<Real> & coord, const ElementType & type);
- /// get the normals on 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 8222dcc1f..8d86b1780 100644
--- a/src/fe_engine/fe_engine_inline_impl.cc
+++ b/src/fe_engine/fe_engine_inline_impl.cc
@@ -1,177 +1,194 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 4bf6c4890..16cec8a11 100644
--- a/src/fe_engine/fe_engine_template.hh
+++ b/src/fe_engine/fe_engine_template.hh
@@ -1,304 +1,365 @@
/**
* @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 last modification: Mon Oct 19 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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __AKANTU_FE_ENGINE_TEMPLATE_HH__
#define __AKANTU_FE_ENGINE_TEMPLATE_HH__
/* -------------------------------------------------------------------------- */
#include "fe_engine.hh"
#include "integrator.hh"
#include "shape_functions.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
-template<ElementKind k> 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 * w_q @f$)
- 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;
+ /// integrate partially around an integration point (@f$ intf_q = f_q * J_q * w_q @f$)
+ void integrateOnIntegrationPoints(const Array<Real> & f,
+ Array<Real> &intf,
+ UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type = _not_ghost,
+ const Array<UInt> & filter_elements = empty_filter) const;
+ /// interpolate on a phyiscal point inside an element
+ void interpolate(const Vector<Real> & real_coords,
+ const Matrix<Real> & nodal_values,
+ Vector<Real> & interpolated,
+ const Element & element) const;
- /// get the number of 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
- const inline Matrix<Real> & getQuadraturePoints(const ElementType & type,
- const GhostType & ghost_type = _not_ghost) const;
+ /// get integration points
+ const inline Matrix<Real> & getIntegrationPoints(const ElementType & type,
+ const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Shape method bridges */
/* ------------------------------------------------------------------------ */
- /// compute the gradient of a nodal field on the quadrature points
- 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;
-
- /// interpolate a nodal field on the quadrature points
- 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;
-
- /// interpolate a nodal field on the quadrature points given a by_element_type
- void interpolateOnQuadraturePoints(const Array<Real> & u,
- ElementTypeMapArray<Real> & uq,
- const ElementTypeMapArray<UInt> * filter_elements = NULL) const;
+ /// compute the gradient of a nodal field on the integration points
+ void gradientOnIntegrationPoints(const Array<Real> &u,
+ Array<Real> &nablauq,
+ const UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type = _not_ghost,
+ const Array<UInt> & filter_elements = empty_filter) const;
+ /// interpolate a nodal field on the integration points
+ void interpolateOnIntegrationPoints(const Array<Real> &u,
+ Array<Real> &uq,
+ UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type = _not_ghost,
+ const Array<UInt> & filter_elements = empty_filter) const;
+
+ /// interpolate a nodal field on the integration points given a by_element_type
+ void interpolateOnIntegrationPoints(const Array<Real> & u,
+ ElementTypeMapArray<Real> & uq,
+ const ElementTypeMapArray<UInt> * filter_elements = NULL) const;
+
+ /// compute the position of integration points given by an element_type_map from nodes position
+ inline void computeIntegrationPointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates,
+ const ElementTypeMapArray<UInt> * filter_elements = NULL) const;
+
+ /// compute the position of integration points from nodes position
+ inline void computeIntegrationPointsCoordinates(Array<Real> & quadrature_points_coordinates,
+ const ElementType & type,
+ const GhostType & ghost_type = _not_ghost,
+ const Array<UInt> & filter_elements = empty_filter) const;
+
+ /// interpolate field at given position (interpolation_points) from given values of this field at integration points (field)
+ inline void interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates,
+ ElementTypeMapArray<Real> & result,
+ const GhostType ghost_type,
+ const ElementTypeMapArray<UInt> * element_filter) const;
+
+ /// Interpolate field at given position from given values of this field at integration points (field)
+ /// using matrices precomputed with initElementalFieldInterplationFromIntegrationPoints
+ inline void interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
+ const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
+ ElementTypeMapArray<Real> & result,
+ const GhostType ghost_type,
+ const ElementTypeMapArray<UInt> * element_filter) const;
+
+ /// Build pre-computed matrices for interpolation of field form integration points at other given positions (interpolation_points)
+ inline void initElementalFieldInterpolationFromIntegrationPoints(const ElementTypeMapArray<Real> & interpolation_points_coordinates,
+ ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
+ ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
+ const ElementTypeMapArray<UInt> * element_filter = NULL) const;
+
/// find natural coords from real coords provided an element
void inverseMap(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
Vector<Real> & natural_coords,
const GhostType & ghost_type = _not_ghost) const;
/// return true if the coordinates provided are inside the element, false otherwise
inline bool contains(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
/// compute the shape on a provided point
inline void computeShapes(const Vector<Real> & real_coords,
UInt element,
const ElementType & type,
Vector<Real> & shapes,
const GhostType & ghost_type = _not_ghost) const;
+ /// compute the shape derivatives on a provided point
+ inline void computeShapeDerivatives(const Vector<Real> & real__coords,
+ UInt element,
+ const ElementType & type,
+ Matrix<Real> & shape_derivatives,
+ const GhostType & ghost_type = _not_ghost) const;
+
/* ------------------------------------------------------------------------ */
/* Other methods */
/* ------------------------------------------------------------------------ */
- /// pre-compute normals on control points
- void computeNormalsOnControlPoints(const GhostType & ghost_type = _not_ghost);
- void computeNormalsOnControlPoints(const Array<Real> & field,
- const GhostType & ghost_type = _not_ghost);
- void computeNormalsOnControlPoints(const Array<Real> & field,
- Array<Real> & normal,
- const ElementType & type,
- const GhostType & ghost_type = _not_ghost) const;
+ /// 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{};
+ virtual void printself(std::ostream & stream, int indent = 0) const;
+ /// assemble a field as a lumped matrix (ex. rho in lumped mass)
void assembleFieldLumped(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
ElementType type,
const GhostType & ghost_type = _not_ghost) const;
+ /// assemble a field as a matrix (ex. rho to mass matrix)
void assembleFieldMatrix(const Array<Real> & field,
UInt nb_degree_of_freedom,
SparseMatrix & matrix,
ElementType type,
const GhostType & ghost_type = _not_ghost) const;
#ifdef AKANTU_STRUCTURAL_MECHANICS
+ /// assemble a field as a matrix (ex. rho to mass matrix)
void assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const ElementType & type,
const GhostType & ghost_type = _not_ghost) const;
+ /// compute shapes function in a matrix for structural elements
void computeShapesMatrix(const ElementType & type,
UInt nb_degree_of_freedom,
UInt nb_nodes_per_element,
Array<Real> * n,
UInt id,
UInt degree_to_interpolate,
UInt degree_interpolated,
const bool sign,
const GhostType & ghost_type = _not_ghost) const;
#endif
private:
- friend 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_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const;
/// @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV = \int \rho \varphi_i dV @f$
template <ElementType type>
void assembleLumpedRowSum(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const;
/// @f$ \tilde{M}_{i} = c * M_{ii} = \int_{V_e} \rho dV @f$
template <ElementType type>
void assembleLumpedDiagonalScaling(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
Array<Real> & lumped,
const Array<Int> & equation_number,
const GhostType & ghost_type) const;
+ /// assemble a field as a matrix (ex. rho to mass matrix)
template <ElementType type>
void assembleFieldMatrix(const Array<Real> & field,
UInt nb_degree_of_freedom,
SparseMatrix & matrix,
const GhostType & ghost_type) const;
#ifdef AKANTU_STRUCTURAL_MECHANICS
+ /// assemble a field as a matrix for structural elements (ex. rho to mass matrix)
template <ElementType type>
void assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const GhostType & ghost_type) const;
#endif
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
-
+ /// get the shape class (probably useless: see getShapeFunction)
const ShapeFunctions & getShapeFunctionsInterface() const { return shape_functions; };
+ /// get the shape class
const Shape & getShapeFunctions() const { return shape_functions; };
+ /// get the integrator class (probably useless: see getIntegrator)
const Integrator & getIntegratorInterface() const { return integrator; };
+ /// get the integrator class
const Integ & getIntegrator() const { return integrator; };
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
Integ integrator;
Shape shape_functions;
};
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "fe_engine_template_tmpl.hh"
-#if defined(AKANTU_STRUCTURAL_MECHANICS)
/* -------------------------------------------------------------------------- */
/* Shape Linked specialization */
/* -------------------------------------------------------------------------- */
-#include "fe_engine_template_tmpl_struct.hh"
+#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..17515c487 100644
--- a/src/fe_engine/fe_engine_template_cohesive.cc
+++ b/src/fe_engine/fe_engine_template_cohesive.cc
@@ -1,173 +1,173 @@
/**
* @file fe_engine_template_cohesive.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Oct 31 2012
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 9c492076a..c923e9c34 100644
--- a/src/fe_engine/fe_engine_template_tmpl.hh
+++ b/src/fe_engine/fe_engine_template_tmpl.hh
@@ -1,1445 +1,1726 @@
/**
* @file fe_engine_template_tmpl.hh
*
* @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Nov 05 2012
* @date last modification: Mon Jul 07 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
+/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ template <ElementKind> class S,
+ ElementKind kind>
FEEngineTemplate<I, S, kind>::FEEngineTemplate(Mesh & mesh, UInt spatial_dimension,
- ID id, MemoryID memory_id) :
+ 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>
+ 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 {
+struct GradientOnIntegrationPointsHelper {
template <class S>
- static void call(const S & shape_functions,
- Mesh & mesh,
- const Array<Real> & u,
- Array<Real> & nablauq,
- const UInt nb_degree_of_freedom,
- const ElementType & type,
- const GhostType & ghost_type,
- const Array<UInt> & filter_elements) {
+ static void call(const S & shape_functions,
+ Mesh & mesh,
+ const Array<Real> & u,
+ Array<Real> & nablauq,
+ const UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define COMPUTE_GRADIENT(type) \
if (element_dimension == ElementClass<type>::getSpatialDimension()) \
- shape_functions.template gradientOnControlPoints<type>(u, \
- nablauq, \
- nb_degree_of_freedom, \
- ghost_type, \
- filter_elements);
+ shape_functions.template gradientOnIntegrationPoints<type>(u, \
+ nablauq, \
+ nb_degree_of_freedom, \
+ ghost_type, \
+ filter_elements);
-#define AKANTU_SPECIALIZE_GRADIENT_ON_QUADRATURE_POINTS_HELPER(kind) \
+#define AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER(kind) \
template<> \
- struct GradientOnQuadraturePointsHelper<kind> { \
+ 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) { \
+ Mesh & mesh, \
+ const Array<Real> & u, \
+ Array<Real> & nablauq, \
+ const UInt nb_degree_of_freedom, \
+ const ElementType & type, \
+ const GhostType & ghost_type, \
+ const Array<UInt> & filter_elements) { \
UInt element_dimension = mesh.getSpatialDimension(type); \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_GRADIENT, kind); \
} \
};
-#define INTEREST_LIST AKANTU_GENERATE_KIND_LIST(AKANTU_REGULAR_KIND AKANTU_COHESIVE_KIND AKANTU_IGFEM_KIND)
+AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER, \
+ AKANTU_FE_ENGINE_LIST_GRADIENT_ON_INTEGRATION_POINTS)
-AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_GRADIENT_ON_QUADRATURE_POINTS_HELPER, \
- INTEREST_LIST)
-
-#undef AKANTU_SPECIALIZE_GRADIENT_ON_QUADRATURE_POINTS_HELPER
+#undef AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER
#undef COMPUTE_GRADIENT
-#undef INTEREST_LIST
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
-void FEEngineTemplate<I, S, kind>::gradientOnQuadraturePoints(const Array<Real> &u,
- Array<Real> &nablauq,
- const UInt nb_degree_of_freedom,
- const ElementType & type,
- const GhostType & ghost_type,
- const Array<UInt> & filter_elements) const {
+ template <ElementKind> class S,
+ ElementKind kind>
+void FEEngineTemplate<I, S, kind>::gradientOnIntegrationPoints(const Array<Real> &u,
+ Array<Real> &nablauq,
+ const UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements != empty_filter) nb_element = filter_elements.getSize();
- UInt nb_points = shape_functions.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.");
+ "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.");
+ "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.");
+ == 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.");
+ // "The vector nablauq(" << nablauq.getID()
+ // << ") has not the good size.");
#endif
nablauq.resize(nb_element * nb_points);
- GradientOnQuadraturePointsHelper<kind>::call(shape_functions,
- mesh,
- u,
- nablauq,
- nb_degree_of_freedom,
- type,
- ghost_type,
- filter_elements);
+ GradientOnIntegrationPointsHelper<kind>::call(shape_functions,
+ mesh,
+ u,
+ nablauq,
+ nb_degree_of_freedom,
+ type,
+ ghost_type,
+ filter_elements);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ template <ElementKind> class S,
+ ElementKind kind>
void FEEngineTemplate<I, S, kind>::initShapeFunctions(const GhostType & ghost_type) {
initShapeFunctions(mesh.getNodes(), ghost_type);
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ template <ElementKind> class S,
+ ElementKind kind>
void FEEngineTemplate<I, S, kind>::initShapeFunctions(const Array<Real> & nodes,
- const GhostType & ghost_type) {
+ 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);
+ 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); \
+ 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) { \
+ 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>
+ 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{
+ 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 << ").");
+ "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.");
+ "The vector f(" << f.getID()
+ << ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
- "The vector intf(" << intf.getID()
- << ") has not the good number of component.");
+ "The vector intf(" << intf.getID()
+ << ") has not the good number of component.");
#endif
intf.resize(nb_element);
IntegrateHelper<kind>::call(integrator,
- f,
- intf,
- nb_degree_of_freedom,
- type,
- ghost_type,
- filter_elements);
+ 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);
+ 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) { \
+ 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>
+ 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{
+ const ElementType & type,
+ const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) const{
AKANTU_DEBUG_IN();
#ifndef AKANTU_NDEBUG
// std::stringstream sstr; sstr << ghost_type;
// AKANTU_DEBUG_ASSERT(sstr.str() == nablauq.getTag(),
- // "The vector " << nablauq.getID() << " is not taged " << ghost_type);
+ // "The vector " << nablauq.getID() << " is not taged " << ghost_type);
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements != empty_filter) nb_element = filter_elements.getSize();
- 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 << ")");
+ "The vector f(" << f.getID()
+ << ") has not the good size. (" << f.getSize() << "!=" << nb_quadrature_points * nb_element << ")");
AKANTU_DEBUG_ASSERT(f.getNbComponent() == 1,
- "The vector f(" << f.getID()
- << ") has not the good number of component.");
+ "The vector f(" << f.getID()
+ << ") has not the good number of component.");
#endif
Real integral = IntegrateScalarHelper<kind>::call(integrator, f, type, ghost_type, filter_elements);
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);
+ 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) { \
+ 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>
+ 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{
+ 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 { };
+struct IntegrateOnIntegrationPointsHelper { };
#define INTEGRATE(type) \
integrator.template integrateOnQuadraturePoints<type>(f, intf, nb_degree_of_freedom, \
- ghost_type, filter_elements);
+ ghost_type, filter_elements);
-#define AKANTU_SPECIALIZE_INTEGRATE_ON_QUADRATURE_POINTS_HELPER(kind) \
+#define AKANTU_SPECIALIZE_INTEGRATE_ON_INTEGRATION_POINTS_HELPER(kind) \
template<> \
- struct IntegrateOnQuadraturePointsHelper<kind> { \
+ 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) { \
+ 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(const Array<Real> & f,
- Array<Real> &intf,
- UInt nb_degree_of_freedom,
- const ElementType & type,
- const GhostType & ghost_type,
- const Array<UInt> & filter_elements) const{
+ template <ElementKind> class S,
+ ElementKind kind>
+void FEEngineTemplate<I, S, kind>::integrateOnIntegrationPoints(const Array<Real> & f,
+ Array<Real> &intf,
+ UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) const{
UInt nb_element = mesh.getNbElement(type, ghost_type);
if(filter_elements != empty_filter) nb_element = filter_elements.getSize();
- UInt nb_quadrature_points = 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);
+ // "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 << ").");
+ "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.");
+ "The vector f(" << f.getID()
+ << ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(intf.getNbComponent() == nb_degree_of_freedom,
- "The vector intf(" << intf.getID()
- << ") has not the good number of component.");
+ "The vector intf(" << intf.getID()
+ << ") has not the good number of component.");
#endif
intf.resize(nb_element*nb_quadrature_points);
- 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 {
+struct InterpolateOnIntegrationPointsHelper {
template <class S>
static void call(const S & shape_functions,
- const Array<Real> &u,
- Array<Real> &uq,
- const UInt nb_degree_of_freedom,
- const ElementType & type,
- const GhostType & ghost_type,
- const Array<UInt> & filter_elements) {
+ const Array<Real> &u,
+ Array<Real> &uq,
+ const UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define INTERPOLATE(type) \
- shape_functions.template interpolateOnControlPoints<type>(u, \
- uq, \
- nb_degree_of_freedom, \
- ghost_type, \
- filter_elements);
+ shape_functions.template interpolateOnIntegrationPoints<type>(u, \
+ uq, \
+ nb_degree_of_freedom, \
+ ghost_type, \
+ filter_elements);
-#define AKANTU_SPECIALIZE_INTERPOLATE_ON_QUADRATURE_POINTS_HELPER(kind) \
+#define AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER(kind) \
template<> \
- struct InterpolateOnQuadraturePointsHelper<kind> { \
+ 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) { \
+ const Array<Real> & u, \
+ Array<Real> & uq, \
+ const UInt nb_degree_of_freedom, \
+ const ElementType & type, \
+ const GhostType & ghost_type, \
+ const Array<UInt> & filter_elements) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTERPOLATE, kind); \
} \
};
-#define INTEREST_LIST AKANTU_GENERATE_KIND_LIST(AKANTU_REGULAR_KIND AKANTU_COHESIVE_KIND AKANTU_IGFEM_KIND)
+AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER, \
+ AKANTU_FE_ENGINE_LIST_INTERPOLATE_ON_INTEGRATION_POINTS)
-AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INTERPOLATE_ON_QUADRATURE_POINTS_HELPER, \
- INTEREST_LIST)
-
-#undef AKANTU_SPECIALIZE_INTERPOLATE_ON_QUADRATURE_POINTS_HELPER
+#undef AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER
#undef INTERPOLATE
-#undef INTEREST_LIST
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
-void FEEngineTemplate<I, S, kind>::interpolateOnQuadraturePoints(const Array<Real> &u,
- Array<Real> &uq,
- const UInt nb_degree_of_freedom,
- const ElementType & type,
- const GhostType & ghost_type,
- const Array<UInt> & filter_elements) const {
+ template <ElementKind> class S,
+ ElementKind kind>
+void FEEngineTemplate<I, S, kind>::interpolateOnIntegrationPoints(const Array<Real> &u,
+ Array<Real> &uq,
+ const UInt nb_degree_of_freedom,
+ const ElementType & type,
+ const GhostType & ghost_type,
+ const Array<UInt> & filter_elements) const {
AKANTU_DEBUG_IN();
- UInt nb_points = shape_functions.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.");
+ "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.");
+ "The vector u(" << u.getID()
+ << ") has not the good number of component.");
AKANTU_DEBUG_ASSERT(uq.getNbComponent() == nb_degree_of_freedom,
- "The vector uq(" << uq.getID()
- << ") has not the good number of component.");
+ "The vector uq(" << uq.getID()
+ << ") has not the good number of component.");
#endif
uq.resize(nb_element * nb_points);
- 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(const Array<Real> & u,
- ElementTypeMapArray<Real> & uq,
- const ElementTypeMapArray<UInt> * filter_elements) const {
+ template <ElementKind> class S,
+ ElementKind kind>
+void FEEngineTemplate<I, S, kind>::interpolateOnIntegrationPoints(const Array<Real> & u,
+ ElementTypeMapArray<Real> & uq,
+ const ElementTypeMapArray<UInt> * filter_elements) const {
AKANTU_DEBUG_IN();
const Array<UInt> * filter = NULL;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
ElementTypeMapArray<Real>::type_iterator it = uq.firstType(_all_dimensions, ghost_type, kind);
ElementTypeMapArray<Real>::type_iterator last = uq.lastType(_all_dimensions, ghost_type, kind);
for (; it != last; ++it) {
ElementType type = *it;
- UInt nb_quad_per_element = 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();
+ filter = &((*filter_elements)(type, ghost_type));
+ nb_element = filter->getSize();
}
else {
- filter = &empty_filter;
- nb_element = mesh.getNbElement(type, ghost_type);
+ 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>
-void FEEngineTemplate<I, S, kind>::computeNormalsOnControlPoints(const GhostType & ghost_type) {
+ 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);
+}
- computeNormalsOnControlPoints(mesh.getNodes(),
- ghost_type);
+/* -------------------------------------------------------------------------- */
+template<template <ElementKind> class I,
+ template <ElementKind> class S,
+ ElementKind kind>
+inline void FEEngineTemplate<I, S, kind>::interpolateElementalFieldFromIntegrationPoints(const ElementTypeMapArray<Real> & field,
+ const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
+ const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
+ ElementTypeMapArray<Real> & result,
+ const GhostType ghost_type,
+ const ElementTypeMapArray<UInt> * element_filter) const {
+
+ shape_functions.interpolateElementalFieldFromIntegrationPoints(field,
+ interpolation_points_coordinates_matrices,
+ quad_points_coordinates_inv_matrices,
+ result,
+ ghost_type,
+ element_filter);
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Helper class to be able to write a partial specialization on the element kind
+ */
+template<ElementKind kind>
+struct InterpolateHelper {
+ template <class S>
+ static void call(const S & shape_functions,
+ const Vector<Real> & real_coords,
+ UInt elem,
+ const Matrix<Real> & nodal_values,
+ Vector<Real> & interpolated,
+ const ElementType & type,
+ const GhostType & ghost_type) {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ }
+};
+
+#define INTERPOLATE(type) \
+ shape_functions.template interpolate<type>(real_coords, \
+ element, \
+ nodal_values, \
+ interpolated, \
+ ghost_type);
+
+#define AKANTU_SPECIALIZE_INTERPOLATE_HELPER(kind) \
+ template<> \
+ struct InterpolateHelper<kind> { \
+ template <class S> \
+ static void call(const S & shape_functions, \
+ const Vector<Real> & real_coords, \
+ UInt element, \
+ const Matrix<Real> & nodal_values, \
+ Vector<Real> & interpolated, \
+ const ElementType & type, \
+ const GhostType & ghost_type) { \
+ AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTERPOLATE, kind); \
+ } \
+ };
+
+AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INTERPOLATE_HELPER, \
+ AKANTU_FE_ENGINE_LIST_INTERPOLATE)
+
+#undef AKANTU_SPECIALIZE_INTERPOLATE_HELPER
+#undef INTERPOLATE
+
+template<template <ElementKind> class I,
+ template <ElementKind> class S,
+ ElementKind kind>
+inline void FEEngineTemplate<I, S, kind>::interpolate(const Vector<Real> & real_coords,
+ const Matrix<Real> & nodal_values,
+ Vector<Real> & interpolated,
+ const Element & element) const{
+
+ AKANTU_DEBUG_IN();
+
+ InterpolateHelper<kind>::call(shape_functions, real_coords, element.element, nodal_values, interpolated, element.type, element.ghost_type);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<template <ElementKind> class I,
+ template <ElementKind> class S,
+ ElementKind kind>
+void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(const GhostType & ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ computeNormalsOnIntegrationPoints(mesh.getNodes(),
+ ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
-void FEEngineTemplate<I, S, kind>::computeNormalsOnControlPoints(const Array<Real> & field,
- const GhostType & ghost_type) {
+ template <ElementKind> class S,
+ ElementKind kind>
+void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(const Array<Real> & field,
+ const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
// Real * coord = mesh.getNodes().storage();
UInt spatial_dimension = mesh.getSpatialDimension();
//allocate the normal arrays
Mesh::type_iterator it = mesh.firstType(element_dimension, ghost_type, kind);
Mesh::type_iterator end = mesh.lastType(element_dimension, ghost_type, kind);
for(; it != end; ++it) {
ElementType type = *it;
UInt size = mesh.getNbElement(type, ghost_type);
- if(normals_on_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 {
+struct ComputeNormalsOnIntegrationPoints {
template <template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind k>
+ 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) {
+ const Array<Real> & field,
+ Array<Real> & normal,
+ const ElementType & type,
+ 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) \
+#define AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS(kind) \
template<> \
- struct ComputeNormalsOnControlPoints<kind> { \
+ struct ComputeNormalsOnIntegrationPoints<kind> { \
template <template <ElementKind> class I, \
- template <ElementKind> class S, \
- ElementKind k> \
+ 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); \
+ const Array<Real> & field, \
+ Array<Real> & normal, \
+ const ElementType & type, \
+ const GhostType & ghost_type) { \
+ AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_NORMALS_ON_INTEGRATION_POINTS, kind); \
} \
- };
-
-#define INTEREST_LIST AKANTU_GENERATE_KIND_LIST(AKANTU_REGULAR_KIND AKANTU_COHESIVE_KIND AKANTU_IGFEM_KIND)
+ };
-AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_CONTROL_POINTS, \
- INTEREST_LIST)
+AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS, \
+ AKANTU_FE_ENGINE_LIST_COMPUTE_NORMALS_ON_INTEGRATION_POINTS)
-#undef AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_CONTROL_POINTS
-#undef COMPUTE_NORMALS_ON_QUAD
-#undef INTEREST_LIST
+#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(const Array<Real> & field,
- Array<Real> & normal,
- const ElementType & type,
- const GhostType & ghost_type) const {
- ComputeNormalsOnControlPoints<kind>::call(*this,
- field,
- normal,
- type,
- ghost_type);
+ template <ElementKind> class S,
+ ElementKind kind>
+void FEEngineTemplate<I, S, kind>::computeNormalsOnIntegrationPoints(const Array<Real> & field,
+ Array<Real> & normal,
+ const ElementType & type,
+ const GhostType & ghost_type) const {
+ ComputeNormalsOnIntegrationPoints<kind>::call(*this,
+ field,
+ normal,
+ type,
+ ghost_type);
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ template <ElementKind> class S,
+ ElementKind kind>
template<ElementType type>
-void FEEngineTemplate<I, S, kind>::computeNormalsOnControlPoints(const Array<Real> & field,
- Array<Real> & normal,
- const GhostType & ghost_type) const {
+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);
+ 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);
+ *f_it,
+ *normals_on_quad);
++normals_on_quad;
++f_it;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* Matrix lumping functions */
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct AssembleLumpedTemplateHelper { };
#define ASSEMBLE_LUMPED(type) \
fem.template assembleLumpedTemplate<type>(field_1, nb_degree_of_freedom,lumped, equation_number,ghost_type)
#define AKANTU_SPECIALIZE_ASSEMBLE_HELPER(kind) \
template<> \
struct AssembleLumpedTemplateHelper<kind> { \
template <template <ElementKind> class I, \
- template <ElementKind> class S, \
- ElementKind k> \
+ 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) { \
+ 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>
+ template <ElementKind> class S,
+ ElementKind kind>
void FEEngineTemplate<I, S, kind>::assembleFieldLumped(const Array<Real> & field_1,
- UInt nb_degree_of_freedom,
- Array<Real> & lumped,
- const Array<Int> & equation_number,
- ElementType type,
- const GhostType & ghost_type) const {
+ UInt nb_degree_of_freedom,
+ Array<Real> & lumped,
+ const Array<Int> & equation_number,
+ ElementType type,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AssembleLumpedTemplateHelper<kind>::call(*this, field_1,
- nb_degree_of_freedom,
- lumped,
- equation_number,
- type,
- ghost_type);
+ nb_degree_of_freedom,
+ lumped,
+ equation_number,
+ type,
+ ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct AssembleFieldMatrixHelper { };
#define ASSEMBLE_MATRIX(type) \
fem.template assembleFieldMatrix<type>(field_1, nb_degree_of_freedom, \
- matrix, \
- ghost_type)
+ matrix, \
+ ghost_type)
#define AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER(kind) \
template<> \
struct AssembleFieldMatrixHelper<kind> { \
template <template <ElementKind> class I, \
- template <ElementKind> class S, \
- ElementKind k> \
+ template <ElementKind> class S, \
+ ElementKind k> \
static void call(const FEEngineTemplate<I, S, k> & fem, \
- const Array<Real> & field_1, \
- UInt nb_degree_of_freedom, \
- SparseMatrix & matrix, \
- ElementType type, \
- const GhostType & ghost_type) { \
+ const Array<Real> & field_1, \
+ UInt nb_degree_of_freedom, \
+ SparseMatrix & matrix, \
+ ElementType type, \
+ const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_MATRIX, kind); \
} \
- };
+ };
AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER)
#undef AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER
#undef ASSEMBLE_MATRIX
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ template <ElementKind> class S,
+ ElementKind kind>
void FEEngineTemplate<I, S, kind>::assembleFieldMatrix(const Array<Real> & field_1,
- UInt nb_degree_of_freedom,
- SparseMatrix & matrix,
- ElementType type,
- const GhostType & ghost_type) const {
+ UInt nb_degree_of_freedom,
+ SparseMatrix & matrix,
+ ElementType type,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AssembleFieldMatrixHelper<kind>::call(*this, field_1, nb_degree_of_freedom, matrix, type, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ template <ElementKind> class S,
+ ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleLumpedTemplate(const Array<Real> & field_1,
- UInt nb_degree_of_freedom,
- Array<Real> & lumped,
- const Array<Int> & equation_number,
- const GhostType & ghost_type) const {
+ UInt nb_degree_of_freedom,
+ Array<Real> & lumped,
+ const Array<Int> & equation_number,
+ const GhostType & ghost_type) const {
this->template assembleLumpedRowSum<type>(field_1, nb_degree_of_freedom,lumped, equation_number,ghost_type);
}
/* -------------------------------------------------------------------------- */
/**
* @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV = \int \rho \varphi_i dV @f$
*/
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ template <ElementKind> class S,
+ ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleLumpedRowSum(const Array<Real> & field_1,
- UInt nb_degree_of_freedom,
- Array<Real> & lumped,
- const Array<Int> & equation_number,
- const GhostType & ghost_type) const {
+ UInt nb_degree_of_freedom,
+ Array<Real> & lumped,
+ const Array<Int> & equation_number,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt shapes_size = ElementClass<type>::getShapeSize();
Array<Real> * field_times_shapes = new Array<Real>(0, shapes_size * nb_degree_of_freedom);
Array<Real> * field = new Array<Real>(field_1.getSize(), nb_degree_of_freedom);
Array<Real>::const_scalar_iterator f1_it = field_1.begin();
Array<Real>::const_scalar_iterator f1_end = field_1.end();
Array<Real>::vector_iterator f_it = field->begin(nb_degree_of_freedom);
for(;f1_it != f1_end; ++f1_it, ++f_it) {
f_it->set(*f1_it);
}
shape_functions.template fieldTimesShapes<type>(*field, *field_times_shapes, ghost_type);
delete field;
UInt nb_element = mesh.getNbElement(type, ghost_type);
Array<Real> * int_field_times_shapes = new Array<Real>(nb_element, shapes_size * nb_degree_of_freedom,
- "inte_rho_x_shapes");
+ "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);
+ nb_degree_of_freedom * shapes_size, ghost_type, empty_filter);
delete field_times_shapes;
assembleArray(*int_field_times_shapes, lumped, equation_number,nb_degree_of_freedom, type, ghost_type);
delete int_field_times_shapes;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* @f$ \tilde{M}_{i} = c * M_{ii} = \int_{V_e} \rho dV @f$
*/
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ template <ElementKind> class S,
+ ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleLumpedDiagonalScaling(const Array<Real> & field_1,
- UInt nb_degree_of_freedom,
- Array<Real> & lumped,
- const Array<Int> & equation_number,
- const GhostType & ghost_type) const {
+ UInt nb_degree_of_freedom,
+ Array<Real> & lumped,
+ const Array<Int> & equation_number,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
const ElementType & type_p1 = ElementClass<type>::getP1ElementType();
UInt nb_nodes_per_element_p1 = Mesh::getNbNodesPerElement(type_p1);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_quadrature_points = integrator.template getQuadraturePoints<type>(ghost_type).cols();
UInt nb_element = field_1.getSize() / nb_quadrature_points;
-
- Real corner_factor = 0;
- Real mid_factor = 0;
-
- if(type == _triangle_6) {
- corner_factor = 1./12.;
- mid_factor = 1./4.;
- }
-
- if (type == _tetrahedron_10) {
- corner_factor = 1./32.;
- mid_factor = 7./48.;
+ 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 == _quadrangle_8) {
- corner_factor = 1./36.;
- mid_factor = 8./36.;
+ if (type == _triangle_6 ) ASSIGN_WEIGHT_TO_NODES(1./12., 1./4.);
+ if (type == _tetrahedron_10) ASSIGN_WEIGHT_TO_NODES(1./32., 7./48.);
+ if (type == _quadrangle_8 ) ASSIGN_WEIGHT_TO_NODES(3./76., 16./76.); /** coeff. derived by scaling the diagonal terms of the corresponding
+ * consistent mass computed with 3x3 gauss points;
+ * coeff. are (1./36., 8./36.) for 2x2 gauss points */
+ if (type == _hexahedron_20 ) ASSIGN_WEIGHT_TO_NODES(7./248., 16./248.); /** coeff. derived by scaling the diagonal terms of the corresponding
+ * consistent mass computed with 3x3x3 gauss points;
+ * coeff. are (1./40., 1./15.) for 2x2x2 gauss points */
+ if (type == _pentahedron_15) {
+ // coefficients derived by scaling the diagonal terms of the corresponding consistent mass computed with 8 gauss points;
+ for (UInt n = 0; n < nb_nodes_per_element_p1; n++)
+ nodal_factor(n) = 51./2358.;
+
+ Real mid_triangle = 192./2358.;
+ Real mid_quadrangle = 300./2358.;
+
+ nodal_factor(6) = mid_triangle;
+ nodal_factor(7) = mid_triangle;
+ nodal_factor(8) = mid_triangle;
+ nodal_factor(9) = mid_quadrangle;
+ nodal_factor(10) = mid_quadrangle;
+ nodal_factor(11) = mid_quadrangle;
+ nodal_factor(12) = mid_triangle;
+ nodal_factor(13) = mid_triangle;
+ nodal_factor(14) = mid_triangle;
}
if (nb_element == 0) {
AKANTU_DEBUG_OUT();
return;
}
+#undef ASSIGN_WEIGHT_TO_NODES
+
/// compute @f$ \int \rho dV = \rho V @f$ for each element
Array<Real> * int_field_1 = new Array<Real>(field_1.getSize(), 1,
- "inte_rho_x_1");
+ "inte_rho_x_1");
integrator.template integrate<type>(field_1, *int_field_1, 1, ghost_type, empty_filter);
/// distribute the mass of the element to the nodes
Array<Real> * lumped_per_node = new Array<Real>(nb_element, nb_degree_of_freedom * nb_nodes_per_element, "mass_per_node");
Array<Real>::const_scalar_iterator int_field_1_it = int_field_1->begin();
Array<Real>::matrix_iterator lumped_per_node_it
= lumped_per_node->begin(nb_degree_of_freedom, nb_nodes_per_element);
for (UInt e = 0; e < nb_element; ++e) {
- Real lmass = *int_field_1_it * corner_factor;
- for (UInt n = 0; n < nb_nodes_per_element_p1; ++n) {
+ for (UInt n = 0; n < nb_nodes_per_element; ++n) {
+ Real lmass = *int_field_1_it * nodal_factor(n);
Vector<Real> l = (*lumped_per_node_it)(n);
- l.set(lmass); /// corner points
+ l.set(lmass);
}
-
- lmass = *int_field_1_it * mid_factor;
- for (UInt n = nb_nodes_per_element_p1; n < nb_nodes_per_element; ++n) {
- Vector<Real> l = (*lumped_per_node_it)(n);
- l.set(lmass); /// mid points
- }
-
++int_field_1_it;
++lumped_per_node_it;
}
delete int_field_1;
// lumped_per_node->extendComponentsInterlaced(nb_degree_of_freedom,1);
assembleArray(*lumped_per_node, lumped, equation_number, nb_degree_of_freedom, type, ghost_type);
delete lumped_per_node;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV = \int \rho \varphi_i dV @f$
*/
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ template <ElementKind> class S,
+ ElementKind kind>
template <ElementType type>
void FEEngineTemplate<I, S, kind>::assembleFieldMatrix(const Array<Real> & field_1,
- UInt nb_degree_of_freedom,
- SparseMatrix & matrix,
- const GhostType & ghost_type) const {
+ UInt nb_degree_of_freedom,
+ SparseMatrix & matrix,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt vect_size = field_1.getSize();
UInt shapes_size = ElementClass<type>::getShapeSize();
UInt lmat_size = nb_degree_of_freedom * shapes_size;
const Array<Real> & shapes = shape_functions.getShapes(type,ghost_type);
Array<Real> * modified_shapes = new Array<Real>(vect_size, lmat_size * nb_degree_of_freedom);
modified_shapes->clear();
Array<Real> * local_mat = new Array<Real>(vect_size, lmat_size * lmat_size);
- Array<Real>::matrix_iterator shape_vect = modified_shapes->begin(nb_degree_of_freedom, lmat_size);
- Real * sh = shapes.storage();
- for(UInt q = 0; q < vect_size; ++q) {
- Real * msh = shape_vect->storage();
+ 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) {
- Real * msh_tmp = msh + d * (lmat_size + 1);
for (UInt s = 0; s < shapes_size; ++s) {
- *msh_tmp = sh[s];
- msh_tmp += nb_degree_of_freedom;
+ (*mshapes_it)(s*nb_degree_of_freedom + d, d) = (*shapes_it)(s);
}
}
- ++shape_vect;
- sh += shapes_size;
}
- shape_vect = modified_shapes->begin(nb_degree_of_freedom, lmat_size);
+ mshapes_it = modified_shapes->begin(lmat_size, nb_degree_of_freedom);
Array<Real>::matrix_iterator lmat = local_mat->begin(lmat_size, lmat_size);
- Real * field_val = field_1.storage();
+ Array<Real>::const_scalar_iterator field_val = field_1.begin();
- for(UInt q = 0; q < vect_size; ++q) {
- (*lmat).mul<true, false>(*shape_vect, *shape_vect, *field_val);
- ++lmat; ++shape_vect; ++field_val;
+ for(UInt q = 0; q < vect_size; ++q, ++lmat, ++mshapes_it, ++field_val) {
+ (*lmat).mul<false, true>(*mshapes_it, *mshapes_it, *field_val);
}
delete modified_shapes;
UInt nb_element = mesh.getNbElement(type, ghost_type);
Array<Real> * int_field_times_shapes = new Array<Real>(nb_element, lmat_size * lmat_size,
- "inte_rho_x_shapes");
+ "inte_rho_x_shapes");
integrator.template integrate<type>(*local_mat, *int_field_times_shapes,
- lmat_size * lmat_size, ghost_type, empty_filter);
+ lmat_size * lmat_size, ghost_type, empty_filter);
delete local_mat;
assembleMatrix(*int_field_times_shapes, matrix, nb_degree_of_freedom, type, ghost_type);
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) {
+ const Vector<Real> & real_coords,
+ UInt element,
+ const ElementType & type,
+ Vector<Real> & natural_coords,
+ const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define INVERSE_MAP(type) \
shape_functions.template inverseMap<type>(real_coords, element, natural_coords, ghost_type); \
#define AKANTU_SPECIALIZE_INVERSE_MAP_HELPER(kind) \
template<> \
struct InverseMapHelper<kind> { \
template <class S> \
static void call(const S & shape_functions, \
- const Vector<Real> & real_coords, \
- UInt element, \
- const ElementType & type, \
- Vector<Real> & natural_coords, \
- const GhostType & ghost_type) { \
+ const Vector<Real> & real_coords, \
+ UInt element, \
+ const ElementType & type, \
+ Vector<Real> & natural_coords, \
+ const GhostType & ghost_type) { \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(INVERSE_MAP, kind); \
} \
};
-#define INTEREST_LIST AKANTU_GENERATE_KIND_LIST(AKANTU_REGULAR_KIND AKANTU_COHESIVE_KIND AKANTU_IGFEM_KIND)
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_INVERSE_MAP_HELPER, \
- INTEREST_LIST)
+ AKANTU_FE_ENGINE_LIST_INVERSE_MAP)
#undef AKANTU_SPECIALIZE_INVERSE_MAP_HELPER
#undef INVERSE_MAP
-#undef INTEREST_LIST
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ 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{
+ 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(const S & shape_functions,
+ const Vector<Real> & real_coords,
+ UInt element,
+ const ElementType & type,
+ const GhostType & ghost_type) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define CONTAINS(type) \
contain = shape_functions.template contains<type>(real_coords, element, ghost_type); \
#define AKANTU_SPECIALIZE_CONTAINS_HELPER(kind) \
template<> \
struct ContainsHelper<kind> { \
template <template <ElementKind> class S, \
- ElementKind k> \
+ ElementKind k> \
static bool call(const S<k> & shape_functions, \
- const Vector<Real> & real_coords, \
- UInt element, \
- const ElementType & type, \
- const GhostType & ghost_type) { \
+ const Vector<Real> & real_coords, \
+ UInt element, \
+ const ElementType & type, \
+ const GhostType & ghost_type) { \
bool contain = false; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(CONTAINS, kind); \
return contain; \
} \
- };
-#define INTEREST_LIST AKANTU_GENERATE_KIND_LIST(AKANTU_REGULAR_KIND AKANTU_COHESIVE_KIND AKANTU_IGFEM_KIND)
+ };
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_CONTAINS_HELPER, \
- INTEREST_LIST)
+ AKANTU_FE_ENGINE_LIST_CONTAINS)
#undef AKANTU_SPECIALIZE_CONTAINS_HELPER
#undef CONTAINS
-#undef INTEREST_LIST
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ 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{
+ 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 { };
+struct ComputeShapesHelper {
+ template <class S>
+ static void call(const S & shape_functions,
+ const Vector<Real> & real_coords,
+ UInt element,
+ const ElementType type,
+ Vector<Real> & shapes,
+ const GhostType & ghost_type) {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ }
+};
-#define COMPUTE_SHAPES(type) \
- shape_functions.template computeShapes<type>(real_coords,element,shapes,ghost_type); \
+#define 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) { \
+ 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(AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER)
+AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER, \
+ AKANTU_FE_ENGINE_LIST_COMPUTE_SHAPES)
-#undef AKANTU_SPECIALIZE_ASSEMBLE_COMPUTE_SHAPES_HELPER
+#undef AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER
#undef COMPUTE_SHAPES
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ 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{
+ 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 GetNbQuadraturePointsHelper { };
+struct ComputeShapeDerivativesHelper {
+ template <class S>
+ static void call(const S & shape_functions,
+ const Vector<Real> & real_coords,
+ UInt element,
+ const ElementType type,
+ Matrix<Real> & shape_derivatives,
+ const GhostType & ghost_type) {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ }
+};
+
+#define COMPUTE_SHAPE_DERIVATIVES(type) \
+ Matrix<Real> coords_mat(real_coords.storage(), shape_derivatives.rows(), 1); \
+ Tensor3<Real> shapesd_tensor(shape_derivatives.storage(), \
+ shape_derivatives.rows(), \
+ shape_derivatives.cols(), 1); \
+ shape_functions.template computeShapeDerivatives<type>(coords_mat, \
+ element, \
+ shapesd_tensor, \
+ ghost_type);
+
+#define AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER(kind) \
+ template<> \
+ struct ComputeShapeDerivativesHelper<kind> { \
+ template <class S> \
+ static void call(const S & shape_functions, \
+ const Vector<Real> & real_coords, \
+ UInt element, \
+ const ElementType type, \
+ Matrix<Real> & shape_derivatives, \
+ const GhostType & ghost_type) { \
+ AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_SHAPE_DERIVATIVES, kind); \
+ } \
+ };
+
+AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER, \
+ AKANTU_FE_ENGINE_LIST_COMPUTE_SHAPES_DERIVATIVES)
+
+#undef AKANTU_SPECIALIZE_COMPUTE_SHAPE_DERIVATIVES_HELPER
+#undef COMPUTE_SHAPE_DERIVATIVES
+
+template<template <ElementKind> class I,
+ template <ElementKind> class S,
+ ElementKind kind>
+inline void FEEngineTemplate<I, S, kind>::computeShapeDerivatives(const Vector<Real> & real_coords,
+ UInt element,
+ const ElementType & type,
+ Matrix<Real> & shape_derivatives,
+ const GhostType & ghost_type) const {
+ AKANTU_DEBUG_IN();
+
+ ComputeShapeDerivativesHelper<kind>::call(shape_functions, real_coords, element, type, shape_derivatives, ghost_type);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Helper class to be able to write a partial specialization on the element kind
+ */
+template<ElementKind kind>
+struct GetNbIntegrationPointsHelper { };
-#define GET_NB_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> { \
- 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); \
- return nb_quad_points; \
- } \
- };
+#define AKANTU_SPECIALIZE_GET_NB_INTEGRATION_POINTS_HELPER(kind) \
+ template<> \
+ struct GetNbIntegrationPointsHelper<kind> { \
+ template <template <ElementKind> class I, \
+ ElementKind k> \
+ static UInt call(const I<k> & integrator, \
+ const ElementType type, \
+ const GhostType & ghost_type) { \
+ UInt nb_quad_points = 0; \
+ AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_NB_INTEGRATION_POINTS, kind); \
+ return nb_quad_points; \
+ } \
+ };
-AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_GET_NB_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(const ElementType & type,
- const GhostType & ghost_type) const {
- return GetNbQuadraturePointsHelper<kind>::call(integrator, type, ghost_type);
+ template <ElementKind> class S,
+ ElementKind kind>
+inline UInt FEEngineTemplate<I, S, kind>::getNbIntegrationPoints(const ElementType & type,
+ const GhostType & ghost_type) const {
+return GetNbIntegrationPointsHelper<kind>::call(integrator, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
/**
* Helper class to be able to write a partial specialization on the element kind
*/
template<ElementKind kind>
struct GetShapesHelper { };
#define GET_SHAPES(type) \
ret = &(shape_functions.getShapes(type, ghost_type));
-#define AKANTU_SPECIALIZE_GET_SHAPES_HELPER(kind) \
- template<> \
- struct GetShapesHelper<kind> { \
- template <class S> \
- static const Array<Real> & call(const S& shape_functions, \
- const ElementType type, \
- const GhostType & ghost_type) { \
- const Array<Real> * ret = NULL; \
- AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_SHAPES, kind); \
- return *ret; \
- } \
+#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>
+ 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 {
+ 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>
+ ElementKind k>
static const Array<Real> & call(const S<k> & shape_functions,
- const ElementType & type,
- const GhostType & ghost_type,
- UInt id) {
+ const ElementType & type,
+ const GhostType & ghost_type,
+ UInt id) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
};
#define GET_SHAPES_DERIVATIVES(type) \
ret = &(shape_functions.getShapesDerivatives(type, ghost_type));
#define AKANTU_SPECIALIZE_GET_SHAPES_DERIVATIVES_HELPER(kind) \
template<> \
struct GetShapesDerivativesHelper<kind> { \
template <template <ElementKind> class S, \
- ElementKind k> \
+ ElementKind k> \
static const Array<Real> & call(const S<k> & shape_functions, \
- const ElementType type, \
- const GhostType & ghost_type, \
- UInt id) { \
+ const ElementType type, \
+ const GhostType & ghost_type, \
+ UInt id) { \
const Array<Real> * ret = NULL; \
AKANTU_BOOST_KIND_ELEMENT_SWITCH(GET_SHAPES_DERIVATIVES, kind); \
return *ret; \
} \
- };
-
-#define INTEREST_LIST AKANTU_GENERATE_KIND_LIST(AKANTU_REGULAR_KIND AKANTU_COHESIVE_KIND AKANTU_IGFEM_KIND)
+ };
AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_GET_SHAPES_DERIVATIVES_HELPER, \
- INTEREST_LIST)
+ AKANTU_FE_ENGINE_LIST_GET_SHAPES_DERIVATIVES)
#undef AKANTU_SPECIALIZE_GET_SHAPE_DERIVATIVES_HELPER
#undef GET_SHAPES_DERIVATIVES
-#undef INTEREST_LIST
template<template <ElementKind> class I,
- template <ElementKind> class S,
- ElementKind kind>
+ 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 {
-
+ 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 { };
+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) \
+#define AKANTU_SPECIALIZE_GET_INTEGRATION_POINTS_HELPER(kind) \
template<> \
- struct GetQuadraturePointsHelper<kind> { \
+ struct GetIntegrationPointsHelper<kind> { \
template <template <ElementKind> class I, \
- ElementKind k> \
+ ElementKind k> \
static const Matrix<Real> & call(const I<k> & integrator, \
- const ElementType type, \
- const GhostType & ghost_type) { \
+ 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>
+ template <ElementKind> class S,
+ ElementKind kind>
inline const Matrix<Real> &
-FEEngineTemplate<I, S, kind>::getQuadraturePoints(const ElementType & type,
- const GhostType & ghost_type) const {
- return GetQuadraturePointsHelper<kind>::call(integrator, type, ghost_type);
+FEEngineTemplate<I, S, kind>::getIntegrationPoints(const ElementType & type,
+ const GhostType & ghost_type) const {
+ return GetIntegrationPointsHelper<kind>::call(integrator, type, ghost_type);
}
/* -------------------------------------------------------------------------- */
+template<template <ElementKind> class I,
+ template <ElementKind> class S,
+ ElementKind kind>
+void FEEngineTemplate<I, S, kind>::printself(std::ostream & stream, int indent) const {
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "FEEngineTemplate [" << std::endl;
+ stream << space << " + parent [" << std::endl;
+ FEEngine::printself(stream, indent + 3);
+ stream << space << " ]" << std::endl;
+ stream << space << " + shape functions [" << std::endl;
+ shape_functions.printself(stream, indent + 3);
+ stream << space << " ]" << std::endl;
+ stream << space << " + integrator [" << std::endl;
+ integrator.printself(stream, indent + 3);
+ stream << space << " ]" << std::endl;
+ stream << space << "]" << std::endl;
+}
+
+/* -------------------------------------------------------------------------- */
+
__END_AKANTU__
+
#include "shape_lagrange.hh"
#include "integrator_gauss.hh"
+
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_triangle_6>(const Array<Real> & field_1,
- UInt nb_degree_of_freedom,
- Array<Real> & lumped,
- const Array<Int> & equation_number,
- const GhostType & ghost_type) const {
+ UInt nb_degree_of_freedom,
+ Array<Real> & lumped,
+ const Array<Int> & equation_number,
+ const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_triangle_6>(field_1, nb_degree_of_freedom,
- lumped, equation_number, ghost_type);
+ lumped, equation_number, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_tetrahedron_10>(const Array<Real> & field_1,
- UInt nb_degree_of_freedom,
- Array<Real> & lumped,
- const Array<Int> & equation_number,
- const GhostType & ghost_type) const {
+ UInt nb_degree_of_freedom,
+ Array<Real> & lumped,
+ const Array<Int> & equation_number,
+ const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_tetrahedron_10>(field_1, nb_degree_of_freedom,
- lumped, equation_number, ghost_type);
+ lumped, equation_number, ghost_type);
}
/* -------------------------------------------------------------------------- */
template <>
template <>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
assembleLumpedTemplate<_quadrangle_8>(const Array<Real> & field_1,
- UInt nb_degree_of_freedom,
- Array<Real> & lumped,
- const Array<Int> & equation_number,
- const GhostType & ghost_type) const {
+ UInt nb_degree_of_freedom,
+ Array<Real> & lumped,
+ const Array<Int> & equation_number,
+ const GhostType & ghost_type) const {
assembleLumpedDiagonalScaling<_quadrangle_8>(field_1, nb_degree_of_freedom,
- lumped, equation_number, ghost_type);
+ lumped, equation_number, ghost_type);
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+template <>
+inline void
+FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
+assembleLumpedTemplate<_hexahedron_20>(const Array<Real> & field_1,
+ UInt nb_degree_of_freedom,
+ Array<Real> & lumped,
+ const Array<Int> & equation_number,
+ const GhostType & ghost_type) const {
+ assembleLumpedDiagonalScaling<_hexahedron_20>(field_1, nb_degree_of_freedom,
+ lumped, equation_number, ghost_type);
+}
+
+/* -------------------------------------------------------------------------- */
+template <>
+template <>
+inline void
+FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
+assembleLumpedTemplate<_pentahedron_15>(const Array<Real> & field_1,
+ UInt nb_degree_of_freedom,
+ Array<Real> & lumped,
+ const Array<Int> & equation_number,
+ const GhostType & ghost_type) const {
+ assembleLumpedDiagonalScaling<_pentahedron_15>(field_1, nb_degree_of_freedom,
+ lumped, equation_number, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<>
template<>
inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular>::
-computeNormalsOnControlPoints<_point_1>(__attribute__((unused))const Array<Real> & field,
- Array<Real> & normal,
- const GhostType & ghost_type) const {
+computeNormalsOnIntegrationPoints<_point_1>(__attribute__((unused))const Array<Real> & field,
+ Array<Real> & normal,
+ const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == 1, "Mesh dimension must be 1 to compute normals on points!");
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);
+ 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));
+ difference = coords(elem)-coords(segment_connectivity(1));
} else {
- difference = coords(elem)-coords(segment_connectivity(0));
+ difference = coords(elem)-coords(segment_connectivity(0));
}
normal_value = difference/std::abs(difference);
}
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..f7c273e6b 100644
--- a/src/fe_engine/fe_engine_template_tmpl_struct.hh
+++ b/src/fe_engine/fe_engine_template_tmpl_struct.hh
@@ -1,238 +1,238 @@
/**
* @file fe_engine_template_tmpl_struct.hh
*
* @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Mon Jul 07 2014
* @date last modification: Mon Jul 07 2014
*
* @brief Template implementation of FEEngineTemplate for Structural Element Kinds
*
* @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 "shape_linked.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <>
inline const Array<Real> &
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::
getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type,
UInt id) const {
AKANTU_DEBUG_IN();
const Array<Real> * ret = NULL;
#define GET_SHAPES(type) \
ret = &(shape_functions.getShapesDerivatives(type, ghost_type, id));
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_SHAPES);
#undef GET_SHAPES
AKANTU_DEBUG_OUT();
return *ret;
}
/* -------------------------------------------------------------------------- */
template<>
inline const Array<Real> &
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::getShapes(const ElementType & type,
const GhostType & ghost_type,
UInt id) const {
AKANTU_DEBUG_IN();
const Array<Real> * ret = NULL;
#define GET_SHAPES(type) \
ret = &(shape_functions.getShapes(type, ghost_type, id));
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_SHAPES);
#undef GET_SHAPES
AKANTU_DEBUG_OUT();
return *ret;
}
/* -------------------------------------------------------------------------- */
template<>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const ElementType & type,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
#define ASSEMBLE_MATRIX(type) \
assembleFieldMatrix<type>(field_1, nb_degree_of_freedom, \
M, n, rotation_mat, \
ghost_type)
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(ASSEMBLE_MATRIX);;
#undef ASSEMBLE_MATRIX
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
inline void FEEngineTemplate<I, S, kind>::computeShapesMatrix(const ElementType & type,
UInt nb_degree_of_freedom,
UInt nb_nodes_per_element,
Array<Real> * n,
UInt id,
UInt degree_to_interpolate,
UInt degree_interpolated,
const bool sign,
const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
template<>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::computeShapesMatrix(const ElementType & type,
UInt nb_degree_of_freedom,
UInt nb_nodes_per_element,
Array<Real> * n,
UInt id,
UInt degree_to_interpolate,
UInt degree_interpolated,
const bool sign, // true +, false -
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt nb_element = mesh.getNbElement(type);
- UInt nb_quadrature_points = getNbQuadraturePoints(type);
+ UInt nb_quadrature_points = getNbIntegrationPoints(type);
UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
UInt n_size = n->getNbComponent()/nt_n_field_size;
Array<Real>::const_vector_iterator shape = getShapes(type, ghost_type, id).begin(nb_nodes_per_element);
Array<Real>::matrix_iterator N_it = n->begin(n_size , nt_n_field_size);
int c;
if (sign == true){
c=1;
}else{
c = -1;
}
UInt line = degree_interpolated;
UInt coll = degree_to_interpolate;
for (UInt e=0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quadrature_points; ++q, ++N_it, ++shape) {
const Vector<Real> & shapes = *shape;
Matrix<Real> & N = *N_it;
N(line, coll) = shapes(0) * c;
N(line, coll + nb_degree_of_freedom) = shapes(1) * c;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
template <ElementType type>
inline void
FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural>::assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const GhostType & ghost_type) const {
AKANTU_DEBUG_IN();
UInt nb_element = mesh.getNbElement(type);
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
- UInt nb_quadrature_points = getNbQuadraturePoints(type);
+ UInt nb_quadrature_points = getNbIntegrationPoints(type);
UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
UInt n_size = n->getNbComponent()/nt_n_field_size;
Array<Real> * nt_n_field = new Array<Real>(nb_element * nb_quadrature_points, // nt_n_size * nt_n_size, nb_elem * nb_quad_points?
nt_n_field_size * nt_n_field_size,
"NT*N*field");
Array<Real> * nt = new Array<Real>(nb_element * nb_quadrature_points,
n_size * nt_n_field_size, "N*T");
Array<Real> t = rotation_mat(type);
nt_n_field->clear();
nt->clear();
Array<Real>::matrix_iterator N = n->begin(n_size, nt_n_field_size);
Array<Real>::matrix_iterator Nt_N_field = nt_n_field->begin(nt_n_field_size, nt_n_field_size);
Array<Real>::matrix_iterator T = rotation_mat(type).begin(nt_n_field_size, nt_n_field_size);
Array<Real>::matrix_iterator NT = nt->begin(n_size, nt_n_field_size);
Real * field_val = field_1.storage();
for (UInt e = 0; e < nb_element; ++e, ++T){
for (UInt q = 0; q< nb_quadrature_points; ++q, ++N, ++NT, ++Nt_N_field, /*++T,*/ ++field_val){
NT->mul<false, false>(*N, *T);
Nt_N_field->mul<true, false>(*NT, *NT, *field_val);
}
}
Array<Real> * int_nt_n_field = new Array<Real>(nb_element,
nt_n_field_size * nt_n_field_size,
"NT*N*field");
int_nt_n_field->clear();
integrate(*nt_n_field, *int_nt_n_field, nt_n_field_size * nt_n_field_size, type);
// integrate(*nt_n_field, *int_nt_n_field, nb_degree_of_freedom, type);
assembleMatrix(*int_nt_n_field, M, nb_degree_of_freedom, type);
delete nt;
delete nt_n_field;
delete int_nt_n_field;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<template <ElementKind> class I,
template <ElementKind> class S,
ElementKind kind>
template <ElementType type>
inline void FEEngineTemplate<I, S, kind>::assembleFieldMatrix(const Array<Real> & field_1,
UInt nb_degree_of_freedom,
SparseMatrix & M,
Array<Real> * n,
ElementTypeMapArray<Real> & rotation_mat,
const GhostType & ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
__END_AKANTU__
diff --git a/src/fe_engine/geometrical_data_tmpl.hh b/src/fe_engine/geometrical_data_tmpl.hh
deleted file mode 100644
index e56655eb1..000000000
--- a/src/fe_engine/geometrical_data_tmpl.hh
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * @file geometrical_data_tmpl.hh
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Wed Jan 16 2013
- * @date last modification: Fri Jun 13 2014
- *
- * @brief Specialization of the geometrical types
- *
- * @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/>.
- *
- */
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_point> {
- static const UInt spatial_dimension = 0;
- static const UInt nb_nodes_per_element = 1;
- static const GeometricalType p1_element_type = _gt_point;
- static const GeometricalType facet_type = _gt_not_defined;
- static const UInt nb_facets = 0;
- static const UInt * facet_connectivity[] = {};
-};
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_segment_2> {
- static const UInt spatial_dimension = 1;
- static const UInt nb_nodes_per_element = 2;
- static const GeometricalType p1_element_type = _gt_segment_2;
- static const UInt nb_facets = 2;
- static const GeometricalType facet_type = _gt_point;
- static const UInt vec_facet_connectivity[] = {0,
- 1};
- static const UInt * facet_connectivity[] = {&vec_facet_connectivity[0],
- &vec_facet_connectivity[1]};
-};
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_segment_3> {
- static const UInt spatial_dimension = 1;
- static const UInt nb_nodes_per_element = 3;
- static const GeometricalType p1_element_type = _gt_segment_2;
- static const UInt nb_facets = 2;
- static const GeometricalType facet_type = _gt_point;
- static const UInt vec_facet_connectivity[] = {0,
- 1};
- static const UInt * facet_connectivity[] = {&vec_facet_connectivity[0],
- &vec_facet_connectivity[1]};
-};
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_triangle_3> {
- static const UInt spatial_dimension = 2;
- static const UInt nb_nodes_per_element = 3;
- static const GeometricalType p1_element_type = _gt_triangle_3;
- static const UInt nb_facets = 3;
- static const GeometricalType facet_type = _gt_segment_2;
- static const UInt vec_facet_connectivity[] = {0, 1,
- 1, 2,
- 2, 0};
- static const UInt * facet_connectivity[] = {&vec_facet_connectivity[0],
- &vec_facet_connectivity[2],
- &vec_facet_connectivity[4]};
-};
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_triangle_6> {
- static const UInt spatial_dimension = 2;
- static const UInt nb_nodes_per_element = 6;
- static const GeometricalType p1_element_type = _gt_triangle_3;
- static const UInt nb_facets = 3;
- static const GeometricalType facet_type = _gt_segment_3;
- static const UInt vec_facet_connectivity[] = {0, 1, 3,
- 1, 2, 4,
- 2, 0, 5};
- static const UInt * facet_connectivity[] = {&vec_facet_connectivity[0],
- &vec_facet_connectivity[3],
- &vec_facet_connectivity[6]};
-};
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_tetrahedron_4> {
- static const UInt spatial_dimension = 3;
- static const UInt nb_nodes_per_element = 4;
- static const GeometricalType p1_element_type = _gt_tetrahedron_4;
- static const UInt nb_facets = 4;
- static const GeometricalType facet_type = _gt_triangle_3;
- static const UInt vec_facet_connectivity[] = {0, 2, 1,
- 1, 2, 3,
- 2, 0, 3,
- 0, 1, 3};
- static const UInt * facet_connectivity[] = {&vec_facet_connectivity[0],
- &vec_facet_connectivity[3],
- &vec_facet_connectivity[6],
- &vec_facet_connectivity[9]};
-};
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_tetrahedron_10> {
- static const UInt spatial_dimension = 3;
- static const UInt nb_nodes_per_element = 10;
- static const GeometricalType p1_element_type = _gt_tetrahedron_4;
- static const UInt nb_facets = 4;
- static const GeometricalType facet_type = _gt_triangle_6;
- static const UInt vec_facet_connectivity[] = {0, 2, 1, 6, 5, 4,
- 1, 2, 3, 5, 9, 8,
- 2, 0, 3, 6, 7, 9,
- 0, 1, 3, 4, 8, 7};
- static const UInt * facet_connectivity[] = {&vec_facet_connectivity[0],
- &vec_facet_connectivity[6],
- &vec_facet_connectivity[12],
- &vec_facet_connectivity[18]};
-};
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_quadrangle_4> {
- static const UInt spatial_dimension = 2;
- static const UInt nb_nodes_per_element = 4;
- static const GeometricalType p1_element_type = _gt_quadrangle_4;
- static const UInt nb_facets = 4;
- static const GeometricalType facet_type = _gt_segment_2;
- static const UInt vec_facet_connectivity[] = {0, 1,
- 1, 2,
- 2, 3,
- 3, 0};
- static const UInt * facet_connectivity[] = {&vec_facet_connectivity[0],
- &vec_facet_connectivity[2],
- &vec_facet_connectivity[4],
- &vec_facet_connectivity[6]};
-};
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_quadrangle_8> {
- static const UInt spatial_dimension = 2;
- static const UInt nb_nodes_per_element = 8;
- static const GeometricalType p1_element_type = _gt_quadrangle_4;
- static const UInt nb_facets = 4;
- static const GeometricalType facet_type = _gt_segment_3;
- static const UInt vec_facet_connectivity[] = {0, 1, 4,
- 1, 2, 5,
- 2, 3, 6,
- 3, 0, 7};
- static const UInt * facet_connectivity[] = {vec_facet_connectivity + 0,
- vec_facet_connectivity + 3,
- vec_facet_connectivity + 6,
- vec_facet_connectivity + 9};
-};
-
-/* -------------------------------------------------------------------------- */
-template<>
-struct GeometricalElementData<_gt_hexahedron_8> {
- static const UInt spatial_dimension = 3;
- static const UInt nb_nodes_per_element = 8;
- static const GeometricalType p1_element_type = _gt_hexahedron_8;
- static const UInt nb_facets = 6;
- static const GeometricalType facet_type = _gt_quadrangle_4;
- static const UInt vec_facet_connectivity[] = {0, 1, 2, 3,
- 0, 1, 5, 4,
- 1, 2, 6, 5,
- 2, 3, 7, 6,
- 3, 0, 4, 7,
- 4, 5, 6, 7};
- static const UInt * facet_connectivity[] = {&vec_facet_connectivity[0],
- &vec_facet_connectivity[4],
- &vec_facet_connectivity[8],
- &vec_facet_connectivity[12],
- &vec_facet_connectivity[16],
- &vec_facet_connectivity[20]};
-};
-
diff --git a/src/fe_engine/geometrical_element.cc b/src/fe_engine/geometrical_element.cc
index 58d7ddc6f..b3354e0c3 100644
--- a/src/fe_engine/geometrical_element.cc
+++ b/src/fe_engine/geometrical_element.cc
@@ -1,164 +1,204 @@
-/**
+
+// 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 Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Nov 14 14:57:27 2012
*
* @brief Specialization of the geometrical types
*
* @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 "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_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_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_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_hexahedron_20>::spatial_dimension = 3;
+template<> UInt GeometricalElement<_gt_hexahedron_20>::nb_nodes_per_element = 20;
+template<> UInt GeometricalElement<_gt_hexahedron_20>::nb_facets[] = { 6 };
+/* -------------------------------------------------------------------------- */
+template<> UInt GeometricalElement<_gt_pentahedron_6>::spatial_dimension = 3;
+template<> UInt GeometricalElement<_gt_pentahedron_6>::nb_nodes_per_element = 6;
+template<> UInt GeometricalElement<_gt_pentahedron_6>::nb_facets[] = { 2, 3 };
+/* -------------------------------------------------------------------------- */
+template<> UInt GeometricalElement<_gt_pentahedron_15>::spatial_dimension = 3;
+template<> UInt GeometricalElement<_gt_pentahedron_15>::nb_nodes_per_element = 15;
+template<> UInt GeometricalElement<_gt_pentahedron_15>::nb_facets[] = { 2, 3 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_not_defined>::nb_nodes_per_facet[] = { 0 };
template<> UInt GeometricalElement<_gt_point>::nb_nodes_per_facet[] = { 1 };
template<> UInt GeometricalElement<_gt_segment_2>::nb_nodes_per_facet[] = { 1 };
template<> UInt GeometricalElement<_gt_segment_3>::nb_nodes_per_facet[] = { 1 };
template<> UInt GeometricalElement<_gt_triangle_3>::nb_nodes_per_facet[] = { 2 };
template<> UInt GeometricalElement<_gt_triangle_6>::nb_nodes_per_facet[] = { 3 };
template<> UInt GeometricalElement<_gt_tetrahedron_4>::nb_nodes_per_facet[] = { 3 };
template<> UInt GeometricalElement<_gt_tetrahedron_10>::nb_nodes_per_facet[] = { 6 };
template<> UInt GeometricalElement<_gt_quadrangle_4>::nb_nodes_per_facet[] = { 2 };
template<> UInt GeometricalElement<_gt_quadrangle_8>::nb_nodes_per_facet[] = { 3 };
template<> UInt GeometricalElement<_gt_hexahedron_8>::nb_nodes_per_facet[] = { 4 };
+template<> UInt GeometricalElement<_gt_hexahedron_20>::nb_nodes_per_facet[] = { 8 };
template<> UInt GeometricalElement<_gt_pentahedron_6>::nb_nodes_per_facet[] = { 3, 4 };
+template<> UInt GeometricalElement<_gt_pentahedron_15>::nb_nodes_per_facet[] = { 6, 8 };
/* -------------------------------------------------------------------------- */
template<> UInt GeometricalElement<_gt_not_defined>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_point>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_segment_2>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_segment_3>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_triangle_3>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_triangle_6>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_tetrahedron_4>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_tetrahedron_10>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_quadrangle_4>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_quadrangle_8>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_hexahedron_8>::nb_facet_types = 1;
+template<> UInt GeometricalElement<_gt_hexahedron_20>::nb_facet_types = 1;
template<> UInt GeometricalElement<_gt_pentahedron_6>::nb_facet_types = 2;
-
-
+template<> UInt GeometricalElement<_gt_pentahedron_15>::nb_facet_types = 2;
/* !!! stored as a matrix nb_facets X nb_nodes_per_facet in COL MAJOR */
/* -------------------------------------------------------------------------- */
/* f1|f2|f3|f4|f5|f6 */
template<> UInt GeometricalElement<_gt_not_defined>::facet_connectivity_vect[] = {};
template<> UInt GeometricalElement<_gt_point>::facet_connectivity_vect[] = {0};
template<> UInt GeometricalElement<_gt_segment_2>::facet_connectivity_vect[] = {0, 1};
template<> UInt GeometricalElement<_gt_segment_3>::facet_connectivity_vect[] = {0, 1};
template<> UInt GeometricalElement<_gt_triangle_3>::facet_connectivity_vect[] = {0, 1, 2,
1, 2, 0};
template<> UInt GeometricalElement<_gt_triangle_6>::facet_connectivity_vect[] = {0, 1, 2,
1, 2, 0,
3, 4, 5};
template<> UInt GeometricalElement<_gt_tetrahedron_4>::facet_connectivity_vect[] = {0, 1, 2, 0,
2, 2, 0, 1,
1, 3, 3, 3};
template<> UInt GeometricalElement<_gt_tetrahedron_10>::facet_connectivity_vect[] = {0, 1, 2, 0,
2, 2, 0, 1,
1, 3, 3, 3,
6, 5, 6, 4,
5, 9, 7, 8,
4, 8, 9, 7};
template<> UInt GeometricalElement<_gt_quadrangle_4>::facet_connectivity_vect[] = {0, 1, 2, 3,
1, 2, 3, 0};
template<> UInt GeometricalElement<_gt_quadrangle_8>::facet_connectivity_vect[] = {0, 1, 2, 3,
1, 2, 3, 0,
4, 5, 6, 7};
template<> UInt GeometricalElement<_gt_hexahedron_8>::facet_connectivity_vect[] = {0, 0, 1, 2, 3, 4,
- 1, 1, 2, 3, 0, 5,
+ 3, 1, 2, 3, 0, 5,
2, 5, 6, 7, 4, 6,
- 3, 4, 5, 6, 7, 7};
-template<> UInt GeometricalElement<_gt_pentahedron_6>::facet_connectivity_vect[] = {0, 3,
- 1, 4,
- 2, 5,
- 0, 0, 1,
- 3, 2, 4,
- 4, 5, 5,
- 1, 3, 2};
+ 1, 4, 5, 6, 7, 7};
+template<> UInt GeometricalElement<_gt_hexahedron_20>::facet_connectivity_vect[] = {0, 1, 2, 3, 0, 4,
+ 1, 2, 3, 0, 3, 5,
+ 5, 6, 7, 4, 2, 6,
+ 4, 5, 6, 7, 1, 7,
+ 8, 9, 10, 11, 11, 16,
+ 13, 14, 15, 12, 10, 17,
+ 16, 17, 18, 19, 9, 18,
+ 12, 13, 14, 15, 8, 19};
+
+template<> UInt GeometricalElement<_gt_pentahedron_6>::facet_connectivity_vect[] = {// first type
+ 0, 3,
+ 2, 4,
+ 1, 5,
+ // second type
+ 0, 0, 1,
+ 1, 3, 2,
+ 4, 5, 5,
+ 3, 2, 4};
+template<> UInt GeometricalElement<_gt_pentahedron_15>::facet_connectivity_vect[] = {// first type
+ 0, 3,
+ 2, 4,
+ 1, 5,
+ 8, 12,
+ 7, 13,
+ 6, 14,
+ // second type
+ 0, 0, 1,
+ 1, 3, 2,
+ 4, 5, 5,
+ 3, 2, 4,
+ 6, 9, 7,
+ 10, 14, 11,
+ 12, 11, 13,
+ 9, 8, 10};
template<> UInt * GeometricalElement<_gt_not_defined>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_point>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_segment_2>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_segment_3>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_triangle_3>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_triangle_6>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_tetrahedron_4>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_tetrahedron_10>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_quadrangle_4>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_quadrangle_8>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_hexahedron_8>::facet_connectivity[] = { &facet_connectivity_vect[0] };
+template<> UInt * GeometricalElement<_gt_hexahedron_20>::facet_connectivity[] = { &facet_connectivity_vect[0] };
template<> UInt * GeometricalElement<_gt_pentahedron_6>::facet_connectivity[] = { &facet_connectivity_vect[0], &facet_connectivity_vect[2*3] };
+template<> UInt * GeometricalElement<_gt_pentahedron_15>::facet_connectivity[] = { &facet_connectivity_vect[0], &facet_connectivity_vect[2*6] };
/* -------------------------------------------------------------------------- */
-
__END_AKANTU__
diff --git a/src/fe_engine/integration_element.cc b/src/fe_engine/integration_element.cc
index 2ade1fa5e..cbcbcef88 100644
--- a/src/fe_engine/integration_element.cc
+++ b/src/fe_engine/integration_element.cc
@@ -1,120 +1,132 @@
/**
* @file integration_element.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Jan 16 2013
* @date last modification: Mon Jul 07 2014
*
- * @brief Definition of the intagration constants
+ * @brief Definition of the integration constants
*
* @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 "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.),
+ 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.,
+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.};
/* -------------------------------------------------------------------------- */
-/* Tetrahedrons */
+/* Pentahedrons */
/* -------------------------------------------------------------------------- */
template<> UInt GaussIntegrationTypeData<_git_pentahedron, 1>::nb_quadrature_points = 6;
-template<> Real GaussIntegrationTypeData<_git_pentahedron, 1>::quad_positions[] = {-1./std::sqrt(3.), 0.5, 0.5,
- -1./std::sqrt(3.), 0. , 0.5,
- -1./std::sqrt(3.), 0.5, 0.,
- 1./std::sqrt(3.), 0.5, 0.5,
- 1./std::sqrt(3.), 0. , 0.5,
- 1./std::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_positions[] = {-1./sqrt(3.), 0.5, 0.5,
+ -1./sqrt(3.), 0. , 0.5,
+ -1./sqrt(3.), 0.5, 0.,
+ 1./sqrt(3.), 0.5, 0.5,
+ 1./sqrt(3.), 0. , 0.5,
+ 1./sqrt(3.), 0.5 ,0.};
+template<> Real GaussIntegrationTypeData<_git_pentahedron, 1>::quad_weights[] = {1./6., 1./6., 1./6.,
+ 1./6., 1./6., 1./6.};
+/* -------------------------------------------------------------------------- */
+template<> UInt GaussIntegrationTypeData<_git_pentahedron, 2>::nb_quadrature_points = 8;
+template<> Real GaussIntegrationTypeData<_git_pentahedron, 2>::quad_positions[] = {-sqrt(3.)/3., 1./3., 1./3.,
+ -sqrt(3.)/3., 0.6 , 0.2,
+ -sqrt(3.)/3., 0.2, 0.6,
+ -sqrt(3.)/3., 0.2, 0.2,
+ sqrt(3.)/3., 1./3., 1./3.,
+ sqrt(3.)/3., 0.6 , 0.2,
+ sqrt(3.)/3., 0.2, 0.6,
+ sqrt(3.)/3., 0.2, 0.2};
+template<> Real GaussIntegrationTypeData<_git_pentahedron, 2>::quad_weights[] = {-27./96., 25./96., 25./96., 25./96.,
+ -27./96., 25./96., 25./96., 25./96.};
__END_AKANTU__
diff --git a/src/fe_engine/integration_point.hh b/src/fe_engine/integration_point.hh
new file mode 100644
index 000000000..c3c713bc1
--- /dev/null
+++ b/src/fe_engine/integration_point.hh
@@ -0,0 +1,157 @@
+/**
+ * @file integration_point.hh
+ *
+ * @author
+ *
+ * @date creation:
+ * @date last modification: Mon Oct 19 2015
+ *
+ * @brief definition of the class IntegrationPoint
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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..933445da0 100644
--- a/src/fe_engine/integrator.hh
+++ b/src/fe_engine/integrator.hh
@@ -1,129 +1,133 @@
/**
* @file integrator.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Feb 15 2011
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 10c926bfc..9df81f94c 100644
--- a/src/fe_engine/integrator_gauss.hh
+++ b/src/fe_engine/integrator_gauss.hh
@@ -1,147 +1,151 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 d040b21e3..fdce1fcf0 100644
--- a/src/fe_engine/integrator_gauss_inline_impl.cc
+++ b/src/fe_engine/integrator_gauss_inline_impl.cc
@@ -1,458 +1,500 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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>
-inline void IntegratorGauss<kind>::initIntegrator(const Array<Real> & nodes,
- const ElementType & type,
- const GhostType & ghost_type) {
-#define INIT_INTEGRATOR(type) \
- computeQuadraturePoints<type>(ghost_type); \
- precomputeJacobiansOnQuadraturePoints<type>(nodes, ghost_type); \
- checkJacobians<type>(ghost_type);
-
- AKANTU_BOOST_ALL_ELEMENT_SWITCH(INIT_INTEGRATOR);
-#undef INIT_INTEGRATOR
-}
-
/* -------------------------------------------------------------------------- */
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);
- 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);
// 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);
- J *= weights;
}
// >>>>>> 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);
-
- J *= weights;
}
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_tmpl.hh b/src/fe_engine/interpolation_element_tmpl.hh
index f84f30783..5b6377754 100644
--- a/src/fe_engine/interpolation_element_tmpl.hh
+++ b/src/fe_engine/interpolation_element_tmpl.hh
@@ -1,55 +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
*
* @brief interpolation property description
*
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Regular Elements */
/* -------------------------------------------------------------------------- */
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_point_1, _itk_lagrangian, 1, 0);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_2, _itk_lagrangian, 2, 1);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_segment_3, _itk_lagrangian, 3, 1);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_3, _itk_lagrangian, 3, 2);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_triangle_6, _itk_lagrangian, 6, 2);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_4, _itk_lagrangian, 4, 3);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_tetrahedron_10, _itk_lagrangian, 10, 3);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_quadrangle_4, _itk_lagrangian, 4, 2);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_quadrangle_8, _itk_lagrangian, 8, 2);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_hexahedron_8, _itk_lagrangian, 8, 3);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_serendip_hexahedron_20, _itk_lagrangian, 20, 3);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_6, _itk_lagrangian, 6, 3);
+AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_lagrange_pentahedron_15, _itk_lagrangian, 15, 3);
/* -------------------------------------------------------------------------- */
/* Structural elements */
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_STRUCTURAL_MECHANICS)
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam, _itk_structural, 2, 1);
AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(_itp_kirchhoff_shell, _itk_structural, 3, 2);
#endif
diff --git a/src/fe_engine/shape_cohesive.hh b/src/fe_engine/shape_cohesive.hh
index 2aea47f6e..59d143eb3 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>
*
* @date creation: Fri Feb 03 2012
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_array.hh"
#include "shape_functions.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SHAPE_COHESIVE_HH__
#define __AKANTU_SHAPE_COHESIVE_HH__
__BEGIN_AKANTU__
struct CohesiveReduceFunctionMean {
inline Real operator()(Real u_plus, Real u_minus) {
return .5*(u_plus + u_minus);
}
};
struct CohesiveReduceFunctionOpening {
inline Real operator()(Real u_plus, Real u_minus) {
return (u_plus - u_minus);
}
};
template<>
class ShapeLagrange<_ek_cohesive> : public ShapeFunctions {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
ShapeLagrange(const Mesh & mesh,
const ID & id = "shape_cohesive",
const MemoryID & memory_id = 0);
virtual ~ShapeLagrange() { }
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
inline void initShapeFunctions(const Array<Real> & nodes,
- const Matrix<Real> & control_points,
+ const Matrix<Real> & integration_points,
const ElementType & type,
const GhostType & ghost_type);
/// extract the nodal values and store them per element
template <ElementType type, class ReduceFunction>
void extractNodalToElementField(const Array<Real> & nodal_f,
Array<Real> & elemental_f,
const GhostType & ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
- /// pre compute all shapes on the element 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, class ReduceFunction>
- 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) const;
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) const {
- interpolateOnControlPoints<type, CohesiveReduceFunctionMean>(u, uq, nb_degree_of_freedom, ghost_type, filter_elements);
+ 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,
+ 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 {
- variationOnControlPoints<type, CohesiveReduceFunctionMean>(u, nablauq, nb_degree_of_freedom, ghost_type, filter_elements);
+ 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,
+ 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,
+ void computeNormalsOnIntegrationPoints(const Array<Real> &u,
Array<Real> &normals_u,
GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// multiply a field by shape functions
template <ElementType type>
void fieldTimesShapes(const Array<Real> & field,
Array<Real> & fiedl_times_shapes,
GhostType ghost_type) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get a the shapes vector
inline const Array<Real> & getShapes(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/// get a the shapes derivatives vector
inline const Array<Real> & getShapesDerivatives(const ElementType & el_type,
const GhostType & ghost_type = _not_ghost) const;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// shape functions for all elements
ElementTypeMapArray<Real, InterpolationType> shapes;
/// shape functions derivatives for all elements
ElementTypeMapArray<Real, InterpolationType> shapes_derivatives;
};
// __END_AKANTU__
// #include "shape_lagrange.hh"
// __BEGIN_AKANTU__
// template<>
// class ShapeLagrange<_ek_cohesive> : public ShapeCohesive< ShapeLagrange<_ek_regular> > {
// public:
// ShapeLagrange(const Mesh & mesh,
// const ID & id = "shape_cohesive",
// const MemoryID & memory_id = 0) :
// ShapeCohesive< ShapeLagrange<_ek_regular> >(mesh, id, memory_id) { }
// virtual ~ShapeLagrange() { };
// };
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "shape_cohesive_inline_impl.cc"
/// standard output stream operator
template <class ShapeFunction>
inline std::ostream & operator <<(std::ostream & stream, const ShapeCohesive<ShapeFunction> & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_SHAPE_COHESIVE_HH__ */
diff --git a/src/fe_engine/shape_cohesive_inline_impl.cc b/src/fe_engine/shape_cohesive_inline_impl.cc
index b8054e602..9e48e268e 100644
--- a/src/fe_engine/shape_cohesive_inline_impl.cc
+++ b/src/fe_engine/shape_cohesive_inline_impl.cc
@@ -1,294 +1,294 @@
/**
* @file shape_cohesive_inline_impl.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 23 2012
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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..3099caf38 100644
--- a/src/fe_engine/shape_functions.hh
+++ b/src/fe_engine/shape_functions.hh
@@ -1,138 +1,188 @@
/**
* @file shape_functions.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Feb 15 2011
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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..419c059d1 100644
--- a/src/fe_engine/shape_functions_inline_impl.cc
+++ b/src/fe_engine/shape_functions_inline_impl.cc
@@ -1,173 +1,584 @@
/**
* @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>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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.hh b/src/fe_engine/shape_lagrange.hh
index 05b6a01ec..ecb41153c 100644
--- a/src/fe_engine/shape_lagrange.hh
+++ b/src/fe_engine/shape_lagrange.hh
@@ -1,158 +1,175 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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;
- /// compute the gradient of u on the control points
+ /// interpolate on physical point
template <ElementType type>
- void gradientOnControlPoints(const Array<Real> &u,
+ void interpolate(const Vector <Real> & real_coords,
+ UInt elem,
+ const Matrix<Real> & nodal_values,
+ Vector<Real> & interpolated,
+ const GhostType & ghost_type) const;
+
+ /// compute the gradient of u on the integration points
+ template <ElementType type>
+ void gradientOnIntegrationPoints(const Array<Real> &u,
Array<Real> &nablauq,
UInt nb_degree_of_freedom,
GhostType ghost_type = _not_ghost,
const Array<UInt> & filter_elements = empty_filter) const;
/// multiply a field by shape functions @f$ fts_{ij} = f_i * \varphi_j @f$
template <ElementType type>
void fieldTimesShapes(const Array<Real> & field,
Array<Real> & field_times_shapes,
GhostType ghost_type) const;
/// find natural coords from real coords provided an element
template <ElementType type>
void inverseMap(const Vector<Real> & real_coords,
UInt element,
Vector<Real> & natural_coords,
const GhostType & ghost_type = _not_ghost) const;
/// return true if the coordinates provided are inside the element, false otherwise
template <ElementType type>
bool contains(const Vector<Real> & real_coords,
UInt elem,
const GhostType & ghost_type) const;
/// compute the shape on a provided point
template <ElementType type>
void computeShapes(const Vector<Real> & real_coords,
UInt elem,
Vector<Real> & shapes,
const GhostType & ghost_type) const;
+ /// compute the shape derivatives on a provided point
+ template <ElementType type>
+ void computeShapeDerivatives(const Matrix<Real> & real_coords,
+ UInt elem,
+ Tensor3<Real> & shapes,
+ const GhostType & ghost_type) const;
+
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
- /// compute the shape derivatives on 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);
+ 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 cacca9d0f..d07ee222d 100644
--- a/src/fe_engine/shape_lagrange_inline_impl.cc
+++ b/src/fe_engine/shape_lagrange_inline_impl.cc
@@ -1,336 +1,410 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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) {
+ 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{
+ 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.hh b/src/fe_engine/shape_linked.hh
index 23b3f2217..6137fae49 100644
--- a/src/fe_engine/shape_linked.hh
+++ b/src/fe_engine/shape_linked.hh
@@ -1,158 +1,160 @@
/**
* @file shape_linked.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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..d13ec494f 100644
--- a/src/fe_engine/shape_linked_inline_impl.cc
+++ b/src/fe_engine/shape_linked_inline_impl.cc
@@ -1,331 +1,331 @@
/**
* @file shape_linked_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Fabian Barras <fabian.barras@epfl.ch>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 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);
+ 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 Matrix<Real> & integration_points,
__attribute__((unused)) const ElementType & type,
__attribute__((unused)) const GhostType & ghost_type) {
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
}
#endif
#undef INIT_SHAPE_FUNCTIONS
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
inline const Array<Real> & ShapeLinked<kind>::getShapes(const ElementType & type,
const GhostType & ghost_type,
UInt id) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(shapes.exists(type, ghost_type),
"No shapes of type "
<< type << " in " << this->id);
AKANTU_DEBUG_OUT();
return *(shapes(type, ghost_type)[id]);
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
inline const Array<Real> & ShapeLinked<kind>::getShapesDerivatives(const ElementType & type,
const GhostType & ghost_type,
UInt id) const {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(shapes_derivatives.exists(type, ghost_type),
"No shapes_derivatives of type "
<< type << " in " << this->id);
AKANTU_DEBUG_OUT();
return *(shapes_derivatives(type, ghost_type)[id]);
}
#if defined(AKANTU_STRUCTURAL_MECHANICS)
/* -------------------------------------------------------------------------- */
template <>
template <ElementType type>
-void ShapeLinked<_ek_structural>::precomputeShapesOnControlPoints(const Array<Real> & nodes,
+void ShapeLinked<_ek_structural>::precomputeShapesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
// Real * coord = mesh.getNodes().storage();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- Matrix<Real> & natural_coords = 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) {
ghost = "ghost_";
}
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt nb_shape_functions = ElementClass<type, _ek_structural>::getNbShapeFunctions();
Array<Real> ** shapes_tmp = new Array<Real> *[nb_shape_functions];
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el,
type, ghost_type);
for (UInt s = 0; s < nb_shape_functions; ++s) {
std::stringstream sstr_shapes;
sstr_shapes << id << ":" << ghost << "shapes:" << type << ":" << s;
shapes_tmp[s] = &(alloc<Real>(sstr_shapes.str(),
nb_element*nb_points,
size_of_shapes));
Array<Real>::matrix_iterator x_it = x_el.begin(spatial_dimension,
nb_nodes_per_element);
Array<Real>::matrix_iterator shapes_it =
shapes_tmp[s]->begin_reinterpret(size_of_shapes, nb_points, nb_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++shapes_it, ++x_it) {
Matrix<Real> & X = *x_it;
Matrix<Real> & N = *shapes_it;
ElementClass<type>::computeShapes(natural_coords,
N, X,
s);
}
}
shapes(type, ghost_type) = shapes_tmp;
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
-void ShapeLinked<kind>::precomputeShapeDerivativesOnControlPoints(const Array<Real> & nodes,
+void ShapeLinked<kind>::precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
// Real * coord = mesh.getNodes().storage();
UInt spatial_dimension = mesh.getSpatialDimension();
UInt natural_spatial_dimension = ElementClass<type>::getNaturalSpaceDimension();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
- Matrix<Real> & natural_coords = control_points(type, ghost_type);
+ Matrix<Real> & natural_coords = integration_points(type, ghost_type);
UInt nb_points = natural_coords.cols();
UInt nb_element = mesh.getNbElement(type, ghost_type);
std::string ghost = "";
if(ghost_type == _ghost) {
ghost = "ghost_";
}
Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
FEEngine::extractNodalToElementField(mesh, nodes, x_el,
type, ghost_type);
UInt nb_shape_functions = ElementClass<type>::getNbShapeDerivatives();
Array<Real> ** shapes_derivatives_tmp = new Array<Real> *[nb_shape_functions];
for (UInt s = 0; s < nb_shape_functions; ++s) {
std::stringstream sstr_shapesd;
sstr_shapesd << id << ":" << ghost << "shapes_derivatives:" << type << ":" << s;
shapes_derivatives_tmp[s] = &(alloc<Real>(sstr_shapesd.str(),
nb_element*nb_points,
size_of_shapesd));
Real * shapesd_val = shapes_derivatives_tmp[s]->storage();
Array<Real>::matrix_iterator x_it = x_el.begin(spatial_dimension,
nb_nodes_per_element);
for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
// compute shape derivatives
Matrix<Real> & X = *x_it;
Tensor3<Real> B(shapesd_val,
natural_spatial_dimension, nb_nodes_per_element, nb_points);
ElementClass<type>::computeShapeDerivatives(natural_coords,
B, X, s);
shapesd_val += size_of_shapesd*nb_points;
}
}
shapes_derivatives(type, ghost_type) = shapes_derivatives_tmp;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
void ShapeLinked<kind>::extractNodalToElementField(const Array<Real> & nodal_f,
Array<Real> & elemental_f,
UInt num_degre_of_freedom_to_extract,
const GhostType & ghost_type,
const Array<UInt> & filter_elements) const{
AKANTU_DEBUG_IN();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_degree_of_freedom = nodal_f.getNbComponent();
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
if(filter_elements != empty_filter) {
nb_element = filter_elements.getSize();
}
elemental_f.resize(nb_element);
Real * nodal_f_val = nodal_f.storage();
Real * f_val = elemental_f.storage();
UInt * el_conn;
for (UInt el = 0; el < nb_element; ++el) {
if(filter_elements != empty_filter) el_conn = conn_val + filter_elements(el) * nb_nodes_per_element;
else el_conn = conn_val + el * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt node = *(el_conn + n);
*f_val = nodal_f_val[node * nb_degree_of_freedom + num_degre_of_freedom_to_extract];
f_val += 1;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <ElementKind kind>
template <ElementType type>
-void ShapeLinked<kind>::interpolateOnControlPoints(const Array<Real> &in_u,
+void ShapeLinked<kind>::interpolateOnIntegrationPoints(const Array<Real> &in_u,
Array<Real> &out_uq,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements,
bool accumulate,
UInt id_shape,
UInt num_degre_of_freedom_to_interpolate,
UInt num_degre_of_freedom_interpolated) const {
AKANTU_DEBUG_IN();
Array<Real> * shapes_loc = shapes(type, ghost_type)[id_shape];
AKANTU_DEBUG_ASSERT(shapes_loc != NULL,
"No shapes for the type " << type);
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
Array<Real> u_el(0, nb_nodes_per_element);
extractNodalToElementField<type>(in_u, u_el, num_degre_of_freedom_to_interpolate,
ghost_type, filter_elements);
if(!accumulate) out_uq.clear();
- UInt nb_points = 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,
+ 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,
+void ShapeLinked<kind>::gradientOnIntegrationPoints(const Array<Real> &in_u,
Array<Real> &out_nablauq,
UInt nb_degree_of_freedom,
const GhostType & ghost_type,
const Array<UInt> & filter_elements,
bool accumulate,
UInt id_shape,
UInt num_degre_of_freedom_to_interpolate,
UInt num_degre_of_freedom_interpolated) const {
AKANTU_DEBUG_IN();
Array<Real> * shapesd_loc = shapes_derivatives(type, ghost_type)[id_shape];
AKANTU_DEBUG_ASSERT(shapesd_loc != NULL,
"No shapes for the type " << type);
UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
Array<Real> u_el(0, nb_nodes_per_element);
extractNodalToElementField<type>(in_u, u_el, num_degre_of_freedom_to_interpolate, ghost_type, filter_elements);
- UInt nb_points = 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,
+ this->template gradientElementalFieldOnIntegrationPoints<type>(u_el,
nablauq,
ghost_type,
*shapesd_loc,
filter_elements);
Array<Real>::matrix_iterator nabla_u_it = nablauq.begin(1, element_dimension);
Array<Real>::matrix_iterator out_nabla_u_it = out_nablauq.begin(nb_degree_of_freedom, element_dimension);
for (UInt q = 0; q < nb_points; ++q, ++nabla_u_it, ++out_nabla_u_it) {
for (UInt s = 0; s < element_dimension; ++s) {
(*out_nabla_u_it)(num_degre_of_freedom_to_interpolate, s) += (*nabla_u_it)(0, s);
}
}
AKANTU_DEBUG_OUT();
}
diff --git a/src/geometry/aabb_primitives/aabb_primitive.cc b/src/geometry/aabb_primitives/aabb_primitive.cc
new file mode 100644
index 000000000..6d5324f33
--- /dev/null
+++ b/src/geometry/aabb_primitives/aabb_primitive.cc
@@ -0,0 +1,48 @@
+/**
+ * @file aabb_primitive.cc
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Tue Jun 2 2015
+ * @date last modification: Tue Jun 2 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100644
index 000000000..e40a83bb9
--- /dev/null
+++ b/src/geometry/aabb_primitives/aabb_primitive.hh
@@ -0,0 +1,89 @@
+/**
+ * @file aabb_primitive.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Fri Mar 13 2015
+ * @date last modification: Fri Mar 13 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..ad62a644b
--- /dev/null
+++ b/src/geometry/aabb_primitives/line_arc.hh
@@ -0,0 +1,78 @@
+/**
+ * @file segment.hh
+ *
+ * @author Clément Roux-Langlois <clement.roux@epfl.ch>
+ *
+ * @date creation: Wed Mar 13 2015
+ * @date last modification: Wed Mar 13 2015
+ *
+ * @brief Segment 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..d0efeb7b4
--- /dev/null
+++ b/src/geometry/aabb_primitives/tetrahedron.hh
@@ -0,0 +1,74 @@
+/**
+ * @file tetrahedron.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Tue Mar 10 2015
+ * @date last modification: Tue Mar 10 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..559285561
--- /dev/null
+++ b/src/geometry/aabb_primitives/triangle.hh
@@ -0,0 +1,71 @@
+/**
+ * @file triangle.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Tue Mar 3 2015
+ * @date last modification: Tue Mar 3 2015
+ *
+ * @brief Triangle 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..7abf04112
--- /dev/null
+++ b/src/geometry/geom_helper_functions.hh
@@ -0,0 +1,103 @@
+/**
+ * @file geom_helper_functions.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Wed Mar 4 2015
+ * @date last modification: Thu Mar 5 2015
+ *
+ * @brief Helper functions for the computational geometry algorithms
+ *
+ * @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_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
new file mode 100644
index 000000000..43c4244e9
--- /dev/null
+++ b/src/geometry/mesh_abstract_intersector.hh
@@ -0,0 +1,106 @@
+/**
+ * @file mesh_abstract_intersector.hh
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Mon Jul 13 2015
+ * @date last modification: Mon Jul 13 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__
+#define __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__
+
+#include "aka_common.hh"
+#include "mesh_geom_abstract.hh"
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/**
+ * @brief Class used to perform intersections on a mesh and construct output data
+ */
+template<class Query>
+class MeshAbstractIntersector : public MeshGeomAbstract {
+
+public:
+ /// Construct from mesh
+ explicit MeshAbstractIntersector(Mesh & mesh);
+
+ /// Destructor
+ virtual ~MeshAbstractIntersector();
+
+public:
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// get the new_node_per_elem array
+ AKANTU_GET_MACRO(NewNodePerElem, *new_node_per_elem, const Array<UInt> &);
+ /// get the intersection_points array
+ AKANTU_GET_MACRO(IntersectionPoints, intersection_points, const Array<Real> *);
+ /// get the nb_seg_by_el UInt
+ AKANTU_GET_MACRO(NbSegByEl, nb_seg_by_el, const UInt);
+
+ /**
+ * @brief Compute the intersection with a query object
+ *
+ * This function needs to be implemented for every subclass. It computes the intersections
+ * with the tree of primitives and creates the data for the user.
+ *
+ * @param query the CGAL primitive of the query object
+ */
+ virtual void computeIntersectionQuery(const Query & query) = 0;
+
+ /// Compute intersection points between the mesh primitives (segments) and a query (surface in 3D or a curve in 2D), double intersection points for the same primitives are not considered. A maximum intersection node per element is set : 2 in 2D and 4 in 3D
+ virtual void computeMeshQueryIntersectionPoint(const Query & query, UInt nb_old_nodes) = 0;
+
+ /// Compute intersection between the mesh and a list of queries
+ virtual void computeIntersectionQueryList(const std::list<Query> & query_list);
+
+ /// Compute intersection points between the mesh and a list of queries
+ virtual void computeMeshQueryListIntersectionPoint(const std::list<Query> & query_list,
+ UInt nb_old_nodes);
+
+ /// Compute whatever result is needed from the user (should be move to the appropriate specific classe for genericity)
+ virtual void buildResultFromQueryList(const std::list<Query> & query_list) = 0;
+
+protected:
+ /// new node per element (column 0: number of new nodes, then odd is the intersection node number and even the ID of the intersected segment)
+ Array<UInt> * new_node_per_elem;
+
+ /// intersection output: new intersection points (computeMeshQueryListIntersectionPoint)
+ Array<Real> * intersection_points;
+
+ /// number of segment in a considered element of the templated type of element specialized intersector
+ const UInt nb_seg_by_el;
+};
+
+__END_AKANTU__
+
+#include "mesh_abstract_intersector_tmpl.hh"
+
+#endif // __AKANTU_MESH_ABSTRACT_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_abstract_intersector_tmpl.hh b/src/geometry/mesh_abstract_intersector_tmpl.hh
new file mode 100644
index 000000000..d40fcaedf
--- /dev/null
+++ b/src/geometry/mesh_abstract_intersector_tmpl.hh
@@ -0,0 +1,87 @@
+/**
+ * @file mesh_abstract_intersector_tmpl.hh
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Mon Jul 13 2015
+ * @date last modification: Mon Jul 13 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
+#define __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
+
+#include "aka_common.hh"
+#include "mesh_abstract_intersector.hh"
+
+__BEGIN_AKANTU__
+
+template<class Query>
+MeshAbstractIntersector<Query>::MeshAbstractIntersector(Mesh & mesh):
+ MeshGeomAbstract(mesh),
+ new_node_per_elem(NULL),
+ intersection_points(NULL),
+ nb_seg_by_el(0)
+{}
+
+template<class Query>
+MeshAbstractIntersector<Query>::~MeshAbstractIntersector()
+{}
+
+template<class Query>
+void MeshAbstractIntersector<Query>::computeIntersectionQueryList(
+ const std::list<Query> & query_list) {
+ AKANTU_DEBUG_IN();
+
+ typename std::list<Query>::const_iterator
+ query_it = query_list.begin(),
+ query_end = query_list.end();
+
+ for (; query_it != query_end ; ++query_it) {
+ computeIntersectionQuery(*query_it);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+template<class Query>
+void MeshAbstractIntersector<Query>::computeMeshQueryListIntersectionPoint(
+ const std::list<Query> & query_list, UInt nb_old_nodes) {
+ AKANTU_DEBUG_IN();
+
+ typename std::list<Query>::const_iterator
+ query_it = query_list.begin(),
+ query_end = query_list.end();
+
+ for (; query_it != query_end ; ++query_it) {
+ computeMeshQueryIntersectionPoint(*query_it, nb_old_nodes);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
+
+#endif // __AKANTU_MESH_ABSTRACT_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/mesh_geom_abstract.hh b/src/geometry/mesh_geom_abstract.hh
new file mode 100644
index 000000000..41af4f4ed
--- /dev/null
+++ b/src/geometry/mesh_geom_abstract.hh
@@ -0,0 +1,64 @@
+/**
+ * @file mesh_geom_abstract.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Thu Feb 26 2015
+ * @date last modification: Fri Mar 6 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MESH_GEOM_ABSTRACT_HH__
+#define __AKANTU_MESH_GEOM_ABSTRACT_HH__
+
+#include "aka_common.hh"
+#include "mesh.hh"
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/// Abstract class for mesh geometry operations
+class MeshGeomAbstract {
+
+public:
+ /// Construct from mesh
+ explicit MeshGeomAbstract(Mesh & mesh) : mesh(mesh) {};
+
+ /// Destructor
+ virtual ~MeshGeomAbstract() {};
+
+public:
+ /// Construct geometric data for computational geometry algorithms
+ virtual void constructData(GhostType ghost_type = _not_ghost) = 0;
+
+protected:
+ /// Mesh used to construct the primitives
+ Mesh & mesh;
+};
+
+__END_AKANTU__
+
+#endif // __AKANTU_MESH_GEOM_ABSTRACT_HH__
diff --git a/src/geometry/mesh_geom_common.hh b/src/geometry/mesh_geom_common.hh
new file mode 100644
index 000000000..8ad6b8314
--- /dev/null
+++ b/src/geometry/mesh_geom_common.hh
@@ -0,0 +1,53 @@
+/**
+ * @file mesh_geom_common.hh
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Wed May 13 2015
+ * @date last modification: Wed May 13 2015
+ *
+ * @brief Common file for MeshGeom module
+ *
+ * @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_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
new file mode 100644
index 000000000..fa48e19e3
--- /dev/null
+++ b/src/geometry/mesh_geom_factory.hh
@@ -0,0 +1,107 @@
+/**
+ * @file mesh_geom_factory.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Thu Feb 26 2015
+ * @date last modification: Fri Mar 6 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MESH_GEOM_FACTORY_HH__
+#define __AKANTU_MESH_GEOM_FACTORY_HH__
+
+#include "aka_common.hh"
+#include "mesh.hh"
+#include "mesh_geom_abstract.hh"
+#include "tree_type_helper.hh"
+#include "geom_helper_functions.hh"
+
+#include <algorithm>
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/**
+ * @brief Class used to construct AABB tree for intersection computations
+ *
+ * This class constructs a CGAL AABB tree of one type of element in a mesh
+ * for fast intersection computations.
+ */
+template<UInt dim, ElementType el_type, class Primitive, class Kernel>
+class MeshGeomFactory : public MeshGeomAbstract {
+
+public:
+ /// Construct from mesh
+ explicit MeshGeomFactory(Mesh & mesh);
+
+ /// Desctructor
+ virtual ~MeshGeomFactory();
+
+public:
+ /// Construct AABB tree for fast intersection computing
+ virtual void constructData(GhostType ghost_type = _not_ghost);
+
+ /**
+ * @brief Construct a primitive and add it to a list of primitives
+ *
+ * This function needs to be specialized for every type that is wished to be supported.
+ * @param node_coordinates coordinates of the nodes making up the element
+ * @param id element number
+ * @param list the primitive list (not used inside MeshGeomFactory)
+ */
+ inline void addPrimitive(
+ const Matrix<Real> & node_coordinates,
+ UInt id,
+ typename TreeTypeHelper<Primitive, Kernel>::container_type & list
+ );
+
+ inline void addPrimitive(
+ const Matrix<Real> & node_coordinates,
+ UInt id
+ );
+
+ /// Getter for the AABB tree
+ const typename TreeTypeHelper<Primitive, Kernel>::tree & getTree() const { return *data_tree; }
+
+ /// Getter for primitive list
+ const typename TreeTypeHelper<Primitive, Kernel>::container_type & getPrimitiveList() const
+ { return primitive_list; }
+
+protected:
+ /// AABB data tree
+ typename TreeTypeHelper<Primitive, Kernel>::tree * data_tree;
+
+ /// Primitive list
+ typename TreeTypeHelper<Primitive, Kernel>::container_type primitive_list;
+};
+
+__END_AKANTU__
+
+#include "mesh_geom_factory_tmpl.hh"
+
+
+#endif // __AKANTU_MESH_GEOM_FACTORY_HH__
diff --git a/src/geometry/mesh_geom_factory_tmpl.hh b/src/geometry/mesh_geom_factory_tmpl.hh
new file mode 100644
index 000000000..222654b94
--- /dev/null
+++ b/src/geometry/mesh_geom_factory_tmpl.hh
@@ -0,0 +1,257 @@
+/**
+ * @file mesh_geom_factory_tmpl.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Thu Feb 26 2015
+ * @date last modification: Fri Mar 6 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/>.
+ *
+ */
+
+#ifndef __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
+#define __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
+
+/* -------------------------------------------------------------------------- */
+
+#include "aka_common.hh"
+#include "mesh_geom_common.hh"
+#include "mesh_geom_factory.hh"
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+template<UInt dim, ElementType type, class Primitive, class Kernel>
+MeshGeomFactory<dim, type, Primitive, Kernel>::MeshGeomFactory(Mesh & mesh) :
+ MeshGeomAbstract(mesh),
+ data_tree(NULL),
+ primitive_list()
+{}
+
+template<UInt dim, ElementType type, class Primitive, class Kernel>
+MeshGeomFactory<dim, type, Primitive, Kernel>::~MeshGeomFactory() {
+ delete data_tree;
+}
+
+/**
+ * This function loops over the elements of `type` in the mesh and creates the
+ * AABB tree of geometrical primitves (`data_tree`).
+ */
+template<UInt dim, ElementType type, class Primitive, class Kernel>
+void MeshGeomFactory<dim, type, Primitive, Kernel>::constructData(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ primitive_list.clear();
+ UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
+
+ const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
+ const Array<Real> & nodes = mesh.getNodes();
+
+ UInt el_index = 0;
+ Array<UInt>::const_vector_iterator it = connectivity.begin(nb_nodes_per_element);
+ Array<UInt>::const_vector_iterator end = connectivity.end(nb_nodes_per_element);
+
+ Matrix<Real> node_coordinates(dim, nb_nodes_per_element);
+
+ // This loop builds the list of primitives
+ for (; it != end ; ++it, ++el_index) {
+ const Vector<UInt> & el_connectivity = *it;
+
+ for (UInt i = 0 ; i < nb_nodes_per_element ; i++)
+ for (UInt j = 0 ; j < dim ; j++)
+ node_coordinates(j, i) = nodes(el_connectivity(i), j);
+
+ // the unique elemental id assigned to the primitive is the
+ // linearized element index over ghost type
+ addPrimitive(node_coordinates, el_index);
+ }
+
+ delete data_tree;
+
+ // This condition allows the use of the mesh geom module
+ // even if types are not compatible with AABB tree algorithm
+ if (TreeTypeHelper<Primitive, Kernel>::is_valid)
+ data_tree = new typename TreeTypeHelper<Primitive, Kernel>::tree(primitive_list.begin(), primitive_list.end());
+
+ AKANTU_DEBUG_OUT();
+}
+
+template<UInt dim, ElementType type, class Primitive, class Kernel>
+void MeshGeomFactory<dim, type, Primitive, Kernel>::addPrimitive(const Matrix<Real> & node_coordinates,
+ UInt id) {
+ this->addPrimitive(node_coordinates, id, this->primitive_list);
+}
+
+// (2D, _triangle_3) decomposed into Triangle<Cartesian>
+template<>
+inline void MeshGeomFactory<2, _triangle_3, Triangle<Cartesian>, Cartesian>::addPrimitive(
+ const Matrix<Real> & node_coordinates,
+ UInt id,
+ TreeTypeHelper<Triangle<Cartesian>, Cartesian>::container_type & list) {
+
+ TreeTypeHelper<Triangle<Cartesian>, Cartesian>::point_type
+ a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+
+ Triangle<Cartesian> t(a, b, c);
+ t.setId(id);
+ list.push_back(t);
+}
+
+// (2D, _triangle_6) decomposed into Triangle<Cartesian>
+template<>
+inline void MeshGeomFactory<2, _triangle_6, Triangle<Cartesian>, Cartesian>::addPrimitive(
+ const Matrix<Real> & node_coordinates,
+ UInt id,
+ TreeTypeHelper<Triangle<Cartesian>, Cartesian>::container_type & list) {
+
+ TreeTypeHelper<Triangle<Cartesian>, Cartesian>::point_type
+ a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+
+ Triangle<Cartesian> t(a, b, c);
+ t.setId(id);
+ list.push_back(t);
+}
+
+// (2D, _triangle_3) decomposed into Line_arc<Spherical>
+template<>
+inline void MeshGeomFactory<2, _triangle_3, Line_arc<Spherical>, Spherical>::addPrimitive(
+ const Matrix<Real> & node_coordinates,
+ UInt id,
+ TreeTypeHelper<Line_arc<Spherical>, Spherical>::container_type & list) {
+
+ TreeTypeHelper<Line_arc<Spherical>, Spherical>::point_type
+ a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+
+ /*std::cout << "elem " << id << " node 1 : x_node=" << node_coordinates(0, 0)
+ << ", x_arc_node=" << a.x() << ", y_node=" << node_coordinates(1, 0)
+ << ", y_arc_node=" << a.y() << std::endl ;
+ std::cout << "elem " << id << " node 2 : x_node=" << node_coordinates(0, 1)
+ << ", x_arc_node=" << b.x() << ", y_node=" << node_coordinates(1, 1)
+ << ", y_arc_node=" << b.y() << std::endl ;
+ std::cout << "elem " << id << " node 2 : x_node=" << node_coordinates(0, 2)
+ << ", x_arc_node=" << c.x() << ", y_node=" << node_coordinates(1, 2)
+ << ", y_arc_node=" << c.y() << std::endl ;*/
+
+ CGAL::Line_3<Spherical> l1(a, b), l2(b, c), l3(c, a);
+ Line_arc<Spherical> s1(l1,a, b), s2(l2, b, c), s3(l3, c, a);
+
+ s1.setId(id); s1.setSegId(0);
+ s2.setId(id); s2.setSegId(1);
+ s3.setId(id); s3.setSegId(2);
+
+ list.push_back(s1);
+ list.push_back(s2);
+ list.push_back(s3);
+}
+
+#if defined(AKANTU_IGFEM)
+
+// (2D, _igfem_triangle_4) decomposed into Line_arc<Spherical>
+template<>
+inline void MeshGeomFactory<2, _igfem_triangle_4, Line_arc<Spherical>, Spherical>::addPrimitive(
+ const Matrix<Real> & node_coordinates,
+ UInt id,
+ TreeTypeHelper<Line_arc<Spherical>, Spherical>::container_type & list) {
+
+ TreeTypeHelper<Line_arc<Spherical>, Spherical>::point_type
+ a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+
+ CGAL::Line_3<Spherical> l1(a, b), l2(b, c), l3(c, a);
+ Line_arc<Spherical> s1(l1,a, b), s2(l2, b, c), s3(l3, c, a);
+
+ s1.setId(id); s1.setSegId(0);
+ s2.setId(id); s2.setSegId(1);
+ s3.setId(id); s3.setSegId(2);
+
+ list.push_back(s1);
+ list.push_back(s2);
+ list.push_back(s3);
+}
+
+// (2D, _igfem_triangle_4) decomposed into Line_arc<Spherical>
+template<>
+inline void MeshGeomFactory<2, _igfem_triangle_5, Line_arc<Spherical>, Spherical>::addPrimitive(
+ const Matrix<Real> & node_coordinates,
+ UInt id,
+ TreeTypeHelper<Line_arc<Spherical>, Spherical>::container_type & list) {
+
+ TreeTypeHelper<Line_arc<Spherical>, Spherical>::point_type
+ a(node_coordinates(0, 0), node_coordinates(1, 0), 0.),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), 0.),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), 0.);
+
+ CGAL::Line_3<Spherical> l1(a, b), l2(b, c), l3(c, a);
+ Line_arc<Spherical> s1(l1,a, b), s2(l2, b, c), s3(l3, c, a);
+
+ s1.setId(id); s1.setSegId(0);
+ s2.setId(id); s2.setSegId(1);
+ s3.setId(id); s3.setSegId(2);
+
+ list.push_back(s1);
+ list.push_back(s2);
+ list.push_back(s3);
+}
+
+#endif
+
+// (3D, _tetrahedron_4) decomposed into Triangle<Cartesian>
+template<>
+inline void MeshGeomFactory<3, _tetrahedron_4, Triangle<Cartesian>, Cartesian>::addPrimitive(
+ const Matrix<Real> & node_coordinates,
+ UInt id,
+ TreeTypeHelper<Triangle<Cartesian>, Cartesian>::container_type & list) {
+
+ TreeTypeHelper<Triangle<Cartesian>, Cartesian>::point_type
+ a(node_coordinates(0, 0), node_coordinates(1, 0), node_coordinates(2, 0)),
+ b(node_coordinates(0, 1), node_coordinates(1, 1), node_coordinates(2, 1)),
+ c(node_coordinates(0, 2), node_coordinates(1, 2), node_coordinates(2, 2)),
+ d(node_coordinates(0, 3), node_coordinates(1, 3), node_coordinates(2, 3));
+
+ Triangle<Cartesian>
+ t1(a, b, c),
+ t2(b, c, d),
+ t3(c, d, a),
+ t4(d, a, b);
+
+ t1.setId(id);
+ t2.setId(id);
+ t3.setId(id);
+ t4.setId(id);
+
+ list.push_back(t1);
+ list.push_back(t2);
+ list.push_back(t3);
+ list.push_back(t4);
+}
+
+__END_AKANTU__
+
+#endif // __AKANTU_MESH_GEOM_FACTORY_TMPL_HH__
diff --git a/src/geometry/mesh_geom_intersector.hh b/src/geometry/mesh_geom_intersector.hh
new file mode 100644
index 000000000..5fd3bfb2e
--- /dev/null
+++ b/src/geometry/mesh_geom_intersector.hh
@@ -0,0 +1,70 @@
+/**
+ * @file mesh_geom_intersector.hh
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Wed Apr 29 2015
+ * @date last modification: Wed Apr 29 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MESH_GEOM_INTERSECTOR_HH__
+#define __AKANTU_MESH_GEOM_INTERSECTOR_HH__
+
+#include "aka_common.hh"
+#include "mesh_abstract_intersector.hh"
+#include "mesh_geom_factory.hh"
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/**
+ * @brief Class used to perform intersections on a mesh and construct output data
+ */
+template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
+class MeshGeomIntersector : public MeshAbstractIntersector<Query> {
+
+public:
+ /// Construct from mesh
+ explicit MeshGeomIntersector(Mesh & mesh);
+
+ /// Destructor
+ virtual ~MeshGeomIntersector();
+
+public:
+ /// Construct the primitive tree object
+ virtual void constructData(GhostType ghost_type = _not_ghost);
+
+protected:
+ /// Factory object containing the primitive tree
+ MeshGeomFactory<dim, type, Primitive, Kernel> factory;
+};
+
+__END_AKANTU__
+
+#include "mesh_geom_intersector_tmpl.hh"
+
+#endif // __AKANTU_MESH_GEOM_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_geom_intersector_tmpl.hh b/src/geometry/mesh_geom_intersector_tmpl.hh
new file mode 100644
index 000000000..134b170fa
--- /dev/null
+++ b/src/geometry/mesh_geom_intersector_tmpl.hh
@@ -0,0 +1,62 @@
+/**
+ * @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
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
+#define __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
+
+#include "aka_common.hh"
+#include "mesh_geom_intersector.hh"
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
+MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::MeshGeomIntersector(Mesh & mesh) :
+MeshAbstractIntersector<Query>(mesh),
+factory(mesh)
+{}
+
+template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
+MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::~MeshGeomIntersector()
+{}
+
+template<UInt dim, ElementType type, class Primitive, class Query, class Kernel>
+void MeshGeomIntersector<dim, type, Primitive, Query, Kernel>::constructData(GhostType ghost_type) {
+ this->intersection_points->resize(0);
+ factory.constructData(ghost_type);
+}
+
+__END_AKANTU__
+
+#endif // __AKANTU_MESH_GEOM_INTERSECTOR_TMPL_HH__
+
diff --git a/src/geometry/mesh_segment_intersector.hh b/src/geometry/mesh_segment_intersector.hh
new file mode 100644
index 000000000..48a20ee9b
--- /dev/null
+++ b/src/geometry/mesh_segment_intersector.hh
@@ -0,0 +1,101 @@
+/**
+ * @file mesh_segment_intersector.hh
+ *
+ * @author Lucas Frerot
+ *
+ * @date creation: Wed Apr 29 2015
+ * @date last modification: Wed Apr 29 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..ca1cdcaea
--- /dev/null
+++ b/src/geometry/mesh_segment_intersector_tmpl.hh
@@ -0,0 +1,268 @@
+/**
+ * @file mesh_segment_intersector_tmpl.hh
+ *
+ * @author Lucas Frerot
+ *
+ * @date creation: Wed Apr 29 2015
+ * @date last modification: Wed Apr 29 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..487d1827e
--- /dev/null
+++ b/src/geometry/mesh_sphere_intersector.hh
@@ -0,0 +1,101 @@
+/**
+ * @file mesh_sphere_intersector.hh
+ *
+ * @author Clement Roux-Langlois <clement.roux@epfl.ch>
+ *
+ * @date creation: Wed Jun 10 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
+#define __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
+
+#include "aka_common.hh"
+#include "mesh_geom_intersector.hh"
+
+#include "mesh_geom_common.hh"
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/// Here, we know what kernel we have to use
+typedef Spherical SK;
+
+template<UInt dim, ElementType type>
+class MeshSphereIntersector : public MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK> {
+ /// Parent class type
+ typedef MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK> parent_type;
+
+ /// Result of intersection function type
+ typedef typename IntersectionTypeHelper<TreeTypeHelper< Triangle<K>, K>, K::Segment_3>::intersection_type result_type;
+
+ /// Pair of intersection points and element id
+ typedef std::pair<SK::Circular_arc_point_3, UInt> pair_type;
+
+public:
+ /// Construct from mesh
+ explicit MeshSphereIntersector(Mesh & mesh);
+
+ /// Destructor
+ virtual ~MeshSphereIntersector();
+
+public:
+ /// Construct the primitive tree object
+ virtual void constructData(GhostType ghost_type = _not_ghost);
+
+ /**
+ * @brief Computes the intersection of the mesh with a sphere
+ *
+ * @param query (sphere) to compute the intersections with the mesh
+ */
+ virtual void computeIntersectionQuery(const SK::Sphere_3 & query){
+ AKANTU_DEBUG_ERROR("This function is not implemented for spheres (It was to generic and has been replaced by computeMeshQueryIntersectionPoint");
+ }
+
+ /// Compute intersection points between the mesh primitives (segments) and a query (surface in 3D or a curve in 2D), double intersection points for the same primitives are not considered. A maximum is set to the number of intersection nodes per element: 2 in 2D and 4 in 3D
+ virtual void computeMeshQueryIntersectionPoint(const SK::Sphere_3 & query, UInt nb_old_nodes);
+
+ /// Build the IGFEM mesh
+ virtual void buildResultFromQueryList(const std::list<SK::Sphere_3> & query){
+ AKANTU_DEBUG_ERROR("This function is no longer implemented to split geometrical operations and dedicated result construction");
+ }
+
+ /// Set the tolerance
+ void setToleranceIntersectionOnNode(UInt tol) {
+ this->tol_intersection_on_node = tol;
+ }
+
+protected:
+ /// tolerance for which the intersection is considered on the mesh node (relative to the segment lenght)
+ Real tol_intersection_on_node;
+
+};
+
+__END_AKANTU__
+
+#include "mesh_sphere_intersector_tmpl.hh"
+
+#endif // __AKANTU_MESH_SPHERE_INTERSECTOR_HH__
diff --git a/src/geometry/mesh_sphere_intersector_tmpl.hh b/src/geometry/mesh_sphere_intersector_tmpl.hh
new file mode 100644
index 000000000..72ad9f6fa
--- /dev/null
+++ b/src/geometry/mesh_sphere_intersector_tmpl.hh
@@ -0,0 +1,193 @@
+/**
+ * @file mesh_sphere_intersector_tmpl.hh
+ *
+ * @author Clément Roux-Langlois <clement.roux@epfl.ch>
+ *
+ * @date creation: Wed june 10 2015
+ * @date last modification: Wed June 17 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
+#define __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
+
+#include "aka_common.hh"
+#include "mesh_geom_common.hh"
+#include "tree_type_helper.hh"
+#include "mesh_sphere_intersector.hh"
+#include "static_communicator.hh"
+
+__BEGIN_AKANTU__
+
+template<UInt dim, ElementType type>
+MeshSphereIntersector<dim, type>::MeshSphereIntersector(Mesh & mesh):
+ parent_type(mesh),
+ tol_intersection_on_node(1e-10)
+{
+#if defined(AKANTU_IGFEM)
+ if( (type == _triangle_3) || (type == _igfem_triangle_4) || (type == _igfem_triangle_5) ){
+ const_cast<UInt &>(this->nb_seg_by_el) = 3;
+ } else {
+ AKANTU_DEBUG_ERROR("Not ready for mesh type " << type);
+ }
+#else
+ if( (type != _triangle_3) )
+ AKANTU_DEBUG_ERROR("Not ready for mesh type " << type);
+#endif
+
+ // initialize the intersection pointsss array with the spatial dimension
+ this->intersection_points = new Array<Real>(0,dim);
+ // A maximum is set to the number of intersection nodes per element to limit the size of new_node_per_elem: 2 in 2D and 4 in 3D
+ this->new_node_per_elem = new Array<UInt>(0, 1 + 4 * (dim-1));
+}
+
+template<UInt dim, ElementType type>
+MeshSphereIntersector<dim, type>::~MeshSphereIntersector() {
+ delete this->new_node_per_elem;
+ delete this->intersection_points;
+}
+
+template<UInt dim, ElementType type>
+void MeshSphereIntersector<dim, type>::constructData(GhostType ghost_type) {
+
+ this->new_node_per_elem->resize(this->mesh.getNbElement(type, ghost_type));
+ this->new_node_per_elem->clear();
+
+ MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK>::constructData(ghost_type);
+}
+
+template<UInt dim, ElementType type>
+void MeshSphereIntersector<dim, type>:: computeMeshQueryIntersectionPoint(const SK::Sphere_3 & query,
+ UInt nb_old_nodes) {
+ /// function to replace computeIntersectionQuery in a more generic geometry module version
+ // The newNodeEvent is not send from this method who only compute the intersection points
+ AKANTU_DEBUG_IN();
+
+ Array<Real> & nodes = this->mesh.getNodes();
+ UInt nb_node = nodes.getSize() + this->intersection_points->getSize();
+
+ // Tolerance for proximity checks should be defined by user
+ Real global_tolerance = Math::getTolerance();
+ Math::setTolerance(tol_intersection_on_node);
+ typedef boost::variant<pair_type> sk_inter_res;
+
+ TreeTypeHelper<Line_arc<Spherical>, Spherical>::const_iterator
+ it = this->factory.getPrimitiveList().begin(),
+ end= this->factory.getPrimitiveList().end();
+
+ for (; it != end ; ++it) { // loop on the primitives (segments)
+ std::list<sk_inter_res> s_results;
+ CGAL::intersection(*it, query, std::back_inserter(s_results));
+
+ if (s_results.size() == 1) { // just one point
+ if (pair_type * pair = boost::get<pair_type>(&s_results.front())) {
+ if (pair->second == 1) { // not a point tangent to the sphere
+ // the intersection point written as a vector
+ Vector<Real> new_node(dim, 0.0);
+ Cartesian::Point_3 point(CGAL::to_double(pair->first.x()),
+ CGAL::to_double(pair->first.y()),
+ CGAL::to_double(pair->first.z()));
+ for (UInt i = 0 ; i < dim ; i++) {
+ new_node(i) = point[i];
+ }
+
+ /// boolean to decide wheter intersection point is on a standard node of the mesh or not
+ bool is_on_mesh = false;
+ /// boolean to decide if this intersection point has been already computed for a neighbor element
+ bool is_new = true;
+
+ /// check if intersection point has already been computed
+ UInt n = nb_old_nodes;
+
+ // check if we already compute this intersection and add it as a node for a neighboor element of another type
+ Array<Real>::vector_iterator existing_node = nodes.begin(dim);
+
+ for (; n < nodes.getSize() ; ++n) {// loop on the nodes from nb_old_nodes
+ if (Math::are_vector_equal(dim, new_node.storage(), existing_node[n].storage())) {
+ is_new = false;
+ break;
+ }
+ }
+ if(is_new){
+ Array<Real>::vector_iterator intersection_points_it = this->intersection_points->begin(dim);
+ Array<Real>::vector_iterator intersection_points_end = this->intersection_points->end(dim);
+ for (; intersection_points_it != intersection_points_end ; ++intersection_points_it, ++n) {
+ if (Math::are_vector_equal(dim, new_node.storage(), intersection_points_it->storage())) {
+ is_new = false;
+ break;
+ }
+ }
+ }
+
+ // get the initial and final points of the primitive (segment) and write them as vectors
+ Cartesian::Point_3 source_cgal(CGAL::to_double(it->source().x()),
+ CGAL::to_double(it->source().y()),
+ CGAL::to_double(it->source().z()));
+ Cartesian::Point_3 target_cgal(CGAL::to_double(it->target().x()),
+ CGAL::to_double(it->target().y()),
+ CGAL::to_double(it->target().z()));
+ Vector<Real> source(dim), target(dim);
+ for (UInt i = 0 ; i < dim ; i++) {
+ source(i) = source_cgal[i];
+ target(i) = target_cgal[i];
+ }
+
+ // Check if we are close from a node of the primitive (segment)
+ if (Math::are_vector_equal(dim, source.storage(), new_node.storage()) ||
+ Math::are_vector_equal(dim, target.storage(), new_node.storage())) {
+ is_on_mesh = true;
+ is_new = false;
+ }
+
+ if (is_new) {// if the intersection point is a new one add it to the list
+ this->intersection_points->push_back(new_node);
+ nb_node++;
+ }
+
+ // deduce the element id
+ UInt element_id = it->id();
+
+ // fill the new_node_per_elem array
+ if (!is_on_mesh) { // if the node is not on a mesh node
+ UInt & nb_new_nodes_per_el = (*this->new_node_per_elem)(element_id, 0);
+ nb_new_nodes_per_el += 1;
+ AKANTU_DEBUG_ASSERT(2 * nb_new_nodes_per_el < this->new_node_per_elem->getNbComponent(),
+ "You might have to interface crossing the same material");
+ (*this->new_node_per_elem)(element_id, (2 * nb_new_nodes_per_el) - 1) = n;
+ (*this->new_node_per_elem)(element_id, 2 * nb_new_nodes_per_el) = it->segId();
+ }
+ }
+ }
+ }
+ }
+
+ Math::setTolerance(global_tolerance);
+
+ AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
+
+#endif // __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
diff --git a/src/geometry/tree_type_helper.hh b/src/geometry/tree_type_helper.hh
new file mode 100644
index 000000000..1f5132501
--- /dev/null
+++ b/src/geometry/tree_type_helper.hh
@@ -0,0 +1,111 @@
+/**
+ * @file tree_type_helper.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Fri Feb 27 2015
+ * @date last modification: Thu Mar 5 2015
+ *
+ * @brief Converts element types of a mesh to CGAL primitive 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_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 c7a3ce3a2..749e6a151 100644
--- a/src/io/dumper/dumpable.cc
+++ b/src/io/dumper/dumpable.cc
@@ -1,284 +1,310 @@
/**
* @file dumpable.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Fri Sep 05 2014
* @date last modification: Fri Sep 05 2014
*
* @brief Implementation of the dumpable 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 "dumpable.hh"
+/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
+#include <io_helper.hh>
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
Dumpable::Dumpable() : default_dumper("") {
}
/* -------------------------------------------------------------------------- */
Dumpable::~Dumpable() {
+
+ DumperMap::iterator it = dumpers.begin();
+ DumperMap::iterator end = dumpers.end();
+
+ for (; it != end; ++it){
+ delete it->second;
+ }
}
/* -------------------------------------------------------------------------- */
void Dumpable::registerExternalDumper(DumperIOHelper & dumper,
const std::string & dumper_name,
const bool is_default) {
this->dumpers[dumper_name] = &dumper;
if (is_default)
this->default_dumper = dumper_name;
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpMesh(const Mesh & mesh, UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
this->addDumpMeshToDumper(this->default_dumper,
mesh,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpMeshToDumper(const std::string & dumper_name,
const Mesh & mesh, UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerMesh(mesh,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
this->addDumpFilteredMeshToDumper(this->default_dumper,
mesh,
elements_filter,
nodes_filter,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFilteredMeshToDumper(const std::string & dumper_name,
const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerFilteredMesh(mesh,
elements_filter,
nodes_filter,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpField(const std::string & field_id) {
this->addDumpFieldToDumper(this->default_dumper, field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id) {
AKANTU_DEBUG_TO_IMPLEMENT();
};
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldExternal(const std::string & field_id,
dumper::Field * field) {
this->addDumpFieldExternalToDumper(this->default_dumper, field_id, field);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerField(field_id, field);
}
/* -------------------------------------------------------------------------- */
void Dumpable::removeDumpField(const std::string & field_id) {
this->removeDumpFieldFromDumper(this->default_dumper, field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::removeDumpFieldFromDumper(const std::string & dumper_name,
const std::string & field_id) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.unRegisterField(field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldVector(const std::string & field_id) {
this->addDumpFieldVectorToDumper(this->default_dumper, field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldTensor(const std::string & field_id) {
this->addDumpFieldTensorToDumper(this->default_dumper, field_id);
}
/* -------------------------------------------------------------------------- */
void Dumpable::addDumpFieldTensorToDumper(const std::string & dumper_name,
const std::string & field_id) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
void Dumpable::setDirectory(const std::string & directory) {
this->setDirectoryToDumper(this->default_dumper, directory);
};
/* -------------------------------------------------------------------------- */
void Dumpable::setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.setDirectory(directory);
}
/* -------------------------------------------------------------------------- */
void Dumpable::setBaseName(const std::string & basename) {
this->setBaseNameToDumper(this->default_dumper, basename);
}
/* -------------------------------------------------------------------------- */
void Dumpable::setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.setBaseName(basename);
}
/* -------------------------------------------------------------------------- */
void Dumpable::setTimeStepToDumper(Real time_step) {
this->setTimeStepToDumper(this->default_dumper, time_step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::setTimeStepToDumper(const std::string & dumper_name,
- Real time_step) {
+ Real time_step) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.setTimeStep(time_step);
};
/* -------------------------------------------------------------------------- */
+
+void Dumpable::setTextModeToDumper(const std::string & dumper_name) {
+ DumperIOHelper & dumper = this->getDumper(dumper_name);
+ dumper.getDumper().setMode(iohelper::TEXT);
+};
+
+
+/* -------------------------------------------------------------------------- */
+void Dumpable::setTextModeToDumper() {
+ DumperIOHelper & dumper = this->getDumper(this->default_dumper);
+ dumper.getDumper().setMode(iohelper::TEXT);
+};
+
+
+/* -------------------------------------------------------------------------- */
+
void Dumpable::dump(const std::string & dumper_name) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.dump();
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump() {
this->dump(this->default_dumper);
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump(const std::string & dumper_name, UInt step) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.dump(step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump(UInt step) {
this->dump(this->default_dumper, step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump(const std::string & dumper_name, Real time, UInt step) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.dump(time, step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::dump(Real time, UInt step) {
this->dump(this->default_dumper, time, step);
}
/* -------------------------------------------------------------------------- */
void Dumpable::internalAddDumpFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
dumper::Field * field) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerField(field_id, field);
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Dumpable::getDumper() {
return this->getDumper(this->default_dumper);
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Dumpable::getDumper(const std::string & dumper_name) {
DumperMap::iterator it = this->dumpers.find(dumper_name);
DumperMap::iterator end = this->dumpers.end();
if (it == end)
AKANTU_EXCEPTION("Dumper " << dumper_name << "has not been registered, yet.");
return *(it->second);
}
/* -------------------------------------------------------------------------- */
std::string Dumpable::getDefaultDumperName() const {
return this->default_dumper;
}
__END_AKANTU__
#endif
diff --git a/src/io/dumper/dumpable.hh b/src/io/dumper/dumpable.hh
index e13564320..6051ed11d 100644
--- a/src/io/dumper/dumpable.hh
+++ b/src/io/dumper/dumpable.hh
@@ -1,410 +1,48 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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"
-#ifdef AKANTU_USE_IOHELPER
-#include "dumper_iohelper.hh"
-#endif //AKANTU_USE_IOHELPER
+/* -------------------------------------------------------------------------- */
+
#ifndef __AKANTU_DUMPABLE_HH__
#define __AKANTU_DUMPABLE_HH__
-/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
-
-#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);
-
- 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;
-
- DumperSet external_dumpers;
-};
-
-__END_AKANTU__
-
+# include "dumpable_iohelper.hh"
#else
-
-__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 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__
-
+# include "dumpable_dummy.hh"
#endif //AKANTU_USE_IOHELPER
-//#include "dumpable_inline_impl.hh"
-
#endif /* __AKANTU_DUMPABLE_HH__ */
diff --git a/src/io/dumper/dumpable_dummy.hh b/src/io/dumper/dumpable_dummy.hh
new file mode 100644
index 000000000..ec8018af5
--- /dev/null
+++ b/src/io/dumper/dumpable_dummy.hh
@@ -0,0 +1,251 @@
+/**
+ * @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
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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 305a6024f..b58a7b53a 100644
--- a/src/io/dumper/dumpable_inline_impl.hh
+++ b/src/io/dumper/dumpable_inline_impl.hh
@@ -1,140 +1,147 @@
/**
* @file dumpable_inline_impl.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Mon Sep 15 2014
*
* @brief Implementation of the Dumpable 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/>.
*
*/
#ifndef __AKANTU_DUMPABLE_INLINE_IMPL_HH__
#define __AKANTU_DUMPABLE_INLINE_IMPL_HH__
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
#include "dumper_elemental_field.hh"
#include "dumper_nodal_field.hh"
/* -------------------------------------------------------------------------- */
-
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<class T>
inline void Dumpable::registerDumper(const std::string & dumper_name,
const std::string & file_name,
const bool is_default) {
- AKANTU_DEBUG_ASSERT(this->dumpers.find(dumper_name) ==
- this->dumpers.end(),
- "Dumper " + dumper_name + "is already registered.");
+ if (this->dumpers.find(dumper_name) != this->dumpers.end()){
+ AKANTU_DEBUG_INFO("Dumper " + dumper_name + "is already registered.");
+ }
std::string name = file_name;
if (name == "")
name = dumper_name;
this->dumpers[dumper_name] = new T(name);
if (is_default)
this->default_dumper = dumper_name;
}
/* -------------------------------------------------------------------------- */
-
template<typename T>
inline void Dumpable::addDumpFieldExternal(const std::string & field_id,
const Array<T> & field) {
this->addDumpFieldExternalToDumper<T>(this->default_dumper,
field_id,
field);
};
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Dumpable::addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
const Array<T> & field) {
dumper::Field * field_cont = new dumper::NodalField<T>(field);
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerField(field_id, field_cont);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Dumpable::addDumpFieldExternal(const std::string & field_id,
const ElementTypeMapArray<T> & field,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
this->addDumpFieldExternalToDumper(this->default_dumper,
field_id,
field,
spatial_dimension,
ghost_type,
element_kind);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Dumpable::addDumpFieldExternalToDumper(const std::string & dumper_name,
const std::string & field_id,
const ElementTypeMapArray<T> & field,
UInt spatial_dimension,
const GhostType & ghost_type,
const ElementKind & element_kind) {
- dumper::Field * field_cont = new dumper::ElementalField<T>(field,
- spatial_dimension,
- ghost_type,
- element_kind);
+
+ dumper::Field * field_cont;
+#if defined(AKANTU_IGFEM)
+ if (element_kind == _ek_igfem) {
+ field_cont = new dumper::IGFEMElementalField<T>(field,
+ spatial_dimension,
+ ghost_type,
+ element_kind);
+ } else
+#endif
+ field_cont = new dumper::ElementalField<T>(field,
+ spatial_dimension,
+ ghost_type,
+ element_kind);
DumperIOHelper & dumper = this->getDumper(dumper_name);
dumper.registerField(field_id, field_cont);
}
/* -------------------------------------------------------------------------- */
template<class T>
inline T & Dumpable::getDumper(const std::string & dumper_name) {
DumperIOHelper & dumper = this->getDumper(dumper_name);
try {
T & templated_dumper = dynamic_cast<T & >(dumper);
return templated_dumper;
}
catch (...) {
AKANTU_EXCEPTION("Dumper " << dumper_name << " is not of type: "
<< debug::demangle(typeid(T).name()));
}
}
-
-
+/* -------------------------------------------------------------------------- */
__END_AKANTU__
#endif
#endif /* __AKANTU_DUMPABLE_INLINE_IMPL_HH__ */
diff --git a/src/io/dumper/dumpable_iohelper.hh b/src/io/dumper/dumpable_iohelper.hh
new file mode 100644
index 000000000..b08f104cd
--- /dev/null
+++ b/src/io/dumper/dumpable_iohelper.hh
@@ -0,0 +1,195 @@
+/**
+ * @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
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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 6cf89b606..13f1dc4e9 100644
--- a/src/io/dumper/dumper_compute.hh
+++ b/src/io/dumper/dumper_compute.hh
@@ -1,312 +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
*
* @brief Field that map a function to another 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_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"
+#include <io_helper.hh>
+
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
class ComputeFunctorInterface {
-
public:
-
virtual ~ComputeFunctorInterface(){};
virtual UInt getDim() = 0;
virtual UInt getNbComponent(UInt old_nb_comp) = 0;
-
};
/* -------------------------------------------------------------------------- */
template <typename return_type>
class ComputeFunctorOutput : public ComputeFunctorInterface {
-
public:
-
ComputeFunctorOutput(){};
virtual ~ComputeFunctorOutput(){};
-
};
-
/* -------------------------------------------------------------------------- */
-
template <typename input_type,typename return_type>
class ComputeFunctor : public ComputeFunctorOutput<return_type> {
-
public:
-
ComputeFunctor(){};
virtual ~ComputeFunctor(){};
virtual return_type func(const input_type & d, Element global_index) = 0;
};
/* -------------------------------------------------------------------------- */
-
-
template <typename SubFieldCompute, typename _return_type>
class FieldCompute : public Field {
-
/* ------------------------------------------------------------------------ */
/* Typedefs */
- /* ------------------------------------------------------------------------ */
-
+ /* ------------------------------------------------------------------------ */
public:
-
typedef typename SubFieldCompute::iterator sub_iterator;
typedef typename SubFieldCompute::types sub_types;
typedef typename sub_types::return_type sub_return_type;
typedef _return_type return_type;
typedef typename sub_types::data_type data_type;
typedef TypeTraits<data_type, return_type, ElementTypeMapArray<data_type> > types;
class iterator {
public:
- iterator(const sub_iterator & it, ComputeFunctor<sub_return_type,return_type> & func)
+ iterator(const sub_iterator & it, ComputeFunctor<sub_return_type,return_type> & func)
: it(it), func(func) {}
-
+
bool operator!=(const iterator & it)const { return it.it != this->it; }
iterator operator++() { ++this->it; return *this; }
-
+
UInt currentGlobalIndex(){
return this->it.currentGlobalIndex();
}
return_type operator*() {
return func.func(*it,it.getCurrentElement());
}
Element getCurrentElement(){
return this->it.getCurrentElement();
}
-
+ UInt element_type() { return this->it.element_type(); }
+
protected:
sub_iterator it;
ComputeFunctor<sub_return_type,return_type> & func;
};
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
-
public:
-
FieldCompute(SubFieldCompute & cont, ComputeFunctorInterface & func)
:sub_field(cont),func(dynamic_cast<ComputeFunctor<sub_return_type,return_type> &>(func)){
this->checkHomogeneity();
};
virtual void registerToDumper(const std::string & id,
iohelper::Dumper & dumper) {
dumper.addElemDataField(id, *this);
}
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-
+public:
iterator begin() { return iterator(sub_field.begin(), func); }
iterator end () { return iterator(sub_field.end(), func); }
-
UInt getDim() {
return func.getDim();
}
-
- UInt size() {
+ UInt size() {
throw;
// return Functor::size();
return 0;
}
virtual void checkHomogeneity(){this->homogeneous = true;};
iohelper::DataType getDataType() { return iohelper::getDataType<data_type>(); }
-
/// get the number of components of the hosted field
virtual ElementTypeMap<UInt> getNbComponents(UInt dim = _all_dimensions,
GhostType ghost_type = _not_ghost,
ElementKind kind = _ek_not_defined){
-
ElementTypeMap<UInt> nb_components;
- const ElementTypeMap<UInt> & old_nb_components =
+ const ElementTypeMap<UInt> & old_nb_components =
this->sub_field.getNbComponents(dim,ghost_type,kind);
-
+
ElementTypeMap<UInt>::type_iterator tit = old_nb_components.firstType(dim,ghost_type,kind);
ElementTypeMap<UInt>::type_iterator end = old_nb_components.lastType(dim,ghost_type,kind);
while (tit != end){
UInt nb_comp = old_nb_components(*tit,ghost_type);
nb_components(*tit,ghost_type) = func.getNbComponent(nb_comp);
++tit;
}
- return nb_components;
-};
+ return nb_components;
+ };
/// for connection to a FieldCompute
inline virtual Field * connect(FieldComputeProxy & proxy);
/// for connection to a FieldCompute
virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy);
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-
public:
-
SubFieldCompute & sub_field;
ComputeFunctor<sub_return_type,return_type> & func;
-
};
+/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class FieldComputeProxy {
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
-
public:
FieldComputeProxy(ComputeFunctorInterface & func):func(func){};
-public:
-
- inline static Field * createFieldCompute(Field * field,
+ inline static Field * createFieldCompute(Field * field,
ComputeFunctorInterface & func){
-
FieldComputeProxy compute_proxy(func);
return field->connect(compute_proxy);
}
template <typename T>
Field * connectToField(T * ptr){
if (dynamic_cast<ComputeFunctorOutput<Vector<Real> > *>(&func)){
return this->connectToFunctor<Vector<Real> >(ptr);
}
else if (dynamic_cast<ComputeFunctorOutput<Vector<UInt> > *>(&func)){
return this->connectToFunctor<Vector<UInt> >(ptr);
}
else if (dynamic_cast<ComputeFunctorOutput<Matrix<UInt> > *>(&func)){
return this->connectToFunctor<Matrix<UInt> >(ptr);
}
else if (dynamic_cast<ComputeFunctorOutput<Matrix<Real> > *>(&func)){
return this->connectToFunctor<Matrix<Real> >(ptr);
}
-
else throw;
}
template <typename output, typename T>
Field * connectToFunctor(T * ptr){
- return new FieldCompute<T,output>(*ptr,func);
+ FieldCompute<T,output> * functor_ptr = new FieldCompute<T,output>(*ptr,func);
+ return functor_ptr;
}
- template <typename output, typename SubFieldCompute,
+ template <typename output, typename SubFieldCompute,
typename return_type1, typename return_type2>
Field * connectToFunctor(FieldCompute<FieldCompute<SubFieldCompute,return_type1>,
return_type2> * ptr){
throw; // return new FieldCompute<T,output>(*ptr,func);
return NULL;
}
-
- template <typename output, typename SubFieldCompute,
- typename return_type1,typename return_type2,
- typename return_type3,typename return_type4>
+ 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){
+ FieldCompute<
+ FieldCompute<
+ FieldCompute<SubFieldCompute,return_type1>,
+ return_type2>,
+ return_type3>,
+ return_type4> * ptr){
throw; // return new FieldCompute<T,output>(*ptr,func);
return NULL;
}
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-
+public:
ComputeFunctorInterface & func;
-
-};
+};
/* -------------------------------------------------------------------------- */
-
/// for connection to a FieldCompute
template <typename SubFieldCompute, typename return_type>
inline Field * FieldCompute<SubFieldCompute,return_type>
::connect(FieldComputeProxy & proxy){
-
return proxy.connectToField(this);
}
/* -------------------------------------------------------------------------- */
-
-
-
-
-
-
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_COMPUTE_HH__ */
diff --git a/src/io/dumper/dumper_connectivity_field.hh b/src/io/dumper/dumper_connectivity_field.hh
deleted file mode 100644
index a94311d8c..000000000
--- a/src/io/dumper/dumper_connectivity_field.hh
+++ /dev/null
@@ -1,162 +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 */
- /* ------------------------------------------------------------------------ */
-
-
- 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 ba3d3f3f1..d71c1064d 100644
--- a/src/io/dumper/dumper_element_iterator.hh
+++ b/src/io/dumper/dumper_element_iterator.hh
@@ -1,192 +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
*
* @brief Iterators for elemental 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_ELEMENT_ITERATOR_HH__
#define __AKANTU_DUMPER_ELEMENT_ITERATOR_HH__
/* -------------------------------------------------------------------------- */
#include "element.hh"
-#include <io_helper.hh>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template<class types, template <class> class final_iterator>
-class element_iterator :
- public iohelper::iterator<typename types::data_type,
- final_iterator<types>,
- typename types::return_type> {
+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 4dbc8bdde..3c4ed6f3d 100644
--- a/src/io/dumper/dumper_element_partition.hh
+++ b/src/io/dumper/dumper_element_partition.hh
@@ -1,122 +1,123 @@
/**
* @file dumper_element_partition.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Tue Sep 02 2014
*
* @brief ElementPartition 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__
+#ifdef AKANTU_IGFEM
+# include "dumper_igfem_element_partition.hh"
+#endif
/* -------------------------------------------------------------------------- */
-
-
template<class types>
-class element_partition_field_iterator
+class element_partition_field_iterator
: public element_iterator<types, element_partition_field_iterator> {
-public:
+
/* ------------------------------------------------------------------------ */
/* 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;
-public:
/* ------------------------------------------------------------------------ */
/* 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 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) :
+ 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 :
+class ElementPartitionField :
public GenericElementalField<SingleType<UInt,Vector,filtered>,
- element_partition_field_iterator> {
+ 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 a8adb815d..000000000
--- a/src/io/dumper/dumper_element_type.hh
+++ /dev/null
@@ -1,116 +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> {
-public:
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
- 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;
-
-public:
-
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-
- 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 */
- /* ------------------------------------------------------------------------ */
-
- 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> {
-public:
- /* ------------------------------------------------------------------------ */
- /* Typedefs */
- /* ------------------------------------------------------------------------ */
-
- 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;
-
-public:
-
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-
- 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 */
- /* ------------------------------------------------------------------------ */
-
- 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 f71d0b508..19c83c414 100644
--- a/src/io/dumper/dumper_elemental_field.hh
+++ b/src/io/dumper/dumper_elemental_field.hh
@@ -1,79 +1,79 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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> {
-
-public:
-
/* ------------------------------------------------------------------------ */
/* 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 e4613367f..1661275c0 100644
--- a/src/io/dumper/dumper_field.hh
+++ b/src/io/dumper/dumper_field.hh
@@ -1,131 +1,123 @@
/**
* @file dumper_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Wed Sep 03 2014
*
* @brief Common interface for 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_FIELD_HH__
#define __AKANTU_DUMPER_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_iohelper.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
class FieldComputeProxy;
class FieldComputeBaseInterface;
class ComputeFunctorInterface;
class HomogenizerProxy;
/* -------------------------------------------------------------------------- */
/// Field interface
class Field {
-
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
-
public:
-
Field(): homogeneous(false) {}
virtual ~Field() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
-
+public:
#ifdef AKANTU_USE_IOHELPER
/// register this to the provided dumper
- virtual void registerToDumper(const std::string & id,
- iohelper::Dumper & dumper) = 0;
+ virtual void registerToDumper(const std::string & id,
+ iohelper::Dumper & dumper) = 0;
#endif
-
+
/// set the number of data per item (used for elements fields at the moment)
virtual void setNbData(UInt nb_data){AKANTU_DEBUG_TO_IMPLEMENT();};
/// set the number of data per elem (used for elements fields at the moment)
virtual void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data){AKANTU_DEBUG_TO_IMPLEMENT();};
/// set the number of data per elem (used for elements fields at the moment)
virtual void setNbDataPerElem(UInt nb_data){AKANTU_DEBUG_TO_IMPLEMENT();};
/// get the number of components of the hosted field
- virtual ElementTypeMap<UInt> getNbComponents(){throw;};
+ virtual ElementTypeMap<UInt> getNbComponents(UInt dim = _all_dimensions,
+ GhostType ghost_type = _not_ghost,
+ ElementKind kind = _ek_not_defined){throw;};
/// for connection to a FieldCompute
inline virtual Field * connect(FieldComputeProxy & proxy){throw;};
/// for connection to a FieldCompute
inline virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy){throw;};
-
/// check if the same quantity of data for all element types
virtual void checkHomogeneity() = 0;
/// return the dumper name
std::string getGroupName(){return group_name;};
/// return the id of the field
std::string getID(){return field_id;};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
-
+public:
/// return the flag to know if the field is homogeneous/contiguous
virtual bool isHomogeneous() { return homogeneous; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-
protected:
/// the flag to know if it is homogeneous
bool homogeneous;
/// the name of the group it was associated to
std::string group_name;
/// the name of the dumper it was associated to
std::string field_id;
};
/* -------------------------------------------------------------------------- */
-
-
-
-
-
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_filtered_connectivity.hh b/src/io/dumper/dumper_filtered_connectivity.hh
index d4f102ee4..8d1fc51df 100644
--- a/src/io/dumper/dumper_filtered_connectivity.hh
+++ b/src/io/dumper/dumper_filtered_connectivity.hh
@@ -1,157 +1,150 @@
/**
* @file dumper_filtered_connectivity.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Tue Sep 02 2014
*
* @brief FilteredConnectivities 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/>.
*
*/
#include "dumper_generic_elemental_field.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <class types>
-class filtered_connectivity_field_iterator
+class filtered_connectivity_field_iterator
: public element_iterator<types, filtered_connectivity_field_iterator> {
-
-public:
-
/* ------------------------------------------------------------------------ */
/* 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;
-public:
-
/* ------------------------------------------------------------------------ */
/* 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,
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) :
+ 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 :
+class FilteredConnectivityField :
public GenericElementalField<SingleType<UInt,Vector,true>,
- filtered_connectivity_field_iterator> {
-
+ 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) :
+ 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 89e1190b5..6f35c558e 100644
--- a/src/io/dumper/dumper_generic_elemental_field.hh
+++ b/src/io/dumper/dumper_generic_elemental_field.hh
@@ -1,228 +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
*
* @brief Generic interface for elemental 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_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
-{
-
+template <class _types, template <class> class iterator_type>
+class GenericElementalField : public Field {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
-
public:
-
+ // check dumper_type_traits.hh for additional information over these types
typedef _types types;
typedef typename types::data_type data_type;
- typedef typename types::it_type it_type;
+ typedef typename types::it_type it_type;
typedef typename types::field_type field_type;
typedef typename types::array_type array_type;
typedef typename types::array_iterator array_iterator;
typedef typename field_type::type_iterator field_type_iterator;
typedef iterator_type<types> iterator;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
-
public:
-
GenericElementalField(const field_type & field,
UInt spatial_dimension = _all_dimensions,
GhostType ghost_type = _not_ghost,
- ElementKind element_kind = _ek_not_defined) :
-
- field(field), spatial_dimension(spatial_dimension),
- ghost_type(ghost_type), element_kind(element_kind) {
+ 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);
+ 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 ?
- UInt size() {
+ virtual UInt size() {
checkHomogeneity();
return this->nb_total_element;
}
/// return the iohelper datatype to be dumped
- iohelper::DataType getDataType() { return iohelper::getDataType<data_type>(); }
+ 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 field(type, ghost_type).getNbComponent();
- return nb_data_per_elem(type,this->ghost_type);
+ 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) {
+ 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){
+ inline virtual Field * connect(FieldComputeProxy & proxy) {
return proxy.connectToField(this);
}
/// for connection to a Homogenizer
- inline virtual ComputeFunctorInterface * connect(HomogenizerProxy & proxy){
+ 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);
+ 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;
+ 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);
+ 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 () {
+ 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);
+ 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;
+ 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);
+ 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);
+ 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){
+ 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__
-
+__END_AKANTU_DUMPER__ __END_AKANTU__
#endif /* __AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_homogenizing_field.hh b/src/io/dumper/dumper_homogenizing_field.hh
index cfd6cdc6f..9317030f0 100644
--- a/src/io/dumper/dumper_homogenizing_field.hh
+++ b/src/io/dumper/dumper_homogenizing_field.hh
@@ -1,226 +1,227 @@
/**
* @file dumper_homogenizing_field.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Tue Sep 02 2014
*
* @brief description of field homogenizing 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_HOMOGENIZING_FIELD_HH__
#define __AKANTU_DUMPER_HOMOGENIZING_FIELD_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_compute.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
template <typename type>
inline type typeConverter(const type & input,
Vector<typename type::value_type> & res,UInt nb_data){
throw;
return input;
}
/* -------------------------------------------------------------------------- */
template <typename type>
inline Matrix<type> typeConverter(const Matrix<type> & input,
Vector<type> & res,UInt nb_data){
Matrix<type> tmp(res.storage(),input.rows(),nb_data/input.rows());
Matrix<type> tmp2(tmp,true);
return tmp2;
}
/* -------------------------------------------------------------------------- */
template <typename type>
inline Vector<type> typeConverter(const Vector<type> & input,
Vector<type> & res,UInt nb_data){
return res;
}
/* -------------------------------------------------------------------------- */
template <typename type>
class AvgHomogenizingFunctor : public ComputeFunctor<type,type> {
/* ------------------------------------------------------------------------ */
/* Typedefs */
/* ------------------------------------------------------------------------ */
typedef typename type::value_type value_type;
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
AvgHomogenizingFunctor(ElementTypeMap<UInt> & nb_datas){
ElementTypeMap<UInt>::type_iterator tit = nb_datas.firstType();
ElementTypeMap<UInt>::type_iterator end = nb_datas.lastType();
nb_data = nb_datas(*tit);
for (;tit != end; ++tit) if (nb_data != nb_datas(*tit)) throw;
}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
virtual type func(const type & d, Element global_index){
Vector<value_type> res(this->nb_data);
if (d.size() % this->nb_data) throw;
UInt nb_to_average = d.size()/this->nb_data;
value_type * ptr = d.storage();
for (UInt i = 0; i < nb_to_average; ++i) {
Vector<value_type> tmp(ptr,this->nb_data);
res += tmp;
+ ptr += this->nb_data;
}
res /= nb_to_average;
return typeConverter(d,res,this->nb_data);
};
UInt getDim(){return nb_data;};
UInt getNbComponent(UInt old_nb_comp){
throw;
};
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// The size of data: i.e. the size of the vector to be returned
UInt nb_data;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class HomogenizerProxy {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
HomogenizerProxy(){};
public:
inline static ComputeFunctorInterface * createHomogenizer(Field & field);
template <typename T>
inline ComputeFunctorInterface * connectToField(T * field){
ElementTypeMap<UInt> nb_components = field->getNbComponents();
typedef typename T::types::return_type ret_type;
return this->instantiateHomogenizer<ret_type>(nb_components);
}
template <typename ret_type>
inline ComputeFunctorInterface *
instantiateHomogenizer(ElementTypeMap<UInt> & nb_components);
};
/* -------------------------------------------------------------------------- */
template <typename ret_type>
inline ComputeFunctorInterface * HomogenizerProxy
::instantiateHomogenizer(ElementTypeMap<UInt> & nb_components){
typedef dumper::AvgHomogenizingFunctor<ret_type> Homogenizer;
Homogenizer * foo = new Homogenizer(nb_components);
return foo;
}
template <>
inline ComputeFunctorInterface * HomogenizerProxy
::instantiateHomogenizer<Vector<iohelper::ElemType> > (ElementTypeMap<UInt> & nb_components){
throw;
return NULL;
}
/* -------------------------------------------------------------------------- */
/// for connection to a FieldCompute
template <typename SubFieldCompute, typename return_type>
inline ComputeFunctorInterface * FieldCompute<SubFieldCompute,return_type>
::connect(HomogenizerProxy & proxy){
return proxy.connectToField(this);
}
/* -------------------------------------------------------------------------- */
inline ComputeFunctorInterface * HomogenizerProxy::createHomogenizer(Field & field){
HomogenizerProxy homogenizer_proxy;
return field.connect(homogenizer_proxy);
}
/* -------------------------------------------------------------------------- */
// inline ComputeFunctorInterface & createHomogenizer(Field & field){
// HomogenizerProxy::createHomogenizer(field);
// throw;
// ComputeFunctorInterface * ptr = NULL;
// return *ptr;
// }
// /* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_HOMOGENIZING_FIELD_HH__ */
diff --git a/src/io/dumper/dumper_internal_material_field.hh b/src/io/dumper/dumper_internal_material_field.hh
new file mode 100644
index 000000000..7ed413a85
--- /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: 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_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 68be2c65a..435266e13 100644
--- a/src/io/dumper/dumper_iohelper.cc
+++ b/src/io/dumper/dumper_iohelper.cc
@@ -1,301 +1,294 @@
/**
* @file dumper_iohelper.cc
*
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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) {
+
+#if defined(AKANTU_IGFEM)
+ if (element_kind == _ek_igfem) {
registerField("connectivities",
- new dumper::CohesiveConnectivityField(mesh.getConnectivities(),
- spatial_dimension,
- ghost_type));
+ 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));
+ new dumper::ElementalField<UInt>(mesh.getConnectivities(),
+ spatial_dimension,
+ ghost_type,
+ element_kind));
+
registerField("positions",
- new dumper::NodalField<Real>(mesh.getNodes()));
+ 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);
+ 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));
-
+ new dumper::FilteredConnectivityField(*f_connectivities,
+ nodes_filter,
+ spatial_dimension,
+ ghost_type,
+ element_kind));
+
this->registerField("positions",new dumper::NodalField<Real,true>(
- mesh.getNodes(),
- 0,
- 0,
- &nodes_filter));
+ mesh.getNodes(),
+ 0,
+ 0,
+ &nodes_filter));
}
/* -------------------------------------------------------------------------- */
void DumperIOHelper::registerField(const std::string & field_id,
- dumper::Field * field) {
+ dumper::Field * field) {
Fields::iterator it = fields.find(field_id);
if(it != fields.end()) {
- AKANTU_DEBUG_WARNING("The field " << field_id
+ 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
+ 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) {
+ dumper::VariableBase * variable) {
Variables::iterator it = variables.find(variable_id);
if(it != variables.end()) {
- AKANTU_DEBUG_WARNING("The Variable " << variable_id
+ 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
+ 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; }
-
+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; }
+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
/* -------------------------------------------------------------------------- */
-iohelper::ElemType getIOHelperType(ElementType type) {
- iohelper::ElemType ioh_type = iohelper::MAX_ELEM_TYPE;
+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 1730a0046..78eaaf8a1 100644
--- a/src/io/dumper/dumper_iohelper.hh
+++ b/src/io/dumper/dumper_iohelper.hh
@@ -1,151 +1,156 @@
/**
* @file dumper_iohelper.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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; }
-
+namespace iohelper {
+ class Dumper;
+}
__BEGIN_AKANTU__
-namespace dumper { class Field; class VariableBase;}
+UInt getIOHelperType(ElementType type);
+
+namespace dumper {
+ class Field;
+ class VariableBase;
+}
class Mesh;
class DumperIOHelper {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DumperIOHelper();
virtual ~DumperIOHelper();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
-
/// register a given Mesh for the current dumper
virtual void registerMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a filtered Mesh (provided filter lists) for the current dumper
virtual void registerFilteredMesh(const Mesh & mesh,
const ElementTypeMapArray<UInt> & elements_filter,
const Array<UInt> & nodes_filter,
UInt spatial_dimension = _all_dimensions,
const GhostType & ghost_type = _not_ghost,
const ElementKind & element_kind = _ek_not_defined);
/// register a Field object identified by name and provided by pointer
void registerField(const std::string & field_id, dumper::Field * field);
/// remove the Field identified by name from managed fields
void unRegisterField(const std::string & field_id);
/// register a VariableBase object identified by name and provided by pointer
void registerVariable(const std::string & variable_id, dumper::VariableBase * variable);
/// remove a VariableBase identified by name from managed fields
void unRegisterVariable(const std::string & variable_id);
/// request dump: this calls IOHelper dump routine
virtual void dump();
/// request dump: this first set the current step and then calls IOHelper dump routine
virtual void dump(UInt step);
/// request dump: this first set the current step and current time and then calls IOHelper dump routine
virtual void dump(Real current_time, UInt step);
/// set the parallel context for IOHeper
virtual void setParallelContext(bool is_parallel);
/// set the directory where to generate the dumped files
virtual void setDirectory(const std::string & directory);
/// set the base name (needed by most IOHelper dumpers)
virtual void setBaseName(const std::string & basename);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// direct access to the iohelper::Dumper object
AKANTU_GET_MACRO(Dumper, *dumper, iohelper::Dumper &)
/// set the timestep of the iohelper::Dumper
void setTimeStep(Real time_step);
public:
/* ------------------------------------------------------------------------ */
/* Variable wrapper */
template<typename T, bool is_scal = is_scalar<T>::value>
class Variable;
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// internal iohelper::Dumper
iohelper::Dumper * dumper;
typedef std::map<std::string, dumper::Field *> Fields;
typedef std::map<std::string, dumper::VariableBase *> Variables;
/// list of registered fields to dump
Fields fields;
Variables variables;
/// dump counter
UInt count;
/// directory name
std::string directory;
/// filename prefix
std::string filename;
/// is time tracking activated in the dumper
bool time_activated;
};
__END_AKANTU__
#endif /* __AKANTU_DUMPER_IOHELPER_HH__ */
diff --git a/src/io/dumper/dumper_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 7ebd66723..000000000
--- a/src/io/dumper/dumper_material_internal_field.hh
+++ /dev/null
@@ -1,74 +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"
-/* -------------------------------------------------------------------------- */
-__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 a54fad56f..1ffecd8da 100644
--- a/src/io/dumper/dumper_material_padders.hh
+++ b/src/io/dumper/dumper_material_padders.hh
@@ -1,168 +1,290 @@
/**
* @file dumper_material_padders.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Fri Sep 19 2014
*
* @brief Material padders for plane stress/ plane strain
*
* @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_PADDERS_HH__
#define __AKANTU_DUMPER_MATERIAL_PADDERS_HH__
/* -------------------------------------------------------------------------- */
#include "dumper_padding_helper.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
__BEGIN_AKANTU_DUMPER__
/* -------------------------------------------------------------------------- */
-
-
-template<class T, class R>
-class MaterialPadder : public PadderGeneric<Vector<T>, R > {
-
+class MaterialFunctor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
-
public:
- MaterialPadder(const SolidMechanicsModel & model) :
+ MaterialFunctor(const SolidMechanicsModel & model) :
model(model),
- element_index_by_material(model.getElementIndexByMaterial()) { }
+ material_index(model.getMaterialByElement()),
+ spatial_dimension(model.getSpatialDimension()){}
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
-
/// return the material from the global element index
const Material & getMaterialFromGlobalIndex(Element global_index){
-
UInt index = global_index.getIndex();
- UInt material_id = element_index_by_material(global_index.getType())(index);
+ UInt material_id = material_index(global_index.getType())(index);
const Material & material = model.getMaterial(material_id);
return material;
}
/// return the type of the element from global index
ElementType getElementTypeFromGlobalIndex(Element global_index){
return global_index.getType();
}
protected:
-
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
/// all material padders probably need access to solid mechanics model
const SolidMechanicsModel & model;
+
/// they also need an access to the map from global ids to material id and local ids
- const ElementTypeMapArray<UInt> & element_index_by_material;
+ const ElementTypeMapArray<UInt> & material_index;
+
/// the number of data per element
const ElementTypeMapArray<UInt> nb_data_per_element;
+ UInt spatial_dimension;
+};
+
+/* -------------------------------------------------------------------------- */
+template<class T, class R>
+class MaterialPadder : public MaterialFunctor, public PadderGeneric<Vector<T>, R > {
+public:
+ MaterialPadder(const SolidMechanicsModel & model) :
+ MaterialFunctor(model) {}
};
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
-class StressPadder :
- public MaterialPadder<Real,Matrix<Real> > {
+class StressPadder : public MaterialPadder<Real, Matrix<Real> > {
public:
StressPadder(const SolidMechanicsModel & model) :
MaterialPadder<Real, Matrix<Real> >(model){
this->setPadding(3,3);
}
inline Matrix<Real> func(const Vector<Real> & in, Element global_element_id){
-
UInt nrows = spatial_dimension;
UInt ncols = in.size() / nrows;
- UInt nb_data = in.size() / (ncols*ncols);
+ UInt nb_data = in.size() / (nrows*nrows);
- Matrix<Real> stress = this->pad(in, nrows,ncols, nb_data);
+ Matrix<Real> stress = this->pad(in, nrows, ncols, nb_data);
const Material & material = this->getMaterialFromGlobalIndex(global_element_id);
bool plane_strain = true;
if(spatial_dimension == 2)
plane_strain = !material.getParam<bool>("Plane_Stress");
if(plane_strain) {
Real nu = material.getParam<Real>("nu");
for (UInt d = 0; d < nb_data; ++d) {
stress(2, 2 + 3*d) = nu * (stress(0, 0 + 3*d) + stress(1, 1 + 3*d));
}
}
return stress;
}
UInt getDim(){return 9;};
UInt getNbComponent(UInt old_nb_comp){
return this->getDim();
};
-
};
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
-class StrainPadder : public MaterialPadder<Real, Matrix<Real> > {
+class StrainPadder : public MaterialFunctor, public PadderGeneric< Matrix<Real>, Matrix<Real> > {
public:
StrainPadder(const SolidMechanicsModel & model) :
- MaterialPadder<Real, Matrix<Real> >(model) {
+ MaterialFunctor(model) {
this->setPadding(3,3);
}
- inline Matrix<Real> func(const Vector<Real> & in, Element global_element_id){
-
+ inline Matrix<Real> func(const Matrix<Real> & in, Element global_element_id){
UInt nrows = spatial_dimension;
- UInt ncols = in.size() / nrows;
- UInt nb_data = in.size() / ncols;
+ UInt nb_data = in.size() / (nrows*nrows);
- Matrix<Real> strain = this->pad(in, nrows,ncols, nb_data);
+ Matrix<Real> strain = this->pad(in, nb_data);
const Material & material = this->getMaterialFromGlobalIndex(global_element_id);
bool plane_stress = material.getParam<bool>("Plane_Stress");
+
if(plane_stress) {
Real nu = material.getParam<Real>("nu");
for (UInt d = 0; d < nb_data; ++d) {
strain(2, 2 + 3*d) = nu / (nu - 1) * (strain(0, 0 + 3*d) + strain(1, 1 + 3*d));
}
}
+
return strain;
}
UInt getDim(){return 9;};
UInt getNbComponent(UInt old_nb_comp){
return this->getDim();
};
};
+/* -------------------------------------------------------------------------- */
+template <bool green_strain>
+class ComputeStrain : public MaterialFunctor, public ComputeFunctor<Vector<Real>, Matrix<Real> > {
+public:
+ ComputeStrain(const SolidMechanicsModel & model) : MaterialFunctor(model) { }
+
+ inline Matrix<Real> func(const Vector<Real> & in, Element global_element_id){
+ UInt nrows = spatial_dimension;
+ UInt ncols = in.size() / nrows;
+ UInt nb_data = in.size() / (nrows*nrows);
+
+ Matrix<Real> ret_all_strain(nrows, ncols);
+ Tensor3<Real> all_grad_u(in.storage(), nrows, nrows, nb_data);
+ Tensor3<Real> all_strain(ret_all_strain.storage(), nrows, nrows, nb_data);
+
+ for (UInt d = 0; d < nb_data; ++d) {
+ Matrix<Real> grad_u = all_grad_u(d);
+ Matrix<Real> strain = all_strain(d);
+
+ if (spatial_dimension == 2) {
+ if (green_strain)
+ Material::gradUToGreenStrain<2>(grad_u, strain);
+ else
+ Material::gradUToEpsilon<2>(grad_u, strain);
+ }
+ else if (spatial_dimension == 3) {
+ if (green_strain)
+ Material::gradUToGreenStrain<3>(grad_u, strain);
+ else
+ Material::gradUToEpsilon<3>(grad_u, strain);
+ }
+ }
+
+ return ret_all_strain;
+ }
+
+ UInt getDim() { return spatial_dimension*spatial_dimension; };
+
+ UInt getNbComponent(UInt old_nb_comp){
+ return this->getDim();
+ };
+
+};
+
+/* -------------------------------------------------------------------------- */
+template <bool green_strain>
+class ComputePrincipalStrain : public MaterialFunctor, public ComputeFunctor<Vector<Real>,
+ Matrix<Real> > {
+public:
+ ComputePrincipalStrain(const SolidMechanicsModel & model) : MaterialFunctor(model) { }
+
+ inline Matrix<Real> func(const Vector<Real> & in, Element global_element_id){
+ UInt nrows = spatial_dimension;
+ UInt nb_data = in.size() / (nrows*nrows);
+
+ Matrix<Real> ret_all_strain(nrows, nb_data);
+ Tensor3<Real> all_grad_u(in.storage(), nrows, nrows, nb_data);
+ Matrix<Real> strain(nrows, nrows);
+
+ for (UInt d = 0; d < nb_data; ++d) {
+ Matrix<Real> grad_u = all_grad_u(d);
+
+ if (spatial_dimension == 2) {
+ if (green_strain)
+ Material::gradUToGreenStrain<2>(grad_u, strain);
+ else
+ Material::gradUToEpsilon<2>(grad_u, strain);
+ }
+ else if (spatial_dimension == 3) {
+ if (green_strain)
+ Material::gradUToGreenStrain<3>(grad_u, strain);
+ else
+ Material::gradUToEpsilon<3>(grad_u, strain);
+ }
+
+ Vector<Real> principal_strain(ret_all_strain(d));
+ strain.eig(principal_strain);
+ }
+
+ return ret_all_strain;
+ }
+
+ UInt getDim() { return spatial_dimension; };
+
+ UInt getNbComponent(UInt old_nb_comp){
+ return this->getDim();
+ };
+
+};
+
+/* -------------------------------------------------------------------------- */
+class ComputeVonMisesStress : public MaterialFunctor,
+ public ComputeFunctor<Vector<Real>, Vector<Real> > {
+public:
+ ComputeVonMisesStress(const SolidMechanicsModel & model) : MaterialFunctor(model) { }
+
+ inline Vector<Real> func(const Vector<Real> & in, Element global_element_id){
+ UInt nrows = spatial_dimension;
+ UInt nb_data = in.size() / (nrows*nrows);
+
+ Vector<Real> von_mises_stress(nb_data);
+ Matrix<Real> deviatoric_stress(3, 3);
+
+ for (UInt d = 0; d < nb_data; ++d) {
+ Matrix<Real> cauchy_stress(in.storage() + d * nrows*nrows, nrows, nrows);
+ von_mises_stress(d) = Material::stressToVonMises(cauchy_stress);
+ }
+
+ return von_mises_stress;
+ }
+
+ UInt getDim() { return 1; };
+
+ UInt getNbComponent(UInt old_nb_comp){
+ return this->getDim();
+ };
+
+};
+
+
+
/* -------------------------------------------------------------------------- */
__END_AKANTU_DUMPER__
__END_AKANTU__
#endif /* __AKANTU_DUMPER_MATERIAL_PADDERS_HH__ */
diff --git a/src/io/dumper/dumper_nodal_field.hh b/src/io/dumper/dumper_nodal_field.hh
index 554910d95..bd9c2de11 100644
--- a/src/io/dumper/dumper_nodal_field.hh
+++ b/src/io/dumper/dumper_nodal_field.hh
@@ -1,245 +1,239 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 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_quadrature_point_iterator.hh b/src/io/dumper/dumper_quadrature_point_iterator.hh
new file mode 100644
index 000000000..abf4437b9
--- /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: Tue Sep 02 2014
+ *
+ * @brief Description of quadrature point iterator
+ *
+ * @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_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 5e6326c88..000000000
--- a/src/io/dumper/dumper_quadrature_points_field.hh
+++ /dev/null
@@ -1,127 +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_type_traits.hh b/src/io/dumper/dumper_type_traits.hh
index e168afd34..b1c6566f0 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
*
* @brief Type traits for field properties
*
* @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_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/mesh_io.cc b/src/io/mesh_io.cc
index 7263bc2df..913385b26 100644
--- a/src/io/mesh_io.cc
+++ b/src/io/mesh_io.cc
@@ -1,95 +1,152 @@
/**
* @file mesh_io.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 3cc8c32f7..d7916f62d 100644
--- a/src/io/mesh_io.hh
+++ b/src/io/mesh_io.hh
@@ -1,102 +1,125 @@
/**
* @file mesh_io.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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) {}
-private:
- MeshIO * getMeshIO(const std::string & filename, const MeshIOType & type);
+ /// 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;
- // std::string filename;
+ /// correspondance between a tag and physical names (if applicable)
+ std::map<UInt, std::string> phys_name_map;
- // Mesh & mesh;
};
+/* -------------------------------------------------------------------------- */
+
+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 654d3d482..babc11e22 100644
--- a/src/io/mesh_io/mesh_io_abaqus.cc
+++ b/src/io/mesh_io/mesh_io_abaqus.cc
@@ -1,541 +1,548 @@
/**
* @file mesh_io_abaqus.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Jan 16 2013
* @date last modification: Fri Sep 19 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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() {
}
/* -------------------------------------------------------------------------- */
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
+ Iterator err_pos,
+ Iterator last) const
{
AKANTU_EXCEPTION("Error! Expecting "
- << what // what failed?
- << " here: \""
- << std::string(err_pos, last) // iterators to error-pos, end
- << "\"");
+ << 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 {
+ 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.");
+ "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;
+ typename NodeMap::const_iterator nit = nodes_mapping.find(*it);
+ AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
+ "There is an unknown node in the connectivity.");
+ tmp_conn[i++] = nit->second;
}
Element el(type, connectivity.getSize());
elements_mapping[id] = el;
connectivity.push_back(tmp_conn);
}
};
struct lazy_node_read_ {
template<class Mesh, class ID, class V, class Map>
struct result { typedef void type; };
template<class Mesh, class ID, class V, class Map>
void operator()(Mesh & mesh,
- const ID & id,
- const V & pos,
- Map & nodes_mapping) const {
+ 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;
+ 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;
+ return *eg_it->second;
} else {
- return mesh.createElementGroup(name, _all_dimensions);
+ return mesh.createElementGroup(name, _all_dimensions);
}
}
};
struct lazy_add_element_to_group_ {
template<class EG, class ID, class Map>
struct result { typedef void type; };
template<class EG, class ID, class Map>
void operator()(EG * el_grp,
- const ID & element,
- const Map & elements_mapping) const {
+ 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() << ".");
+ "There is an unknown element ("<< element <<") in the in the ELSET "
+ << el_grp->getName() << ".");
el_grp->add(eit->second, true, false);
}
};
/* ------------------------------------------------------------------------ */
struct lazy_node_group_create_ {
template<class Mesh, class S> struct result { typedef NodeGroup & type; };
template<class Mesh, class S>
NodeGroup & operator()(Mesh & mesh, const S & name) const {
typename Mesh::node_group_iterator ng_it = mesh.node_group_find(name);
if(ng_it != mesh.node_group_end()) {
- return *ng_it->second;
+ return *ng_it->second;
} else {
- return mesh.createNodeGroup(name, mesh.getSpatialDimension());
+ return mesh.createNodeGroup(name, mesh.getSpatialDimension());
}
}
};
struct lazy_add_node_to_group_ {
template<class NG, class ID, class Map>
struct result { typedef void type; };
template<class NG, class ID, class Map>
void operator()(NG * node_grp,
- const ID & node,
- const Map & nodes_mapping) const {
+ 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() << ".");
+ "There is an unknown node in the in the NSET "
+ << node_grp->getName() << ".");
node_grp->add(nit->second, false);
}
};
struct lazy_optimize_group_ {
template<class G> struct result { typedef void type; };
template<class G> void operator()(G * grp) const {
grp->optimize();
}
};
}
/* -------------------------------------------------------------------------- */
template<class Iterator>
struct AbaqusSkipper : qi::grammar<Iterator> {
AbaqusSkipper() : AbaqusSkipper::base_type(skip,
- "abaqus_skipper") {
+ "abaqus_skipper") {
skip
= (ascii::space - spirit::eol)
| "**" >> *(qi::char_ - spirit::eol) >> spirit::eol
;
}
qi::rule<Iterator> skip;
};
/* -------------------------------------------------------------------------- */
template<class Iterator, typename Skipper = AbaqusSkipper<Iterator> >
struct AbaqusMeshGrammar : qi::grammar<Iterator, void(),
- Skipper> {
+ Skipper> {
public:
AbaqusMeshGrammar(Mesh & mesh) : AbaqusMeshGrammar::base_type(start,
- "abaqus_mesh_reader"),
- mesh(mesh) {
+ "abaqus_mesh_reader"),
+ mesh(mesh) {
phx::function<mesh_io_abaqus_lazy_eval::mesh_abaqus_error_handler_> const error_handler
= mesh_io_abaqus_lazy_eval::mesh_abaqus_error_handler_();
phx::function<mesh_io_abaqus_lazy_eval::lazy_element_read_> lazy_element_read;
phx::function<mesh_io_abaqus_lazy_eval::lazy_node_read_> lazy_node_read;
phx::function<mesh_io_abaqus_lazy_eval::lazy_element_group_create_> lazy_element_group_create;
phx::function<mesh_io_abaqus_lazy_eval::lazy_add_element_to_group_> lazy_add_element_to_group;
phx::function<mesh_io_abaqus_lazy_eval::lazy_node_group_create_> lazy_node_group_create;
phx::function<mesh_io_abaqus_lazy_eval::lazy_add_node_to_group_> lazy_add_node_to_group;
phx::function<mesh_io_abaqus_lazy_eval::lazy_optimize_group_> lazy_optimize_group;
start
= *(
- (qi::char_('*')
- > ( (qi::no_case[ qi::lit("node output") ] > any_section)
- | (qi::no_case[ qi::lit("element output") ] > any_section)
- | (qi::no_case[ qi::lit("node") ] > nodes)
- | (qi::no_case[ qi::lit("element") ] > elements)
- | (qi::no_case[ qi::lit("heading") ] > header)
- | (qi::no_case[ qi::lit("elset") ] > elements_set)
- | (qi::no_case[ qi::lit("nset") ] > nodes_set)
- | (qi::no_case[ qi::lit("material") ] > material)
- | (keyword > any_section)
- )
- )
- | spirit::eol
- )
+ (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");
}
public:
AKANTU_GET_MACRO(MaterialNames, material_names, const std::vector<std::string> &);
/* ------------------------------------------------------------------------ */
/* Rules */
/* ------------------------------------------------------------------------ */
private:
qi::rule<Iterator, void(), Skipper> start;
qi::rule<Iterator, std::vector<int>(), Skipper> connectivity;
qi::rule<Iterator, std::vector<Real>(), Skipper> node_position;
qi::rule<Iterator, void(), Skipper> nodes, any_section, header, material;
qi::rule<Iterator, void(), qi::locals<ElementType>, Skipper> elements;
qi::rule<Iterator, void(), qi::locals<ElementGroup *>, Skipper> elements_set;
qi::rule<Iterator, void(), qi::locals<NodeGroup *>, Skipper> nodes_set;
qi::rule<Iterator, std::string(), Skipper> key, value, option, keyword, any_line;
qi::real_parser< Real, qi::real_policies<Real> > real;
qi::symbols<char, ElementType> abaqus_element_type;
/* ------------------------------------------------------------------------ */
/* Mambers */
/* ------------------------------------------------------------------------ */
private:
/// reference to the mesh to read
Mesh & mesh;
/// correspondance between the numbering of nodes in the abaqus file and in
/// the akantu mesh
std::map<UInt, UInt> abaqus_nodes_to_akantu;
/// correspondance between the element number in the abaqus file and the
/// Element in the akantu mesh
std::map<UInt, Element> abaqus_elements_to_akantu;
/// list of the material names
std::vector<std::string> material_names;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void MeshIOAbaqus::read(const std::string& filename, Mesh& mesh) {
namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace lbs = boost::spirit::qi::labels;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
std::ifstream infile;
infile.open(filename.c_str());
if(!infile.good()) {
AKANTU_DEBUG_ERROR("Cannot open file " << filename);
}
std::string storage; // We will read the contents here.
infile.unsetf(std::ios::skipws); // No white space skipping!
std::copy(std::istream_iterator<char>(infile),
- std::istream_iterator<char>(),
- std::back_inserter(storage));
+ std::istream_iterator<char>(),
+ std::back_inserter(storage));
typedef std::string::const_iterator iterator_t;
typedef AbaqusSkipper <iterator_t> skipper;
typedef AbaqusMeshGrammar<iterator_t, skipper> grammar;
grammar g(mesh);
skipper ws;
iterator_t iter = storage.begin();
iterator_t end = storage.end();
qi::phrase_parse(iter, end, g, ws);
std::vector<std::string>::const_iterator mnit = g.getMaterialNames().begin();
std::vector<std::string>::const_iterator mnend = g.getMaterialNames().end();
for (; mnit != mnend; ++mnit) {
Mesh::element_group_iterator eg_it = mesh.element_group_find(*mnit);
ElementGroup & eg = *eg_it->second;
if(eg_it != mesh.element_group_end()) {
ElementGroup::type_iterator tit = eg.firstType();
ElementGroup::type_iterator tend = eg.lastType();
for (; tit != tend; ++tit) {
- Array<std::string> & abaqus_material
- = *mesh.getDataPointer<std::string>("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 81c02616f..4ed265243 100644
--- a/src/io/mesh_io/mesh_io_abaqus.hh
+++ b/src/io/mesh_io/mesh_io_abaqus.hh
@@ -1,58 +1,59 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 {
+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 4030c42b4..33c9452fa 100644
--- a/src/io/mesh_io/mesh_io_diana.cc
+++ b/src/io/mesh_io/mesh_io_diana.cc
@@ -1,529 +1,580 @@
/**
* @file 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 creation: Sat Mar 26 2011
* @date last modification: Thu Mar 27 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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();
- std::vector<Element> global_to_local_index;
+ 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, global_to_local_index, first_node_number);
+ 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, global_to_local_index, first_node_number);
+ line = readGroups(infile, mesh, first_node_number);
}
-
}
infile.close();
mesh.nb_global_nodes = mesh.nodes->getSize();
- mesh.registerEventHandler(*this);
+ 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) {
+ std::set<UInt> & interval) {
UInt first;
line >> first;
- if(line.fail()) { return 0; }
+ if (line.fail()) { return 0; }
interval.insert(first);
UInt second;
int dash;
dash = line.get();
- if(dash == '-') {
+ if (dash == '-') {
line >> second;
interval.insert(second);
return 2;
}
- if(line.fail())
- line.clear(std::ios::eofbit); // in case of get at end of the line
- else line.unget();
+ 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,
- std::vector<Element> & global_to_local_index,
- 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::stringstream *str = new std::stringstream(line);
+ std::stringstream * str = new std::stringstream(line);
UInt id;
std::string name;
char c;
*str >> id >> name >> c;
Array<UInt> * list_ids = new Array<UInt>(0, 1, name);
- UInt s = 1; bool end = false;
- while(!end) {
- while(!str->eof() && s != 0) {
- std::set<UInt> interval;
- s = readInterval(*str, interval);
- std::set<UInt>::iterator it = interval.begin();
- if(s == 1) list_ids->push_back(*it);
- if(s == 2) {
- UInt first = *it;
- ++it;
- UInt second = *it;
- for(UInt i = first; i <= second; ++i) {
- list_ids->push_back(i);
- }
- }
+ 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);
+ my_getline(infile, line);
+ delete str;
+ str = new std::stringstream(line);
}
}
delete str;
- if(reading_nodes_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;
+ delete list_ids;
+
} else {
- std::vector<Element> * elem = new std::vector<Element>;
- elem->reserve(list_ids->getSize());
+ ElementGroup & eg = mesh.createElementGroup(name);
for (UInt i = 0; i < list_ids->getSize(); ++i) {
- Element & e = global_to_local_index[(*list_ids)(i)-1];
- 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,
- std::vector<Element> & global_to_local_index,
- 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) {
- line = readConnectivity(infile, mesh, global_to_local_index, first_node_number);
+ if ("CONNECTIVITY" == line) {
+ line = readConnectivity(infile, mesh, first_node_number);
}
/// read the line corresponding to the materials
- if ("MATERIALS" == line) {
- line = readMaterialElement(infile, mesh, global_to_local_index);
- }
+ if ("MATERIALS" == line) { line = readMaterialElement(infile, mesh); }
AKANTU_DEBUG_OUT();
return line;
}
-
/* -------------------------------------------------------------------------- */
-std::string MeshIODiana::readConnectivity(std::ifstream & infile,
- Mesh & mesh,
- std::vector<Element> & global_to_local_index,
- 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;
- bool end = false;
- do {
+ while (1) {
my_getline(infile, lline);
+ // std::cerr << lline << std::endl;
std::stringstream sstr_elem(lline);
- if(lline == "MATERIALS") end = true;
- else {
- /// traiter les coordonnees
- sstr_elem >> index;
- sstr_elem >> diana_type;
-
- akantu_type = _diana_to_akantu_element_types[diana_type];
-
- if(akantu_type != _not_defined) {
- if(akantu_type != akantu_type_old) {
- connectivity = mesh.getConnectivityPointer(akantu_type);
-
- node_per_element = connectivity->getNbComponent();
- akantu_type_old = akantu_type;
- }
-
- UInt local_connect[node_per_element];
- for(UInt j = 0; j < node_per_element; ++j) {
- UInt node_index;
- sstr_elem >> node_index;
-
- node_index -= first_node_number;
- local_connect[j] = node_index;
- }
- connectivity->push_back(local_connect);
-
- elem.type = akantu_type;
- elem.element = connectivity->getSize() - 1;
- } else {
- elem.type = _not_defined;
- elem.element = UInt(-1);
+ if (lline == "MATERIALS") break;
+
+ /// traiter les coordonnees
+ sstr_elem >> index;
+ sstr_elem >> diana_type;
+
+ akantu_type = _diana_to_akantu_element_types[diana_type];
+
+ if (akantu_type == _not_defined) continue;
+
+ if (akantu_type != akantu_type_old) {
+ connectivity = mesh.getConnectivityPointer(akantu_type);
+
+ node_per_element = connectivity->getNbComponent();
+ akantu_type_old = akantu_type;
+ read_order = _read_order[akantu_type];
+ }
+
+ UInt local_connect[node_per_element];
+
+ // used if element is written on two lines
+ UInt j_last;
+
+ for (UInt j = 0; j < node_per_element; ++j) {
+ UInt node_index;
+ sstr_elem >> node_index;
+
+ // check s'il y a pas plus rien après un certain point
+
+ if (sstr_elem.fail()) {
+ sstr_elem.clear();
+ sstr_elem.ignore();
+ break;
}
- global_to_local_index.push_back(elem);
+ node_index -= first_node_number;
+ local_connect[read_order[j]] = node_index;
+ j_last = j;
+ }
+
+ // check if element is written in two lines
+ if (j_last != (node_per_element - 1)) {
+
+ // if this is the case, read on more line
+ my_getline(infile, lline);
+ std::stringstream sstr_elem(lline);
+
+ for (UInt j = (j_last + 1); j < node_per_element; ++j) {
+
+ UInt node_index;
+ sstr_elem >> node_index;
+
+ node_index -= first_node_number;
+ local_connect[read_order[j]] = node_index;
+ }
}
+
+ connectivity->push_back(local_connect);
+
+ elem.type = akantu_type;
+ elem.element = connectivity->getSize() - 1;
+
+ diana_element_number_to_elements[index] = elem;
+ akantu_number_to_diana_number[elem] = index;
}
- while(!end);
AKANTU_DEBUG_OUT();
return lline;
}
/* -------------------------------------------------------------------------- */
std::string MeshIODiana::readMaterialElement(std::ifstream & infile,
- Mesh & mesh,
- std::vector<Element> & global_to_local_index) {
+ 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);
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 = global_to_local_index[j - 1];
- 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) {
- 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::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 0c827ccb3..ff5f24ddf 100644
--- a/src/io/mesh_io/mesh_io_diana.hh
+++ b/src/io/mesh_io/mesh_io_diana.hh
@@ -1,154 +1,105 @@
/**
* @file mesh_io_diana.hh
*
* @author David Simon Kammer <david.kammer@epfl.ch>
* @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sat Mar 26 2011
* @date last modification: Mon Aug 19 2013
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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);
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,
- std::vector<Element> & global_to_local_index,
- UInt first_node_number);
+ std::string readElements(std::ifstream & infile, Mesh & mesh,
+ UInt first_node_number);
- std::string readGroups(std::ifstream & infile,
- std::vector<Element> & global_to_local_index,
- UInt first_node_number);
+ std::string readGroups(std::ifstream & infile, Mesh & mesh, UInt first_node_number);
- std::string readConnectivity(std::ifstream & infile,
- Mesh & mesh,
- std::vector<Element> & global_to_local_index,
- 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::vector<Element> & global_to_local_index);
+ 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);
+ 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;
};
__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 b3d0cc294..8d5712792 100644
--- a/src/io/mesh_io/mesh_io_msh.cc
+++ b/src/io/mesh_io/mesh_io_msh.cc
@@ -1,541 +1,969 @@
/**
* @file mesh_io_msh.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Jul 04 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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_prism_18 ] = 18;
- _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_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[_pentahedron_6 ] = _msh_prism_1;
- _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[11] = 10;
+ tmp[12] = 14;
+ tmp[14] = 12;
+ break;
+ case _hexahedron_20:
+ tmp[9] = 11;
+ tmp[10] = 12;
+ tmp[11] = 9;
+ tmp[12] = 13;
+ tmp[13] = 10;
+ tmp[17] = 19;
+ tmp[18] = 17;
+ tmp[19] = 18;
+ break;
default:
- //nothing to change
+ // 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) {
+ 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);
}
- 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();
- 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_0", *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;
- }
- }
- }
- }
+ 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.getSize() << 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 d7dac7f7c..f4656242a 100644
--- a/src/io/mesh_io/mesh_io_msh.hh
+++ b/src/io/mesh_io/mesh_io_msh.hh
@@ -1,115 +1,114 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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_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;
-
- /// correspondance between tag_0 and physical name (if applicable)
- std::map<UInt, std::string> phys_name_map;
};
__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..b2861b290 100644
--- a/src/io/mesh_io/mesh_io_msh_struct.cc
+++ b/src/io/mesh_io/mesh_io_msh_struct.cc
@@ -1,79 +1,79 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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/parser/algebraic_parser.hh b/src/io/parser/algebraic_parser.hh
index 838adb63b..d1545130c 100644
--- a/src/io/parser/algebraic_parser.hh
+++ b/src/io/parser/algebraic_parser.hh
@@ -1,498 +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
*
* @brief algebraic_parser definition of the grammar
*
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
// 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));
+ ;
- expr .name("expression");
- term .name("term");
- factor .name("factor");
- number .name("numerical-value");
- variable.name("variable");
- function.name("function");
+ qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
- constant.name("constants-list");
- unary_function.name("unary-functions-list");
- binary_function.name("binary-functions-list");
+ expr .name("expression");
+ term .name("term");
+ factor .name("factor");
+ number .name("numerical-value");
+ variable.name("variable");
+ function.name("function");
+
+ constant.name("constants-list");
+ unary_function.name("unary-functions-list");
+ binary_function.name("binary-functions-list");
+
+#if !defined AKANTU_NDEBUG
+ if(AKANTU_DEBUG_TEST(dblDebug)) {
+ qi::debug(expr);
+ qi::debug(term);
+ qi::debug(factor);
+ qi::debug(number);
+ qi::debug(variable);
+ qi::debug(function);
+ }
+#endif
}
private:
qi::rule<Iterator, Real(), Skipper> start;
qi::rule<Iterator, Real(), Skipper> expr;
qi::rule<Iterator, Real(), Skipper> term;
qi::rule<Iterator, Real(), Skipper> factor;
qi::rule<Iterator, Real(), Skipper> number;
qi::rule<Iterator, Real(), Skipper> variable;
qi::rule<Iterator, Real(), Skipper> function;
qi::rule<Iterator, std::string(), Skipper> key;
qi::real_parser< Real, qi::real_policies<Real> > real;
qi::symbols<char, Real> constant;
qi::symbols<char, Real (*) (Real)> unary_function;
qi::symbols<char, Real (*) (Real, Real)> binary_function;
const ParserSection & section;
};
/* ---------------------------------------------------------------------- */
/* Vector Parser */
/* ---------------------------------------------------------------------- */
struct parsable_vector {
operator Vector<Real>() {
- Vector<Real> tmp(_cells.size());
- std::vector<Real>::iterator it = _cells.begin();
- for (UInt i = 0; it != _cells.end(); ++it, ++i) tmp(i) = *it;
- return tmp;
+ Vector<Real> tmp(_cells.size());
+ std::vector<Real>::iterator it = _cells.begin();
+ for (UInt i = 0; it != _cells.end(); ++it, ++i) tmp(i) = *it;
+ return tmp;
}
std::vector<Real> _cells;
};
+ inline std::ostream& operator<<(std::ostream& stream, const parsable_vector& pv) {
+ stream << "pv[";
+ std::vector<Real>::const_iterator it = pv._cells.begin();
+ if(it != pv._cells.end()) {
+ stream << *it;
+ for (++it; it != pv._cells.end(); ++it) stream << ", " << *it;
+ }
+ stream << "]";
+ return stream;
+ }
+
struct parsable_matrix {
operator Matrix<Real>() {
- size_t cols = 0;
- std::vector<parsable_vector>::iterator it_rows = _cells.begin();
- for (;it_rows != _cells.end(); ++it_rows) cols = std::max(cols, it_rows->_cells.size());
-
- Matrix<Real> tmp(_cells.size(), _cells[0]._cells.size(), 0.);
-
- it_rows = _cells.begin();
- for (UInt i = 0; it_rows != _cells.end(); ++it_rows, ++i) {
- std::vector<Real>::iterator it_cols = it_rows->_cells.begin();
- for (UInt j = 0; it_cols != it_rows->_cells.end(); ++it_cols, ++j) {
- tmp(i, j) = *it_cols;
- }
- }
- return tmp;
+ size_t cols = 0;
+ std::vector<parsable_vector>::iterator it_rows = _cells.begin();
+ for (;it_rows != _cells.end(); ++it_rows) cols = std::max(cols, it_rows->_cells.size());
+
+ Matrix<Real> tmp(_cells.size(), _cells[0]._cells.size(), 0.);
+
+ it_rows = _cells.begin();
+ for (UInt i = 0; it_rows != _cells.end(); ++it_rows, ++i) {
+ std::vector<Real>::iterator it_cols = it_rows->_cells.begin();
+ for (UInt j = 0; it_cols != it_rows->_cells.end(); ++it_cols, ++j) {
+ tmp(i, j) = *it_cols;
+ }
+ }
+ return tmp;
}
std::vector<parsable_vector> _cells;
};
+ inline std::ostream& operator<<(std::ostream& stream, const parsable_matrix& pm) {
+ stream << "pm[";
+ std::vector<parsable_vector>::const_iterator it = pm._cells.begin();
+ if(it != pm._cells.end()) {
+ stream << *it;
+ for (++it; it != pm._cells.end(); ++it) stream << ", " << *it;
+ }
+ stream << "]";
+ return stream;
+ }
/* ---------------------------------------------------------------------- */
struct lazy_cont_add_ {
template <typename T1, typename T2>
struct result { typedef void type; };
template <typename T1, typename T2>
void operator()(T1 & cont, T2 & value) const {
- cont._cells.push_back(value);
+ 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) {
+ "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) ]
- )
+ >> *( ','
+ >> 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");
+ start .name("start");
vector.name("vector");
- number.name("value");
+ number.name("value");
+
+#if !defined AKANTU_NDEBUG
+ if(AKANTU_DEBUG_TEST(dblDebug)) {
+ qi::debug(start);
+ qi::debug(vector);
+ }
+#endif
}
private:
qi::rule<Iterator, parsable_vector(), Skipper> start;
qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper> vector;
qi::rule<Iterator, Real(), Skipper> value;
AlgebraicGrammar<Iterator, Skipper> number;
};
/* ---------------------------------------------------------------------- */
struct lazy_vector_eval_ {
template <typename T1, typename T2, typename res>
struct result { typedef bool type; };
template <typename T1, typename T2, typename res>
bool operator()(T1 a, const T2 & section, res & result) const {
- std::string value = section.getParameter(a, _ppsc_current_and_parent_scope);
- std::string::const_iterator b = value.begin();
- std::string::const_iterator e = value.end();
- parser::VectorGrammar<std::string::const_iterator, qi::space_type> grammar(section);
- return qi::phrase_parse(b, e, grammar, qi::space, result);
+ 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) {
+ "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 >> ']'
;
matrix
= ( rows [ lazy_matrix_add(lbs::_a, lbs::_1) ]
- >> *( ','
- >> rows [ lazy_matrix_add(lbs::_a, lbs::_1) ]
- )
- ) [ lbs::_val = lbs::_a ]
- ;
+ >> *( ','
+ >> rows [ lazy_matrix_add(lbs::_a, lbs::_1) ]
+ )
+ ) [ lbs::_val = lbs::_a ]
+ ;
- rows
- = eval_vector
- | vector
- ;
+ rows
+ = eval_vector
+ | vector
+ ;
- eval_vector
- = (key [ lbs::_pass = lazy_vector_eval(lbs::_1, section, lbs::_a) ]) [lbs::_val = lbs::_a]
- ;
+ 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
+ ;
- 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");
+ start .name("matrix");
+ matrix.name("all_rows");
rows .name("rows");
- vector.name("vector");
- eval_vector.name("eval_vector");
+ vector.name("vector");
+ eval_vector.name("eval_vector");
+
+#ifndef AKANTU_NDEBUG
+ if(AKANTU_DEBUG_TEST(dblDebug)) {
+ qi::debug(start);
+ qi::debug(matrix);
+ qi::debug(rows);
+ qi::debug(eval_vector);
+ qi::debug(key);
+ }
+#endif
}
private:
qi::rule<Iterator, parsable_matrix(), Skipper> start;
qi::rule<Iterator, parsable_matrix(), qi::locals<parsable_matrix>, Skipper> matrix;
qi::rule<Iterator, parsable_vector(), Skipper> rows;
qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper> eval_vector;
qi::rule<Iterator, std::string(), Skipper> key;
VectorGrammar<Iterator, Skipper> vector;
};
/* ---------------------------------------------------------------------- */
/* Randon Generator */
/* ---------------------------------------------------------------------- */
struct ParsableRandomGenerator {
ParsableRandomGenerator(Real base = Real(),
- const RandomDistributionType & type = _rdt_not_defined,
- const parsable_vector & parameters = parsable_vector()) :
- base(base), type(type), parameters(parameters) {}
+ const RandomDistributionType & type = _rdt_not_defined,
+ const parsable_vector & parameters = parsable_vector()) :
+ base(base), type(type), parameters(parameters) {}
Real base;
RandomDistributionType type;
parsable_vector parameters;
};
+ inline std::ostream& operator<<(std::ostream& stream, const ParsableRandomGenerator& prg) {
+ stream << "prg[" << prg.base << " " << UInt(prg.type) << " " << prg.parameters << "]";
+ return stream;
+ }
+
/* ---------------------------------------------------------------------- */
template<class Iterator, typename Skipper = spirit::unused_type>
struct RandomGeneratorGrammar : qi::grammar<Iterator, ParsableRandomGenerator(), Skipper> {
RandomGeneratorGrammar(const ParserSection & section) : RandomGeneratorGrammar::base_type(start,
- "random_generator_grammar"),
- number(section) {
+ "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()
- ;
+ start
+ = generator.alias()
+ ;
generator
= qi::hold[distribution [ lbs::_val = lbs::_1 ] ]
- | number [ lbs::_val = phx::construct<ParsableRandomGenerator>(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) ]
- ;
+ 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 ]
- ;
+ >> *( ','
+ > 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));
- start .name("random-generator");
- generator .name("random-generator");
- distribution .name("random-distribution");
- generator_type .name("generator-type");
+ 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");
+ number .name("number");
+
+#ifndef AKANTU_NDEBUG
+ if(AKANTU_DEBUG_TEST(dblDebug)) {
+ qi::debug(generator);
+ qi::debug(distribution);
+ qi::debug(generator_params);
+ }
+#endif
}
private:
qi::rule<Iterator, ParsableRandomGenerator(), Skipper> start;
qi::rule<Iterator, ParsableRandomGenerator(), Skipper> generator;
qi::rule<Iterator, ParsableRandomGenerator(), Skipper> distribution;
qi::rule<Iterator, parsable_vector(), qi::locals<parsable_vector>, Skipper> generator_params;
AlgebraicGrammar<Iterator, Skipper> number;
qi::symbols<char, RandomDistributionType> generator_type;
};
}
}
#endif /* __AKANTU_ALGEBRAIC_PARSER_HH__ */
diff --git a/src/io/parser/cppargparse/cppargparse.cc b/src/io/parser/cppargparse/cppargparse.cc
index 7293d7102..b6544aa02 100644
--- a/src/io/parser/cppargparse/cppargparse.cc
+++ b/src/io/parser/cppargparse/cppargparse.cc
@@ -1,454 +1,471 @@
/**
* @file cppargparse.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Apr 03 2014
* @date last modification: Mon Sep 15 2014
*
* @brief implementation of the ArgumentParser
*
* @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 "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) {
+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 == "") {
+ if(this->program_name == "" && argc > 0) {
std::string prog = argvs[current_position];
const char * c_prog = prog.c_str();
char * c_prog_tmp = strdup(c_prog);
std::string base_prog(basename(c_prog_tmp));
this->program_name = base_prog;
std::free(c_prog_tmp);
}
std::queue<_Argument *> positional_queue;
for(PositionalArgument::iterator it = pos_args.begin();
it != pos_args.end(); ++it)
positional_queue.push(*it);
std::vector<int> argvs_to_remove;
++current_position; // consume argv[0]
while(current_position < argvs.size()) {
std::string arg = argvs[current_position];
++current_position;
ArgumentKeyMap::iterator key_it = key_args.find(arg);
bool is_positional = false;
_Argument * argument_ptr = NULL;
if(key_it == key_args.end()) {
if(positional_queue.empty()) {
if(stop_in_not_parsed) this->_exit("Argument " + arg + " not recognized", EXIT_FAILURE);
continue;
} else {
argument_ptr = positional_queue.front();
is_positional = true;
--current_position;
}
} else {
argument_ptr = key_it->second;
}
if(remove_parsed && ! is_positional && argument_ptr->name != "help") {
argvs_to_remove.push_back(current_position - 1);
}
_Argument & argument = *argument_ptr;
unsigned int min_nb_val = 0, max_nb_val = 0;
switch(argument.nargs) {
case _one_if_possible: max_nb_val = 1; break; // "?"
case _at_least_one: min_nb_val = 1; // "+"
case _any: max_nb_val = argc - current_position; break; // "*"
default: min_nb_val = max_nb_val = argument.nargs; // "N"
}
std::vector<std::string> values;
unsigned int arg_consumed = 0;
if(max_nb_val <= (argc - current_position)) {
for(; arg_consumed < max_nb_val; ++arg_consumed) {
std::string v = argvs[current_position];
++current_position;
bool is_key = key_args.find(v) != key_args.end();
bool is_good_type = checkType(argument.type, v);
if(!is_key && is_good_type) {
values.push_back(v);
if(remove_parsed) argvs_to_remove.push_back(current_position - 1);
} else {
// unconsume not parsed argument for optional
if(!is_positional || (is_positional && is_key)) --current_position;
break;
}
}
}
if(arg_consumed < min_nb_val) {
if(!is_positional) {
this->_exit("Not enought values for the argument "
+ argument.name + " where provided", EXIT_FAILURE);
} else {
if(stop_in_not_parsed) this->_exit("Argument " + arg + " not recognized", EXIT_FAILURE);
}
} else {
if (is_positional) positional_queue.pop();
if(!argument.parsed) {
success_parsed[argument.name] = &argument;
argument.parsed = true;
if((argument.nargs == _one_if_possible || argument.nargs == 0) && arg_consumed == 0) {
if(argument.has_const)
argument.setToConst();
else if(argument.has_default)
argument.setToDefault();
} else {
argument.setValues(values);
}
} else {
this->_exit("Argument " + argument.name
+ " already present in the list of argument", EXIT_FAILURE);
}
}
}
for (_Arguments::iterator ait = arguments.begin();
ait != arguments.end(); ++ait) {
_Argument & argument = *(ait->second);
if(!argument.parsed) {
if(argument.has_default) {
argument.setToDefault();
success_parsed[argument.name] = &argument;
}
if(argument.required) {
this->_exit("Argument " + argument.name + " required but not given!", EXIT_FAILURE);
}
}
}
// removing the parsed argument if remove_parsed is true
if(argvs_to_remove.size()) {
std::vector<int>::const_iterator next_to_remove = argvs_to_remove.begin();
for (int i = 0, c = 0; i < argc; ++i) {
if(next_to_remove == argvs_to_remove.end() || i != *next_to_remove) {
argv[c] = argv[i];
++c;
} else {
if (next_to_remove != argvs_to_remove.end()) ++next_to_remove;
}
}
argc -= argvs_to_remove.size();
}
if(this->arguments["help"]->parsed && parse_help) {
this->_exit();
}
}
/* -------------------------------------------------------------------------- */
bool ArgumentParser::checkType(ArgumentType type, const std::string & value) const {
std::stringstream sstr(value);
switch(type) {
case _string: { std::string s; sstr >> s; break; }
case _float: { double d; sstr >> d; break; }
case _integer: { int i; sstr >> i; break; }
case _boolean: { bool b; sstr >> b; break; }
}
return (sstr.fail() == false);
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::printself(std::ostream & stream) const {
for(Arguments::const_iterator it = success_parsed.begin();
it != success_parsed.end(); ++it) {
const Argument & argument = *(it->second);
argument.printself(stream);
stream << std::endl;
}
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::print_usage(std::ostream & stream) const {
stream << "Usage: " << this->program_name;
std::stringstream sstr_opt;
// print shorten usage
for(_Arguments::const_iterator it = arguments.begin();
it != arguments.end(); ++it) {
const _Argument & argument = *(it->second);
if(!argument.is_positional) {
if(!argument.required) stream << " [";
stream << argument.keys[0];
this->print_usage_nargs(stream, argument);
if(!argument.required) stream << "]";
}
}
for(PositionalArgument::const_iterator it = pos_args.begin();
it != pos_args.end(); ++it) {
const _Argument & argument = **it;
this->print_usage_nargs(stream, argument);
}
stream << std::endl;
}
/* -------------------------------------------------------------------------- */
void ArgumentParser::print_usage_nargs(std::ostream & stream,
const _Argument & argument) const {
std::string u_name = to_upper(argument.name);
switch(argument.nargs) {
case _one_if_possible: stream << " [" << u_name << "]"; break;
case _at_least_one: stream << " " << u_name;
case _any: stream << " [" << u_name << " ...]"; break;
default:
for(int i = 0; i < argument.nargs; ++i) {
stream << " " << u_name;
}
}
}
void ArgumentParser::print_help(std::ostream & stream) const {
this->print_usage(stream);
if(!pos_args.empty()) {
stream << std::endl;
stream << "positional arguments:" << std::endl;
for(PositionalArgument::const_iterator it = pos_args.begin();
it != pos_args.end(); ++it) {
const _Argument & argument = **it;
this->print_help_argument(stream, argument);
}
}
if(!key_args.empty()) {
stream << std::endl;
stream << "optional arguments:" << std::endl;
for(_Arguments::const_iterator it = arguments.begin();
it != arguments.end(); ++it) {
const _Argument & argument = *(it->second);
if(!argument.is_positional) {
this->print_help_argument(stream, argument);
}
}
}
}
void ArgumentParser::print_help_argument(std::ostream & stream, const _Argument & argument) const {
std::string key("");
if(argument.is_positional)
key = argument.name;
else {
std::stringstream sstr;
for(unsigned int i = 0; i < argument.keys.size(); ++i) {
if(i != 0) sstr << ", ";
sstr << argument.keys[i];
this->print_usage_nargs(sstr, argument);
}
key = sstr.str();
}
stream << " " << std::left << std::setw(15) << key << " " << argument.help;
argument.printDefault(stream);
stream << std::endl;
}
}
diff --git a/src/io/parser/cppargparse/cppargparse.hh b/src/io/parser/cppargparse/cppargparse.hh
index 2a0a697b7..9db3b0b27 100644
--- a/src/io/parser/cppargparse/cppargparse.hh
+++ b/src/io/parser/cppargparse/cppargparse.hh
@@ -1,177 +1,185 @@
/**
* @file cppargparse.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Apr 03 2014
* @date last modification: Mon Sep 15 2014
*
* @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)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 {
-enum ArgumentType {
- _string,
- _integer,
- _float,
- _boolean
-};
+/// define the types of the arguments
+enum ArgumentType { _string, _integer, _float, _boolean };
-enum ArgumentNargs {
- _one_if_possible = -1,
- _at_least_one = -2,
- _any = -3
-};
+/// 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;
+ 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);
+ 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);
+ 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);
+ 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);
+ void parse(int & argc, char **& argv, int flags = _stop_on_not_parsed,
+ bool parse_help = true);
/// print the content in the stream
void printself(std::ostream & stream) const;
/// print the help text
void print_help(std::ostream & stream = std::cout) const;
/// print the usage text
void print_usage(std::ostream & stream = std::cout) const;
/// set an external function to replace the exit function from the stdlib
void setExternalExitFunction(void (*external_exit)(int)) {
this->external_exit = external_exit;
}
/// accessor for a registered argument that was parsed, throw an exception if
/// the argument does not exist or was not set (parsed or default value)
const Argument & operator[](const std::string & name) const;
bool has(const std::string &) const;
-
- /// set the parallel context to avoid multiple help messages in multiproc/thread cases
+
+ /// set the parallel context to avoid multiple help messages in
+ /// multiproc/thread cases
void setParallelContext(int prank, int psize);
public:
- class _Argument;
+
+ /// Internal class describing the arguments
+ struct _Argument;
+ /// Stores that value of an argument
template<class T> class ArgumentStorage;
private:
+ /// Internal function to be used by the public addArgument
_Argument & _addArgument(const std::string & name_or_flag,
- const std::string & description,
- int nargs,
- ArgumentType type);
+ 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;
- void print_usage_nargs(std::ostream & stream, const _Argument & argument) const;
- void print_help_argument(std::ostream & stream, const _Argument & argument) 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 storage of arguments declared by the user
_Arguments arguments;
-
- ArgumentKeyMap key_args;
- PositionalArgument pos_args;
+ /// list of arguments successfully parsed
Arguments success_parsed;
+ /// keys associated to arguments
+ ArgumentKeyMap key_args;
+ /// positional arguments
+ PositionalArgument pos_args;
+ /// argv[0]
std::string program_name;
+
+ /// exit function to use
void (*external_exit)(int);
+ /// parallel context
int prank, psize;
};
-
}
-inline std::ostream & operator<<(std::ostream & stream, const cppargparse::ArgumentParser & argparse) {
+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 51338fc99..c11e97294 100644
--- a/src/io/parser/cppargparse/cppargparse_tmpl.hh
+++ b/src/io/parser/cppargparse/cppargparse_tmpl.hh
@@ -1,261 +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
*
- * @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)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 unsigned int() 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 {
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 30956171e..81eb05690 100644
--- a/src/io/parser/input_file_parser.hh
+++ b/src/io/parser/input_file_parser.hh
@@ -1,272 +1,287 @@
/**
* @file input_file_parser.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Fri Apr 04 2014
*
* @brief Grammar definition for the input files
*
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
// Boost
/* -------------------------------------------------------------------------- */
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
//#include <boost/foreach.hpp>
#ifndef __AKANTU_INPUT_FILE_PARSER_HH__
#define __AKANTU_INPUT_FILE_PARSER_HH__
namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace lbs = boost::spirit::qi::labels;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
__BEGIN_AKANTU__
namespace parser {
struct error_handler_
{
template <typename, typename, typename, typename>
struct result { typedef void type; };
template <typename Iterator>
void operator()(qi::info const& what,
Iterator err_pos,
Iterator first,
Iterator last) const {
spirit::classic::file_position pos = err_pos.get_position();
AKANTU_EXCEPTION("Parse error [ "
<< "Expecting " << what << " instead of \"" << *err_pos << "\" ]"
<< " in file " << pos.file
<< " line " << pos.line
<< " column " << pos.column << std::endl
<< "'" << err_pos.get_currentline() << "'" << std::endl
<< std::setw(pos.column) << " " << "^- here");
}
private:
};
struct lazy_create_subsection_ {
template<typename, typename, typename, typename>
struct result { typedef ParserSection& type; };
template<typename T>
ParserSection& operator()(const SectionType & type, const std::string & name,
const T & option,
ParserSection & sect) const {
std::string opt;
if(option) opt = *option;
ParserSection sect_tmp(name, type, opt, sect);
return sect.addSubSection(sect_tmp);
}
};
template<typename Iterator>
struct lazy_create_parameter_ {
lazy_create_parameter_(std::string & error_message) : error_message(error_message) {}
template<typename, typename, typename>
struct result { typedef bool type; };
template<typename Range>
bool operator()(const Range & rng,
const std::string & value,
ParserSection & sect) const {
try {
std::string name(rng.begin(), rng.end());
name = trim(name);
spirit::classic::file_position pos = rng.begin().get_position();
ParserParameter param_tmp(name, value, sect);
param_tmp.setDebugInfo(pos.file, pos.line, pos.column);
sect.addParameter(param_tmp);
} catch (debug::Exception & e) {
error_message = e.info();
return false;
}
return true;
}
private:
std::string & error_message;
};
struct lazy_concatenate_ {
template<class T1, class T2>
struct result { typedef T1 type; };
template<class T1, class T2>
T1 operator()(const T1 & t1, const T2 & t2) const {
return (t1 + t2);
}
};
/* ---------------------------------------------------------------------- */
/* Grammars definitions */
/* ---------------------------------------------------------------------- */
template<class Iterator>
struct InputFileGrammar : qi::grammar<Iterator, void(),
typename Skipper<Iterator>::type> {
InputFileGrammar(ParserSection * sect) : InputFileGrammar::base_type(start,
"input_file_grammar"),
parent_section(sect) {
phx::function<error_handler_> const error_handler = error_handler_();
phx::function< lazy_create_parameter_<Iterator> > lazy_create_parameter
= lazy_create_parameter_<Iterator>(error_message);
phx::function<lazy_create_subsection_> lazy_create_subsection;
phx::function<lazy_concatenate_> lazy_concatenate;
start
= mini_section(parent_section)
;
mini_section
= *(
entry (lbs::_r1)
| section(lbs::_r1)
)
;
entry
= (
qi::raw[key]
>> '='
> value
) [ lbs::_pass = lazy_create_parameter(lbs::_1,
lbs::_2,
*lbs::_r1) ]
;
section
= (
qi::no_case[section_type]
> qi::lexeme
[
section_name
> -section_option
]
) [ lbs::_a = &lazy_create_subsection(lbs::_1,
phx::at_c<0>(lbs::_2),
phx::at_c<1>(lbs::_2),
*lbs::_r1) ]
> '['
> mini_section(lbs::_a)
> ']'
;
section_name
= qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")
;
section_option
= (+ascii::space >> section_name) [ lbs::_val = lbs::_2 ]
;
key
= qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")
;
value
= (
mono_line_value [ lbs::_a = lazy_concatenate(lbs::_a, lbs::_1) ]
> *(
'\\' > mono_line_value [ lbs::_a = lazy_concatenate(lbs::_a, lbs::_1) ]
)
) [ lbs::_val = lbs::_a ]
;
mono_line_value
= qi::lexeme
[
+(qi::char_ - (qi::char_('=') | spirit::eol | '#' | ';' | '\\'))
]
;
skipper
= ascii::space
| "#" >> *(qi::char_ - spirit::eol)
;
#define AKANTU_SECTION_TYPE_ADD(r, data, elem) \
(BOOST_PP_STRINGIZE(elem), AKANTU_SECTION_TYPES_PREFIX(elem))
section_type.add
BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_ADD, _, AKANTU_SECTION_TYPES);
#undef AKANTU_SECTION_TYPE_ADD
qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_1, lbs::_2));
section .name("section");
section_name .name("section-name");
section_option .name("section-option");
mini_section .name("section-content");
entry .name("parameter");
key .name("parameter-name");
value .name("parameter-value");
section_type .name("section-types-list");
mono_line_value.name("mono-line-value");
+
+
+#if !defined AKANTU_NDEBUG
+ if(AKANTU_DEBUG_TEST(dblDebug)) {
+ // qi::debug(section);
+ qi::debug(section_name);
+ qi::debug(section_option);
+ // qi::debug(mini_section);
+ // qi::debug(entry);
+ qi::debug(key);
+ qi::debug(value);
+ qi::debug(mono_line_value);
+ }
+#endif
+
}
const std::string & getErrorMessage() const { return error_message; };
typedef typename Skipper<Iterator>::type skipper_type;
skipper_type skipper;
private:
std::string error_message;
qi::rule<Iterator, void(ParserSection *), skipper_type> mini_section;
qi::rule<Iterator, void(ParserSection *), qi::locals<ParserSection *>, skipper_type> section;
qi::rule<Iterator, void() , skipper_type> start;
qi::rule<Iterator, std::string() > section_name;
qi::rule<Iterator, std::string() > section_option;
qi::rule<Iterator, void(ParserSection *), skipper_type> entry;
qi::rule<Iterator, std::string() , skipper_type> key;
qi::rule<Iterator, std::string() , qi::locals<std::string>, skipper_type> value;
qi::rule<Iterator, std::string() , skipper_type> mono_line_value;
qi::symbols<char, SectionType> section_type;
ParserSection * parent_section;
};
}
__END_AKANTU__
#endif /* __AKANTU_INPUT_FILE_PARSER_HH__ */
diff --git a/src/io/parser/parsable.cc b/src/io/parser/parsable.cc
index 54be8e9c4..3ffd75688 100644
--- a/src/io/parser/parsable.cc
+++ b/src/io/parser/parsable.cc
@@ -1,202 +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
*
* @brief Parsable 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#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){
-#ifdef AKANTU_NDEBUG
- if(!it->second->isInternal()) {
-#endif
- stream << space;
- it->second->printself(stream);
-#ifdef AKANTU_NDEBUG
- }
-#endif
+ 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..ac05a188e 100644
--- a/src/io/parser/parsable.hh
+++ b/src/io/parser/parsable.hh
@@ -1,185 +1,203 @@
/**
* @file parsable.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Tue Jun 24 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 ad67c7de0..e6afc79c4 100644
--- a/src/io/parser/parsable_tmpl.hh
+++ b/src/io/parser/parsable_tmpl.hh
@@ -1,210 +1,210 @@
/**
* @file parsable_tmpl.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Tue Jun 24 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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.cols(); ++i) {
- for (UInt j = 0; j < param.rows(); ++j) {
+ 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 056355802..ec822b345 100644
--- a/src/io/parser/parser.cc
+++ b/src/io/parser/parser.cc
@@ -1,227 +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
*
* @brief implementation of the parser
*
* @section LICENSE
*
* Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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);
- 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);
- 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);
- 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);
- 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 5061e9a94..4e9d2d476 100644
--- a/src/io/parser/parser.hh
+++ b/src/io/parser/parser.hh
@@ -1,405 +1,467 @@
/**
* @file parser.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Thu Aug 21 2014
*
* @brief File parser 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 "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) \
- (rules) \
- (non_local) \
- (user) \
- (not_defined)
-
+#define AKANTU_SECTION_TYPES \
+ (global)(material)(model)(mesh)(heat)(contact)(friction)( \
+ embedded_interface)(rules)(neighborhoods)(non_local)(weight_function)( \
+ neighborhood)(user)(not_defined)
#define AKANTU_SECTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_st_, elem)
#define AKANTU_SECT_PREFIX(s, data, elem) AKANTU_SECTION_TYPES_PREFIX(elem)
+/// Defines the possible section types
enum SectionType {
- BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_SECT_PREFIX, _, AKANTU_SECTION_TYPES))
+ BOOST_PP_SEQ_ENUM(
+ BOOST_PP_SEQ_TRANSFORM(AKANTU_SECT_PREFIX, _, AKANTU_SECTION_TYPES))
};
#undef AKANTU_SECT_PREFIX
-#define AKANTU_SECTION_TYPE_PRINT_CASE(r, data, elem) \
- case AKANTU_SECTION_TYPES_PREFIX(elem): { \
- stream << BOOST_PP_STRINGIZE(AKANTU_SECTION_TYPES_PREFIX(elem)); \
- break; \
+#define AKANTU_SECTION_TYPE_PRINT_CASE(r, data, elem) \
+ case AKANTU_SECTION_TYPES_PREFIX(elem): { \
+ stream << BOOST_PP_STRINGIZE(AKANTU_SECTION_TYPES_PREFIX(elem)); \
+ break; \
}
-inline std::ostream & operator <<(std::ostream & stream, SectionType type) {
- switch(type) {
- BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_PRINT_CASE, _, AKANTU_SECTION_TYPES)
- default: stream << "not a SectionType"; break;
+inline std::ostream & operator<<(std::ostream & stream, SectionType type) {
+ switch (type) {
+ BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_PRINT_CASE, _,
+ AKANTU_SECTION_TYPES)
+ default:
+ stream << "not a SectionType";
+ break;
}
return stream;
}
#undef AKANTU_SECTION_TYPE_PRINT_CASE
+/// Defines the possible search contexts/scopes (for parameter search)
enum ParserParameterSearchCxt {
- _ppsc_current_scope = 0x1,
- _ppsc_parent_scope = 0x2,
- _ppsc_current_and_parent_scope = 0x3
+ _ppsc_current_scope = 0x1,
+ _ppsc_parent_scope = 0x2,
+ _ppsc_current_and_parent_scope = 0x3
};
/* ------------------------------------------------------------------------ */
/* Parameters Class */
/* ------------------------------------------------------------------------ */
class ParserSection;
+/// @brief The ParserParameter objects represent the end of tree branches as
+/// they
+/// 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;
-
+ /// Print parameter info in stream
void printself(std::ostream & stream, unsigned int indent = 0) const {
- stream << name << ": " << value
- << " (" << dbg_filename << ":" << dbg_line << ":" << dbg_column << ")";
+ 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..e91e0a691
--- /dev/null
+++ b/src/io/parser/parser_grammar_tmpl.hh
@@ -0,0 +1,82 @@
+/**
+ * @file parsable_tmpl.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Tue Jun 24 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..1f3fc5679
--- /dev/null
+++ b/src/io/parser/parser_input_files.cc
@@ -0,0 +1,97 @@
+/**
+ * @file parser.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Fri Sep 05 2014
+ *
+ * @brief implementation of the parser
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..ccd7ab25b
--- /dev/null
+++ b/src/io/parser/parser_random.cc
@@ -0,0 +1,58 @@
+/**
+ * @file parser.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Fri Sep 05 2014
+ *
+ * @brief implementation of the parser
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..b5a5ecb85
--- /dev/null
+++ b/src/io/parser/parser_real.cc
@@ -0,0 +1,48 @@
+/**
+ * @file parser.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Fri Sep 05 2014
+ *
+ * @brief implementation of the parser
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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 225456d02..5b722dd73 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
*
* @brief Implementation of the parser templated methods
*
* @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__
/* -------------------------------------------------------------------------- */
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 std::string() const {
- return value;
+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..63d2d19ca
--- /dev/null
+++ b/src/io/parser/parser_types.cc
@@ -0,0 +1,58 @@
+/**
+ * @file parser.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Wed Nov 13 2013
+ * @date last modification: Fri Sep 05 2014
+ *
+ * @brief implementation of the parser
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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 269209a5b..e6241ec00 100644
--- a/src/mesh/element_group.cc
+++ b/src/mesh/element_group.cc
@@ -1,165 +1,200 @@
/**
* @file element_group.cc
*
* @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
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @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 <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);
+ 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();
+ elem_list = &elements(type, ghost_type);
+ nb_elem = elem_list->getSize();
}
else {
- elem_list = &(elements.alloc(0, 1, type, ghost_type));
+ 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);
+ 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 << "]" << std::endl;
+ 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 2ac622b6f..38ec48f84 100644
--- a/src/mesh/element_group.hh
+++ b/src/mesh/element_group.hh
@@ -1,175 +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
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @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_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,
+ 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_type_map.hh b/src/mesh/element_type_map.hh
index 246c9431a..5c9121e6d 100644
--- a/src/mesh/element_type_map.hh
+++ b/src/mesh/element_type_map.hh
@@ -1,315 +1,330 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 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 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 1a62a6c1b..f419005ad 100644
--- a/src/mesh/element_type_map_filter.hh
+++ b/src/mesh/element_type_map_filter.hh
@@ -1,316 +1,334 @@
/**
* @file element_type_map_filter.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Tue Sep 02 2014
* @date last modification: Tue Sep 02 2014
*
- * @brief Filtered version based on a an akantu::ElementGroup of a akantu::ElementTypeMap
+ * @brief Filtered version based on a an akantu::ElementGroup of a
+ *akantu::ElementTypeMap
*
* @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_BY_ELEMENT_TYPE_FILTER_HH__
#define __AKANTU_BY_ELEMENT_TYPE_FILTER_HH__
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
/* ArrayFilter */
/* -------------------------------------------------------------------------- */
-template <typename T>
-class 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();};
+ 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{
+ template <template <class S> class original_iterator, typename Shape,
+ typename filter_iterator>
+ class const_iterator {
public:
-
- UInt getCurrentIndex(){throw;};
+ 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){};
+ 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{
+ 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_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{
+
+ 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 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++(){
+
+ inline const_iterator & operator++() {
++sub_element_counter;
- if (sub_element_counter == nb_item_per_elem){
- sub_element_counter = 0;
- ++filter_it;
+ 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];
+ inline Shape operator*() {
+ return origin_it[nb_item_per_elem * (*filter_it) + sub_element_counter];
};
- private:
-
+ private:
original_iterator<Shape> origin_it;
- filter_iterator filter_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> > const_vector_iterator;
+ 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){};
-
- 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 = array.getSize()*array.getNbComponent()/n;
- return const_vector_iterator(array.begin_reinterpret(n,new_full_array_size),filter.begin(),nb_item_per_elem);
+ 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 = array.getSize()*array.getNbComponent()/n;
- return const_vector_iterator(array.begin_reinterpret(n,new_full_array_size),filter.end(),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;};
+ 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 filter.getSize(); };
+ UInt getSize() const {
+ return this->filter.getSize() * this->nb_item_per_elem;
+ };
/// the number of components of the filtered array
- UInt getNbComponent() const{ return array.getNbComponent(); };
+ 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
+ /// reference to the filter used to select elements
const Array<UInt> & filter;
/// the number of item per element
UInt nb_item_per_elem;
-
};
/* -------------------------------------------------------------------------- */
-/* ElementTypeMapFilter */
+/* ElementTypeMapFilter */
/* -------------------------------------------------------------------------- */
-template<class T, typename SupportType = ElementType>
+template <class T, typename SupportType = ElementType>
class ElementTypeMapArrayFilter {
/* ------------------------------------------------------------------------ */
/* Typedefs */
- /* ------------------------------------------------------------------------ */
-
-public:
+ /* ------------------------------------------------------------------------ */
+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;
- typedef typename ElementTypeMapArray<UInt,SupportType>::type_iterator type_iterator;
-
- //class type_iterator{
-
- //public:
-
- // typedef typename ElementTypeMapArray<T,SupportType>::type_iterator type_it;
-
+ // 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_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;};
+ // 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,
- 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(){
- }
+ 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 (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);
+ 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) ;
+ GhostType ghost_type = _not_ghost,
+ ElementKind kind = _ek_not_defined) const {
+ return filter.firstType(dim, _not_ghost, kind);
};
inline type_iterator lastType(UInt dim = _all_dimensions,
- GhostType ghost_type = _not_ghost,
- ElementKind kind = _ek_not_defined) const{
- return filter.lastType(dim,_not_ghost,kind);
+ GhostType ghost_type = _not_ghost,
+ ElementKind kind = _ek_not_defined) const {
+ return filter.lastType(dim, _not_ghost, kind);
};
- ElementTypeMap<UInt> getNbComponents(UInt dim = _all_dimensions,
- GhostType ghost_type = _not_ghost,
- ElementKind kind = _ek_not_defined) const {
- return this->array.getNbComponents(dim,ghost_type,kind);
+ 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());}
-
+ std::string getID() {
+ return std::string("filtered:" + this->array().getID());
+ }
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-
-protected:
- const ElementTypeMapArray<T,SupportType> & array;
- const ElementTypeMapArray<UInt,SupportType> & filter;
+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 f6263e819..f382b45de 100644
--- a/src/mesh/element_type_map_tmpl.hh
+++ b/src/mesh/element_type_map_tmpl.hh
@@ -1,424 +1,457 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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) {
+ 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, T()));
+ 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) {
- this->alloc(size, nb_component, type, _not_ghost);
- this->alloc(size, nb_component, type, _ghost);
+ 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 84cb09b7b..a2e872046 100644
--- a/src/mesh/group_manager.cc
+++ b/src/mesh/group_manager.cc
@@ -1,1010 +1,1014 @@
/**
* @file group_manager.cc
*
* @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>
*
* @date creation: Fri May 03 2013
* @date last modification: Tue Sep 02 2014
*
* @brief Stores information about ElementGroup and NodeGroup
*
* @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 "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 << "_nodes");
+ AKANTU_EXCEPTION("Trying to create a node group that already exists:" << group_name);
}
- NodeGroup * node_group = new NodeGroup(group_name, id + ":" + group_name + "_node_group",
+ 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,
- id + ":" + group_name + "_element_group",
+ sstr.str(),
memory_id);
- node_groups[group_name + "_nodes"] = &new_node_group;
+ 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);
+ 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
- Array<UInt>::iterator<Vector<UInt> > pairs_it = total_pairs.begin(2);
- Array<UInt>::iterator<Vector<UInt> > pairs_end = total_pairs.end(2);
/// 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);
}
- std::list<Element> unseen_elements;
- Element el;
+ 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))
- unseen_elements.push_back(el);
+ 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
- while(!unseen_elements.empty()) {
- /// create a new cluster
- std::stringstream sstr;
- sstr << tmp_cluster_name_prefix << "_" << nb_cluster;
- ElementGroup & cluster = createElementGroup(sstr.str(),
- element_dimension,
- true);
- ++nb_cluster;
-
- /// initialize the queue of elements to check in the current cluster
- std::list<Element>::iterator uns_it = unseen_elements.begin();
- Element uns_el = *uns_it;
- unseen_elements.erase(uns_it);
-
- // point element are cluster by themself
- if(element_dimension == 0) {
- cluster.add(uns_el);
-
- UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(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;
- }
- }
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
- continue;
- }
+ GhostType ghost_type = *gt;
+ Element uns_el;
+ uns_el.ghost_type = ghost_type;
- std::queue<Element> element_to_add;
- element_to_add.push(uns_el);
+ 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);
- /// keep looping until current cluster is complete (no more
- /// connected elements)
- while(!element_to_add.empty()) {
+ 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;
+ }
+ }
- /// take first element and erase it in the queue
- Element el = element_to_add.front();
- element_to_add.pop();
+ 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;
+ /// 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);
+ /// add current element to the cluster
+ cluster.add(el);
- const Array<Element> & element_to_facet
- = mesh_facets->getSubelementToElement(el.type, el.ghost_type);
+ const Array<Element> & element_to_facet
+ = mesh_facets->getSubelementToElement(el.type, el.ghost_type);
- UInt nb_facet_per_element = element_to_facet.getNbComponent();
+ 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);
+ for (UInt f = 0; f < nb_facet_per_element; ++f) {
+ const Element & facet = element_to_facet(el.element, f);
- if (facet == ElementNull) continue;
+ if (facet == ElementNull) continue;
- const std::vector<Element> & connected_elements
- = mesh_facets->getElementToSubelement(facet.type, facet.ghost_type)(facet.element);
+ 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];
+ for (UInt elem = 0; elem < connected_elements.size(); ++elem) {
+ const Element & check_el = connected_elements[elem];
- if (check_el == ElementNull || check_el == el) continue;
+ // check if this element has to be skipped
+ if (check_el == ElementNull || check_el == el) continue;
- std::list<Element>::iterator it_clus = std::find(unseen_elements.begin(),
- unseen_elements.end(),
- check_el);
+ Array<bool> & seen_elements_vec_current
+ = seen_elements(check_el.type, check_el.ghost_type);
- /// if neighbor not seen yet, add it to check list and
- /// remove it from unseen elements
- if(it_clus != unseen_elements.end()) {
- unseen_elements.erase(it_clus);
- element_to_add.push(check_el);
+ 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);
- checked_node(node) = true;
+ 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);
- CSR<Element> node_to_elem;
- MeshUtils::buildNode2Elements(mesh, node_to_elem, dimension);
-
- std::set<Element> seen;
-
- Array<UInt>::const_iterator<> itn = node_group.begin();
- Array<UInt>::const_iterator<> endn = 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(dimension != _all_dimensions && 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 =
- 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 += (node_group.getNodes().find(conn(n)) != -1 ? 1 : 0);
- }
-
- if(count == nb_nodes_per_element) group.add(elem);
-
- seen.insert(elem);
- }
- }
-
- group.optimize();
+ 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 834858173..c93556bf9 100644
--- a/src/mesh/group_manager.hh
+++ b/src/mesh/group_manager.hh
@@ -1,301 +1,304 @@
/**
* @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>
*
* @date creation: Fri May 03 2013
* @date last modification: Fri Sep 05 2014
*
* @brief Stores information relevent to the notion of element and nodes groups.
*
* @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_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,
+ 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,
+ 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,
+ template <typename T,
/// type of InternalMaterialField
- template<typename T, bool filtered> class dump_type>
- inline dumper::Field * createElementalField(const ElementTypeMapArray<T> & field,
+ 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,
+ 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,
+ 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 b7c381090..b5226c4e4 100644
--- a/src/mesh/group_manager_inline_impl.cc
+++ b/src/mesh/group_manager_inline_impl.cc
@@ -1,197 +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
*
* @brief Stores information relevent to the notion of domain boundary and surfaces.
*
* @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_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,
+::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;
- 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);
-}
+ 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>
+template <typename T,
+ template <class> class T2,
+ template <class, template <class> class,bool> class dump_type>
dumper::Field * GroupManager
-::createElementalField(const ElementTypeMapArray<T> & field,
+::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;
- 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);
-}
+ 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,
- /// type of InternalMaterialField
- template<typename T, bool filtered> class dump_type>
-dumper::Field * GroupManager::createElementalField(const ElementTypeMapArray<T> & field,
+template <typename T,
+ template<typename T2, bool filtered> class dump_type> ///< type of InternalMaterialField
+dumper::Field * GroupManager::createElementalField(const ElementTypeMapArray<T> & field,
const std::string & group_name,
UInt spatial_dimension,
const ElementKind & kind,
- ElementTypeMap<UInt> nb_data_per_elem){
-
- if (&field == 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);
+ ElementTypeMap<UInt> nb_data_per_elem) {
+ const ElementTypeMapArray<T> * field_ptr = &field;
+
+ if (field_ptr == NULL) return NULL;
+ if (group_name == "all")
+ return this->createElementalField< dump_type<T,false> >(field,
+ group_name,
+ spatial_dimension,
+ kind,
+ nb_data_per_elem);
+ else
+ return this->createElementalFilteredField< dump_type<T,true> >(field,
+ group_name,
+ spatial_dimension,
+ kind,
+ nb_data_per_elem);
}
/* -------------------------------------------------------------------------- */
template <typename dump_type,typename field_type>
-dumper::Field * GroupManager::createElementalField(const field_type & field,
+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;
+ ElementTypeMap<UInt> nb_data_per_elem) {
+ const field_type * field_ptr = &field;
+ if (field_ptr == NULL) return NULL;
if (group_name != "all") throw;
dumper::Field * dumper = new dump_type(field,spatial_dimension,_not_ghost,kind);
dumper->setNbDataPerElem(nb_data_per_elem);
return dumper;
}
/* -------------------------------------------------------------------------- */
template <typename dump_type,typename field_type>
-dumper::Field * GroupManager::createElementalFilteredField(const field_type & field,
+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;
+ ElementTypeMap<UInt> nb_data_per_elem) {
+
+ const field_type * field_ptr = &field;
+ if (field_ptr == NULL) return NULL;
if (group_name == "all") throw;
typedef typename field_type::type T;
- ElementGroup & group = this->getElementGroup(group_name);
+ 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 =
+ 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);
+ 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 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);
+ 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 dee3fed7c..139386376 100644
--- a/src/mesh/mesh.cc
+++ b/src/mesh/mesh.cc
@@ -1,476 +1,507 @@
/**
* @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>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Sep 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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_internal_material_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const Element ElementNull(_not_defined, 0);
/* -------------------------------------------------------------------------- */
void Element::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Element [" << type << ", " << element << ", " << ghost_type << "]";
}
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
GroupManager(*this, id + ":group_manager", memory_id),
nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
created_nodes(true),
connectivities("connectivities", id),
normals("normals", id),
spatial_dimension(spatial_dimension),
types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
ghost_types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
lower_bounds(spatial_dimension,0.),
upper_bounds(spatial_dimension,0.),
size(spatial_dimension, 0.),
local_lower_bounds(spatial_dimension,0.),
local_upper_bounds(spatial_dimension,0.),
mesh_data("mesh_data", id, memory_id),
mesh_facets(NULL) {
AKANTU_DEBUG_IN();
this->nodes = &(alloc<Real>(id + ":coordinates", 0, this->spatial_dimension));
nb_global_nodes = 0;
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension,
const ID & nodes_id,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
GroupManager(*this, id + ":group_manager", memory_id),
nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
created_nodes(false),
connectivities("connectivities", id),
normals("normals", id),
spatial_dimension(spatial_dimension),
types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
ghost_types_offsets(Array<UInt>((UInt) _max_element_type + 1, 1)),
lower_bounds(spatial_dimension,0.),
upper_bounds(spatial_dimension,0.),
size(spatial_dimension, 0.),
local_lower_bounds(spatial_dimension,0.),
local_upper_bounds(spatial_dimension,0.),
mesh_data("mesh_data", id, memory_id),
mesh_facets(NULL) {
AKANTU_DEBUG_IN();
this->nodes = &(getArray<Real>(nodes_id));
nb_global_nodes = nodes->getSize();
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh::Mesh(UInt spatial_dimension,
Array<Real> & nodes,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
GroupManager(*this, id + ":group_manager", memory_id),
nodes_global_ids(NULL), nodes_type(0, 1, id + ":nodes_type"),
created_nodes(false),
connectivities("connectivities", id),
normals("normals", id),
spatial_dimension(spatial_dimension),
types_offsets(Array<UInt>(_max_element_type + 1, 1)),
ghost_types_offsets(Array<UInt>(_max_element_type + 1, 1)),
lower_bounds(spatial_dimension,0.),
upper_bounds(spatial_dimension,0.),
size(spatial_dimension, 0.),
local_lower_bounds(spatial_dimension,0.),
local_upper_bounds(spatial_dimension,0.),
mesh_data("mesh_data", id, memory_id),
mesh_facets(NULL) {
AKANTU_DEBUG_IN();
this->nodes = &(nodes);
nb_global_nodes = nodes.getSize();
init();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Mesh & Mesh::initMeshFacets(const ID & id) {
AKANTU_DEBUG_IN();
if (!mesh_facets) {
mesh_facets = new Mesh(spatial_dimension,
*(this->nodes),
getID()+":"+id,
getMemoryID());
mesh_facets->mesh_parent = this;
mesh_facets->is_mesh_facets = true;
}
AKANTU_DEBUG_OUT();
return *mesh_facets;
}
/* -------------------------------------------------------------------------- */
void Mesh::defineMeshParent(const Mesh & mesh) {
AKANTU_DEBUG_IN();
this->mesh_parent = &mesh;
this->is_mesh_facets = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Mesh::init() {
this->is_mesh_facets = false;
this->mesh_parent = NULL;
this->is_distributed = false;
// computeBoundingBox();
}
/* -------------------------------------------------------------------------- */
Mesh::~Mesh() {
AKANTU_DEBUG_IN();
delete mesh_facets;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Mesh::read (const std::string & filename, const MeshIOType & mesh_io_type) {
MeshIO mesh_io;
mesh_io.read(filename, *this, mesh_io_type);
type_iterator it = this->firstType(spatial_dimension, _not_ghost, _ek_not_defined);
type_iterator last = this->lastType(spatial_dimension, _not_ghost, _ek_not_defined);
if(it == last) AKANTU_EXCEPTION("The mesh contained in the file " << filename
- << " does not seam to be of the good dimension."
+ << " does not seem to be of the good dimension."
<< " No element of dimension " << spatial_dimension
<< " where read.");
}
/* -------------------------------------------------------------------------- */
void Mesh::write(const std::string & filename, const MeshIOType & mesh_io_type) {
MeshIO mesh_io;
mesh_io.write(filename, *this, mesh_io_type);
}
/* -------------------------------------------------------------------------- */
void Mesh::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Mesh [" << std::endl;
stream << space << " + id : " << getID() << std::endl;
stream << space << " + spatial dimension : " << this->spatial_dimension << std::endl;
stream << space << " + nodes [" << std::endl;
nodes->printself(stream, indent+2);
stream << space << " + connectivities [" << std::endl;
connectivities.printself(stream, indent+2);
stream << space << " ]" << std::endl;
GroupManager::printself(stream, indent + 1);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
void Mesh::computeBoundingBox(){
AKANTU_DEBUG_IN();
for (UInt k = 0; k < spatial_dimension; ++k) {
local_lower_bounds(k) = std::numeric_limits<double>::max();
local_upper_bounds(k) = - std::numeric_limits<double>::max();
}
for (UInt i = 0; i < nodes->getSize(); ++i) {
// if(!isPureGhostNode(i))
for (UInt k = 0; k < spatial_dimension; ++k) {
local_lower_bounds(k) = std::min(local_lower_bounds[k], (*nodes)(i, k));
local_upper_bounds(k) = std::max(local_upper_bounds[k], (*nodes)(i, k));
}
}
if (this->is_distributed) {
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
Real reduce_bounds[2 * spatial_dimension];
for (UInt k = 0; k < spatial_dimension; ++k) {
reduce_bounds[2*k ] = local_lower_bounds(k);
reduce_bounds[2*k + 1] = - local_upper_bounds(k);
}
comm.allReduce(reduce_bounds, 2 * spatial_dimension, _so_min);
for (UInt k = 0; k < spatial_dimension; ++k) {
lower_bounds(k) = reduce_bounds[2*k];
upper_bounds(k) = - reduce_bounds[2*k + 1];
}
}
else {
this->lower_bounds = this->local_lower_bounds;
this->upper_bounds = this->local_upper_bounds;
}
size = upper_bounds - lower_bounds;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T>
void Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
UInt nb_component,
UInt dim,
const bool & flag_nb_node_per_elem_multiply,
ElementKind element_kind,
bool size_to_nb_element) const {
AKANTU_DEBUG_IN();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
this->initElementTypeMapArray(vect, nb_component, dim, gt,
flag_nb_node_per_elem_multiply,
element_kind, size_to_nb_element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<typename T>
void Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
- UInt nb_component,
- UInt dim,
- GhostType gt,
- const bool & flag_nb_node_per_elem_multiply,
- ElementKind element_kind,
- bool size_to_nb_element) const {
+ UInt nb_component,
+ UInt dim,
+ GhostType gt,
+ const bool & flag_nb_node_per_elem_multiply,
+ ElementKind element_kind,
+ bool size_to_nb_element) const {
+ AKANTU_DEBUG_IN();
+
+ this->initElementTypeMapArray(vect,
+ nb_component,
+ dim,
+ gt,
+ T(),
+ flag_nb_node_per_elem_multiply,
+ element_kind,
+ size_to_nb_element);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+void Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
+ UInt nb_component,
+ UInt dim,
+ GhostType gt,
+ const T & default_value,
+ const bool & flag_nb_node_per_elem_multiply,
+ ElementKind element_kind,
+ bool size_to_nb_element) const {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = firstType(dim, gt, element_kind);
Mesh::type_iterator end = lastType(dim, gt, element_kind);
for(; it != end; ++it) {
ElementType type = *it;
- if (flag_nb_node_per_elem_multiply) nb_component *= Mesh::getNbNodesPerElement(*it);
+ UInt nb_comp = nb_component;
+ if (flag_nb_node_per_elem_multiply) nb_comp *= Mesh::getNbNodesPerElement(*it);
UInt size = 0;
if (size_to_nb_element) size = this->getNbElement(type, gt);
- vect.alloc(size, nb_component, type, gt);
+ vect.alloc(size, nb_comp, type, gt, default_value);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Mesh::initNormals() {
- 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) {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = firstType(dimension, ghost_type);
Mesh::type_iterator end = lastType(dimension, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
Array<UInt> & local_conn = connectivities(type, ghost_type);
Array<UInt> & g_connectivity = global_connectivity(type, ghost_type);
if (!nodes_global_ids)
nodes_global_ids = mesh_parent->nodes_global_ids;
UInt * local_c = local_conn.storage();
UInt * global_c = g_connectivity.storage();
UInt nb_terms = local_conn.getSize() * local_conn.getNbComponent();
for (UInt i = 0; i < nb_terms; ++i, ++local_c, ++global_c)
*global_c = (*nodes_global_ids)(*local_c);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Mesh::getGroupDumper(const std::string & dumper_name,
const std::string & group_name){
if (group_name == "all") return this->getDumper(dumper_name);
else return element_groups[group_name]->getDumper(dumper_name);
}
/* -------------------------------------------------------------------------- */
#define AKANTU_INSTANTIATE_INIT(type) \
template void Mesh::initElementTypeMapArray<type>(ElementTypeMapArray<type> & vect, \
- UInt nb_component, \
- UInt dim, \
- const bool & flag_nb_elem_multiply, \
- ElementKind element_kind, \
- bool size_to_nb_element) const; \
+ 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
-
+ UInt nb_component, \
+ UInt dim, \
+ GhostType gt, \
+ const bool & flag_nb_elem_multiply, \
+ ElementKind element_kind, \
+ bool size_to_nb_element) const; \
+template void Mesh::initElementTypeMapArray<type>(ElementTypeMapArray<type> & vect, \
+ UInt nb_component, \
+ UInt dim, \
+ GhostType gt, \
+ const type & default_value, \
+ const bool & flag_nb_elem_multiply, \
+ ElementKind element_kind, \
+ bool size_to_nb_element) const;
+
AKANTU_INSTANTIATE_INIT(Real);
AKANTU_INSTANTIATE_INIT(UInt);
AKANTU_INSTANTIATE_INIT(Int);
AKANTU_INSTANTIATE_INIT(bool);
/* -------------------------------------------------------------------------- */
template <typename T>
ElementTypeMap<UInt> Mesh::getNbDataPerElem(ElementTypeMapArray<T> & array,
const ElementKind & element_kind){
ElementTypeMap<UInt> nb_data_per_elem;
typename ElementTypeMapArray<T>::type_iterator it =
array.firstType(spatial_dimension, _not_ghost,element_kind);
typename ElementTypeMapArray<T>::type_iterator last_type =
array.lastType(spatial_dimension, _not_ghost,element_kind);
for(; it != last_type; ++it) {
UInt nb_elements = this->getNbElement(*it);
nb_data_per_elem(*it) =
array(*it).getNbComponent() *
array(*it).getSize();
nb_data_per_elem(*it) /= nb_elements;
}
return nb_data_per_elem;
}
/* -------------------------------------------------------------------------- */
template
ElementTypeMap<UInt> Mesh::getNbDataPerElem(ElementTypeMapArray<Real> & array,
const ElementKind & element_kind);
template
ElementTypeMap<UInt> Mesh::getNbDataPerElem(ElementTypeMapArray<UInt> & array,
const ElementKind & element_kind);
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
template <typename T>
dumper::Field * Mesh::createFieldFromAttachedData(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind){
dumper::Field * field = NULL;
ElementTypeMapArray<T> * internal = NULL;
try {
internal = &(this->getData<T>(field_id));
}
catch (...){
return NULL;
}
ElementTypeMap<UInt> nb_data_per_elem =
this->getNbDataPerElem(*internal,element_kind);
field =
this->createElementalField<T, dumper::InternalMaterialField>(*internal,
group_name,
this->spatial_dimension,
element_kind,
nb_data_per_elem);
return field;
}
template dumper::Field *
Mesh::createFieldFromAttachedData<Real>(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind);
template dumper::Field *
Mesh::createFieldFromAttachedData<UInt>(const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind);
-
-/* -------------------------------------------------------------------------- */
-
#endif
+/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/mesh/mesh.hh b/src/mesh/mesh.hh
index 86592e534..1e165d4ce 100644
--- a/src/mesh/mesh.hh
+++ b/src/mesh/mesh.hh
@@ -1,624 +1,574 @@
/**
* @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>
*
* @date creation: Fri Jun 18 2010
* @date last modification: Fri Sep 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 */
/* -------------------------------------------------------------------------- */
-template<class Entity>
-class MeshEvent {
-public:
- virtual ~MeshEvent() {}
- const Array<Entity> & getList() const { return list; }
- Array<Entity> & getList() { return list; }
-protected:
- Array<Entity> list;
-};
-
-class Mesh;
-
-class NewNodesEvent : public MeshEvent<UInt> {
-public:
- virtual ~NewNodesEvent() {};
-};
-class RemovedNodesEvent : public MeshEvent<UInt> {
-public:
- virtual ~RemovedNodesEvent() {};
- inline RemovedNodesEvent(const Mesh & mesh);
- AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, Array<UInt> &);
- AKANTU_GET_MACRO(NewNumbering, new_numbering, const Array<UInt> &);
-private:
- Array<UInt> new_numbering;
-};
-
-class NewElementsEvent : public MeshEvent<Element> {
-public:
- virtual ~NewElementsEvent() {};
-};
-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> &);
- AKANTU_GET_MACRO_BY_ELEMENT_TYPE(NewNumbering, new_numbering, UInt);
- AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NewNumbering, new_numbering, UInt);
-protected:
- ElementTypeMapArray<UInt> new_numbering;
-};
-
-/* -------------------------------------------------------------------------- */
-
-class MeshEventHandler {
-public:
- 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); }
+#include "mesh_events.hh"
- 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) { }
-};
/* -------------------------------------------------------------------------- */
/* 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
+
/// 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);
+ // /// 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);
+ static inline MatrixProxy<UInt> getFacetLocalConnectivity(const ElementType & type, UInt t = 0);
/// get connectivity of facets for a given element
- inline Matrix<UInt> getFacetConnectivity(UInt element, const ElementType & type, const GhostType & ghost_type) const;
+ 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);
+ 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
new file mode 100644
index 000000000..f820383aa
--- /dev/null
+++ b/src/mesh/mesh_accessor.hh
@@ -0,0 +1,108 @@
+/**
+ * @file mesh_accessor.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Jun 18 2010
+ * @date last modification: Fri Sep 05 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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.hh b/src/mesh/mesh_data.hh
index 42beadb81..6d7e4dd6a 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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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..852fa8798 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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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
new file mode 100644
index 000000000..bd1acd14e
--- /dev/null
+++ b/src/mesh/mesh_events.hh
@@ -0,0 +1,179 @@
+/**
+ * @file mesh_events.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date Fri Feb 20 10:48:36 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MESH_EVENTS_HH__
+#define __AKANTU_MESH_EVENTS_HH__
+
+/// akantu::MeshEvent is the base event for meshes
+template <class Entity> class MeshEvent {
+public:
+ virtual ~MeshEvent() {}
+ /// Get the list of entity modified by the event nodes or elements
+ const Array<Entity> & getList() const { return list; }
+ /// Get the list of entity modified by the event nodes or elements
+ Array<Entity> & getList() { return list; }
+
+protected:
+ Array<Entity> list;
+};
+
+class Mesh;
+
+/// akantu::MeshEvent related to new nodes in the mesh
+class NewNodesEvent : public MeshEvent<UInt> {
+public:
+ virtual ~NewNodesEvent(){};
+};
+
+/// akantu::MeshEvent related to nodes removed from the mesh
+class RemovedNodesEvent : public MeshEvent<UInt> {
+public:
+ virtual ~RemovedNodesEvent(){};
+ inline RemovedNodesEvent(const Mesh & mesh);
+ /// Get the new numbering following suppression of nodes from nodes arrays
+ AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, Array<UInt> &);
+ /// Get the new numbering following suppression of nodes from nodes arrays
+ AKANTU_GET_MACRO(NewNumbering, new_numbering, const Array<UInt> &);
+
+private:
+ Array<UInt> new_numbering;
+};
+
+/// akantu::MeshEvent related to new elements in the mesh
+class NewElementsEvent : public MeshEvent<Element> {
+public:
+ virtual ~NewElementsEvent(){};
+};
+
+/// akantu::MeshEvent related to elements removed from the mesh
+class RemovedElementsEvent : public MeshEvent<Element> {
+public:
+ virtual ~RemovedElementsEvent(){};
+ inline RemovedElementsEvent(const Mesh & mesh,
+ ID new_numbering_id = "new_numbering");
+ /// Get the new numbering following suppression of elements from elements
+ /// arrays
+ AKANTU_GET_MACRO(NewNumbering, new_numbering,
+ const ElementTypeMapArray<UInt> &);
+ /// Get the new numbering following suppression of elements from elements
+ /// arrays
+ AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering,
+ ElementTypeMapArray<UInt> &);
+ /// Get the new numbering following suppression of elements from elements
+ /// arrays
+ AKANTU_GET_MACRO_BY_ELEMENT_TYPE(NewNumbering, new_numbering, UInt);
+ /// Get the new numbering following suppression of elements from elements
+ /// arrays
+ AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NewNumbering, new_numbering, UInt);
+
+protected:
+ ElementTypeMapArray<UInt> new_numbering;
+};
+
+/// akantu::MeshEvent for element that changed in some sort, can be seen as a
+/// combination of removed and added elements
+class ChangedElementsEvent : public RemovedElementsEvent {
+public:
+ virtual ~ChangedElementsEvent(){};
+ inline ChangedElementsEvent(
+ const Mesh & mesh, ID new_numbering_id = "changed_event:new_numbering")
+ : RemovedElementsEvent(mesh, new_numbering_id){};
+ AKANTU_GET_MACRO(ListOld, list, const Array<Element> &);
+ AKANTU_GET_MACRO_NOT_CONST(ListOld, list, Array<Element> &);
+ AKANTU_GET_MACRO(ListNew, new_list, const Array<Element> &);
+ AKANTU_GET_MACRO_NOT_CONST(ListNew, new_list, Array<Element> &);
+
+protected:
+ Array<Element> new_list;
+};
+
+/* -------------------------------------------------------------------------- */
+
+class MeshEventHandler {
+public:
+ virtual ~MeshEventHandler(){};
+ /* ------------------------------------------------------------------------ */
+ /* Internal code */
+ /* ------------------------------------------------------------------------ */
+private:
+ /// send a akantu::NewNodesEvent
+ inline void sendEvent(const NewNodesEvent & event) {
+ onNodesAdded(event.getList(), event);
+ }
+ /// send a akantu::RemovedNodesEvent
+ inline void sendEvent(const RemovedNodesEvent & event) {
+ onNodesRemoved(event.getList(), event.getNewNumbering(), event);
+ }
+ /// send a akantu::NewElementsEvent
+ inline void sendEvent(const NewElementsEvent & event) {
+ onElementsAdded(event.getList(), event);
+ }
+ /// send a akantu::RemovedElementsEvent
+ inline void sendEvent(const RemovedElementsEvent & event) {
+ onElementsRemoved(event.getList(), event.getNewNumbering(), event);
+ }
+ /// send a akantu::ChangedElementsEvent
+ inline void sendEvent(const ChangedElementsEvent & event) {
+ onElementsChanged(event.getListOld(), event.getListNew(),
+ event.getNewNumbering(), event);
+ }
+ template <class EventHandler> friend class EventHandlerManager;
+
+ /* ------------------------------------------------------------------------ */
+ /* Interface */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// function to implement to react on akantu::NewNodesEvent
+ virtual void onNodesAdded(const Array<UInt> & nodes_list,
+ const NewNodesEvent & event) = 0;
+ /// function to implement to react on akantu::RemovedNodesEvent
+ virtual void onNodesRemoved(const Array<UInt> & nodes_list,
+ const Array<UInt> & new_numbering,
+ const RemovedNodesEvent & event) = 0;
+ /// function to implement to react on akantu::NewElementsEvent
+ virtual void onElementsAdded(__attribute__((unused))
+ const Array<Element> & elements_list,
+ __attribute__((unused))
+ const NewElementsEvent & event) = 0;
+ /// function to implement to react on akantu::RemovedElementsEvent
+ virtual void onElementsRemoved(
+ __attribute__((unused)) const Array<Element> & elements_list,
+ __attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
+ __attribute__((unused)) const RemovedElementsEvent & event) = 0;
+ /// function to implement to react on akantu::ChangedElementsEvent
+ virtual void onElementsChanged(
+ __attribute__((unused)) const Array<Element> & old_elements_list,
+ __attribute__((unused)) const Array<Element> & new_elements_list,
+ __attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
+ __attribute__((unused)) const ChangedElementsEvent & event) = 0;
+};
+
+#endif /* __AKANTU_MESH_EVENTS_HH__ */
diff --git a/src/mesh/mesh_filter.hh b/src/mesh/mesh_filter.hh
index 2562c5484..5fc7ec1f5 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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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
};
};
+/// class (functor) for the node filter
class NodeFilterFunctor : public FilterFunctor {
public:
bool operator()(UInt node) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
public:
static const Type type = _node_filter_functor;
};
+/// class (functor) for the element filter
class ElementFilterFunctor : public FilterFunctor {
public:
bool operator()(const Element & element) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
public:
static const Type type = _element_filter_functor;
};
__END_AKANTU__
#endif /* __AKANTU_MESH_FILTER_HH__ */
diff --git a/src/mesh/mesh_inline_impl.cc b/src/mesh/mesh_inline_impl.cc
index 2bade9ae1..160b2ad57 100644
--- a/src/mesh/mesh_inline_impl.cc
+++ b/src/mesh/mesh_inline_impl.cc
@@ -1,555 +1,600 @@
/**
* @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>
*
* @date creation: Thu Jul 15 2010
* @date last modification: Fri Sep 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_COHESIVE_ELEMENT)
# include "cohesive_element.hh"
#endif
-#if defined(AKANTU_IGFEM)
-# include "igfem_element.hh"
-#endif
#ifndef __AKANTU_MESH_INLINE_IMPL_CC__
#define __AKANTU_MESH_INLINE_IMPL_CC__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
inline RemovedNodesEvent::RemovedNodesEvent(const Mesh & mesh) :
new_numbering(mesh.getNbNodes(), 1, "new_numbering") {
}
/* -------------------------------------------------------------------------- */
-inline RemovedElementsEvent::RemovedElementsEvent(const Mesh & mesh) :
- 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) {
connectivities.onElementsRemoved(event.getNewNumbering());
EventHandlerManager<MeshEventHandler>::sendEvent(event);
}
/* -------------------------------------------------------------------------- */
template <>
inline void Mesh::sendEvent<RemovedNodesEvent>(RemovedNodesEvent & event) {
if(created_nodes) removeNodesFromArray(*nodes , event.getNewNumbering());
if(nodes_global_ids) removeNodesFromArray(*nodes_global_ids, event.getNewNumbering());
if(nodes_type.getSize() != 0) removeNodesFromArray(nodes_type , event.getNewNumbering());
EventHandlerManager<MeshEventHandler>::sendEvent(event);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Mesh::removeNodesFromArray(Array<T> & vect, const Array<UInt> & new_numbering) {
Array<T> tmp(vect.getSize(), vect.getNbComponent());
UInt nb_component = vect.getNbComponent();
UInt new_nb_nodes = 0;
for (UInt i = 0; i < new_numbering.getSize(); ++i) {
UInt new_i = new_numbering(i);
if(new_i != UInt(-1)) {
memcpy(tmp.storage() + new_i * nb_component,
vect.storage() + i * nb_component,
nb_component * sizeof(T));
++new_nb_nodes;
}
}
tmp.resize(new_nb_nodes);
vect.copy(tmp);
}
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_CORE_CXX11
template <typename... Args>
inline void Mesh::translate(Args... params) {
// check that the number of parameters corresponds to the dimension
AKANTU_DEBUG_ASSERT(sizeof...(Args) <= spatial_dimension , "Number of arguments greater than dimension.");
// unpack parameters
Real s[] = { params... };
Array<Real>& nodes = getNodes();
for (UInt i = 0; i < nodes.getSize(); ++i)
for (UInt k = 0; k < sizeof...(Args); ++k)
nodes(i, k) += s[k];
}
#endif
/* -------------------------------------------------------------------------- */
inline UInt Mesh::elementToLinearized(const Element & elem) const {
AKANTU_DEBUG_ASSERT(elem.type < _max_element_type &&
elem.element < types_offsets.storage()[elem.type+1],
"The element " << elem
<< "does not exists in the mesh " << getID());
return types_offsets.storage()[elem.type] + elem.element;
}
/* -------------------------------------------------------------------------- */
inline Element Mesh::linearizedToElement (UInt linearized_element) const {
UInt t;
for (t = _not_defined;
t != _max_element_type && linearized_element >= types_offsets(t);
++t);
AKANTU_DEBUG_ASSERT(linearized_element < types_offsets(t),
"The linearized element " << linearized_element
<< "does not exists in the mesh " << getID());
--t;
ElementType type = ElementType(t);
return Element(type,
linearized_element - types_offsets.storage()[t],
_not_ghost,
getKind(type));
}
/* -------------------------------------------------------------------------- */
inline void Mesh::updateTypesOffsets(const GhostType & ghost_type) {
Array<UInt> * types_offsets_ptr = &this->types_offsets;
if(ghost_type == _ghost) types_offsets_ptr = &this->ghost_types_offsets;
Array<UInt> & types_offsets = *types_offsets_ptr;
types_offsets.clear();
type_iterator it = firstType(_all_dimensions, ghost_type, _ek_not_defined);
type_iterator last = lastType(_all_dimensions, ghost_type, _ek_not_defined);
for (; it != last; ++it)
types_offsets(*it) = connectivities(*it, ghost_type).getSize();
for (UInt t = _not_defined + 1; t < _max_element_type; ++t)
types_offsets(t) += types_offsets(t - 1);
for (UInt t = _max_element_type; t > _not_defined; --t)
types_offsets(t) = types_offsets(t - 1);
types_offsets(0) = 0;
}
/* -------------------------------------------------------------------------- */
inline const Mesh::ConnectivityTypeList & Mesh::getConnectivityTypeList(const GhostType & ghost_type) const {
if (ghost_type == _not_ghost)
return type_set;
else
return ghost_type_set;
}
/* -------------------------------------------------------------------------- */
inline Array<UInt> * Mesh::getNodesGlobalIdsPointer() {
AKANTU_DEBUG_IN();
if(nodes_global_ids == NULL) {
std::stringstream sstr; sstr << getID() << ":nodes_global_ids";
nodes_global_ids = &(alloc<UInt>(sstr.str(), nodes->getSize(), 1));
}
AKANTU_DEBUG_OUT();
return nodes_global_ids;
}
/* -------------------------------------------------------------------------- */
inline Array<Int> * Mesh::getNodesTypePointer() {
AKANTU_DEBUG_IN();
if(nodes_type.getSize() == 0) {
nodes_type.resize(nodes->getSize());
nodes_type.set(-1);
}
AKANTU_DEBUG_OUT();
return &nodes_type;
}
/* -------------------------------------------------------------------------- */
inline Array<UInt> * Mesh::getConnectivityPointer(const ElementType & type,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
Array<UInt> * tmp;
if(!connectivities.exists(type, ghost_type)) {
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
tmp = &(connectivities.alloc(0, nb_nodes_per_element,
type, ghost_type));
AKANTU_DEBUG_INFO("The connectivity vector for the type "
<< type << " created");
if (ghost_type == _not_ghost) type_set.insert(type);
else ghost_type_set.insert(type);
updateTypesOffsets(ghost_type);
} else {
tmp = &connectivities(type, ghost_type);
}
AKANTU_DEBUG_OUT();
return tmp;
}
/* -------------------------------------------------------------------------- */
inline Array< std::vector<Element> > * Mesh::getElementToSubelementPointer(const ElementType & type,
const GhostType & ghost_type) {
Array< std::vector<Element> > * tmp =
getDataPointer< std::vector<Element> >("element_to_subelement", type, ghost_type, 1, true);
return tmp;
}
/* -------------------------------------------------------------------------- */
inline Array<Element > * Mesh::getSubelementToElementPointer(const ElementType & type,
const GhostType & ghost_type) {
Array<Element> * tmp =
getDataPointer<Element>("subelement_to_element", type, ghost_type,
getNbFacetsPerElement(type), true, is_mesh_facets);
return tmp;
}
/* -------------------------------------------------------------------------- */
inline const Array< std::vector<Element> > & Mesh::getElementToSubelement(const ElementType & type,
const GhostType & ghost_type) const {
return getData< std::vector<Element> >("element_to_subelement", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline Array< std::vector<Element> > & Mesh::getElementToSubelement(const ElementType & type,
const GhostType & ghost_type) {
return getData< std::vector<Element> >("element_to_subelement", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline const Array<Element> & Mesh::getSubelementToElement(const ElementType & type,
const GhostType & ghost_type) const {
return getData<Element>("subelement_to_element", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline Array<Element> & Mesh::getSubelementToElement(const ElementType & type,
const GhostType & ghost_type) {
return getData<Element>("subelement_to_element", type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline Array<T> * Mesh::getDataPointer(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type,
UInt nb_component,
bool size_to_nb_element,
bool resize_with_parent) {
Array<T> & tmp = mesh_data.getElementalDataArrayAlloc<T>(data_name,
el_type, ghost_type,
nb_component);
if (size_to_nb_element) {
if (resize_with_parent)
tmp.resize(mesh_parent->getNbElement(el_type, ghost_type));
else
tmp.resize(this->getNbElement(el_type, ghost_type));
} else {
tmp.resize(0);
}
return &tmp;
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline const Array<T> & Mesh::getData(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type) const {
return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline Array<T> & Mesh::getData(const std::string & data_name,
const ElementType & el_type,
const GhostType & ghost_type) {
return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline const ElementTypeMapArray<T> & Mesh::getData(const std::string & data_name) const {
return mesh_data.getElementalData<T>(data_name);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline ElementTypeMapArray<T> & Mesh::getData(const std::string & data_name) {
return mesh_data.getElementalData<T>(data_name);
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline ElementTypeMapArray<T> & Mesh::registerData(const std::string & data_name) {
this->mesh_data.registerElementalData<T>(data_name);
return this->getData<T>(data_name);
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbElement(const ElementType & type,
const GhostType & ghost_type) const {
- AKANTU_DEBUG_IN();
-
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();
UInt nb_element = 0;
type_iterator it = firstType(spatial_dimension, ghost_type, kind);
type_iterator last = lastType(spatial_dimension, ghost_type, kind);
for (; it != last; ++it) nb_element += getNbElement(*it, ghost_type);
- AKANTU_DEBUG_OUT();
return nb_element;
}
/* -------------------------------------------------------------------------- */
inline void Mesh::getBarycenter(UInt element, const ElementType & type,
Real * barycenter,
GhostType ghost_type) const {
- AKANTU_DEBUG_IN();
-
UInt * conn_val = getConnectivity(type, ghost_type).storage();
UInt nb_nodes_per_element = getNbNodesPerElement(type);
Real local_coord[spatial_dimension * nb_nodes_per_element];
UInt offset = element * nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
memcpy(local_coord + n * spatial_dimension,
nodes->storage() + conn_val[offset + n] * spatial_dimension,
spatial_dimension*sizeof(Real));
}
Math::barycenter(local_coord, nb_nodes_per_element, spatial_dimension, barycenter);
-
- AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void Mesh::getBarycenter(const Element & element, Vector<Real> & barycenter) const {
getBarycenter(element.element, element.type, barycenter.storage(), element.ghost_type);
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbNodesPerElement(const ElementType & type) {
UInt nb_nodes_per_element = 0;
#define GET_NB_NODES_PER_ELEMENT(type) \
nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_NODES_PER_ELEMENT);
#undef GET_NB_NODES_PER_ELEMENT
return nb_nodes_per_element;
}
/* -------------------------------------------------------------------------- */
inline ElementType Mesh::getP1ElementType(const ElementType & type) {
ElementType p1_type = _not_defined;
#define GET_P1_TYPE(type) \
p1_type = ElementClass<type>::getP1ElementType()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_P1_TYPE);
#undef GET_P1_TYPE
return p1_type;
}
/* -------------------------------------------------------------------------- */
inline ElementKind Mesh::getKind(const ElementType & type) {
ElementKind kind = _ek_not_defined;
#define GET_KIND(type) \
kind = ElementClass<type>::getKind()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_KIND);
#undef GET_KIND
return kind;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getSpatialDimension(const ElementType & type) {
UInt spatial_dimension = 0;
#define GET_SPATIAL_DIMENSION(type) \
spatial_dimension = ElementClass<type>::getSpatialDimension()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SPATIAL_DIMENSION);
#undef GET_SPATIAL_DIMENSION
return spatial_dimension;
}
/* -------------------------------------------------------------------------- */
-inline ElementType Mesh::getFacetType(const ElementType & type) {
+inline UInt Mesh::getNbFacetTypes(const ElementType & type, UInt t) {
+ UInt nb = 0;
+#define GET_NB_FACET_TYPE(type) \
+ nb = ElementClass<type>::getNbFacetTypes()
+
+ AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET_TYPE);
+#undef GET_NB_FACET_TYPE
+ return nb;
+}
+
+/* -------------------------------------------------------------------------- */
+inline ElementType Mesh::getFacetType(const ElementType & type, UInt t) {
ElementType surface_type = _not_defined;
#define GET_FACET_TYPE(type) \
- surface_type = ElementClass<type>::getFacetType()
+ surface_type = ElementClass<type>::getFacetType(t)
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_TYPE);
#undef GET_FACET_TYPE
return surface_type;
}
+/* -------------------------------------------------------------------------- */
+inline VectorProxy<ElementType> Mesh::getAllFacetTypes(const ElementType & type) {
+#define GET_FACET_TYPE(type) \
+ UInt nb = ElementClass<type>::getNbFacetTypes(); \
+ ElementType * elt_ptr = const_cast<ElementType *>(ElementClass<type>::getFacetTypeInternal()); \
+ return VectorProxy<ElementType>(elt_ptr, nb);
+
+ AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_TYPE);
+#undef GET_FACET_TYPE
+}
+
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbFacetsPerElement(const ElementType & type) {
AKANTU_DEBUG_IN();
UInt n_facet = 0;
#define GET_NB_FACET(type) \
n_facet = ElementClass<type>::getNbFacetsPerElement()
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
#undef GET_NB_FACET
AKANTU_DEBUG_OUT();
return n_facet;
}
/* -------------------------------------------------------------------------- */
-inline MatrixProxy<UInt> Mesh::getFacetLocalConnectivity(const ElementType & type) {
+inline UInt Mesh::getNbFacetsPerElement(const ElementType & type, UInt t) {
AKANTU_DEBUG_IN();
- MatrixProxy<UInt> mat;
+ UInt n_facet = 0;
+#define GET_NB_FACET(type) \
+ n_facet = ElementClass<type>::getNbFacetsPerElement(t)
+
+ AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
+#undef GET_NB_FACET
+
+ AKANTU_DEBUG_OUT();
+ return n_facet;
+}
+
+/* -------------------------------------------------------------------------- */
+inline MatrixProxy<UInt> Mesh::getFacetLocalConnectivity(const ElementType & type, UInt t) {
+ AKANTU_DEBUG_IN();
#define GET_FACET_CON(type) \
- mat = ElementClass<type>::getFacetLocalConnectivityPerElement()
+ AKANTU_DEBUG_OUT(); \
+ return ElementClass<type>::getFacetLocalConnectivityPerElement(t)
AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_CON);
#undef GET_FACET_CON
AKANTU_DEBUG_OUT();
- return mat;
+ return Matrix<UInt>(); // This avoid a compilation warning but will certainly
+ // also cause a segfault if reached
}
/* -------------------------------------------------------------------------- */
-inline Matrix<UInt> Mesh::getFacetConnectivity(UInt element,
- const ElementType & type,
- const GhostType & ghost_type) const {
+inline Matrix<UInt> Mesh::getFacetConnectivity(const Element & element, UInt t) const {
AKANTU_DEBUG_IN();
- Matrix<UInt> local_facets(getFacetLocalConnectivity(type), false);
+ Matrix<UInt> local_facets(getFacetLocalConnectivity(element.type, t), false);
Matrix<UInt> facets(local_facets.rows(), local_facets.cols());
- const Array<UInt> & conn = connectivities(type, ghost_type);
+ 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, local_facets(f, n));
+ facets(f, n) = conn(element.element, local_facets(f, n));
}
}
AKANTU_DEBUG_OUT();
return facets;
}
/* -------------------------------------------------------------------------- */
template<typename T>
inline void Mesh::extractNodalValuesFromElement(const Array<T> & nodal_values,
T * local_coord,
UInt * connectivity,
UInt n_nodes,
UInt nb_degree_of_freedom) const {
for (UInt n = 0; n < n_nodes; ++n) {
memcpy(local_coord + n * nb_degree_of_freedom,
nodal_values.storage() + connectivity[n] * nb_degree_of_freedom,
nb_degree_of_freedom * sizeof(T));
}
}
/* -------------------------------------------------------------------------- */
inline void Mesh::addConnectivityType(const ElementType & type,
const GhostType & ghost_type){
getConnectivityPointer(type, ghost_type);
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isPureGhostNode(UInt n) const {
return nodes_type.getSize() ? (nodes_type(n) == -3) : false;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isLocalOrMasterNode(UInt n) const {
return nodes_type.getSize() ? (nodes_type(n) == -2) || (nodes_type(n) == -1) : true;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isLocalNode(UInt n) const {
return nodes_type.getSize() ? nodes_type(n) == -1 : true;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isMasterNode(UInt n) const {
return nodes_type.getSize() ? nodes_type(n) == -2 : false;
}
/* -------------------------------------------------------------------------- */
inline bool Mesh::isSlaveNode(UInt n) const {
return nodes_type.getSize() ? nodes_type(n) >= 0 : false;
}
/* -------------------------------------------------------------------------- */
inline Int Mesh::getNodeType(UInt local_id) const {
return nodes_type.getSize() ? nodes_type(local_id) : -1;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNodeGlobalId(UInt local_id) const {
return nodes_global_ids ? (*nodes_global_ids)(local_id) : local_id;
}
/* -------------------------------------------------------------------------- */
inline UInt Mesh::getNbGlobalNodes() const {
return nodes_global_ids ? nb_global_nodes : nodes->getSize();
}
/* -------------------------------------------------------------------------- */
+inline UInt Mesh::getNbNodesPerElementList(const Array<Element> & elements) {
+ UInt nb_nodes_per_element = 0;
+ UInt nb_nodes = 0;
+ ElementType current_element_type = _not_defined;
+
+ Array<Element>::const_iterator<Element> el_it = elements.begin();
+ Array<Element>::const_iterator<Element> el_end = elements.end();
+
+ for (; el_it != el_end; ++el_it) {
+ const Element & el = *el_it;
+
+ if(el.type != current_element_type) {
+ current_element_type = el.type;
+ nb_nodes_per_element = Mesh::getNbNodesPerElement(current_element_type);
+ }
+
+ nb_nodes += nb_nodes_per_element;
+ }
+
+ return nb_nodes;
+}
+/* -------------------------------------------------------------------------- */
+
__END_AKANTU__
#endif /* __AKANTU_MESH_INLINE_IMPL_CC__ */
diff --git a/src/mesh/node_group.cc b/src/mesh/node_group.cc
index f9d355c8e..04b54fefb 100644
--- a/src/mesh/node_group.cc
+++ b/src/mesh/node_group.cc
@@ -1,91 +1,110 @@
/**
* @file node_group.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Mon Jun 09 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 std::string & id,
+ const Mesh & mesh,
+ const std::string & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
name(name),
- node_group(alloc<UInt>(id + ":nodes", 0, 1)) {
+ 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 07fc695ad..5b3a1e9b2 100644
--- a/src/mesh/node_group.hh
+++ b/src/mesh/node_group.hh
@@ -1,126 +1,133 @@
/**
* @file node_group.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Mon Jun 09 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 : Memory {
+class NodeGroup : public Memory, public Dumpable {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
NodeGroup(const std::string & name,
+ const Mesh & mesh,
const std::string & id = "node_group",
const MemoryID & memory_id = 0);
virtual ~NodeGroup();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
typedef Array<UInt>::const_iterator<UInt> const_node_iterator;
/// empty the node group
void empty();
/// iterator to the beginning of the node group
inline const_node_iterator begin() const;
/// iterator to the end of the node group
inline const_node_iterator end() const;
/// add a node and give the local position through an iterator
inline const_node_iterator add(UInt node, bool check_for_duplicate = true);
/// remove duplicated nodes
void optimize();
/// append a group to current one
void append(const NodeGroup & other_group);
/// apply a filter on current node group
template <typename T>
void applyNodeFilter(T & filter);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO_NOT_CONST(Nodes, node_group, Array<UInt> &);
AKANTU_GET_MACRO(Nodes, node_group, const Array<UInt> &);
AKANTU_GET_MACRO(Name, name, const std::string &);
/// give the number of nodes in the current group
inline UInt getSize() const;
+ UInt * storage(){return node_group.storage();};
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// name of the group
std::string name;
/// list of nodes in the group
Array<UInt> & node_group;
+
+ /// reference to the mesh in question
+ //const Mesh & mesh;
};
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const NodeGroup & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "node_group_inline_impl.cc"
#endif /* __AKANTU_NODE_GROUP_HH__ */
diff --git a/src/mesh/node_group_inline_impl.cc b/src/mesh/node_group_inline_impl.cc
index 040dfb403..08d36c1fd 100644
--- a/src/mesh/node_group_inline_impl.cc
+++ b/src/mesh/node_group_inline_impl.cc
@@ -1,88 +1,88 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 032b42b07..6fa11dc03 100644
--- a/src/mesh_utils/cohesive_element_inserter.cc
+++ b/src/mesh_utils/cohesive_element_inserter.cc
@@ -1,350 +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
*
* @brief Cohesive element inserter functions
*
* @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 <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::insertElements() {
+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;
- MeshUtils::insertCohesiveElements(mesh,
- mesh_facets,
- insertion_facets,
- node_event.getList(),
- element_event.getList());
+ 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();
- UInt nb_new_elements = element_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);
}
- AKANTU_DEBUG_OUT();
+ 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 b5b5fe5d1..6c1a14248 100644
--- a/src/mesh_utils/cohesive_element_inserter.hh
+++ b/src/mesh_utils/cohesive_element_inserter.hh
@@ -1,192 +1,204 @@
/**
* @file cohesive_element_inserter.hh
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Wed Dec 04 2013
* @date last modification: Tue Jul 29 2014
*
* @brief Cohesive element inserter
*
* @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_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();
- /// insert extrinsic cohesive elements
- void insertElements();
+ /// 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..178abb647
--- /dev/null
+++ b/src/mesh_utils/global_ids_updater.cc
@@ -0,0 +1,44 @@
+/**
+ * @file global_ids_updater.cc
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @date Fri Oct 2 13:44:02 2015
+ *
+ * @brief Functions of the GlobalIdsUpdater
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..380866a83
--- /dev/null
+++ b/src/mesh_utils/global_ids_updater.hh
@@ -0,0 +1,83 @@
+/**
+ * @file global_ids_updater.hh
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @date Fri Oct 2 13:21:44 2015
+ *
+ * @brief Class that updates the global ids of new nodes that are
+ * inserted in the mesh. The functions in this class must be called
+ * after updating the node types
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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..05e7909a0
--- /dev/null
+++ b/src/mesh_utils/global_ids_updater_inline_impl.cc
@@ -0,0 +1,120 @@
+/**
+ * @file global_ids_updater_inline_impl.cc
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @date Fri Oct 2 13:33:44 2015
+ *
+ * @brief Implementation of the inline functions of GlobalIdsUpdater
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * 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.hh b/src/mesh_utils/mesh_partition.hh
index 7036e31e3..62cb97ec8 100644
--- a/src/mesh_utils/mesh_partition.hh
+++ b/src/mesh_utils/mesh_partition.hh
@@ -1,149 +1,149 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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..d234d80e3 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
+++ b/src/mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
@@ -1,138 +1,138 @@
/**
* @file mesh_partition_mesh_data.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Fri May 03 2013
* @date last modification: Thu Jul 31 2014
*
* @brief implementation of the MeshPartitionMeshData 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 "mesh_partition_mesh_data.hh"
#if !defined(AKANTU_NDEBUG)
#include <set>
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
MeshPartitionMeshData::MeshPartitionMeshData(const Mesh & mesh, UInt spatial_dimension,
const ID & id,
const MemoryID & memory_id) :
MeshPartition(mesh, spatial_dimension, id, memory_id) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
MeshPartitionMeshData::MeshPartitionMeshData(const Mesh & mesh,
const ElementTypeMapArray<UInt> & mapping,
UInt spatial_dimension,
const ID & id,
const MemoryID & memory_id) :
MeshPartition(mesh, spatial_dimension, id, memory_id), partition_mapping(&mapping) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::partitionate(UInt nb_part,
const EdgeLoadFunctor & edge_load_func,
const Array<UInt> & pairs) {
AKANTU_DEBUG_IN();
tweakConnectivity(pairs);
nb_partitions = nb_part;
GhostType ghost_type = _not_ghost;
UInt spatial_dimension = mesh.getSpatialDimension();
Mesh::type_iterator it = mesh.firstType(spatial_dimension,
ghost_type,
_ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension,
ghost_type,
_ek_not_defined);
UInt linearized_el = 0;
UInt nb_elements = mesh.getNbElement(mesh.getSpatialDimension(), ghost_type);
Int * partition_list = new Int[nb_elements];
#if !defined(AKANTU_NDEBUG)
std::set<UInt> partitions;
#endif
for(; it != end; ++it) {
ElementType type = *it;
const Array<UInt> & partition_array = (*partition_mapping)(type, ghost_type);
Array<UInt>::const_iterator< Vector<UInt> > p_it = partition_array.begin(1);
Array<UInt>::const_iterator< Vector<UInt> > p_end = partition_array.end(1);
- AKANTU_DEBUG_ASSERT(p_end-p_it == mesh.getNbElement(type, ghost_type),
+ AKANTU_DEBUG_ASSERT(UInt(p_end - p_it) == mesh.getNbElement(type, ghost_type),
"The partition mapping does not have the right number "
<< "of entries for type " << type << " and ghost type "
<< ghost_type << "." << " Tags=" << p_end-p_it
<< " Mesh=" << mesh.getNbElement(type, ghost_type));
for(; p_it != p_end; ++p_it, ++linearized_el) {
partition_list[linearized_el] = (*p_it)(0);
#if !defined(AKANTU_NDEBUG)
partitions.insert((*p_it)(0));
#endif
}
}
#if !defined(AKANTU_NDEBUG)
AKANTU_DEBUG_ASSERT(partitions.size() == nb_part, "The number of real partitions does not match with the number of asked partitions");
#endif
fillPartitionInformation(mesh, partition_list);
delete[] partition_list;
restoreConnectivity();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::reorder() {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::setPartitionMapping(const ElementTypeMapArray<UInt> & mapping) {
partition_mapping = &mapping;
}
/* -------------------------------------------------------------------------- */
void MeshPartitionMeshData::setPartitionMappingFromMeshData(const std::string & data_name) {
partition_mapping = &(mesh.getData<UInt>(data_name));
}
__END_AKANTU__
diff --git a/src/mesh_utils/mesh_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 2d4935129..9528921d7 100644
--- a/src/mesh_utils/mesh_utils.cc
+++ b/src/mesh_utils/mesh_utils.cc
@@ -1,2033 +1,2204 @@
/**
* @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>
*
* @date creation: Fri Aug 20 2010
* @date last modification: Mon Jun 09 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "mesh_utils.hh"
#include "aka_safe_enum.hh"
#include "fe_engine.hh"
/* -------------------------------------------------------------------------- */
+#include <limits>
#include <numeric>
+#include <queue>
+#include <set>
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
void MeshUtils::buildNode2Elements(const Mesh & mesh,
CSR<Element> & node_to_elem,
UInt spatial_dimension) {
AKANTU_DEBUG_IN();
if (spatial_dimension == _all_dimensions) spatial_dimension = mesh.getSpatialDimension();
/// count number of occurrence of each node
UInt nb_nodes = mesh.getNbNodes();
/// array for the node-element list
node_to_elem.resizeRows(nb_nodes);
node_to_elem.clearRows();
AKANTU_DEBUG_ASSERT(mesh.firstType(spatial_dimension) !=
mesh.lastType(spatial_dimension),
"Some elements must be found in right dimension to compute facets!");
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
Mesh::type_iterator first = mesh.firstType(spatial_dimension, *gt, _ek_not_defined);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, *gt, _ek_not_defined);
for (; first != last; ++first) {
ElementType type = *first;
UInt nb_element = mesh.getNbElement(type, *gt);
Array<UInt>::const_iterator< Vector<UInt> > conn_it =
mesh.getConnectivity(type, *gt).begin(Mesh::getNbNodesPerElement(type));
for (UInt el = 0; el < nb_element; ++el, ++conn_it)
for (UInt n = 0; n < conn_it->size(); ++n)
++node_to_elem.rowOffset((*conn_it)(n));
}
}
node_to_elem.countToCSR();
node_to_elem.resizeCols();
/// rearrange element to get the node-element list
Element e;
node_to_elem.beginInsertions();
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
Mesh::type_iterator first = mesh.firstType(spatial_dimension, *gt, _ek_not_defined);
Mesh::type_iterator last = mesh.lastType(spatial_dimension, *gt, _ek_not_defined);
e.ghost_type = *gt;
for (; first != last; ++first) {
ElementType type = *first;
e.type = type;
e.kind = Mesh::getKind(type);
UInt nb_element = mesh.getNbElement(type, *gt);
Array<UInt>::const_iterator< Vector<UInt> > conn_it =
mesh.getConnectivity(type, *gt).begin(Mesh::getNbNodesPerElement(type));
for (UInt el = 0; el < nb_element; ++el, ++conn_it) {
e.element = el;
for (UInt n = 0; n < conn_it->size(); ++n)
node_to_elem.insertInRow((*conn_it)(n), e);
}
}
}
node_to_elem.endInsertions();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* This function should disappear in the future (used in mesh partitioning)
*/
void MeshUtils::buildNode2Elements(const Mesh & mesh,
CSR<UInt> & node_to_elem,
UInt spatial_dimension) {
AKANTU_DEBUG_IN();
if (spatial_dimension == _all_dimensions) spatial_dimension = mesh.getSpatialDimension();
UInt nb_nodes = mesh.getNbNodes();
const Mesh::ConnectivityTypeList & type_list = mesh.getConnectivityTypeList();
Mesh::ConnectivityTypeList::const_iterator it;
UInt nb_types = type_list.size();
UInt nb_good_types = 0;
UInt nb_nodes_per_element[nb_types];
UInt * conn_val[nb_types];
UInt nb_element[nb_types];
for(it = type_list.begin(); it != type_list.end(); ++it) {
ElementType type = *it;
if(Mesh::getSpatialDimension(type) != spatial_dimension) continue;
nb_nodes_per_element[nb_good_types] = Mesh::getNbNodesPerElement(type);
conn_val[nb_good_types] = mesh.getConnectivity(type, _not_ghost).storage();
nb_element[nb_good_types] = mesh.getConnectivity(type, _not_ghost).getSize();
nb_good_types++;
}
AKANTU_DEBUG_ASSERT(nb_good_types != 0,
"Some elements must be found in right dimension to compute facets!");
/// array for the node-element list
node_to_elem.resizeRows(nb_nodes);
node_to_elem.clearRows();
/// count number of occurrence of each node
for (UInt t = 0; t < nb_good_types; ++t) {
for (UInt el = 0; el < nb_element[t]; ++el) {
UInt el_offset = el*nb_nodes_per_element[t];
for (UInt n = 0; n < nb_nodes_per_element[t]; ++n) {
++node_to_elem.rowOffset(conn_val[t][el_offset + n]);
}
}
}
node_to_elem.countToCSR();
node_to_elem.resizeCols();
node_to_elem.beginInsertions();
/// rearrange element to get the node-element list
for (UInt t = 0, linearized_el = 0; t < nb_good_types; ++t)
for (UInt el = 0; el < nb_element[t]; ++el, ++linearized_el) {
UInt el_offset = el*nb_nodes_per_element[t];
for (UInt n = 0; n < nb_nodes_per_element[t]; ++n)
node_to_elem.insertInRow(conn_val[t][el_offset + n], linearized_el);
}
node_to_elem.endInsertions();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildNode2ElementsElementTypeMap(const Mesh & mesh,
CSR<UInt> & node_to_elem,
const ElementType & type,
const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_elements = mesh.getConnectivity(type, ghost_type).getSize();
UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
/// array for the node-element list
node_to_elem.resizeRows(nb_nodes);
node_to_elem.clearRows();
/// count number of occurrence of each node
for (UInt el = 0; el < nb_elements; ++el) {
UInt el_offset = el*nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n)
++node_to_elem.rowOffset(conn_val[el_offset + n]);
}
/// convert the occurrence array in a csr one
node_to_elem.countToCSR();
node_to_elem.resizeCols();
node_to_elem.beginInsertions();
/// save the element index in the node-element list
for (UInt el = 0; el < nb_elements; ++el) {
UInt el_offset = el*nb_nodes_per_element;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
node_to_elem.insertInRow(conn_val[el_offset + n], el);
}
}
node_to_elem.endInsertions();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildFacets(Mesh & mesh){
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
mesh.getConnectivity(*it, *gt).resize(0);
// \todo inform the mesh event handler
}
}
buildFacetsDimension(mesh,
mesh,
true,
spatial_dimension);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildAllFacets(const Mesh & mesh,
Mesh & mesh_facets,
UInt to_dimension,
DistributedSynchronizer * synchronizer) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
buildAllFacets(mesh, mesh_facets, spatial_dimension, to_dimension, synchronizer);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildAllFacets(const Mesh & mesh,
Mesh & mesh_facets,
UInt from_dimension,
UInt to_dimension,
DistributedSynchronizer * synchronizer) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(mesh_facets.isMeshFacets(),
"The mesh_facets should be initialized with initMeshFacets");
const ElementTypeMapArray<UInt> * prank_to_element = NULL;
if (synchronizer) {
synchronizer->buildPrankToElement();
prank_to_element = &synchronizer->getPrankToElement();
}
/// generate facets
buildFacetsDimension(mesh,
mesh_facets,
false,
from_dimension,
prank_to_element);
/// copy nodes type
mesh_facets.nodes_type.resize(mesh.nodes_type.getSize());
mesh_facets.nodes_type.copy(mesh.nodes_type);
/// sort facets and generate subfacets
for (UInt i = from_dimension - 1; i > to_dimension; --i) {
buildFacetsDimension(mesh_facets,
mesh_facets,
false,
i,
prank_to_element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::buildFacetsDimension(const Mesh & mesh,
Mesh & mesh_facets,
bool boundary_only,
UInt dimension,
const ElementTypeMapArray<UInt> * prank_to_element){
AKANTU_DEBUG_IN();
// save the current parent of mesh_facets and set it temporarly to mesh since
// mesh is the one containing the elements for which mesh_facets has the subelements
// example: if the function is called with mesh = mesh_facets
const Mesh & mesh_facets_parent = mesh_facets.getMeshParent();
mesh_facets.defineMeshParent(mesh);
UInt spatial_dimension = mesh.getSpatialDimension();
const Array<Real> & mesh_facets_nodes = mesh_facets.getNodes();
const Array<Real>::const_vector_iterator mesh_facets_nodes_it =
mesh_facets_nodes.begin(spatial_dimension);
CSR<Element> node_to_elem;
buildNode2Elements(mesh, node_to_elem, dimension);
Array<UInt> counter;
+ std::vector<Element> connected_elements;
+ // init the SubelementToElement data to improve performance
+ for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ GhostType ghost_type = *gt;
+ Mesh::type_iterator first = mesh.firstType(dimension, ghost_type);
+ Mesh::type_iterator last = mesh.lastType(dimension, ghost_type);
+
+ for(; first != last; ++first) {
+ ElementType type = *first;
+
+ mesh_facets.getSubelementToElementPointer(type, ghost_type);
+
+ Vector<ElementType> facet_types = mesh.getAllFacetTypes(type);
+
+ for (UInt ft = 0; ft < facet_types.size(); ++ft) {
+ ElementType facet_type = facet_types(ft);
+ mesh_facets.getElementToSubelementPointer(facet_type, ghost_type);
+ mesh_facets.getConnectivityPointer(facet_type, ghost_type);
+ }
+ }
+ }
Element current_element;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
GhostType facet_ghost_type = ghost_type;
current_element.ghost_type = ghost_type;
Mesh::type_iterator first = mesh.firstType(dimension, ghost_type);
Mesh::type_iterator last = mesh.lastType(dimension, ghost_type);
for(; first != last; ++first) {
ElementType type = *first;
- ElementType facet_type = mesh.getFacetType(type);
+ Vector<ElementType> facet_types = mesh.getAllFacetTypes(type);
current_element.type = type;
- UInt nb_element = mesh.getNbElement(type, ghost_type);
- Array< std::vector<Element> > * element_to_subelement =
- mesh_facets.getElementToSubelementPointer(facet_type, ghost_type);
- Array<UInt> * connectivity_facets =
- mesh_facets.getConnectivityPointer(facet_type, ghost_type);
-
- for (UInt el = 0; el < nb_element; ++el) {
- current_element.element = el;
- Matrix<UInt> facets = mesh.getFacetConnectivity(el, type, ghost_type);
- UInt nb_nodes_per_facet = facets.cols();
-
- for (UInt f = 0; f < facets.rows(); ++f) {
- Vector<UInt> facet(nb_nodes_per_facet);
- for (UInt n = 0; n < nb_nodes_per_facet; ++n) facet(n) = facets(f, n);
-
- UInt first_node_nb_elements = node_to_elem.getNbCols(facets(f, 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);
+ 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;
- Array<Element> connected_elements;
- 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);
+ // 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.getSize(); ++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);
+ 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);
}
-
- 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.getConnectivityPointer(facet_type, facet_ghost_type);
- element_to_subelement = mesh_facets.getElementToSubelementPointer(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));
+ /// 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);
+ element_to_subelement->push_back(elements);
+ connectivity_facets->push_back(facet);
- /// current facet index
- UInt current_facet = connectivity_facets->getSize() - 1;
+ /// 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];
+ /// 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) {
+ if (loc_el.type != _not_defined) {
- Array<Element> & subelement_to_element =
- *mesh_facets.getSubelementToElementPointer(type, loc_el.ghost_type);
+ Array<Element> & subelement_to_element =
+ mesh_facets.getSubelementToElement(loc_el.type, loc_el.ghost_type);
- for (UInt f_in = 0; f_in < facets.rows(); ++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;
+ 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);
+ /// reset connectivity in case a facet was found in
+ /// between ghost and normal elements
+ if (facet_ghost_type != ghost_type) {
+ facet_ghost_type = ghost_type;
+ connectivity_facets = mesh_facets.getConnectivityPointer(facet_type, facet_ghost_type);
+ element_to_subelement = mesh_facets.getElementToSubelementPointer(facet_type, facet_ghost_type);
+ }
}
}
}
}
}
}
}
}
-
// restore the parent of mesh_facet
mesh_facets.defineMeshParent(mesh_facets_parent);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::renumberMeshNodes(Mesh & mesh,
UInt * local_connectivities,
UInt nb_local_element,
UInt nb_ghost_element,
ElementType type,
Array<UInt> & old_nodes_numbers) {
AKANTU_DEBUG_IN();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
std::map<UInt, UInt> renumbering_map;
for (UInt i = 0; i < old_nodes_numbers.getSize(); ++i) {
renumbering_map[old_nodes_numbers(i)] = i;
}
/// renumber the nodes
renumberNodesInConnectivity(local_connectivities,
(nb_local_element + nb_ghost_element)*nb_nodes_per_element,
renumbering_map);
std::map<UInt, UInt>::iterator it = renumbering_map.begin();
std::map<UInt, UInt>::iterator end = renumbering_map.end();
old_nodes_numbers.resize(renumbering_map.size());
for (;it != end; ++it) {
old_nodes_numbers(it->second) = it->first;
}
renumbering_map.clear();
/// copy the renumbered connectivity to the right place
Array<UInt> * local_conn = mesh.getConnectivityPointer(type);
local_conn->resize(nb_local_element);
memcpy(local_conn->storage(),
local_connectivities,
nb_local_element * nb_nodes_per_element * sizeof(UInt));
Array<UInt> * ghost_conn = mesh.getConnectivityPointer(type, _ghost);
ghost_conn->resize(nb_ghost_element);
memcpy(ghost_conn->storage(),
local_connectivities + nb_local_element * nb_nodes_per_element,
nb_ghost_element * nb_nodes_per_element * sizeof(UInt));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::renumberNodesInConnectivity(UInt * list_nodes,
UInt nb_nodes,
std::map<UInt, UInt> & renumbering_map) {
AKANTU_DEBUG_IN();
UInt * connectivity = list_nodes;
UInt new_node_num = renumbering_map.size();
for (UInt n = 0; n < nb_nodes; ++n, ++connectivity) {
UInt & node = *connectivity;
std::map<UInt, UInt>::iterator it = renumbering_map.find(node);
if(it == renumbering_map.end()) {
UInt old_node = node;
renumbering_map[old_node] = new_node_num;
node = new_node_num;
++new_node_num;
} else {
node = it->second;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::purifyMesh(Mesh & mesh) {
AKANTU_DEBUG_IN();
std::map<UInt, UInt> renumbering_map;
RemovedNodesEvent remove_nodes(mesh);
Array<UInt> & nodes_removed = remove_nodes.getList();
for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
GhostType ghost_type = (GhostType) gt;
Mesh::type_iterator it = mesh.firstType(_all_dimensions, ghost_type, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType(_all_dimensions, ghost_type, _ek_not_defined);
for(; it != end; ++it) {
ElementType type(*it);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
const Array<UInt> & connectivity_vect = mesh.getConnectivity(type, ghost_type);
UInt nb_element(connectivity_vect.getSize());
UInt * connectivity = connectivity_vect.storage();
renumberNodesInConnectivity (connectivity, nb_element*nb_nodes_per_element, renumbering_map);
}
}
Array<UInt> & new_numbering = remove_nodes.getNewNumbering();
std::fill(new_numbering.begin(), new_numbering.end(), UInt(-1));
std::map<UInt, UInt>::iterator it = renumbering_map.begin();
std::map<UInt, UInt>::iterator end = renumbering_map.end();
for (; it != end; ++it) {
new_numbering(it->first) = it->second;
}
for (UInt i = 0; i < new_numbering.getSize(); ++i) {
if(new_numbering(i) == UInt(-1))
nodes_removed.push_back(i);
}
mesh.sendEvent(remove_nodes);
AKANTU_DEBUG_OUT();
}
#if defined(AKANTU_COHESIVE_ELEMENT)
/* -------------------------------------------------------------------------- */
-void MeshUtils::insertCohesiveElements(Mesh & mesh,
+UInt MeshUtils::insertCohesiveElements(Mesh & mesh,
Mesh & mesh_facets,
const ElementTypeMapArray<bool> & facet_insertion,
Array<UInt> & doubled_nodes,
- Array<Element> & new_elements) {
- AKANTU_DEBUG_IN();
-
+ Array<Element> & new_elements,
+ bool only_double_facets) {
UInt spatial_dimension = mesh.getSpatialDimension();
+ UInt elements_to_insert = updateFacetToDouble(mesh_facets, facet_insertion);
- if (updateFacetToDouble(mesh_facets, facet_insertion)) {
+ if (elements_to_insert > 0) {
if (spatial_dimension == 1) {
doublePointFacet(mesh, mesh_facets, doubled_nodes);
}
else {
doubleFacet(mesh, mesh_facets, spatial_dimension - 1,
doubled_nodes, true);
findSubfacetToDouble<false>(mesh, mesh_facets);
if (spatial_dimension == 2) {
doubleSubfacet<2>(mesh, mesh_facets, doubled_nodes);
}
else if (spatial_dimension == 3) {
doubleFacet(mesh, mesh_facets, 1, doubled_nodes, false);
findSubfacetToDouble<true>(mesh, mesh_facets);
doubleSubfacet<3>(mesh, mesh_facets, doubled_nodes);
}
}
- updateCohesiveData(mesh, mesh_facets, new_elements);
+ if (!only_double_facets)
+ updateCohesiveData(mesh, mesh_facets, new_elements);
}
- AKANTU_DEBUG_OUT();
+ return elements_to_insert;
}
#endif
/* -------------------------------------------------------------------------- */
void MeshUtils::doubleNodes(Mesh & mesh,
- const Array<UInt> & old_nodes,
+ 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.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.getSize();
+ UInt new_nb_doubled_nodes = old_nb_doubled_nodes + old_nodes.size();
position.resize(new_nb_nodes);
doubled_nodes.resize(new_nb_doubled_nodes);
Array<Real>::iterator<Vector<Real> > position_begin
= position.begin(spatial_dimension);
- for (UInt n = 0; n < old_nodes.getSize(); ++n) {
+ 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, 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,
+ std::copy(position_begin + old_nodes[n],
+ position_begin + old_nodes[n] + 1,
position_begin + new_node);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::doubleFacet(Mesh & mesh,
Mesh & mesh_facets,
UInt facet_dimension,
Array<UInt> & doubled_nodes,
bool facet_mode) {
AKANTU_DEBUG_IN();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(facet_dimension, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(facet_dimension, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
if (nb_facet_to_double == 0) continue;
ElementType type_subfacet = Mesh::getFacetType(type_facet);
const UInt nb_subfacet_per_facet = Mesh::getNbFacetsPerElement(type_facet);
GhostType gt_subfacet = _casper;
Array<std::vector<Element> > * f_to_subfacet = NULL;
Array<Element> & subfacet_to_facet
= mesh_facets.getSubelementToElement(type_facet, gt_facet);
Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
UInt nb_nodes_per_facet = conn_facet.getNbComponent();
UInt old_nb_facet = conn_facet.getSize();
UInt new_nb_facet = old_nb_facet + nb_facet_to_double;
conn_facet.resize(new_nb_facet);
subfacet_to_facet.resize(new_nb_facet);
UInt new_facet = old_nb_facet - 1;
Element new_facet_el(type_facet, 0, gt_facet);
Array<Element>::iterator<Vector<Element> > subfacet_to_facet_begin
= subfacet_to_facet.begin(nb_subfacet_per_facet);
Array<UInt>::iterator<Vector<UInt> > conn_facet_begin
= conn_facet.begin(nb_nodes_per_facet);
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
++new_facet;
/// adding a new facet by copying original one
/// copy connectivity in new facet
std::copy(conn_facet_begin + old_facet,
conn_facet_begin + old_facet + 1,
conn_facet_begin + new_facet);
/// update subfacet_to_facet
std::copy(subfacet_to_facet_begin + old_facet,
subfacet_to_facet_begin + old_facet + 1,
subfacet_to_facet_begin + new_facet);
new_facet_el.element = new_facet;
/// loop on every subfacet
for (UInt sf = 0; sf < nb_subfacet_per_facet; ++sf) {
Element & subfacet = subfacet_to_facet(old_facet, sf);
if (subfacet == ElementNull) continue;
if (gt_subfacet != subfacet.ghost_type) {
gt_subfacet = subfacet.ghost_type;
f_to_subfacet = & mesh_facets.getElementToSubelement(type_subfacet,
subfacet.ghost_type);
}
/// update facet_to_subfacet array
(*f_to_subfacet)(subfacet.element).push_back(new_facet_el);
}
}
/// update facet_to_subfacet and _segment_3 facets if any
if (!facet_mode) {
updateSubfacetToFacet(mesh_facets, type_facet, gt_facet, true);
updateFacetToSubfacet(mesh_facets, type_facet, gt_facet, true);
updateQuadraticSegments<true>(mesh, mesh_facets, type_facet,
gt_facet, doubled_nodes);
}
else
updateQuadraticSegments<false>(mesh, mesh_facets, type_facet,
gt_facet, doubled_nodes);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-bool MeshUtils::updateFacetToDouble(Mesh & mesh_facets,
+UInt MeshUtils::updateFacetToDouble(Mesh & mesh_facets,
const ElementTypeMapArray<bool> & facet_insertion) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh_facets.getSpatialDimension();
- bool facets_to_double = false;
+ UInt nb_facets_to_double = 0.;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
const Array<bool> & f_insertion = facet_insertion(type_facet, gt_facet);
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
ElementType el_type = _not_defined;
GhostType el_gt = _casper;
UInt nb_facet_per_element = 0;
Element old_facet_el(type_facet, 0, gt_facet);
Array<Element> * facet_to_element = NULL;
for (UInt f = 0; f < f_insertion.getSize(); ++f) {
if (f_insertion(f) == false) continue;
- facets_to_double = true;
+ ++nb_facets_to_double;
if (element_to_facet(f)[1].type == _not_defined
#if defined(AKANTU_COHESIVE_ELEMENT)
|| element_to_facet(f)[1].kind == _ek_cohesive
#endif
) {
AKANTU_DEBUG_WARNING("attempt to double a facet on the boundary");
continue;
}
f_to_double.push_back(f);
UInt new_facet =
mesh_facets.getNbElement(type_facet, gt_facet) + f_to_double.getSize() - 1;
old_facet_el.element = f;
/// update facet_to_element vector
Element & elem_to_update = element_to_facet(f)[1];
UInt el = elem_to_update.element;
if (elem_to_update.ghost_type != el_gt || elem_to_update.type != el_type) {
el_type = elem_to_update.type;
el_gt = elem_to_update.ghost_type;
facet_to_element = & mesh_facets.getSubelementToElement(el_type, el_gt);
nb_facet_per_element = facet_to_element->getNbComponent();
}
Element * f_update
= std::find(facet_to_element->storage() + el * nb_facet_per_element,
facet_to_element->storage() + el * nb_facet_per_element
+ nb_facet_per_element,
old_facet_el);
AKANTU_DEBUG_ASSERT(facet_to_element->storage() + el * nb_facet_per_element !=
facet_to_element->storage() + el * nb_facet_per_element
+ nb_facet_per_element,
"Facet not found");
f_update->element = new_facet;
/// update elements connected to facet
std::vector<Element> first_facet_list = element_to_facet(f);
element_to_facet.push_back(first_facet_list);
/// set new and original facets as boundary facets
element_to_facet(new_facet)[0] = element_to_facet(new_facet)[1];
element_to_facet(f)[1] = ElementNull;
element_to_facet(new_facet)[1] = ElementNull;
}
}
}
AKANTU_DEBUG_OUT();
- return facets_to_double;
+ return nb_facets_to_double;
}
/* -------------------------------------------------------------------------- */
void MeshUtils::resetFacetToDouble(Mesh & mesh_facets) {
AKANTU_DEBUG_IN();
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
Mesh::type_iterator it = mesh_facets.firstType(_all_dimensions, gt);
Mesh::type_iterator end = mesh_facets.lastType(_all_dimensions, gt);
for(; it != end; ++it) {
ElementType type = *it;
mesh_facets.getDataPointer<UInt>("facet_to_double", type, gt, 1, false);
mesh_facets.getDataPointer<std::vector<Element> >
("facets_to_subfacet_double", type, gt, 1, false);
mesh_facets.getDataPointer<std::vector<Element> >
("elements_to_subfacet_double", type, gt, 1, false);
mesh_facets.getDataPointer<std::vector<Element> >
("subfacets_to_subsubfacet_double", type, gt, 1, false);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool subsubfacet_mode>
void MeshUtils::findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh_facets.getSpatialDimension();
if (spatial_dimension == 1) return;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
if (nb_facet_to_double == 0) continue;
ElementType type_subfacet = Mesh::getFacetType(type_facet);
GhostType gt_subfacet = _casper;
ElementType type_subsubfacet = Mesh::getFacetType(type_subfacet);
GhostType gt_subsubfacet = _casper;
Array<UInt> * conn_subfacet = NULL;
Array<UInt> * sf_to_double = NULL;
Array<std::vector<Element> > * sf_to_subfacet_double = NULL;
Array<std::vector<Element> > * f_to_subfacet_double = NULL;
Array<std::vector<Element> > * el_to_subfacet_double = NULL;
UInt nb_subfacet = Mesh::getNbFacetsPerElement(type_facet);
UInt nb_subsubfacet;
UInt nb_nodes_per_sf_el;
if (subsubfacet_mode) {
nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subsubfacet);
nb_subsubfacet = Mesh::getNbFacetsPerElement(type_subfacet);
}
else
nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subfacet);
Array<Element> & subfacet_to_facet
= mesh_facets.getSubelementToElement(type_facet, gt_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
Array<Element> * subsubfacet_to_subfacet = NULL;
UInt old_nb_facet = subfacet_to_facet.getSize() - nb_facet_to_double;
Element current_facet(type_facet, 0, gt_facet);
std::vector<Element> element_list;
std::vector<Element> facet_list;
std::vector<Element> * subfacet_list;
if (subsubfacet_mode)
subfacet_list = new std::vector<Element>;
/// map to filter subfacets
Array< std::vector<Element> > * facet_to_subfacet = NULL;
/// this is used to make sure that both new and old facets are
/// checked
UInt facets[2];
/// loop on every facet
for (UInt f_index = 0; f_index < 2; ++f_index) {
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
facets[bool(f_index)] = f_to_double(facet);
facets[!bool(f_index)] = old_nb_facet + facet;
UInt old_facet = facets[0];
UInt new_facet = facets[1];
Element & starting_element = element_to_facet(new_facet)[0];
current_facet.element = old_facet;
/// loop on every subfacet
for (UInt sf = 0; sf < nb_subfacet; ++sf) {
Element & subfacet = subfacet_to_facet(old_facet, sf);
if (subfacet == ElementNull) continue;
if (gt_subfacet != subfacet.ghost_type) {
gt_subfacet = subfacet.ghost_type;
if (subsubfacet_mode) {
subsubfacet_to_subfacet
= & mesh_facets.getSubelementToElement(type_subfacet,
gt_subfacet);
}
else {
conn_subfacet = & mesh_facets.getConnectivity(type_subfacet,
gt_subfacet);
sf_to_double = & mesh_facets.getData<UInt>("facet_to_double",
type_subfacet,
gt_subfacet);
f_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subfacet,
gt_subfacet);
el_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("elements_to_subfacet_double",
type_subfacet,
gt_subfacet);
facet_to_subfacet
= & mesh_facets.getElementToSubelement(type_subfacet,
gt_subfacet);
}
}
if (subsubfacet_mode) {
/// loop on every subsubfacet
for (UInt ssf = 0; ssf < nb_subsubfacet; ++ssf) {
Element & subsubfacet
= (*subsubfacet_to_subfacet)(subfacet.element, ssf);
if (subsubfacet == ElementNull) continue;
if (gt_subsubfacet != subsubfacet.ghost_type) {
gt_subsubfacet = subsubfacet.ghost_type;
conn_subfacet = & mesh_facets.getConnectivity(type_subsubfacet,
gt_subsubfacet);
sf_to_double = & mesh_facets.getData<UInt>("facet_to_double",
type_subsubfacet,
gt_subsubfacet);
sf_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("subfacets_to_subsubfacet_double",
type_subsubfacet,
gt_subsubfacet);
f_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subsubfacet,
gt_subsubfacet);
el_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("elements_to_subfacet_double",
type_subsubfacet,
gt_subsubfacet);
facet_to_subfacet
= & mesh_facets.getElementToSubelement(type_subsubfacet,
gt_subsubfacet);
}
UInt global_ssf = subsubfacet.element;
Vector<UInt> subsubfacet_connectivity(conn_subfacet->storage()
+ global_ssf
* nb_nodes_per_sf_el,
nb_nodes_per_sf_el);
/// check if subsubfacet is to be doubled
if (findElementsAroundSubfacet<true>(mesh, mesh_facets,
starting_element, current_facet,
subsubfacet_connectivity,
element_list,
facet_list,
subfacet_list) == false &&
removeElementsInVector(*subfacet_list,
(*facet_to_subfacet)(global_ssf)) == false) {
sf_to_double->push_back(global_ssf);
sf_to_subfacet_double->push_back(*subfacet_list);
f_to_subfacet_double->push_back(facet_list);
el_to_subfacet_double->push_back(element_list);
}
}
}
else {
const UInt global_sf = subfacet.element;
Vector<UInt> subfacet_connectivity(conn_subfacet->storage()
+ global_sf
* nb_nodes_per_sf_el,
nb_nodes_per_sf_el);
/// check if subfacet is to be doubled
if (findElementsAroundSubfacet<false>(mesh, mesh_facets,
starting_element, current_facet,
subfacet_connectivity,
element_list,
facet_list) == false &&
removeElementsInVector(facet_list,
(*facet_to_subfacet)(global_sf)) == false) {
sf_to_double->push_back(global_sf);
f_to_subfacet_double->push_back(facet_list);
el_to_subfacet_double->push_back(element_list);
}
}
}
}
}
if (subsubfacet_mode)
delete subfacet_list;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
#if defined(AKANTU_COHESIVE_ELEMENT)
void MeshUtils::updateCohesiveData(Mesh & mesh,
Mesh & mesh_facets,
Array<Element> & new_elements) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
bool third_dimension = spatial_dimension == 3;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
if (nb_facet_to_double == 0) continue;
ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
Array<Element> * facet_to_coh_element
= mesh_facets.getSubelementToElementPointer(type_cohesive, gt_facet);
Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
Array<UInt> * conn_cohesive = mesh.getConnectivityPointer(type_cohesive,
gt_facet);
UInt nb_nodes_per_facet = Mesh::getNbNodesPerElement(type_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
UInt old_nb_cohesive_elements = conn_cohesive->getSize();
UInt new_nb_cohesive_elements = conn_cohesive->getSize() + nb_facet_to_double;
UInt old_nb_facet = element_to_facet.getSize() - nb_facet_to_double;
facet_to_coh_element->resize(new_nb_cohesive_elements);
conn_cohesive->resize(new_nb_cohesive_elements);
UInt new_elements_old_size = new_elements.getSize();
new_elements.resize(new_elements_old_size + nb_facet_to_double);
Element c_element(type_cohesive, 0, gt_facet, _ek_cohesive);
Element f_element(type_facet, 0, gt_facet);
UInt facets[2];
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
/// (in 3D cohesive elements connectivity is inverted)
facets[third_dimension] = f_to_double(facet);
facets[!third_dimension] = old_nb_facet + facet;
UInt cohesive_element = old_nb_cohesive_elements + facet;
/// store doubled facets
f_element.element = facets[0];
(*facet_to_coh_element)(cohesive_element, 0) = f_element;
f_element.element = facets[1];
(*facet_to_coh_element)(cohesive_element, 1) = f_element;
/// modify cohesive elements' connectivity
for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
(*conn_cohesive)(cohesive_element, n) = conn_facet(facets[0], n);
(*conn_cohesive)(cohesive_element, n + nb_nodes_per_facet)
= conn_facet(facets[1], n);
}
/// update element_to_facet vectors
c_element.element = cohesive_element;
element_to_facet(facets[0])[1] = c_element;
element_to_facet(facets[1])[1] = c_element;
/// add cohesive element to the element event list
new_elements(new_elements_old_size + facet) = c_element;
}
}
}
AKANTU_DEBUG_OUT();
}
#endif
/* -------------------------------------------------------------------------- */
void MeshUtils::doublePointFacet(Mesh & mesh,
Mesh & mesh_facets,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh.getSpatialDimension();
if (spatial_dimension != 1) return;
Array<Real> & position = mesh.getNodes();
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_facet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
const Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
UInt old_nb_facet = element_to_facet.getSize() - nb_facet_to_double;
UInt new_nb_facet = element_to_facet.getSize();
UInt old_nb_nodes = position.getSize();
UInt new_nb_nodes = old_nb_nodes + nb_facet_to_double;
position.resize(new_nb_nodes);
conn_facet.resize(new_nb_facet);
UInt old_nb_doubled_nodes = doubled_nodes.getSize();
doubled_nodes.resize(old_nb_doubled_nodes + nb_facet_to_double);
for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
UInt old_facet = f_to_double(facet);
UInt new_facet = old_nb_facet + facet;
ElementType type = element_to_facet(new_facet)[0].type;
UInt el = element_to_facet(new_facet)[0].element;
GhostType gt = element_to_facet(new_facet)[0].ghost_type;
UInt old_node = conn_facet(old_facet);
UInt new_node = old_nb_nodes + facet;
/// update position
position(new_node) = position(old_node);
conn_facet(new_facet) = new_node;
Array<UInt> & conn_segment = mesh.getConnectivity(type, gt);
UInt nb_nodes_per_segment = conn_segment.getNbComponent();
/// update facet connectivity
UInt i;
for (i = 0; conn_segment(el, i) != old_node
&& i <= nb_nodes_per_segment; ++i);
conn_segment(el, i) = new_node;
doubled_nodes(old_nb_doubled_nodes + facet, 0) = old_node;
doubled_nodes(old_nb_doubled_nodes + facet, 1) = new_node;
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool third_dim_segments>
void MeshUtils::updateQuadraticSegments(Mesh & mesh,
Mesh & mesh_facets,
ElementType type_facet,
GhostType gt_facet,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
if (type_facet != _segment_3) return;
Array<UInt> & f_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_facet,
gt_facet);
UInt nb_facet_to_double = f_to_double.getSize();
UInt old_nb_facet
= mesh_facets.getNbElement(type_facet, gt_facet) - nb_facet_to_double;
Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet,
gt_facet);
Array< std::vector<Element> > & element_to_facet
= mesh_facets.getElementToSubelement(type_facet, gt_facet);
/// this ones matter only for segments in 3D
Array< std::vector<Element> > * el_to_subfacet_double = NULL;
Array< std::vector<Element> > * f_to_subfacet_double = NULL;
if (third_dim_segments) {
el_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("elements_to_subfacet_double",
type_facet,
gt_facet);
f_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_facet,
gt_facet);
}
- Array<UInt> middle_nodes;
- Array<UInt> subfacets;
+ 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);
- subfacets.push_back(facet);
- }
+ if (!mesh.isPureGhostNode(node)) middle_nodes.push_back(node);
}
- UInt old_nb_doubled_nodes = doubled_nodes.getSize();
+ UInt n = doubled_nodes.getSize();
doubleNodes(mesh, middle_nodes, doubled_nodes);
- for (UInt n = old_nb_doubled_nodes; n < doubled_nodes.getSize(); ++n) {
- UInt old_node = doubled_nodes(n, 0);
+ for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
+ UInt old_facet = f_to_double(facet);
+ UInt old_node = conn_facet(old_facet, 2);
+ if (mesh.isPureGhostNode(old_node)) continue;
+
UInt new_node = doubled_nodes(n, 1);
- UInt sf = subfacets(n - old_nb_doubled_nodes);
- UInt new_facet = old_nb_facet + sf;
+ 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)(sf),
- &(*f_to_subfacet_double)(sf));
+ (*el_to_subfacet_double)(facet),
+ &(*f_to_subfacet_double)(facet));
}
else {
updateElementalConnectivity(mesh,
old_node, new_node,
element_to_facet(new_facet));
}
+ ++n;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::updateSubfacetToFacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet,
bool facet_mode) {
AKANTU_DEBUG_IN();
Array<UInt> & sf_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_subfacet,
gt_subfacet);
UInt nb_subfacet_to_double = sf_to_double.getSize();
/// update subfacet_to_facet vector
ElementType type_facet = _not_defined;
GhostType gt_facet = _casper;
Array<Element> * subfacet_to_facet = NULL;
UInt nb_subfacet_per_facet = 0;
UInt old_nb_subfacet
= mesh_facets.getNbElement(type_subfacet, gt_subfacet) - nb_subfacet_to_double;
Array<std::vector<Element> > * facet_list = NULL;
if (facet_mode)
facet_list = & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subfacet,
gt_subfacet);
else
facet_list = & mesh_facets.getData<std::vector<Element> >("subfacets_to_subsubfacet_double",
type_subfacet,
gt_subfacet);
Element old_subfacet_el(type_subfacet, 0, gt_subfacet);
Element new_subfacet_el(type_subfacet, 0, gt_subfacet);
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
old_subfacet_el.element = sf_to_double(sf);
new_subfacet_el.element = old_nb_subfacet + sf;
for (UInt f = 0; f < (*facet_list)(sf).size(); ++f) {
Element & facet = (*facet_list)(sf)[f];
if (facet.type != type_facet || facet.ghost_type != gt_facet) {
type_facet = facet.type;
gt_facet = facet.ghost_type;
subfacet_to_facet = & mesh_facets.getSubelementToElement(type_facet,
gt_facet);
nb_subfacet_per_facet = subfacet_to_facet->getNbComponent();
}
Element * sf_update
= std::find(subfacet_to_facet->storage()
+ facet.element * nb_subfacet_per_facet,
subfacet_to_facet->storage()
+ facet.element * nb_subfacet_per_facet + nb_subfacet_per_facet,
old_subfacet_el);
AKANTU_DEBUG_ASSERT(subfacet_to_facet->storage()
+ facet.element * nb_subfacet_per_facet !=
subfacet_to_facet->storage()
+ facet.element * nb_subfacet_per_facet + nb_subfacet_per_facet,
"Subfacet not found");
*sf_update = new_subfacet_el;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::updateFacetToSubfacet(Mesh & mesh_facets,
ElementType type_subfacet,
GhostType gt_subfacet,
bool facet_mode) {
AKANTU_DEBUG_IN();
Array<UInt> & sf_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_subfacet,
gt_subfacet);
UInt nb_subfacet_to_double = sf_to_double.getSize();
Array< std::vector<Element> > & facet_to_subfacet
= mesh_facets.getElementToSubelement(type_subfacet, gt_subfacet);
Array< std::vector<Element> > * facet_to_subfacet_double = NULL;
if (facet_mode) {
facet_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subfacet,
gt_subfacet);
}
else {
facet_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("subfacets_to_subsubfacet_double",
type_subfacet,
gt_subfacet);
}
+ UInt old_nb_subfacet = facet_to_subfacet.getSize();
+ facet_to_subfacet.resize(old_nb_subfacet + nb_subfacet_to_double);
+
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf)
- facet_to_subfacet.push_back((*facet_to_subfacet_double)(sf));
+ facet_to_subfacet(old_nb_subfacet + sf) = (*facet_to_subfacet_double)(sf);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <UInt spatial_dimension>
void MeshUtils::doubleSubfacet(Mesh & mesh,
Mesh & mesh_facets,
Array<UInt> & doubled_nodes) {
AKANTU_DEBUG_IN();
if (spatial_dimension == 1) return;
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end(); ++gt) {
GhostType gt_subfacet = *gt;
Mesh::type_iterator it = mesh_facets.firstType(0, gt_subfacet);
Mesh::type_iterator end = mesh_facets.lastType(0, gt_subfacet);
for(; it != end; ++it) {
ElementType type_subfacet = *it;
Array<UInt> & sf_to_double = mesh_facets.getData<UInt>("facet_to_double",
type_subfacet,
gt_subfacet);
UInt nb_subfacet_to_double = sf_to_double.getSize();
if (nb_subfacet_to_double == 0) continue;
AKANTU_DEBUG_ASSERT(type_subfacet == _point_1,
"Only _point_1 subfacet doubling is supported at the moment");
Array<UInt> & conn_subfacet = mesh_facets.getConnectivity(type_subfacet,
gt_subfacet);
UInt old_nb_subfacet = conn_subfacet.getSize();
UInt new_nb_subfacet = old_nb_subfacet + nb_subfacet_to_double;
conn_subfacet.resize(new_nb_subfacet);
- Array<UInt> nodes_to_double;
+ std::vector<UInt> nodes_to_double;
UInt old_nb_doubled_nodes = doubled_nodes.getSize();
/// double nodes
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
UInt old_subfacet = sf_to_double(sf);
nodes_to_double.push_back(conn_subfacet(old_subfacet));
}
doubleNodes(mesh, nodes_to_double, doubled_nodes);
/// add new nodes in connectivity
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
UInt new_subfacet = old_nb_subfacet + sf;
UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
conn_subfacet(new_subfacet) = new_node;
}
/// update facet and element connectivity
Array<std::vector<Element> > & f_to_subfacet_double =
mesh_facets.getData<std::vector<Element> >("facets_to_subfacet_double",
type_subfacet,
gt_subfacet);
Array<std::vector<Element> > & el_to_subfacet_double =
mesh_facets.getData<std::vector<Element> >("elements_to_subfacet_double",
type_subfacet,
gt_subfacet);
Array<std::vector<Element> > * sf_to_subfacet_double = NULL;
if (spatial_dimension == 3)
sf_to_subfacet_double
= & mesh_facets.getData<std::vector<Element> >("subfacets_to_subsubfacet_double",
type_subfacet,
gt_subfacet);
for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
UInt old_node = doubled_nodes(old_nb_doubled_nodes + sf, 0);
UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
updateElementalConnectivity(mesh,
old_node, new_node,
el_to_subfacet_double(sf),
&f_to_subfacet_double(sf));
updateElementalConnectivity(mesh_facets,
old_node, new_node,
f_to_subfacet_double(sf));
if (spatial_dimension == 3)
updateElementalConnectivity(mesh_facets,
old_node, new_node,
(*sf_to_subfacet_double)(sf));
}
if (spatial_dimension == 2) {
updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, true);
updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, true);
}
else if (spatial_dimension == 3) {
updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, false);
updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, false);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::flipFacets(Mesh & mesh_facets,
const ElementTypeMapArray<UInt> & global_connectivity,
GhostType gt_facet) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = mesh_facets.getSpatialDimension();
/// get global connectivity for local mesh
ElementTypeMapArray<UInt> global_connectivity_tmp;
mesh_facets.initElementTypeMapArray(global_connectivity_tmp, 1,
spatial_dimension - 1, gt_facet,
true, _ek_regular, true);
mesh_facets.getGlobalConnectivity(global_connectivity_tmp,
spatial_dimension - 1, gt_facet);
Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, gt_facet);
Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, gt_facet);
/// loop on every facet
for(; it != end; ++it) {
ElementType type_facet = *it;
Array<UInt> & connectivity = mesh_facets.getConnectivity(type_facet, gt_facet);
const Array<UInt> & g_connectivity = global_connectivity(type_facet, gt_facet);
Array<std::vector<Element> > & el_to_f =
mesh_facets.getElementToSubelement(type_facet, gt_facet);
Array<Element> & subfacet_to_facet =
mesh_facets.getSubelementToElement(type_facet, gt_facet);
UInt nb_subfacet_per_facet = subfacet_to_facet.getNbComponent();
UInt nb_nodes_per_facet = connectivity.getNbComponent();
UInt nb_facet = connectivity.getSize();
UInt nb_nodes_per_P1_facet
= Mesh::getNbNodesPerElement(Mesh::getP1ElementType(type_facet));
Array<UInt> & global_conn_tmp = global_connectivity_tmp(type_facet, gt_facet);
Array<UInt>::iterator<Vector<UInt> > conn_it =
connectivity.begin(nb_nodes_per_facet);
Array<UInt>::iterator<Vector<UInt> > gconn_tmp_it =
global_conn_tmp.begin(nb_nodes_per_facet);
Array<UInt>::const_iterator<Vector<UInt> > conn_glob_it =
g_connectivity.begin(nb_nodes_per_facet);
Array<Element>::iterator<Vector<Element> > subf_to_f =
subfacet_to_facet.begin(nb_subfacet_per_facet);
UInt * conn_tmp_pointer = new UInt[nb_nodes_per_facet];
Vector<UInt> conn_tmp(conn_tmp_pointer, nb_nodes_per_facet);
Element el_tmp;
Element * subf_tmp_pointer = new Element[nb_subfacet_per_facet];
Vector<Element> subf_tmp(subf_tmp_pointer, nb_subfacet_per_facet);
for (UInt f = 0; f < nb_facet; ++f, ++conn_it, ++gconn_tmp_it,
++subf_to_f, ++conn_glob_it) {
Vector<UInt> & gconn_tmp = *gconn_tmp_it;
const Vector<UInt> & conn_glob = *conn_glob_it;
Vector<UInt> & conn_local = *conn_it;
/// skip facet if connectivities are the same
if (gconn_tmp == conn_glob) continue;
/// re-arrange connectivity
conn_tmp = conn_local;
UInt * begin = conn_glob.storage();
UInt * end = conn_glob.storage() + nb_nodes_per_facet;
for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
UInt * new_node = std::find(begin, end, gconn_tmp(n));
AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
UInt new_position = new_node - begin;
conn_local(new_position) = conn_tmp(n);
}
/// if 3D, check if facets are just rotated
if (spatial_dimension == 3) {
/// find first node
UInt * new_node = std::find(begin, end, gconn_tmp(0));
AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
UInt new_position = new_node - begin;
UInt n = 1;
/// count how many nodes in the received connectivity follow
/// the same order of those in the local connectivity
for (; n < nb_nodes_per_P1_facet &&
gconn_tmp(n) == conn_glob((new_position + n) % nb_nodes_per_P1_facet);
++n);
/// skip the facet inversion if facet is just rotated
if (n == nb_nodes_per_P1_facet) continue;
}
/// update data to invert facet
el_tmp = el_to_f(f)[0];
el_to_f(f)[0] = el_to_f(f)[1];
el_to_f(f)[1] = el_tmp;
subf_tmp = (*subf_to_f);
(*subf_to_f)(0) = subf_tmp(1);
(*subf_to_f)(1) = subf_tmp(0);
}
delete [] subf_tmp_pointer;
delete [] conn_tmp_pointer;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void MeshUtils::fillElementToSubElementsData(Mesh & mesh) {
AKANTU_DEBUG_IN();
if(mesh.getNbElement(mesh.getSpatialDimension() - 1) == 0) {
AKANTU_DEBUG_INFO("There are not facets, add them in the mesh file or call the buildFacet method.");
return;
}
UInt spatial_dimension = mesh.getSpatialDimension();
ElementTypeMapArray<Real> barycenters("barycenter_tmp", mesh.getID());
mesh.initElementTypeMapArray(barycenters,
spatial_dimension,
_all_dimensions);
for (ghost_type_t::iterator gt = ghost_type_t::begin();
gt != ghost_type_t::end();
++gt) {
Mesh::type_iterator it = mesh.firstType(_all_dimensions, *gt);
Mesh::type_iterator end = mesh.lastType(_all_dimensions, *gt);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it, *gt);
Array<Real> & barycenters_arr = barycenters(*it, *gt);
barycenters_arr.resize(nb_element);
Array<Real>::vector_iterator bary = barycenters_arr.begin(spatial_dimension);
Array<Real>::vector_iterator bary_end = barycenters_arr.end(spatial_dimension);
for (UInt el = 0; bary != bary_end; ++bary, ++el) {
mesh.getBarycenter(el, *it, bary->storage(), *gt);
}
}
}
for(Int sp(spatial_dimension); sp >= 1; --sp) {
if(mesh.getNbElement(sp) == 0) continue;
for (ghost_type_t::iterator git = ghost_type_t::begin(); git != ghost_type_t::end(); ++git) {
Mesh::type_iterator tit = mesh.firstType(sp, *git);
Mesh::type_iterator tend = mesh.lastType(sp, *git);
for (;tit != tend; ++tit) {
mesh.getSubelementToElementPointer(*tit, *git)->resize(mesh.getNbElement(*tit, *git));
mesh.getSubelementToElement(*tit, *git).clear();
}
tit = mesh.firstType(sp - 1, *git);
tend = mesh.lastType(sp - 1, *git);
for (;tit != tend; ++tit) {
mesh.getElementToSubelementPointer(*tit, *git)->resize(mesh.getNbElement(*tit, *git));
mesh.getElementToSubelement(*tit, *git).clear();
}
}
-
CSR<Element> nodes_to_elements;
buildNode2Elements(mesh, nodes_to_elements, sp);
Element facet_element;
for (ghost_type_t::iterator git = ghost_type_t::begin(); git != ghost_type_t::end(); ++git) {
Mesh::type_iterator tit = mesh.firstType(sp - 1, *git);
Mesh::type_iterator tend = mesh.lastType(sp - 1, *git);
facet_element.ghost_type = *git;
for (;tit != tend; ++tit) {
facet_element.type = *tit;
Array< std::vector<Element> > & element_to_subelement = mesh.getElementToSubelement(*tit, *git);
const Array<UInt> & connectivity = mesh.getConnectivity(*tit, *git);
Array<UInt>::const_iterator< Vector<UInt> > fit = connectivity.begin(mesh.getNbNodesPerElement(*tit));
Array<UInt>::const_iterator< Vector<UInt> > fend = connectivity.end(mesh.getNbNodesPerElement(*tit));
UInt fid = 0;
for (;fit != fend; ++fit, ++fid) {
const Vector<UInt> & facet = *fit;
facet_element.element = fid;
std::map<Element, UInt> element_seen_counter;
UInt nb_nodes_per_facet = mesh.getNbNodesPerElement(Mesh::getP1ElementType(*tit));
for (UInt n(0); n < nb_nodes_per_facet; ++n) {
CSR<Element>::iterator eit = nodes_to_elements.begin(facet(n));
CSR<Element>::iterator eend = nodes_to_elements.end(facet(n));
for(;eit != eend; ++eit) {
Element & elem = *eit;
std::map<Element, UInt>::iterator cit = element_seen_counter.find(elem);
if(cit != element_seen_counter.end()) {
cit->second++;
} else {
element_seen_counter[elem] = 1;
}
}
}
std::vector<Element> connected_elements;
std::map<Element, UInt>::iterator cit = element_seen_counter.begin();
std::map<Element, UInt>::iterator cend = element_seen_counter.end();
for(;cit != cend; ++cit) {
if(cit->second == nb_nodes_per_facet) connected_elements.push_back(cit->first);
}
std::vector<Element>::iterator ceit = connected_elements.begin();
std::vector<Element>::iterator ceend = connected_elements.end();
for(;ceit != ceend; ++ceit)
element_to_subelement(fid).push_back(*ceit);
for (UInt ce = 0; ce < connected_elements.size(); ++ce) {
Element & elem = connected_elements[ce];
Array<Element> & subelement_to_element =
*(mesh.getSubelementToElementPointer(elem.type,
elem.ghost_type));
UInt f(0);
- for(; f < mesh.getNbFacetsPerElement(elem.type) && subelement_to_element(elem.element, f) != ElementNull; ++f);
+ for(; f < mesh.getNbFacetsPerElement(elem.type) &&
+ subelement_to_element(elem.element, f) != ElementNull; ++f);
+
AKANTU_DEBUG_ASSERT(f < mesh.getNbFacetsPerElement(elem.type), "The element " << elem << " seems to have too many facets!! (" << f << " < " << mesh.getNbFacetsPerElement(elem.type) << ")");
+
subelement_to_element(elem.element, f) = facet_element;
}
}
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template <bool third_dim_points>
bool MeshUtils::findElementsAroundSubfacet(const Mesh & mesh,
const Mesh & mesh_facets,
const Element & starting_element,
const Element & end_facet,
const Vector<UInt> & subfacet_connectivity,
std::vector<Element> & elem_list,
std::vector<Element> & facet_list,
std::vector<Element> * subfacet_list) {
AKANTU_DEBUG_IN();
/// preallocated stuff before starting
bool facet_matched = false;
- elem_list.resize(0);
- facet_list.resize(0);
+ elem_list.clear();
+ facet_list.clear();
if (third_dim_points)
- subfacet_list->resize(0);
+ subfacet_list->clear();
elem_list.push_back(starting_element);
const Array<UInt> * facet_connectivity = NULL;
const Array<UInt> * sf_connectivity = NULL;
const Array<Element> * facet_to_element = NULL;
const Array<Element> * subfacet_to_facet = NULL;
ElementType current_type = _not_defined;
GhostType current_ghost_type = _casper;
ElementType current_facet_type = _not_defined;
GhostType current_facet_ghost_type = _casper;
ElementType current_subfacet_type = _not_defined;
GhostType current_subfacet_ghost_type = _casper;
const Array< std::vector<Element> > * element_to_facet = NULL;
const Element * opposing_el = NULL;
- Array<Element> elements_to_check;
- elements_to_check.resize(0);
- elements_to_check.push_back(starting_element);
+ std::queue<Element> elements_to_check;
+ elements_to_check.push(starting_element);
/// keep going until there are elements to check
- while (elements_to_check.getSize() != 0) {
+ while (!elements_to_check.empty()) {
- /// loop over each element to check
- for (UInt el = 0; el < elements_to_check.getSize(); ++el) {
+ /// check current element
+ Element & current_el = elements_to_check.front();
- Element & current_el = elements_to_check(el);
+ if (current_el.type != current_type ||
+ current_el.ghost_type != current_ghost_type) {
- if (current_el.type != current_type ||
- current_el.ghost_type != current_ghost_type) {
+ current_type = current_el.type;
+ current_ghost_type = current_el.ghost_type;
- 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) {
- /// 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) {
- if (current_facet_type != current_facet.type ||
- current_facet_ghost_type != current_facet.ghost_type) {
+ current_facet_type = current_facet.type;
+ current_facet_ghost_type = current_facet.ghost_type;
- 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,
+ if (third_dim_points)
+ subfacet_to_facet =
+ & mesh_facets.getSubelementToElement(current_facet_type,
current_facet_ghost_type);
- facet_connectivity = & mesh_facets.getConnectivity(current_facet_type,
- current_facet_ghost_type);
-
- if (third_dim_points)
- subfacet_to_facet =
- & mesh_facets.getSubelementToElement(current_facet_type,
- current_facet_ghost_type);
- }
-
- /// check if end facet is reached
- if (current_facet == end_facet)
- facet_matched = true;
-
- /// add this facet if not already passed
- if (std::find(facet_list.begin(),
- facet_list.end(),
- current_facet) == facet_list.end() &&
- hasElement(*facet_connectivity, current_facet, subfacet_connectivity)) {
- facet_list.push_back(current_facet);
-
- if (third_dim_points) {
- /// check subfacets
- for (UInt sf = 0; sf < subfacet_to_facet->getNbComponent(); ++sf) {
- const Element & current_subfacet
- = (*subfacet_to_facet)(current_facet.element, sf);
-
- if (current_subfacet == ElementNull) continue;
-
- if (current_subfacet_type != current_subfacet.type ||
- current_subfacet_ghost_type != current_subfacet.ghost_type) {
- current_subfacet_type = current_subfacet.type;
- current_subfacet_ghost_type = current_subfacet.ghost_type;
-
- sf_connectivity
- = & mesh_facets.getConnectivity(current_subfacet_type,
- current_subfacet_ghost_type);
- }
+ }
- if (std::find(subfacet_list->begin(),
- subfacet_list->end(),
- current_subfacet) == subfacet_list->end() &&
- hasElement(*sf_connectivity, current_subfacet, subfacet_connectivity))
- subfacet_list->push_back(current_subfacet);
+ /// check if end facet is reached
+ if (current_facet == end_facet)
+ facet_matched = true;
+
+ /// add this facet if not already passed
+ if (std::find(facet_list.begin(),
+ facet_list.end(),
+ current_facet) == facet_list.end() &&
+ hasElement(*facet_connectivity, current_facet, subfacet_connectivity)) {
+ facet_list.push_back(current_facet);
+
+ if (third_dim_points) {
+ /// check subfacets
+ for (UInt sf = 0; sf < subfacet_to_facet->getNbComponent(); ++sf) {
+ const Element & current_subfacet
+ = (*subfacet_to_facet)(current_facet.element, sf);
+
+ if (current_subfacet == ElementNull) continue;
+
+ if (current_subfacet_type != current_subfacet.type ||
+ current_subfacet_ghost_type != current_subfacet.ghost_type) {
+ current_subfacet_type = current_subfacet.type;
+ current_subfacet_ghost_type = current_subfacet.ghost_type;
+
+ sf_connectivity
+ = & mesh_facets.getConnectivity(current_subfacet_type,
+ current_subfacet_ghost_type);
}
+
+ if (std::find(subfacet_list->begin(),
+ subfacet_list->end(),
+ current_subfacet) == subfacet_list->end() &&
+ hasElement(*sf_connectivity, current_subfacet, subfacet_connectivity))
+ subfacet_list->push_back(current_subfacet);
}
}
- else
- continue;
+ }
+ else
+ continue;
- /// consider opposing element
- if ( (*element_to_facet)(current_facet.element)[0] == current_el)
- opposing_el = & (*element_to_facet)(current_facet.element)[1];
- else
- opposing_el = & (*element_to_facet)(current_facet.element)[0];
+ /// consider opposing element
+ if ( (*element_to_facet)(current_facet.element)[0] == current_el)
+ opposing_el = & (*element_to_facet)(current_facet.element)[1];
+ else
+ opposing_el = & (*element_to_facet)(current_facet.element)[0];
- /// skip null elements since they are on a boundary
- if (*opposing_el == ElementNull) continue;
+ /// skip null elements since they are on a boundary
+ if (*opposing_el == ElementNull) continue;
- /// skip this element if already added
- if ( std::find(elem_list.begin(),
- elem_list.end(),
- *opposing_el) != elem_list.end() ) continue;
+ /// skip this element if already added
+ if ( std::find(elem_list.begin(),
+ elem_list.end(),
+ *opposing_el) != elem_list.end() ) continue;
- /// only regular elements have to be checked
- if (opposing_el->kind == _ek_regular)
- elements_to_check.push_back(*opposing_el);
+ /// only regular elements have to be checked
+ if (opposing_el->kind == _ek_regular)
+ elements_to_check.push(*opposing_el);
- elem_list.push_back(*opposing_el);
+ 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.erase(el);
}
+
+ /// 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 38002c684..8c216a95b 100644
--- a/src/mesh_utils/mesh_utils.hh
+++ b/src/mesh_utils/mesh_utils.hh
@@ -1,277 +1,278 @@
/**
* @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>
*
* @date creation: Fri Aug 20 2010
* @date last modification: Mon Jun 23 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 {
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-public:
-
- MeshUtils();
- virtual ~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);
- /// create a multimap of nodes per surfaces
- static void buildNodesPerSurface(const Mesh & mesh, CSR<UInt> & nodes_per_surface);
-
/// 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
- static void insertCohesiveElements(Mesh & mesh,
+ /// @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);
+ 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 Array<UInt> & old_nodes,
+ const std::vector<UInt> & old_nodes,
Array<UInt> & doubled_nodes);
/// fill facet_to_double array in the mesh
- static bool updateFacetToDouble(Mesh & mesh_facets,
+ /// 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 e7945293f..d7b3a2e9a 100644
--- a/src/mesh_utils/mesh_utils_inline_impl.cc
+++ b/src/mesh_utils/mesh_utils_inline_impl.cc
@@ -1,164 +1,160 @@
/**
* @file mesh_utils_inline_impl.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Fri Aug 20 2010
* @date last modification: Mon Jun 09 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 matched_nodes = 0;
+ UInt n = 0;
- for (UInt n = 0; n < nodes.size(); ++n) {
- if (std::find(el_nodes.storage(),
- el_nodes.storage() + nb_nodes_per_element,
- nodes[n])
- != (el_nodes.storage() + nb_nodes_per_element))
- ++matched_nodes;
- }
+ while (n < nodes.size() &&
+ std::find(el_nodes.storage(), el_nodes_end, nodes[n]) != el_nodes_end) ++n;
- return (matched_nodes == nodes.size());
+ 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..a32f8318a
--- /dev/null
+++ b/src/mesh_utils/mesh_utils_pbc.cc
@@ -0,0 +1,295 @@
+/**
+ * @file mesh_utils_pbc.cc
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author David Simon Kammer <david.kammer@epfl.ch>
+ *
+ * @date creation: Wed Feb 09 2011
+ * @date last modification: Fri Aug 01 2014
+ *
+ * @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::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..1e67df981 100644
--- a/src/model/boundary_condition.hh
+++ b/src/model/boundary_condition.hh
@@ -1,104 +1,105 @@
/**
* @file boundary_condition.hh
*
* @author Dana Christen <dana.christen@gmail.com>
*
* @date creation: Fri May 03 2013
* @date last modification: Thu Jun 05 2014
*
* @brief XXX
*
* @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_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 e1e300106..2f75450c8 100644
--- a/src/model/boundary_condition_functor.hh
+++ b/src/model/boundary_condition_functor.hh
@@ -1,205 +1,207 @@
/**
* @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>
*
* @date creation: Fri May 03 2013
* @date last modification: Fri Sep 19 2014
*
* @brief XXX
*
* @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_BOUNDARY_CONDITION_FUNCTOR_HH__
#define __AKANTU_BOUNDARY_CONDITION_FUNCTOR_HH__
#include "aka_common.hh"
#include "fe_engine.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
namespace BC {
typedef ::akantu::SpacialDirection Axis;
struct Functor {
enum Type {
_dirichlet,
_neumann
};
};
/* ------------------------------------------------------------------------ */
/* Dirichlet */
/* ------------------------------------------------------------------------ */
namespace Dirichlet {
/* ---------------------------------------------------------------------- */
class DirichletFunctor : public Functor {
protected:
DirichletFunctor() : axis(_x) {}
DirichletFunctor(Axis ax) : axis(ax) {}
public:
void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
public:
static const Type type = _dirichlet;
protected:
Axis axis;
};
/* ---------------------------------------------------------------------- */
class FlagOnly : public DirichletFunctor {
public:
FlagOnly(Axis ax = _x) : DirichletFunctor(ax) {}
public:
inline void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const;
};
/* ---------------------------------------------------------------------- */
class FreeBoundary : public DirichletFunctor {
public:
FreeBoundary(Axis ax = _x) : DirichletFunctor(ax) {}
public:
inline void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const;
};
/* ---------------------------------------------------------------------- */
class FixedValue : public DirichletFunctor {
public:
FixedValue(Real val, Axis ax = _x) : DirichletFunctor(ax), value(val) {}
public:
inline void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const;
protected:
Real value;
};
/* ---------------------------------------------------------------------- */
class IncrementValue : public DirichletFunctor {
public:
IncrementValue(Real val, Axis ax = _x) : DirichletFunctor(ax), value(val) {}
public:
inline void operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const;
inline void setIncrement(Real val) { this->value = val; }
protected:
Real value;
};
} //end namespace Dirichlet
/* ------------------------------------------------------------------------ */
/* Neumann */
/* ------------------------------------------------------------------------ */
namespace Neumann {
/* ---------------------------------------------------------------------- */
class NeumannFunctor : public Functor {
protected:
NeumannFunctor() {}
public:
- void operator()(UInt node,
- Vector<bool> & flags,
- Vector<Real> & primal,
- const Vector<Real> & coord) const {
- AKANTU_DEBUG_TO_IMPLEMENT();
- }
+ 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 QuadraturePoint & quad_point,
+ 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 QuadraturePoint & quad_point,
+ inline void operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const;
protected:
Vector<Real> bc_data;
};
/* ---------------------------------------------------------------------- */
class FreeBoundary : public NeumannFunctor {
public:
- inline void operator()(const QuadraturePoint & quad_point,
+ 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..5b8c03422 100644
--- a/src/model/boundary_condition_functor_inline_impl.cc
+++ b/src/model/boundary_condition_functor_inline_impl.cc
@@ -1,130 +1,130 @@
/**
* @file boundary_condition_functor.cc
*
* @author Dana Christen <dana.christen@gmail.com>
*
* @date Wed Mar 18 11:30:00 2013
*
* @brief XXX
*
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
#define DIRICHLET_SANITY_CHECK \
AKANTU_DEBUG_ASSERT(coord.size() <= flags.size(), \
"The coordinates and flags vectors given to the boundary" \
<< " condition functor have different sizes!"); \
AKANTU_DEBUG_ASSERT(primal.size() <= coord.size(), \
"The primal vector and coordinates vector given" \
<< " to the boundary condition functor have different sizes!");
#define NEUMANN_SANITY_CHECK \
AKANTU_DEBUG_ASSERT(coord.size() <= normals.size(), \
"The coordinates and normals vectors given to the" \
<< " boundary condition functor have different sizes!"); \
AKANTU_DEBUG_ASSERT(dual.size() <= coord.size(), \
"The dual vector and coordinates vector given to" \
<< " the boundary condition functor have different sizes!");
__BEGIN_AKANTU__
namespace BC {
namespace Dirichlet {
/* ---------------------------------------------------------------------- */
inline void FlagOnly::operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = true;
}
/* ---------------------------------------------------------------------- */
inline void FreeBoundary::operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = false;
}
/* ---------------------------------------------------------------------- */
inline void FixedValue::operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = true;
primal(axis) = value;
}
/* ---------------------------------------------------------------------- */
inline void IncrementValue::operator()(UInt node,
Vector<bool> & flags,
Vector<Real> & primal,
const Vector<Real> & coord) const {
DIRICHLET_SANITY_CHECK;
flags(axis) = true;
primal(axis) += value;
}
} // end namespace Dirichlet
/* ------------------------------------------------------------------------ */
/* Neumann */
/* ------------------------------------------------------------------------ */
namespace Neumann {
/* ---------------------------------------------------------------------- */
- inline void FreeBoundary::operator()(const QuadraturePoint & quad_point,
+ inline void FreeBoundary::operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const {
for(UInt i(0); i<dual.size(); ++i) {
dual(i) = 0.0;
}
}
/* -------------------------------------------------------------------------- */
- inline void FromHigherDim::operator()(const QuadraturePoint & quad_point,
+ inline void FromHigherDim::operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const {
dual.mul<false>(bc_data, normals);
}
/* -------------------------------------------------------------------------- */
- inline void FromSameDim::operator()(const QuadraturePoint & quad_point,
+ inline void FromSameDim::operator()(const IntegrationPoint & quad_point,
Vector<Real> & dual,
const Vector<Real> & coord,
const Vector<Real> & normals) const {
dual = bc_data;
}
} // end namespace Neumann
} // end namespace BC
__END_AKANTU__
diff --git a/src/model/boundary_condition_python_functor.cc b/src/model/boundary_condition_python_functor.cc
new file mode 100644
index 000000000..4ee348fbf
--- /dev/null
+++ b/src/model/boundary_condition_python_functor.cc
@@ -0,0 +1,62 @@
+/**
+ * @file boundary_condition_python_functor.cc
+ *
+
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ *
+ *
+ * @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 "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..e871574ac
--- /dev/null
+++ b/src/model/boundary_condition_python_functor.hh
@@ -0,0 +1,113 @@
+/**
+ * @file boundary_condition_python_functor.hh
+ *
+
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ *
+ *
+ * @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 "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 ff63f45d0..ab4e1bdce 100644
--- a/src/model/boundary_condition_tmpl.hh
+++ b/src/model/boundary_condition_tmpl.hh
@@ -1,262 +1,265 @@
/**
* @file boundary_condition_tmpl.hh
*
* @author Dana Christen <dana.christen@gmail.com>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri May 03 2013
* @date last modification: Mon Jun 23 2014
*
* @brief XXX
*
* @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_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;
- func(n, flags_iter[n], primal_iter[n], coords_iter[n]);
+ 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
fem_boundary.assembleArray(*dual_by_shapes_integ,
dual,
model.getDOFSynchronizer().getLocalDOFEquationNumbers(),
nb_degree_of_freedom,
*type_it,
ghost_type,
element_ids);
delete dual_by_shapes_integ;
}
}
};
/* -------------------------------------------------------------------------- */
template<typename ModelType>
template<typename FunctorType>
inline void BoundaryCondition<ModelType>::applyBC(const FunctorType & func) {
GroupManager::const_element_group_iterator bit = model->getMesh().getGroupManager().element_group_begin();
GroupManager::const_element_group_iterator bend = model->getMesh().getGroupManager().element_group_end();
for(; bit != bend; ++bit) applyBC(func, *bit);
}
/* -------------------------------------------------------------------------- */
template<typename ModelType>
template<typename FunctorType>
inline void BoundaryCondition<ModelType>::applyBC(const FunctorType & func,
const std::string & group_name) {
try {
const ElementGroup & element_group = model->getMesh().getElementGroup(group_name);
applyBC(func, element_group);
} catch(akantu::debug::Exception e) {
AKANTU_EXCEPTION("Error applying a boundary condition onto \""
<< group_name << "\"! [" << e.what() <<"]");
}
}
/* -------------------------------------------------------------------------- */
template<typename ModelType>
template<typename FunctorType>
inline void BoundaryCondition<ModelType>::applyBC(const FunctorType & func,
const ElementGroup & element_group) {
#if !defined(AKANTU_NDEBUG)
if(element_group.getDimension() != model->getSpatialDimension() - 1)
AKANTU_DEBUG_WARNING("The group " << element_group.getName()
<< " does not contain only boundaries elements");
#endif
TemplateFunctionWrapper<FunctorType>::applyBC(func, element_group, *this);
}
__END_AKANTU__
diff --git a/src/model/common/neighborhood_base.cc b/src/model/common/neighborhood_base.cc
new file mode 100644
index 000000000..9b624f8b1
--- /dev/null
+++ b/src/model/common/neighborhood_base.cc
@@ -0,0 +1,293 @@
+/**
+ * @file neighborhood_base.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Thu Oct 8 15:40:36 2015
+ *
+ * @brief Implementation of generic neighborhood base
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..bacc6bf2f
--- /dev/null
+++ b/src/model/common/neighborhood_base.hh
@@ -0,0 +1,149 @@
+/**
+ * @file neighborhood_base.hh
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Thu Oct 8 15:27:33 2015
+ *
+ * @brief Generic neighborhood of quadrature points
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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..8464f1a8e
--- /dev/null
+++ b/src/model/common/neighborhood_base_inline_impl.cc
@@ -0,0 +1,45 @@
+/**
+ * @file neighborhood_base_inline_impl.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Mon Sep 21 18:25:31 2015
+ *
+ * @brief Inline implementation of neighborhood base functions
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+__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..d9c47abd4
--- /dev/null
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
@@ -0,0 +1,311 @@
+/**
+ * @file neighborhood_max_criterion.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Oct 14 21:31:07 2015
+ *
+ * @brief Implementation of class NeighborhoodMaxCriterion
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..e2e4261c7
--- /dev/null
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
@@ -0,0 +1,121 @@
+/**
+ * @file neighborhood_max_criterion.hh
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Oct 14 20:59:00 2015
+ *
+ * @brief Neighborhood to find a maximum value in a neighborhood
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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..2eb6a3753
--- /dev/null
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
@@ -0,0 +1,77 @@
+/**
+ * @file neighborhood_max_criterion_inline_implementation.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Oct 14 21:31:07 2015
+ *
+ * @brief Implementation of inline functions for class NeighborhoodMaxCriterion
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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..2cb119858
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_manager.cc
@@ -0,0 +1,619 @@
+/**
+ * @file non_local_manager.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Mon Sep 21 15:32:10 2015
+ *
+ * @brief Implementation of non-local manager
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..1d6c047eb
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_manager.hh
@@ -0,0 +1,284 @@
+/**
+ * @file non_local_manager.hh
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Mon Sep 21 14:21:33 2015
+ *
+ * @brief Classes that manages all the non-local neighborhoods
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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..11797e49f
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_manager_inline_impl.cc
@@ -0,0 +1,234 @@
+/**
+ * @file non_local_manager_inline_impl.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Mon Sep 21 17:30:03 2015
+ *
+ * @brief inline implementation of non-local manager functions
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "grid_synchronizer.hh"
+#include "synchronizer_registry.hh"
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__
+#define __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::insertQuad(const IntegrationPoint & quad, const Vector<Real> & coords, const ID & neighborhood) {
+
+ AKANTU_DEBUG_ASSERT(neighborhoods[neighborhood] != NULL,
+ "The neighborhood " << neighborhood << "has not been created");
+
+ neighborhoods[neighborhood]->insertQuad(quad, coords);
+
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::registerNeighborhood(const ID & neighborhood, const ID & weight_func_id) {
+
+ /// check if neighborhood has already been created
+ NeighborhoodMap::const_iterator it = neighborhoods.find(neighborhood);
+ if (it == neighborhoods.end()) {
+ this->createNeighborhood(weight_func_id, neighborhood);
+ }
+
+}
+
+/* -------------------------------------------------------------------------- */
+inline NonLocalNeighborhoodBase & NonLocalManager::getNeighborhood(const ID & name) const{
+ AKANTU_DEBUG_IN();
+
+ NeighborhoodMap::const_iterator it = neighborhoods.find(name);
+
+ AKANTU_DEBUG_ASSERT(it != neighborhoods.end(),
+ "The neighborhood " << name << " is not registered");
+
+ AKANTU_DEBUG_OUT();
+ return *(it->second);
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::computeWeights() {
+ AKANTU_DEBUG_IN();
+
+ this->updateWeightFunctionInternals();
+ this->volumes.clear();
+
+ // NeighborhoodMap::iterator it = neighborhoods.begin();
+ // NeighborhoodMap::iterator end = neighborhoods.end();
+
+ // for (; it != end; ++it)
+ // it->second->updateWeights();
+
+ /// loop over all the neighborhoods and call onElementsRemoved
+ std::set<ID>::const_iterator global_neighborhood_it = global_neighborhoods.begin();
+ NeighborhoodMap::iterator it;
+ for(; global_neighborhood_it != global_neighborhoods.end(); ++global_neighborhood_it) {
+ it = neighborhoods.find(*global_neighborhood_it);
+ if (it != neighborhoods.end())
+ it->second->updateWeights();
+ else {
+ dummy_synchronizers[*global_neighborhood_it]->asynchronousSynchronize(dummy_accessor, _gst_mnl_weight);
+ dummy_synchronizers[*global_neighborhood_it]->waitEndSynchronize(dummy_accessor, _gst_mnl_weight);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::updatePairLists() {
+ AKANTU_DEBUG_IN();
+
+ /// compute the position of the quadrature points
+ this->model.getFEEngine().computeIntegrationPointsCoordinates(quad_positions);
+
+ NeighborhoodMap::iterator it = neighborhoods.begin();
+ NeighborhoodMap::iterator end = neighborhoods.end();
+
+ for (; it != end; ++it)
+ it->second->updatePairList();
+
+ AKANTU_DEBUG_OUT();
+
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::registerNonLocalVariable(const ID & variable_name, const ID & nl_variable_name, UInt nb_component) {
+
+ AKANTU_DEBUG_IN();
+
+ std::map<ID, NonLocalVariable *>::iterator non_local_variable_it = non_local_variables.find(variable_name);
+
+ if (non_local_variable_it == non_local_variables.end())
+ non_local_variables[nl_variable_name] = new NonLocalVariable(variable_name, nl_variable_name, this->id, nb_component);
+
+
+ AKANTU_DEBUG_OUT();
+
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::registerNonLocalMaterial(Material & new_mat) {
+ non_local_materials.push_back(&new_mat);
+}
+
+/* -------------------------------------------------------------------------- */
+inline ElementTypeMapReal & NonLocalManager::registerWeightFunctionInternal(const ID & field_name) {
+
+ AKANTU_DEBUG_IN();
+
+ std::map<ID, ElementTypeMapReal *>::const_iterator it = this->weight_function_internals.find(field_name);
+ if (it == weight_function_internals.end()) {
+ weight_function_internals[field_name] = new ElementTypeMapReal(field_name, id);
+ }
+
+ return *(weight_function_internals[field_name]);
+
+ AKANTU_DEBUG_OUT();
+
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::updateWeightFunctionInternals() {
+
+ std::map<ID, ElementTypeMapReal *>::const_iterator it = this->weight_function_internals.begin();
+ std::map<ID, ElementTypeMapReal *>::const_iterator end = this->weight_function_internals.end();
+ for (; it != end; ++it) {
+ it->second->clear();
+ for(UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType ghost_type = (GhostType) g;
+ this->flattenInternal(*(it->second), ghost_type, _ek_regular);
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::nonLocalVariableToNeighborhood(const ID & variable_name, const ID & neighborhood) {
+
+ NeighborhoodMap::const_iterator it = neighborhoods.find(neighborhood);
+
+ AKANTU_DEBUG_ASSERT(it != neighborhoods.end(),
+ "The neighborhood " << neighborhood << " is not registered");
+ it->second->registerNonLocalVariable(variable_name);
+
+}
+
+/* -------------------------------------------------------------------------- */
+inline UInt NonLocalManager::getNbDataForElements(const Array<Element> & elements,
+ const ID & id) const {
+ UInt size = 0;
+ UInt nb_quadrature_points = this->getModel().getNbIntegrationPoints(elements);
+ std::map<ID, NonLocalVariable *>::const_iterator it = non_local_variables.find(id);
+
+ AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
+ "The non-local variable " << id << " is not registered");
+
+ size += it->second->nb_component * sizeof(Real) * nb_quadrature_points;
+ return size;
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::packElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag,
+ const ID & id) const {
+
+ std::map<ID, NonLocalVariable *>::const_iterator it = non_local_variables.find(id);
+
+ AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
+ "The non-local variable " << id << " is not registered");
+
+ DataAccessor::packElementalDataHelper<Real>(it->second->local, buffer, elements, true,
+ this->model.getFEEngine());
+}
+
+/* -------------------------------------------------------------------------- */
+inline void NonLocalManager::unpackElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag,
+ const ID & id) const {
+
+ std::map<ID, NonLocalVariable *>::const_iterator it = non_local_variables.find(id);
+
+ AKANTU_DEBUG_ASSERT(it != non_local_variables.end(),
+ "The non-local variable " << id << " is not registered");
+
+ DataAccessor::unpackElementalDataHelper<Real>(it->second->local, buffer, elements, true,
+ this->model.getFEEngine());
+}
+
+__END_AKANTU__
+
+#endif /* __AKANTU_NON_LOCAL_MANAGER_INLINE_IMPL_CC__ */
+
+
+
+
+
+
+
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood.hh b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
new file mode 100644
index 000000000..3ccb7dcc1
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood.hh
@@ -0,0 +1,132 @@
+/**
+ * @file non_local_neighborhood.hh
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Sat Sep 26 18:29:59 2015
+ *
+ * @brief Non-local neighborhood for non-local averaging based on
+ * weight function
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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..b3bb7d761
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.cc
@@ -0,0 +1,110 @@
+/**
+ * @file non_local_neighborhood_base.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Mon Sep 21 18:10:49 2015
+ *
+ * @brief Implementation of non-local neighborhood base
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..9d104308d
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_base.hh
@@ -0,0 +1,122 @@
+/**
+ * @file non_local_neighborhood_base.hh
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Mon Sep 21 15:43:26 2015
+ *
+ * @brief Non-local neighborhood base class
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
+#define __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__
+/* -------------------------------------------------------------------------- */
+#include "neighborhood_base.hh"
+#include "parsable.hh"
+/* -------------------------------------------------------------------------- */
+
+
+
+__BEGIN_AKANTU__
+
+class NonLocalNeighborhoodBase : public NeighborhoodBase,
+ public Parsable{
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ NonLocalNeighborhoodBase(const SolidMechanicsModel & model,
+ const ElementTypeMapReal & quad_coordinates,
+ const ID & id = "non_local_neighborhood",
+ const MemoryID & memory_id = 0);
+ virtual ~NonLocalNeighborhoodBase();
+
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+
+public:
+
+ /// create grid synchronizer and exchange ghost cells
+ virtual void createGridSynchronizer();
+
+ /// compute weights, for instance needed for non-local damage computation
+ virtual void computeWeights() {};
+
+ /// compute the non-local counter part for a given element type map
+ virtual void weightedAverageOnNeighbours(const ElementTypeMapReal & to_accumulate,
+ ElementTypeMapReal & accumulated,
+ UInt nb_degree_of_freedom,
+ const GhostType & ghost_type2) const {};
+
+ /// update the weights for the non-local averaging
+ virtual void updateWeights() {};
+
+ /// register a new non-local variable in the neighborhood
+ virtual void registerNonLocalVariable(const ID & id) {};
+
+ /// clean up the unneccessary ghosts
+ void cleanupExtraGhostElements(std::set<Element> & relevant_ghost_elements);
+
+
+protected:
+
+ /// create the grid
+ void createGrid();
+
+/* -------------------------------------------------------------------------- */
+/* DataAccessor inherited members */
+/* -------------------------------------------------------------------------- */
+public:
+
+ virtual inline UInt getNbDataForElements(const Array<Element> & elements,
+ SynchronizationTag tag) const {return 0; };
+
+ virtual inline void packElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag) const {};
+
+ virtual inline void unpackElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag) {};
+
+/* -------------------------------------------------------------------------- */
+/* Accessors */
+/* -------------------------------------------------------------------------- */
+public:
+ AKANTU_GET_MACRO(NonLocalVariables, non_local_variables, const std::set<ID> &);
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+
+ /// list of non-local variables associated to the neighborhood
+ std::set<ID> non_local_variables;
+};
+
+
+
+__END_AKANTU__
+#endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_BASE_HH__ */
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc b/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
new file mode 100644
index 000000000..77b5640e3
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
@@ -0,0 +1,92 @@
+/**
+ * @file non_local_neighborhood_inline_impl.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Mon Oct 5 09:36:33 2015
+ *
+ * @brief Implementation of inline functions of non-local neighborhood class
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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..794755440
--- /dev/null
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
@@ -0,0 +1,283 @@
+/**
+ * @file non_local_neighborhood_tmpl.hh
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @date Sat Sep 26 18:43:30 2015
+ *
+ * @brief Implementation of class non-local neighborhood
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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/heat_transfer/heat_transfer_model.cc b/src/model/heat_transfer/heat_transfer_model.cc
index 2fda3f8d2..3eb41bb3d 100644
--- a/src/model/heat_transfer/heat_transfer_model.cc
+++ b/src/model/heat_transfer/heat_transfer_model.cc
@@ -1,952 +1,1255 @@
/**
* @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 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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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_internal_material_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const HeatTransferModelOptions default_heat_transfer_model_options(_explicit_lumped_capacity);
/* -------------------------------------------------------------------------- */
HeatTransferModel::HeatTransferModel(Mesh & mesh,
UInt dim,
const ID & id,
const MemoryID & memory_id) :
Model(mesh, dim, id, memory_id), Parsable(_st_heat, id),
- integrator(new ForwardEuler()),
- stiffness_matrix(NULL),
+ 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) {
+ thermal_energy ("thermal_energy", id),
+ solver(NULL),
+ pbc_synch(NULL) {
AKANTU_DEBUG_IN();
createSynchronizerRegistry(this);
std::stringstream sstr; sstr << id << ":fem";
registerFEEngineObject<MyFEEngineType>(sstr.str(), mesh,spatial_dimension);
this->temperature= NULL;
this->residual = NULL;
this->blocked_dofs = NULL;
#ifdef AKANTU_USE_IOHELPER
this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_regular);
#endif
this->registerParam("conductivity" , conductivity , _pat_parsmod);
this->registerParam("conductivity_variation", conductivity_variation, 0., _pat_parsmod);
this->registerParam("temperature_reference" , T_ref , 0., _pat_parsmod);
this->registerParam("capacity" , capacity , _pat_parsmod);
this->registerParam("density" , density , _pat_parsmod);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initModel() {
getFEEngine().initShapeFunctions(_not_ghost);
getFEEngine().initShapeFunctions(_ghost);
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initParallel(MeshPartition * partition,
DataAccessor * data_accessor) {
AKANTU_DEBUG_IN();
if (data_accessor == NULL) data_accessor = this;
Synchronizer & synch_parallel = createParallelSynch(partition,data_accessor);
synch_registry->registerSynchronizer(synch_parallel, _gst_htm_capacity);
synch_registry->registerSynchronizer(synch_parallel, _gst_htm_temperature);
synch_registry->registerSynchronizer(synch_parallel, _gst_htm_gradient_temperature);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initPBC() {
AKANTU_DEBUG_IN();
Model::initPBC();
- 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);
+ synch_registry->registerSynchronizer(*pbc_synch, _gst_htm_capacity);
+ synch_registry->registerSynchronizer(*pbc_synch, _gst_htm_temperature);
changeLocalEquationNumberForPBC(pbc_pair,1);
+ // as long as there are ones on the diagonal of the matrix, we can put boudandary true for slaves
+ std::map<UInt, UInt>::iterator it = pbc_pair.begin();
+ std::map<UInt, UInt>::iterator end = pbc_pair.end();
+ while(it != end) {
+ (*blocked_dofs)((*it).first,0) = true;
+ ++it;
+ }
+
+
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initArrays() {
AKANTU_DEBUG_IN();
UInt nb_nodes = getFEEngine().getMesh().getNbNodes();
std::stringstream sstr_temp; sstr_temp << Model::id << ":temperature";
std::stringstream sstr_temp_rate; sstr_temp_rate << Model::id << ":temperature_rate";
std::stringstream sstr_inc; sstr_inc << Model::id << ":increment";
std::stringstream sstr_ext_flx; sstr_ext_flx << Model::id << ":external_flux";
std::stringstream sstr_residual; sstr_residual << Model::id << ":residual";
std::stringstream sstr_lump; sstr_lump << Model::id << ":lumped";
std::stringstream sstr_boun; sstr_boun << Model::id << ":blocked_dofs";
temperature = &(alloc<Real>(sstr_temp.str(), nb_nodes, 1, REAL_INIT_VALUE));
temperature_rate = &(alloc<Real>(sstr_temp_rate.str(), nb_nodes, 1, REAL_INIT_VALUE));
increment = &(alloc<Real>(sstr_inc.str(), nb_nodes, 1, REAL_INIT_VALUE));
external_heat_rate = &(alloc<Real>(sstr_ext_flx.str(), nb_nodes, 1, REAL_INIT_VALUE));
residual = &(alloc<Real>(sstr_residual.str(), nb_nodes, 1, REAL_INIT_VALUE));
capacity_lumped = &(alloc<Real>(sstr_lump.str(), nb_nodes, 1, REAL_INIT_VALUE));
blocked_dofs = &(alloc<bool>(sstr_boun.str(), nb_nodes, 1, false));
Mesh::ConnectivityTypeList::const_iterator it;
/* -------------------------------------------------------------------------- */
// byelementtype vectors
getFEEngine().getMesh().initElementTypeMapArray(temperature_on_qpoints,
- 1,
- spatial_dimension);
+ 1,
+ spatial_dimension);
getFEEngine().getMesh().initElementTypeMapArray(temperature_gradient,
- spatial_dimension,
- spatial_dimension);
+ spatial_dimension,
+ spatial_dimension);
getFEEngine().getMesh().initElementTypeMapArray(conductivity_on_qpoints,
- spatial_dimension*spatial_dimension,
- spatial_dimension);
+ spatial_dimension*spatial_dimension,
+ spatial_dimension);
getFEEngine().getMesh().initElementTypeMapArray(k_gradt_on_qpoints,
- spatial_dimension,
- spatial_dimension);
+ spatial_dimension,
+ spatial_dimension);
getFEEngine().getMesh().initElementTypeMapArray(bt_k_gT,
- 1,
- spatial_dimension,true);
+ 1,
+ spatial_dimension,
+ true);
getFEEngine().getMesh().initElementTypeMapArray(int_bt_k_gT,
- 1,
- spatial_dimension,true);
+ 1,
+ spatial_dimension,
+ true);
getFEEngine().getMesh().initElementTypeMapArray(thermal_energy,
1,
spatial_dimension);
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
const Mesh::ConnectivityTypeList & type_list =
getFEEngine().getMesh().getConnectivityTypeList(gt);
for(it = type_list.begin(); it != type_list.end(); ++it) {
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
UInt nb_element = getFEEngine().getMesh().getNbElement(*it, gt);
- UInt nb_quad_points = this->getFEEngine().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->initLocalDOFEquationNumbers();
dof_synchronizer->initGlobalDOFEquationNumbers();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
+
void HeatTransferModel::initSolver(__attribute__((unused)) SolverOptions & options) {
#if !defined(AKANTU_USE_MUMPS) // or other solver in the future \todo add AKANTU_HAS_SOLVER in CMake
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#else
UInt nb_global_nodes = mesh.getNbGlobalNodes();
delete jacobian_matrix;
std::stringstream sstr; sstr << Memory::id << ":jacobian_matrix";
jacobian_matrix = new SparseMatrix(nb_global_nodes, _symmetric, sstr.str(), memory_id);
jacobian_matrix->buildProfile(mesh, *dof_synchronizer, 1);
- delete stiffness_matrix;
- std::stringstream sstr_sti; sstr_sti << Memory::id << ":stiffness_matrix";
- stiffness_matrix = new SparseMatrix(*jacobian_matrix, sstr_sti.str(), memory_id);
+ delete conductivity_matrix;
+ std::stringstream sstr_sti; sstr_sti << Memory::id << ":conductivity_matrix";
+ conductivity_matrix = new SparseMatrix(*jacobian_matrix, sstr_sti.str(), memory_id);
#ifdef AKANTU_USE_MUMPS
std::stringstream sstr_solv; sstr_solv << Memory::id << ":solver";
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
dof_synchronizer->initScatterGatherCommunicationScheme();
#else
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#endif //AKANTU_USE_MUMPS
if(solver)
solver->initialize(options);
#endif //AKANTU_HAS_SOLVER
}
/* -------------------------------------------------------------------------- */
-void HeatTransferModel::initImplicit(SolverOptions & solver_options) {
- method = _static;
+void HeatTransferModel::initImplicit(bool dynamic, SolverOptions & solver_options) {
+ AKANTU_DEBUG_IN();
+
+ method = dynamic ? _implicit_dynamic : _static;
initSolver(solver_options);
+
+ if(method == _implicit_dynamic) {
+ if(integrator) delete integrator;
+ integrator = new TrapezoidalRule1();
+ }
+
+ AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
HeatTransferModel::~HeatTransferModel()
{
AKANTU_DEBUG_IN();
+ if (integrator) delete integrator ;
+ if (conductivity_matrix) delete conductivity_matrix;
+ if (capacity_matrix) delete capacity_matrix ;
+ if (jacobian_matrix) delete jacobian_matrix ;
+ if (solver) delete solver ;
+ delete pbc_synch;
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleCapacityLumped(const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
FEEngine & fem = getFEEngine();
const Mesh::ConnectivityTypeList & type_list
= fem.getMesh().getConnectivityTypeList(ghost_type);
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it)
{
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
UInt nb_element = getFEEngine().getMesh().getNbElement(*it,ghost_type);
- UInt nb_quadrature_points = getFEEngine().getNbQuadraturePoints(*it, ghost_type);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(*it, ghost_type);
Array<Real> rho_1 (nb_element * nb_quadrature_points,1, capacity * density);
fem.assembleFieldLumped(rho_1,1,*capacity_lumped,
dof_synchronizer->getLocalDOFEquationNumbers(),
*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::assembleCapacityLumped() {
AKANTU_DEBUG_IN();
capacity_lumped->clear();
assembleCapacityLumped(_not_ghost);
assembleCapacityLumped(_ghost);
getSynchronizerRegistry().synchronize(_gst_htm_capacity);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void HeatTransferModel::updateResidual() {
+void HeatTransferModel::updateResidual(bool compute_conductivity) {
AKANTU_DEBUG_IN();
/// @f$ r = q_{ext} - q_{int} - C \dot T @f$
// start synchronization
synch_registry->asynchronousSynchronize(_gst_htm_temperature);
// finalize communications
synch_registry->waitEndSynchronize(_gst_htm_temperature);
//clear the array
/// first @f$ r = q_{ext} @f$
// residual->clear();
residual->copy(*external_heat_rate);
/// then @f$ r -= q_{int} @f$
// update the not ghost ones
updateResidual(_not_ghost);
// update for the received ghosts
updateResidual(_ghost);
/* if (method == _explicit_lumped_capacity) {
this->solveExplicitLumped();
}*/
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void HeatTransferModel::assembleStiffnessMatrix() {
+void HeatTransferModel::assembleConductivityMatrix(bool compute_conductivity) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Assemble the new stiffness matrix.");
- stiffness_matrix->clear();
+ conductivity_matrix->clear();
switch(mesh.getSpatialDimension()) {
- case 1: this->assembleStiffnessMatrix<1>(_not_ghost); break;
- case 2: this->assembleStiffnessMatrix<2>(_not_ghost); break;
- case 3: this->assembleStiffnessMatrix<3>(_not_ghost); break;
+ 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::assembleStiffnessMatrix(const GhostType & ghost_type) {
+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->assembleStiffnessMatrix<dim>(*it, ghost_type);
+ this->assembleConductivityMatrix<dim>(*it, ghost_type,compute_conductivity);
}
AKANTU_DEBUG_OUT();
}
-
+
+/* -------------------------------------------------------------------------- */
+
+
/* -------------------------------------------------------------------------- */
template <UInt dim>
-void HeatTransferModel::assembleStiffnessMatrix(const ElementType & type, const GhostType & ghost_type) {
+void HeatTransferModel::assembleConductivityMatrix(const ElementType & type,
+ const GhostType & ghost_type,
+ bool compute_conductivity) {
AKANTU_DEBUG_IN();
- SparseMatrix & K = *stiffness_matrix;
+ SparseMatrix & K = *conductivity_matrix;
const Array<Real> & shapes_derivatives = this->getFEEngine().getShapesDerivatives(type, ghost_type);
UInt nb_element = mesh.getNbElement(type, ghost_type);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt nb_quadrature_points = getFEEngine().getNbQuadraturePoints(type, ghost_type);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type, ghost_type);
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_d_b_size = nb_nodes_per_element;
Array<Real> * bt_d_b = new Array<Real>(nb_element * nb_quadrature_points,
bt_d_b_size * bt_d_b_size,
"B^t*D*B");
Matrix<Real> Bt_D(nb_nodes_per_element, dim);
Array<Real>::const_iterator< Matrix<Real> > shapes_derivatives_it = shapes_derivatives.begin(dim, nb_nodes_per_element);
Array<Real>::iterator< Matrix<Real> > Bt_D_B_it = bt_d_b->begin(bt_d_b_size, bt_d_b_size);
- this->computeConductivityOnQuadPoints(ghost_type);
+ if (compute_conductivity)
+ this->computeConductivityOnQuadPoints(ghost_type);
Array<Real>::iterator< Matrix<Real> > D_it = conductivity_on_qpoints(type, ghost_type).begin(dim, dim);
Array<Real>::iterator< Matrix<Real> > D_end = conductivity_on_qpoints(type, ghost_type).end(dim, dim);
for (; D_it != D_end; ++D_it, ++Bt_D_B_it, ++shapes_derivatives_it) {
Matrix<Real> & D = *D_it;
const Matrix<Real> & B = *shapes_derivatives_it;
Matrix<Real> & Bt_D_B = *Bt_D_B_it;
Bt_D.mul<true, false>(B, D);
Bt_D_B.mul<false, false>(Bt_D, B);
}
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e = new Array<Real>(nb_element,
bt_d_b_size * bt_d_b_size,
"K_e");
this->getFEEngine().integrate(*bt_d_b, *K_e,
bt_d_b_size * bt_d_b_size,
type, ghost_type);
delete bt_d_b;
this->getFEEngine().assembleMatrix(*K_e, K, 1, type, ghost_type);
delete K_e;
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
+
+void HeatTransferModel::updateResidualInternal() {
+
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_INFO("Update the residual");
+ // f = q_ext - q_int - Mddot = q - Mddot;
+
+ if(method != _static) {
+ // f -= Mddot
+ if(capacity_matrix) {
+ // if full mass_matrix
+ Array<Real> * Mddot = new Array<Real>(*temperature_rate, true, "Mddot");
+ *Mddot *= *capacity_matrix;
+ *residual -= *Mddot;
+ delete Mddot;
+ } else if (capacity_lumped) {
+
+ // else lumped mass
+ UInt nb_nodes = temperature_rate->getSize();
+ UInt nb_degree_of_freedom = temperature_rate->getNbComponent();
+
+ Real * capacity_val = capacity_lumped->storage();
+ Real * temp_rate_val = temperature_rate->storage();
+ Real * res_val = residual->storage();
+ bool * blocked_dofs_val = blocked_dofs->storage();
+
+ for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
+ if(!(*blocked_dofs_val)) {
+ *res_val -= *temp_rate_val * *capacity_val;
+ }
+ blocked_dofs_val++;
+ res_val++;
+ capacity_val++;
+ temp_rate_val++;
+ }
+ } else {
+ AKANTU_DEBUG_ERROR("No function called to assemble the mass matrix.");
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
/* -------------------------------------------------------------------------- */
void HeatTransferModel::solveStatic() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Solving Ku = f");
- AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
+ AKANTU_DEBUG_ASSERT(conductivity_matrix != NULL,
"You should first initialize the implicit solver and assemble the stiffness matrix");
UInt nb_nodes = temperature->getSize();
UInt nb_degree_of_freedom = temperature->getNbComponent() * nb_nodes;
- jacobian_matrix->copyContent(*stiffness_matrix);
+ jacobian_matrix->copyContent(*conductivity_matrix);
jacobian_matrix->applyBoundary(*blocked_dofs);
increment->clear();
solver->setRHS(*residual);
solver->factorize();
solver->solve(*increment);
Real * increment_val = increment->storage();
Real * temperature_val = temperature->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt j = 0; j < nb_degree_of_freedom;
++j, ++temperature_val, ++increment_val, ++blocked_dofs_val) {
if (!(*blocked_dofs_val)) {
*temperature_val += *increment_val;
}
else {
*increment_val = 0.0;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::computeConductivityOnQuadPoints(const GhostType & ghost_type) {
const Mesh::ConnectivityTypeList & type_list =
this->getFEEngine().getMesh().getConnectivityTypeList(ghost_type);
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it) {
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
Array<Real> & temperature_interpolated = temperature_on_qpoints(*it, ghost_type);
//compute the temperature on quadrature points
- this->getFEEngine().interpolateOnQuadraturePoints(*temperature,
+ this->getFEEngine().interpolateOnIntegrationPoints(*temperature,
temperature_interpolated,
1 ,*it,ghost_type);
Array<Real>::matrix_iterator C_it =
conductivity_on_qpoints(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator C_end =
conductivity_on_qpoints(*it, ghost_type).end(spatial_dimension, spatial_dimension);
Array<Real>::iterator<Real> T_it = temperature_interpolated.begin();
for (;C_it != C_end; ++C_it, ++T_it) {
Matrix<Real> & C = *C_it;
Real & T = *T_it;
C = conductivity;
Matrix<Real> variation(spatial_dimension, spatial_dimension, conductivity_variation * (T - T_ref));
C += conductivity_variation;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void HeatTransferModel::computeKgradT(const GhostType & ghost_type) {
+void HeatTransferModel::computeKgradT(const GhostType & ghost_type,bool compute_conductivity) {
- computeConductivityOnQuadPoints(ghost_type);
+ if (compute_conductivity)
+ computeConductivityOnQuadPoints(ghost_type);
const Mesh::ConnectivityTypeList & type_list =
this->getFEEngine().getMesh().getConnectivityTypeList(ghost_type);
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it) {
const ElementType & type = *it;
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
Array<Real> & gradient = temperature_gradient(*it, ghost_type);
- this->getFEEngine().gradientOnQuadraturePoints(*temperature,
+ this->getFEEngine().gradientOnIntegrationPoints(*temperature,
gradient,
1 ,*it, ghost_type);
Array<Real>::matrix_iterator C_it =
conductivity_on_qpoints(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
Array<Real>::vector_iterator BT_it = gradient.begin(spatial_dimension);
Array<Real>::vector_iterator k_BT_it =
k_gradt_on_qpoints(type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator k_BT_end =
k_gradt_on_qpoints(type, ghost_type).end(spatial_dimension);
for (;k_BT_it != k_BT_end; ++k_BT_it, ++BT_it, ++C_it) {
Vector<Real> & k_BT = *k_BT_it;
Vector<Real> & BT = *BT_it;
Matrix<Real> & C = *C_it;
k_BT.mul<false>(C, BT);
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void HeatTransferModel::updateResidual(const GhostType & ghost_type) {
+void HeatTransferModel::updateResidual(const GhostType & ghost_type, bool compute_conductivity) {
AKANTU_DEBUG_IN();
const Mesh::ConnectivityTypeList & type_list =
this->getFEEngine().getMesh().getConnectivityTypeList(ghost_type);
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it) {
if(Mesh::getSpatialDimension(*it) != spatial_dimension) continue;
Array<Real> & shapes_derivatives =
const_cast<Array<Real> &>(getFEEngine().getShapesDerivatives(*it,ghost_type));
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
// compute k \grad T
- computeKgradT(ghost_type);
+ computeKgradT(ghost_type,compute_conductivity);
Array<Real>::vector_iterator k_BT_it =
k_gradt_on_qpoints(*it,ghost_type).begin(spatial_dimension);
Array<Real>::matrix_iterator B_it =
shapes_derivatives.begin(spatial_dimension, nb_nodes_per_element);
Array<Real>::vector_iterator Bt_k_BT_it =
bt_k_gT(*it,ghost_type).begin(nb_nodes_per_element);
Array<Real>::vector_iterator Bt_k_BT_end =
bt_k_gT(*it,ghost_type).end(nb_nodes_per_element);
for (;Bt_k_BT_it != Bt_k_BT_end; ++Bt_k_BT_it, ++B_it, ++k_BT_it) {
Vector<Real> & k_BT = *k_BT_it;
Vector<Real> & Bt_k_BT = *Bt_k_BT_it;
Matrix<Real> & B = *B_it;
Bt_k_BT.mul<true>(B, k_BT);
}
this->getFEEngine().integrate(bt_k_gT(*it,ghost_type),
int_bt_k_gT(*it,ghost_type),
nb_nodes_per_element, *it,ghost_type);
this->getFEEngine().assembleArray(int_bt_k_gT(*it,ghost_type), *residual,
dof_synchronizer->getLocalDOFEquationNumbers(),
1, *it,ghost_type, empty_filter, -1);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::solveExplicitLumped() {
AKANTU_DEBUG_IN();
/// finally @f$ r -= C \dot T @f$
// lumped C
UInt nb_nodes = temperature_rate->getSize();
UInt nb_degree_of_freedom = temperature_rate->getNbComponent();
Real * capacity_val = capacity_lumped->storage();
Real * temp_rate_val = temperature_rate->storage();
Real * res_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*res_val -= *capacity_val * *temp_rate_val;
}
blocked_dofs_val++;
res_val++;
capacity_val++;
temp_rate_val++;
}
#ifndef AKANTU_NDEBUG
getSynchronizerRegistry().synchronize(akantu::_gst_htm_gradient_temperature);
#endif
capacity_val = capacity_lumped->storage();
res_val = residual->storage();
blocked_dofs_val = blocked_dofs->storage();
Real * inc = increment->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*inc = (*res_val / *capacity_val);
}
res_val++;
blocked_dofs_val++;
inc++;
capacity_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::explicitPred() {
AKANTU_DEBUG_IN();
+ AKANTU_DEBUG_ASSERT(integrator, "integrator was not instanciated");
integrator->integrationSchemePred(time_step,
*temperature,
*temperature_rate,
*blocked_dofs);
UInt nb_nodes = temperature->getSize();
UInt nb_degree_of_freedom = temperature->getNbComponent();
Real * temp = temperature->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n, ++temp)
if(*temp < 0.) *temp = 0.;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::explicitCorr() {
AKANTU_DEBUG_IN();
integrator->integrationSchemeCorrTempRate(time_step,
*temperature,
*temperature_rate,
*blocked_dofs,
*increment);
AKANTU_DEBUG_OUT();
}
+
+/* -------------------------------------------------------------------------- */
+void HeatTransferModel::implicitPred(){
+ AKANTU_DEBUG_IN();
+
+ if(method == _implicit_dynamic)
+ integrator->integrationSchemePred(time_step,
+ *temperature,
+ *temperature_rate,
+ *blocked_dofs);
+
+ AKANTU_DEBUG_OUT();
+}
+/* -------------------------------------------------------------------------- */
+
+void HeatTransferModel::implicitCorr(){
+
+ AKANTU_DEBUG_IN();
+
+ if(method == _implicit_dynamic) {
+ integrator->integrationSchemeCorrTemp(time_step,
+ *temperature,
+ *temperature_rate,
+ *blocked_dofs,
+ *increment);
+ } else {
+ UInt nb_nodes = temperature->getSize();
+ UInt nb_degree_of_freedom = temperature->getNbComponent() * nb_nodes;
+
+ Real * incr_val = increment->storage();
+ Real * temp_val = temperature->storage();
+ bool * boun_val = blocked_dofs->storage();
+
+ for (UInt j = 0; j < nb_degree_of_freedom; ++j, ++temp_val, ++incr_val, ++boun_val){
+ *incr_val *= (1. - *boun_val);
+ *temp_val += *incr_val;
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getStableTimeStep()
{
AKANTU_DEBUG_IN();
Real el_size;
Real min_el_size = std::numeric_limits<Real>::max();
Real conductivitymax = conductivity(0, 0);
//get the biggest parameter from k11 until k33//
for(UInt i = 0; i < spatial_dimension; i++)
for(UInt j = 0; j < spatial_dimension; j++)
conductivitymax = std::max(conductivity(i, j), conductivitymax);
const Mesh::ConnectivityTypeList & type_list =
getFEEngine().getMesh().getConnectivityTypeList();
Mesh::ConnectivityTypeList::const_iterator it;
for(it = type_list.begin(); it != type_list.end(); ++it) {
if(getFEEngine().getMesh().getSpatialDimension(*it) != spatial_dimension)
continue;
UInt nb_nodes_per_element = getFEEngine().getMesh().getNbNodesPerElement(*it);
Array<Real> coord(0, nb_nodes_per_element*spatial_dimension);
FEEngine::extractNodalToElementField(getFEEngine().getMesh(), getFEEngine().getMesh().getNodes(),
coord, *it, _not_ghost);
Array<Real>::matrix_iterator el_coord = coord.begin(spatial_dimension, nb_nodes_per_element);
UInt nb_element = getFEEngine().getMesh().getNbElement(*it);
for (UInt el = 0; el < nb_element; ++el, ++el_coord) {
el_size = getFEEngine().getElementInradius(*el_coord, *it);
min_el_size = std::min(min_el_size, el_size);
}
AKANTU_DEBUG_INFO("The minimum element size : " << min_el_size
<< " and the max conductivity is : "
<< conductivitymax);
}
Real min_dt = 2 * min_el_size * min_el_size * density
* capacity / conductivitymax;
StaticCommunicator::getStaticCommunicator().allReduce(&min_dt, 1, _so_min);
AKANTU_DEBUG_OUT();
return min_dt;
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::readMaterials() {
std::pair<Parser::const_section_iterator, Parser::const_section_iterator>
sub_sect = this->parser->getSubSections(_st_heat);
Parser::const_section_iterator it = sub_sect.first;
const ParserSection & section = *it;
this->parseSection(section);
}
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initFull(const ModelOptions & options){
Model::initFull(options);
readMaterials();
- const HeatTransferModelOptions & my_options = dynamic_cast<const HeatTransferModelOptions &>(options);
+ const HeatTransferModelOptions & my_options
+ = dynamic_cast<const HeatTransferModelOptions &>(options);
+
+ method = my_options.analysis_method;
//initialize the vectors
initArrays();
temperature->clear();
temperature_rate->clear();
external_heat_rate->clear();
- method = my_options.analysis_method;
+
+ // initialize pbc
+ if(pbc_pair.size()!=0)
+ initPBC();
+ if (method == _explicit_lumped_capacity){
+ integrator = new ForwardEuler();
+ }
+ if (method == _implicit_dynamic) {
+ initImplicit(true);
+ }
if (method == _static) {
- initImplicit();
+ initImplicit(false);
+ }
+}
+/* -------------------------------------------------------------------------- */
+void HeatTransferModel::assembleCapacity() {
+ AKANTU_DEBUG_IN();
+
+ if(!capacity_matrix) {
+ std::stringstream sstr; sstr << id << ":capacity_matrix";
+ capacity_matrix = new SparseMatrix(*jacobian_matrix, sstr.str(), memory_id);
+ }
+
+ assembleCapacity(_not_ghost);
+ // assembleMass(_ghost);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void HeatTransferModel::assembleCapacity(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
+
+ Array<Real> rho_1(0,1);
+ //UInt nb_element;
+ capacity_matrix->clear();
+
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
+ Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
+ for(; it != end; ++it) {
+ ElementType type = *it;
+
+ computeRho(rho_1, type, ghost_type);
+ fem.assembleFieldMatrix(rho_1, 1, *capacity_matrix, type, ghost_type);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+void HeatTransferModel::computeRho(Array<Real> & rho,
+ ElementType type,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ FEEngine & fem = this->getFEEngine();
+ UInt nb_element = fem.getMesh().getNbElement(type,ghost_type);
+ UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
+
+ rho.resize(nb_element * nb_quadrature_points);
+ Real * rho_1_val = rho.storage();
+
+ /// compute @f$ rho @f$ for each nodes of each element
+ for (UInt el = 0; el < nb_element; ++el) {
+
+ for (UInt n = 0; n < nb_quadrature_points; ++n) {
+ *rho_1_val++ = this->capacity;
+ }
}
+
+ AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
+
+template<>
+bool HeatTransferModel::testConvergence<_scc_increment>(Real tolerance, Real & error){
+ AKANTU_DEBUG_IN();
+
+ UInt nb_nodes = temperature->getSize();
+ UInt nb_degree_of_freedom = temperature->getNbComponent();
+
+ error = 0;
+ Real norm[2] = {0., 0.};
+ Real * increment_val = increment->storage();
+ bool * blocked_dofs_val = blocked_dofs->storage();
+ Real * temperature_val = temperature->storage();
+
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ bool is_local_node = mesh.isLocalOrMasterNode(n);
+ for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
+ if(!(*blocked_dofs_val) && is_local_node) {
+ norm[0] += *increment_val * *increment_val;
+ norm[1] += *temperature_val * *temperature_val;
+ }
+ blocked_dofs_val++;
+ increment_val++;
+ temperature_val++;
+ }
+ }
+
+ StaticCommunicator::getStaticCommunicator().allReduce(norm, 2, _so_sum);
+
+ norm[0] = sqrt(norm[0]);
+ norm[1] = sqrt(norm[1]);
+
+ AKANTU_DEBUG_ASSERT(!Math::isnan(norm[0]), "Something goes wrong in the solve phase");
+
+ if (norm[1] < Math::getTolerance()) {
+ error = norm[0];
+ AKANTU_DEBUG_OUT();
+ // cout<<"Error 1: "<<error<<endl;
+ return error < tolerance;
+ }
+
+
+ AKANTU_DEBUG_OUT();
+ if(norm[1] > Math::getTolerance())
+ error = norm[0] / norm[1];
+ else
+ error = norm[0]; //In case the total displacement is zero!
+
+ // cout<<"Error 2: "<<error<<endl;
+
+ return (error < tolerance);
+}
+
+
/* -------------------------------------------------------------------------- */
void HeatTransferModel::initFEEngineBoundary(bool create_surface) {
if(create_surface)
MeshUtils::buildFacets(getFEEngine().getMesh());
FEEngine & fem_boundary = getFEEngineBoundary();
fem_boundary.initShapeFunctions();
- fem_boundary.computeNormalsOnControlPoints();
+ fem_boundary.computeNormalsOnIntegrationPoints();
}
/* -------------------------------------------------------------------------- */
+
Real HeatTransferModel::computeThermalEnergyByNode() {
AKANTU_DEBUG_IN();
Real ethermal = 0.;
Array<Real>::vector_iterator heat_rate_it =
residual->begin(residual->getNbComponent());
Array<Real>::vector_iterator heat_rate_end =
residual->end(residual->getNbComponent());
UInt n = 0;
for(;heat_rate_it != heat_rate_end; ++heat_rate_it, ++n) {
Real heat = 0;
bool is_local_node = mesh.isLocalOrMasterNode(n);
bool is_not_pbc_slave_node = !isPBCSlaveNode(n);
bool count_node = is_local_node && is_not_pbc_slave_node;
Vector<Real> & heat_rate = *heat_rate_it;
for (UInt i = 0; i < heat_rate.size(); ++i) {
if (count_node)
heat += heat_rate[i] * time_step;
}
ethermal += heat;
}
StaticCommunicator::getStaticCommunicator().allReduce(&ethermal, 1, _so_sum);
AKANTU_DEBUG_OUT();
return ethermal;
}
/* -------------------------------------------------------------------------- */
template<class iterator>
void HeatTransferModel::getThermalEnergy(iterator Eth,
Array<Real>::const_iterator<Real> T_it,
Array<Real>::const_iterator<Real> T_end) const {
for(;T_it != T_end; ++T_it, ++Eth) {
*Eth = capacity * density * *T_it;
}
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getThermalEnergy(const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
- UInt nb_quadrature_points = getFEEngine().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_end = T_it + nb_quadrature_points;
getThermalEnergy(Eth_on_quarature_points.storage(), T_it, T_end);
return getFEEngine().integrate(Eth_on_quarature_points, type, index);
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getThermalEnergy() {
Real Eth = 0;
Mesh & mesh = getFEEngine().getMesh();
Mesh::type_iterator it = mesh.firstType(spatial_dimension);
Mesh::type_iterator last_type = mesh.lastType(spatial_dimension);
for(; it != last_type; ++it) {
UInt nb_element = getFEEngine().getMesh().getNbElement(*it, _not_ghost);
- UInt nb_quadrature_points = getFEEngine().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_end = this->temperature_on_qpoints(*it).end();
getThermalEnergy(Eth_per_quad.begin(), T_it, T_end);
Eth += getFEEngine().integrate(Eth_per_quad, *it);
}
return Eth;
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getEnergy(const std::string & id) {
AKANTU_DEBUG_IN();
Real energy = 0;
if("thermal") energy = getThermalEnergy();
// reduction sum over all processors
StaticCommunicator::getStaticCommunicator().allReduce(&energy, 1, _so_sum);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
Real HeatTransferModel::getEnergy(const std::string & energy_id, const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
Real energy = 0.;
if("thermal") energy = getThermalEnergy(type, index);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+#ifdef AKANTU_USE_IOHELPER
+
dumper::Field * HeatTransferModel::createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
std::map<std::string,Array<bool>* > uint_nodal_fields;
uint_nodal_fields["blocked_dofs" ] = blocked_dofs;
dumper::Field * field = NULL;
field = mesh.createNodalField(uint_nodal_fields[field_name],group_name);
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * HeatTransferModel::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
std::map<std::string,Array<Real>* > real_nodal_fields;
real_nodal_fields["temperature" ] = temperature;
real_nodal_fields["temperature_rate" ] = temperature_rate;
real_nodal_fields["external_heat_rate" ] = external_heat_rate;
real_nodal_fields["residual" ] = residual;
real_nodal_fields["capacity_lumped" ] = capacity_lumped;
+ real_nodal_fields["increment" ] = increment;
dumper::Field * field =
mesh.createNodalField(real_nodal_fields[field_name],group_name);
return field;
}
+
/* -------------------------------------------------------------------------- */
+
dumper::Field * HeatTransferModel
::createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
+ const UInt & spatial_dimension,
const ElementKind & element_kind){
dumper::Field * field = NULL;
if(field_name == "partitions")
field = mesh.createElementalField<UInt, dumper::ElementPartitionField>(mesh.getConnectivities(),group_name,this->spatial_dimension,element_kind);
else if(field_name == "temperature_gradient"){
ElementTypeMap<UInt> nb_data_per_elem = this->mesh.getNbDataPerElem(temperature_gradient,element_kind);
field =
mesh.createElementalField<Real,
dumper::InternalMaterialField>(temperature_gradient,
group_name,
this->spatial_dimension,
element_kind,
nb_data_per_elem);
}
+ else if(field_name == "conductivity"){
+ ElementTypeMap<UInt> nb_data_per_elem = this->mesh.getNbDataPerElem(conductivity_on_qpoints,element_kind);
+
+ field =
+ mesh.createElementalField<Real,
+ dumper::InternalMaterialField>(conductivity_on_qpoints,
+ group_name,
+ this->spatial_dimension,
+ element_kind,
+ nb_data_per_elem);
+ }
return field;
}
+/* -------------------------------------------------------------------------- */
+#else
+/* -------------------------------------------------------------------------- */
+dumper::Field * HeatTransferModel
+::createElementalField(const std::string & field_name,
+ const std::string & group_name,
+ bool padding_flag,
+ const ElementKind & element_kind){
+ return NULL;
+}
+
+/* -------------------------------------------------------------------------- */
+
+dumper::Field * HeatTransferModel::createNodalFieldBool(const std::string & field_name,
+ const std::string & group_name,
+ bool padding_flag) {
+
+ return NULL;
+
+}
/* -------------------------------------------------------------------------- */
-
-
+
+dumper::Field * HeatTransferModel::createNodalFieldReal(const std::string & field_name,
+ const std::string & group_name,
+ bool padding_flag) {
+
+ return NULL;
+}
+
+
+
+#endif
__END_AKANTU__
diff --git a/src/model/heat_transfer/heat_transfer_model.hh b/src/model/heat_transfer/heat_transfer_model.hh
index b3235ee09..b84341028 100644
--- a/src/model/heat_transfer/heat_transfer_model.hh
+++ b/src/model/heat_transfer/heat_transfer_model.hh
@@ -1,391 +1,455 @@
/**
* @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>
*
* @date creation: Sun May 01 2011
* @date last modification: Tue Sep 02 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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(SolverOptions & solver_options = _solver_no_options);
+ 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();
+ 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 the static equilibrium
+
+ /**
+ * solve Kt = q
+ **/
void solveStatic();
- //
- /// assemble the stiffness matrix
- void assembleStiffnessMatrix();
+ /// 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);
+ 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 stiffness matrix (w/ ghost type)
+ /// assemble the conductivity matrix (w/ ghost type)
template <UInt dim>
- void assembleStiffnessMatrix(const GhostType & ghost_type);
+ void assembleConductivityMatrix(const GhostType & ghost_type,
+ bool compute_conductivity = true);
- /// assemble the stiffness matrix
+ /// assemble the conductivity matrix
template <UInt dim>
- void assembleStiffnessMatrix(const ElementType & type, const GhostType & ghost_type);
+ 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);
+ 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 stiffness matrix
- AKANTU_GET_MACRO(StiffnessMatrix, *stiffness_matrix, const SparseMatrix&);
+ /// 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;
- /// stiffness matrix
- SparseMatrix * stiffness_matrix;
+ /// 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 b4828e30d..00007b56a 100644
--- a/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
+++ b/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
@@ -1,296 +1,467 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 6d8a0a54c..43cc7fef6 100644
--- a/src/model/integration_scheme/generalized_trapezoidal.hh
+++ b/src/model/integration_scheme/generalized_trapezoidal.hh
@@ -1,169 +1,169 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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} + \Delta t v_{n} \\
+ * u^0_{n+1} &=& u_{n} + (1-\alpha) \Delta t v_{n} \\
* \dot{u}^0_{n+1} &=& \dot{u}_{n}
* @f}
*
* Solve :
* @f[ (a C + b K^i_{n+1}) w = q_{n+1} - f^i_{n+1} - C \dot{u}^i_{n+1} @f]
*
* Corrector :
* @f{eqnarray*}{
* \dot{u}^{i+1}_{n+1} &=& \dot{u}^{i}_{n+1} + a w \\
* u^{i+1}_{n+1} &=& u^{i}_{n+1} + b w
* @f}
*
* a and b depends on the resolution method : temperature (u) or temperature rate (@f$\dot{u}@f$)
*
* For temperature : @f$ w = \delta u, a = 1 / (\alpha \Delta t) , b = 1 @f$ @n
* For temperature rate : @f$ w = \delta \dot{u}, a = 1, b = \alpha \Delta t @f$
*/
class GeneralizedTrapezoidal : public IntegrationScheme1stOrder {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
GeneralizedTrapezoidal(Real alpha) : alpha(alpha) {};
virtual ~GeneralizedTrapezoidal() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void integrationSchemePred(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs);
virtual void integrationSchemeCorrTemp(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta);
virtual void integrationSchemeCorrTempRate(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta);
public:
/// the coeffichent @f{b@f} in the description
template<IntegrationSchemeCorrectorType type>
Real getTemperatureCoefficient(Real delta_t);
/// the coeffichent @f{a@f} in the description
template<IntegrationSchemeCorrectorType type>
Real getTemperatureRateCoefficient(Real delta_t);
private:
template<IntegrationSchemeCorrectorType type>
void integrationSchemeCorr(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(Alpha, alpha, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// the @f$\alpha@f$ parameter
const Real alpha;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "generalized_trapezoidal_inline_impl.cc"
#endif
/**
* Forward Euler (explicit) -> condition on delta_t
*/
class ForwardEuler : public GeneralizedTrapezoidal {
public:
ForwardEuler() : GeneralizedTrapezoidal(0.) {};
};
/**
* Trapezoidal rule (implicit), midpoint rule or Crank-Nicolson
*/
class TrapezoidalRule1 : public GeneralizedTrapezoidal {
public:
TrapezoidalRule1() : GeneralizedTrapezoidal(.5) {};
};
/**
* Backward Euler (implicit)
*/
class BackwardEuler : public GeneralizedTrapezoidal {
public:
BackwardEuler() : GeneralizedTrapezoidal(1.) {};
};
__END_AKANTU__
#endif /* __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__ */
diff --git a/src/model/integration_scheme/generalized_trapezoidal_inline_impl.cc b/src/model/integration_scheme/generalized_trapezoidal_inline_impl.cc
index 713dc67f9..8b8766182 100644
--- a/src/model/integration_scheme/generalized_trapezoidal_inline_impl.cc
+++ b/src/model/integration_scheme/generalized_trapezoidal_inline_impl.cc
@@ -1,146 +1,146 @@
/**
* @file generalized_trapezoidal_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Jul 04 2011
* @date last modification: Thu Jun 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
inline void GeneralizedTrapezoidal::integrationSchemePred(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs) {
AKANTU_DEBUG_IN();
UInt nb_nodes = u.getSize();
UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
Real * u_val = u.storage();
Real * u_dot_val = u_dot.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
for (UInt d = 0; d < nb_degree_of_freedom; d++) {
if(!(*blocked_dofs_val)) {
- *u_val += delta_t * *u_dot_val;
+ *u_val += (1. - alpha) * delta_t * *u_dot_val;
}
u_val++;
u_dot_val++;
blocked_dofs_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void GeneralizedTrapezoidal::integrationSchemeCorrTemp(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) {
AKANTU_DEBUG_IN();
integrationSchemeCorr<GeneralizedTrapezoidal::_temperature_corrector>(delta_t,
u,
u_dot,
blocked_dofs,
delta);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void GeneralizedTrapezoidal::integrationSchemeCorrTempRate(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) {
AKANTU_DEBUG_IN();
integrationSchemeCorr<GeneralizedTrapezoidal::_temperature_rate_corrector>(delta_t,
u,
u_dot,
blocked_dofs,
delta);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
inline Real GeneralizedTrapezoidal::getTemperatureCoefficient<GeneralizedTrapezoidal::_temperature_corrector>(__attribute__ ((unused)) Real delta_t) {
return 1.;
}
template<>
inline Real GeneralizedTrapezoidal::getTemperatureRateCoefficient<GeneralizedTrapezoidal::_temperature_corrector>(Real delta_t) {
return 1./(alpha * delta_t);
}
/* -------------------------------------------------------------------------- */
template<>
inline Real GeneralizedTrapezoidal::getTemperatureCoefficient<GeneralizedTrapezoidal::_temperature_rate_corrector>(Real delta_t) {
return alpha * delta_t;
}
template<>
inline Real GeneralizedTrapezoidal::getTemperatureRateCoefficient<GeneralizedTrapezoidal::_temperature_rate_corrector>(__attribute__ ((unused)) Real delta_t) {
return 1.;
}
/* -------------------------------------------------------------------------- */
template<GeneralizedTrapezoidal::IntegrationSchemeCorrectorType type>
inline void GeneralizedTrapezoidal::integrationSchemeCorr(Real delta_t,
Array<Real> & u,
Array<Real> & u_dot,
Array<bool> & blocked_dofs,
Array<Real> & delta) {
AKANTU_DEBUG_IN();
UInt nb_nodes = u.getSize();
UInt nb_degree_of_freedom = u.getNbComponent() * nb_nodes;
Real e = getTemperatureCoefficient<type>(delta_t);
Real d = getTemperatureRateCoefficient<type>(delta_t);
Real * u_val = u.storage();
Real * u_dot_val = u_dot.storage();
Real * delta_val = delta.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
for (UInt dof = 0; dof < nb_degree_of_freedom; dof++) {
if(!(*blocked_dofs_val)) {
*u_val += e * *delta_val;
*u_dot_val += d * *delta_val;
}
u_val++;
u_dot_val++;
delta_val++;
blocked_dofs_val++;
}
AKANTU_DEBUG_OUT();
}
diff --git a/src/model/model.cc b/src/model/model.cc
index 45928f30e..764277053 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -1,373 +1,396 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "model.hh"
#include "element_group.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
Model::Model(Mesh& m, UInt dim, const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id), mesh(m),
spatial_dimension(dim == _all_dimensions ? m.getSpatialDimension() : dim),
- synch_registry(NULL),is_pbc_slave_node(0,1,"is_pbc_slave_node") ,
+ synch_registry(NULL),
+ dof_synchronizer(NULL),
+ is_pbc_slave_node(0,1,"is_pbc_slave_node") ,
parser(&getStaticParser()) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Model::~Model() {
AKANTU_DEBUG_IN();
FEEngineMap::iterator it;
for (it = fems.begin(); it != fems.end(); ++it) {
if(it->second) delete it->second;
}
for (it = fems_boundary.begin(); it != fems_boundary.end(); ++it) {
if(it->second) delete it->second;
}
delete synch_registry;
delete dof_synchronizer;
dof_synchronizer = NULL;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Model::setParser(Parser & parser){
this->parser = &parser;
}
/* -------------------------------------------------------------------------- */
void Model::initFull(const ModelOptions & options) {
AKANTU_DEBUG_IN();
initModel();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Model::createSynchronizerRegistry(DataAccessor * data_accessor){
synch_registry = new SynchronizerRegistry(*data_accessor);
}
/* -------------------------------------------------------------------------- */
void Model::setPBC(UInt x, UInt y, UInt z){
mesh.computeBoundingBox();
if (x) MeshUtils::computePBCMap(this->mesh, 0, this->pbc_pair);
if (y) MeshUtils::computePBCMap(this->mesh, 1, this->pbc_pair);
if (z) MeshUtils::computePBCMap(this->mesh, 2, this->pbc_pair);
}
/* -------------------------------------------------------------------------- */
void Model::setPBC(SurfacePairList & surface_pairs){
SurfacePairList::iterator s_it;
for(s_it = surface_pairs.begin(); s_it != surface_pairs.end(); ++s_it) {
MeshUtils::computePBCMap(this->mesh, *s_it, this->pbc_pair);
}
}
/* -------------------------------------------------------------------------- */
void Model::initPBC() {
std::map<UInt,UInt>::iterator it = pbc_pair.begin();
std::map<UInt,UInt>::iterator end = pbc_pair.end();
is_pbc_slave_node.resize(mesh.getNbNodes());
#ifndef AKANTU_NDEBUG
- 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){
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){
AKANTU_DEBUG_IN();
/* ------------------------------------------------------------------------ */
/* Parallel initialization */
/* ------------------------------------------------------------------------ */
StaticCommunicator & comm =
StaticCommunicator::getStaticCommunicator();
Int prank = comm.whoAmI();
DistributedSynchronizer * synch = NULL;
if(prank == 0)
synch =
DistributedSynchronizer::createDistributedSynchronizerMesh(getFEEngine().getMesh(),
partition);
else
synch =
DistributedSynchronizer::createDistributedSynchronizerMesh(getFEEngine().getMesh(),
NULL);
AKANTU_DEBUG_OUT();
return *synch;
}
/* -------------------------------------------------------------------------- */
void Model::dumpGroup(const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.dump();
}
/* -------------------------------------------------------------------------- */
void Model::dumpGroup(const std::string & group_name,
const std::string & dumper_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.dump(dumper_name);
}
/* -------------------------------------------------------------------------- */
void Model::dumpGroup() {
GroupManager::element_group_iterator bit = mesh.element_group_begin();
GroupManager::element_group_iterator bend = mesh.element_group_end();
for(; bit != bend; ++bit) {
bit->second->dump();
}
}
/* -------------------------------------------------------------------------- */
void Model::setGroupDirectory(const std::string & directory) {
GroupManager::element_group_iterator bit = mesh.element_group_begin();
GroupManager::element_group_iterator bend = mesh.element_group_end();
for (; bit != bend; ++bit) {
bit->second->setDirectory(directory);
}
}
/* -------------------------------------------------------------------------- */
void Model::setGroupDirectory(const std::string & directory,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.setDirectory(directory);
}
/* -------------------------------------------------------------------------- */
void Model::setGroupBaseName(const std::string & basename,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
group.setBaseName(basename);
}
/* -------------------------------------------------------------------------- */
DumperIOHelper & Model::getGroupDumper(const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
return group.getDumper();
}
/* -------------------------------------------------------------------------- */
// DUMPER stuff
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldToDumper(const std::string & field_id,
dumper::Field * field,
DumperIOHelper & dumper) {
#ifdef AKANTU_USE_IOHELPER
dumper.registerField(field_id,field);
#endif
}
/* -------------------------------------------------------------------------- */
void Model::addDumpField(const std::string & field_id) {
this->addDumpFieldToDumper(mesh.getDefaultDumperName(),field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldVector(const std::string & field_id) {
this->addDumpFieldVectorToDumper(mesh.getDefaultDumperName(),field_id);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldTensor(const std::string & field_id) {
this->addDumpFieldTensorToDumper(mesh.getDefaultDumperName(),field_id);
}
/* -------------------------------------------------------------------------- */
void Model::setBaseName(const std::string & field_id) {
mesh.setBaseName(field_id);
}
/* -------------------------------------------------------------------------- */
void Model::setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename) {
mesh.setBaseNameToDumper(dumper_name,basename);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+ const std::string & field_id) {
this->addDumpGroupFieldToDumper(dumper_name,field_id,"all",_ek_regular,false);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupField(const std::string & field_id,
const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
this->addDumpGroupFieldToDumper(group.getDefaultDumperName(),
field_id,
group_name,_ek_regular,false);
}
/* -------------------------------------------------------------------------- */
void Model::removeDumpGroupField(const std::string & field_id,
- const std::string & group_name) {
+ const std::string & group_name) {
ElementGroup & group = mesh.getElementGroup(group_name);
this->removeDumpGroupFieldFromDumper(group.getDefaultDumperName(),
field_id,
group_name);
}
/* -------------------------------------------------------------------------- */
void Model::removeDumpGroupFieldFromDumper(const std::string & dumper_name,
- const std::string & field_id,
- const std::string & group_name) {
+ 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) {
-
ElementGroup & group = mesh.getElementGroup(group_name);
this->addDumpGroupFieldVectorToDumper(group.getDefaultDumperName(),
field_id,
group_name);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name) {
this->addDumpGroupFieldToDumper(dumper_name,field_id,group_name,_ek_regular,true);
}
/* -------------------------------------------------------------------------- */
void Model::addDumpFieldTensorToDumper(const std::string & dumper_name,
- const std::string & field_id) {
+ const std::string & field_id) {
this->addDumpGroupFieldToDumper(dumper_name,field_id,"all",_ek_regular,true);
}
/* -------------------------------------------------------------------------- */
+void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id,
+ const std::string & group_name,
+ const ElementKind & element_kind,
+ bool padding_flag) {
+ this->addDumpGroupFieldToDumper(dumper_name,
+ field_id,
+ group_name,
+ this->spatial_dimension,
+ element_kind,
+ padding_flag);
+}
+/* -------------------------------------------------------------------------- */
void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
- const std::string & field_id,
- const std::string & group_name,
- const ElementKind & element_kind,
- bool padding_flag) {
+ const std::string & field_id,
+ const std::string & group_name,
+ UInt spatial_dimension,
+ const ElementKind & element_kind,
+ bool padding_flag) {
#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,element_kind);
+ if (!field) field = this->createElementalField(field_id,group_name,padding_flag,spatial_dimension,element_kind);
if (!field) field =
this->mesh.createFieldFromAttachedData<UInt>(field_id,group_name,
element_kind);
if (!field) field =
this->mesh.createFieldFromAttachedData<Real>(field_id,group_name,
element_kind);
if (!field) AKANTU_DEBUG_WARNING("No field could be found based on name: " << field_id);
if (field) {
DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name,group_name);
this->addDumpGroupFieldToDumper(field_id,field,dumper);
}
#endif
}
/* -------------------------------------------------------------------------- */
void Model::dump() {
mesh.dump();
}
/* -------------------------------------------------------------------------- */
void Model::setDirectory(const std::string & directory) {
mesh.setDirectory(directory);
}
/* -------------------------------------------------------------------------- */
void Model::setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory) {
mesh.setDirectoryToDumper(dumper_name,directory);
}
+/* -------------------------------------------------------------------------- */
+
+void Model::setTextModeToDumper(){
+ mesh.setTextModeToDumper();
+}
+
+/* -------------------------------------------------------------------------- */
+
__END_AKANTU__
diff --git a/src/model/model.hh b/src/model/model.hh
index ee38ae66e..283a95e6a 100644
--- a/src/model/model.hh
+++ b/src/model/model.hh
@@ -1,316 +1,326 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MODEL_HH__
#define __AKANTU_MODEL_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_memory.hh"
#include "mesh.hh"
#include "fe_engine.hh"
#include "mesh_utils.hh"
#include "synchronizer_registry.hh"
#include "distributed_synchronizer.hh"
#include "static_communicator.hh"
#include "mesh_partition.hh"
#include "dof_synchronizer.hh"
#include "pbc_synchronizer.hh"
#include "parser.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
struct ModelOptions {
virtual ~ModelOptions() {}
};
class DumperIOHelper;
class Model : public Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef Mesh mesh_type;
Model(Mesh& mesh, UInt spatial_dimension = _all_dimensions,
- const ID & id = "model",
- const MemoryID & memory_id = 0);
+ const ID & id = "model",
+ const MemoryID & memory_id = 0);
virtual ~Model();
typedef std::map<std::string, FEEngine *> FEEngineMap;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
virtual void initFull(const ModelOptions & options);
virtual void initModel() = 0;
/// create the synchronizer registry object
void createSynchronizerRegistry(DataAccessor * data_accessor);
/// create a parallel synchronizer and distribute the mesh
DistributedSynchronizer & createParallelSynch(MeshPartition * partition,
DataAccessor * data_accessor);
/// change local equation number so that PBC is assembled properly
void changeLocalEquationNumberForPBC(std::map<UInt,UInt> & pbc_pair,UInt dimension);
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const = 0;
/// initialize the model for PBC
void setPBC(UInt x, UInt y, UInt z);
void setPBC(SurfacePairList & surface_pairs);
virtual void initPBC();
/// set the parser to use
void setParser(Parser & parser);
/* ------------------------------------------------------------------------ */
/* Access to the dumpable interface of the boundaries */
/* ------------------------------------------------------------------------ */
/// Dump the data for a given group
void dumpGroup(const std::string & group_name);
void dumpGroup(const std::string & group_name,
- const std::string & dumper_name);
+ const std::string & dumper_name);
/// Dump the data for all boundaries
void dumpGroup();
/// Set the directory for a given group
void setGroupDirectory(const std::string & directory,
- const std::string & group_name);
+ const std::string & group_name);
/// Set the directory for all boundaries
void setGroupDirectory(const std::string & directory);
/// Set the base name for a given group
void setGroupBaseName(const std::string & basename,
- const std::string & group_name);
+ const std::string & group_name);
/// Get the internal dumper of a given group
DumperIOHelper & getGroupDumper(const std::string & group_name);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get id of model
AKANTU_GET_MACRO(ID, id, const ID)
/// get the number of surfaces
AKANTU_GET_MACRO(Mesh, mesh, Mesh&);
/// return the object handling equation numbers
AKANTU_GET_MACRO(DOFSynchronizer, *dof_synchronizer, const DOFSynchronizer &)
/// return the object handling synchronizers
AKANTU_GET_MACRO(SynchronizerRegistry, *synch_registry, SynchronizerRegistry &)
-
+
/// synchronize the boundary in case of parallel run
virtual void synchronizeBoundaries() {};
/// return the fem object associated with a provided name
inline FEEngine & getFEEngine(const ID & name = "") const;
/// return the fem boundary object associated with a provided name
virtual FEEngine & getFEEngineBoundary(const ID & name = "");
/// register a fem object associated with name
template <typename FEEngineClass> inline void registerFEEngineObject(const std::string & name,
- Mesh & mesh,
- UInt spatial_dimension);
+ Mesh & mesh,
+ UInt spatial_dimension);
/// unregister a fem object associated with name
inline void unRegisterFEEngineObject(const std::string & name);
/// return the synchronizer registry
SynchronizerRegistry & getSynchronizerRegistry();
/// return the fem object associated with a provided name
template <typename FEEngineClass>
inline FEEngineClass & getFEEngineClass(std::string name = "") const;
/// return the fem boundary object associated with a provided name
template <typename FEEngineClass>
inline FEEngineClass & getFEEngineClassBoundary(std::string name = "");
/// get the pbc pairs
std::map<UInt,UInt> & getPBCPairs(){return pbc_pair;};
/// returns if node is slave in pbc
inline bool isPBCSlaveNode(const UInt node) const;
/// returns the array of pbc slave nodes (boolean information)
AKANTU_GET_MACRO(IsPBCSlaveNode, is_pbc_slave_node, const Array<bool> &)
/* ------------------------------------------------------------------------ */
/* Pack and unpack helper functions */
/* ------------------------------------------------------------------------ */
public:
- inline UInt getNbQuadraturePoints(const Array<Element> & elements,
+ 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,
+ virtual void setBaseName(const std::string & basename);
+
+ virtual void setBaseNameToDumper(const std::string & dumper_name,
const std::string & basename);
virtual void addDumpGroupField(const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name,
const ElementKind & element_kind,
bool padding_flag);
+ virtual void addDumpGroupFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id,
+ const std::string & group_name,
+ UInt spatial_dimension,
+ const ElementKind & element_kind,
+ bool padding_flag);
+
virtual void removeDumpGroupField(const std::string & field_id,
const std::string & group_name);
virtual void removeDumpGroupFieldFromDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldVector(const std::string & field_id,
const std::string & group_name);
virtual void addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
const std::string & field_id,
const std::string & group_name);
virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag){return NULL;}
virtual dumper::Field * createNodalFieldUInt(const std::string & field_name,
const std::string & group_name,
bool padding_flag){return NULL;}
virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag){return NULL;}
- virtual dumper::Field * createElementalField(const std::string & field_name,
+ virtual dumper::Field * createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
+ const UInt & spatial_dimension,
const ElementKind & kind){return NULL;}
void setDirectory(const std::string & directory);
void setDirectoryToDumper(const std::string & dumper_name,
const std::string & directory);
virtual void dump();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// Mesh
Mesh & mesh;
/// Spatial dimension of the problem
UInt spatial_dimension;
/// the main fem object present in all models
FEEngineMap fems;
/// the fem object present in all models for boundaries
FEEngineMap fems_boundary;
/// default fem object
std::string default_fem;
/// synchronizer registry
SynchronizerRegistry * synch_registry;
/// handle the equation number things
DOFSynchronizer * dof_synchronizer;
/// pbc pairs
std::map<UInt,UInt> pbc_pair;
/// flag per node to know is pbc slave
Array<bool> is_pbc_slave_node;
/// parser to the pointer to use
Parser * parser;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "model_inline_impl.cc"
#endif
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const Model & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_MODEL_HH__ */
diff --git a/src/model/model_inline_impl.cc b/src/model/model_inline_impl.cc
index 4850edcdb..5ed36cf1d 100644
--- a/src/model/model_inline_impl.cc
+++ b/src/model/model_inline_impl.cc
@@ -1,196 +1,207 @@
/**
* @file model_inline_impl.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 25 2010
* @date last modification: Tue Jul 29 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
inline SynchronizerRegistry & Model::getSynchronizerRegistry(){
AKANTU_DEBUG_ASSERT(synch_registry,"synchronizer registry not initialized:"
<< " did you call createSynchronizerRegistry ?");
return *synch_registry;
}
/* -------------------------------------------------------------------------- */
template <typename FEEngineClass>
inline FEEngineClass & Model::getFEEngineClassBoundary(std::string name) {
AKANTU_DEBUG_IN();
if (name == "") name = default_fem;
FEEngineMap::const_iterator it_boun = fems_boundary.find(name);
FEEngineClass * tmp_fem_boundary;
if (it_boun == fems_boundary.end()){
AKANTU_DEBUG_INFO("Creating FEEngine boundary " << name);
FEEngineMap::const_iterator it = fems.find(name);
AKANTU_DEBUG_ASSERT(it != fems.end(), "The FEEngine " << name << " is not registered");
UInt spatial_dimension = it->second->getElementDimension();
std::stringstream sstr; sstr << id << ":fem_boundary:" << name;
tmp_fem_boundary = new FEEngineClass(it->second->getMesh(),
spatial_dimension-1,
sstr.str(),
memory_id);
fems_boundary[name] = tmp_fem_boundary;
} else {
tmp_fem_boundary = dynamic_cast<FEEngineClass *>(it_boun->second);
}
AKANTU_DEBUG_OUT();
return *tmp_fem_boundary;
}
/* -------------------------------------------------------------------------- */
template <typename FEEngineClass>
inline FEEngineClass & Model::getFEEngineClass(std::string name) const{
AKANTU_DEBUG_IN();
if (name == "") name = default_fem;
FEEngineMap::const_iterator it = fems.find(name);
AKANTU_DEBUG_ASSERT(it != fems.end(), "The FEEngine " << name << " is not registered");
AKANTU_DEBUG_OUT();
return dynamic_cast<FEEngineClass &>(*(it->second));
}
/* -------------------------------------------------------------------------- */
inline void Model::unRegisterFEEngineObject(const std::string & name){
FEEngineMap::iterator it = fems.find(name);
AKANTU_DEBUG_ASSERT(it != fems.end(), "FEEngine object with name "
<< name << " was not found");
delete((*it).second);
fems.erase(it);
if (!fems.empty())
default_fem = (*fems.begin()).first;
}
/* -------------------------------------------------------------------------- */
template <typename FEEngineClass>
inline void Model::registerFEEngineObject(const std::string & name,
Mesh & mesh,
UInt spatial_dimension){
if (fems.size() == 0) default_fem = name;
#ifndef AKANTU_NDEBUG
FEEngineMap::iterator it = fems.find(name);
AKANTU_DEBUG_ASSERT(it == fems.end(), "FEEngine object with name "
<< name << " was already created");
#endif
std::stringstream sstr; sstr << id << ":fem:" << name;
fems[name] = new FEEngineClass(mesh, spatial_dimension, sstr.str(), memory_id);
// MeshUtils::buildFacets(fems[name]->getMesh());
// std::stringstream sstr2; sstr2 << id << ":fem_boundary:" << name;
// fems_boundary[name] = new FEEngineClass(mesh, spatial_dimension-1, sstr2.str(), memory_id);
}
/* -------------------------------------------------------------------------- */
inline FEEngine & Model::getFEEngine(const ID & name) const{
AKANTU_DEBUG_IN();
ID tmp_name = name;
if (name == "") tmp_name = default_fem;
FEEngineMap::const_iterator it = fems.find(tmp_name);
AKANTU_DEBUG_ASSERT(it != fems.end(),
"The FEEngine " << tmp_name << " is not registered");
AKANTU_DEBUG_OUT();
return *(it->second);
}
/* -------------------------------------------------------------------------- */
inline FEEngine & Model::getFEEngineBoundary(const ID & name){
AKANTU_DEBUG_IN();
ID tmp_name = name;
if (name == "") tmp_name = default_fem;
FEEngineMap::const_iterator it = fems_boundary.find(tmp_name);
AKANTU_DEBUG_ASSERT(it != fems_boundary.end(),
"The FEEngine boundary " << tmp_name << " is not registered");
AKANTU_DEBUG_ASSERT(it->second != NULL,
"The FEEngine boundary " << tmp_name << " was not created");
AKANTU_DEBUG_OUT();
return *(it->second);
}
/* -------------------------------------------------------------------------- */
/// @todo : should merge with a single function which handles local and global
inline void Model::changeLocalEquationNumberForPBC(std::map<UInt,UInt> & pbc_pair,
- UInt dimension){
+ UInt dimension) {
+ Array<Int> & local_eq_num = *dof_synchronizer->getLocalDOFEquationNumbersPointer();
+ Array<Int> & global_eq_num = *dof_synchronizer->getGlobalDOFEquationNumbersPointer();
+
for (std::map<UInt,UInt>::iterator it = pbc_pair.begin();
it != pbc_pair.end();++it) {
Int node_master = (*it).second;
Int node_slave = (*it).first;
for (UInt i = 0; i < dimension; ++i) {
- (*dof_synchronizer->getLocalDOFEquationNumbersPointer())
- (node_slave*dimension+i) = dimension*node_master+i;
- (*dof_synchronizer->getGlobalDOFEquationNumbersPointer())
- (node_slave*dimension+i) = dimension*node_master+i;
+ local_eq_num(node_slave * dimension + i) =
+ dimension * node_master + i;
+
+ if(mesh.isDistributed()) {
+ global_eq_num(node_slave * dimension+i) =
+ dimension * mesh.getNodeGlobalId(node_master) + i;
+ }
+ else {
+ global_eq_num(node_slave * dimension+i) =
+ dimension * node_master + i;
+ }
}
}
}
+
/* -------------------------------------------------------------------------- */
inline bool Model::isPBCSlaveNode(const UInt node) const {
// if no pbc is defined, is_pbc_slave_node is of size zero
if (is_pbc_slave_node.getSize() == 0)
return false;
else
return is_pbc_slave_node(node);
}
/* -------------------------------------------------------------------------- */
-inline UInt Model::getNbQuadraturePoints(const Array<Element> & elements,
+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/fragment_manager.cc b/src/model/solid_mechanics/fragment_manager.cc
deleted file mode 100644
index 2516987f5..000000000
--- a/src/model/solid_mechanics/fragment_manager.cc
+++ /dev/null
@@ -1,644 +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> & el_id_by_mat = model.getElementIndexByMaterial(el.type,
- el.ghost_type);
-
- const MaterialCohesive & mat
- = static_cast<const MaterialCohesive &>
- (model.getMaterial(el_id_by_mat(el.element, 0)));
-
- UInt el_index = el_id_by_mat(el.element, 1);
- 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);
-
- Array<UInt> & el_index_by_mat = model.getElementIndexByMaterial(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(el_index_by_mat(el, 0));
-
- 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
- output_begin[*fragment_index_it]
- += 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>::template iterator< Vector<T> > 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)
- mesh_data_begin[*el_it](0) = *fragment_index_it;
- } else {
- for (; el_it != el_end; ++el_it)
- mesh_data_begin[*el_it] = 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 287f8f369..57b7b421f 100644
--- a/src/model/solid_mechanics/material.cc
+++ b/src/model/solid_mechanics/material.cc
@@ -1,1559 +1,1566 @@
/**
* @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>
*
* @date creation: Tue Jul 27 2010
* @date last modification: Tue Sep 16 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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),
- eigenstrain("eigenstrain", *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) {
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);
+ 1,
+ spatial_dimension,
+ false,
+ _ek_regular);
- registerParam("rho" , rho , 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");
+ this->initialize();
+ AKANTU_DEBUG_OUT();
+}
- /// allocate gradu stress for local elements
- eigenstrain.initialize(spatial_dimension * spatial_dimension);
- gradu.initialize(spatial_dimension * spatial_dimension);
- stress.initialize(spatial_dimension * spatial_dimension);
+/* -------------------------------------------------------------------------- */
+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) {
- model.registerEventHandler(*this);
+ AKANTU_DEBUG_IN();
+ mesh.initElementTypeMapArray(element_filter,
+ 1,
+ spatial_dimension,
+ false,
+ _ek_regular);
+ this->initialize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Material::~Material() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
+void Material::initialize() {
+ registerParam("rho" , rho , Real(0.) , _pat_parsable | _pat_modifiable, "Density");
+ registerParam("name" , name , std::string(), _pat_parsable | _pat_readable);
+ registerParam("finite_deformation" , finite_deformation , false , _pat_parsable | _pat_readable, "Is finite deformation");
+ registerParam("inelastic_deformation", inelastic_deformation, false , _pat_internal, "Is inelastic deformation");
+
+ /// allocate gradu stress for local elements
+ eigengradu.initialize(spatial_dimension * spatial_dimension);
+ gradu.initialize(spatial_dimension * spatial_dimension);
+ stress.initialize(spatial_dimension * spatial_dimension);
+
+ potential_energy.initialize(1);
+
+ this->model->registerEventHandler(*this);
+}
+
/* -------------------------------------------------------------------------- */
void Material::initMaterial() {
AKANTU_DEBUG_IN();
if(finite_deformation) {
this->piola_kirchhoff_2.initialize(spatial_dimension * spatial_dimension);
if(use_previous_stress) this->piola_kirchhoff_2.initializeHistory();
+ this->green_strain.initialize(spatial_dimension * spatial_dimension);
}
if(use_previous_stress) this->stress.initializeHistory();
if(use_previous_gradu) this->gradu.initializeHistory();
for (std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.begin();
it != internal_vectors_real.end();
++it) it->second->resize();
+ for (std::map<ID, InternalField<UInt> *>::iterator it = internal_vectors_uint.begin();
+ it != internal_vectors_uint.end();
+ ++it) it->second->resize();
+
+ for (std::map<ID, InternalField<bool> *>::iterator it = internal_vectors_bool.begin();
+ it != internal_vectors_bool.end();
+ ++it) it->second->resize();
+
is_init = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::savePreviousState() {
AKANTU_DEBUG_IN();
for (std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.begin();
it != internal_vectors_real.end();
++it) {
if(it->second->hasHistory()) it->second->saveCurrentValues();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the residual by assembling @f$\int_{e} \sigma_e \frac{\partial
* \varphi}{\partial X} dX @f$
*
* @param[in] displacements nodes displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void Material::updateResidual(GhostType ghost_type) {
AKANTU_DEBUG_IN();
computeAllStresses(ghost_type);
assembleResidual(ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::assembleResidual(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model->getSpatialDimension();
if(!finite_deformation){
Array<Real> & residual = const_cast<Array<Real> &>(model->getResidual());
- Mesh & mesh = model->getFEEngine().getMesh();
+ 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) {
- const Array<Real> & shapes_derivatives = model->getFEEngine().getShapesDerivatives(*it, ghost_type);
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
+ UInt nb_element = elem_filter.getSize();
+ if (nb_element) {
+ const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(*it, ghost_type);
- UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
- UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
- UInt nb_quadrature_points = model->getFEEngine().getNbQuadraturePoints(*it, ghost_type);
+ UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
+ UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(*it, ghost_type);
- UInt nb_element = elem_filter.getSize();
- /// 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");
+ /// compute @f$\sigma \frac{\partial \varphi}{\partial X}@f$ by @f$\mathbf{B}^t \mathbf{\sigma}_q@f$
+ Array<Real> * sigma_dphi_dx =
+ new Array<Real>(nb_element*nb_quadrature_points,
+ size_of_shapes_derivatives, "sigma_x_dphi_/_dX");
- Array<Real> * shapesd_filtered =
- new Array<Real>(0, size_of_shapes_derivatives, "filtered shapesd");
+ Array<Real> * shapesd_filtered =
+ new Array<Real>(0, size_of_shapes_derivatives, "filtered shapesd");
- FEEngine::filterElementalData(mesh, shapes_derivatives, *shapesd_filtered,
- *it, ghost_type, elem_filter);
+ FEEngine::filterElementalData(mesh, shapes_derivatives, *shapesd_filtered,
+ *it, ghost_type, elem_filter);
- Array<Real> & stress_vect = stress(*it, ghost_type);
+ Array<Real> & stress_vect = this->stress(*it, ghost_type);
- Array<Real>::matrix_iterator sigma =
- stress_vect.begin(spatial_dimension, spatial_dimension);
- Array<Real>::matrix_iterator B =
- shapesd_filtered->begin(spatial_dimension, nb_nodes_per_element);
- Array<Real>::matrix_iterator Bt_sigma_it =
- sigma_dphi_dx->begin(spatial_dimension, nb_nodes_per_element);
+ Array<Real>::matrix_iterator sigma =
+ stress_vect.begin(spatial_dimension, spatial_dimension);
+ Array<Real>::matrix_iterator B =
+ shapesd_filtered->begin(spatial_dimension, nb_nodes_per_element);
+ Array<Real>::matrix_iterator Bt_sigma_it =
+ sigma_dphi_dx->begin(spatial_dimension, nb_nodes_per_element);
- for (UInt q = 0; q < nb_element*nb_quadrature_points; ++q, ++sigma, ++B, ++Bt_sigma_it)
- Bt_sigma_it->mul<false,false>(*sigma, *B);
+ 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;
+ delete shapesd_filtered;
- /**
- * compute @f$\int \sigma * \frac{\partial \varphi}{\partial X}dX@f$ by @f$ \sum_q \mathbf{B}^t
- * \mathbf{\sigma}_q \overline w_q J_q@f$
- */
- Array<Real> * int_sigma_dphi_dx = new Array<Real>(nb_element,
- nb_nodes_per_element * spatial_dimension,
- "int_sigma_x_dphi_/_dX");
+ /**
+ * 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");
- model->getFEEngine().integrate(*sigma_dphi_dx, *int_sigma_dphi_dx,
- size_of_shapes_derivatives,
- *it, ghost_type,
- elem_filter);
- delete sigma_dphi_dx;
+ fem->integrate(*sigma_dphi_dx, *int_sigma_dphi_dx,
+ size_of_shapes_derivatives,
+ *it, ghost_type,
+ elem_filter);
+ delete sigma_dphi_dx;
- /// assemble
- model->getFEEngine().assembleArray(*int_sigma_dphi_dx, residual,
- model->getDOFSynchronizer().getLocalDOFEquationNumbers(),
- residual.getNbComponent(),
- *it, ghost_type, elem_filter, -1);
- delete int_sigma_dphi_dx;
+ /// assemble
+ fem->assembleArray(*int_sigma_dphi_dx, residual,
+ model->getDOFSynchronizer().getLocalDOFEquationNumbers(),
+ residual.getNbComponent(),
+ *it, ghost_type, elem_filter, -1);
+ delete int_sigma_dphi_dx;
+ }
}
-
}
else{
switch (spatial_dimension){
case 1:
this->assembleResidual<1>(ghost_type);
break;
case 2:
this->assembleResidual<2>(ghost_type);
break;
case 3:
this->assembleResidual<3>(ghost_type);
break;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Compute the stress from the gradu
*
* @param[in] current_position nodes postition + displacements
* @param[in] ghost_type compute the residual for _ghost or _not_ghost element
*/
void Material::computeAllStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model->getSpatialDimension();
- Mesh::type_iterator it = model->getFEEngine().getMesh().firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = model->getFEEngine().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) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
+ if (elem_filter.getSize() == 0) continue;
Array<Real> & gradu_vect = gradu(*it, ghost_type);
/// compute @f$\nabla u@f$
- model->getFEEngine().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 -= eigenstrain(*it, ghost_type);
+ gradu_vect -= eigengradu(*it, ghost_type);
/// compute @f$\mathbf{\sigma}_q@f$ from @f$\nabla u@f$
computeStress(*it, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computeAllCauchyStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(finite_deformation,"The Cauchy stress can only be computed if you are working in finite deformation.");
//resizeInternalArray(stress);
- Mesh::type_iterator it = model->getFEEngine().getMesh().firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = model->getFEEngine().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){
case 1:
this->computeCauchyStress<1>(*it, ghost_type);
break;
case 2:
this->computeCauchyStress<2>(*it, ghost_type);
break;
case 3:
this->computeCauchyStress<3>(*it, ghost_type);
break;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::computeCauchyStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::matrix_iterator gradu_it =
this->gradu(el_type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator gradu_end =
this->gradu(el_type, ghost_type).end(dim, dim);
Array<Real>::matrix_iterator piola_it =
this->piola_kirchhoff_2(el_type, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator stress_it =
this->stress(el_type, ghost_type).begin(dim, dim);
Matrix<Real> F_tensor(dim, dim);
for (; gradu_it != gradu_end; ++gradu_it, ++piola_it, ++stress_it) {
Matrix<Real> & grad_u = *gradu_it;
Matrix<Real> & piola = *piola_it;
Matrix<Real> & sigma = *stress_it;
gradUToF<dim > (grad_u, F_tensor);
this->computeCauchyStressOnQuad<dim >(F_tensor, piola, sigma);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::setToSteadyState(GhostType ghost_type) {
AKANTU_DEBUG_IN();
const Array<Real> & displacement = model->getDisplacement();
//resizeInternalArray(gradu);
UInt spatial_dimension = model->getSpatialDimension();
- Mesh::type_iterator it = model->getFEEngine().getMesh().firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = model->getFEEngine().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) {
Array<UInt> & elem_filter = element_filter(*it, ghost_type);
Array<Real> & gradu_vect = gradu(*it, ghost_type);
/// compute @f$\nabla u@f$
- model->getFEEngine().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){
switch (spatial_dimension) {
case 1:
- {
- assembleStiffnessMatrixNL < 1 > (*it, ghost_type);
- assembleStiffnessMatrixL2 < 1 > (*it, ghost_type);
- break;
- }
+ {
+ assembleStiffnessMatrixNL < 1 > (*it, ghost_type);
+ assembleStiffnessMatrixL2 < 1 > (*it, ghost_type);
+ break;
+ }
case 2:
- {
- assembleStiffnessMatrixNL < 2 > (*it, ghost_type);
- assembleStiffnessMatrixL2 < 2 > (*it, ghost_type);
- break;
- }
+ {
+ assembleStiffnessMatrixNL < 2 > (*it, ghost_type);
+ assembleStiffnessMatrixL2 < 2 > (*it, ghost_type);
+ break;
+ }
case 3:
- {
- assembleStiffnessMatrixNL < 3 > (*it, ghost_type);
- assembleStiffnessMatrixL2 < 3 > (*it, ghost_type);
- break;
- }
+ {
+ assembleStiffnessMatrixNL < 3 > (*it, ghost_type);
+ assembleStiffnessMatrixL2 < 3 > (*it, ghost_type);
+ break;
+ }
}
} else {
switch(spatial_dimension) {
case 1: { assembleStiffnessMatrix<1>(*it, ghost_type); break; }
case 2: { assembleStiffnessMatrix<2>(*it, ghost_type); break; }
case 3: { assembleStiffnessMatrix<3>(*it, ghost_type); break; }
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::assembleStiffnessMatrix(const ElementType & type,
- GhostType ghost_type) {
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
- SparseMatrix & K = const_cast<SparseMatrix &>(model->getStiffnessMatrix());
-
- const Array<Real> & shapes_derivatives = model->getFEEngine().getShapesDerivatives(type,
- ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
- Array<Real> & gradu_vect = gradu(type, ghost_type);
+ if (elem_filter.getSize()) {
- UInt nb_element = elem_filter.getSize();
- UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt nb_quadrature_points = model->getFEEngine().getNbQuadraturePoints(type,
- ghost_type);
+ SparseMatrix & K = const_cast<SparseMatrix &>(model->getStiffnessMatrix());
- gradu_vect.resize(nb_quadrature_points * nb_element);
+ const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type,
+ ghost_type);
+
+ Array<Real> & gradu_vect = gradu(type, ghost_type);
- model->getFEEngine().gradientOnQuadraturePoints(model->getDisplacement(),
- gradu_vect, dim, type, ghost_type,
- elem_filter);
+ UInt nb_element = elem_filter.getSize();
+ UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(type,
+ ghost_type);
- UInt tangent_size = getTangentStiffnessVoigtSize(dim);
+ gradu_vect.resize(nb_quadrature_points * nb_element);
- Array<Real> * tangent_stiffness_matrix =
- new Array<Real>(nb_element*nb_quadrature_points, tangent_size * tangent_size,
- "tangent_stiffness_matrix");
+ fem->gradientOnIntegrationPoints(model->getDisplacement(),
+ gradu_vect, dim, type, ghost_type,
+ elem_filter);
- tangent_stiffness_matrix->clear();
+ UInt tangent_size = getTangentStiffnessVoigtSize(dim);
- computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
+ Array<Real> * tangent_stiffness_matrix =
+ new Array<Real>(nb_element*nb_quadrature_points, tangent_size * tangent_size,
+ "tangent_stiffness_matrix");
- Array<Real> * shapesd_filtered =
- new Array<Real>(0, dim * nb_nodes_per_element, "filtered shapesd");
+ tangent_stiffness_matrix->clear();
- FEEngine::filterElementalData(model->getFEEngine().getMesh(), shapes_derivatives,
- *shapesd_filtered, type, ghost_type, elem_filter);
+ computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
+ Array<Real> * shapesd_filtered =
+ new Array<Real>(0, dim * nb_nodes_per_element, "filtered shapesd");
- /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
- UInt bt_d_b_size = dim * nb_nodes_per_element;
+ FEEngine::filterElementalData(fem->getMesh(), shapes_derivatives,
+ *shapesd_filtered, type, ghost_type, elem_filter);
- 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);
+ /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
+ UInt bt_d_b_size = dim * nb_nodes_per_element;
- Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
- shapesd_filtered->begin(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>::matrix_iterator Bt_D_B_it
- = bt_d_b->begin(dim*nb_nodes_per_element, dim*nb_nodes_per_element);
+ 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 D_it
- = tangent_stiffness_matrix->begin(tangent_size, tangent_size);
+ Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
+ shapesd_filtered->begin(dim, nb_nodes_per_element);
- Array<Real>::matrix_iterator D_end
- = tangent_stiffness_matrix->end (tangent_size, tangent_size);
+ 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);
- 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;
+ Array<Real>::matrix_iterator D_end
+ = tangent_stiffness_matrix->end (tangent_size, tangent_size);
- VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
- *shapes_derivatives_filtered_it, B, nb_nodes_per_element);
- Bt_D.mul<true, false>(B, D);
- Bt_D_B.mul<false, false>(Bt_D, B);
- }
- delete tangent_stiffness_matrix;
- delete shapesd_filtered;
+ 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;
- /// 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");
+ VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
+ *shapes_derivatives_filtered_it, B, nb_nodes_per_element);
+ Bt_D.mul<true, false>(B, D);
+ Bt_D_B.mul<false, false>(Bt_D, B);
+ }
- model->getFEEngine().integrate(*bt_d_b, *K_e,
- bt_d_b_size * bt_d_b_size,
- type, ghost_type,
- elem_filter);
+ delete tangent_stiffness_matrix;
+ delete shapesd_filtered;
- delete 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");
- model->getFEEngine().assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type,
- elem_filter);
- delete K_e;
+ fem->integrate(*bt_d_b, *K_e,
+ bt_d_b_size * bt_d_b_size,
+ type, ghost_type,
+ elem_filter);
+
+ delete bt_d_b;
+ fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type,
+ elem_filter);
+ delete K_e;
+ }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::assembleStiffnessMatrixNL(const ElementType & type,
- GhostType ghost_type) {
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
SparseMatrix & K = const_cast<SparseMatrix &> (model->getStiffnessMatrix());
- const Array<Real> & shapes_derivatives = model->getFEEngine().getShapesDerivatives(type, ghost_type);
+ const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
//Array<Real> & gradu_vect = delta_gradu(type, ghost_type);
UInt nb_element = elem_filter.getSize();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt nb_quadrature_points = model->getFEEngine().getNbQuadraturePoints(type, ghost_type);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(type, ghost_type);
//gradu_vect.resize(nb_quadrature_points * nb_element);
- // model->getFEEngine().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");
+ 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);
+ nb_nodes_per_element);
Array<Real>::matrix_iterator shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension,
- nb_nodes_per_element);
+ nb_nodes_per_element);
UInt * elem_filter_val = elem_filter.storage();
for (UInt e = 0; e < nb_element; ++e, ++elem_filter_val)
for (UInt q = 0; q < nb_quadrature_points; ++q, ++shapes_derivatives_filtered_it)
*shapes_derivatives_filtered_it = shapes_derivatives_it[*elem_filter_val * nb_quadrature_points + q];
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_s_b_size = dim * nb_nodes_per_element;
Array<Real> * bt_s_b = new Array<Real > (nb_element * nb_quadrature_points,
- bt_s_b_size * bt_s_b_size,
- "B^t*D*B");
+ bt_s_b_size * bt_s_b_size,
+ "B^t*D*B");
UInt piola_matrix_size = getCauchyStressMatrixSize(dim);
Matrix<Real> B(piola_matrix_size, bt_s_b_size);
Matrix<Real> Bt_S(bt_s_b_size, piola_matrix_size);
Matrix<Real> S(piola_matrix_size, piola_matrix_size);
shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension, nb_nodes_per_element);
Array<Real>::matrix_iterator Bt_S_B_it = bt_s_b->begin(bt_s_b_size,
- bt_s_b_size);
+ bt_s_b_size);
Array<Real>::matrix_iterator Bt_S_B_end = bt_s_b->end(bt_s_b_size,
- bt_s_b_size);
+ bt_s_b_size);
Array<Real>::matrix_iterator piola_it = piola_kirchhoff_2(type, ghost_type).begin(dim, dim);
for (; Bt_S_B_it != Bt_S_B_end; ++Bt_S_B_it, ++shapes_derivatives_filtered_it, ++piola_it) {
Matrix<Real> & Bt_S_B = *Bt_S_B_it;
Matrix<Real> & Piola_kirchhoff_matrix = *piola_it;
setCauchyStressMatrix< dim >(Piola_kirchhoff_matrix, S);
VoigtHelper<dim>::transferBMatrixToBNL(*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
Bt_S.mul < true, false > (B, S);
Bt_S_B.mul < false, false > (Bt_S, B);
}
delete shapes_derivatives_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e = new Array<Real > (nb_element,
- bt_s_b_size * bt_s_b_size,
- "K_e");
+ bt_s_b_size * bt_s_b_size,
+ "K_e");
- model->getFEEngine().integrate(*bt_s_b, *K_e,
- bt_s_b_size * bt_s_b_size,
- type, ghost_type,
- elem_filter);
+ fem->integrate(*bt_s_b, *K_e,
+ bt_s_b_size * bt_s_b_size,
+ type, ghost_type,
+ elem_filter);
delete bt_s_b;
- model->getFEEngine().assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, elem_filter);
+ fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, elem_filter);
delete K_e;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::assembleStiffnessMatrixL2(const ElementType & type,
- GhostType ghost_type) {
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
SparseMatrix & K = const_cast<SparseMatrix &> (model->getStiffnessMatrix());
- const Array<Real> & shapes_derivatives = model->getFEEngine().getShapesDerivatives(type, ghost_type);
+ const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
Array<Real> & gradu_vect = gradu(type, ghost_type);
UInt nb_element = elem_filter.getSize();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt nb_quadrature_points = model->getFEEngine().getNbQuadraturePoints(type, ghost_type);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(type, ghost_type);
gradu_vect.resize(nb_quadrature_points * nb_element);
- model->getFEEngine().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");
+ "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");
+ 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);
+ nb_nodes_per_element);
Array<Real>::matrix_iterator shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension,
- nb_nodes_per_element);
+ nb_nodes_per_element);
UInt * elem_filter_val = elem_filter.storage();
for (UInt e = 0; e < nb_element; ++e, ++elem_filter_val)
for (UInt q = 0; q < nb_quadrature_points; ++q, ++shapes_derivatives_filtered_it)
*shapes_derivatives_filtered_it = shapes_derivatives_it[*elem_filter_val * nb_quadrature_points + q];
/// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
UInt bt_d_b_size = dim * nb_nodes_per_element;
Array<Real> * bt_d_b = new Array<Real > (nb_element * nb_quadrature_points,
- bt_d_b_size * bt_d_b_size,
- "B^t*D*B");
+ bt_d_b_size * bt_d_b_size,
+ "B^t*D*B");
Matrix<Real> B(tangent_size, dim * nb_nodes_per_element);
Matrix<Real> B2(tangent_size, dim * nb_nodes_per_element);
Matrix<Real> Bt_D(dim * nb_nodes_per_element, tangent_size);
shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension, nb_nodes_per_element);
Array<Real>::matrix_iterator Bt_D_B_it = bt_d_b->begin(dim*nb_nodes_per_element,
- dim * nb_nodes_per_element);
+ 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);
+ tangent_size);
Array<Real>::matrix_iterator D_end = tangent_stiffness_matrix->end(tangent_size,
- tangent_size);
+ tangent_size);
for (; D_it != D_end; ++D_it, ++Bt_D_B_it, ++shapes_derivatives_filtered_it, ++grad_u_it) {
Matrix<Real> & grad_u = *grad_u_it;
Matrix<Real> & D = *D_it;
Matrix<Real> & Bt_D_B = *Bt_D_B_it;
//transferBMatrixToBL1<dim > (*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
VoigtHelper<dim>::transferBMatrixToBL2(*shapes_derivatives_filtered_it, grad_u, B2, nb_nodes_per_element);
B += B2;
Bt_D.mul < true, false > (B, D);
Bt_D_B.mul < false, false > (Bt_D, B);
}
delete tangent_stiffness_matrix;
delete shapes_derivatives_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * K_e = new Array<Real > (nb_element,
- bt_d_b_size * bt_d_b_size,
- "K_e");
+ bt_d_b_size * bt_d_b_size,
+ "K_e");
- model->getFEEngine().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->getFEEngine().assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, elem_filter);
+ fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, elem_filter);
delete K_e;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::assembleResidual(GhostType ghost_type){
AKANTU_DEBUG_IN();
Array<Real> & residual = const_cast<Array<Real> &> (model->getResidual());
- Mesh & mesh = model->getFEEngine().getMesh();
+ 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 = model->getFEEngine().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;
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 = model->getFEEngine().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");
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);
+ nb_nodes_per_element);
//Set stress vectors
UInt stress_size = getTangentStiffnessVoigtSize(dim);
//Set matrices B and BNL*
UInt bt_s_size = dim * nb_nodes_per_element;
Array<Real> * bt_s = new Array<Real > (nb_element * nb_quadrature_points,
- bt_s_size,
- "B^t*S");
+ bt_s_size,
+ "B^t*S");
Array<Real>::matrix_iterator grad_u_it = this->gradu(*it, ghost_type).begin(dim, dim);
Array<Real>::matrix_iterator grad_u_end = this->gradu(*it, ghost_type).end(dim, dim);
Array<Real>::matrix_iterator stress_it = this->piola_kirchhoff_2(*it, ghost_type).begin(dim, dim);
shapes_derivatives_filtered_it = shapesd_filtered->begin(dim, nb_nodes_per_element);
Array<Real>::matrix_iterator bt_s_it = bt_s->begin(bt_s_size, 1);
Matrix<Real> S_vect(stress_size, 1);
Matrix<Real> B_tensor(stress_size, bt_s_size);
Matrix<Real> B2_tensor(stress_size, bt_s_size);
for (; grad_u_it != grad_u_end; ++grad_u_it, ++stress_it, ++shapes_derivatives_filtered_it, ++bt_s_it) {
Matrix<Real> & grad_u = *grad_u_it;
Matrix<Real> & r_it = *bt_s_it;
Matrix<Real> & S_it = *stress_it;
- SetCauchyStressArray <dim> (S_it, S_vect);
+ setCauchyStressArray <dim> (S_it, S_vect);
VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B_tensor, nb_nodes_per_element);
VoigtHelper<dim>::transferBMatrixToBL2(*shapes_derivatives_filtered_it, grad_u, B2_tensor, nb_nodes_per_element);
B_tensor += B2_tensor;
r_it.mul < true, false > (B_tensor, S_vect);
}
delete shapesd_filtered;
/// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
Array<Real> * r_e = new Array<Real > (nb_element,
- bt_s_size, "r_e");
+ bt_s_size, "r_e");
- model->getFEEngine().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->getFEEngine().assembleArray(*r_e, residual,
- model->getDOFSynchronizer().getLocalDOFEquationNumbers(),
- residual.getNbComponent(),
- *it, ghost_type, elem_filter, -1);
+ fem->assembleArray(*r_e, residual,
+ model->getDOFSynchronizer().getLocalDOFEquationNumbers(),
+ residual.getNbComponent(),
+ *it, ghost_type, elem_filter, -1);
delete r_e;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computeAllStressesFromTangentModuli(GhostType ghost_type) {
AKANTU_DEBUG_IN();
UInt spatial_dimension = model->getSpatialDimension();
Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension, ghost_type);
for(; it != last_type; ++it) {
switch(spatial_dimension) {
case 1: { computeAllStressesFromTangentModuli<1>(*it, ghost_type); break; }
case 2: { computeAllStressesFromTangentModuli<2>(*it, ghost_type); break; }
case 3: { computeAllStressesFromTangentModuli<3>(*it, ghost_type); break; }
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void Material::computeAllStressesFromTangentModuli(const ElementType & type,
- GhostType ghost_type) {
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
- const Array<Real> & shapes_derivatives = model->getFEEngine().getShapesDerivatives(type, ghost_type);
+ const Array<Real> & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type);
Array<UInt> & elem_filter = element_filter(type, ghost_type);
Array<Real> & gradu_vect = gradu(type, ghost_type);
UInt nb_element = elem_filter.getSize();
- UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
- UInt nb_quadrature_points = model->getFEEngine().getNbQuadraturePoints(type, ghost_type);
-
-
- gradu_vect.resize(nb_quadrature_points * nb_element);
+ if (nb_element) {
+ UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(type, ghost_type);
- Array<Real> & disp = model->getDisplacement();
- model->getFEEngine().gradientOnQuadraturePoints(disp, gradu_vect,
- dim, type, ghost_type, elem_filter);
+ gradu_vect.resize(nb_quadrature_points * nb_element);
- UInt tangent_moduli_size = getTangentStiffnessVoigtSize(dim);
+ Array<Real> & disp = model->getDisplacement();
- Array<Real> * tangent_moduli_tensors =
- new Array<Real>(nb_element*nb_quadrature_points, tangent_moduli_size * tangent_moduli_size,
- "tangent_moduli_tensors");
+ fem->gradientOnIntegrationPoints(disp, gradu_vect,
+ dim, type, ghost_type, elem_filter);
- tangent_moduli_tensors->clear();
- computeTangentModuli(type, *tangent_moduli_tensors, ghost_type);
+ UInt tangent_moduli_size = getTangentStiffnessVoigtSize(dim);
- Array<Real> * shapesd_filtered =
- new Array<Real>(0, dim* nb_nodes_per_element, "filtered shapesd");
+ Array<Real> * tangent_moduli_tensors =
+ new Array<Real>(nb_element*nb_quadrature_points, tangent_moduli_size * tangent_moduli_size,
+ "tangent_moduli_tensors");
- FEEngine::filterElementalData(model->getFEEngine().getMesh(), shapes_derivatives, *shapesd_filtered,
- type, ghost_type, elem_filter);
+ tangent_moduli_tensors->clear();
+ computeTangentModuli(type, *tangent_moduli_tensors, ghost_type);
- Array<Real> filtered_u(nb_element, nb_nodes_per_element * spatial_dimension);
-
- FEEngine::extractNodalToElementField(model->getFEEngine().getMesh(), disp, filtered_u,
- type, ghost_type, elem_filter);
-
- /// compute @f$\mathbf{D} \mathbf{B} \mathbf{u}@f$
- Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
- shapesd_filtered->begin(dim, nb_nodes_per_element);
-
- Array<Real>::matrix_iterator D_it = tangent_moduli_tensors->begin(tangent_moduli_size,
- tangent_moduli_size);
- Array<Real>::matrix_iterator sigma_it = stress(type, ghost_type).begin(spatial_dimension,
- spatial_dimension);
- Array<Real>::vector_iterator u_it = filtered_u.begin(spatial_dimension * nb_nodes_per_element);
-
- Matrix<Real> B(tangent_moduli_size, spatial_dimension * nb_nodes_per_element);
- Vector<Real> Bu(tangent_moduli_size);
- Vector<Real> DBu(tangent_moduli_size);
-
- for (UInt e = 0; e < nb_element; ++e, ++u_it) {
- for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it, ++shapes_derivatives_filtered_it, ++sigma_it) {
- Vector<Real> & u = *u_it;
- Matrix<Real> & sigma = *sigma_it;
- Matrix<Real> & D = *D_it;
-
- VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
-
- Bu.mul<false>(B, u);
- DBu.mul<false>(D, Bu);
-
- // Voigt notation to full symmetric tensor
- for (UInt i = 0; i < dim; ++i) sigma(i, i) = DBu(i);
- if(dim == 2) {
- sigma(0,1) = sigma(1,0) = DBu(2);
- } else if(dim == 3) {
- sigma(1,2) = sigma(2,1) = DBu(3);
- sigma(0,2) = sigma(2,0) = DBu(4);
- sigma(0,1) = sigma(1,0) = DBu(5);
+ Array<Real> * shapesd_filtered =
+ new Array<Real>(0, dim* nb_nodes_per_element, "filtered shapesd");
+
+ FEEngine::filterElementalData(fem->getMesh(), shapes_derivatives, *shapesd_filtered,
+ type, ghost_type, elem_filter);
+
+ Array<Real> filtered_u(nb_element, nb_nodes_per_element * spatial_dimension);
+
+ FEEngine::extractNodalToElementField(fem->getMesh(), disp, filtered_u,
+ type, ghost_type, elem_filter);
+
+ /// compute @f$\mathbf{D} \mathbf{B} \mathbf{u}@f$
+ Array<Real>::matrix_iterator shapes_derivatives_filtered_it =
+ shapesd_filtered->begin(dim, nb_nodes_per_element);
+
+ Array<Real>::matrix_iterator D_it = tangent_moduli_tensors->begin(tangent_moduli_size,
+ tangent_moduli_size);
+ Array<Real>::matrix_iterator sigma_it = stress(type, ghost_type).begin(spatial_dimension,
+ spatial_dimension);
+ Array<Real>::vector_iterator u_it = filtered_u.begin(spatial_dimension * nb_nodes_per_element);
+
+ Matrix<Real> B(tangent_moduli_size, spatial_dimension * nb_nodes_per_element);
+ Vector<Real> Bu(tangent_moduli_size);
+ Vector<Real> DBu(tangent_moduli_size);
+
+ for (UInt e = 0; e < nb_element; ++e, ++u_it) {
+ for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it, ++shapes_derivatives_filtered_it, ++sigma_it) {
+ Vector<Real> & u = *u_it;
+ Matrix<Real> & sigma = *sigma_it;
+ Matrix<Real> & D = *D_it;
+
+ VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B, nb_nodes_per_element);
+
+ Bu.mul<false>(B, u);
+ DBu.mul<false>(D, Bu);
+
+ // Voigt notation to full symmetric tensor
+ for (UInt i = 0; i < dim; ++i) sigma(i, i) = DBu(i);
+ if(dim == 2) {
+ sigma(0,1) = sigma(1,0) = DBu(2);
+ } else if(dim == 3) {
+ sigma(1,2) = sigma(2,1) = DBu(3);
+ sigma(0,2) = sigma(2,0) = DBu(4);
+ sigma(0,1) = sigma(1,0) = DBu(5);
+ }
}
}
}
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computePotentialEnergyByElements() {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = element_filter.firstType(spatial_dimension);
Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension);
for(; it != last_type; ++it) {
computePotentialEnergy(*it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::computePotentialEnergy(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
- if(!potential_energy.exists(el_type, ghost_type)) {
- UInt nb_element = element_filter(el_type, ghost_type).getSize();
- UInt nb_quadrature_points = model->getFEEngine().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) {
- epot += model->getFEEngine().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(model->getFEEngine().getNbQuadraturePoints(type));
+ Vector<Real> epot_on_quad_points(fem->getNbIntegrationPoints(type));
computePotentialEnergyByElement(type, index, epot_on_quad_points);
- epot = model->getFEEngine().integrate(epot_on_quad_points, type, element_filter(type)(index));
+ epot = fem->integrate(epot_on_quad_points, type, element_filter(type)(index));
AKANTU_DEBUG_OUT();
return epot;
}
/* -------------------------------------------------------------------------- */
Real Material::getEnergy(std::string type) {
AKANTU_DEBUG_IN();
if(type == "potential") return getPotentialEnergy();
AKANTU_DEBUG_OUT();
return 0.;
}
/* -------------------------------------------------------------------------- */
Real Material::getEnergy(std::string energy_id, ElementType type, UInt index) {
AKANTU_DEBUG_IN();
if(energy_id == "potential") return getPotentialEnergy(type, index);
AKANTU_DEBUG_OUT();
return 0.;
}
/* -------------------------------------------------------------------------- */
-void Material::computeQuadraturePointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates,
- const GhostType & ghost_type) const {
+void Material::initElementalFieldInterpolation(const ElementTypeMapArray<Real> & interpolation_points_coordinates) {
AKANTU_DEBUG_IN();
- const Mesh & mesh = model->getFEEngine().getMesh();
-
- Array<Real> nodes_coordinates(mesh.getNodes(), true);
- nodes_coordinates += model->getDisplacement();
-
- 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) {
- const Array<UInt> & elem_filter = element_filter(*it, ghost_type);
-
- UInt nb_element = elem_filter.getSize();
- UInt nb_tot_quad = model->getFEEngine().getNbQuadraturePoints(*it, ghost_type) * nb_element;
-
- Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
- quads.resize(nb_tot_quad);
-
- model->getFEEngine().interpolateOnQuadraturePoints(nodes_coordinates,
- quads, spatial_dimension,
- *it, ghost_type, elem_filter);
- }
-
+ this->fem->initElementalFieldInterpolationFromIntegrationPoints(interpolation_points_coordinates,
+ this->interpolation_points_matrices,
+ this->interpolation_inverse_coordinates,
+ &(this->element_filter));
AKANTU_DEBUG_OUT();
}
+
/* -------------------------------------------------------------------------- */
-void Material::initElementalFieldInterpolation(const ElementTypeMapArray<Real> & interpolation_points_coordinates) {
- AKANTU_DEBUG_IN();
- const Mesh & mesh = model->getFEEngine().getMesh();
+void Material::interpolateStress(ElementTypeMapArray<Real> & result,
+ const GhostType ghost_type) {
+
+ this->fem->interpolateElementalFieldFromIntegrationPoints(this->stress,
+ this->interpolation_points_matrices,
+ this->interpolation_inverse_coordinates,
+ result,
+ ghost_type,
+ &(this->element_filter));
+}
- ElementTypeMapArray<Real> quadrature_points_coordinates("quadrature_points_coordinates_for_interpolation", getID());
- mesh.initElementTypeMapArray(quadrature_points_coordinates, spatial_dimension, spatial_dimension);
+/* -------------------------------------------------------------------------- */
+void Material::interpolateStressOnFacets(ElementTypeMapArray<Real> & result,
+ ElementTypeMapArray<Real> & by_elem_result,
+ const GhostType ghost_type) {
- for (ghost_type_t::iterator gt = ghost_type_t::begin();
- gt != ghost_type_t::end(); ++gt) {
+
+ interpolateStress(by_elem_result, ghost_type);
- GhostType ghost_type = *gt;
+ UInt stress_size = this->stress.getNbComponent();
- computeQuadraturePointsCoordinates(quadrature_points_coordinates, ghost_type);
+ 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);
- for (; it != last; ++it) {
- ElementType type = *it;
- UInt nb_element = mesh.getNbElement(type, ghost_type);
- if (nb_element == 0) continue;
+ 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) {
- const Array<Real> & interp_points_coord = interpolation_points_coordinates(type, ghost_type);
- UInt nb_interpolation_points_per_elem = interp_points_coord.getSize() / nb_element;
+ ElementType type = *it;
+ Array<UInt> & elem_fil = element_filter(type, ghost_type);
+ Array<Real> & by_elem_res = by_elem_result(type, ghost_type);
+ UInt nb_element = elem_fil.getSize();
+ UInt nb_element_full = this->model->getMesh().getNbElement(type, ghost_type);
+ UInt nb_interpolation_points_per_elem = by_elem_res.getSize() / nb_element_full;
+
+ const Array<Element> & facet_to_element =
+ mesh_facets.getSubelementToElement(type, ghost_type);
+ ElementType type_facet = Mesh::getFacetType(type);
+ UInt nb_facet_per_elem = facet_to_element.getNbComponent();
+ UInt nb_quad_per_facet = nb_interpolation_points_per_elem / nb_facet_per_elem;
+ Element element_for_comparison(type, 0, ghost_type);
+ const Array< std::vector<Element> > * element_to_facet = NULL;
+ GhostType current_ghost_type = _casper;
+ Array<Real> * result_vec = NULL;
+
+ Array<Real>::const_matrix_iterator result_it
+ = by_elem_res.begin_reinterpret(stress_size,
+ nb_interpolation_points_per_elem,
+ nb_element_full);
+
+ for (UInt el = 0; el < nb_element; ++el){
+ UInt global_el = elem_fil(el);
+ element_for_comparison.element = global_el;
+ for (UInt f = 0; f < nb_facet_per_elem; ++f) {
+
+ Element facet_elem = facet_to_element(global_el, f);
+ UInt global_facet = facet_elem.element;
+ if (facet_elem.ghost_type != current_ghost_type) {
+ current_ghost_type = facet_elem.ghost_type;
+ element_to_facet = &mesh_facets.getElementToSubelement(type_facet,
+ current_ghost_type);
+ result_vec = &result(type_facet, current_ghost_type);
+ }
- AKANTU_DEBUG_ASSERT(interp_points_coord.getSize() % nb_element == 0,
- "Number of interpolation points is wrong");
+ bool is_second_element = (*element_to_facet)(global_facet)[0] != element_for_comparison;
-#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) \
+ for (UInt q = 0; q < nb_quad_per_facet; ++q) {
+ Vector<Real> result_local(result_vec->storage()
+ + (global_facet * nb_quad_per_facet + q) * result_vec->getNbComponent()
+ + is_second_element * stress_size,
+ stress_size);
- AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(AKANTU_INIT_INTERPOLATE_ELEMENTAL_FIELD);
-#undef AKANTU_INIT_INTERPOLATE_ELEMENTAL_FIELD
+ const Matrix<Real> & result_tmp(result_it[global_el]);
+ result_local = result_tmp(f * nb_quad_per_facet + q);
+ }
+ }
}
}
-
- 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) {
- AKANTU_DEBUG_IN();
- UInt size_inverse_coords =
- getSizeElementalFieldInterpolationCoodinates<type>(ghost_type);
-
- Array<UInt> & elem_fil = element_filter(type, ghost_type);
- UInt nb_element = elem_fil.getSize();
- UInt nb_quad_per_element = model->getFEEngine().getNbQuadraturePoints(type, ghost_type);
-
- if(!interpolation_inverse_coordinates.exists(type, ghost_type))
- interpolation_inverse_coordinates.alloc(nb_element,
- size_inverse_coords*size_inverse_coords,
- type, ghost_type);
-
- if(!interpolation_points_matrices.exists(type, ghost_type))
- interpolation_points_matrices.alloc(nb_element,
- nb_interpolation_points_per_elem * size_inverse_coords,
- type, ghost_type);
-
- 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(size_inverse_coords, size_inverse_coords);
-
- 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(size_inverse_coords, size_inverse_coords);
-
- Array<Real>::matrix_iterator inv_points_mat_it =
- interp_points_mat.begin(nb_interpolation_points_per_elem, size_inverse_coords);
-
- /// 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);
- }
-
- AKANTU_DEBUG_OUT();
+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;
}
/* -------------------------------------------------------------------------- */
-void Material::interpolateStress(ElementTypeMapArray<Real> & result,
- const GhostType ghost_type) {
- AKANTU_DEBUG_IN();
-
- const Mesh & mesh = model->getFEEngine().getMesh();
-
- 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;
-
- Array<Real> & res = result(type, 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;
+}
-#define INTERPOLATE_ELEMENTAL_FIELD(type) \
- interpolateElementalField<type>(stress(type, ghost_type), \
- res, \
- ghost_type)
+/* -------------------------------------------------------------------------- */
+template<>
+const Array<Real> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) const {
+ std::stringstream sstr;
+ std::string ghost_id = "";
+ if (ghost_type == _ghost) ghost_id = ":ghost";
+ sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
- AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(INTERPOLATE_ELEMENTAL_FIELD);
-#undef INTERPOLATE_ELEMENTAL_FIELD
+ 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 << "]");
}
-
- AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template <ElementType type>
-void Material::interpolateElementalField(const Array<Real> & field,
- Array<Real> & result,
- const GhostType ghost_type) {
- AKANTU_DEBUG_IN();
-
- Array<UInt> & elem_fil = element_filter(type, ghost_type);
- UInt nb_element = elem_fil.getSize();
- UInt nb_quad_per_element = model->getFEEngine().getNbQuadraturePoints(type, ghost_type);
- UInt size_inverse_coords = getSizeElementalFieldInterpolationCoodinates<type>(ghost_type);
-
- Matrix<Real> coefficients(nb_quad_per_element, field.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() / size_inverse_coords;
-
- 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 =
- interp_points_coord.begin(nb_interpolation_points_per_elem, size_inverse_coords);
-
- Array<Real>::matrix_iterator result_begin
- = result.begin_reinterpret(field.getNbComponent(),
- nb_interpolation_points_per_elem,
- result.getSize() / nb_interpolation_points_per_elem);
-
- Array<Real>::const_matrix_iterator inv_quad_coord_it =
- interp_inv_coord.begin(size_inverse_coords, size_inverse_coords);
-
- /// 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;
+template<>
+Array<Real> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) {
+ std::stringstream sstr;
+ std::string ghost_id = "";
+ if (ghost_type == _ghost) ghost_id = ":ghost";
+ sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
- /// multiply the coordinates matrix by the coefficients matrix and store the result
- result_begin[elem_fil(el)].mul<true, true>(coefficients, coord);
+ 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 << "]");
}
-
-
- AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-
-const Array<Real> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) const {
+template<>
+const Array<UInt> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) const {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost) ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
- return Memory::getArray<Real>(fvect_id);
+ return Memory::getArray<UInt>(fvect_id);
} catch(debug::Exception & e) {
- AKANTU_EXCEPTION("The material " << name << "(" <<getID() << ") does not contain a vector " << vect_id << "(" << fvect_id << ") [" << e << "]");
+ AKANTU_SILENT_EXCEPTION("The material " << name << "(" <<getID() << ") does not contain a vector " << vect_id << "(" << fvect_id << ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
-Array<Real> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) {
+template<>
+Array<UInt> & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) {
std::stringstream sstr;
std::string ghost_id = "";
if (ghost_type == _ghost) ghost_id = ":ghost";
sstr << getID() << ":" << vect_id << ":" << type << ghost_id;
ID fvect_id = sstr.str();
try {
- return Memory::getArray<Real>(fvect_id);
+ return Memory::getArray<UInt>(fvect_id);
} catch(debug::Exception & e) {
- AKANTU_EXCEPTION("The material " << name << "(" << getID() << ") does not contain a vector " << vect_id << "(" << fvect_id << ") [" << e << "]");
+ AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() << ") does not contain a vector " << vect_id << "(" << fvect_id << ") [" << e << "]");
}
}
/* -------------------------------------------------------------------------- */
+template<typename T>
+const InternalField<T> & Material::getInternal(const ID & int_id) const {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ return NULL;
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+InternalField<T> & Material::getInternal(const ID & int_id) {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ return NULL;
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
const InternalField<Real> & Material::getInternal(const ID & int_id) const {
std::map<ID, InternalField<Real> *>::const_iterator it = internal_vectors_real.find(getID() + ":" + int_id);
if(it == internal_vectors_real.end()) {
- AKANTU_EXCEPTION("The material " << name << "(" << getID()
+ AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " (" << (getID() + ":" + int_id) << ")");
}
return *it->second;
}
/* -------------------------------------------------------------------------- */
+template<>
InternalField<Real> & Material::getInternal(const ID & int_id) {
std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.find(getID() + ":" + int_id);
if(it == internal_vectors_real.end()) {
- AKANTU_EXCEPTION("The material " << name << "(" << getID()
+ AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
+ << ") does not contain an internal "
+ << int_id << " (" << (getID() + ":" + int_id) << ")");
+ }
+ return *it->second;
+}
+
+/* -------------------------------------------------------------------------- */
+template<>
+const InternalField<UInt> & Material::getInternal(const ID & int_id) const {
+ std::map<ID, InternalField<UInt> *>::const_iterator it = internal_vectors_uint.find(getID() + ":" + int_id);
+ if(it == internal_vectors_uint.end()) {
+ AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
<< ") does not contain an internal "
<< int_id << " (" << (getID() + ":" + int_id) << ")");
}
return *it->second;
}
+/* -------------------------------------------------------------------------- */
+template<>
+InternalField<UInt> & Material::getInternal(const ID & int_id) {
+ std::map<ID, InternalField<UInt> *>::iterator it = internal_vectors_uint.find(getID() + ":" + int_id);
+ if(it == internal_vectors_uint.end()) {
+ AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
+ << ") does not contain an internal "
+ << int_id << " (" << (getID() + ":" + int_id) << ")");
+ }
+ return *it->second;
+}
+
/* -------------------------------------------------------------------------- */
void Material::addElements(const Array<Element> & elements_to_add) {
AKANTU_DEBUG_IN();
UInt mat_id = model->getInternalIndexFromID(getID());
Array<Element>::const_iterator<Element> el_begin = elements_to_add.begin();
Array<Element>::const_iterator<Element> el_end = elements_to_add.end();
for(;el_begin != el_end; ++el_begin) {
const Element & element = *el_begin;
- Array<UInt> & element_index_material = model->getElementIndexByMaterial(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);
- element_index_material(element.element, 0) = mat_id;
- element_index_material(element.element, 1) = index;
+ mat_indexes(element.element) = mat_id;
+ mat_loc_num(element.element) = index;
}
this->resizeInternals();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::removeElements(const Array<Element> & elements_to_remove) {
AKANTU_DEBUG_IN();
Array<Element>::const_iterator<Element> el_begin = elements_to_remove.begin();
Array<Element>::const_iterator<Element> el_end = elements_to_remove.end();
if(el_begin==el_end)
return;
ElementTypeMapArray<UInt> material_local_new_numbering("remove mat filter elem", getID());
Element element;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
GhostType ghost_type = *gt;
element.ghost_type = ghost_type;
ElementTypeMapArray<UInt>::type_iterator it = element_filter.firstType(_all_dimensions, ghost_type, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end = element_filter.lastType(_all_dimensions, ghost_type, _ek_not_defined);
for(; it != end; ++it) {
ElementType type = *it;
element.type = type;
Array<UInt> & elem_filter = this->element_filter(type, ghost_type);
- Array<UInt> & element_index_material = model->getElementIndexByMaterial(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);
+ material_local_new_numbering.alloc(elem_filter.getSize(), 1, type, ghost_type);
Array<UInt> & mat_renumbering = material_local_new_numbering(type, ghost_type);
UInt nb_element = elem_filter.getSize();
element.kind=(*el_begin).kind;
Array<UInt> elem_filter_tmp;
UInt new_id = 0;
for (UInt el = 0; el < nb_element; ++el) {
- element.element = elem_filter(el);
+ element.element = elem_filter(el);
- if(std::find(el_begin, el_end, element) == el_end) {
- elem_filter_tmp.push_back(element.element);
+ if(std::find(el_begin, el_end, element) == el_end) {
+ elem_filter_tmp.push_back(element.element);
- mat_renumbering(el) = new_id;
- element_index_material(element.element, 1) = new_id;
- ++new_id;
- } else {
- mat_renumbering(el) = UInt(-1);
- }
+ 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);
+ ++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);
+ ++it) it->second->removeIntegrationPoints(material_local_new_numbering);
+
+ for (std::map<ID, InternalField<bool> *>::iterator it = internal_vectors_bool.begin();
+ it != internal_vectors_bool.end();
+ ++it) it->second->removeIntegrationPoints(material_local_new_numbering);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::resizeInternals() {
AKANTU_DEBUG_IN();
for (std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.begin();
it != internal_vectors_real.end();
++it) it->second->resize();
for (std::map<ID, InternalField<UInt> *>::iterator it = internal_vectors_uint.begin();
it != internal_vectors_uint.end();
++it) it->second->resize();
+
+ for (std::map<ID, InternalField<bool> *>::iterator it = internal_vectors_bool.begin();
+ it != internal_vectors_bool.end();
+ ++it) it->second->resize();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void Material::onElementsAdded(__attribute__((unused)) const Array<Element> & element_list,
- __attribute__((unused)) const NewElementsEvent & event) {
+ __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) {
+ const ElementTypeMapArray<UInt> & new_numbering,
+ __attribute__((unused)) const RemovedElementsEvent & event) {
UInt my_num = model->getInternalIndexFromID(getID());
ElementTypeMapArray<UInt> material_local_new_numbering("remove mat filter elem", getID());
Array<Element>::const_iterator<Element> el_begin = element_list.begin();
Array<Element>::const_iterator<Element> el_end = element_list.end();
for (ghost_type_t::iterator g = ghost_type_t::begin(); g != ghost_type_t::end(); ++g) {
GhostType gt = *g;
ElementTypeMapArray<UInt>::type_iterator it = new_numbering.firstType(_all_dimensions, gt, _ek_not_defined);
- ElementTypeMapArray<UInt>::type_iterator end = new_numbering.lastType(_all_dimensions, gt, _ek_not_defined);
+ 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)){
- Array<UInt> & elem_filter = element_filter(type, gt);
-
- Array<UInt> & element_index_material = model->getElementIndexByMaterial(type, gt);
- element_index_material.resize(model->getFEEngine().getMesh().getNbElement(type, gt)); // all materials will resize of the same size...
-
- 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;
- for (UInt i = 0; i < elem_filter.getSize(); ++i) {
- el.element = elem_filter(i);
- if(std::find(el_begin, el_end, el) == el_end) {
- UInt new_el = renumbering(el.element);
- AKANTU_DEBUG_ASSERT(new_el != UInt(-1), "A not removed element as been badly renumbered");
- elem_filter_tmp.push_back(new_el);
- mat_renumbering(i) = ni;
- element_index_material(new_el, 0) = my_num;
- element_index_material(new_el, 1) = ni;
- ++ni;
- } else {
- mat_renumbering(i) = UInt(-1);
- }
- }
-
- elem_filter.resize(elem_filter_tmp.getSize());
- elem_filter.copy(elem_filter);
+ if(element_filter.exists(type, gt) && element_filter(type, gt).getSize()){
+ Array<UInt> & elem_filter = element_filter(type, gt);
+
+ Array<UInt> & mat_indexes = this->model->getMaterialByElement (*it, gt);
+ Array<UInt> & mat_loc_num = this->model->getMaterialLocalNumbering(*it, gt);
+ UInt nb_element = this->model->getMesh().getNbElement(type, gt);
+
+ // all materials will resize of the same size...
+ mat_indexes.resize(nb_element);
+ mat_loc_num.resize(nb_element);
+
+ if(!material_local_new_numbering.exists(type, gt))
+ material_local_new_numbering.alloc(elem_filter.getSize(), 1, type, gt);
+
+ Array<UInt> & mat_renumbering = material_local_new_numbering(type, gt);
+ const Array<UInt> & renumbering = new_numbering(type, gt);
+ Array<UInt> elem_filter_tmp;
+ UInt ni = 0;
+ Element el;
+ el.type = type;
+ el.ghost_type = gt;
+ el.kind = Mesh::getKind(type);
+ for (UInt i = 0; i < elem_filter.getSize(); ++i) {
+ el.element = elem_filter(i);
+ if(std::find(el_begin, el_end, el) == el_end) {
+ UInt new_el = renumbering(el.element);
+ AKANTU_DEBUG_ASSERT(new_el != UInt(-1), "A not removed element as been badly renumbered");
+ elem_filter_tmp.push_back(new_el);
+ mat_renumbering(i) = ni;
+
+ mat_indexes(new_el) = my_num;
+ mat_loc_num(new_el) = ni;
+ ++ni;
+ } else {
+ mat_renumbering(i) = UInt(-1);
+ }
+ }
+
+ elem_filter.resize(elem_filter_tmp.getSize());
+ elem_filter.copy(elem_filter_tmp);
}
}
}
for (std::map<ID, InternalField<Real> *>::iterator it = internal_vectors_real.begin();
it != internal_vectors_real.end();
- ++it) it->second->removeQuadraturePoints(material_local_new_numbering);
+ ++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);
+ ++it) it->second->removeIntegrationPoints(material_local_new_numbering);
+
+ for (std::map<ID, InternalField<bool> *>::iterator it = internal_vectors_bool.begin();
+ it != internal_vectors_bool.end();
+ ++it) it->second->removeIntegrationPoints(material_local_new_numbering);
}
/* -------------------------------------------------------------------------- */
void Material::onBeginningSolveStep(const AnalysisMethod & method) {
this->savePreviousState();
}
/* -------------------------------------------------------------------------- */
void Material::onEndSolveStep(const AnalysisMethod & method) {
ElementTypeMapArray<UInt>::type_iterator it
= this->element_filter.firstType(_all_dimensions, _not_ghost, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end
= element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
for(; it != end; ++it) {
this->updateEnergies(*it, _not_ghost);
}
}
/* -------------------------------------------------------------------------- */
void Material::onDamageIteration() {
this->savePreviousState();
}
/* -------------------------------------------------------------------------- */
void Material::onDamageUpdate() {
ElementTypeMapArray<UInt>::type_iterator it
= this->element_filter.firstType(_all_dimensions, _not_ghost, _ek_not_defined);
ElementTypeMapArray<UInt>::type_iterator end
= element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
for(; it != end; ++it) {
-
- if(!this->potential_energy.exists(*it, _not_ghost)) {
- UInt nb_element = this->element_filter(*it, _not_ghost).getSize();
- UInt nb_quadrature_points = this->model->getFEEngine().getNbQuadraturePoints(*it, _not_ghost);
-
- this->potential_energy.alloc(nb_element * nb_quadrature_points, 1,
- *it, _not_ghost);
- }
this->updateEnergiesAfterDamage(*it, _not_ghost);
}
}
/* -------------------------------------------------------------------------- */
void Material::onDump(){
if(this->isFiniteDeformation())
this->computeAllCauchyStresses(_not_ghost);
}
/* -------------------------------------------------------------------------- */
void Material::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
std::string type = getID().substr(getID().find_last_of(":") + 1);
stream << space << "Material " << type << " [" << std::endl;
Parsable::printself(stream, indent);
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
-
-void Material::flattenInternal(const std::string & field_id,
- ElementTypeMapArray<Real> & internal_flat,
- const GhostType ghost_type,
- ElementKind element_kind){
-
- typedef ElementTypeMapArray<UInt>::type_iterator iterator;
- iterator tit = this->element_filter.firstType(this->spatial_dimension,
- ghost_type, element_kind);
- iterator end = this->element_filter.lastType(this->spatial_dimension,
- ghost_type, element_kind);
-
-
- for (; tit != end; ++tit) {
-
- ElementType type = *tit;
-
- try {
- __attribute__((unused)) const Array<Real> & src_vect
- = this->getArray(field_id,type,ghost_type);
-
- } catch(debug::Exception & e) {
- continue;
+/// extrapolate internal values
+void Material::extrapolateInternal(const ID & id, const Element & element, const Matrix<Real> & point, Matrix<Real> & extrapolated) {
+ if (this->isInternal<Real>(id, element.kind)) {
+ UInt nb_element = this->element_filter(element.type, element.ghost_type).getSize();
+ const ID name = this->getID() + ":" + id;
+ UInt nb_quads = this->internal_vectors_real[name]->getFEEngine().getNbIntegrationPoints(element.type, element.ghost_type);
+ const Array<Real> & internal = this->getArray<Real>(id, element.type, element.ghost_type);
+ UInt nb_component = internal.getNbComponent();
+ Array<Real>::const_matrix_iterator internal_it = internal.begin_reinterpret(nb_component, nb_quads, nb_element);
+ Element local_element = this->convertToLocalElement(element);
+
+ /// instead of really extrapolating, here the value of the first GP
+ /// is copied into the result vector. This works only for linear
+ /// elements
+ /// @todo extrapolate!!!!
+ AKANTU_DEBUG_WARNING("This is a fix, values are not truly extrapolated");
+
+ const Matrix<Real> & values = internal_it[local_element.element];
+ UInt index = 0;
+ Vector<Real> tmp(nb_component);
+ for (UInt j = 0; j < values.cols(); ++j) {
+ tmp = values(j);
+ if (tmp.norm() > 0) {
+ index = j;
+ break;
}
+ }
- const Array<Real> & src_vect = this->getArray(field_id,type,ghost_type);
- const Array<UInt> & filter = this->element_filter(type,ghost_type);
-
- // total number of elements for a given type
- UInt nb_element = this->model->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);
+ for (UInt i = 0; i < extrapolated.size(); ++i) {
+ extrapolated(i) = values(index);
+ }
+ }
+ else {
+ Matrix<Real> default_values(extrapolated.rows(), extrapolated.cols(), 0.);
+ extrapolated = default_values;
+ }
+}
- 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);
+/* -------------------------------------------------------------------------- */
+void Material::applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const GhostType ghost_type) {
- Array<Real>::vector_iterator it_dst =
- dst_vect.begin_reinterpret(nb_data,nb_element);
+ 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,++it_src) {
- it_dst[*it] = *it_src;
- }
+ 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 a1bdba331..39f512864 100644
--- a/src/model/solid_mechanics/material.hh
+++ b/src/model/solid_mechanics/material.hh
@@ -1,575 +1,633 @@
/**
* @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>
*
* @date creation: Tue Jul 27 2010
* @date last modification: Tue Sep 16 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_memory.hh"
#include "aka_voigthelper.hh"
#include "parser.hh"
#include "parsable.hh"
#include "data_accessor.hh"
#include "internal_field.hh"
#include "random_internal_field.hh"
#include "solid_mechanics_model_event_handler.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_HH__
#define __AKANTU_MATERIAL_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class Model;
class SolidMechanicsModel;
}
__BEGIN_AKANTU__
/**
* Interface of all materials
* Prerequisites for a new material
* - inherit from this class
* - implement the following methods:
* \code
* virtual Real getStableTimeStep(Real h, const Element & element = ElementNull);
*
* virtual void computeStress(ElementType el_type,
* GhostType ghost_type = _not_ghost);
*
* virtual void computeTangentStiffness(const ElementType & el_type,
* Array<Real> & tangent_matrix,
* GhostType ghost_type = _not_ghost);
* \endcode
*
*/
class Material : public Memory, public DataAccessor, public Parsable,
public MeshEventHandler,
protected SolidMechanicsModelEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
+#if __cplusplus > 199711L
+ Material(const Material & mat) = delete;
+ Material & operator=(const Material & mat) = delete;
+#endif
+ /// Initialize material with defaults
Material(SolidMechanicsModel & model, const ID & id = "");
+
+ /// Initialize material with custom mesh & fe_engine
+ Material(SolidMechanicsModel & model,
+ UInt dim,
+ const Mesh & mesh,
+ FEEngine & fe_engine,
+ const ID & id = "");
+
+ /// Destructor
virtual ~Material();
+protected:
+ void initialize();
+
/* ------------------------------------------------------------------------ */
/* Function that materials can/should reimplement */
/* ------------------------------------------------------------------------ */
protected:
/// constitutive law
virtual void computeStress(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type = _not_ghost) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// compute the tangent stiffness matrix
virtual void computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
__attribute__((unused)) Array<Real> & tangent_matrix,
__attribute__((unused)) GhostType ghost_type = _not_ghost) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// compute the potential energy
virtual void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost);
/// compute the potential energy for an element
virtual void computePotentialEnergyByElement(__attribute__((unused)) ElementType type,
- __attribute__((unused)) UInt index,
+ __attribute__((unused)) UInt index,
__attribute__((unused)) Vector<Real> & epot_on_quad_points) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
virtual void updateEnergies(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type = _not_ghost) { }
virtual void updateEnergiesAfterDamage(__attribute__((unused)) ElementType el_type,
- __attribute__((unused)) GhostType ghost_type = _not_ghost) {}
+ __attribute__((unused)) GhostType ghost_type = _not_ghost) {}
/// set the material to steady state (to be implemented for materials that need it)
virtual void setToSteadyState(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type = _not_ghost) { }
/// function called to update the internal parameters when the modifiable
/// parameters are modified
virtual void updateInternalParameters() {}
public:
+ /// extrapolate internal values
+ virtual void extrapolateInternal(const ID & id, const Element & element, const Matrix<Real> & points, Matrix<Real> & extrapolated);
/// compute the p-wave speed in the material
virtual Real getPushWaveSpeed(const Element & element) const { AKANTU_DEBUG_TO_IMPLEMENT(); }
/// compute the s-wave speed in the material
virtual Real getShearWaveSpeed(const Element & element) const { AKANTU_DEBUG_TO_IMPLEMENT(); }
/// get a material celerity to compute the stable time step (default: is the push wave speed)
virtual Real getCelerity(const Element & element) const { return getPushWaveSpeed(element); }
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
template<typename T>
void registerInternal(__attribute__((unused)) InternalField<T> & vect) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
template<typename T>
void unregisterInternal(__attribute__((unused)) InternalField<T> & vect) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// initialize the material computed parameter
virtual void initMaterial();
/// compute the residual for this material
virtual void updateResidual(GhostType ghost_type = _not_ghost);
/// assemble the residual for this material
virtual void assembleResidual(GhostType ghost_type);
- /// 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 computeAllCauchyStresses(GhostType ghost_type = _not_ghost);
/// set material to steady state
void setToSteadyState(GhostType ghost_type = _not_ghost);
/// compute the stiffness matrix
virtual void assembleStiffnessMatrix(GhostType ghost_type);
/// add an element to the local mesh filter
inline UInt addElement(const ElementType & type,
UInt element,
const GhostType & ghost_type);
/// add many elements at once
void addElements(const Array<Element> & elements_to_add);
/// remove many element at once
void removeElements(const Array<Element> & elements_to_remove);
/// function to print the contain of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
/**
* interpolate stress on given positions for each element by means
* of a geometrical interpolation on quadrature points
*/
void interpolateStress(ElementTypeMapArray<Real> & result,
const GhostType ghost_type = _not_ghost);
+ /**
+ * interpolate stress on given positions for each element by means
+ * of a geometrical interpolation on quadrature points and store the
+ * results per facet
+ */
+ void interpolateStressOnFacets(ElementTypeMapArray<Real> & result,
+ ElementTypeMapArray<Real> & by_elem_result,
+ const GhostType ghost_type = _not_ghost);
+
/**
* function to initialize the elemental field interpolation
* function by inverting the quadrature points' coordinates
*/
void initElementalFieldInterpolation(const ElementTypeMapArray<Real> & interpolation_points_coordinates);
/* ------------------------------------------------------------------------ */
/* Common part */
/* ------------------------------------------------------------------------ */
+protected:
+ /* ------------------------------------------------------------------------ */
+ inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const;
+
+
+ /// compute the potential energy by element
+ void computePotentialEnergyByElements();
+
+ /// resize the intenals arrays
+ virtual void resizeInternals();
+
+ /* ------------------------------------------------------------------------ */
+ /* Finite deformation functions */
+ /* This functions area implementing what is described in the paper of Bathe */
+ /* et al, in IJNME, Finite Element Formulations For Large Deformation */
+ /* Dynamic Analysis, Vol 9, 353-386, 1975 */
+ /* ------------------------------------------------------------------------ */
protected:
/// assemble the residual
template<UInt dim>
void assembleResidual(GhostType ghost_type);
- /// Computation of Cauchy stress tensor in the case of finite deformation
+ /// 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;
+ 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);
/// assembling in finite deformation
template<UInt dim>
void assembleStiffnessMatrixNL(const ElementType & type,
GhostType ghost_type);
template<UInt dim>
void assembleStiffnessMatrixL2(const ElementType & type,
GhostType ghost_type);
- /// 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>
inline void setCauchyStressMatrix(const Matrix<Real> & S_t,
- Matrix<Real> & Stress_matrix);
-
- /// compute the potential energy by element
- void computePotentialEnergyByElements();
+ Matrix<Real> & sigma);
- /// resize the intenals arrays
- void resizeInternals();
-
-public:
- /// compute the coordinates of the quadrature points
- void computeQuadraturePointsCoordinates(ElementTypeMapArray<Real> & quadrature_points_coordinates,
- const GhostType & ghost_type) const;
-
-protected:
- /// interpolate an elemental field on given points for each element
- template <ElementType type>
- void interpolateElementalField(const Array<Real> & field,
- Array<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);
-
- /// get the size of the coordiante matrix used in the interpolation
- template <ElementType type>
- inline UInt getSizeElementalFieldInterpolationCoodinates(GhostType ghost_type = _not_ghost);
+ /// 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 */
/* ------------------------------------------------------------------------ */
+public:
template<UInt dim>
- inline void gradUToF (const Matrix<Real> & grad_u, Matrix<Real> & F) const;
- inline void rightCauchy(const Matrix<Real> & F, Matrix<Real> & C) const;
- inline void leftCauchy (const Matrix<Real> & F, Matrix<Real> & B) const;
+ 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>
- inline void gradUToEpsilon(const Matrix<Real> & grad_u, Matrix<Real> & epsilon) const;
+ static inline void gradUToEpsilon(const Matrix<Real> & grad_u,
+ Matrix<Real> & epsilon);
template<UInt dim>
- inline void gradUToGreenStrain(const Matrix<Real> & grad_u,
- Matrix<Real> & epsilon) const;
+ static inline void gradUToGreenStrain(const Matrix<Real> & grad_u,
+ Matrix<Real> & epsilon);
+
+ static inline Real stressToVonMises(const Matrix<Real> & stress);
+
+protected:
+ /// converts global element to local element
+ inline Element convertToLocalElement(const Element & global_element) const;
+ /// converts local element to global element
+ inline Element convertToGlobalElement(const Element & local_element) const;
+
+ /// converts global quadrature point to local quadrature point
+ inline IntegrationPoint convertToLocalPoint(const IntegrationPoint & global_point) const;
+ /// converts local quadrature point to global quadrature point
+ inline IntegrationPoint convertToGlobalPoint(const IntegrationPoint & local_point) const;
/* ------------------------------------------------------------------------ */
/* DataAccessor inherited members */
/* ------------------------------------------------------------------------ */
public:
virtual inline UInt getNbDataForElements(const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const;
virtual inline void unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag);
template<typename T>
inline void packElementDataHelper(const ElementTypeMapArray<T> & data_to_pack,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const ID & fem_id = ID()) const;
template<typename T>
inline void unpackElementDataHelper(ElementTypeMapArray<T> & data_to_unpack,
CommunicationBuffer & buffer,
const Array<Element> & elements,
const ID & fem_id = ID());
/* ------------------------------------------------------------------------ */
/* MeshEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
+ virtual void onNodesAdded(
+ __attribute__((unused)) const Array<UInt> & nodes_list,
+ __attribute__((unused)) const NewNodesEvent & event) {};
+ virtual void onNodesRemoved(
+ __attribute__((unused)) const Array<UInt> & nodes_list,
+ __attribute__((unused)) const Array<UInt> & new_numbering,
+ __attribute__((unused)) const RemovedNodesEvent & event) {};
+
virtual void onElementsAdded(const Array<Element> & element_list,
const NewElementsEvent & event);
virtual void onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event);
+ virtual void onElementsChanged(__attribute__((unused)) const Array<Element> & old_elements_list,
+ __attribute__((unused)) const Array<Element> & new_elements_list,
+ __attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
+ __attribute__((unused)) const ChangedElementsEvent & event) {};
+
/* ------------------------------------------------------------------------ */
/* SolidMechanicsModelEventHandler inherited members */
/* ------------------------------------------------------------------------ */
public:
virtual void onBeginningSolveStep(const AnalysisMethod & method);
virtual void onEndSolveStep(const AnalysisMethod & method);
virtual void onDamageIteration();
virtual void onDamageUpdate();
virtual void onDump();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
+
+ AKANTU_GET_MACRO(Name, name, const std::string &);
+
AKANTU_GET_MACRO(Model, *model, const SolidMechanicsModel &)
AKANTU_GET_MACRO(ID, Memory::getID(), const ID &);
AKANTU_GET_MACRO(Rho, rho, Real);
AKANTU_SET_MACRO(Rho, rho, Real);
+ AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
+
/// return the potential energy for the subset of elements contained by the material
Real getPotentialEnergy();
/// return the potential energy for the provided element
Real getPotentialEnergy(ElementType & type, UInt index);
/// return the energy (identified by id) for the subset of elements contained by the material
virtual Real getEnergy(std::string energy_id);
/// return the energy (identified by id) for the provided element
virtual Real getEnergy(std::string energy_id, ElementType type, UInt index);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(GradU, gradu, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(PotentialEnergy, potential_energy, Real);
AKANTU_GET_MACRO(GradU, gradu, const ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO(Stress, stress, const ElementTypeMapArray<Real> &);
AKANTU_GET_MACRO(ElementFilter, element_filter, const ElementTypeMapArray<UInt> &);
+ AKANTU_GET_MACRO(FEEngine, *fem, FEEngine &);
bool isNonLocal() const { return is_non_local; }
- const Array<Real> & getArray(const ID & id, const ElementType & type, const GhostType & ghost_type = _not_ghost) const;
- Array<Real> & getArray(const ID & id, const ElementType & type, const GhostType & ghost_type = _not_ghost);
+ template <typename T>
+ const Array<T> & getArray(const ID & id, const ElementType & type, const GhostType & ghost_type = _not_ghost) const;
+ template <typename T>
+ Array<T> & getArray(const ID & id, const ElementType & type, const GhostType & ghost_type = _not_ghost);
- const InternalField<Real> & getInternal(const ID & id) const;
- InternalField<Real> & getInternal(const ID & id);
+ template <typename T>
+ const InternalField<T> & getInternal(const ID & id) const;
+ template <typename T>
+ InternalField<T> & getInternal(const ID & id);
+ template<typename T>
inline bool isInternal(const ID & id, const ElementKind & element_kind) const;
- inline ElementTypeMap<UInt> getInternalDataPerElem(const ID & id, const ElementKind & element_kind) const;
+
+ template <typename T>
+ ElementTypeMap<UInt> getInternalDataPerElem(const ID & id,
+ const ElementKind & element_kind) const;
bool isFiniteDeformation() const { return finite_deformation; }
bool isInelasticDeformation() const { return inelastic_deformation; }
template <typename T>
inline void setParam(const ID & param, T value);
template <typename T>
inline const T & getParam(const ID & param) const;
+ template <typename T>
void flattenInternal(const std::string & field_id,
- ElementTypeMapArray<Real> & internal_flat,
- const GhostType ghost_type = _not_ghost,
- ElementKind element_kind = _ek_not_defined);
+ ElementTypeMapArray<T> & internal_flat,
+ const GhostType ghost_type = _not_ghost,
+ ElementKind element_kind = _ek_not_defined) const;
+ /// apply a constant eigengrad_u everywhere in the material
+ virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const GhostType = _not_ghost);
protected:
bool isInit() const { return is_init; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
-private:
+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;
- /// eigenstrain arrays ordered by element types
- InternalField<Real> eigenstrain;
+ /// eigengrad_u arrays ordered by element types
+ InternalField<Real> eigengradu;
/// grad_u arrays ordered by element types
InternalField<Real> gradu;
+ /// Green Lagrange strain (Finite deformation)
+ InternalField<Real> green_strain;
+
/// Second Piola-Kirchhoff stress tensor arrays ordered by element types (Finite deformation)
InternalField<Real> piola_kirchhoff_2;
/// potential energy by element
InternalField<Real> potential_energy;
/// tell if using in non local mode or not
bool is_non_local;
/// tell if the material need the previous stress state
bool use_previous_stress;
/// tell if the material need the previous strain state
bool use_previous_gradu;
/// elemental field interpolation coordinates
InternalField<Real> interpolation_inverse_coordinates;
/// elemental field interpolation points
InternalField<Real> interpolation_points_matrices;
-};
-/* -------------------------------------------------------------------------- */
-/* inline functions */
-/* -------------------------------------------------------------------------- */
-
-#include "material_inline_impl.cc"
+ /// vector that contains the names of all the internals that need to
+ /// be transferred when material interfaces move
+ std::vector<ID> internals_to_transfer;
+};
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const Material & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
+#include "material_inline_impl.cc"
+
#include "internal_field_tmpl.hh"
#include "random_internal_field_tmpl.hh"
/* -------------------------------------------------------------------------- */
/* Auto loop */
/* -------------------------------------------------------------------------- */
-
+/// This can be used to automatically write the loop on quadrature points in
+/// functions such as computeStress. This macro in addition to write the loop
+/// provides two tensors (matrices) sigma and grad_u
#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type) \
- Array<Real>::matrix_iterator gradu_it = \
+ 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->spatial_dimension); \
+ Array<Real>::matrix_iterator gradu_end = \
this->gradu(el_type, ghost_type).end(this->spatial_dimension, \
- this->spatial_dimension); \
+ this->spatial_dimension); \
\
this->stress(el_type, \
- ghost_type).resize(this->gradu(el_type, \
- ghost_type).getSize()); \
+ ghost_type).resize(this->gradu(el_type, \
+ ghost_type).getSize()); \
\
- Array<Real>::iterator< Matrix<Real> > stress_it = \
+ 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()); \
+ 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); \
+ 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; \
+ for(;gradu_it != gradu_end; ++gradu_it, ++stress_it) { \
+ Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it; \
Matrix<Real> & __attribute__((unused)) sigma = *stress_it
-#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END \
- } \
+#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END \
+ } \
-#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_mat) \
- Array<Real>::matrix_iterator gradu_it = \
+/// 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->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->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->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; \
+ Array<Real>::matrix_iterator tangent_it = \
+ tangent_mat.begin(tangent_size, \
+ tangent_size); \
+ \
+ for(;gradu_it != gradu_end; ++gradu_it, ++sigma_it, ++tangent_it) { \
+ Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it; \
+ Matrix<Real> & __attribute__((unused)) sigma_tensor = *sigma_it; \
Matrix<Real> & tangent = *tangent_it
-#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END \
+#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END \
} \
/* -------------------------------------------------------------------------- */
-#define INSTANSIATE_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 a399bd902..e9408ba69 100644
--- a/src/model/solid_mechanics/material_inline_impl.cc
+++ b/src/model/solid_mechanics/material_inline_impl.cc
@@ -1,432 +1,461 @@
/**
* @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>
*
* @date creation: Tue Jul 27 2010
* @date last modification: Tue Sep 16 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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) const {
- 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) const {
+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) const {
+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) const {
+ 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) const {
+ 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));
}
-/* ---------------------------------------------------------------------------*/
-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);
-
- //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
- 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
- Stress_vect(dim+i-1, 0) = S_t(dim-i-1, dim-1);
-
- for (UInt i = 2; i < dim; ++i)//term s13 in 3D
- Stress_vect(dim+i, 0) = S_t(0, 1);
-
- AKANTU_DEBUG_OUT();
-}
-
/* -------------------------------------------------------------------------- */
-template<UInt dim>
-inline void Material::setCauchyStressMatrix(const Matrix<Real> & S_t, Matrix<Real> & Stress_matrix) {
-
- AKANTU_DEBUG_IN();
-
- Stress_matrix.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);
- }
- }
- }
-
- //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);
- }*/
+inline Real Material::stressToVonMises(const Matrix<Real> & stress) {
+ // compute deviatoric stress
+ UInt dim = stress.cols();
+ Matrix<Real> deviatoric_stress =
+ Matrix<Real>::eye(dim, -1. * stress.trace() / 3.);
+ for (UInt i = 0; i < dim; ++i)
+ for (UInt j = 0; j < dim; ++j)
+ deviatoric_stress(i, j) += stress(i, j);
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<ElementType type>
-inline void Material::buildElementalFieldInterpolationCoodinates(__attribute__((unused)) const Matrix<Real> & coordinates,
- __attribute__((unused)) Matrix<Real> & coordMatrix) {
- AKANTU_DEBUG_TO_IMPLEMENT();
+ // return Von Mises stress
+ return std::sqrt(3. * deviatoric_stress.doubleDot(deviatoric_stress) / 2.);
}
-/* -------------------------------------------------------------------------- */
-inline void Material::buildElementalFieldInterpolationCoodinatesLinear(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
+/* ---------------------------------------------------------------------------*/
+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
- for (UInt i = 0; i < coordinates.cols(); ++i)
- coordMatrix(i, 0) = 1;
-}
+ /*
+ * 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);
-/* -------------------------------------------------------------------------- */
-inline void Material::buildElementalFieldInterpolationCoodinatesQuadratic(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
+ 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);
- UInt nb_quadrature_points = coordMatrix.cols();
+ for (UInt i = 2; i < dim; ++i) // term s13 in 3D
+ sigma_voight(dim + i, 0) = S_t(0, 1);
- 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);
- }
+ AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_segment_2>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
- buildElementalFieldInterpolationCoodinatesLinear(coordinates, coordMatrix);
-}
+template <UInt dim>
+inline void Material::setCauchyStressMatrix(const Matrix<Real> & S_t,
+ Matrix<Real> & sigma) {
+ AKANTU_DEBUG_IN();
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_segment_3>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
+ sigma.clear();
- buildElementalFieldInterpolationCoodinatesQuadratic(coordinates, coordMatrix);
-}
+ /// 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);
+ }
+ }
+ }
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_triangle_3>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
- buildElementalFieldInterpolationCoodinatesLinear(coordinates, coordMatrix);
+ AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_triangle_6>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
-
- buildElementalFieldInterpolationCoodinatesQuadratic(coordinates, coordMatrix);
-}
+inline Element
+Material::convertToLocalElement(const Element & global_element) const {
+ UInt ge = global_element.element;
+#ifndef AKANTU_NDEBUG
+ UInt model_mat_index = this->model->getMaterialByElement(
+ global_element.type, global_element.ghost_type)(ge);
+ UInt mat_index = this->model->getMaterialIndex(this->name);
+ AKANTU_DEBUG_ASSERT(model_mat_index == mat_index,
+ "Conversion of a global element in a local element for "
+ "the wrong material "
+ << this->name << std::endl);
+#endif
+ UInt le = this->model->getMaterialLocalNumbering(
+ global_element.type, global_element.ghost_type)(ge);
-/* -------------------------------------------------------------------------- */
-template<>
-inline void Material::buildElementalFieldInterpolationCoodinates<_tetrahedron_4>(const Matrix<Real> & coordinates,
- Matrix<Real> & coordMatrix) {
- buildElementalFieldInterpolationCoodinatesLinear(coordinates, coordMatrix);
+ Element tmp_quad(global_element.type, le, global_element.ghost_type,
+ global_element.kind);
+ return tmp_quad;
}
/* -------------------------------------------------------------------------- */
-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
- *
- */
+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);
-/* -------------------------------------------------------------------------- */
-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;
- }
+ Element tmp_quad(local_element.type, ge, local_element.ghost_type,
+ local_element.kind);
+ return tmp_quad;
}
/* -------------------------------------------------------------------------- */
-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 IntegrationPoint
+Material::convertToLocalPoint(const IntegrationPoint & global_point) const {
+ const FEEngine & fem = this->model->getFEEngine();
+ UInt nb_quad = fem.getNbIntegrationPoints(global_point.type);
+ Element el =
+ this->convertToLocalElement(static_cast<const Element &>(global_point));
+ IntegrationPoint tmp_quad(el, global_point.num_point, nb_quad);
+ return tmp_quad;
}
/* -------------------------------------------------------------------------- */
-template<ElementType type>
-inline UInt Material::getSizeElementalFieldInterpolationCoodinates(GhostType ghost_type) {
- return model->getFEEngine().getNbQuadraturePoints(type, ghost_type);
+inline IntegrationPoint
+Material::convertToGlobalPoint(const IntegrationPoint & local_point) const {
+ const FEEngine & fem = this->model->getFEEngine();
+ UInt nb_quad = fem.getNbIntegrationPoints(local_point.type);
+ Element el =
+ this->convertToGlobalElement(static_cast<const Element &>(local_point));
+ IntegrationPoint tmp_quad(el, local_point.num_point, nb_quad);
+ return tmp_quad;
}
/* -------------------------------------------------------------------------- */
inline UInt Material::getNbDataForElements(const Array<Element> & elements,
- SynchronizationTag tag) const {
- if(tag == _gst_smm_stress) {
- return (this->isFiniteDeformation() ? 3 : 1) * spatial_dimension * spatial_dimension *
- sizeof(Real) * this->getModel().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 {
- DataAccessor::packElementalDataHelper<T>(data_to_pack, buffer, elements, true,
- model->getFEEngine(fem_id));
+template <typename T>
+inline void Material::packElementDataHelper(
+ const ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
+ const Array<Element> & elements, const ID & fem_id) const {
+ DataAccessor::packElementalDataHelper<T>(data_to_pack, buffer, elements, true,
+ model->getFEEngine(fem_id));
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-inline void Material::unpackElementDataHelper(ElementTypeMapArray<T> & data_to_unpack,
- CommunicationBuffer & buffer,
- const Array<Element> & elements,
- const ID & fem_id) {
- DataAccessor::unpackElementalDataHelper<T>(data_to_unpack, buffer, elements, true,
- model->getFEEngine(fem_id));
+template <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) {
+ 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) {
+ 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()) return false;
- if (internal_array->second->getElementKind() != element_kind) return false;
+ if (internal_array == internal_vectors_real.end() ||
+ internal_array->second->getElementKind() != element_kind)
+ return false;
return true;
}
/* -------------------------------------------------------------------------- */
+template <typename T>
+inline ElementTypeMap<UInt>
+Material::getInternalDataPerElem(const ID & field_id,
+ const ElementKind & element_kind) const {
-inline ElementTypeMap<UInt> Material::getInternalDataPerElem(const ID & 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);
- std::map<ID, InternalField<Real> *>::const_iterator internal_array =
- internal_vectors_real.find(this->getID()+":"+id);
+ 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();
- if (internal_array == internal_vectors_real.end()) AKANTU_EXCEPTION("cannot find internal " << id);
- if (internal_array->second->getElementKind() != element_kind) AKANTU_EXCEPTION("cannot find internal " << id);
-
- InternalField<Real> & internal = *internal_array->second;
- InternalField<Real>::type_iterator it = internal.firstType(spatial_dimension, _not_ghost,element_kind);
- InternalField<Real>::type_iterator last_type = internal.lastType(spatial_dimension, _not_ghost,element_kind);
+ 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);
- ElementTypeMap<UInt> res;
- for(; it != last_type; ++it) {
- UInt nb_quadrature_points = 0;
- if (element_kind == _ek_regular)
- nb_quadrature_points = model->getFEEngine().getNbQuadraturePoints(*it);
-#if defined(AKANTU_COHESIVE_ELEMENT)
- else if (element_kind == _ek_cohesive)
- nb_quadrature_points = model->getFEEngine("CohesiveFEEngine").getNbQuadraturePoints(*it);
-#endif
- res(*it) = internal.getNbComponent() * nb_quadrature_points;
+ 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;
+ 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 b/src/model/solid_mechanics/material_list.hh
deleted file mode 100644
index 29e21e209..000000000
--- a/src/model/solid_mechanics/material_list.hh
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * @file material_list.hh
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Tue Oct 29 2013
- * @date last modification: Fri Sep 19 2014
- *
- * @brief List of materials and all includes
- *
- * @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_MATERIAL_LIST_HH__
-#define __AKANTU_MATERIAL_LIST_HH__
-
-#include "aka_config.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)))
-
-
-#if defined(AKANTU_EXTRA_MATERIALS)
-# include "material_extra_includes.hh"
-#else
-# define AKANTU_EXTRA_MATERIAL_LIST
-#endif
-
-#if defined(AKANTU_COHESIVE_ELEMENT)
-# include "material_cohesive_includes.hh"
-#else
-# define AKANTU_COHESIVE_MATERIAL_LIST
-#endif
-
-#if defined(AKANTU_DAMAGE_NON_LOCAL)
-# include "material_non_local_includes.hh"
-#else
-# define AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST
-#endif
-
-#if defined(AKANTU_DAMAGE_NON_LOCAL_EXTRA)
-# include "material_non_local_extra_includes.hh"
-#else
-# define AKANTU_DAMAGE_NON_LOCAL_EXTRA_MATERIAL_LIST
-#endif
-
-#define AKANTU_MATERIAL_LIST \
- AKANTU_CORE_MATERIAL_LIST \
- AKANTU_EXTRA_MATERIAL_LIST \
- AKANTU_COHESIVE_MATERIAL_LIST \
- AKANTU_DAMAGE_NON_LOCAL_MATERIAL_LIST \
- AKANTU_DAMAGE_NON_LOCAL_EXTRA_MATERIAL_LIST
-
-#endif /* __AKANTU_MATERIAL_LIST_HH__ */
diff --git a/src/model/solid_mechanics/material_list.hh.in b/src/model/solid_mechanics/material_list.hh.in
new file mode 100644
index 000000000..bb5d70ac3
--- /dev/null
+++ b/src/model/solid_mechanics/material_list.hh.in
@@ -0,0 +1,51 @@
+/**
+ * @file material_list.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Tue Oct 29 2013
+ * @date last modification: Fri Sep 19 2014
+ *
+ * @brief List of materials and all includes
+ *
+ * @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_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_random_internal.hh b/src/model/solid_mechanics/material_random_internal.hh
deleted file mode 100644
index 9ca3dae10..000000000
--- a/src/model/solid_mechanics/material_random_internal.hh
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * @file material_random_internal.hh
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Wed Nov 13 2013
- * @date last modification: Thu Jun 05 2014
- *
- * @brief Class describing a material parameter that can be set depending on a
- * random distribution
- *
- * @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_type_map.hh"
-#include "aka_random_generator.hh"
-
-
-#ifndef __AKANTU_MATERIAL_RANDOM_INTERNAL_HH__
-#define __AKANTU_MATERIAL_RANDOM_INTERNAL_HH__
-
-__BEGIN_AKANTU__
-
-template<typename Distribution, typename Generator = Rand48Generator<Real> >
-class MaterialRandomInternal : public ElementTypeMapArray<Real> {
- /* ------------------------------------------------------------------------ */
- /* Constructors/Destructors */
- /* ------------------------------------------------------------------------ */
-public:
- MaterialRandomInternal(const ID & id, const ID & parent_id,
- const MemoryID & memory_id = 0) :
- ElementTypeMapArray<Real>(id, parent_id, memory_id) {};
-
- virtual ~MaterialRandomInternal();
-
- /* ------------------------------------------------------------------------ */
- /* Methods */
- /* ------------------------------------------------------------------------ */
-public:
-
- /* ------------------------------------------------------------------------ */
- /* Accessors */
- /* ------------------------------------------------------------------------ */
-public:
-
- /* ------------------------------------------------------------------------ */
- /* Class Members */
- /* ------------------------------------------------------------------------ */
-private:
- Distribution distribution;
-};
-
-
-/* -------------------------------------------------------------------------- */
-/* inline functions */
-/* -------------------------------------------------------------------------- */
-//#include "material_random_internal_inline_impl.cc"
-
-
-__END_AKANTU__
-
-#endif /* __AKANTU_MATERIAL_RANDOM_INTERNAL_HH__ */
diff --git a/src/model/solid_mechanics/material_selector.hh b/src/model/solid_mechanics/material_selector.hh
index a71d3a514..48295573c 100644
--- a/src/model/solid_mechanics/material_selector.hh
+++ b/src/model/solid_mechanics/material_selector.hh
@@ -1,100 +1,146 @@
/**
* @file material_selector.hh
*
* @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
*
* @brief class describing how to choose a material for a given element
*
* @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 "mesh.hh"
-
+/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_SELECTOR_HH__
#define __AKANTU_MATERIAL_SELECTOR_HH__
+/* -------------------------------------------------------------------------- */
+
__BEGIN_AKANTU__
class SolidMechanicsModel;
-/* -------------------------------------------------------------------------- */
+/**
+ * main class to assign same or different materials for different
+ * elements
+ */
class MaterialSelector {
public:
MaterialSelector() : fallback_value(0) {}
virtual ~MaterialSelector() {}
virtual UInt operator()(const Element & element) {
return fallback_value;
}
void setFallback(UInt f) { fallback_value = f; }
protected:
UInt fallback_value;
};
/* -------------------------------------------------------------------------- */
+/**
+ * class that assigns the first material to regular elements by default
+ */
class DefaultMaterialSelector : public MaterialSelector {
public:
- DefaultMaterialSelector(const ElementTypeMapArray<UInt> & element_index_by_material) :
- element_index_by_material(element_index_by_material) { }
+ 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> & el_by_mat = element_index_by_material(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 < el_by_mat.getSize())
- mat = el_by_mat(element.element, 0);
+
+ 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> & element_index_by_material;
+ const ElementTypeMapArray<UInt> & material_index;
};
/* -------------------------------------------------------------------------- */
+/**
+ * Use elemental data to assign materials
+ */
template<typename T>
-class MeshDataMaterialSelector : public MaterialSelector {
+class ElementDataMaterialSelector : public MaterialSelector {
public:
- MeshDataMaterialSelector(const std::string & name, const SolidMechanicsModel & model) : mesh_data(name), model(model) { }
- UInt operator() (const Element & element) {
- return 0;
+ ElementDataMaterialSelector(const ElementTypeMapArray<T> & element_data,
+ const SolidMechanicsModel & model,
+ UInt first_index = 1):
+ element_data(element_data),
+ model(model),
+ first_index(first_index)
+ {}
+
+ inline T elementData(const Element & element) {
+ DebugLevel dbl = debug::getDebugLevel();
+ debug::setDebugLevel(dblError);
+ T data = element_data(element.type, element.ghost_type)(element.element);
+ debug::setDebugLevel(dbl);
+ return data;
}
-private:
- std::string mesh_data;
+
+ inline UInt operator() (const Element & element) {
+ return MaterialSelector::operator()(element);
+ }
+
+protected:
+ /// list of element with the specified data (i.e. tag value)
+ const ElementTypeMapArray<T> & element_data;
+
+ /// the model that the materials belong
const SolidMechanicsModel & model;
+
+ /// first material index: equal to 1 if none specified
+ UInt first_index;
+};
+
+/* -------------------------------------------------------------------------- */
+/**
+ * class to use mesh data information to assign different materials
+ * where name is the tag value: tag_0, tag_1
+ */
+template<typename T>
+class MeshDataMaterialSelector : public ElementDataMaterialSelector<T> {
+public:
+ MeshDataMaterialSelector(const std::string & name, const SolidMechanicsModel & model, UInt first_index = 1);
};
__END_AKANTU__
#endif /* __AKANTU_MATERIAL_SELECTOR_HH__ */
diff --git a/src/model/solid_mechanics/material_selector_tmpl.hh b/src/model/solid_mechanics/material_selector_tmpl.hh
index ff4394841..35dbdf388 100644
--- a/src/model/solid_mechanics/material_selector_tmpl.hh
+++ b/src/model/solid_mechanics/material_selector_tmpl.hh
@@ -1,89 +1,70 @@
/**
* @file material_selector_tmpl.hh
*
* @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: Fri May 1 2015
*
* @brief Implementation of the template MaterialSelector
*
* @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_MATERIAL_SELECTOR_TMPL_HH__
#define __AKANTU_MATERIAL_SELECTOR_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-template<>
-class MeshDataMaterialSelector<std::string> : public MaterialSelector {
-public:
- MeshDataMaterialSelector(const std::string & name, const SolidMechanicsModel & model) :
- names(model.getMesh().getData<std::string>(name)), model(model) { }
- UInt operator() (const Element & element) {
- try {
- DebugLevel dbl = debug::getDebugLevel();
- debug::setDebugLevel(dblError);
- std::string material_name = names(element.type, element.ghost_type)(element.element);
- debug::setDebugLevel(dbl);
+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)
+{}
- return model.getMaterialIndex(material_name);
- } catch (...) {
- return MaterialSelector::operator()(element);
- }
+/* -------------------------------------------------------------------------- */
+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);
}
-
-private:
- const ElementTypeMapArray<std::string> & names;
-protected:
- const SolidMechanicsModel & model;
-};
+}
/* -------------------------------------------------------------------------- */
template<>
-class MeshDataMaterialSelector<UInt> : public MaterialSelector {
-public:
- MeshDataMaterialSelector(const std::string & name, const SolidMechanicsModel & model, UInt first_index = 1) :
- indexes(model.getMesh().getData<UInt>(name)), model(model), first_index(first_index) { }
- UInt operator() (const Element & element) {
- try {
- DebugLevel dbl = debug::getDebugLevel();
- debug::setDebugLevel(dblError);
- UInt mat = indexes(element.type, element.ghost_type)(element.element) - first_index;
- debug::setDebugLevel(dbl);
- return mat;
- } catch (...) {
- return MaterialSelector::operator()(element);
- }
+inline UInt ElementDataMaterialSelector<UInt>::operator() (const Element & element) {
+ try {
+ return this->elementData(element) - first_index;
+ } catch (...) {
+ return MaterialSelector::operator()(element);
}
-protected:
- const ElementTypeMapArray<UInt> indexes;
- const SolidMechanicsModel & model;
- UInt first_index;
-};
-
+}
__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 5c05a641c..4afe99c2a 100644
--- a/src/model/solid_mechanics/materials/internal_field.hh
+++ b/src/model/solid_mechanics/materials/internal_field.hh
@@ -1,191 +1,256 @@
/**
* @file internal_field.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Nov 13 2013
* @date last modification: Tue Sep 02 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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();
-protected:
+ /// This constructor is only here to let cohesive elements compile
InternalField(const ID & id, Material & material, FEEngine & fem,
- const ElementTypeMapArray<UInt> & element_filter);
+ const ElementTypeMapArray<UInt> & element_filter);
+
+ /// More general constructor
+ InternalField(const ID & id, Material & material, UInt dim, FEEngine & fem,
+ const ElementTypeMapArray<UInt> & element_filter);
InternalField(const ID & id, const InternalField<T> & other);
private:
- InternalField operator=(__attribute__((unused)) const InternalField & other) {};
+ 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; }
+
+ 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;};
-
+ const ElementKind & getElementKind() const { return element_kind; }
/// return the number of components
- UInt getNbComponent(){return nb_component;}
+ UInt getNbComponent() const { return nb_component; }
+
+ /// return the spatial dimension corresponding to the internal element type
+ /// loop filter
+ UInt getSpatialDimension() const { return this->spatial_dimension; }
+
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the material for which this is an internal parameter
Material & material;
/// the fem containing the mesh and the element informations
- FEEngine & fem;
+ 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 d4cd52b32..61fff3d1f 100644
--- a/src/model/solid_mechanics/materials/internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/internal_field_tmpl.hh
@@ -1,298 +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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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.getModel().getSpatialDimension()),
- element_kind(_ek_regular),
- nb_component(0),
- is_init(false),
- previous_values(NULL) {
-}
+template <typename T>
+InternalField<T>::InternalField(
+ const ID & id, Material & material, FEEngine & fem,
+ const ElementTypeMapArray<UInt> & element_filter)
+ : ElementTypeMapArray<T>(id, material.getID(), material.getMemoryID()),
+ material(material), fem(&fem), element_filter(element_filter),
+ default_value(T()), spatial_dimension(material.getSpatialDimension()),
+ element_kind(_ek_regular), nb_component(0), is_init(false),
+ previous_values(NULL) {}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
+InternalField<T>::InternalField(
+ const ID & id, Material & material, UInt dim, FEEngine & fem,
+ const ElementTypeMapArray<UInt> & element_filter)
+ : ElementTypeMapArray<T>(id, material.getID(), material.getMemoryID()),
+ material(material), fem(&fem), element_filter(element_filter),
+ default_value(T()), spatial_dimension(dim), element_kind(_ek_regular),
+ nb_component(0), is_init(false), previous_values(NULL) {}
/* -------------------------------------------------------------------------- */
-template<typename T>
-InternalField<T>::InternalField(const ID & id, const InternalField<T> & other) :
- ElementTypeMapArray<T>(id, other.material.getID(), other.material.getMemoryID()),
- material(other.material),
- fem(other.fem),
- element_filter(other.element_filter),
- default_value(other.default_value),
- spatial_dimension(other.spatial_dimension),
- element_kind(other.element_kind),
- nb_component(other.nb_component),
- is_init(false),
- previous_values(NULL) {
-
- AKANTU_DEBUG_ASSERT(other.is_init, "Cannot create a copy of a non initialized field");
+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>::initialize(UInt nb_component) {
+template <typename T> void InternalField<T>::setFEEngine(FEEngine & fe_engine) {
+ this->fem = &fe_engine;
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
+void InternalField<T>::setElementKind(ElementKind element_kind) {
+ this->element_kind = element_kind;
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T> void InternalField<T>::initialize(UInt nb_component) {
internalInitialize(nb_component);
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-void InternalField<T>::initializeHistory() {
- if(!previous_values)
+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, unsigned int 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 {
+ 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..926073b60 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,69 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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/constitutive_laws/material_cohesive_bilinear.cc b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_bilinear.cc
index 5927ebfca..55afde9c6 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,210 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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, 0.,
+ 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];
+ Vector<Real> sigma_c_vec = sigma_c_begin[index];
Array<Real>::vector_iterator delta_c_begin
- = this->delta_c(type).begin_reinterpret(nb_quad_per_element, nb_element);
- Vector<Real> & delta_c_vec = delta_c_begin[index];
+ = 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_cI / sigma_c_vec(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(el_type, ghost_type).begin();
+ = 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), 0.);
- *damage_it = std::min(*damage_it, 1.);
+ *damage_it = std::max((*delta_max_it - delta_0) / (*delta_c_it - delta_0), Real(0.));
+ *damage_it = std::min(*damage_it, Real(1.));
}
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialCohesiveBilinear);
+INSTANTIATE_MATERIAL(MaterialCohesiveBilinear);
__END_AKANTU__
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 c755e58f9..7b3b59faa 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,363 +1,362 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 , 0. , _pat_parsable, "Beta parameter" );
- this->registerParam("delta_c", delta_c, 0. , _pat_parsable, "Critical displacement" );
+ 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, 1.0,
+ this->registerParam("contact_tangent", contact_tangent, Real(1.0),
_pat_parsable, "Ratio of contact tangent over the initial exponential tangent" );
// this->initInternalArray(delta_max, 1, _ek_cohesive);
use_previous_delta_max=true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialCohesive::initMaterial();
if ((exp_penalty)&&(contact_tangent!=1)){
contact_tangent = 1;
AKANTU_DEBUG_WARNING("The parsed paramter <contact_tangent> is forced to 1.0 when the contact penalty follows the exponential law");
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeTraction(const Array<Real> & normal,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
/// define iterators
Array<Real>::vector_iterator traction_it =
tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator opening_it =
opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::const_vector_iterator normal_it =
normal.begin(spatial_dimension);
Array<Real>::vector_iterator traction_end =
tractions(el_type, ghost_type).end(spatial_dimension);
Array<Real>::iterator<Real> delta_max_it =
delta_max(el_type, ghost_type).begin();
Array<Real>::iterator<Real> delta_max_prev_it =
delta_max.previous(el_type, ghost_type).begin();
/// compute scalars
Real beta2 = beta*beta;
/// loop on each quadrature point
for (; traction_it != traction_end;
++traction_it, ++opening_it, ++normal_it, ++delta_max_it, ++delta_max_prev_it) {
/// compute normal and tangential opening vectors
Real normal_opening_norm = opening_it->dot(*normal_it);
Vector<Real> normal_opening(spatial_dimension);
normal_opening = (*normal_it);
normal_opening *= normal_opening_norm;
Vector<Real> tangential_opening(spatial_dimension);
tangential_opening = *opening_it;
tangential_opening -= normal_opening;
Real tangential_opening_norm = tangential_opening.norm();
/**
* compute effective opening displacement
* @f$ \delta = \sqrt{
* \beta^2 \Delta_t^2 + \Delta_n^2 } @f$
*/
Real delta = tangential_opening_norm;
delta *= delta * beta2;
delta += normal_opening_norm * normal_opening_norm;
delta = sqrt(delta);
if ((normal_opening_norm<0) && (std::abs(normal_opening_norm) > Math::getTolerance())) {
Vector<Real> op_n(*opening_it);
op_n *= *normal_it;
Vector<Real> delta_s(*opening_it);
delta_s -= op_n;
delta = tangential_opening_norm*beta;
computeCoupledTraction(*traction_it, *normal_it, delta, delta_s,
*delta_max_it, *delta_max_prev_it);
computeCompressiveTraction(*traction_it, *normal_it, normal_opening_norm,
*opening_it);
}
else computeCoupledTraction(*traction_it, *normal_it, delta, *opening_it,
*delta_max_it, *delta_max_prev_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTraction(Vector<Real> & tract,
const Vector<Real> & normal,
Real delta,
const Vector<Real> & opening,
Real & delta_max_new,
Real delta_max) {
AKANTU_DEBUG_IN();
/// full damage case
if (std::abs(delta) < Math::getTolerance()) {
/// set traction to zero
tract.clear();
} else { /// element not fully damaged
/**
* Compute traction loading @f$ \mathbf{T} =
* e \sigma_c \frac{\delta}{\delta_c} e^{-\delta/ \delta_c}@f$
*/
/**
* Compute traction unloading @f$ \mathbf{T} =
* \frac{t_{max}}{\delta_{max}} \delta @f$
*/
Real beta2 = beta*beta;
Vector<Real> op_n_n(opening);
op_n_n*=normal;
op_n_n*=(1-beta2);
op_n_n*=normal;
tract = beta2*opening;
tract += op_n_n;
delta_max_new = std::max(delta_max, delta);
tract *= exp(1)*sigma_c*exp(- delta_max_new / delta_c)/delta_c;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCompressiveTraction(Vector<Real> & tract,
const Vector<Real> & normal,
Real delta_n,
const Vector<Real> & opening) {
Vector<Real> temp_tract(normal);
if(exp_penalty) {
temp_tract *= delta_n*exp(1)*sigma_c*exp(- delta_n / delta_c)/delta_c;
}
else {
Real initial_tg = contact_tangent*exp(1)*sigma_c*delta_n/delta_c;
temp_tract *= initial_tg;
}
tract += temp_tract;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeTangentTraction(const ElementType & el_type,
Array<Real> & tangent_matrix,
const Array<Real> & normal,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::matrix_iterator tangent_it = tangent_matrix.begin(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator tangent_end = tangent_matrix.end(spatial_dimension, spatial_dimension);
Array<Real>::const_vector_iterator normal_it = normal.begin(spatial_dimension);
Array<Real>::vector_iterator opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::vector_iterator traction_it = tractions(el_type, ghost_type).begin(spatial_dimension);
Array<Real>::iterator<Real>delta_max_it = delta_max.previous(el_type, ghost_type).begin();
Real beta2 = beta*beta;
/**
* compute tangent matrix @f$ \frac{\partial \mathbf{t}}
* {\partial \delta} = \hat{\mathbf{t}} \otimes
* \frac{\partial (t/\delta)}{\partial \delta}
* \frac{\hat{\mathbf{t}}}{\delta}+ \frac{t}{\delta} [ \beta^2 \mathbf{I} +
* (1-\beta^2) (\mathbf{n} \otimes \mathbf{n})] @f$
**/
/**
* In which @f$
* \frac{\partial(t/ \delta)}{\partial \delta} =
* \left\{\begin{array} {l l}
* -e \frac{\sigma_c}{\delta_c^2 }e^{-\delta / \delta_c} & \quad if
* \delta \geq \delta_{max} \\
* 0 & \quad if \delta < \delta_{max}, \delta_n > 0
* \end{array}\right. @f$
**/
for (; tangent_it != tangent_end; ++tangent_it, ++normal_it, ++opening_it, ++traction_it, ++ delta_max_it) {
Real normal_opening_norm = opening_it->dot(*normal_it);
Vector<Real> normal_opening(spatial_dimension);
normal_opening = (*normal_it);
normal_opening *= normal_opening_norm;
Vector<Real> tangential_opening(spatial_dimension);
tangential_opening = *opening_it;
tangential_opening -= normal_opening;
Real tangential_opening_norm = tangential_opening.norm();
Real delta = tangential_opening_norm;
delta *= delta * beta2;
delta += normal_opening_norm * normal_opening_norm;
delta = sqrt(delta);
if ((normal_opening_norm<0) && (std::abs(normal_opening_norm) > Math::getTolerance())) {
Vector<Real> op_n(*opening_it);
op_n *= *normal_it;
Vector<Real> delta_s(*opening_it);
delta_s -= op_n;
delta = tangential_opening_norm*beta;
computeCoupledTangent(*tangent_it, *traction_it, *normal_it, delta,
delta_s, *delta_max_it);
computeCompressivePenalty(*tangent_it, *normal_it, normal_opening_norm);
}
else computeCoupledTangent(*tangent_it, *traction_it, *normal_it, delta,
*opening_it, *delta_max_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTangent(Matrix<Real> & tangent,
Vector<Real> tract,
const Vector<Real> & normal,
Real delta,
const Vector<Real> & opening,
Real delta_max_new) {
AKANTU_DEBUG_IN();
Real beta2 = beta*beta;
Matrix<Real> I(spatial_dimension, spatial_dimension);
I.eye(beta2);
Matrix<Real> nn(spatial_dimension, spatial_dimension);
nn.outerProduct(normal, normal);
nn *= (1-beta2);
I += nn;
if(std::abs(delta) < Math::getTolerance()){
I *= exp(1)*sigma_c/delta_c;
tangent += I;
} else {
Real traction_norm = tract.norm();
Vector<Real> t_hat(opening);
Vector<Real> beta2delta(opening);
beta2delta *= beta2;
t_hat *= normal;
t_hat *= (beta2-1);
t_hat *= normal;
t_hat += beta2delta;
Vector<Real> deriv_t_hat(t_hat);
deriv_t_hat /= delta;
Real derivatives = 0;
if ((delta > delta_max_new) || (std::abs(delta - delta_max_new) < 1e-12)) {
derivatives = -exp(1- delta/delta_c)*sigma_c/(delta_c*delta_c);
}
deriv_t_hat *= derivatives;
Matrix<Real> t_var_t(spatial_dimension, spatial_dimension);
t_var_t.outerProduct(t_hat, deriv_t_hat);
I *= traction_norm / delta;
tangent += t_var_t;
tangent += I;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveExponential<spatial_dimension>::computeCompressivePenalty(Matrix<Real> & tangent,
const Vector<Real> & normal,
Real delta_n) {
if (!exp_penalty) delta_n=0;
Matrix<Real> n_outer_n(spatial_dimension,spatial_dimension);
n_outer_n.outerProduct(normal,normal);
Real normal_tg = contact_tangent*exp(1)*sigma_c*exp(-delta_n/delta_c)*(1-delta_n/delta_c)/delta_c;
n_outer_n *= normal_tg;
tangent += n_outer_n;
}
-INSTANSIATE_MATERIAL(MaterialCohesiveExponential);
+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 03a8d2fc0..6bfdb33d3 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,129 +1,126 @@
/**
* @file material_cohesive_exponential.hh
*
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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;
- /// critical displacement
- Real delta_c;
-
/// 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 78b4687ac..325b064e9 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,503 +1,753 @@
/**
* @file material_cohesive_linear.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
*
* @date creation: Tue May 08 2012
- * @date last modification: Thu Aug 07 2014
+ * @date last modification: Thu Nov 19 2015
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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) :
+ const ID & id) :
MaterialCohesive(model,id),
sigma_c_eff("sigma_c_eff", *this),
- delta_c("delta_c", *this),
- insertion_stress("insertion_stress", *this) {
+ delta_c_eff("delta_c_eff", *this),
+ insertion_stress("insertion_stress", *this),
+ opening_prec("opening_prec", *this),
+ residual_sliding("residual_sliding", *this),
+ friction_force("friction_force", *this),
+ reduction_penalty("reduction_penalty", *this) {
AKANTU_DEBUG_IN();
- this->registerParam("beta" , beta , 0. ,
- _pat_parsable | _pat_readable,
- "Beta parameter" );
- this->registerParam("G_cI" , G_cI , 0. ,
- _pat_parsable | _pat_readable,
- "Mode I fracture energy" );
- this->registerParam("G_cII" , G_cII , 0. ,
- _pat_parsable | _pat_readable,
- "Mode II fracture energy");
- this->registerParam("penalty", penalty, 0. ,
+ this->registerParam("beta", beta, Real(0.),
+ _pat_parsable | _pat_readable,
+ "Beta parameter");
+
+ this->registerParam("G_c", G_c, Real(0.),
+ _pat_parsable | _pat_readable,
+ "Mode I fracture energy");
+
+ this->registerParam("penalty", penalty, Real(0.),
+ _pat_parsable | _pat_readable,
+ "Penalty coefficient");
+
+ this->registerParam("volume_s", volume_s, Real(0.),
+ _pat_parsable | _pat_readable,
+ "Reference volume for sigma_c scaling");
+
+ this->registerParam("m_s", m_s, Real(1.),
+ _pat_parsable | _pat_readable,
+ "Weibull exponent for sigma_c scaling");
+
+ this->registerParam("kappa", kappa, Real(1.),
+ _pat_parsable | _pat_readable,
+ "Kappa parameter");
+
+ this->registerParam("contact_after_breaking", contact_after_breaking, false,
_pat_parsable | _pat_readable,
- "Penalty coefficient" );
- this->registerParam("volume_s", volume_s, 0. ,
+ "Activation of contact when the elements are fully damaged");
+
+ this->registerParam("max_quad_stress_insertion", max_quad_stress_insertion, false,
_pat_parsable | _pat_readable,
- "Reference volume for sigma_c scaling");
- this->registerParam("m_s", m_s, 1. ,
+ "Insertion of cohesive element when stress is high enough just on one quadrature point");
+
+ this->registerParam("friction", friction, false,
_pat_parsable | _pat_readable,
- "Weibull exponent for sigma_c scaling");
- this->registerParam("kappa" , kappa , 1. , _pat_readable, "Kappa parameter");
+ "Activation of friction in case of contact");
+
+ this->registerParam("mu", mu_max, Real(0.),
+ _pat_parsable | _pat_readable,
+ "Maximum value of the friction coefficient");
+
+ this->registerParam("penalty_for_friction", friction_penalty, Real(0.),
+ _pat_parsable | _pat_readable,
+ "Penalty parameter for the friction behavior");
+
+ this->registerParam("recompute", recompute, false,
+ _pat_parsable | _pat_modifiable,
+ "recompute solution");
+
+ this->use_previous_delta_max = true;
+ this->use_previous_opening = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialCohesive::initMaterial();
- if (G_cII != 0)
- kappa = G_cII / G_cI;
-
/// compute scalars
beta2_kappa2 = beta * beta/kappa/kappa;
beta2_kappa = beta * beta/kappa;
- if (beta == 0)
+ if (Math::are_float_equal(beta, 0))
beta2_inv = 0;
else
beta2_inv = 1./beta/beta;
- sigma_c_eff .initialize( 1);
- delta_c .initialize( 1);
+ sigma_c_eff.initialize(1);
+ delta_c_eff.initialize(1);
insertion_stress.initialize(spatial_dimension);
+ opening_prec.initialize(spatial_dimension);
+ friction_force.initialize(spatial_dimension);
+ residual_sliding.initialize(1);
+ reduction_penalty.initialize(1);
+
+ if (!Math::are_float_equal(delta_c, 0.))
+ delta_c_eff.setDefaultValue(delta_c);
+ else
+ delta_c_eff.setDefaultValue(2 * G_c / sigma_c);
if (model->getIsExtrinsic()) scaleInsertionTraction();
+ residual_sliding.initializeHistory();
+ opening_prec.initializeHistory();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialCohesiveLinear<spatial_dimension>::scaleInsertionTraction() {
AKANTU_DEBUG_IN();
// do nothing if volume_s hasn't been specified by the user
if (Math::are_float_equal(volume_s, 0.)) return;
const Mesh & mesh_facets = model->getMeshFacets();
const FEEngine & fe_engine = model->getFEEngine();
const FEEngine & fe_engine_facet = model->getFEEngine("FacetsFEEngine");
// loop over facet type
Mesh::type_iterator first = mesh_facets.firstType(spatial_dimension - 1);
Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1);
Real base_sigma_c = sigma_c;
for(;first != last; ++first) {
ElementType type_facet = *first;
const Array< std::vector<Element> > & facet_to_element
= mesh_facets.getElementToSubelement(type_facet);
UInt nb_facet = facet_to_element.getSize();
- UInt nb_quad_per_facet = fe_engine_facet.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;
+ if (*elem == ElementNull) continue;
- // unit vector for integration in order to obtain the volume
- UInt nb_quadrature_points = fe_engine.getNbQuadraturePoints(elem->type);
- Vector<Real> unit_vector(nb_quadrature_points, 1);
+ // unit vector for integration in order to obtain the volume
+ UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(elem->type);
+ Vector<Real> unit_vector(nb_quadrature_points, 1);
- volume += fe_engine.integrate(unit_vector, elem->type,
- elem->element, elem->ghost_type);
+ 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() {
+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(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;
-
- UInt tot_nb_quad = nb_facet * nb_quad_facet;
-
- Array<Real> stress_check (tot_nb_quad);
- Array<Real> normal_traction(tot_nb_quad, spatial_dimension);
-
- computeStressNorms(f_stress, stress_check, normal_traction, type_facet);
-
- Array<Real>::iterator<Vector<Real> > stress_check_it =
- stress_check.begin_reinterpret(nb_quad_facet, nb_facet);
- Array<Real>::iterator<Matrix<Real> > normal_traction_it =
- normal_traction.begin_reinterpret(nb_quad_facet, spatial_dimension, nb_facet);
+ // if (nb_facet == 0) continue;
Array<Real>::const_iterator<Real> sigma_lim_it = sigma_lim.begin();
- for (UInt f = 0; f < nb_facet; ++f, ++sigma_lim_it, ++stress_check_it,
- ++normal_traction_it) {
+ Matrix<Real> stress_tmp(spatial_dimension, spatial_dimension);
+ Matrix<Real> normal_traction(spatial_dimension, nb_quad_facet);
+ Vector<Real> stress_check(nb_quad_facet);
+ UInt sp2 = spatial_dimension * spatial_dimension;
+
+ const Array<Real> & tangents = model->getTangents(type_facet);
+ const Array<Real> & normals
+ = model->getFEEngine("FacetsFEEngine").getNormalsOnIntegrationPoints(type_facet);
+ Array<Real>::const_vector_iterator normal_begin = normals.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator tangent_begin = tangents.begin(tangents.getNbComponent());
+ Array<Real>::const_matrix_iterator facet_stress_begin =
+ f_stress.begin(spatial_dimension, spatial_dimension * 2);
+
+ std::vector<Real> new_sigmas;
+ std::vector< Vector<Real> > new_normal_traction;
+ std::vector<Real> new_delta_c;
+
+ // loop over each facet belonging to this material
+ for (UInt f = 0; f < nb_facet; ++f, ++sigma_lim_it) {
UInt facet = f_filter(f);
+ // skip facets where check shouldn't be realized
if (!facets_check(facet)) continue;
- Real mean_stress = std::accumulate(stress_check_it->storage(),
- stress_check_it->storage() + nb_quad_facet,
- 0.);
- mean_stress /= nb_quad_facet;
+ // 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];
- if (mean_stress > (*sigma_lim_it - tolerance)) {
- f_insertion(facet) = true;
+ // compute average stress on the current quadrature point
+ Matrix<Real> stress_1(facet_stress_it.storage(),
+ spatial_dimension,
+ spatial_dimension);
- for (UInt q = 0; q < nb_quad_facet; ++q) {
- Real new_sigma = (*stress_check_it)(q);
- Real new_delta = 2 * G_cI / new_sigma;
+ Matrix<Real> stress_2(facet_stress_it.storage() + sp2,
+ spatial_dimension,
+ spatial_dimension);
- Vector<Real> ins_s(normal_traction_it->storage() + q * spatial_dimension,
- spatial_dimension);
+ stress_tmp.copy(stress_1);
+ stress_tmp += stress_2;
+ stress_tmp /= 2.;
- if (spatial_dimension != 3)
- ins_s *= -1.;
+ Vector<Real> normal_traction_vec(normal_traction(q));
- sig_c_eff.push_back(new_sigma);
- del_c.push_back(new_delta);
- ins_stress.push_back(ins_s);
- trac_old.push_back(ins_s);
- }
+ // compute normal and effective stress
+ stress_check(q) = computeEffectiveNorm(stress_tmp, normal, tangent,
+ normal_traction_vec);
+ }
- #if defined (AKANTU_DEBUG_TOOLS) && defined(AKANTU_CORE_CXX11)
- debug::element_manager.print(debug::_dm_material_cohesive,
- [facet, type_facet, nb_quad_facet, &f_stress](const Element & el)->std::string {
- std::stringstream sout;
- Element facet_el(type_facet, facet, _not_ghost);
- if(facet_el == el) {
- Array<Real>::const_iterator< Vector<Real> > stress = f_stress.begin(f_stress.getNbComponent());
- stress += nb_quad_facet * facet;
- for (UInt qs = 0; qs < nb_quad_facet; ++qs, ++stress) {
- sout << *stress;
- }
- }
- return sout.str();
- });
- #endif
+ // verify if the effective stress overcomes the threshold
+ Real final_stress = stress_check.mean();
+ if (max_quad_stress_insertion)
+ final_stress = *std::max_element(stress_check.storage(),
+ stress_check.storage() + nb_quad_facet);
+
+ if (final_stress > (*sigma_lim_it - tolerance)) {
+
+ if (model->isExplicit()){
+ f_insertion(facet) = true;
+
+ if (!check_only) {
+ // store the new cohesive material parameters for each quadrature point
+ for (UInt q = 0; q < nb_quad_facet; ++q) {
+ Real new_sigma = stress_check(q);
+ Vector<Real> normal_traction_vec(normal_traction(q));
+
+ if (spatial_dimension != 3)
+ normal_traction_vec *= -1.;
+
+ new_sigmas.push_back(new_sigma);
+ new_normal_traction.push_back(normal_traction_vec);
+
+ Real new_delta;
+
+ // set delta_c in function of G_c or a given delta_c value
+ if (Math::are_float_equal(delta_c, 0.))
+ new_delta = 2 * G_c / new_sigma;
+ else
+ new_delta = (*sigma_lim_it) / new_sigma * delta_c;
+
+ new_delta_c.push_back(new_delta);
+ }
+ }
+
+ }else{
+ Real ratio = final_stress/(*sigma_lim_it);
+ if (ratio > max_ratio){
+ ++nn;
+ max_ratio = ratio;
+ index_f = f;
+ index_filter = f_filter(f);
+ }
+ }
}
}
- }
- AKANTU_DEBUG_OUT();
-}
+ /// 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);
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension>
-inline void MaterialCohesiveLinear<spatial_dimension>::computeEffectiveNorm(const Matrix<Real> & stress,
- const Vector<Real> & normal,
- const Vector<Real> & tangent,
- Vector<Real> & normal_traction,
- Real & effective_norm) {
- AKANTU_DEBUG_IN();
+ Array<Real>::scalar_iterator it = std::max_element(abs_max.begin(), abs_max.end());
+ Int pos = it - abs_max.begin();
- normal_traction.mul<false>(stress, normal);
+ if (pos != comm.whoAmI()) {
+ AKANTU_DEBUG_OUT();
+ return;
+ }
- Real normal_contrib = normal_traction.dot(normal);
+ if (nn) {
+ f_insertion(index_filter) = true;
- /// in 3D tangential components must be summed
- Real tangent_contrib = 0;
+ 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();
- if (spatial_dimension == 2) {
- Real tangent_contrib_tmp = normal_traction.dot(tangent);
- tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
- }
- else if (spatial_dimension == 3) {
- for (UInt s = 0; s < spatial_dimension - 1; ++s) {
- const Vector<Real> tangent_v(tangent.storage() + s * spatial_dimension,
- spatial_dimension);
- Real tangent_contrib_tmp = normal_traction.dot(tangent_v);
- tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
- }
- }
+ for (UInt q = 0; q < nb_quad_facet; ++q) {
- tangent_contrib = std::sqrt(tangent_contrib);
+ // Vector<Real> ins_s(normal_traction_it[index_f].storage() + q * spatial_dimension,
+ // spatial_dimension);
- normal_contrib = std::max(0., normal_contrib);
+ 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);
+ }
+
+ }
+ }
+ }
- effective_norm = std::sqrt(normal_contrib * normal_contrib
- + tangent_contrib * tangent_contrib * beta2_inv);
+ // 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>::computeStressNorms(const Array<Real> & facet_stress,
- Array<Real> & stress_check,
- Array<Real> & normal_traction,
- ElementType type_facet) {
+void MaterialCohesiveLinear<spatial_dimension>::computeTraction(const Array<Real> & normal,
+ ElementType el_type,
+ GhostType ghost_type) {
AKANTU_DEBUG_IN();
- Array<bool> & facets_check = model->getElementInserter().getCheckFacets(type_facet);
- Array<UInt> & f_filter = facet_filter(type_facet);
+ /// 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);
- UInt nb_quad_facet = model->getFEEngine("FacetsFEEngine").getNbQuadraturePoints(type_facet);
+ Array<Real>::vector_iterator opening_prev_it =
+ opening.previous(el_type, ghost_type).begin(spatial_dimension);
- const Array<Real> & tangents = model->getTangents(type_facet);
- const Array<Real> & normals
- = model->getFEEngine("FacetsFEEngine").getNormalsOnQuadPoints(type_facet);
+ Array<Real>::vector_iterator opening_prec_it =
+ opening_prec(el_type, ghost_type).begin(spatial_dimension);
- Real * stress_check_it = stress_check.storage();
+ Array<Real>::vector_iterator contact_traction_it =
+ contact_tractions(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator contact_opening_it =
+ contact_opening(el_type, ghost_type).begin(spatial_dimension);
- Array<Real>::const_iterator< Vector<Real> > normal_begin =
- normals.begin(spatial_dimension);
+ Array<Real>::const_vector_iterator normal_it =
+ normal.begin(spatial_dimension);
- Array<Real>::const_iterator< Vector<Real> > tangent_begin =
- tangents.begin(tangents.getNbComponent());
+ Array<Real>::vector_iterator traction_end =
+ tractions(el_type, ghost_type).end(spatial_dimension);
- Array<Real>::const_iterator< Matrix<Real> > facet_stress_begin =
- facet_stress.begin(spatial_dimension, spatial_dimension * 2);
+ Array<Real>::scalar_iterator sigma_c_it =
+ sigma_c_eff(el_type, ghost_type).begin();
- Array<Real>::iterator<Vector<Real> > normal_traction_it =
- normal_traction.begin(spatial_dimension);
+ Array<Real>::scalar_iterator delta_max_it =
+ delta_max(el_type, ghost_type).begin();
- Matrix<Real> stress_tmp(spatial_dimension, spatial_dimension);
- UInt nb_facet = f_filter.getSize();
- UInt sp2 = spatial_dimension * spatial_dimension;
- UInt * current_facet = f_filter.storage();
+ Array<Real>::scalar_iterator delta_max_prev_it =
+ delta_max.previous(el_type, ghost_type).begin();
- for (UInt f = 0; f < nb_facet; ++f, ++current_facet) {
+ Array<Real>::scalar_iterator delta_c_it =
+ delta_c_eff(el_type, ghost_type).begin();
- if (!facets_check(*current_facet)) {
- stress_check_it += nb_quad_facet;
- normal_traction_it += nb_quad_facet;
- continue;
- }
+ Array<Real>::scalar_iterator damage_it =
+ damage(el_type, ghost_type).begin();
- UInt current_quad = *current_facet * nb_quad_facet;
+ Array<Real>::vector_iterator insertion_stress_it =
+ insertion_stress(el_type, ghost_type).begin(spatial_dimension);
- for (UInt q = 0; q < nb_quad_facet; ++q, ++stress_check_it,
- ++normal_traction_it, ++current_quad) {
+ Array<Real>::scalar_iterator res_sliding_it =
+ residual_sliding(el_type, ghost_type).begin();
- 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];
+ Array<Real>::scalar_iterator res_sliding_prev_it =
+ residual_sliding.previous(el_type, ghost_type).begin();
- /// compute average stress
- Matrix<Real> stress_1(facet_stress_it.storage(),
- spatial_dimension,
- spatial_dimension);
+ Array<Real>::vector_iterator friction_force_it =
+ friction_force(el_type, ghost_type).begin(spatial_dimension);
- Matrix<Real> stress_2(facet_stress_it.storage() + sp2,
- spatial_dimension,
- spatial_dimension);
+ Array<bool>::scalar_iterator reduction_penalty_it =
+ reduction_penalty(el_type, ghost_type).begin();
- stress_tmp.copy(stress_1);
- stress_tmp += stress_2;
- stress_tmp /= 2.;
+ Vector<Real> normal_opening(spatial_dimension);
+ Vector<Real> tangential_opening(spatial_dimension);
- /// compute normal, tangential and effective stress
- computeEffectiveNorm(stress_tmp, normal, tangent,
- *normal_traction_it, *stress_check_it);
- }
+ if (! this->model->isExplicit())
+ this->delta_max(el_type, ghost_type).copy(this->delta_max.previous(el_type, ghost_type));
+
+ /// loop on each quadrature point
+ for (; traction_it != traction_end;
+ ++traction_it, ++opening_it, ++opening_prec_it,
+ ++normal_it, ++sigma_c_it, ++delta_max_it, ++delta_c_it, ++damage_it,
+ ++contact_traction_it, ++insertion_stress_it, ++contact_opening_it,
+ ++delta_max_prev_it, ++reduction_penalty_it) {
+
+ Real normal_opening_norm, tangential_opening_norm;
+ bool penetration;
+ Real current_penalty = 0.;
+ this->computeTractionOnQuad(*traction_it,
+ *delta_max_it,
+ *delta_max_prev_it,
+ *delta_c_it,
+ *insertion_stress_it,
+ *sigma_c_it,
+ *opening_it,
+ *opening_prec_it,
+ *normal_it,
+ normal_opening,
+ tangential_opening,
+ normal_opening_norm,
+ tangential_opening_norm,
+ *damage_it,
+ penetration,
+ *reduction_penalty_it,
+ current_penalty,
+ *contact_traction_it,
+ *contact_opening_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
-void MaterialCohesiveLinear<spatial_dimension>::computeTraction(const Array<Real> & normal,
- ElementType el_type,
- GhostType ghost_type) {
+void MaterialCohesiveLinear<spatial_dimension>::checkDeltaMax(GhostType ghost_type) {
AKANTU_DEBUG_IN();
+
+ /// This function set a predefined value to the parameter
+ /// delta_max_prev of the elements that have been inserted in the
+ /// last loading step for which convergence has not been
+ /// reached. This is done before reducing the loading and re-doing
+ /// the step. Otherwise, the updating of delta_max_prev would be
+ /// done with reference to the non-convergent solution. In this
+ /// function also other variables related to the contact and
+ /// friction behavior are correctly set.
+
+ Mesh & mesh = fem_cohesive->getMesh();
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension,
+ ghost_type, _ek_cohesive);
+ Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
+ ghost_type, _ek_cohesive);
+
+ /// the variable "recompute" is set to true to activate the
+ /// procedure that reduce the penalty parameter for
+ /// compression. This procedure is set true only during the phase of
+ /// load_reduction, that has to be set in the maiin file. The
+ /// penalty parameter will be reduced only for the elements having
+ /// reduction_penalty = true.
+ recompute = true;
+
+ for(; it != last_type; ++it) {
+ Array<UInt> & elem_filter = element_filter(*it, ghost_type);
+
+ UInt nb_element = elem_filter.getSize();
+ if (nb_element == 0) continue;
+
+ ElementType el_type = *it;
+
+ /// define iterators
+ Array<Real>::scalar_iterator delta_max_it =
+ delta_max(el_type, ghost_type).begin();
+
+ Array<Real>::scalar_iterator delta_max_end =
+ delta_max(el_type, ghost_type).end();
+
+ Array<Real>::scalar_iterator delta_max_prev_it =
+ delta_max.previous(el_type, ghost_type).begin();
+
+ Array<Real>::scalar_iterator delta_c_it =
+ delta_c_eff(el_type, ghost_type).begin();
+
+ Array<Real>::vector_iterator opening_prec_it =
+ opening_prec(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator opening_prec_prev_it =
+ opening_prec.previous(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::scalar_iterator res_sliding_it =
+ residual_sliding(el_type, ghost_type).begin();
+
+ Array<Real>::scalar_iterator res_sliding_prev_it =
+ residual_sliding.previous(el_type, ghost_type).begin();
+
+ /// loop on each quadrature point
+ for (; delta_max_it != delta_max_end;
+ ++delta_max_it, ++delta_max_prev_it, ++delta_c_it,
+ ++opening_prec_it, ++opening_prec_prev_it,
+ ++res_sliding_it, ++res_sliding_prev_it) {
+
+ if (*delta_max_prev_it == 0)
+ /// elements inserted in the last incremental step, that did
+ /// not converge
+ *delta_max_it = *delta_c_it / 1000;
+ else
+ /// elements introduced in previous incremental steps, for
+ /// which a correct value of delta_max_prev already exists
+ *delta_max_it = *delta_max_prev_it;
+
+ /// in case convergence is not reached, set opening_prec to the
+ /// value referred to the previous incremental step
+ *opening_prec_it = *opening_prec_prev_it;
+
+ /// in case convergence is not reached, set "residual_sliding"
+ /// for the friction behaviour to the value referred to the
+ /// previous incremental step
+ *res_sliding_it = *res_sliding_prev_it;
+ }
+ }
+}
- /// define iterators
- Array<Real>::iterator< Vector<Real> > traction_it =
- tractions(el_type, ghost_type).begin(spatial_dimension);
- Array<Real>::iterator< Vector<Real> > opening_it =
- opening(el_type, ghost_type).begin(spatial_dimension);
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialCohesiveLinear<spatial_dimension>::resetVariables(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
- Array<Real>::iterator< Vector<Real> > contact_traction_it =
- contact_tractions(el_type, ghost_type).begin(spatial_dimension);
+ /// 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.
- Array<Real>::iterator< Vector<Real> > contact_opening_it =
- contact_opening(el_type, ghost_type).begin(spatial_dimension);
+ 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;
- Array<Real>::const_iterator< Vector<Real> > normal_it =
- normal.begin(spatial_dimension);
+ // std::cout << "RESET VARIABLE" << std::endl;
- Array<Real>::iterator< Vector<Real> >traction_end =
- tractions(el_type, ghost_type).end(spatial_dimension);
+ for(; it != last_type; ++it) {
+ Array<UInt> & elem_filter = element_filter(*it, ghost_type);
- Array<Real>::iterator<Real>sigma_c_it =
- sigma_c_eff(el_type, ghost_type).begin();
+ UInt nb_element = elem_filter.getSize();
+ if (nb_element == 0) continue;
- Array<Real>::iterator<Real>delta_max_it =
- delta_max(el_type, ghost_type).begin();
+ ElementType el_type = *it;
- Array<Real>::iterator<Real>delta_c_it =
- delta_c(el_type, ghost_type).begin();
+ Array<bool>::scalar_iterator reduction_penalty_it =
+ reduction_penalty(el_type, ghost_type).begin();
- Array<Real>::iterator<Real>damage_it =
- damage(el_type, ghost_type).begin();
+ Array<bool>::scalar_iterator reduction_penalty_end =
+ reduction_penalty(el_type, ghost_type).end();
- Array<Real>::iterator<Vector<Real> > insertion_stress_it =
- insertion_stress(el_type, ghost_type).begin(spatial_dimension);
+ /// 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();
- 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);
+ /// define iterators
+ Array<Real>::matrix_iterator tangent_it =
+ tangent_matrix.begin(spatial_dimension, spatial_dimension);
- /// 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) {
-
- /// 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 (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();
- }
+ Array<Real>::matrix_iterator tangent_end =
+ tangent_matrix.end(spatial_dimension, spatial_dimension);
- delta = std::sqrt(delta);
+ Array<Real>::const_vector_iterator normal_it =
+ normal.begin(spatial_dimension);
- /// update maximum displacement and damage
- *delta_max_it = std::max(*delta_max_it, delta);
- *damage_it = std::min(*delta_max_it / *delta_c_it, 1.);
+ Array<Real>::vector_iterator opening_it =
+ opening(el_type, ghost_type).begin(spatial_dimension);
- /**
- * 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$
- */
+ /// 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();
- 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;
+ Array<Real>::scalar_iterator sigma_c_it =
+ sigma_c_eff(el_type, ghost_type).begin();
- AKANTU_DEBUG_ASSERT(*delta_max_it != 0.,
- "Division by zero, tolerance might be too low");
+ Array<Real>::scalar_iterator delta_c_it =
+ delta_c_eff(el_type, ghost_type).begin();
- *traction_it *= *sigma_c_it / *delta_max_it * (1. - *damage_it);
- }
- }
+ Array<Real>::scalar_iterator damage_it =
+ damage(el_type, ghost_type).begin();
+
+ Array<Real>::vector_iterator contact_opening_it =
+ contact_opening(el_type, ghost_type).begin(spatial_dimension);
- delete [] memory_space;
+ Array<Real>::scalar_iterator res_sliding_prev_it =
+ residual_sliding.previous(el_type, ghost_type).begin();
+
+ Array<bool>::scalar_iterator reduction_penalty_it =
+ reduction_penalty(el_type, ghost_type).begin();
+
+ Vector<Real> normal_opening(spatial_dimension);
+ Vector<Real> tangential_opening(spatial_dimension);
+
+ for (; tangent_it != tangent_end;
+ ++tangent_it, ++normal_it, ++opening_it,
+ ++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
+ ++contact_opening_it, ++reduction_penalty_it) {
+
+ Real normal_opening_norm, tangential_opening_norm;
+ bool penetration;
+ Real current_penalty = 0.;
+ this->computeTangentTractionOnQuad(*tangent_it,
+ *delta_max_it,
+ *delta_c_it,
+ *sigma_c_it,
+ *opening_it,
+ *normal_it,
+ normal_opening,
+ tangential_opening,
+ normal_opening_norm,
+ tangential_opening_norm,
+ *damage_it,
+ penetration,
+ *reduction_penalty_it,
+ current_penalty,
+ *contact_opening_it);
+
+ /// check if the tangential stiffness matrix is symmetric
+// for (UInt h = 0; h < spatial_dimension; ++h){
+// for (UInt l = h; l < spatial_dimension; ++l){
+// if (l > h){
+// Real k_ls = (*tangent_it)[spatial_dimension*h+l];
+// Real k_us = (*tangent_it)[spatial_dimension*l+h];
+// // std::cout << "k_ls = " << k_ls << std::endl;
+// // std::cout << "k_us = " << k_us << std::endl;
+// if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
+// Real error = std::abs((k_ls - k_us) / k_us);
+// if (error > 1e-10){
+// std::cout << "non symmetric cohesive matrix" << std::endl;
+// // std::cout << "error " << error << std::endl;
+// }
+// }
+// }
+// }
+// }
+ }
+
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialCohesiveLinear);
+
+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 867fd039c..34b417771 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,162 +1,227 @@
/**
* @file material_cohesive_linear.hh
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
*
* @date creation: Tue May 08 2012
* @date last modification: Tue Jul 29 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 computed parameter
+ /// initialize the material parameters
virtual void initMaterial();
/// check stress for cohesive elements' insertion
- virtual void checkInsertion();
+ 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
- void computeTraction(const Array<Real> & normal,
- ElementType el_type,
- GhostType ghost_type = _not_ghost);
+ virtual void computeTraction(const Array<Real> & normal,
+ ElementType el_type,
+ GhostType ghost_type = _not_ghost);
- /// compute stress norms on quadrature points for each facet for stress check
- virtual void computeStressNorms(const Array<Real> & facet_stress,
- Array<Real> & stress_check,
- Array<Real> & normal_stress,
- ElementType type_facet);
+ /// 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 effective stress norm for insertion check
- inline void computeEffectiveNorm(const Matrix<Real> & stress,
- const Vector<Real> & normal,
- const Vector<Real> & tangent,
- Vector<Real> & normal_stress,
- Real & effective_norm);
+ /// reset variables when convergence is reached (only for
+ /// extrinsic-implicit)
+ void resetVariables(GhostType ghost_type = _not_ghost);
+
+ /// compute tangent stiffness matrix
+ virtual void computeTangentTraction(const ElementType & el_type,
+ Array<Real> & tangent_matrix,
+ const Array<Real> & normal,
+ GhostType ghost_type);
/**
* Scale insertion traction sigma_c according to the volume of the
* two elements surrounding a facet
+ *
+ * see the article: F. Zhou and J. F. Molinari "Dynamic crack
+ * propagation with cohesive elements: a methodology to address mesh
+ * dependency" International Journal for Numerical Methods in
+ * Engineering (2004)
*/
void scaleInsertionTraction();
+ /// compute the traction for a given quadrature point
+ inline void computeTractionOnQuad(Vector<Real> & traction, Real & delta_max,
+ const Real & delta_max_prev, const Real & delta_c,
+ const Vector<Real> & insertion_stress, const Real & sigma_c,
+ Vector<Real> & opening, Vector<Real> & opening_prec, const Vector<Real> & normal,
+ Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
+ Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
+ bool & penetration, bool & reduction_penalty, Real & current_penalty,
+ Vector<Real> & contact_traction, Vector<Real> & contact_opening);
+
+ inline void computeTangentTractionOnQuad(Matrix<Real> & tangent,
+ Real & delta_max, const Real & delta_c,
+ const Real & sigma_c,
+ Vector<Real> & opening, const Vector<Real> & normal,
+ Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
+ Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
+ bool & penetration, bool & reduction_penalty, Real & current_penalty,
+ Vector<Real> & contact_opening);
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// get sigma_c_eff
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(InsertionTraction, sigma_c_eff, Real);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// beta parameter
Real beta;
/// beta square inverse to compute effective norm
Real beta2_inv;
/// mode I fracture energy
- Real G_cI;
-
- /// mode II fracture energy
- Real G_cII;
+ Real G_c;
/// kappa parameter
Real kappa;
/// constitutive law scalar to compute delta
Real beta2_kappa2;
/// constitutive law scalar to compute traction
Real beta2_kappa;
/// penalty coefficient
Real penalty;
/// reference volume used to scale sigma_c
Real volume_s;
/// weibull exponent used to scale sigma_c
Real m_s;
+ /// maximum value of the friction coefficient
+ Real mu_max;
+
+ /// penalty parameter for the friction law
+ Real friction_penalty;
+
+ /// variable defining if we are recomputing the last loading step
+ /// after load_reduction
+ bool recompute;
+
/// critical effective stress
RandomInternalField<Real, CohesiveInternalField> sigma_c_eff;
- /// critical displacement
- CohesiveInternalField<Real> delta_c;
+ /// effective critical displacement (each element can have a
+ /// different value)
+ CohesiveInternalField<Real> delta_c_eff;
/// stress at insertion
CohesiveInternalField<Real> insertion_stress;
+
+ /// delta of the previous step
+ CohesiveInternalField<Real> opening_prec;
+
+ /// history parameter for the friction law
+ CohesiveInternalField<Real> residual_sliding;
+
+ /// friction force
+ CohesiveInternalField<Real> friction_force;
+
+ /// variable that defines if the penalty parameter for compression
+ /// has to be decreased for problems of convergence in the solution
+ /// loops
+ CohesiveInternalField<bool> reduction_penalty;
+
+ /// variable saying if there should be penalty contact also after
+ /// breaking the cohesive elements
+ bool contact_after_breaking;
+
+ /// insertion of cohesive element when stress is high enough just on
+ /// one quadrature point
+ bool max_quad_stress_insertion;
+
+ /// variable saying if friction has to be added to the cohesive behavior
+ bool friction;
+
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-//#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
new file mode 100644
index 000000000..cfa3635c4
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.cc
@@ -0,0 +1,293 @@
+/**
+ * @file material_cohesive_linear_fatigue.cc
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @date Thu Feb 19 14:40:57 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "material_cohesive_linear_fatigue.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template <UInt spatial_dimension>
+MaterialCohesiveLinearFatigue<spatial_dimension>
+::MaterialCohesiveLinearFatigue(SolidMechanicsModel & model,
+ const ID & id) :
+ MaterialCohesiveLinear<spatial_dimension>(model, id),
+ delta_prec("delta_prec", *this),
+ K_plus("K_plus", *this),
+ K_minus("K_minus", *this),
+ T_1d("T_1d", *this),
+ switches("switches", *this),
+ delta_dot_prec("delta_dot_prec", *this),
+ normal_regime("normal_regime", *this) {
+
+ this->registerParam("delta_f", delta_f, Real(-1.) ,
+ _pat_parsable | _pat_readable,
+ "delta_f");
+
+ this->registerParam("progressive_delta_f", progressive_delta_f, false,
+ _pat_parsable | _pat_readable,
+ "Whether or not delta_f is equal to delta_max");
+
+ this->registerParam("count_switches", count_switches, false,
+ _pat_parsable | _pat_readable,
+ "Count the opening/closing switches per element");
+
+ this->registerParam("fatigue_ratio", fatigue_ratio, Real(1.),
+ _pat_parsable | _pat_readable,
+ "What portion of the cohesive law is subjected to fatigue");
+}
+
+/* -------------------------------------------------------------------------- */
+template <UInt spatial_dimension>
+void MaterialCohesiveLinearFatigue<spatial_dimension>::initMaterial() {
+ MaterialCohesiveLinear<spatial_dimension>::initMaterial();
+
+ // check that delta_f has a proper value or assign a defaul value
+ if (delta_f < 0) delta_f = this->delta_c_eff;
+ else if (delta_f < this->delta_c_eff)
+ AKANTU_DEBUG_ERROR("Delta_f must be greater or equal to delta_c");
+
+ delta_prec.initialize(1);
+ K_plus.initialize(1);
+ K_minus.initialize(1);
+ T_1d.initialize(1);
+ normal_regime.initialize(1);
+
+ if (count_switches) {
+ switches.initialize(1);
+ delta_dot_prec.initialize(1);
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialCohesiveLinearFatigue<spatial_dimension>
+::computeTraction(const Array<Real> & normal,
+ ElementType el_type,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ /// define iterators
+ Array<Real>::vector_iterator traction_it =
+ this->tractions(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator opening_it =
+ this->opening(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator contact_traction_it =
+ this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator contact_opening_it =
+ this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::const_vector_iterator normal_it = normal.begin(spatial_dimension);
+
+ Array<Real>::vector_iterator traction_end =
+ this->tractions(el_type, ghost_type).end(spatial_dimension);
+
+ const Array<Real> & sigma_c_array = this->sigma_c_eff(el_type, ghost_type);
+ Array<Real> & delta_max_array = this->delta_max(el_type, ghost_type);
+ const Array<Real> & delta_c_array = this->delta_c_eff(el_type, ghost_type);
+ Array<Real> & damage_array = this->damage(el_type, ghost_type);
+
+ Array<Real>::vector_iterator insertion_stress_it =
+ this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real> & delta_prec_array = delta_prec(el_type, ghost_type);
+ Array<Real> & K_plus_array = K_plus(el_type, ghost_type);
+ Array<Real> & K_minus_array = K_minus(el_type, ghost_type);
+ Array<Real> & T_1d_array = T_1d(el_type, ghost_type);
+ Array<bool> & normal_regime_array = normal_regime(el_type, ghost_type);
+
+ Array<UInt> * switches_array = NULL;
+ Array<Real> * delta_dot_prec_array = NULL;
+
+ if (count_switches) {
+ switches_array = &switches(el_type, ghost_type);
+ delta_dot_prec_array = &delta_dot_prec(el_type, ghost_type);
+ }
+
+ Real * memory_space = new Real[2*spatial_dimension];
+ Vector<Real> normal_opening(memory_space, spatial_dimension);
+ Vector<Real> tangential_opening(memory_space + spatial_dimension,
+ spatial_dimension);
+
+ Real tolerance = Math::getTolerance();
+
+ /// loop on each quadrature point
+ for (UInt q = 0; traction_it != traction_end;
+ ++traction_it, ++opening_it, ++normal_it,
+ ++contact_traction_it, ++insertion_stress_it, ++contact_opening_it, ++q) {
+
+ /// compute normal and tangential opening vectors
+ Real normal_opening_norm = opening_it->dot(*normal_it);
+ normal_opening = (*normal_it);
+ normal_opening *= normal_opening_norm;
+
+ tangential_opening = *opening_it;
+ tangential_opening -= normal_opening;
+
+ Real tangential_opening_norm = tangential_opening.norm();
+
+ /**
+ * compute effective opening displacement
+ * @f$ \delta = \sqrt{
+ * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
+ */
+ Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
+
+ bool penetration = normal_opening_norm < -tolerance;
+ if (this->contact_after_breaking == false && Math::are_float_equal(damage_array(q), 1.))
+ penetration = false;
+
+ if (penetration) {
+ /// use penalty coefficient in case of penetration
+ *contact_traction_it = normal_opening;
+ *contact_traction_it *= this->penalty;
+ *contact_opening_it = normal_opening;
+ /// don't consider penetration contribution for delta
+ *opening_it = tangential_opening;
+ normal_opening.clear();
+ }
+ else {
+ delta += normal_opening_norm * normal_opening_norm;
+ contact_traction_it->clear();
+ contact_opening_it->clear();
+ }
+
+ delta = std::sqrt(delta);
+
+ /**
+ * Compute traction @f$ \mathbf{T} = \left(
+ * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
+ * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
+ * \frac{\delta}{\delta_c} \right)@f$
+ */
+
+
+ // update maximum displacement and damage
+ delta_max_array(q) = std::max(delta, delta_max_array(q));
+ damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
+
+ Real delta_dot = delta - delta_prec_array(q);
+
+ // count switches if asked
+ if (count_switches) {
+ if ( (delta_dot > 0. && (*delta_dot_prec_array)(q) <= 0.) ||
+ (delta_dot < 0. && (*delta_dot_prec_array)(q) >= 0.) )
+ ++((*switches_array)(q));
+
+ (*delta_dot_prec_array)(q) = delta_dot;
+ }
+
+ // set delta_f equal to delta_max if desired
+ if (progressive_delta_f) delta_f = delta_max_array(q);
+
+ // broken element case
+ if (Math::are_float_equal(damage_array(q), 1.))
+ traction_it->clear();
+ // just inserted element case
+ else if (Math::are_float_equal(damage_array(q), 0.)) {
+ if (penetration)
+ traction_it->clear();
+ else
+ *traction_it = *insertion_stress_it;
+ // initialize the 1d traction to sigma_c
+ T_1d_array(q) = sigma_c_array(q);
+ }
+ // normal case
+ else {
+ // if element is closed then there are zero tractions
+ if (delta <= tolerance)
+ traction_it->clear();
+ // otherwise compute new tractions if the new delta is different
+ // than the previous one
+ else if (std::abs(delta_dot) > tolerance) {
+ // loading case
+ if (delta_dot > 0.) {
+ if (!normal_regime_array(q)) {
+ // equation (4) of the article
+ K_plus_array(q) *= 1. - delta_dot / delta_f;
+ // equivalent to equation (2) of the article
+ T_1d_array(q) += K_plus_array(q) * delta_dot;
+
+ // in case of reloading, traction must not exceed that of the
+ // envelop of the cohesive law
+ Real max_traction = sigma_c_array(q) * (1 - delta / delta_c_array(q));
+ bool max_traction_exceeded = T_1d_array(q) > max_traction;
+ if (max_traction_exceeded) T_1d_array(q) = max_traction;
+
+ // switch to standard linear cohesive law
+ if (delta_max_array(q) > fatigue_ratio * delta_c_array(q)) {
+ // reset delta_max to avoid big jumps in the traction
+ delta_max_array(q) = sigma_c_array(q) / (T_1d_array(q) / delta + sigma_c_array(q) / delta_c_array(q));
+ damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
+ K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
+ normal_regime_array(q) = true;
+ } else {
+ // equation (3) of the article
+ K_minus_array(q) = T_1d_array(q) / delta;
+
+ // if the traction is following the cohesive envelop, then
+ // K_plus has to be reset
+ if (max_traction_exceeded) K_plus_array(q) = K_minus_array(q);
+ }
+ } else {
+ // compute stiffness according to the standard law
+ K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
+ }
+ }
+ // unloading case
+ else if (!normal_regime_array(q)) {
+ // equation (4) of the article
+ K_plus_array(q) += (K_plus_array(q) - K_minus_array(q)) * delta_dot / delta_f;
+ // equivalent to equation (2) of the article
+ T_1d_array(q) = K_minus_array(q) * delta;
+ }
+
+ // applying the actual stiffness
+ *traction_it = tangential_opening;
+ *traction_it *= this->beta2_kappa;
+ *traction_it += normal_opening;
+ *traction_it *= K_minus_array(q);
+ }
+ }
+
+ // update precendent delta
+ delta_prec_array(q) = delta;
+ }
+
+ delete [] memory_space;
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+INSTANTIATE_MATERIAL(MaterialCohesiveLinearFatigue);
+
+
+__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.hh
new file mode 100644
index 000000000..1bb26232b
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_fatigue.hh
@@ -0,0 +1,132 @@
+/**
+ * @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
+ * 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..55ca17900
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.cc
@@ -0,0 +1,382 @@
+/**
+ * @file material_cohesive_linear_friction.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date creation: Tue May 08 2012
+ * @date last modification: Thu Nov 19 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "material_cohesive_linear_friction.hh"
+#include "solid_mechanics_model_cohesive.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+MaterialCohesiveLinearFriction<spatial_dimension>::MaterialCohesiveLinearFriction(SolidMechanicsModel & model,
+ const ID & id) :
+ MaterialParent(model,id),
+ residual_sliding("residual_sliding", *this),
+ friction_force("friction_force", *this) {
+ AKANTU_DEBUG_IN();
+
+ this->registerParam("mu", mu_max, Real(0.),
+ _pat_parsable | _pat_readable,
+ "Maximum value of the friction coefficient");
+
+ this->registerParam("penalty_for_friction", friction_penalty, Real(0.),
+ _pat_parsable | _pat_readable,
+ "Penalty parameter for the friction behavior");
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialCohesiveLinearFriction<spatial_dimension>::initMaterial() {
+ AKANTU_DEBUG_IN();
+
+ MaterialParent::initMaterial();
+
+ friction_force.initialize(spatial_dimension);
+ residual_sliding.initialize(1);
+ residual_sliding.initializeHistory();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialCohesiveLinearFriction<spatial_dimension>::computeTraction(const Array<Real> & normal,
+ ElementType el_type,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ residual_sliding.resize();
+
+ /// define iterators
+ Array<Real>::vector_iterator traction_it =
+ this->tractions(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator traction_end =
+ this->tractions(el_type, ghost_type).end(spatial_dimension);
+
+ Array<Real>::vector_iterator opening_it =
+ this->opening(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator opening_prev_it =
+ this->opening.previous(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator opening_prec_it =
+ this->opening_prec(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator contact_traction_it =
+ this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator contact_opening_it =
+ this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::const_iterator< Vector<Real> > normal_it =
+ this->normal.begin(spatial_dimension);
+
+ Array<Real>::iterator<Real>sigma_c_it =
+ this->sigma_c_eff(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>delta_max_it =
+ this->delta_max(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>delta_max_prev_it =
+ this->delta_max.previous(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>delta_c_it =
+ this->delta_c_eff(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>damage_it =
+ this->damage(el_type, ghost_type).begin();
+
+ Array<Real>::vector_iterator insertion_stress_it =
+ this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::iterator<Real>res_sliding_it =
+ this->residual_sliding(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>res_sliding_prev_it =
+ this->residual_sliding.previous(el_type, ghost_type).begin();
+
+ Array<Real>::vector_iterator friction_force_it =
+ this->friction_force(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<bool>::iterator<bool> reduction_penalty_it =
+ this->reduction_penalty(el_type, ghost_type).begin();
+
+ Vector<Real> normal_opening(spatial_dimension);
+ Vector<Real> tangential_opening(spatial_dimension);
+
+ if (! this->model->isExplicit())
+ this->delta_max(el_type, ghost_type).copy(this->delta_max.previous(el_type, ghost_type));
+
+ /// loop on each quadrature point
+ for (; traction_it != traction_end;
+ ++traction_it, ++opening_it, ++opening_prev_it, ++opening_prec_it,
+ ++normal_it, ++sigma_c_it,
+ ++delta_max_it, ++delta_c_it, ++damage_it, ++contact_traction_it,
+ ++insertion_stress_it, ++contact_opening_it, ++delta_max_prev_it,
+ ++res_sliding_it, ++res_sliding_prev_it,
+ ++friction_force_it, ++reduction_penalty_it) {
+
+ Real normal_opening_norm, tangential_opening_norm;
+ bool penetration;
+ Real current_penalty = 0.;
+ this->computeTractionOnQuad(*traction_it,
+ *delta_max_it,
+ *delta_max_prev_it,
+ *delta_c_it,
+ *insertion_stress_it,
+ *sigma_c_it,
+ *opening_it,
+ *opening_prec_it,
+ *normal_it,
+ normal_opening,
+ tangential_opening,
+ normal_opening_norm,
+ tangential_opening_norm,
+ *damage_it,
+ penetration,
+ *reduction_penalty_it,
+ current_penalty,
+ *contact_traction_it,
+ *contact_opening_it);
+
+
+ if (penetration) {
+ /* ----------------------------------------- */
+ Real damage = std::min(*delta_max_prev_it / *delta_c_it, Real(1.));
+ Real mu = mu_max * std::sqrt(damage);
+ /// the definition of tau_max refers to the opening
+ /// (penetration) of the previous incremental step
+ Real normal_opening_prev_norm = opening_prev_it->dot(*normal_it);
+ Vector<Real> normal_opening_prev = (*normal_it);
+ normal_opening_prev *= normal_opening_prev_norm;
+ Real tau_max = mu * current_penalty * (normal_opening_prev.norm());
+ Real delta_sliding_norm = std::abs(tangential_opening_norm - *res_sliding_prev_it);
+ // tau is the norm of the friction force, acting tangentially to the surface
+ Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
+ if ((tangential_opening_norm - *res_sliding_it) < -Math::getTolerance())
+ tau = -tau;
+ // from tau get the x and y components of friction, to be added in the force vector
+ Vector<Real> tangent(spatial_dimension);
+ tangent = tangential_opening / tangential_opening_norm;
+ *friction_force_it = tau * tangent;
+
+ //update residual_sliding
+ *res_sliding_it = tangential_opening_norm - (tau / friction_penalty);
+ /* ----------------------------------------- */
+ } else {
+ friction_force_it->clear();
+ }
+
+ *traction_it += *friction_force_it;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialCohesiveLinearFriction<spatial_dimension>::checkDeltaMax(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ MaterialParent::checkDeltaMax();
+
+ Mesh & mesh = this->fem_cohesive->getMesh();
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension,
+ ghost_type, _ek_cohesive);
+ Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
+ ghost_type, _ek_cohesive);
+
+ for(; it != last_type; ++it) {
+ Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
+
+ UInt nb_element = elem_filter.getSize();
+ if (nb_element == 0) continue;
+
+ ElementType el_type = *it;
+
+ /// define iterators
+ Array<Real>::iterator<Real>delta_max_it =
+ this->delta_max(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>delta_max_end =
+ this->delta_max(el_type, ghost_type).end();
+
+ Array<Real>::iterator<Real>res_sliding_it =
+ this->residual_sliding(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>res_sliding_prev_it =
+ this->residual_sliding.previous(el_type, ghost_type).begin();
+
+ /// loop on each quadrature point
+ for (; delta_max_it != delta_max_end;
+ ++delta_max_it, ++res_sliding_it, ++res_sliding_prev_it) {
+
+ /// in case convergence is not reached, set "residual_sliding"
+ /// for the friction behaviour to the value referred to the
+ /// previous incremental step
+ *res_sliding_it = *res_sliding_prev_it;
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialCohesiveLinearFriction<spatial_dimension>::computeTangentTraction(const ElementType & el_type,
+ Array<Real> & tangent_matrix,
+ const Array<Real> & normal,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ /// define iterators
+ Array<Real>::matrix_iterator tangent_it =
+ tangent_matrix.begin(spatial_dimension, spatial_dimension);
+
+ Array<Real>::matrix_iterator tangent_end =
+ tangent_matrix.end(spatial_dimension, spatial_dimension);
+
+ Array<Real>::const_vector_iterator normal_it =
+ this->normal.begin(spatial_dimension);
+
+ Array<Real>::vector_iterator opening_it =
+ this->opening(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::vector_iterator opening_prev_it =
+ this->opening.previous(el_type, ghost_type).begin(spatial_dimension);
+
+ /// NB: delta_max_it points on delta_max_previous, i.e. the
+ /// delta_max related to the solution of the previous incremental
+ /// step
+ Array<Real>::iterator<Real>delta_max_it =
+ this->delta_max.previous(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>sigma_c_it =
+ this->sigma_c_eff(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>delta_c_it =
+ this->delta_c_eff(el_type, ghost_type).begin();
+
+ Array<Real>::iterator<Real>damage_it =
+ this->damage(el_type, ghost_type).begin();
+
+ Array<Real>::iterator< Vector<Real> > contact_opening_it =
+ this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
+
+ Array<Real>::iterator<Real>res_sliding_prev_it =
+ this->residual_sliding.previous(el_type, ghost_type).begin();
+
+ Array<bool>::iterator<bool> reduction_penalty_it =
+ this->reduction_penalty(el_type, ghost_type).begin();
+
+ Vector<Real> normal_opening(spatial_dimension);
+ Vector<Real> tangential_opening(spatial_dimension);
+
+ for (; tangent_it != tangent_end;
+ ++tangent_it, ++normal_it, ++opening_it, ++opening_prev_it,
+ ++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
+ ++contact_opening_it, ++res_sliding_prev_it, ++reduction_penalty_it) {
+
+ Real normal_opening_norm, tangential_opening_norm;
+ bool penetration;
+ Real current_penalty = 0.;
+ this->computeTangentTractionOnQuad(*tangent_it,
+ *delta_max_it,
+ *delta_c_it,
+ *sigma_c_it,
+ *opening_it,
+ *normal_it,
+ normal_opening,
+ tangential_opening,
+ normal_opening_norm,
+ tangential_opening_norm,
+ *damage_it,
+ penetration,
+ *reduction_penalty_it,
+ current_penalty,
+ *contact_opening_it);
+
+ if (penetration) {
+ Real damage = std::min(*delta_max_it / *delta_c_it, Real(1.));
+ // the friction coefficient mu is increasing with the
+ // damage. It equals the maximum value when damage = 1.
+ Real mu = mu_max * damage;
+ Real normal_opening_prev_norm = opening_prev_it->dot(*normal_it);
+ Vector<Real> normal_opening_prev = (*normal_it);
+ normal_opening_prev *= normal_opening_prev_norm;
+ Real tau_max = mu * current_penalty * normal_opening_prev.norm();
+ Real delta_sliding_norm = std::abs(tangential_opening_norm - *res_sliding_prev_it);
+ // tau is the norm of the friction force, acting tangentially to the surface
+ Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
+
+ if (tau < tau_max && tau_max > Math::getTolerance()){
+ Matrix<Real> I(spatial_dimension, spatial_dimension);
+ I.eye(1.);
+
+ Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
+ n_outer_n.outerProduct(*normal_it, *normal_it);
+
+ Matrix<Real> nn(n_outer_n);
+ I -= nn;
+ *tangent_it += I * friction_penalty;
+ }
+ }
+
+ /// check if the tangential stiffness matrix is symmetric
+// for (UInt h = 0; h < spatial_dimension; ++h){
+// for (UInt l = h; l < spatial_dimension; ++l){
+// if (l > h){
+// Real k_ls = (*tangent_it)[spatial_dimension*h+l];
+// Real k_us = (*tangent_it)[spatial_dimension*l+h];
+// // std::cout << "k_ls = " << k_ls << std::endl;
+// // std::cout << "k_us = " << k_us << std::endl;
+// if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
+// Real error = std::abs((k_ls - k_us) / k_us);
+// if (error > 1e-10){
+// std::cout << "non symmetric cohesive matrix" << std::endl;
+// // std::cout << "error " << error << std::endl;
+// }
+// }
+// }
+// }
+// }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+/* -------------------------------------------------------------------------- */
+
+
+INSTANTIATE_MATERIAL(MaterialCohesiveLinearFriction);
+
+__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
new file mode 100644
index 000000000..d01b97737
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_friction.hh
@@ -0,0 +1,110 @@
+/**
+ * @file material_cohesive_linear_friction.hh
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date creation: Tue May 08 2012
+ * @date last modification: Tue Jul 29 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100644
index 000000000..2aba0b544
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_cohesive/constitutive_laws/material_cohesive_linear_inline_impl.cc
@@ -0,0 +1,313 @@
+/**
+ * @file material_cohesive_linear_inline_impl.cc
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @date Tue Apr 21 14:49:56 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
+#define __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+inline Real MaterialCohesiveLinear<dim>::computeEffectiveNorm(const Matrix<Real> & stress,
+ const Vector<Real> & normal,
+ const Vector<Real> & tangent,
+ Vector<Real> & normal_traction) const {
+ normal_traction.mul<false>(stress, normal);
+
+ Real normal_contrib = normal_traction.dot(normal);
+
+ /// in 3D tangential components must be summed
+ Real tangent_contrib = 0;
+
+ if (dim == 2) {
+ Real tangent_contrib_tmp = normal_traction.dot(tangent);
+ tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
+ }
+ else if (dim == 3) {
+ for (UInt s = 0; s < dim - 1; ++s) {
+ const Vector<Real> tangent_v(tangent.storage() + s * dim, dim);
+ Real tangent_contrib_tmp = normal_traction.dot(tangent_v);
+ tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
+ }
+ }
+
+ tangent_contrib = std::sqrt(tangent_contrib);
+ normal_contrib = std::max(Real(0.), normal_contrib);
+
+ return std::sqrt(normal_contrib * normal_contrib + tangent_contrib * tangent_contrib * beta2_inv);
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+inline void MaterialCohesiveLinear<dim>::computeTractionOnQuad(
+ Vector<Real> & traction,
+ Real & delta_max,
+ const Real & delta_max_prev,
+ const Real & delta_c,
+ const Vector<Real> & insertion_stress,
+ const Real & sigma_c,
+ Vector<Real> & opening,
+ Vector<Real> & opening_prec,
+ const Vector<Real> & normal,
+ Vector<Real> & normal_opening,
+ Vector<Real> & tangential_opening,
+ Real & normal_opening_norm,
+ Real & tangential_opening_norm,
+ Real & damage,
+ bool & penetration,
+ bool & reduction_penalty,
+ Real & current_penalty,
+ Vector<Real> & contact_traction,
+ Vector<Real> & contact_opening) {
+
+ /// compute normal and tangential opening vectors
+ normal_opening_norm = opening.dot(normal);
+
+ normal_opening = normal;
+ normal_opening *= normal_opening_norm;
+ tangential_opening = opening;
+ tangential_opening -= normal_opening;
+
+ tangential_opening_norm = tangential_opening.norm();
+
+ /**
+ * compute effective opening displacement
+ * @f$ \delta = \sqrt{
+ * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
+ */
+ Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
+
+ penetration = normal_opening_norm < -Math::getTolerance();
+ if (this->contact_after_breaking == false && Math::are_float_equal(damage, 1.))
+ penetration = false;
+
+ /**
+ * if during the convergence loop a cohesive element continues to
+ * jumps from penetration to opening, and convergence is not
+ * reached, its penalty parameter will be reduced in the
+ * recomputation of the same incremental step. recompute is set
+ * equal to true when convergence is not reached in the
+ * solveStepCohesive function and the execution of the program
+ * goes back to the main file where the variable load_reduction
+ * is set equal to true.
+ */
+
+ // opening_prec is the opening of the previous convergence loop
+ // (NB: it is different from opening_prev, that refers to the solution
+ // of the previous incremental step)
+ Real normal_opening_prec_norm = opening_prec.dot(normal);
+ opening_prec = opening;
+
+ if (!this->model->isExplicit() && !this->recompute)
+ if ((normal_opening_prec_norm * normal_opening_norm) < 0) {
+ reduction_penalty = true;
+ }
+
+ if (penetration) {
+ if (this->recompute && reduction_penalty){
+ /// the penalty parameter is locally reduced
+ current_penalty = this->penalty / 1000.;
+ }
+ else
+ current_penalty = this->penalty;
+
+ /// use penalty coefficient in case of penetration
+ contact_traction = normal_opening;
+ contact_traction *= current_penalty;
+ contact_opening = normal_opening;
+
+ /// don't consider penetration contribution for delta
+ opening = tangential_opening;
+ normal_opening.clear();
+
+ }
+ else {
+ delta += normal_opening_norm * normal_opening_norm;
+ contact_traction.clear();
+ contact_opening.clear();
+ }
+
+ delta = std::sqrt(delta);
+
+ /// update maximum displacement and damage
+ delta_max = std::max(delta_max, delta);
+ damage = std::min(delta_max / delta_c, Real(1.));
+
+ /**
+ * Compute traction @f$ \mathbf{T} = \left(
+ * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
+ * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
+ * \frac{\delta}{\delta_c} \right)@f$
+ */
+
+ if (Math::are_float_equal(damage, 1.))
+ traction.clear();
+ else if (Math::are_float_equal(damage, 0.)) {
+ if (penetration)
+ traction.clear();
+ else
+ traction = insertion_stress;
+ }
+ else {
+ traction = tangential_opening;
+ traction *= beta2_kappa;
+ traction += normal_opening;
+
+ AKANTU_DEBUG_ASSERT(delta_max != 0.,
+ "Division by zero, tolerance might be too low");
+
+ traction *= sigma_c / delta_max * (1. - damage);
+ }
+}
+
+
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+inline void MaterialCohesiveLinear<dim>::computeTangentTractionOnQuad(
+ Matrix<Real> & tangent,
+ Real & delta_max,
+ const Real & delta_c,
+ const Real & sigma_c,
+ Vector<Real> & opening,
+ const Vector<Real> & normal,
+ Vector<Real> & normal_opening,
+ Vector<Real> & tangential_opening,
+ Real & normal_opening_norm,
+ Real & tangential_opening_norm,
+ Real & damage,
+ bool & penetration,
+ bool & reduction_penalty,
+ Real & current_penalty,
+ Vector<Real> & contact_opening) {
+
+ /// During the update of the residual the interpenetrations are
+ /// stored in the array "contact_opening", therefore, in the case
+ /// of penetration, in the array "opening" there are only the
+ /// tangential components.
+ opening += contact_opening;
+
+ /// compute normal and tangential opening vectors
+ normal_opening_norm = opening.dot(normal);
+ normal_opening = normal;
+ normal_opening *= normal_opening_norm;
+
+ tangential_opening = opening;
+ tangential_opening -= normal_opening;
+
+ tangential_opening_norm = tangential_opening.norm();
+ penetration = normal_opening_norm < -Math::getTolerance();
+ if (contact_after_breaking == false && Math::are_float_equal(damage, 1.))
+ penetration = false;
+
+ Real derivative = 0; // derivative = d(t/delta)/ddelta
+ Real t = 0;
+
+ Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
+
+ Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
+ n_outer_n.outerProduct(normal, normal);
+
+ if (penetration){
+ if (recompute && reduction_penalty)
+ current_penalty = this->penalty / 1000.;
+ else
+ current_penalty = this->penalty;
+
+ /// stiffness in compression given by the penalty parameter
+ tangent += n_outer_n;
+ tangent *= current_penalty;
+
+ opening = tangential_opening;
+ normal_opening_norm = opening.dot(normal);
+ normal_opening = normal;
+ normal_opening *= normal_opening_norm;
+
+ }
+ else{
+ delta += normal_opening_norm * normal_opening_norm;
+ }
+
+ delta = std::sqrt(delta);
+
+ /// Delta has to be different from 0 to have finite values of
+ /// tangential stiffness. At the element insertion, delta =
+ /// 0. Therefore, a fictictious value is defined, for the
+ /// evaluation of the first value of K.
+ if (delta < Math::getTolerance())
+ delta = (delta_c)/1000.;
+
+ if (delta >= delta_max){
+ if (delta <= delta_c){
+ derivative = -sigma_c / (delta * delta);
+ t = sigma_c * (1 - delta / delta_c);
+ } else {
+ derivative = 0.;
+ t = 0.;
+ }
+ } else if (delta < delta_max){
+ Real tmax = sigma_c * (1 - delta_max / delta_c);
+ t = tmax / delta_max * delta;
+ }
+
+
+ /// computation of the derivative of the constitutive law (dT/ddelta)
+ Matrix<Real> I(spatial_dimension, spatial_dimension);
+ I.eye(this->beta2_kappa);
+
+ Matrix<Real> nn(n_outer_n);
+ nn *= (1. - this->beta2_kappa);
+ nn += I;
+ nn *= t/delta;
+
+ Vector<Real> t_tilde(normal_opening);
+ t_tilde *= (1. - this->beta2_kappa2);
+
+ Vector<Real> mm(opening);
+ mm *= this->beta2_kappa2;
+ t_tilde += mm;
+
+ Vector<Real> t_hat(normal_opening);
+ t_hat += this->beta2_kappa * tangential_opening;
+
+ Matrix<Real> prov(spatial_dimension, spatial_dimension);
+ prov.outerProduct(t_hat, t_tilde);
+ prov *= derivative/delta;
+ prov += nn;
+
+ Matrix<Real> prov_t = prov.transpose();
+ tangent += prov_t;
+}
+
+/* -------------------------------------------------------------------------- */
+__END_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+#endif //__AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
diff --git a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc
index 14376a897..140d1f284 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc
+++ b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.cc
@@ -1,616 +1,624 @@
/**
* @file material_cohesive.cc
*
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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) {
+ 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);
+ 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);
+ 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");
- Array<Real> normal(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);
- Array<Real> normal(nb_quadrature_points, spatial_dimension, "normal");
+ 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) {
+ ++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.;
}
/* -------------------------------------------------------------------------- */
-
-
__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 38600f1fb..0eade6996 100644
--- a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive.hh
@@ -1,243 +1,267 @@
/**
* @file material_cohesive.hh
*
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "material.hh"
#include "fe_engine_template.hh"
#include "aka_common.hh"
#include "cohesive_internal_field.hh"
#include "cohesive_element_inserter.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_COHESIVE_HH__
#define __AKANTU_MATERIAL_COHESIVE_HH__
/* -------------------------------------------------------------------------- */
namespace akantu {
class SolidMechanicsModelCohesive;
}
__BEGIN_AKANTU__
class MaterialCohesive : public Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef FEEngineTemplate<IntegratorGauss,
- ShapeLagrange, _ek_cohesive> MyFEEngineCohesiveType;
+ ShapeLagrange, _ek_cohesive> MyFEEngineCohesiveType;
public:
MaterialCohesive(SolidMechanicsModel& model, const ID & id = "");
virtual ~MaterialCohesive();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the material computed parameter
virtual void initMaterial();
/// compute tractions (including normals and openings)
void computeTraction(GhostType ghost_type = _not_ghost);
/// assemble residual
void assembleResidual(GhostType ghost_type = _not_ghost);
/// compute reversible and total energies by element
void computeEnergies();
- /// check stress for cohesive elements' insertion
- virtual void checkInsertion() {
+ /// check stress for cohesive elements' insertion, by default it
+ /// also updates the cohesive elements' data
+ virtual void checkInsertion(bool check_only = false) {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ }
+
+ /// check delta_max for cohesive elements in case of no convergence
+ /// in the solveStep (only for extrinsic-implicit)
+ virtual void checkDeltaMax(GhostType ghost_type = _not_ghost) {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ }
+
+ /// reset variables when convergence is reached (only for
+ /// extrinsic-implicit)
+ virtual void resetVariables(GhostType ghost_type = _not_ghost) {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/// interpolate stress on given positions for each element (empty
/// implemantation to avoid the generic call to be done on cohesive elements)
virtual void interpolateStress(__attribute__((unused)) const ElementType type,
- __attribute__((unused)) Array<Real> & result) { };
+ __attribute__((unused)) Array<Real> & result) { };
+ /// compute the stresses
virtual void computeAllStresses(__attribute__((unused)) GhostType ghost_type = _not_ghost) { };
// add the facet to be handled by the material
UInt addFacet(const Element & element);
protected:
virtual void computeTangentTraction(__attribute__((unused)) const ElementType & el_type,
- __attribute__((unused)) Array<Real> & tangent_matrix,
- __attribute__((unused)) const Array<Real> & normal,
- __attribute__((unused)) GhostType ghost_type = _not_ghost) {
+ __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);
+ 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);
+ Array<Real> & normal,
+ ElementType type,
+ GhostType ghost_type);
template<ElementType type>
void computeNormal(const Array<Real> & position,
- Array<Real> & normal,
- GhostType ghost_type);
+ 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;
+ 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> &);
/// compute reversible energy
Real getReversibleEnergy();
/// compute dissipated energy
Real getDissipatedEnergy();
/// compute contact energy
Real getContactEnergy();
/// get energy
virtual Real getEnergy(std::string type);
/// return the energy (identified by id) for the provided element
virtual Real getEnergy(std::string energy_id, ElementType type, UInt index) {
return Material::getEnergy(energy_id, type, index);
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// list of facets assigned to this material
ElementTypeMapArray<UInt> facet_filter;
/// Link to the cohesive fem object in the model
MyFEEngineCohesiveType * fem_cohesive;
private:
/// reversible energy by quadrature point
CohesiveInternalField<Real> reversible_energy;
/// total energy by quadrature point
CohesiveInternalField<Real> total_energy;
protected:
/// opening in all elements and quadrature points
CohesiveInternalField<Real> opening;
/// opening in all elements and quadrature points (previous time step)
CohesiveInternalField<Real> opening_old;
/// traction in all elements and quadrature points
CohesiveInternalField<Real> tractions;
/// traction in all elements and quadrature points (previous time step)
CohesiveInternalField<Real> tractions_old;
/// traction due to contact
CohesiveInternalField<Real> contact_tractions;
/// normal openings for contact tractions
CohesiveInternalField<Real> contact_opening;
/// maximum displacement
CohesiveInternalField<Real> delta_max;
/// tell if the previous delta_max state is needed (in iterative schemes)
bool use_previous_delta_max;
+ /// tell if the previous opening state is needed (in iterative schemes)
+ bool use_previous_opening;
+
/// damage
CohesiveInternalField<Real> damage;
/// pointer to the solid mechanics model for cohesive elements
SolidMechanicsModelCohesive * model;
/// critical stress
RandomInternalField<Real, FacetInternalField> sigma_c;
+
+ /// critical displacement
+ Real delta_c;
+
+ /// array to temporarily store the normals
+ Array<Real> normal;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "material_cohesive_inline_impl.cc"
__END_AKANTU__
#include "cohesive_internal_field_tmpl.hh"
#endif /* __AKANTU_MATERIAL_COHESIVE_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc b/src/model/solid_mechanics/materials/material_cohesive/material_cohesive_inline_impl.cc
index 958271fd9..5c62b3eae 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,94 @@
/**
* @file material_cohesive_inline_impl.cc
*
* @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Feb 23 2012
* @date last modification: Thu Jun 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 03d6987dd..70ede7cf9 100644
--- a/src/model/solid_mechanics/materials/material_cohesive_includes.hh
+++ b/src/model/solid_mechanics/materials/material_cohesive_includes.hh
@@ -1,42 +1,46 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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
new file mode 100644
index 000000000..1e6a4d135
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_core_includes.hh
@@ -0,0 +1,69 @@
+/**
+ * @file material_list.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Tue Oct 29 2013
+ * @date last modification: Fri Sep 19 2014
+ *
+ * @brief List of materials for core package
+ *
+ * @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_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_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_damage_non_local.hh
index 0470be6ea..b7a09446b 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,103 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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_marigo.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
index 0ae32e74c..947a01332 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,105 @@
/**
* @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>
*
* @date creation: Thu Feb 02 2012
* @date last modification: Fri Mar 21 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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, 5000., ParamAccessType(_pat_parsable | _pat_modifiable));
- this->registerParam("epsilon_c", epsilon_c, 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->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();
}
-/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialMarigo);
+INSTANTIATE_MATERIAL(MaterialMarigo);
__END_AKANTU__
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 bfa104e82..2c2e83597 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,122 @@
/**
* @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>
*
* @date creation: Thu Feb 02 2012
* @date last modification: Tue Jun 24 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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,1.);
+ 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..5cdaefb9c 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,98 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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..c2d2a6b36 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,104 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 9dc3c9958..86ee96a34 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,83 @@
/**
* @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>
*
* @date creation: Wed Apr 06 2011
* @date last modification: Mon Feb 10 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 , 0.8 , _pat_parsable, "At");
- this->registerParam("Ac" , Ac , 1.4 , _pat_parsable, "Ac");
- this->registerParam("Bc" , Bc , 1900. , _pat_parsable, "Bc");
- this->registerParam("Bt" , Bt , 12000., _pat_parsable, "Bt");
- this->registerParam("beta", beta, 1.06 , _pat_parsable, "beta");
+ 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();
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialMazars);
+INSTANTIATE_MATERIAL(MaterialMazars);
__END_AKANTU__
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 fa1a062c4..58d8a993a 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,144 +1,153 @@
/**
* @file material_mazars_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
*
* @date creation: Wed Apr 06 2011
* @date last modification: Wed Mar 13 2013
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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(0., Fdiag(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(0., sigma_princ(i));
- sigma_p *= 1-dam;
+ 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(0., epsilon_princ(i));
+ 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, 1.);
+ alpha_t = std::min(alpha_t, Real(1.));
- Real alpha_c = 1 - alpha_t;
+ 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,1.);
+ 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 43b2598e1..abc0c22fb 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,149 @@
/**
* @file material_mazars_non_local.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
* @author Marion Estelle Chambart <marion.chambart@epfl.ch>
*
* @date creation: Mon Oct 03 2011
* @date last modification: Thu Jun 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_mazars_non_local.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialMazarsNonLocal<spatial_dimension>::MaterialMazarsNonLocal(SolidMechanicsModel & model,
const ID & id) :
Material(model, id),
MaterialMazars<spatial_dimension>(model, id),
MaterialNonLocalParent(model, id),
Ehat("epsilon_equ", *this) {
AKANTU_DEBUG_IN();
this->is_non_local = true;
this->Ehat.initialize(1);
this->registerParam("average_on_damage", this->damage_in_compute_stress, false,
_pat_parsable | _pat_modifiable, "Is D the non local variable");
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazarsNonLocal<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
MaterialMazars<spatial_dimension>::initMaterial();
MaterialNonLocalParent::initMaterial();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazarsNonLocal<spatial_dimension>::computeStress(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * damage = this->damage(el_type, ghost_type).storage();
Real * epsilon_equ = this->Ehat(el_type, ghost_type).storage();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
MaterialMazars<spatial_dimension>::computeStressOnQuad(grad_u, sigma,
*damage,
*epsilon_equ);
++damage;
++epsilon_equ;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazarsNonLocal<spatial_dimension>::computeNonLocalStresses(GhostType ghost_type) {
AKANTU_DEBUG_IN();
InternalField<Real> nl_var("Non local variable", *this);
nl_var.initialize(1);
- if(this->damage_in_compute_stress)
- this->weightedAvergageOnNeighbours(this->damage, nl_var, 1);
- else
- this->weightedAvergageOnNeighbours(this->Ehat, nl_var, 1);
-
- Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(spatial_dimension, ghost_type);
- for(; it != last_type; ++it) {
- this->computeNonLocalStress(nl_var(*it, ghost_type), *it, ghost_type);
- }
+
+ // if(this->damage_in_compute_stress)
+ // this->weightedAvergageOnNeighbours(this->damage, nl_var, 1);
+ // else
+ // this->weightedAvergageOnNeighbours(this->Ehat, nl_var, 1);
+
+ // Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(spatial_dimension, ghost_type);
+ // Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(spatial_dimension, ghost_type);
+ // for(; it != last_type; ++it) {
+ // this->computeNonLocalStress(nl_var(*it, ghost_type), *it, ghost_type);
+ // }
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialMazarsNonLocal<spatial_dimension>::computeNonLocalStress(Array<Real> & non_loc_var,
ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Real * damage;
Real * epsilon_equ;
if(this->damage_in_compute_stress){
damage = non_loc_var.storage();
epsilon_equ = this->Ehat(el_type, ghost_type).storage();
} else {
damage = this->damage(el_type, ghost_type).storage();
epsilon_equ = non_loc_var.storage();
}
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->computeDamageAndStressOnQuad(grad_u, sigma, *damage, *epsilon_equ);
++damage;
++epsilon_equ;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
-
/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialMazarsNonLocal<spatial_dimension>::nonLocalVariableToNeighborhood() {
+
+}
-INSTANSIATE_MATERIAL(MaterialMazarsNonLocal);
+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..b9a9b39ec 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,102 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 4787baf68..d6250fd6b 100644
--- a/src/model/solid_mechanics/materials/material_elastic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic.cc
@@ -1,229 +1,248 @@
/**
* @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>
*
* @date creation: Tue Jul 27 2010
* @date last modification: Tue Sep 16 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "material_elastic.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt dim>
MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
Parent(model, id) {
AKANTU_DEBUG_IN();
+ this->initialize();
+ AKANTU_DEBUG_OUT();
+}
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model,
+ UInt a_dim,
+ const Mesh & mesh,
+ FEEngine & fe_engine,
+ const ID & id) :
+ Material(model, dim, mesh, fe_engine, id),
+ Parent(model, dim, mesh, fe_engine, id) {
+ AKANTU_DEBUG_IN();
+ this->initialize();
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+void MaterialElastic<dim>::initialize() {
this->registerParam("lambda" ,lambda , _pat_readable, "First Lamé coefficient" );
this->registerParam("mu" ,mu , _pat_readable, "Second Lamé coefficient");
this->registerParam("kapa" ,kpa , _pat_readable, "Bulk coefficient" );
-
- AKANTU_DEBUG_OUT();
}
+
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialElastic<dim>::initMaterial() {
AKANTU_DEBUG_IN();
Parent::initMaterial();
if (dim == 1) this->nu = 0.;
this->updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialElastic<dim>::updateInternalParameters() {
MaterialThermal<dim>::updateInternalParameters();
this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2*this->nu));
this->mu = this->E / (2 * (1 + this->nu));
this->kpa = this->lambda + 2./3. * this->mu;
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialElastic<2>::updateInternalParameters() {
MaterialThermal<2>::updateInternalParameters();
this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2*this->nu));
this->mu = this->E / (2 * (1 + this->nu));
if(this->plane_stress) this->lambda = this->nu * this->E / ((1 + this->nu)*(1 - this->nu));
this->kpa = this->lambda + 2./3. * this->mu;
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Parent::computeStress(el_type, ghost_type);
Array<Real>::const_scalar_iterator sigma_th_it = this->sigma_th(el_type, ghost_type).begin();
if (!this->finite_deformation) {
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
const Real & sigma_th = *sigma_th_it;
this->computeStressOnQuad(grad_u, sigma, sigma_th);
++sigma_th_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
} else {
/// finite gradus
Matrix<Real> E(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
/// compute E
this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
const Real & sigma_th = *sigma_th_it;
/// compute second Piola-Kirchhoff stress tensor
this->computeStressOnQuad(E, sigma, sigma_th);
++sigma_th_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
Array<Real> & tangent_matrix,
__attribute__((unused)) GhostType ghost_type) {
AKANTU_DEBUG_IN();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
this->computeTangentModuliOnQuad(tangent);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialElastic<spatial_dimension>::getPushWaveSpeed(__attribute__((unused)) const Element & element) const {
return sqrt((lambda + 2*mu)/this->rho);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialElastic<spatial_dimension>::getShearWaveSpeed(__attribute__((unused)) const Element & element) const {
return sqrt(mu/this->rho);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computePotentialEnergy(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
MaterialThermal<spatial_dimension>::computePotentialEnergy(el_type, ghost_type);
if(ghost_type != _not_ghost) return;
Array<Real>::scalar_iterator epot = this->potential_energy(el_type, ghost_type).begin();
if (!this->finite_deformation) {
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->computePotentialEnergyOnQuad(grad_u, sigma, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
} else {
Matrix<Real> E(spatial_dimension, spatial_dimension);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
this->computePotentialEnergyOnQuad(E, sigma, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialElastic<spatial_dimension>::computePotentialEnergyByElement(ElementType type, UInt index,
Vector<Real> & epot_on_quad_points) {
Array<Real>::matrix_iterator gradu_it =
this->gradu(type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator gradu_end =
this->gradu(type).begin(spatial_dimension,
spatial_dimension);
Array<Real>::matrix_iterator stress_it =
this->stress(type).begin(spatial_dimension,
spatial_dimension);
if (this->finite_deformation)
stress_it = this->piola_kirchhoff_2(type).begin(spatial_dimension,
spatial_dimension);
- UInt nb_quadrature_points = this->model->getFEEngine().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) {
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);
}
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialElastic);
+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 5f9f0f810..a4e81fce5 100644
--- a/src/model/solid_mechanics/materials/material_elastic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic.hh
@@ -1,140 +1,156 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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);
+ 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 8f3bc379d..829b7ac36 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,107 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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) {
+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) {
+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 ddd7ecfff..90c43eb42 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
@@ -1,331 +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
*
* @brief Anisotropic elastic material
*
* @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_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), 0., _pat_parsmod,
+ 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 id default value
+ //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);
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialElasticLinearAnisotropic);
+INSTANTIATE_MATERIAL(MaterialElasticLinearAnisotropic);
__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
index cf62db2f6..c861535df 100644
--- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
@@ -1,210 +1,212 @@
/**
* @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>
*
* @date creation: Tue May 08 2012
* @date last modification: Fri Sep 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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 , 0., _pat_parsmod, "Young's modulus (n1)");
- this->registerParam("E2", E2 , 0., _pat_parsmod, "Young's modulus (n2)");
- this->registerParam("nu12", nu12, 0., _pat_parsmod, "Poisson's ratio (12)");
- this->registerParam("G12", G12 , 0., _pat_parsmod, "Shear modulus (12)");
+ 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 , 0., _pat_parsmod, "Young's modulus (n3)");
- this->registerParam("nu13", nu13, 0., _pat_parsmod, "Poisson's ratio (13)");
- this->registerParam("nu23", nu23, 0., _pat_parsmod, "Poisson's ratio (23)");
- this->registerParam("G13" , G13 , 0., _pat_parsmod, "Shear modulus (13)");
- this->registerParam("G23" , G23 , 0., _pat_parsmod, "Shear modulus (23)");
+ 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);
}
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialElasticOrthotropic);
+INSTANTIATE_MATERIAL(MaterialElasticOrthotropic);
__END_AKANTU__
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
new file mode 100644
index 000000000..33a91e935
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_embedded/embedded_internal_field.hh
@@ -0,0 +1,82 @@
+/**
+ * @file embedded_internal_field.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Thu Mar 19 2015
+ * @date last modification: Thu Mar 19 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..3c20a1b5e
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_embedded/material_embedded_includes.hh
@@ -0,0 +1,43 @@
+/**
+ * @file material_embedded_includes.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Fri Mar 13 2015
+ * @date last modification: Fri Mar 13 2015
+ *
+ * @brief List of includes for embedded 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#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
new file mode 100644
index 000000000..bfa8c03a3
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.cc
@@ -0,0 +1,742 @@
+/**
+ * @file material_reinforcement.cc
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Thu Mar 12 2015
+ * @date last modification: Thu Mar 12 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#include "aka_common.hh"
+#include "aka_voigthelper.hh"
+#include "material_reinforcement.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+MaterialReinforcement<dim>::MaterialReinforcement(SolidMechanicsModel & model,
+ UInt spatial_dimension,
+ const Mesh & mesh,
+ FEEngine & fe_engine,
+ const ID & id) :
+ Material(model, dim, mesh, fe_engine, id), // /!\ dim, not spatial_dimension !
+ model(NULL),
+ stress_embedded("stress_embedded", *this, 1, fe_engine, this->element_filter),
+ gradu_embedded("gradu_embedded", *this, 1, fe_engine, this->element_filter),
+ directing_cosines("directing_cosines", *this, 1, fe_engine, this->element_filter),
+ pre_stress("pre_stress", *this, 1, fe_engine, this->element_filter),
+ area(1.0),
+ shape_derivatives() {
+ AKANTU_DEBUG_IN();
+ this->initialize(model);
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+void MaterialReinforcement<dim>::initialize(SolidMechanicsModel & a_model) {
+ this->model = dynamic_cast<EmbeddedInterfaceModel *>(&a_model);
+ AKANTU_DEBUG_ASSERT(this->model != NULL, "MaterialReinforcement needs an EmbeddedInterfaceModel");
+
+ this->registerParam("area", area, _pat_parsable | _pat_modifiable,
+ "Reinforcement cross-sectional area");
+ this->registerParam("pre_stress", pre_stress, _pat_parsable | _pat_modifiable,
+ "Uniform pre-stress");
+
+ // Fool the AvgHomogenizingFunctor
+ //stress.initialize(dim * dim);
+
+
+ // Reallocate the element filter
+ this->element_filter.free();
+ this->model->getInterfaceMesh().initElementTypeMapArray(this->element_filter,
+ 1, 1, false, _ek_regular);
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim>
+MaterialReinforcement<dim>::~MaterialReinforcement() {
+ AKANTU_DEBUG_IN();
+
+ ElementTypeMap<ElementTypeMapArray<Real> *>::type_iterator it = shape_derivatives.firstType();
+ ElementTypeMap<ElementTypeMapArray<Real> *>::type_iterator end = shape_derivatives.lastType();
+
+ for (; it != end ; ++it) {
+ delete shape_derivatives(*it, _not_ghost);
+ delete shape_derivatives(*it, _ghost);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim>
+void MaterialReinforcement<dim>::initMaterial() {
+ Material::initMaterial();
+
+ stress_embedded.initialize(dim * dim);
+ gradu_embedded.initialize(dim * dim);
+ pre_stress.initialize(1);
+
+ /// We initialise the stuff that is not going to change during the simulation
+ this->allocBackgroundShapeDerivatives();
+ this->initBackgroundShapeDerivatives();
+ this->initDirectingCosines();
+}
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * Background shape derivatives need to be stored per background element
+ * types but also per embedded element type, which is why they are stored
+ * in an ElementTypeMap<ElementTypeMapArray<Real> *>. The outer ElementTypeMap
+ * refers to the embedded types, and the inner refers to the background types.
+ */
+template<UInt dim>
+void MaterialReinforcement<dim>::allocBackgroundShapeDerivatives() {
+ AKANTU_DEBUG_IN();
+
+ Mesh & interface_mesh = model->getInterfaceMesh();
+ Mesh & mesh = model->getMesh();
+
+ ghost_type_t::iterator int_ghost_it = ghost_type_t::begin();
+
+ // Loop over interface ghosts
+ for (; int_ghost_it != ghost_type_t::end() ; ++int_ghost_it) {
+ Mesh::type_iterator interface_type_it = interface_mesh.firstType(1, *int_ghost_it);
+ Mesh::type_iterator interface_type_end = interface_mesh.lastType(1, *int_ghost_it);
+
+ // Loop over interface types
+ for (; interface_type_it != interface_type_end ; ++interface_type_it) {
+ Mesh::type_iterator background_type_it = mesh.firstType(dim, *int_ghost_it);
+ Mesh::type_iterator background_type_end = mesh.lastType(dim, *int_ghost_it);
+
+ // Loop over background types
+ for (; background_type_it != background_type_end ; ++background_type_it) {
+ const ElementType & int_type = *interface_type_it;
+ const ElementType & back_type = *background_type_it;
+ const GhostType & int_ghost = *int_ghost_it;
+
+ std::string shaped_id = "embedded_shape_derivatives";
+
+ if (int_ghost == _ghost) shaped_id += ":ghost";
+
+ ElementTypeMapArray<Real> * shaped_etma = new ElementTypeMapArray<Real>(shaped_id, this->name);
+
+ UInt nb_points = Mesh::getNbNodesPerElement(back_type);
+ UInt nb_quad_points = model->getFEEngine("EmbeddedInterfaceFEEngine").getNbIntegrationPoints(int_type);
+ UInt nb_elements = element_filter(int_type, int_ghost).getSize();
+
+ // Alloc the background ElementTypeMapArray
+ shaped_etma->alloc(nb_elements * nb_quad_points,
+ dim * nb_points,
+ back_type);
+
+ // Insert the background ElementTypeMapArray in the interface ElementTypeMap
+ shape_derivatives(shaped_etma, int_type, int_ghost);
+ }
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim>
+void MaterialReinforcement<dim>::initBackgroundShapeDerivatives() {
+ AKANTU_DEBUG_IN();
+
+ Mesh & mesh = model->getMesh();
+
+ Mesh::type_iterator type_it = mesh.firstType(dim, _not_ghost);
+ Mesh::type_iterator type_end = mesh.lastType(dim, _not_ghost);
+
+ for (; type_it != type_end ; ++type_it) {
+ computeBackgroundShapeDerivatives(*type_it, _not_ghost);
+ //computeBackgroundShapeDerivatives(*type_it, _ghost);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim>
+void MaterialReinforcement<dim>::initDirectingCosines() {
+ AKANTU_DEBUG_IN();
+
+ Mesh & mesh = model->getInterfaceMesh();
+
+ Mesh::type_iterator type_it = mesh.firstType(1, _not_ghost);
+ Mesh::type_iterator type_end = mesh.lastType(1, _not_ghost);
+
+ const UInt voigt_size = getTangentStiffnessVoigtSize(dim);
+ directing_cosines.initialize(voigt_size * voigt_size);
+
+ for (; type_it != type_end ; ++type_it) {
+ computeDirectingCosines(*type_it, _not_ghost);
+ //computeDirectingCosines(*type_it, _ghost);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim>
+void MaterialReinforcement<dim>::assembleStiffnessMatrix(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Mesh & interface_mesh = model->getInterfaceMesh();
+
+ Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
+ Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
+
+ for (; type_it != type_end ; ++type_it) {
+ assembleStiffnessMatrix(*type_it, ghost_type);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim>
+void MaterialReinforcement<dim>::updateResidual(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ computeAllStresses(ghost_type);
+ assembleResidual(ghost_type);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim>
+void MaterialReinforcement<dim>::assembleResidual(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Mesh & interface_mesh = model->getInterfaceMesh();
+
+ Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
+ Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
+
+ for (; type_it != type_end ; ++type_it) {
+ assembleResidual(*type_it, ghost_type);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+void MaterialReinforcement<dim>::computeGradU(const ElementType & type, GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Array<UInt> & elem_filter = element_filter(type, ghost_type);
+ UInt nb_element = elem_filter.getSize();
+ UInt nb_quad_points = model->getFEEngine("EmbeddedInterfaceFEEngine").getNbIntegrationPoints(type);
+
+ Array<Real> & gradu_vec = gradu_embedded(type, ghost_type);
+
+ Mesh::type_iterator back_it = model->getMesh().firstType(dim, ghost_type);
+ Mesh::type_iterator back_end = model->getMesh().lastType(dim, ghost_type);
+
+ for (; back_it != back_end ; ++back_it) {
+ UInt nodes_per_background_e = Mesh::getNbNodesPerElement(*back_it);
+
+ Array<Real> & shapesd = shape_derivatives(type, ghost_type)->operator()(*back_it, ghost_type);
+
+ Array<UInt> * background_filter = new Array<UInt>(nb_element, 1, "background_filter");
+ filterInterfaceBackgroundElements(*background_filter, *back_it, type, ghost_type);
+
+ Array<Real> * disp_per_element = new Array<Real>(0, dim * nodes_per_background_e, "disp_elem");
+ FEEngine::extractNodalToElementField(model->getMesh(),
+ model->getDisplacement(),
+ *disp_per_element,
+ *back_it, ghost_type, *background_filter);
+
+ Array<Real>::matrix_iterator disp_it = disp_per_element->begin(dim, nodes_per_background_e);
+ Array<Real>::matrix_iterator disp_end = disp_per_element->end(dim, nodes_per_background_e);
+
+ Array<Real>::matrix_iterator shapes_it = shapesd.begin(dim, nodes_per_background_e);
+ Array<Real>::matrix_iterator grad_u_it = gradu_vec.begin(dim, dim);
+
+ for (; disp_it != disp_end ; ++disp_it) {
+ for (UInt i = 0; i < nb_quad_points; i++, ++shapes_it, ++grad_u_it) {
+ Matrix<Real> & B = *shapes_it;
+ Matrix<Real> & du = *grad_u_it;
+ Matrix<Real> & u = *disp_it;
+
+ du.mul<false, true>(u, B);
+ }
+ }
+
+ delete background_filter;
+ delete disp_per_element;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+void MaterialReinforcement<dim>::computeAllStresses(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Mesh::type_iterator it = model->getInterfaceMesh().firstType();
+ Mesh::type_iterator last_type = model->getInterfaceMesh().lastType();
+
+ for(; it != last_type; ++it) {
+ computeGradU(*it, ghost_type);
+ computeStress(*it, ghost_type);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+void MaterialReinforcement<dim>::assembleResidual(const ElementType & type, GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Mesh & mesh = model->getMesh();
+
+ Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
+ Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
+
+ for (; type_it != type_end ; ++type_it) {
+ assembleResidualInterface(type, *type_it, ghost_type);
+ }
+
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+/**
+ * Computes and assemble the residual. Residual in reinforcement is computed as :
+ * \f[
+ * \vec{r} = A_s \int_S{\mathbf{B}^T\mathbf{C}^T \vec{\sigma_s}\,\mathrm{d}s}
+ * \f]
+ */
+template<UInt dim>
+void MaterialReinforcement<dim>::assembleResidualInterface(const ElementType & interface_type,
+ const ElementType & background_type,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ UInt voigt_size = getTangentStiffnessVoigtSize(dim);
+
+ Array<Real> & residual = const_cast<Array<Real> &>(model->getResidual());
+
+ FEEngine & interface_engine = model->getFEEngine("EmbeddedInterfaceFEEngine");
+ FEEngine & background_engine = model->getFEEngine();
+
+ Array<UInt> & elem_filter = element_filter(interface_type, ghost_type);
+
+ UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
+ UInt nb_quadrature_points = interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
+ UInt nb_element = elem_filter.getSize();
+
+ UInt back_dof = dim * nodes_per_background_e;
+
+ Array<Real> & shapesd = shape_derivatives(interface_type, ghost_type)->operator()(background_type, ghost_type);
+
+ Array<Real> * integrant = new Array<Real>(nb_quadrature_points * nb_element,
+ back_dof,
+ "integrant");
+
+ Array<Real>::vector_iterator integrant_it =
+ integrant->begin(back_dof);
+ Array<Real>::vector_iterator integrant_end =
+ integrant->end(back_dof);
+
+ Array<Real>::matrix_iterator B_it =
+ shapesd.begin(dim, nodes_per_background_e);
+ Array<Real>::matrix_iterator C_it =
+ directing_cosines(interface_type, ghost_type).begin(voigt_size, voigt_size);
+ Array<Real>::matrix_iterator sigma_it =
+ stress_embedded(interface_type, ghost_type).begin(dim, dim);
+
+ Vector<Real> sigma(voigt_size);
+ Matrix<Real> Bvoigt(voigt_size, back_dof);
+ Vector<Real> Ct_sigma(voigt_size);
+
+ for (; integrant_it != integrant_end ; ++integrant_it,
+ ++B_it,
+ ++C_it,
+ ++sigma_it) {
+ VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*B_it, Bvoigt, nodes_per_background_e);
+ Matrix<Real> & C = *C_it;
+ Vector<Real> & BtCt_sigma = *integrant_it;
+
+ stressTensorToVoigtVector(*sigma_it, sigma);
+
+ Ct_sigma.mul<true>(C, sigma);
+ BtCt_sigma.mul<true>(Bvoigt, Ct_sigma);
+ BtCt_sigma *= area;
+ }
+
+
+ Array<Real> * residual_interface = new Array<Real>(nb_element, back_dof, "residual_interface");
+ interface_engine.integrate(*integrant,
+ *residual_interface,
+ back_dof,
+ interface_type, ghost_type,
+ elem_filter);
+
+ delete integrant;
+
+ Array<UInt> * background_filter = new Array<UInt>(nb_element, 1, "background_filter");
+
+ filterInterfaceBackgroundElements(*background_filter,
+ background_type, interface_type,
+ ghost_type);
+ background_engine.assembleArray(*residual_interface, residual,
+ model->getDOFSynchronizer().getLocalDOFEquationNumbers(),
+ dim, background_type, ghost_type, *background_filter, -1.0);
+ delete residual_interface;
+ delete background_filter;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+void MaterialReinforcement<dim>::filterInterfaceBackgroundElements(Array<UInt> & filter,
+ const ElementType & type,
+ const ElementType & interface_type,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ filter.resize(0);
+ filter.clear();
+
+ Array<Element> & elements = model->getInterfaceAssociatedElements(interface_type, ghost_type);
+ Array<UInt> & elem_filter = element_filter(interface_type, ghost_type);
+
+ Array<UInt>::scalar_iterator
+ filter_it = elem_filter.begin(),
+ filter_end = elem_filter.end();
+
+ for (; filter_it != filter_end ; ++filter_it) {
+ Element & elem = elements(*filter_it);
+ if (elem.type == type) filter.push_back(elem.element);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim>
+void MaterialReinforcement<dim>::computeDirectingCosines(const ElementType & type, GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Mesh & interface_mesh = this->model->getInterfaceMesh();
+
+ const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+ const UInt steel_dof = dim * nb_nodes_per_element;
+ const UInt voigt_size = getTangentStiffnessVoigtSize(dim);
+ const UInt nb_quad_points =
+ model->getFEEngine("EmbeddedInterfaceFEEngine").getNbIntegrationPoints(type, ghost_type);
+
+ Array<Real> node_coordinates(this->element_filter(type, ghost_type).getSize(), steel_dof);
+
+ this->model->getFEEngine().template extractNodalToElementField<Real>(interface_mesh,
+ interface_mesh.getNodes(),
+ node_coordinates,
+ type,
+ ghost_type,
+ this->element_filter(type, ghost_type));
+
+ Array<Real>::matrix_iterator
+ directing_cosines_it = directing_cosines(type, ghost_type).begin(voigt_size, voigt_size);
+
+ Array<Real>::matrix_iterator node_coordinates_it = node_coordinates.begin(dim, nb_nodes_per_element);
+ Array<Real>::matrix_iterator node_coordinates_end = node_coordinates.end(dim, nb_nodes_per_element);
+
+ for (; node_coordinates_it != node_coordinates_end ; ++node_coordinates_it) {
+ for (UInt i = 0 ; i < nb_quad_points ; i++, ++directing_cosines_it) {
+ Matrix<Real> & nodes = *node_coordinates_it;
+ Matrix<Real> & cosines = *directing_cosines_it;
+
+ computeDirectingCosinesOnQuad(nodes, cosines);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim>
+void MaterialReinforcement<dim>::assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Mesh & mesh = model->getMesh();
+
+ Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
+ Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
+
+ for (; type_it != type_end ; ++type_it) {
+ assembleStiffnessMatrixInterface(type, *type_it, ghost_type);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Computes the reinforcement stiffness matrix (Gomes & Awruch, 2001)
+ * \f[
+ * \mathbf{K}_e = \sum_{i=1}^R{A_i\int_{S_i}{\mathbf{B}^T
+ * \mathbf{C}_i^T \mathbf{D}_{s, i} \mathbf{C}_i \mathbf{B}\,\mathrm{d}s}}
+ * \f]
+ */
+template<UInt dim>
+void MaterialReinforcement<dim>::assembleStiffnessMatrixInterface(const ElementType & interface_type,
+ const ElementType & background_type,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ UInt voigt_size = getTangentStiffnessVoigtSize(dim);
+
+ SparseMatrix & K = const_cast<SparseMatrix &>(model->getStiffnessMatrix());
+
+ FEEngine & background_engine = model->getFEEngine();
+ FEEngine & interface_engine = model->getFEEngine("EmbeddedInterfaceFEEngine");
+
+ Array<UInt> & elem_filter = element_filter(interface_type, ghost_type);
+ Array<Real> & grad_u = gradu_embedded(interface_type, ghost_type);
+
+ UInt nb_element = elem_filter.getSize();
+ UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
+ UInt nb_quadrature_points = interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
+
+ UInt back_dof = dim * nodes_per_background_e;
+
+ UInt integrant_size = back_dof;
+
+ grad_u.resize(nb_quadrature_points * nb_element);
+
+ Array<Real> * tangent_moduli = new Array<Real>(nb_element * nb_quadrature_points,
+ 1, "interface_tangent_moduli");
+ tangent_moduli->clear();
+ computeTangentModuli(interface_type, *tangent_moduli, ghost_type);
+
+ Array<Real> & shapesd = shape_derivatives(interface_type, ghost_type)->operator()(background_type, ghost_type);
+
+ Array<Real> * integrant = new Array<Real>(nb_element * nb_quadrature_points,
+ integrant_size * integrant_size,
+ "B^t*C^t*D*C*B");
+ integrant->clear();
+
+ /// Temporary matrices for integrant product
+ Matrix<Real> Bvoigt(voigt_size, back_dof);
+ Matrix<Real> DC(voigt_size, voigt_size);
+ Matrix<Real> DCB(voigt_size, back_dof);
+ Matrix<Real> CtDCB(voigt_size, back_dof);
+
+ Array<Real>::scalar_iterator D_it = tangent_moduli->begin();
+ Array<Real>::scalar_iterator D_end = tangent_moduli->end();
+
+ Array<Real>::matrix_iterator C_it =
+ directing_cosines(interface_type, ghost_type).begin(voigt_size, voigt_size);
+ Array<Real>::matrix_iterator B_it =
+ shapesd.begin(dim, nodes_per_background_e);
+ Array<Real>::matrix_iterator integrant_it =
+ integrant->begin(integrant_size, integrant_size);
+
+ for (; D_it != D_end ; ++D_it, ++C_it, ++B_it, ++integrant_it) {
+ Real & D = *D_it;
+ Matrix<Real> & C = *C_it;
+ Matrix<Real> & B = *B_it;
+ Matrix<Real> & BtCtDCB = *integrant_it;
+
+ VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(B, Bvoigt, nodes_per_background_e);
+
+ DC.clear();
+ DC(0, 0) = D * area;
+ DC *= C;
+ DCB.mul<false, false>(DC, Bvoigt);
+ CtDCB.mul<true, false>(C, DCB);
+ BtCtDCB.mul<true, false>(Bvoigt, CtDCB);
+ }
+
+ delete tangent_moduli;
+
+ Array<Real> * K_interface = new Array<Real>(nb_element, integrant_size * integrant_size, "K_interface");
+ interface_engine.integrate(*integrant, *K_interface,
+ integrant_size * integrant_size,
+ interface_type, ghost_type,
+ elem_filter);
+
+ delete integrant;
+
+ Array<UInt> * background_filter = new Array<UInt>(nb_element, 1, "background_filter");
+
+ filterInterfaceBackgroundElements(*background_filter,
+ background_type, interface_type,
+ ghost_type);
+
+ background_engine.assembleMatrix(*K_interface, K, dim, background_type, ghost_type, *background_filter);
+
+ delete K_interface;
+ delete background_filter;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+/// In this function, type and ghost_type refer to background elements
+template<UInt dim>
+void MaterialReinforcement<dim>::computeBackgroundShapeDerivatives(const ElementType & type, GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Mesh & interface_mesh = model->getInterfaceMesh();
+
+ FEEngine & engine = model->getFEEngine();
+ FEEngine & interface_engine = model->getFEEngine("EmbeddedInterfaceFEEngine");
+
+ Mesh::type_iterator interface_type = interface_mesh.firstType();
+ Mesh::type_iterator interface_last = interface_mesh.lastType();
+
+ for (; interface_type != interface_last ; ++interface_type) {
+ Array<UInt> & filter = element_filter(*interface_type, ghost_type);
+
+ const UInt nb_elements = filter.getSize();
+ const UInt nb_nodes = Mesh::getNbNodesPerElement(type);
+ const UInt nb_quad_per_element = interface_engine.getNbIntegrationPoints(*interface_type);
+
+ Array<Real> quad_pos(nb_quad_per_element * nb_elements, dim, "interface_quad_points");
+ quad_pos.resize(nb_quad_per_element * nb_elements);
+ interface_engine.interpolateOnIntegrationPoints(interface_mesh.getNodes(),
+ quad_pos, dim, *interface_type,
+ ghost_type, filter);
+
+
+ Array<Real> & background_shapesd = shape_derivatives(*interface_type, ghost_type)->operator()(type, ghost_type);
+ background_shapesd.clear();
+
+ Array<UInt> * background_elements = new Array<UInt>(nb_elements, 1, "computeBackgroundShapeDerivatives:background_filter");
+ filterInterfaceBackgroundElements(*background_elements, type, *interface_type, ghost_type);
+
+ Array<UInt>::scalar_iterator
+ back_it = background_elements->begin(),
+ back_end = background_elements->end();
+
+ Array<Real>::matrix_iterator shapesd_it = background_shapesd.begin(dim, nb_nodes);
+
+ Array<Real>::vector_iterator quad_pos_it = quad_pos.begin(dim);
+
+
+ for (; back_it != back_end ; ++back_it) {
+ for (UInt i = 0 ; i < nb_quad_per_element ; i++, ++shapesd_it, ++quad_pos_it)
+ engine.computeShapeDerivatives(*quad_pos_it, *back_it, type, *shapesd_it, ghost_type);
+ }
+
+ delete background_elements;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+template<UInt dim>
+Real MaterialReinforcement<dim>::getEnergy(std::string id) {
+ AKANTU_DEBUG_IN();
+ if (id == "potential") {
+ Real epot = 0.;
+
+ computePotentialEnergyByElements();
+
+ Mesh::type_iterator
+ it = element_filter.firstType(spatial_dimension),
+ end = element_filter.lastType(spatial_dimension);
+
+ for (; it != end ; ++it) {
+ FEEngine & interface_engine = model->getFEEngine("EmbeddedInterfaceFEEngine");
+ epot += interface_engine.integrate(potential_energy(*it, _not_ghost),
+ *it, _not_ghost,
+ element_filter(*it, _not_ghost));
+ epot *= area;
+ }
+
+ return epot;
+ }
+
+ AKANTU_DEBUG_OUT();
+ return 0;
+}
+
+// /* -------------------------------------------------------------------------- */
+// template<UInt dim>
+// ElementTypeMap<UInt> MaterialReinforcement<dim>::getInternalDataPerElem(const ID & field_name,
+// const ElementKind & kind,
+// const ID & fe_engine_id) const {
+// return Material::getInternalDataPerElem(field_name, kind, "EmbeddedInterfaceFEEngine");
+// }
+
+
+// /* -------------------------------------------------------------------------- */
+// // Author is Guillaume Anciaux, see material.cc
+// template<UInt dim>
+// void MaterialReinforcement<dim>::flattenInternal(const std::string & field_id,
+// ElementTypeMapArray<Real> & internal_flat,
+// const GhostType ghost_type,
+// ElementKind element_kind) const {
+// AKANTU_DEBUG_IN();
+
+// if (field_id == "stress_embedded" || field_id == "inelastic_strain") {
+// Material::flattenInternalIntern(field_id,
+// internal_flat,
+// 1,
+// ghost_type,
+// _ek_not_defined,
+// &(this->element_filter),
+// &(this->model->getInterfaceMesh()));
+// }
+
+// AKANTU_DEBUG_OUT();
+// }
+
+
+/* -------------------------------------------------------------------------- */
+
+INSTANTIATE_MATERIAL(MaterialReinforcement);
+
+/* -------------------------------------------------------------------------- */
+
+__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
new file mode 100644
index 000000000..1969cd56f
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement.hh
@@ -0,0 +1,197 @@
+/**
+ * @file material_reinforcement.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Thu Mar 12 2015
+ * @date last modification: Thu Mar 12 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_MATERIAL_REINFORCEMENT_HH__
+#define __AKANTU_MATERIAL_REINFORCEMENT_HH__
+
+#include "aka_common.hh"
+
+#include "material.hh"
+#include "embedded_interface_model.hh"
+#include "embedded_internal_field.hh"
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/**
+ * @brief Material used to represent embedded reinforcements
+ *
+ * This class is used for computing the reinforcement stiffness matrix
+ * along with the reinforcement residual. Room is made for constitutive law,
+ * but actual use of contitutive laws is made in MaterialReinforcementTemplate.
+ *
+ * Be careful with the dimensions in this class :
+ * - this->spatial_dimension is always 1
+ * - the template parameter dim is the dimension of the problem
+ */
+template<UInt dim>
+class MaterialReinforcement : virtual public Material {
+
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// Constructor
+ MaterialReinforcement(SolidMechanicsModel & model,
+ UInt spatial_dimension,
+ const Mesh & mesh,
+ FEEngine & fe_engine,
+ const ID & id = "");
+
+ /// Destructor
+ virtual ~MaterialReinforcement();
+
+protected:
+ void initialize(SolidMechanicsModel & a_model);
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// Init the material
+ virtual void initMaterial();
+
+ /// Init the background shape derivatives
+ void initBackgroundShapeDerivatives();
+
+ /// Init the cosine matrices
+ void initDirectingCosines();
+
+ /// Assemble stiffness matrix
+ virtual void assembleStiffnessMatrix(GhostType ghost_type);
+
+ /// Update the residual
+ virtual void updateResidual(GhostType ghost_type = _not_ghost);
+
+ /// Assembled the residual
+ virtual void assembleResidual(GhostType ghost_type);
+
+ /// Compute all the stresses !
+ virtual void computeAllStresses(GhostType ghost_type);
+
+ /// Compute the stiffness parameter for elements of a type
+ virtual void computeTangentModuli(const ElementType & type,
+ Array<Real> & tangent,
+ GhostType ghost_type) = 0;
+
+ /// Compute energy
+ virtual Real getEnergy(std::string id);
+
+ // virtual ElementTypeMap<UInt> getInternalDataPerElem(const ID & field_name,
+ // const ElementKind & kind,
+ // const ID & fe_engine_id) const;
+
+ // /// Reimplementation of Material's function to accomodate for interface mesh
+ // virtual void flattenInternal(const std::string & field_id,
+ // ElementTypeMapArray<Real> & internal_flat,
+ // const GhostType ghost_type = _not_ghost,
+ // ElementKind element_kind = _ek_not_defined) const;
+
+ /* ------------------------------------------------------------------------ */
+ /* Protected methods */
+ /* ------------------------------------------------------------------------ */
+protected:
+ /// Allocate the background shape derivatives
+ void allocBackgroundShapeDerivatives();
+
+ /// Compute the directing cosines matrix for one element type
+ void computeDirectingCosines(const ElementType & type, GhostType ghost_type);
+
+ /// Compute the directing cosines matrix on quadrature points.
+ inline void computeDirectingCosinesOnQuad(const Matrix<Real> & nodes,
+ Matrix<Real> & cosines);
+
+ /// Assemble the stiffness matrix for an element type (typically _segment_2)
+ void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type);
+
+ /// Assemble the stiffness matrix for background & interface types
+ void assembleStiffnessMatrixInterface(const ElementType & interface_type,
+ const ElementType & background_type,
+ GhostType ghost_type);
+
+ /// Compute the background shape derivatives for a type
+ void computeBackgroundShapeDerivatives(const ElementType & type, GhostType ghost_type);
+
+ /// Filter elements crossed by interface of a type
+ void filterInterfaceBackgroundElements(Array<UInt> & filter,
+ const ElementType & type,
+ const ElementType & interface_type,
+ GhostType ghost_type);
+
+ /// Assemble the residual of one type of element (typically _segment_2)
+ void assembleResidual(const ElementType & type, GhostType ghost_type);
+
+ /// Assemble the residual for a pair of elements
+ void assembleResidualInterface(const ElementType & interface_type,
+ const ElementType & background_type,
+ GhostType ghost_type);
+
+ // TODO figure out why voigt size is 4 in 2D
+ inline void stressTensorToVoigtVector(const Matrix<Real> & tensor, Vector<Real> & vector);
+ inline void strainTensorToVoigtVector(const Matrix<Real> & tensor, Vector<Real> & vector);
+
+ /// Compute gradu on the interface quadrature points
+ virtual void computeGradU(const ElementType & type, GhostType ghost_type);
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+protected:
+ /// Embedded model
+ EmbeddedInterfaceModel * model;
+
+ /// Stress in the reinforcement
+ InternalField<Real> stress_embedded;
+
+ /// Gradu of concrete on reinforcement
+ InternalField<Real> gradu_embedded;
+
+ /// C matrix on quad
+ InternalField<Real> directing_cosines;
+
+ /// Prestress on quad
+ InternalField<Real> pre_stress;
+
+ /// Cross-sectional area
+ Real area;
+
+ /// Background mesh shape derivatives
+ ElementTypeMap< ElementTypeMapArray<Real> * > shape_derivatives;
+
+};
+
+#include "material_reinforcement_inline_impl.cc"
+
+__END_AKANTU__
+
+#endif // __AKANTU_MATERIAL_REINFORCEMENT_HH__
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_inline_impl.cc b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_inline_impl.cc
new file mode 100644
index 000000000..ec0b8e06f
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_inline_impl.cc
@@ -0,0 +1,123 @@
+/**
+ * @file material_reinforcement_inline_impl.cc
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Thu Mar 12 2015
+ * @date last modification: Thu Mar 12 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * 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
new file mode 100644
index 000000000..b62de7c69
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template.hh
@@ -0,0 +1,109 @@
+/**
+ * @file material_reinforcement_template.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Mon Mar 16 2015
+ * @date last modification: Mon Mar 16 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..a458c76bf
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_template_tmpl.hh
@@ -0,0 +1,182 @@
+/**
+ * @file material_reinforcement_template_tmpl.hh
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Mon Mar 16 2015
+ * @date last modification: Mon Mar 16 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// /!\ no namespace here !
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim, class ConstLaw>
+MaterialReinforcementTemplate<dim, ConstLaw>::MaterialReinforcementTemplate(SolidMechanicsModel & a_model,
+ const ID & id):
+ Material(a_model, 1,
+ dynamic_cast<EmbeddedInterfaceModel &>(a_model).getInterfaceMesh(),
+ a_model.getFEEngine("EmbeddedInterfaceFEEngine"), id),
+ MaterialReinforcement<dim>(a_model, 1,
+ dynamic_cast<EmbeddedInterfaceModel &>(a_model).getInterfaceMesh(),
+ a_model.getFEEngine("EmbeddedInterfaceFEEngine"), id),
+ ConstLaw(a_model, 1,
+ dynamic_cast<EmbeddedInterfaceModel &>(a_model).getInterfaceMesh(),
+ a_model.getFEEngine("EmbeddedInterfaceFEEngine"), id)
+{}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim, class ConstLaw>
+MaterialReinforcementTemplate<dim, ConstLaw>::~MaterialReinforcementTemplate()
+{}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim, class ConstLaw>
+void MaterialReinforcementTemplate<dim, ConstLaw>::initMaterial() {
+ MaterialReinforcement<dim>::initMaterial();
+ ConstLaw::initMaterial();
+
+ // Needed for plasticity law
+ this->ConstLaw::nu = 0.5;
+ this->ConstLaw::updateInternalParameters();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim, class ConstLaw>
+void MaterialReinforcementTemplate<dim, ConstLaw>::computeGradU(const ElementType & el_type,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ MaterialReinforcement<dim>::computeGradU(el_type, ghost_type);
+
+ const UInt voigt_size = Material::getTangentStiffnessVoigtSize(dim);
+
+ Array<Real>::matrix_iterator full_gradu_it =
+ this->MaterialReinforcement<dim>::gradu_embedded(el_type, ghost_type).begin(dim, dim);
+ Array<Real>::matrix_iterator full_gradu_end =
+ this->MaterialReinforcement<dim>::gradu_embedded(el_type, ghost_type).end(dim, dim);
+
+ Array<Real>::scalar_iterator gradu_it =
+ this->ConstLaw::gradu(el_type, ghost_type).begin();
+
+ Array<Real>::matrix_iterator cosines_it =
+ this->directing_cosines(el_type, ghost_type).begin(voigt_size, voigt_size);
+
+
+ for (; full_gradu_it != full_gradu_end ; ++full_gradu_it,
+ ++gradu_it,
+ ++cosines_it) {
+ Matrix<Real> & full_gradu = *full_gradu_it;
+ Real & gradu = *gradu_it;
+ Matrix<Real> & C = *cosines_it;
+
+ computeInterfaceGradUOnQuad(full_gradu, gradu, C);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim, class ConstLaw>
+void MaterialReinforcementTemplate<dim, ConstLaw>::computeInterfaceGradUOnQuad(const Matrix<Real> & full_gradu,
+ Real & gradu,
+ const Matrix<Real> & C) {
+ const UInt voigt_size = Material::getTangentStiffnessVoigtSize(dim);
+
+ Matrix<Real> epsilon(dim, dim);
+ Vector<Real> e_voigt(voigt_size);
+ Vector<Real> e_interface_voigt(voigt_size);
+
+ epsilon = 0.5 * (full_gradu + full_gradu.transpose());
+ MaterialReinforcement<dim>::strainTensorToVoigtVector(epsilon, e_voigt);
+ e_interface_voigt.mul<false>(C, e_voigt);
+
+ gradu = e_interface_voigt(0);
+}
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim, class ConstLaw>
+void MaterialReinforcementTemplate<dim, ConstLaw>::computeTangentModuli(const ElementType & el_type,
+ Array<Real> & tangent,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(tangent.getNbComponent() == 1, "Reinforcements only work in 1D");
+
+ ConstLaw::computeTangentModuli(el_type, tangent, ghost_type);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim, class ConstLaw>
+void MaterialReinforcementTemplate<dim, ConstLaw>::computeStress(ElementType type,
+ GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ ConstLaw::computeStress(type, ghost_type);
+
+ Array<Real>::matrix_iterator full_sigma_it =
+ this->MaterialReinforcement<dim>::stress_embedded(type, ghost_type).begin(dim, dim);
+ Array<Real>::matrix_iterator full_sigma_end =
+ this->MaterialReinforcement<dim>::stress_embedded(type, ghost_type).end(dim, dim);
+ Array<Real>::scalar_iterator sigma_it =
+ this->ConstLaw::stress(type, ghost_type).begin();
+ Array<Real>::scalar_iterator pre_stress_it =
+ this->MaterialReinforcement<dim>::pre_stress(type, ghost_type).begin();
+
+ for (; full_sigma_it != full_sigma_end ; ++full_sigma_it, ++sigma_it, ++pre_stress_it) {
+ Matrix<Real> & sigma = *full_sigma_it;
+
+ sigma(0, 0) = *sigma_it + *pre_stress_it;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+template<UInt dim, class ConstLaw>
+Real MaterialReinforcementTemplate<dim, ConstLaw>::getEnergy(std::string id) {
+ return MaterialReinforcement<dim>::getEnergy(id);
+}
+
+/* -------------------------------------------------------------------------- */
+
+template <UInt dim, class ConstLaw>
+void MaterialReinforcementTemplate<dim, ConstLaw>::computePotentialEnergy(ElementType type,
+ GhostType ghost_type) {
+ const UInt nb_elements = this->element_filter(type, ghost_type).getSize();
+ const UInt nb_quad = this->model->getFEEngine("EmbeddedInterfaceFEEngine").getNbIntegrationPoints(type);
+ this->ConstLaw::potential_energy.alloc(nb_quad * nb_elements, 1, type, ghost_type, 0.);
+
+ ConstLaw::computePotentialEnergy(type, ghost_type);
+}
+
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
index 9876a0dc0..919eaf50f 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
@@ -1,271 +1,271 @@
/**
* @file material_neohookean.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Mon Apr 08 2013
* @date last modification: Tue Sep 16 2014
*
* @brief Specialization of the material class for finite deformation neo-hookean material
*
* @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_neohookean.hh"
#include "solid_mechanics_model.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
MaterialNeohookean<spatial_dimension>::MaterialNeohookean(SolidMechanicsModel & model, const ID & id) :
PlaneStressToolbox<spatial_dimension>(model, id) {
AKANTU_DEBUG_IN();
- this->registerParam("E", E, 0., _pat_parsable | _pat_modifiable, "Young's modulus");
- this->registerParam("nu", nu, 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>
void MaterialNeohookean<spatial_dimension>::initMaterial() {
AKANTU_DEBUG_IN();
PlaneStressToolbox<spatial_dimension>::initMaterial();
if (spatial_dimension == 1) nu = 0.;
this->updateInternalParameters();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<> void MaterialNeohookean<2>::initMaterial() {
AKANTU_DEBUG_IN();
PlaneStressToolbox<2>::initMaterial();
this->updateInternalParameters();
if(this->plane_stress) this->third_axis_deformation.setDefaultValue(1.);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNeohookean<spatial_dimension>::updateInternalParameters() {
lambda = nu * E / ((1 + nu) * (1 - 2 * nu));
mu = E / (2 * (1 + nu));
kpa = lambda + 2. / 3. * mu;
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialNeohookean<dim>::computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
PlaneStressToolbox<dim>::computeCauchyStressPlaneStress(el_type, ghost_type);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialNeohookean<2>::computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
Array<Real>::matrix_iterator gradu_it =
this->gradu(el_type, ghost_type).begin(2, 2);
Array<Real>::matrix_iterator gradu_end =
this->gradu(el_type, ghost_type).end(2, 2);
Array<Real>::matrix_iterator piola_it =
this->piola_kirchhoff_2(el_type, ghost_type).begin(2, 2);
Array<Real>::matrix_iterator stress_it =
this->stress(el_type, ghost_type).begin(2, 2);
Array<Real>::const_scalar_iterator c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
Matrix<Real> F_tensor(2, 2);
for (; gradu_it != gradu_end; ++gradu_it, ++piola_it, ++stress_it, ++c33_it) {
Matrix<Real> & grad_u = *gradu_it;
Matrix<Real> & piola = *piola_it;
Matrix<Real> & sigma = *stress_it;
gradUToF<2 > (grad_u, F_tensor);
computeCauchyStressOnQuad<2 >(F_tensor, piola, sigma, *c33_it);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialNeohookean<dim>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeStressOnQuad(grad_u, sigma);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialNeohookean<2>::computeStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
if(this->plane_stress){
PlaneStressToolbox<2>::computeStress(el_type, ghost_type);
Array<Real>::const_scalar_iterator c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeStressOnQuad(grad_u, sigma, *c33_it);
++c33_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
else{
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeStressOnQuad(grad_u, sigma);
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt dim>
void MaterialNeohookean<dim>::computeThirdAxisDeformation(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialNeohookean<2>::computeThirdAxisDeformation(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(this->plane_stress, "The third component of the strain can only be computed for 2D problems in Plane Stress!!");
Array<Real>::scalar_iterator c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computeThirdAxisDeformationOnQuad(grad_u, *c33_it);
++c33_it;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNeohookean<spatial_dimension>::computePotentialEnergy(ElementType el_type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
Material::computePotentialEnergy(el_type, ghost_type);
if(ghost_type != _not_ghost) return;
Array<Real>::scalar_iterator epot = this->potential_energy(el_type, ghost_type).begin();
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
computePotentialEnergyOnQuad(grad_u, *epot);
++epot;
MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
void MaterialNeohookean<spatial_dimension>::computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
Array<Real> & tangent_matrix,
__attribute__((unused)) GhostType ghost_type) {
AKANTU_DEBUG_IN();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
computeTangentModuliOnQuad(tangent, grad_u);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void MaterialNeohookean<2>::computeTangentModuli(__attribute__((unused)) const ElementType & el_type,
Array<Real> & tangent_matrix,
__attribute__((unused)) GhostType ghost_type) {
AKANTU_DEBUG_IN();
if(this->plane_stress){
PlaneStressToolbox<2>::computeStress(el_type, ghost_type);
Array<Real>::const_scalar_iterator c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
computeTangentModuliOnQuad(tangent, grad_u, *c33_it);
++c33_it;
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
}
else{
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
computeTangentModuliOnQuad(tangent, grad_u);
MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialNeohookean<spatial_dimension>::getPushWaveSpeed(__attribute__((unused)) const Element & element) const {
return sqrt((this->lambda + 2 * this->mu) / this->rho);
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialNeohookean<spatial_dimension>::getShearWaveSpeed(__attribute__((unused)) const Element & element) const {
return sqrt(this->mu / this->rho);
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialNeohookean);
+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..9e2fb8e42 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,170 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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_non_local.cc b/src/model/solid_mechanics/materials/material_non_local.cc
new file mode 100644
index 000000000..85bae8601
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_non_local.cc
@@ -0,0 +1,152 @@
+/**
+ * @file material_non_local.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Thu Oct 8 15:12:27 2015
+ *
+ * @brief Implementation of material non-local
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "material_non_local.hh"
+/* -------------------------------------------------------------------------- */
+__BEGIN_AKANTU__
+/* -------------------------------------------------------------------------- */
+template<UInt DIM>
+MaterialNonLocal<DIM>::MaterialNonLocal(SolidMechanicsModel & model,
+ const ID & id) :
+ Material(model, id) {
+ AKANTU_DEBUG_IN();
+
+ NonLocalManager & manager = this->model->getNonLocalManager();
+ manager.registerNonLocalMaterial(*this);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+MaterialNonLocal<spatial_dimension>::~MaterialNonLocal() {
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::initMaterial() {
+ this->registerNeighborhood();
+ this->insertQuadsInNeighborhoods(_not_ghost);
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::insertQuadsInNeighborhoods(GhostType ghost_type) {
+
+ NonLocalManager & manager = this->model->getNonLocalManager();
+ UInt _spatial_dimension = this->model->getSpatialDimension();
+ AKANTU_DEBUG_ASSERT(_spatial_dimension == spatial_dimension, "This assert was inserted because the current variable shadows a template parameter: cannot know which to use");
+
+ InternalField<Real> quadrature_points_coordinates("quadrature_points_coordinates_tmp_nl", *this);
+ quadrature_points_coordinates.initialize(spatial_dimension);
+
+ /// intialize quadrature point object
+ IntegrationPoint q;
+ q.ghost_type = ghost_type;
+ q.kind = _ek_regular;
+
+ Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_regular);
+ Mesh::type_iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_regular);
+ for(; it != last_type; ++it) {
+ q.type = *it;
+ const Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
+ UInt nb_element = elem_filter.getSize();
+ if(nb_element) {
+ UInt nb_quad = this->fem->getNbIntegrationPoints(*it, ghost_type);
+ UInt nb_tot_quad = nb_quad * nb_element;
+
+ Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
+ quads.resize(nb_tot_quad);
+
+ this->model->getFEEngine().computeIntegrationPointsCoordinates(quads, *it, ghost_type, elem_filter);
+
+ Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
+ UInt * elem = elem_filter.storage();
+
+ for (UInt e = 0; e < nb_element; ++e) {
+ q.element = *elem;
+ for (UInt nq = 0; nq < nb_quad; ++nq) {
+ q.num_point = nq;
+ q.global_num = q.element * nb_quad + nq;
+ manager.insertQuad(q, *quad, this->name);
+ ++quad;
+ }
+ ++elem;
+ }
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::updateNonLocalInternals(ElementTypeMapReal & non_local_flattened, const ID & field_id, const UInt nb_component) {
+
+ for (ghost_type_t::iterator g = ghost_type_t::begin(); g != ghost_type_t::end(); ++g) {
+ GhostType ghost_type = *g;
+ /// loop over all types in the material
+ typedef ElementTypeMapArray<UInt>:: type_iterator iterator;
+ iterator it = this->element_filter.firstType(spatial_dimension, ghost_type, _ek_regular);
+ iterator last_type = this->element_filter.lastType(spatial_dimension, ghost_type, _ek_regular);
+ for(; it != last_type; ++it) {
+ ElementType el_type = *it;
+ Array<Real> & internal = this->getInternal<Real>(field_id)(el_type, ghost_type);
+ Array<Real>::vector_iterator internal_it = internal.begin(nb_component);
+ Array<Real> & internal_flat = non_local_flattened(el_type, ghost_type);
+ Array<Real>::const_vector_iterator internal_flat_it = internal_flat.begin(nb_component);
+ /// loop all elements for the given type
+ const Array<UInt> & filter = this->element_filter(el_type,ghost_type);
+ UInt nb_elements = filter.getSize();
+ UInt nb_quads = this->getFEEngine().getNbIntegrationPoints(el_type, ghost_type);
+ for (UInt e = 0; e < nb_elements; ++e) {
+ UInt global_el = filter(e);
+ for (UInt q = 0; q < nb_quads; ++q, ++internal_it) {
+ UInt global_quad = global_el * nb_quads + q;
+ *internal_it = internal_flat_it[global_quad];
+ }
+ }
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::updateResidual(GhostType ghost_type) {
+ AKANTU_EXCEPTION("this method has not been implemented");
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt spatial_dimension>
+void MaterialNonLocal<spatial_dimension>::registerNeighborhood() {
+ this->model->getNonLocalManager().registerNeighborhood(this->name, this->name);
+}
+
+/* -------------------------------------------------------------------------- */
+
+INSTANTIATE_MATERIAL(MaterialNonLocal);
+
+__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_non_local.hh b/src/model/solid_mechanics/materials/material_non_local.hh
index 0b3007bd9..61f8d4515 100644
--- a/src/model/solid_mechanics/materials/material_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_non_local.hh
@@ -1,180 +1,100 @@
/**
* @file material_non_local.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 31 2011
* @date last modification: Thu Jun 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 "non_local_manager.hh"
-#include "weight_function.hh"
-
-namespace akantu {
- class GridSynchronizer;
-}
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MATERIAL_NON_LOCAL_HH__
#define __AKANTU_MATERIAL_NON_LOCAL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
-template<UInt dim, template <UInt> class WeightFunction = BaseWeightFunction>
+template<UInt dim>
class MaterialNonLocal : public virtual Material {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
MaterialNonLocal(SolidMechanicsModel & model, const ID & id = "");
virtual ~MaterialNonLocal();
- template<typename T>
- class PairList : public ElementTypeMap< ElementTypeMapArray<T> > {};
/* ------------------------------------------------------------------------ */
/* 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 ElementTypeMapArray<T> & to_accumulate,
- ElementTypeMapArray<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(const Array<Element> & element_list,
+ const NewElementsEvent & event) {
+ AKANTU_DEBUG_ERROR("This is a case not taken into account!!!");
}
-
- AKANTU_GET_MACRO(PairList, pair_list, const PairList<UInt> &)
- 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
- PairList<UInt> pair_list;
- /// the weights associated to the pairs
- PairList<Real> pair_weight;
-
- /// 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..7280d38e5 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,39 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 8ac291d91..717767067 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,1212 +1,34 @@
/**
* @file material_non_local_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Aug 31 2011
* @date last modification: Mon Jun 23 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 <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();
-
- 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();
-
- 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);
-
- // >>>>>> DEBUG CODE >>>>>> //
-#if defined(AKANTU_DEBUG_TOOLS) && defined(AKANTU_CORE_CXX11)
- debug::element_manager.print
- (debug::_dm_material_non_local,
- [this, &quadrature_points_coordinates](const Element & el)->std::string {
- std::stringstream out;
- FEEngine & fem = this->model->getFEEngine();
-
- Mesh mesh(spatial_dimension, getID() + "mesh_tmp");
- mesh.addConnectivityType(_segment_2);
- Array<UInt> & connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(_segment_2));
- Array<Real> & nodes = const_cast<Array<Real> &>(mesh.getNodes());
- Array<bool> g_notg(0,1);
- Array<Real> dist(0,1);
- Array<Real> weight(0,1);
- Array<Real> damage(0,1);
- Array<Real> jac(0,1);
-
- UInt nb_quad_per_elem =
- this->model->getFEEngine().getNbQuadraturePoints(el.type,
- el.ghost_type);
-
- Array<Real>::const_vector_iterator quad_it = quadrature_points_coordinates(el.type, el.ghost_type).begin(spatial_dimension);
- std::map<Vector<Real>, UInt> numbering;
- UInt counter = 0;
- const Vector<Real> quad = quad_it[el.element * nb_quad_per_elem];
- numbering[el.element * nb_quad_per_elem] = counter++;
- nodes.push_back(quad);
- g_notg.push_back(el.ghost_type == _ghost);
- dist.push_back(quad.distance(quad));
- weight.push_back(0.);
- damage.push_back((getArray("damage", el.type, el.ghost_type)(el.element * fem.getNbQuadraturePoints(el.type, el.ghost_type))));
- jac.push_back(fem.getIntegratorInterface().getJacobians(el.type, el.ghost_type)(el.element * fem.getNbQuadraturePoints(el.type, el.ghost_type)));
-
- Vector<UInt> conn(2);
- conn(0) = 0;
-
- bool found = false;
- GhostType ghost_type1 = _not_ghost;
-
- for (ghost_type_t::iterator git = ghost_type_t::begin(); git != ghost_type_t::end(); ++git) {
- GhostType ghost_type2 = *git;
- UInt existing_pairs_num = ghost_type2 - _not_ghost;
- pair_type::iterator first_pair_types = existing_pairs[existing_pairs_num].begin();
- pair_type::iterator last_pair_types = existing_pairs[existing_pairs_num].end();
-
- // Compute the weights
- for (; first_pair_types != last_pair_types; ++first_pair_types) {
- ElementType type1 = first_pair_types->first;
- ElementType type2 = first_pair_types->second;
-
- const Array<UInt> & elem_mat_1 = element_filter(type1, ghost_type1);
- const Array<UInt> & elem_mat_2 = element_filter(type2, ghost_type2);
-
- const Array<UInt> & pairs = pair_list(type1, ghost_type1)(type2, ghost_type2);
- const Array<Real> & weights = pair_weight(type1, ghost_type1)(type2, ghost_type2);
-
- UInt nb_quad1 = fem.getNbQuadraturePoints(type1, ghost_type1);
- UInt nb_quad2 = fem.getNbQuadraturePoints(type2, ghost_type2);
-
- Array<UInt>::const_iterator< Vector<UInt> > first_pair = pairs.begin(2);
- Array<UInt>::const_iterator< Vector<UInt> > last_pair = pairs.end(2);
- Array<Real>::const_vector_iterator pair_w = weights.begin(2);
-
- for(;first_pair != last_pair; ++first_pair, ++pair_w) {
- UInt _q1 = (*first_pair)(0);
- UInt _q2 = (*first_pair)(1);
- QuadraturePoint q1(type1, elem_mat_1(_q1 / nb_quad1), _q1 % nb_quad1, ghost_type1);
- QuadraturePoint q2(type2, elem_mat_2(_q2 / nb_quad2), _q2 % nb_quad2, ghost_type2);
-
- if(el == (Element) q1 || el == (Element) q2) {
- QuadraturePoint q;
- Real w1;
- UInt ele;
- // Real w2;
- if(el == (Element) q1) {
- q = q2;
- w1 = (*pair_w)(0);
- ele = q.element * nb_quad2;
- // w2 = (*pair_w)(1);
- } else {
- q = q1;
- w1 = (*pair_w)(1);
- ele = q.element * nb_quad1;
- // w2 = (*pair_w)(0);
- }
-
- found = true;
-
- fem.getNbQuadraturePoints(q.type, q.ghost_type);
- quad_it = quadrature_points_coordinates(q.type, q.ghost_type).begin(spatial_dimension);
- const Vector<Real> & quad_coord = quad_it[q.element * nb_quad_per_elem];
- std::map<Vector<Real>, UInt>::iterator nit = numbering.find(quad_coord);
- if(nit != numbering.end()) {
- conn(1) = nit->second;
- if(conn(1) == 0) {
- weight(0) = w1;
- }
- } else {
- conn(1) = counter++;
- numbering[quad_coord] = conn(1);
- nodes.push_back(quad_coord);
- g_notg.push_back(q.ghost_type == _ghost);
- dist.push_back(quad.distance(quad_coord));
- weight.push_back(w1);
- damage.push_back((getArray("damage", q.type, q.ghost_type)(q.global_num)));
- jac.push_back(fem.getIntegratorInterface().getJacobians(q.type, q.ghost_type)(ele));
- }
- connectivity.push_back(conn);
- }
- }
- }
- }
- if(found) {
- std::stringstream sstr;
- sstr << "neigh_mesh" << el;
- out << "./neighbors" << sstr.str() << " dumped!";
- DumperParaview dumper(sstr.str(), "./neighbors", false);
- dumper.registerMesh(mesh);
- dumper.registerField("ghost", new DumperIOHelper::NodalField<bool>(g_notg));
- dumper.registerField("distance", new DumperIOHelper::NodalField<Real>(dist));
- dumper.registerField("weight", new DumperIOHelper::NodalField<Real>(weight));
- dumper.registerField("damage", new DumperIOHelper::NodalField<Real>(damage));
- dumper.registerField("jacobian", new DumperIOHelper::NodalField<Real>(jac));
- dumper.dump();
- }
-
- return out.str();
- });
-#endif
- // <<<<<< DEBUG CODE <<<<<< //
-
-
- 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;
-
- pair_type::const_iterator first_pair_types = existing_pairs[1].begin();
- pair_type::const_iterator last_pair_types = existing_pairs[1].end();
- for (; first_pair_types != last_pair_types; ++first_pair_types) {
- ElementType type2 = first_pair_types->second;
- GhostType ghost_type2 = _ghost;
- UInt nb_quad2 = this->model->getFEEngine().getNbQuadraturePoints(type2);
- Array<UInt> & elem_filter = element_filter(type2, ghost_type2);
-
- const Array<UInt> & pairs =
- pair_list(first_pair_types->first, _not_ghost)(first_pair_types->second, ghost_type2);
- Array<UInt>::const_iterator< Vector<UInt> > first_pair = pairs.begin(2);
- Array<UInt>::const_iterator< Vector<UInt> > last_pair = pairs.end(2);
- for(;first_pair != last_pair; ++first_pair) {
- UInt _q2 = (*first_pair)(1);
- QuadraturePoint q2(type2, elem_filter(_q2 / nb_quad2), _q2 % nb_quad2, ghost_type2);
- 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;
- 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> & elem_filter = element_filter(*it, _ghost);
- Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
- UInt ng = 0;
- for (UInt g = 0; g < nb_ghost_elem; ++g) {
- element.element = elem_filter(g);
- if(element.element >= nb_ghost_elem_protected &&
- (std::find(relevant_ghost_element.begin(),
- relevant_ghost_element.end(),
- element) == relevant_ghost_element.end())) {
- ghost_to_erase.insert(element);
- remove_elem.getList().push_back(element);
-
- new_numbering(g) = UInt(-1);
- } else {
- 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);
-
- computeQuadraturePointsCoordinates(quadrature_points_coordinates, _not_ghost);
- fillCellList(quadrature_points_coordinates, _not_ghost);
-
- is_creating_grid = true;
- SynchronizerRegistry & synch_registry = this->model->getSynchronizerRegistry();
- std::stringstream sstr; sstr << getID() << ":grid_synchronizer";
- grid_synchronizer = GridSynchronizer::createGridSynchronizer(mesh,
- *spatial_grid,
- sstr.str());
- synch_registry.registerSynchronizer(*grid_synchronizer, _gst_mnl_for_average);
- synch_registry.registerSynchronizer(*grid_synchronizer, _gst_mnl_weight);
- is_creating_grid = false;
-
-#if not defined(AKANTU_NDEBUG)
- Mesh * mesh_tmp = NULL;
- if(AKANTU_DEBUG_TEST(dblDump)) {
- mesh_tmp = new Mesh(spatial_dimension, "mnl_grid");
- spatial_grid->saveAsMesh(*mesh_tmp);
- std::stringstream sstr_grid;
- StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- Int prank = comm.whoAmI();
-
- sstr_grid << "material_non_local_grid_" << std::setfill('0') << std::setw(4) << prank << ".msh";
- mesh_tmp->write(sstr_grid.str());
- delete mesh_tmp;
- }
-#endif
-
- this->computeQuadraturePointsCoordinates(quadrature_points_coordinates, _ghost);
- fillCellList(quadrature_points_coordinates, _ghost);
-
-#if not defined(AKANTU_NDEBUG)
- if(AKANTU_DEBUG_TEST(dblDump)) {
- mesh_tmp = new Mesh(spatial_dimension, "mnl_grid");
- spatial_grid->saveAsMesh(*mesh_tmp);
- std::stringstream sstr_grid;
- StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- Int prank = comm.whoAmI();
-
- sstr_grid.str(std::string());
- sstr_grid << "material_non_local_grid_ghost_" << std::setfill('0') << std::setw(4) << prank << ".msh";
-
- mesh_tmp->write(sstr_grid.str());
- delete mesh_tmp;
- }
-#endif
-
- 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) {
- Mesh & mesh = this->model->getFEEngine().getMesh();
-
- QuadraturePoint q;
- q.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) {
- 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.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();
-
- Mesh & mesh = this->model->getFEEngine().getMesh();
-
- GhostType ghost_type = _not_ghost;
- QuadraturePoint quad_point;
- quad_point.ghost_type = ghost_type;
-
- // generate the pair of neighbor depending of the cell_list
- 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) {
- // Preparing datas
- const Array<Real> & quads = quadrature_points_coordinates(*it, ghost_type);
- Array<Real>::const_vector_iterator first_quad = quads.begin(spatial_dimension);
- Array<Real>::const_vector_iterator last_quad = quads.end(spatial_dimension);
-
- ElementTypeMapArray<UInt> & pairs = pair_list(ElementTypeMapArray<UInt>("pairs", getID(), memory_id),
- *it,
- ghost_type);
-
- ElementType current_element_type = _not_defined;
- GhostType current_ghost_type = _casper;
- UInt existing_pairs_num = 0;
-
- Array<UInt> * neighbors = NULL;
- Array<UInt>::const_iterator< Vector<UInt> > element_index_material_it;
- Array<Real>::const_vector_iterator quad_coord_it;
-
- UInt my_num_quad = 0;
- quad_point.type = *it;
- // loop over quad points
- for(;first_quad != last_quad; ++first_quad, ++my_num_quad) {
- SpatialGrid<QuadraturePoint>::CellID cell_id = spatial_grid->getCellID(*first_quad);
-
- 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);
-
- quad_point.element = my_num_quad / this->model->getFEEngine().getNbQuadraturePoints(*it,
- quad_point.ghost_type);
-
- // 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 quad = *first_neigh_quad;
- UInt nb_quad_per_elem =
- this->model->getFEEngine().getNbQuadraturePoints(quad.type,
- quad.ghost_type);
-
- // little optimization to not search in the map at each quad points
- if(quad.type != current_element_type ||
- quad.ghost_type != current_ghost_type) {
-
- current_element_type = quad.type;
- current_ghost_type = quad.ghost_type;
- existing_pairs_num = quad.ghost_type == _not_ghost ? 0 : 1;
- if(!pairs.exists(current_element_type, current_ghost_type)) {
- neighbors = &(pairs.alloc(0, 2,
- current_element_type,
- current_ghost_type));
- } else {
- neighbors = &(pairs(current_element_type,
- current_ghost_type));
- }
- existing_pairs[existing_pairs_num].insert(std::pair<ElementType,
- ElementType>(*it,
- current_element_type));
- element_index_material_it = this->model->getElementIndexByMaterial(current_element_type,
- current_ghost_type).begin(2);
- quad_coord_it = quadrature_points_coordinates(current_element_type, current_ghost_type).begin(spatial_dimension);
- }
-
- const Vector<UInt> & el_mat = element_index_material_it[quad.element];
- UInt neigh_num_quad = el_mat(1) * nb_quad_per_elem + quad.num_point;
- const Vector<Real> & neigh_quad = quad_coord_it[neigh_num_quad];
-
- Real distance = first_quad->distance(neigh_quad);
- if(distance <= weight_func->getRadius() &&
- (quad.ghost_type == _ghost ||
- (quad.ghost_type == _not_ghost && my_num_quad <= neigh_num_quad))) { // storing only half lists
- UInt pair[2];
- pair[0] = my_num_quad;
- pair[1] = neigh_num_quad;
- neighbors->push_back(pair);
-
- // >>>>>> DEBUG CODE >>>>>> //
-#if defined(AKANTU_DEBUG_TOOLS) && defined(AKANTU_CORE_CXX11)
- debug::element_manager.print
- (debug::_dm_material_non_local,
- [this, &first_quad, &neigh_quad, &distance,
- &quad_point, &quad](const Element & el)->std::string {
- std::stringstream out;
- if((Element) quad_point == el) {
- out << " neigh1: " << quad << " -- " << *first_quad << " " << neigh_quad << " dist: " << distance;
- }
- if((Element) quad == el) {
- out << " neigh2: " << quad_point << " -- " << *first_quad << " " << neigh_quad << " dist: " << distance;
- }
- return out.str();
- });
-#endif
- // <<<<<< DEBUG CODE <<<<<< //
- }
- }
- }
- }
- }
-
- 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();
-
- GhostType ghost_type1;
- ghost_type1 = _not_ghost;
-
- 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;
- UInt existing_pairs_num = gt - _not_ghost;
- pair_type::iterator first_pair_types = existing_pairs[existing_pairs_num].begin();
- pair_type::iterator last_pair_types = existing_pairs[existing_pairs_num].end();
-
- // Compute the weights
- for (; first_pair_types != last_pair_types; ++first_pair_types) {
- ElementType type1 = first_pair_types->first;
- ElementType type2 = first_pair_types->second;
-
- const Array<UInt> & pairs = pair_list(type1, ghost_type1)(type2, ghost_type2);
-
- std::string ghost_id = "";
- if (ghost_type1 == _ghost) ghost_id = ":ghost";
-
- ElementTypeMapArray<Real> & weights_type_1 = pair_weight(type1, ghost_type1);
- std::stringstream sstr; sstr << getID() << ":pair_weight:" << type1 << ghost_id;
- weights_type_1.setID(sstr.str());
-
- Array<Real> * tmp_weight = NULL;
- if(!weights_type_1.exists(type2, ghost_type2)) {
- tmp_weight = &(weights_type_1.alloc(0, 2, type2, ghost_type2));
- } else {
- tmp_weight = &(weights_type_1(type2, ghost_type2));
- }
- Array<Real> & weights = *tmp_weight;
- weights.resize(pairs.getSize());
- weights.clear();
-
- const Array<Real> & jacobians_1 = fem.getIntegratorInterface().getJacobians(type1, ghost_type1);
- const Array<Real> & jacobians_2 = fem.getIntegratorInterface().getJacobians(type2, ghost_type2);
-
- const Array<UInt> & elem_mat_1 = element_filter(type1, ghost_type1);
- const Array<UInt> & elem_mat_2 = element_filter(type2, ghost_type2);
-
- UInt nb_quad1 = fem.getNbQuadraturePoints(type1);
- UInt nb_quad2 = fem.getNbQuadraturePoints(type2);
-
- Array<Real> & quads_volumes1 = quadrature_points_volumes(type1, ghost_type1);
- Array<Real> & quads_volumes2 = quadrature_points_volumes(type2, ghost_type2);
-
- Array<Real>::const_vector_iterator iquads1;
- Array<Real>::const_vector_iterator iquads2;
- iquads1 = quadrature_points_coordinates(type1, ghost_type1).begin(spatial_dimension);
- iquads2 = quadrature_points_coordinates(type2, ghost_type2).begin(spatial_dimension);
-
- Array<UInt>::const_iterator< Vector<UInt> > first_pair = pairs.begin(2);
- Array<UInt>::const_iterator< Vector<UInt> > last_pair = pairs.end(2);
- Array<Real>::vector_iterator weight = weights.begin(2);
-
- this->weight_func->selectType(type1, ghost_type1, type2, ghost_type2);
-
- // Weight function
- for(;first_pair != last_pair; ++first_pair, ++weight) {
- UInt _q1 = (*first_pair)(0);
- UInt _q2 = (*first_pair)(1);
- const Vector<Real> & pos1 = iquads1[_q1];
- const Vector<Real> & pos2 = iquads2[_q2];
- QuadraturePoint q1(_q1 / nb_quad1, _q1 % nb_quad1, _q1, pos1, type1, ghost_type1);
- QuadraturePoint q2(_q2 / nb_quad2, _q2 % nb_quad2, _q2, pos2, type2, ghost_type2);
-
- Real r = pos1.distance(pos2);
-
- Real w2J2 = jacobians_2(elem_mat_2(q2.element)*nb_quad2 + q2.num_point);
- Real w = this->weight_func->operator()(r, q1, q2);
- (*weight)(0) = w2J2 * w;
- quads_volumes1(_q1) += (*weight)(0);
-
- if(ghost_type2 != _ghost && _q1 != _q2) {
- Real w1J1 = jacobians_1(elem_mat_1(q1.element)*nb_quad1 + q1.num_point);
- (*weight)(1) = w1J1 * this->weight_func->operator()(r, q2, q1);
- quads_volumes2(_q2) += (*weight)(1);
- } else
- (*weight)(1) = 0;
- }
- }
- }
-
- //normalize the weights
- for(UInt gt = _not_ghost; gt <= _ghost; ++gt) {
- GhostType ghost_type2 = (GhostType) gt;
- UInt existing_pairs_num = gt - _not_ghost;
- pair_type::iterator first_pair_types = existing_pairs[existing_pairs_num].begin();
- pair_type::iterator last_pair_types = existing_pairs[existing_pairs_num].end();
-
- first_pair_types = existing_pairs[existing_pairs_num].begin();
- for (; first_pair_types != last_pair_types; ++first_pair_types) {
- ElementType type1 = first_pair_types->first;
- ElementType type2 = first_pair_types->second;
-
- const Array<UInt> & pairs = pair_list(type1, ghost_type1)(type2, ghost_type2);
- Array<Real> & weights = pair_weight(type1, ghost_type1)(type2, ghost_type2);
-
- Array<Real> & quads_volumes1 = quadrature_points_volumes(type1, ghost_type1);
- Array<Real> & quads_volumes2 = quadrature_points_volumes(type2, ghost_type2);
-
- Array<UInt>::const_iterator< Vector<UInt> > first_pair = pairs.begin(2);
- Array<UInt>::const_iterator< Vector<UInt> > last_pair = pairs.end(2);
- Array<Real>::vector_iterator weight = weights.begin(2);
-
- for(;first_pair != last_pair; ++first_pair, ++weight) {
- UInt q1 = (*first_pair)(0);
- UInt q2 = (*first_pair)(1);
-
- (*weight)(0) *= 1. / quads_volumes1(q1);
- if(ghost_type2 != _ghost) (*weight)(1) *= 1. / quads_volumes2(q2);
- }
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-template<UInt spatial_dimension, template <UInt> class WeightFunction>
-template<typename T>
-void MaterialNonLocal<spatial_dimension, WeightFunction>::weightedAvergageOnNeighbours(const ElementTypeMapArray<T> & to_accumulate,
- ElementTypeMapArray<T> & accumulated,
- UInt nb_degree_of_freedom,
- GhostType ghost_type2) const {
- AKANTU_DEBUG_IN();
-
- UInt existing_pairs_num = 0;
- if (ghost_type2 == _ghost) existing_pairs_num = 1;
-
- 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();
-
- GhostType ghost_type1 = _not_ghost; // does not make sens the ghost vs ghost so this should always by _not_ghost
-
- 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);
- const Array<Real> & weights =
- pair_weight(first_pair_types->first, ghost_type1)(first_pair_types->second, ghost_type2);
-
- const Array<T> & to_acc = to_accumulate(first_pair_types->second, ghost_type2);
- Array<T> & acc = accumulated(first_pair_types->first, ghost_type1);
-
- if(ghost_type2 == _not_ghost) acc.clear();
-
- Array<UInt>::const_iterator< Vector<UInt> > first_pair = pairs.begin(2);
- Array<UInt>::const_iterator< Vector<UInt> > last_pair = pairs.end(2);
- Array<Real>::const_vector_iterator pair_w = weights.begin(2);
-
- for(;first_pair != last_pair; ++first_pair, ++pair_w) {
- UInt q1 = (*first_pair)(0);
- UInt q2 = (*first_pair)(1);
- for(UInt d = 0; d < nb_degree_of_freedom; ++d){
- acc(q1, d) += (*pair_w)(0) * to_acc(q2, d);
- if(ghost_type2 != _ghost) acc(q2, d) += (*pair_w)(1) * to_acc(q1, d);
- }
- }
- }
-
- 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);
-
- // >>>>>> DEBUG CODE >>>>>> //
-#if defined(AKANTU_DEBUG_TOOLS)
-#if defined(AKANTU_CORE_CXX11)
- debug::element_manager.print(debug::_dm_material,
- [non_local_variable, &element_filter](const Element & el)->std::string {
- std::stringstream out;
- if(element_filter.exists(el.type, el.ghost_type)) {
- UInt pos = element_filter(el.type, el.ghost_type).find(el.element);
- if(pos != UInt(-1)) {
- out << (*non_local_variable.local)(el.type, el.ghost_type).getID()
- << ": loc "
- << (*non_local_variable.local)(el.type, el.ghost_type).begin(non_local_variable.nb_component)[pos]
- << " - non loc "
- << (*non_local_variable.non_local)(el.type, el.ghost_type).begin(non_local_variable.nb_component)[pos];
- }
- }
- return out.str();
- });
-#else
- debug::element_manager.printData(debug::_dm_material, "MaterialNonLocal: computeAllNonLocalStress",
- *non_local_variable.local, this->element_filter);
- debug::element_manager.printData(debug::_dm_material, "MaterialNonLocal: computeAllNonLocalStress",
- *non_local_variable.non_local, this->element_filter);
-#endif
-#endif
- // <<<<<< DEBUG CODE <<<<<< //
- }
-
- computeNonLocalStresses(_not_ghost);
-
- // >>>>>> DEBUG CODE >>>>>> //
-#if defined(AKANTU_DEBUG_TOOLS) && defined(AKANTU_CORE_CXX11)
- ElementTypeMapArray<Real> quadrature_points_coordinates("quadrature_points_coordinates", id);
- 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);
-
- debug::element_manager.print
- (debug::_dm_material_non_local,
- [this, &quadrature_points_coordinates](const Element & el)->std::string {
- static UInt step = 0;
- std::stringstream out;
-
- GhostType ghost_type1 = _not_ghost;
- FEEngine & fem = this->model->getFEEngine();
- Mesh & mesh = this->model->getMesh();
-
- std::ofstream quad_out;
- std::stringstream sstro;
- sstro << "neigh_vals_" << el.element << ".csv";
- if(step == 0) {
- quad_out.open(sstro.str());
- quad_out << "#id,step,gt,realid,w1,w2";
- for (UInt i = 0; i < spatial_dimension; ++i) {
- std::stringstream sstr; sstr << ",x" << i ;
- quad_out << sstr.str();
- }
- quad_out << ",dam,jac";
-
- 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;
- for (UInt i = 0; i < non_local_variable.nb_component; ++i) {
- std::stringstream sstr; sstr << "," << non_local_variable.local->getID() << i;
- quad_out << sstr.str();
- }
- for (UInt i = 0; i < non_local_variable.nb_component; ++i) {
- std::stringstream sstr; sstr << "," << non_local_variable.non_local->getID() << i;
- quad_out << sstr.str();
- }
- }
- quad_out << std::endl;
- } else {
- quad_out.open(sstro.str(), std::ios_base::app);
- }
- quad_out.precision(16);
-
- for (ghost_type_t::iterator git = ghost_type_t::begin(); git != ghost_type_t::end(); ++git) {
- GhostType ghost_type2 = *git;
- UInt existing_pairs_num = ghost_type2 - _not_ghost;
- pair_type::iterator first_pair_types = existing_pairs[existing_pairs_num].begin();
- pair_type::iterator last_pair_types = existing_pairs[existing_pairs_num].end();
-
- // Compute the weights
- for (; first_pair_types != last_pair_types; ++first_pair_types) {
- ElementType type1 = first_pair_types->first;
- ElementType type2 = first_pair_types->second;
-
- const Array<UInt> & elem_mat_1 = element_filter(type1, ghost_type1);
- const Array<UInt> & elem_mat_2 = element_filter(type2, ghost_type2);
-
- UInt nb_quad1 = fem.getNbQuadraturePoints(type1, ghost_type1);
- UInt nb_quad2 = fem.getNbQuadraturePoints(type2, ghost_type2);
-
- const Array<UInt> & pairs = pair_list(type1, ghost_type1)(type2, ghost_type2);
- const Array<Real> & weights = pair_weight(type1, ghost_type1)(type2, ghost_type2);
-
- Array<UInt>::const_iterator< Vector<UInt> > first_pair = pairs.begin(2);
- Array<UInt>::const_iterator< Vector<UInt> > last_pair = pairs.end(2);
- Array<Real>::const_vector_iterator pair_w = weights.begin(2);
-
- for(;first_pair != last_pair; ++first_pair, ++pair_w) {
- UInt _q1 = (*first_pair)(0);
- UInt _q2 = (*first_pair)(1);
-
- QuadraturePoint q1(type1, elem_mat_1(_q1 / nb_quad1), _q1 % nb_quad1, ghost_type1);
- QuadraturePoint q2(type2, elem_mat_2(_q2 / nb_quad2), _q2 % nb_quad2, ghost_type2);
- q1.global_num = _q1;
- q2.global_num = _q2;
-
- if(el == (Element) q1 || el == (Element) q2) {
- QuadraturePoint q;
- Real w1, w2;
- UInt nb_quad;
- if(el == (Element) q1) {
- q = q2;
- nb_quad = nb_quad2;
- w1 = (*pair_w)(0);
- w2 = (*pair_w)(1);
- } else {
- q = q1;
- nb_quad = nb_quad1;
- w1 = (*pair_w)(1);
- w2 = (*pair_w)(0);
- }
-
- quad_out << ((q.ghost_type == _ghost ? mesh.getNbElement(q.type, q.ghost_type) : 0) + q.global_num)
- << "," << step << "," << q.ghost_type << "," << q.global_num;
- quad_out << "," << w1 << "," << w2;
- Array<Real>::const_vector_iterator iquads =
- quadrature_points_coordinates(q.type, q.ghost_type).begin(spatial_dimension);
- const Vector<Real> & coord = iquads[q.global_num];
- for(UInt i(0); i < coord.size(); ++i) {
- quad_out << "," << coord(i);
- }
-
- typename std::map<ID, NonLocalVariable>::iterator nlit = non_local_variables.begin();
- typename std::map<ID, NonLocalVariable>::iterator nlend = non_local_variables.end();
- for(;nlit != nlend; ++nlit) {
- NonLocalVariable & non_local_variable = nlit->second;
- const Array<Real> & local = (*non_local_variable.local)(q.type, q.ghost_type);
- for(UInt i(0); i < local.getNbComponent(); ++i) {
- quad_out << "," << local(q.global_num, i);
- }
- const Array<Real> & non_local = (*non_local_variable.non_local)(q.type, q.ghost_type);
- for(UInt i(0); i < non_local.getNbComponent(); ++i) {
- quad_out << "," << non_local(q.global_num, i);
- }
- }
- Real d = getArray("damage", q.type, q.ghost_type)(q.global_num);
- Real j = fem.getIntegratorInterface().getJacobians(q.type, q.ghost_type)(q.element*nb_quad + q.num_point);
- quad_out << "," << d << "," << j;
-
- quad_out << std::endl;
- }
- }
- }
- }
- step++;
- return out.str();
- });
-#endif
- // <<<<<< DEBUG CODE <<<<<< //
- }
-
- // >>>>>> DEBUG CODE >>>>>> //
-#if defined(AKANTU_DEBUG_TOOLS)
-#if defined(AKANTU_CORE_CXX11)
- debug::element_manager.print(debug::_dm_material_damage,
- [ghost_type, this](const Element & el)->std::string {
- std::stringstream out;
- if(el.ghost_type == ghost_type && element_filter.exists(el.type, ghost_type)) {
- UInt pos = element_filter(el.type, el.ghost_type).find(el.element);
- if(pos != UInt(-1)) {
- Real d = getArray("damage", el.type, el.ghost_type)(pos);
- out << " damage: " << d;
- }
- }
- return out.str();
- });
-#endif
-#endif
- // <<<<<< DEBUG CODE <<<<<< //
-
-}
-
-/* -------------------------------------------------------------------------- */
-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());
-
- GhostType ghost_type1;
- ghost_type1 = _not_ghost;
-
- 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);
- const Array<Real> & weights =
- (*pair_weight(first_pair_types->first, ghost_type1))(first_pair_types->second, ghost_type2);
-
- pout << "Types : " << first_pair_types->first << " (" << ghost_type1 << ") - " << first_pair_types->second << " (" << ghost_type2 << ")" << 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<Real>::const_vector_iterator pair_w = weights.begin(2);
-
- for(;first_pair != last_pair; ++first_pair, ++pair_w) {
- UInt q1 = (*first_pair)(0);
- UInt q2 = (*first_pair)(1);
- pout << q1 << " " << q2 << " "<< (*pair_w)(0) << " " << (*pair_w)(1) << 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();
-
-// Material::onElementsAdded(element_list, event);
-
-// 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();
-
- Material::onElementsRemoved(element_list, new_numbering, event);
-
- pair_type::const_iterator first_pair_types = existing_pairs[1].begin();
- pair_type::const_iterator last_pair_types = existing_pairs[1].end();
-
- // Renumber element to keep
- for (; first_pair_types != last_pair_types; ++first_pair_types) {
- ElementType type2 = first_pair_types->second;
- GhostType ghost_type2 = _ghost;
- UInt nb_quad2 = this->model->getFEEngine().getNbQuadraturePoints(type2);
-
- Array<UInt> & pairs =
- pair_list(first_pair_types->first, _not_ghost)(first_pair_types->second, ghost_type2);
- Array<UInt>::iterator< Vector<UInt> > first_pair = pairs.begin(2);
- Array<UInt>::iterator< Vector<UInt> > last_pair = pairs.end(2);
- for(;first_pair != last_pair; ++first_pair) {
- UInt _q2 = (*first_pair)(1);
- const Array<UInt> & renumbering = new_numbering(type2, ghost_type2);
- UInt el = _q2 / nb_quad2;
- UInt new_el = renumbering(el);
- AKANTU_DEBUG_ASSERT(new_el != UInt(-1), "A local quad as been removed instead f just renumbered");
- (*first_pair)(1) = new_el * nb_quad2 + _q2 % nb_quad2;
- }
- }
-
- 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 f3c0d5ad7..0d46f95f9 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,144 +1,215 @@
/**
* @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 Benjamin Paccaud <benjamin.paccaud@epfl.ch>
*
* @date creation: Thu Oct 03 2013
* @date last modification: Fri Jun 13 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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);
-
- 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_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();
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialLinearIsotropicHardening);
+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 f7611c93d..933bd414a 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,100 +1,118 @@
/**
* @file material_linear_isotropic_hardening.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
*
* @date creation: Thu Oct 03 2013
* @date last modification: Mon Apr 07 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 0c744dfcf..609e3b199 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,178 +1,307 @@
/**
* @file material_linear_isotropic_hardening_inline_impl.cc
*
* @author Lucas Frerot <lucas.frerot@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
*
* @brief Implementation of the inline functions of the material plasticity
*
* @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_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 r=iso_hardening;
- Real dp=0.0;
- Real d_dp=0.0;
- UInt n=0;
+ Real dp = 0.0;
+ Real d_dp = 0.0;
+ UInt n = 0;
Real delta_sigma_th = sigma_th - previous_sigma_th;
Matrix<Real> grad_delta_u(grad_u);
grad_delta_u -= previous_grad_u;
//Compute trial stress, sigma_tr
Matrix<Real> sigma_tr(dim, dim);
MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr, delta_sigma_th);
sigma_tr += previous_sigma;
// Compute deviatoric trial stress, sigma_tr_dev
Matrix<Real> sigma_tr_dev(sigma_tr);
sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
// Compute effective deviatoric trial stress
Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
Real sigma_tr_dev_eff = std::sqrt(3./2. * s);
+ // In 1D Von-Mises stress is the stress
+ if (dim == 1) sigma_tr_dev_eff = sigma_tr(0, 0);
+
const Real iso_hardening_t = previous_iso_hardening;
+ iso_hardening = iso_hardening_t;
+
//Loop for correcting stress based on yield function
- while ((sigma_tr_dev_eff - iso_hardening - this->sigma_y) > 0) {
+ 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;
- iso_hardening = iso_hardening_t + this->h * d_dp;
dp = dp + d_dp;
-
+ iso_hardening = iso_hardening_t + this->h * dp;
++n;
- /// TODO : explicit this criterion with an error message
- if ((d_dp < 1e-5) || (n>50))
+ if (d_dp < 1e-5) {
+ break;
+ } else if (n > 50) {
+ AKANTU_DEBUG_WARNING("Isotropic hardening convergence failed");
break;
+ }
}
//Update internal variable
Matrix<Real> delta_inelastic_strain(dim, dim, 0.);
if (std::abs(sigma_tr_dev_eff) >
sigma_tr_dev.norm<L_inf>() * Math::getTolerance()) {
delta_inelastic_strain.copy(sigma_tr_dev);
delta_inelastic_strain *= 3./2. * dp / sigma_tr_dev_eff;
}
MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(grad_delta_u, sigma, previous_sigma,
inelastic_strain, previous_inelastic_strain,
delta_inelastic_strain);
}
/* -------------------------------------------------------------------------- */
+///Finite deformations
+template<UInt dim>
+inline void
+MaterialLinearIsotropicHardening<dim>::computeStressOnQuad(const Matrix<Real> & grad_u,
+ const Matrix<Real> & previous_grad_u,
+ Matrix<Real> & sigma,
+ const Matrix<Real> & previous_sigma,
+ Matrix<Real> & inelastic_strain,
+ const Matrix<Real> & previous_inelastic_strain,
+ Real & iso_hardening,
+ const Real & previous_iso_hardening,
+ const Real & sigma_th,
+ const Real & previous_sigma_th,
+ const Matrix<Real> & F_tensor) {
+ //Finite plasticity
+ Real dp=0.0;
+ Real d_dp=0.0;
+ UInt n=0;
+
+ Real delta_sigma_th = sigma_th - previous_sigma_th;
+
+ Matrix<Real> grad_delta_u(grad_u);
+ grad_delta_u -= previous_grad_u;
+
+ //Compute trial stress, sigma_tr
+ Matrix<Real> sigma_tr(dim, dim);
+ MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr, delta_sigma_th);
+ sigma_tr += previous_sigma;
+
+ // Compute deviatoric trial stress, sigma_tr_dev
+ Matrix<Real> sigma_tr_dev(sigma_tr);
+ sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
+
+ // Compute effective deviatoric trial stress
+ Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
+ Real sigma_tr_dev_eff = std::sqrt(3./2. * s);
+
+ // compute the cauchy stress to apply the Von-Mises criterion
+ Matrix<Real> cauchy_stress(dim,dim);
+ Material::computeCauchyStressOnQuad<dim>(F_tensor,sigma_tr,cauchy_stress);
+ Matrix<Real> cauchy_stress_dev(cauchy_stress);
+ cauchy_stress_dev -= Matrix<Real>::eye(dim, cauchy_stress.trace() / 3.0);
+ Real c = cauchy_stress_dev.doubleDot(cauchy_stress_dev);
+ Real cauchy_stress_dev_eff = std::sqrt(3./2. * c);
+
+
+ const Real iso_hardening_t = previous_iso_hardening;
+ iso_hardening = iso_hardening_t;
+ //Loop for correcting stress based on yield function
+
+ // F is written in terms of S
+ // bool initial_yielding = ( (sigma_tr_dev_eff - iso_hardening - this->sigma_y) > 0) ;
+ // while ( initial_yielding && std::abs(sigma_tr_dev_eff - iso_hardening - this->sigma_y) > Math::getTolerance() ) {
+
+ // d_dp = (sigma_tr_dev_eff - 3. * this->mu *dp - iso_hardening - this->sigma_y)
+ // / (3. * this->mu + this->h);
+
+ // //r = r + h * dp;
+ // dp = dp + d_dp;
+ // iso_hardening = iso_hardening_t + this->h * dp;
+
+ // ++n;
+
+ // /// TODO : explicit this criterion with an error message
+ // if ((std::abs(d_dp) < 1e-9) || (n>50)){
+ // AKANTU_DEBUG_INFO("convergence of increment of plastic strain. d_dp:" << d_dp << "\tNumber of iteration:"<<n);
+ // break;
+ // }
+ // }
+
+ // F is written in terms of cauchy stress
+ bool initial_yielding = ( (cauchy_stress_dev_eff - iso_hardening - this->sigma_y) > 0) ;
+ while ( initial_yielding && std::abs(cauchy_stress_dev_eff - iso_hardening - this->sigma_y) > Math::getTolerance() ) {
+
+ d_dp = ( cauchy_stress_dev_eff - 3. * this->mu *dp - iso_hardening - this->sigma_y)
+ / (3. * this->mu + this->h);
+
+ //r = r + h * dp;
+ dp = dp + d_dp;
+ iso_hardening = iso_hardening_t + this->h * dp;
+
+
+ ++n;
+ /// TODO : explicit this criterion with an error message
+ if ((d_dp < 1e-5) || (n>50)){
+ AKANTU_DEBUG_INFO("convergence of increment of plastic strain. d_dp:" << d_dp << "\tNumber of iteration:"<<n);
+ break;
+ }
+ }
+
+ //Update internal variable
+ Matrix<Real> delta_inelastic_strain(dim, dim, 0.);
+ if (std::abs(sigma_tr_dev_eff) >
+ sigma_tr_dev.norm<L_inf>() * Math::getTolerance()) {
+
+ // /// compute the direction of the plastic strain as \frac{\partial F}{\partial S} = \frac{3}{2J\sigma_{effective}}} Ft \sigma_{dev} F
+ Matrix<Real> cauchy_dev_F(dim,dim);
+ cauchy_dev_F.mul<false,false>(F_tensor,cauchy_stress_dev);
+ Real J = F_tensor.det();
+ Real constant = J ? 1./J : 0;
+ constant *= 3. * dp / (2. * cauchy_stress_dev_eff);
+ delta_inelastic_strain.mul<true,false>(F_tensor,cauchy_dev_F,constant);
+
+ //Direction given by the piola kirchhoff deviatoric tensor \frac{\partial F}{\partial S} = \frac{3}{2\sigma_{effective}}}S_{dev}
+ // delta_inelastic_strain.copy(sigma_tr_dev);
+ // delta_inelastic_strain *= 3./2. * dp / sigma_tr_dev_eff;
+ }
+
+ MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(grad_delta_u, sigma, previous_sigma,
+ inelastic_strain, previous_inelastic_strain,
+ delta_inelastic_strain);
+}
+
+/* -------------------------------------------------------------------------- */
+
+
template<UInt dim>
inline void
MaterialLinearIsotropicHardening<dim>::computeTangentModuliOnQuad(Matrix<Real> & tangent,
const Matrix<Real> & grad_u,
const Matrix<Real> & previous_grad_u,
const Matrix<Real> & sigma_tensor,
const Matrix<Real> & previous_sigma_tensor,
const Real & iso_hardening) const {
// Real r=iso_hardening;
// Matrix<Real> grad_delta_u(grad_u);
// grad_delta_u -= previous_grad_u;
// //Compute trial stress, sigma_tr
// Matrix<Real> sigma_tr(dim, dim);
// MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr);
// sigma_tr += previous_sigma_tensor;
// // Compute deviatoric trial stress, sigma_tr_dev
// Matrix<Real> sigma_tr_dev(sigma_tr);
// sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
// // Compute effective deviatoric trial stress
// Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
// Real sigma_tr_dev_eff=std::sqrt(3./2. * s);
// // Compute deviatoric stress, sigma_dev
// Matrix<Real> sigma_dev(sigma_tensor);
// sigma_dev -= Matrix<Real>::eye(dim, sigma_tensor.trace() / 3.0);
// // Compute effective deviatoric stress
// s = sigma_dev.doubleDot(sigma_dev);
// Real sigma_dev_eff = std::sqrt(3./2. * s);
// Real xr = 0.0;
// if(sigma_tr_dev_eff > sigma_dev_eff * Math::getTolerance())
// xr = sigma_dev_eff / sigma_tr_dev_eff;
// Real __attribute__((unused)) q = 1.5 * (1. / (1. + 3. * this->mu / this->h) - xr);
+ /*
UInt cols = tangent.cols();
UInt rows = tangent.rows();
for (UInt m = 0; m < rows; ++m) {
UInt i = VoigtHelper<dim>::vec[m][0];
UInt j = VoigtHelper<dim>::vec[m][1];
for (UInt n = 0; n < cols; ++n) {
UInt k = VoigtHelper<dim>::vec[n][0];
UInt l = VoigtHelper<dim>::vec[n][1];
+ */
// This section of the code is commented
// There were some problems with the convergence of plastic-coupled simulations with thermal expansion
// XXX: DO NOT REMOVE
/*if (((sigma_tr_dev_eff-iso_hardening-sigmay) > 0) && (xr > 0)) {
tangent(m,n) =
2. * this->mu * q * (sigma_tr_dev (i,j) / sigma_tr_dev_eff) * (sigma_tr_dev (k,l) / sigma_tr_dev_eff) +
(i==k) * (j==l) * 2. * this->mu * xr +
(i==j) * (k==l) * (this->kpa - 2./3. * this->mu * xr);
if ((m == n) && (m>=dim))
tangent(m, n) = tangent(m, n) - this->mu * xr;
} else {*/
+ /*
tangent(m,n) = (i==k) * (j==l) * 2. * this->mu +
(i==j) * (k==l) * this->lambda;
tangent(m,n) -= (m==n) * (m>=dim) * this->mu;
+ */
//}
//correct tangent stiffness for shear component
- }
- }
+ //}
+ //}
+ MaterialElastic<dim>::computeTangentModuliOnQuad(tangent);
}
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc b/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
index f35c6e322..5f224990f 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
@@ -1,184 +1,202 @@
/**
* @file material_plastic.cc
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Mon Apr 07 2014
* @date last modification: Fri Jun 13 2014
*
* @brief Implemantation of the akantu::MaterialPlastic 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 "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();
+}
- this->registerParam("h", h, 0., _pat_parsable | _pat_modifiable, "Hardening modulus");
- this->registerParam("sigma_y", sigma_y, 0., _pat_parsable | _pat_modifiable, "Yield stress");
+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->finite_deformation = false;
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();
-
- AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<UInt spatial_dimension>
Real MaterialPlastic<spatial_dimension>::getEnergy(std::string type) {
- AKANTU_DEBUG_IN();
-
if (type == "plastic") return getPlasticEnergy();
else return MaterialElastic<spatial_dimension>::getEnergy(type);
- AKANTU_DEBUG_OUT();
+ 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));
+ *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) {
+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) {
+ 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();
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialPlastic);
+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 abcd54021..ec3ad3f78 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
@@ -1,129 +1,140 @@
/**
* @file material_plastic.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Mon Apr 07 2014
* @date last modification: Mon Apr 07 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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_python/material_python.cc b/src/model/solid_mechanics/materials/material_python/material_python.cc
new file mode 100644
index 000000000..4722077fc
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_python/material_python.cc
@@ -0,0 +1,125 @@
+/**
+ * @file material_python.cc
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "material_python.hh"
+#include "solid_mechanics_model.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+MaterialPython::MaterialPython(SolidMechanicsModel & model,
+ PyObject * obj,
+ const ID & id) :
+
+ Material(model, id),
+ PythonFunctor(obj){
+ AKANTU_DEBUG_IN();
+
+ this->registerInternals();
+
+ std::vector<std::string> param_names = this->callFunctor<std::vector<std::string> >("registerParam");
+
+ this->local_params.resize(param_names.size());
+
+ for (UInt i = 0; i < param_names.size(); ++i) {
+ std::stringstream sstr;
+ sstr << "PythonParameter" << i;
+ this->registerParam(param_names[i],local_params[i],0., _pat_parsable,sstr.str() );
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+void MaterialPython::registerInternals() {
+
+ std::vector<std::string> internal_names = this->callFunctor<std::vector<std::string> >("registerInternals");
+
+ this->internals.resize(internal_names.size());
+
+ for (UInt i = 0; i < internal_names.size(); ++i) {
+ std::stringstream sstr;
+ sstr << "PythonInternal" << i;
+ this->internals[i] = new InternalField<Real>(internal_names[i],*this);
+ this->internals[i]->initialize(1);
+ }
+
+
+}
+/* -------------------------------------------------------------------------- */
+
+
+void MaterialPython::initMaterial() {
+ AKANTU_DEBUG_IN();
+
+ Material::initMaterial();
+
+ // initInternalArray(this->damage, 1);
+ // resizeInternalArray(this->damage);
+
+
+ // lambda = nu * E / ((1 + nu) * (1 - 2*nu));
+ // mu = E / (2 * (1 + nu));
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void MaterialPython::computeStress(ElementType el_type, GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ typedef Array<Real>::iterator<Real> it_type;
+ std::vector<it_type> its;
+ for (auto i: this->internals) {
+ its.push_back((*i)(el_type,ghost_type).begin());
+ }
+
+ MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
+
+ computeStress(grad_u, sigma, its);
+
+ for (auto b: its) ++(*b);
+
+ MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename it_type>
+void MaterialPython::computeStress( Matrix<Real> & grad_u,
+ Matrix<Real> & sigma,
+ std::vector<it_type> & internal_iterators){
+
+ std::vector<Real> inputs;
+ for (auto i: internal_iterators){
+ inputs.push_back(*i);
+ }
+ this->callFunctor<void>("computeStress",grad_u,sigma,inputs);
+
+ for (UInt i = 0; i < inputs.size(); ++i) {
+ *internal_iterators[i] = inputs[i];
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+void MaterialPython::computeTangentModuli(const ElementType & el_type,
+ Array<Real> & tangent_matrix,
+ GhostType ghost_type){
+
+ this->callFunctor<void>("computeTangentModuli",el_type,tangent_matrix,ghost_type);
+}
+
+/* -------------------------------------------------------------------------- */
+
+Real MaterialPython::getPushWaveSpeed(const Element & element) const{
+ return this->callFunctor<Real>("getPushWaveSpeed");
+}
+
+__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_python/material_python.hh b/src/model/solid_mechanics/materials/material_python/material_python.hh
new file mode 100644
index 000000000..7abb45fe2
--- /dev/null
+++ b/src/model/solid_mechanics/materials/material_python/material_python.hh
@@ -0,0 +1,93 @@
+/**
+ * @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 50001d6aa..c799bc65e 100644
--- a/src/model/solid_mechanics/materials/material_thermal.cc
+++ b/src/model/solid_mechanics/materials/material_thermal.cc
@@ -1,101 +1,122 @@
/**
* @file material_thermal.cc
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Thu Oct 17 2013
* @date last modification: Thu Apr 03 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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();
+}
- this->registerParam("E" , E , 0. , _pat_parsable | _pat_modifiable, "Young's modulus" );
- this->registerParam("nu" , nu , 0.5 , _pat_parsable | _pat_modifiable, "Poisson's ratio" );
- this->registerParam("alpha" , alpha , 0. , _pat_parsable | _pat_modifiable, "Thermal expansion coefficient");
- this->registerParam("delta_T", delta_T, _pat_parsable | _pat_modifiable, "Uniform temperature field");
+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);
- AKANTU_DEBUG_OUT();
}
+
/* -------------------------------------------------------------------------- */
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();
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialThermal);
+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 a15c04f06..9e120c0d2 100644
--- a/src/model/solid_mechanics/materials/material_thermal.hh
+++ b/src/model/solid_mechanics/materials/material_thermal.hh
@@ -1,96 +1,104 @@
/**
* @file material_thermal.hh
*
* @author Lucas Frerot <lucas.frerot@epfl.ch>
*
* @date creation: Thu Oct 17 2013
* @date last modification: Thu Apr 03 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 0734a1a68..564882e77 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,298 @@
/**
* @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>
*
* @date creation: Wed Feb 08 2012
* @date last modification: Thu Jun 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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, 1., ParamAccessType(_pat_parsable | _pat_modifiable), "Viscosity");
- this->registerParam("Ev", Ev, 1., ParamAccessType(_pat_parsable | _pat_modifiable), "Stiffness of the viscous element");
- this->registerParam("Einf", E_inf, 1., ParamAccessType(_pat_readable), "Stiffness of the elastic element");
+ 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(1./3. * Theta);
+ 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(1./3. * Theta);
+ 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);
}
/* -------------------------------------------------------------------------- */
-INSTANSIATE_MATERIAL(MaterialStandardLinearSolidDeviatoric);
+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..d73f19ee6 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,136 @@
/**
* @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>
*
* @date creation: Wed Feb 08 2012
* @date last modification: Wed Nov 13 2013
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 840ae01de..aca90d1ed 100644
--- a/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
+++ b/src/model/solid_mechanics/materials/plane_stress_toolbox.hh
@@ -1,87 +1,98 @@
/**
* @file plane_stress_toolbox.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Sep 16 2014
* @date last modification: Tue Sep 16 2014
*
* @brief Tools to implement the plane stress behavior in a material
*
* @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_PLANE_STRESS_TOOLBOX_HH__
#define __AKANTU_PLANE_STRESS_TOOLBOX_HH__
__BEGIN_AKANTU__
/**
* Empty class in dimensions different from 2
* This class is only specialized for 2D in the tmpl file
*/
template<UInt dim, class ParentMaterial = Material>
class PlaneStressToolbox : public ParentMaterial {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PlaneStressToolbox(SolidMechanicsModel & model, const ID & id = "") : Material(model, id),
ParentMaterial(model, id) {}
+ PlaneStressToolbox(SolidMechanicsModel & model,
+ UInt spatial_dimension,
+ const Mesh & mesh,
+ FEEngine & fe_engine,
+ const ID & id = "") : Material(model, spatial_dimension, mesh, fe_engine, id),
+ ParentMaterial(model, spatial_dimension, mesh, fe_engine, id) {}
+
virtual ~PlaneStressToolbox() {}
+protected:
+ void initialize();
+
+public:
virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost){
AKANTU_DEBUG_IN();
ParentMaterial::computeAllCauchyStresses(ghost_type);
AKANTU_DEBUG_OUT();
}
virtual void computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ERROR("The function \"computeCauchyStressPlaneStress\" can only be used in 2D Plane stress problems, which means that you made a mistake somewhere!! ");
AKANTU_DEBUG_OUT();
}
protected:
bool initialize_third_axis_deformation;
};
#define AKANTU_PLANE_STRESS_TOOL_SPEC(dim)\
template<> \
inline PlaneStressToolbox<dim, Material>::PlaneStressToolbox(SolidMechanicsModel & model, \
const ID & id) : \
Material(model, id) {} \
AKANTU_PLANE_STRESS_TOOL_SPEC(1)
AKANTU_PLANE_STRESS_TOOL_SPEC(3)
__END_AKANTU__
#include "plane_stress_toolbox_tmpl.hh"
#endif /* __AKANTU_PLANE_STRESS_TOOLBOX_HH__ */
diff --git a/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh b/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
index dc3e57a78..5b20c9eda 100644
--- a/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
+++ b/src/model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
@@ -1,147 +1,171 @@
/**
* @file plane_stress_toolbox_tmpl.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Tue Sep 16 2014
* @date last modification: Tue Sep 16 2014
*
* @brief 2D specialization of the akantu::PlaneStressToolbox 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_PLANE_STRESS_TOOLBOX_TMPL_HH__
#define __AKANTU_PLANE_STRESS_TOOLBOX_TMPL_HH__
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template<class ParentMaterial>
class PlaneStressToolbox<2, ParentMaterial> : public ParentMaterial {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
PlaneStressToolbox(SolidMechanicsModel & model, const ID & id = "");
+ PlaneStressToolbox(SolidMechanicsModel & model,
+ UInt dim,
+ const Mesh & mesh,
+ FEEngine & fe_engine,
+ const ID & id = "");
virtual ~PlaneStressToolbox() {}
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ThirdAxisDeformation, third_axis_deformation, Real);
+protected:
+ void initialize() {
+ this->registerParam("Plane_Stress", plane_stress, false, _pat_parsmod, "Is plane stress");
+ }
+
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
virtual void initMaterial() {
ParentMaterial::initMaterial();
if(this->plane_stress && this->initialize_third_axis_deformation){
this->third_axis_deformation.initialize(1);
this->third_axis_deformation.resize();
}
}
/* ------------------------------------------------------------------------ */
virtual void computeStress(ElementType el_type, GhostType ghost_type) {
ParentMaterial::computeStress(el_type, ghost_type);
if(this->plane_stress) computeThirdAxisDeformation(el_type, ghost_type);
}
/* ------------------------------------------------------------------------ */
virtual void computeThirdAxisDeformation(__attribute__((unused)) ElementType el_type,
__attribute__((unused)) GhostType ghost_type) {
}
/// Computation of Cauchy stress tensor in the case of finite deformation
virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost){
AKANTU_DEBUG_IN();
if(this->plane_stress){
AKANTU_DEBUG_ASSERT(this->finite_deformation,"The Cauchy stress can only be computed if you are working in finite deformation.");
//resizeInternalArray(stress);
Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(2, ghost_type);
Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(2, ghost_type);
for(; it != last_type; ++it)
this->computeCauchyStressPlaneStress(*it, ghost_type);
}
else
ParentMaterial::computeAllCauchyStresses(ghost_type);
AKANTU_DEBUG_OUT();
}
virtual void computeCauchyStressPlaneStress(ElementType el_type, GhostType ghost_type = _not_ghost){};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// third axis strain measure value
InternalField<Real> third_axis_deformation;
/// Plane stress or plane strain
bool plane_stress;
/// For non linear materials, the \epsilon_{zz} might be required
bool initialize_third_axis_deformation;
};
template<class ParentMaterial>
inline PlaneStressToolbox<2, ParentMaterial>::PlaneStressToolbox(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
ParentMaterial(model, id),
third_axis_deformation("third_axis_deformation", *this),
plane_stress(false),
initialize_third_axis_deformation(false) {
/// @todo Plane_Stress should not be possible to be modified after initMaterial (but before)
- this->registerParam("Plane_Stress", plane_stress, false, _pat_parsmod, "Is plane stress");
+ this->initialize();
+}
+
+template<class ParentMaterial>
+inline PlaneStressToolbox<2, ParentMaterial>::PlaneStressToolbox(SolidMechanicsModel & model,
+ UInt dim,
+ const Mesh & mesh,
+ FEEngine & fe_engine,
+ const ID & id):
+ Material(model, dim, mesh, fe_engine, id),
+ ParentMaterial(model, dim, mesh, fe_engine, id),
+ third_axis_deformation("third_axis_deformation", *this, dim, fe_engine, this->element_filter),
+ plane_stress(false),
+ initialize_third_axis_deformation(false) {
+ this->initialize();
}
template<>
inline PlaneStressToolbox<2, Material>::PlaneStressToolbox(SolidMechanicsModel & model, const ID & id) :
Material(model, id),
third_axis_deformation("third_axis_deformation", *this),
plane_stress(false),
initialize_third_axis_deformation(false) {
/// @todo Plane_Stress should not be possible to be modified after initMaterial (but before)
this->registerParam("Plane_Stress", plane_stress, false, _pat_parsmod, "Is plane stress");
}
__END_AKANTU__
#endif /* __AKANTU_PLANE_STRESS_TOOLBOX_TMPL_HH__ */
diff --git a/src/model/solid_mechanics/materials/random_internal_field.hh b/src/model/solid_mechanics/materials/random_internal_field.hh
index 144e1dd77..d22a7a418 100644
--- a/src/model/solid_mechanics/materials/random_internal_field.hh
+++ b/src/model/solid_mechanics/materials/random_internal_field.hh
@@ -1,100 +1,108 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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..15c1be9ee 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
*
* @brief Random internal material parameter 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/>.
*
*/
/* -------------------------------------------------------------------------- */
#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 224825d2f..000000000
--- a/src/model/solid_mechanics/materials/weight_function.hh
+++ /dev/null
@@ -1,398 +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 <vector>
-
-
-#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,
- __attribute__((unused)) QuadraturePoint & q1,
- __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") {}
-
- inline void selectType(__attribute__((unused)) ElementType type1,
- __attribute__((unused)) GhostType ghost_type1,
- ElementType type2,
- GhostType ghost_type2) {
- selected_damage = &this->material.getArray("damage", type2, ghost_type2);
- }
-
- inline Real operator()(Real r, __attribute__((unused)) QuadraturePoint & q1, 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.getArray("damage", type2, ghost_type2);
- }
-
- inline Real operator()(Real r, __attribute__((unused)) QuadraturePoint & q1, 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.getInternal("damage");
- this->material.packElementDataHelper(damage,
- buffer,
- elements);
-#if defined(AKANTU_DEBUG_TOOLS)
-#if defined(AKANTU_CORE_CXX11)
- debug::element_manager.print(debug::_dm_material,
- [&elements, &mat](const Element & el)->std::string {
- std::stringstream out;
- UInt pos = elements.find(el);
- if(pos != UInt(-1)) {
- Real d = mat.getArray("damage", el.type, el.ghost_type)(el.element);
- if(d > 0.3)
- out << " damage sent: " << d;
- }
- return out.str();
- });
-#else
- debug::element_manager.printData(debug::_dm_material, "RemoveDamagedWeightFunction: packElementData",
- mat.getDamage(), mat.getElementFilter());
-#endif
-#endif
- }
- }
-
- virtual inline void unpackElementData(CommunicationBuffer & buffer,
- const Array<Element> & elements,
- SynchronizationTag tag) {
- if(tag == _gst_mnl_weight) {
- ElementTypeMapArray<Real> & damage = this->material.getInternal("damage");
- this->material.unpackElementDataHelper(damage,
- buffer,
- elements);
-#if defined(AKANTU_DEBUG_TOOLS)
-#if defined(AKANTU_CORE_CXX11)
- debug::element_manager.print(debug::_dm_material,
- [&elements, &mat](const Element & el)->std::string {
- std::stringstream out;
- UInt pos = elements.find(el);
- if(pos != UInt(-1)) {
- Real d = mat.getArray("damage", el.type, el.ghost_type)(el.element);
- if(d > 0.3)
- out << " damage recv: " << d;
- }
- return out.str();
- });
-#else
- debug::element_manager.printData(debug::_dm_material, "RemoveDamagedWeightFunction: unpackElementData",
- mat.getDamage(), mat.getElementFilter());
-#endif
-#endif
-
- }
- }
-
-
-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.getArray("damage",type2, ghost_type2));
- selected_damage_rate_with_damage_rate = &(this->material.getArray("damage-rate",type2, ghost_type2));
- }
-
- inline Real operator()(Real r, __attribute__((unused)) QuadraturePoint & q1, 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, QuadraturePoint & q1, 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 516b3b5e4..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,
- QuadraturePoint & q1,
- 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..37da662d7
--- /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: Fri Apr 13 2012
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @brief Base weight function for non local materials
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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..572cff38b
--- /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.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 Implementation of inline function of base weight function
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+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..0145a6680
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/damaged_weight_function.hh
@@ -0,0 +1,82 @@
+/**
+ * @file damaged_weight_function.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @brief Damaged weight function for non local materials
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..a2ccd6915
--- /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.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 Implementation of inline function of damaged weight function
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * 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..ea30b36ec
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_weight_function.hh
@@ -0,0 +1,100 @@
+
+/**
+ * @file remove_damaged_weight_function.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @brief Removed damaged weight function for non local materials
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..e9d5d883a
--- /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.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 Implementation of inline function of remove damaged weight function
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * 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..46e274113
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/remove_damaged_with_damage_rate_weight_function.hh
@@ -0,0 +1,81 @@
+/**
+ * @file remove_damaged_with damage_rate_weight_function.hh
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @brief Removed damaged weight function for non local materials
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..f2442933d
--- /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: Fri Apr 13 2012
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @brief Implementation of inline function of remove damaged with
+ * damage rate weight function
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * 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..0f475c808
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
@@ -0,0 +1,116 @@
+/**
+ * @file stress_based_weight_function.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @brief implementation of the stres based weight function classes
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+/* -------------------------------------------------------------------------- */
+#include "stress_based_weight_function.hh"
+__BEGIN_AKANTU__
+/* -------------------------------------------------------------------------- */
+StressBasedWeightFunction::StressBasedWeightFunction(NonLocalManager & manager) :
+ BaseWeightFunction(manager, "stress_based")
+ // stress_diag("stress_diag", material), selected_stress_diag(NULL),
+ // stress_base("stress_base", material), selected_stress_base(NULL),
+ // characteristic_size("lc", material), selected_characteristic_size(NULL)
+{
+
+ // this->registerParam("ft", this->ft, 0., _pat_parsable, "Tensile strength");
+ // stress_diag.initialize(spatial_dimension);
+ // stress_base.initialize(spatial_dimension * spatial_dimension);
+ // characteristic_size.initialize(1);
+}
+
+/* -------------------------------------------------------------------------- */
+/// During intialization the characteristic sizes for all quadrature
+/// points are computed
+void StressBasedWeightFunction::init() {
+ // const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
+ // for (UInt g = _not_ghost; g <= _ghost; ++g) {
+ // GhostType gt = GhostType(g);
+ // Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt);
+ // Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt);
+ // for(; it != last_type; ++it) {
+ // UInt nb_quadrature_points =
+ // this->material.getModel().getFEEngine().getNbQuadraturePoints(*it, gt);
+ // const Array<UInt> & element_filter = this->material.getElementFilter(*it, gt);
+ // UInt nb_element = element_filter.getSize();
+
+ // Array<Real> ones(nb_element*nb_quadrature_points, 1, 1.);
+ // Array<Real> & lc = characteristic_size(*it, gt);
+ // this->material.getModel().getFEEngine().integrateOnQuadraturePoints(ones,
+ // lc,
+ // 1,
+ // *it,
+ // gt,
+ // element_filter);
+
+ // for (UInt q = 0; q < nb_quadrature_points * nb_element; q++) {
+ // lc(q) = pow(lc(q), 1./ Real(spatial_dimension));
+ // }
+ // }
+ // }
+}
+
+
+/* -------------------------------------------------------------------------- */
+/// computation of principals stresses and principal directions
+void StressBasedWeightFunction::updatePrincipalStress(GhostType ghost_type) {
+// AKANTU_DEBUG_IN();
+
+// const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
+
+// Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
+// Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
+// for(; it != last_type; ++it) {
+// Array<Real>::const_matrix_iterator sigma =
+// this->material.getStress(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
+// Array<Real>::vector_iterator eigenvalues =
+// stress_diag(*it, ghost_type).begin(spatial_dimension);
+// Array<Real>::vector_iterator eigenvalues_end =
+// stress_diag(*it, ghost_type).end(spatial_dimension);
+// Array<Real>::matrix_iterator eigenvector =
+// stress_base(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
+
+// #ifndef __trick__
+// Array<Real>::iterator<Real> cl = characteristic_size(*it, ghost_type).begin();
+// #endif
+// UInt q = 0;
+// for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues, ++eigenvector, ++cl, ++q) {
+// sigma->eig(*eigenvalues, *eigenvector);
+// *eigenvalues /= ft;
+// #ifndef __trick__
+// // specify a lower bound for principal stress based on the size of the element
+// for (UInt i = 0; i < spatial_dimension; ++i) {
+// (*eigenvalues)(i) = std::max(*cl / this->R, (*eigenvalues)(i));
+// }
+// #endif
+// }
+// }
+// AKANTU_DEBUG_OUT();
+}
+
+__END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.hh
new file mode 100644
index 000000000..8d2f12c91
--- /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: Fri Apr 13 2012
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @brief Removed damaged weight function for non local materials
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..9a4cc5e89
--- /dev/null
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function_inline_impl.cc
@@ -0,0 +1,189 @@
+/**
+ * @file stress_based_weight_function_inline_impl.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
+ *
+ * @date creation: Fri Apr 13 2012
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @brief Implementation of inline function of remove damaged with
+ * damage rate weight function
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+inline void StressBasedWeightFunction::updateInternals() {
+ // updatePrincipalStress(_not_ghost);
+ // updatePrincipalStress(_ghost);
+}
+
+/* -------------------------------------------------------------------------- */
+// inline void StressBasedWeightFunction::selectType(ElementType type1,
+// GhostType ghost_type1,
+// ElementType type2,
+// GhostType ghost_type2) {
+// selected_stress_diag = &stress_diag(type2, ghost_type2);
+// selected_stress_base = &stress_base(type2, ghost_type2);
+
+// selected_characteristic_size = &characteristic_size(type1, ghost_type1);
+// }
+
+/* -------------------------------------------------------------------------- */
+inline Real StressBasedWeightFunction::computeRhoSquare(Real r,
+ Vector<Real> & eigs,
+ Matrix<Real> & eigenvects,
+ Vector<Real> & x_s) {
+// if (spatial_dimension == 1)
+// return eigs[0];
+// else if (spatial_dimension == 2) {
+// Vector<Real> u1(eigenvects.storage(), 2);
+// Real cos_t = x_s.dot(u1) / (x_s.norm() * u1.norm());
+
+// Real cos_t_2;
+// Real sin_t_2;
+
+// Real sigma1_2 = eigs[0]*eigs[0];
+// Real sigma2_2 = eigs[1]*eigs[1];
+
+// #ifdef __trick__
+// Real zero = std::numeric_limits<Real>::epsilon();
+// if(std::abs(cos_t) < zero) {
+// cos_t_2 = 0;
+// sin_t_2 = 1;
+// } else {
+// cos_t_2 = cos_t * cos_t;
+// sin_t_2 = (1 - cos_t_2);
+// }
+
+// Real rhop1 = std::max(0., cos_t_2 / sigma1_2);
+// Real rhop2 = std::max(0., sin_t_2 / sigma2_2);
+// #else
+// cos_t_2 = cos_t * cos_t;
+// sin_t_2 = (1 - cos_t_2);
+
+// Real rhop1 = cos_t_2 / sigma1_2;
+// Real rhop2 = sin_t_2 / sigma2_2;
+// #endif
+
+// return 1./ (rhop1 + rhop2);
+// } else if (spatial_dimension == 3) {
+// Vector<Real> u1(eigenvects.storage() + 0*3, 3);
+// //Vector<Real> u2(eigenvects.storage() + 1*3, 3);
+// Vector<Real> u3(eigenvects.storage() + 2*3, 3);
+
+// Real zero = std::numeric_limits<Real>::epsilon();
+
+// Vector<Real> tmp(3);
+// tmp.crossProduct(x_s, u3);
+
+// Vector<Real> u3_C_x_s_C_u3(3);
+// u3_C_x_s_C_u3.crossProduct(u3, tmp);
+
+// Real norm_u3_C_x_s_C_u3 = u3_C_x_s_C_u3.norm();
+// Real cos_t = 0.;
+// if(std::abs(norm_u3_C_x_s_C_u3) > zero) {
+// Real inv_norm_u3_C_x_s_C_u3 = 1. / norm_u3_C_x_s_C_u3;
+// cos_t = u1.dot(u3_C_x_s_C_u3) * inv_norm_u3_C_x_s_C_u3;
+// }
+
+// Real cos_p = u3.dot(x_s) / r;
+
+// Real cos_t_2;
+// Real sin_t_2;
+// Real cos_p_2;
+// Real sin_p_2;
+
+// Real sigma1_2 = eigs[0]*eigs[0];
+// Real sigma2_2 = eigs[1]*eigs[1];
+// Real sigma3_2 = eigs[2]*eigs[2];
+
+// #ifdef __trick__
+// if(std::abs(cos_t) < zero) {
+// cos_t_2 = 0;
+// sin_t_2 = 1;
+// } else {
+// cos_t_2 = cos_t * cos_t;
+// sin_t_2 = (1 - cos_t_2);
+// }
+
+// if(std::abs(cos_p) < zero) {
+// cos_p_2 = 0;
+// sin_p_2 = 1;
+// } else {
+// cos_p_2 = cos_p * cos_p;
+// sin_p_2 = (1 - cos_p_2);
+// }
+
+// Real rhop1 = std::max(0., sin_p_2 * cos_t_2 / sigma1_2);
+// Real rhop2 = std::max(0., sin_p_2 * sin_t_2 / sigma2_2);
+// Real rhop3 = std::max(0., cos_p_2 / sigma3_2);
+// #else
+// cos_t_2 = cos_t * cos_t;
+// sin_t_2 = (1 - cos_t_2);
+
+// cos_p_2 = cos_p * cos_p;
+// sin_p_2 = (1 - cos_p_2);
+
+// Real rhop1 = sin_p_2 * cos_t_2 / sigma1_2;
+// Real rhop2 = sin_p_2 * sin_t_2 / sigma2_2;
+// Real rhop3 = cos_p_2 / sigma3_2;
+// #endif
+
+// return 1./ (rhop1 + rhop2 + rhop3);
+// }
+ return 0.;
+}
+
+
+/* -------------------------------------------------------------------------- */
+inline Real StressBasedWeightFunction::operator()(Real r,
+ const IntegrationPoint & q1,
+ const IntegrationPoint & q2) {
+ // Real zero = std::numeric_limits<Real>::epsilon();
+
+ // if(r < zero) return 1.; // means x and s are the same points
+
+ // const Vector<Real> & x = q1.getPosition();
+ // const Vector<Real> & s = q2.getPosition();
+
+ // Vector<Real> eigs =
+ // selected_stress_diag->begin(spatial_dimension)[q2.global_num];
+
+ // Matrix<Real> eigenvects =
+ // selected_stress_base->begin(spatial_dimension, spatial_dimension)[q2.global_num];
+
+ // Real min_rho_lc = selected_characteristic_size->begin()[q1.global_num];
+
+ // Vector<Real> x_s(spatial_dimension);
+ // x_s = x;
+ // x_s -= s;
+
+ // Real rho_2 = computeRhoSquare(r, eigs, eigenvects, x_s);
+
+ // Real rho_lc_2 = std::max(this->R2 * rho_2, min_rho_lc*min_rho_lc);
+
+ // // Real w = std::max(0., 1. - r*r / rho_lc_2);
+ // // w = w*w;
+ // Real w = exp(- 2*2*r*r / rho_lc_2);
+ // return w;
+ return 0.;
+}
diff --git a/src/model/solid_mechanics/solid_mechanics_model.cc b/src/model/solid_mechanics/solid_mechanics_model.cc
index ce40bc72f..9efc3c880 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model.cc
@@ -1,1830 +1,1832 @@
/**
* @file solid_mechanics_model.cc
*
* @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 Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Tue Jul 27 2010
* @date last modification: Fri Sep 19 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_math.hh"
#include "aka_common.hh"
#include "solid_mechanics_model.hh"
#include "group_manager_inline_impl.cc"
#include "dumpable_inline_impl.hh"
#include "integration_scheme_2nd_order.hh"
#include "element_group.hh"
#include "static_communicator.hh"
#include "dof_synchronizer.hh"
#include "element_group.hh"
#include <cmath>
#ifdef AKANTU_USE_MUMPS
#include "solver_mumps.hh"
#endif
+#ifdef AKANTU_USE_PETSC
+#include "solver_petsc.hh"
+#include "petsc_matrix.hh"
+#endif
+
#ifdef AKANTU_USE_IOHELPER
# include "dumper_field.hh"
# include "dumper_paraview.hh"
# include "dumper_homogenizing_field.hh"
-# include "dumper_material_internal_field.hh"
+# include "dumper_internal_material_field.hh"
# include "dumper_elemental_field.hh"
# include "dumper_material_padders.hh"
# include "dumper_element_partition.hh"
# include "dumper_iohelper.hh"
#endif
+#ifdef AKANTU_DAMAGE_NON_LOCAL
+# include "non_local_manager.hh"
+#endif
+
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const SolidMechanicsModelOptions default_solid_mechanics_model_options(_explicit_lumped_mass, false);
/* -------------------------------------------------------------------------- */
/**
* A solid mechanics model need a mesh and a dimension to be created. the model
* by it self can not do a lot, the good init functions should be called in
* order to configure the model depending on what we want to do.
*
* @param mesh mesh representing the model we want to simulate
* @param dim spatial dimension of the problem, if dim = 0 (default value) the
* dimension of the problem is assumed to be the on of the mesh
* @param id an id to identify the model
*/
SolidMechanicsModel::SolidMechanicsModel(Mesh & mesh,
- UInt dim,
- const ID & id,
- const MemoryID & memory_id) :
- Model(mesh, dim, id, memory_id),
+ UInt dim,
+ const ID & id,
+ const MemoryID & memory_id) :
+ Model(mesh, dim, id, memory_id),
BoundaryCondition<SolidMechanicsModel>(),
time_step(NAN), f_m2a(1.0),
mass_matrix(NULL),
velocity_damping_matrix(NULL),
stiffness_matrix(NULL),
jacobian_matrix(NULL),
- element_index_by_material("element index by material", id),
- material_selector(new DefaultMaterialSelector(element_index_by_material)),
+ material_index("material index", id),
+ material_local_numbering("material local numbering", id),
+ material_selector(new DefaultMaterialSelector(material_index)),
is_default_material_selector(true),
integrator(NULL),
increment_flag(false), solver(NULL),
synch_parallel(NULL),
- are_materials_instantiated(false) {
+ are_materials_instantiated(false),
+ non_local_manager(NULL),
+ pbc_synch(NULL) {
AKANTU_DEBUG_IN();
createSynchronizerRegistry(this);
registerFEEngineObject<MyFEEngineType>("SolidMechanicsFEEngine", mesh, spatial_dimension);
this->displacement = NULL;
this->mass = NULL;
this->velocity = NULL;
this->acceleration = NULL;
this->force = NULL;
this->residual = NULL;
this->blocked_dofs = NULL;
this->increment = NULL;
this->increment_acceleration = NULL;
this->dof_synchronizer = NULL;
this->previous_displacement = NULL;
materials.clear();
mesh.registerEventHandler(*this);
#if defined(AKANTU_USE_IOHELPER)
this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_regular);
#endif
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SolidMechanicsModel::~SolidMechanicsModel() {
AKANTU_DEBUG_IN();
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
delete *mat_it;
}
materials.clear();
delete integrator;
delete solver;
delete mass_matrix;
delete velocity_damping_matrix;
if(stiffness_matrix && stiffness_matrix != jacobian_matrix)
delete stiffness_matrix;
delete jacobian_matrix;
delete synch_parallel;
if(is_default_material_selector) {
delete material_selector;
material_selector = NULL;
}
+#ifdef AKANTU_DAMAGE_NON_LOCAL
+ delete non_local_manager;
+ non_local_manager = NULL;
+#endif
+
+ delete pbc_synch;
+
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::setTimeStep(Real time_step) {
this->time_step = time_step;
#if defined(AKANTU_USE_IOHELPER)
this->mesh.getDumper().setTimeStep(time_step);
#endif
}
/* -------------------------------------------------------------------------- */
/* Initialisation */
/* -------------------------------------------------------------------------- */
/**
* This function groups many of the initialization in on function. For most of
* basics case the function should be enough. The functions initialize the
* model, the internal vectors, set them to 0, and depending on the parameters
* it also initialize the explicit or implicit solver.
*
* @param material_file the file containing the materials to use
* @param method the analysis method wanted. See the akantu::AnalysisMethod for
* the different possibilities
*/
void SolidMechanicsModel::initFull(const ModelOptions & options) {
Model::initFull(options);
const SolidMechanicsModelOptions & smm_options =
dynamic_cast<const SolidMechanicsModelOptions &>(options);
- method = smm_options.analysis_method;
+ this->method = smm_options.analysis_method;
// initialize the vectors
- initArrays();
+ this->initArrays();
// set the initial condition to 0
- force->clear();
- velocity->clear();
- acceleration->clear();
- displacement->clear();
+ this->force->clear();
+ this->velocity->clear();
+ this->acceleration->clear();
+ this->displacement->clear();
- // initialize pcb
- if(pbc_pair.size()!=0)
- initPBC();
+ // initialize pbc
+ 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();
+ this->instantiateMaterials();
}
if(!smm_options.no_init_materials) {
- initMaterials();
+ this->initMaterials();
}
- if(increment_flag)
- initBC(*this, *displacement, *increment, *force);
+ if(this->increment_flag)
+ this->initBC(*this, *this->displacement, *this->increment, *this->force);
else
- initBC(*this, *displacement, *force);
+ this->initBC(*this, *this->displacement, *this->force);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initParallel(MeshPartition * partition,
- DataAccessor * data_accessor) {
+ DataAccessor * data_accessor) {
AKANTU_DEBUG_IN();
if (data_accessor == NULL) data_accessor = this;
synch_parallel = &createParallelSynch(partition,data_accessor);
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())
method = analysis_method;
if (integrator) delete integrator;
integrator = new CentralDifference();
UInt nb_nodes = acceleration->getSize();
UInt nb_degree_of_freedom = acceleration->getNbComponent();
std::stringstream sstr; sstr << id << ":increment_acceleration";
increment_acceleration = &(alloc<Real>(sstr.str(), nb_nodes, nb_degree_of_freedom, Real()));
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initArraysPreviousDisplacment() {
AKANTU_DEBUG_IN();
- 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_mass; sstr_mass << id << ":mass";
std::stringstream sstr_velo; sstr_velo << id << ":velocity";
std::stringstream sstr_acce; sstr_acce << id << ":acceleration";
std::stringstream sstr_forc; sstr_forc << id << ":force";
std::stringstream sstr_resi; sstr_resi << id << ":residual";
std::stringstream sstr_boun; sstr_boun << id << ":blocked_dofs";
displacement = &(alloc<Real>(sstr_disp.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
// mass = &(alloc<Real>(sstr_mass.str(), nb_nodes, spatial_dimension, 0));
velocity = &(alloc<Real>(sstr_velo.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
acceleration = &(alloc<Real>(sstr_acce.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
force = &(alloc<Real>(sstr_forc.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
residual = &(alloc<Real>(sstr_resi.str(), nb_nodes, spatial_dimension, REAL_INIT_VALUE));
blocked_dofs = &(alloc<bool>(sstr_boun.str(), nb_nodes, spatial_dimension, false));
std::stringstream sstr_curp; sstr_curp << id << ":current_position";
current_position = &(alloc<Real>(sstr_curp.str(), 0, spatial_dimension, REAL_INIT_VALUE));
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, gt, _ek_not_defined);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it, gt);
- element_index_by_material.alloc(nb_element, 2, *it, gt);
+ material_index.alloc(nb_element, 1, *it, gt);
+ material_local_numbering.alloc(nb_element, 1, *it, gt);
}
}
dof_synchronizer = new DOFSynchronizer(mesh, spatial_dimension);
dof_synchronizer->initLocalDOFEquationNumbers();
dof_synchronizer->initGlobalDOFEquationNumbers();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/**
* Initialize the model,basically it pre-compute the shapes, shapes derivatives
* and jacobian
*
*/
void SolidMechanicsModel::initModel() {
/// \todo add the current position as a parameter to initShapeFunctions for
/// large deformation
getFEEngine().initShapeFunctions(_not_ghost);
getFEEngine().initShapeFunctions(_ghost);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initPBC() {
Model::initPBC();
registerPBCSynchronizer();
// as long as there are ones on the diagonal of the matrix, we can put boudandary true for slaves
std::map<UInt, UInt>::iterator it = pbc_pair.begin();
std::map<UInt, UInt>::iterator end = pbc_pair.end();
UInt dim = mesh.getSpatialDimension();
while(it != end) {
for (UInt i=0; i<dim; ++i)
(*blocked_dofs)((*it).first,i) = true;
++it;
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::registerPBCSynchronizer(){
- 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);
+ pbc_synch = new PBCSynchronizer(pbc_pair);
+ synch_registry->registerSynchronizer(*pbc_synch, _gst_smm_uv);
+ synch_registry->registerSynchronizer(*pbc_synch, _gst_smm_mass);
+ synch_registry->registerSynchronizer(*pbc_synch, _gst_smm_res);
+ synch_registry->registerSynchronizer(*pbc_synch, _gst_for_dump);
changeLocalEquationNumberForPBC(pbc_pair, mesh.getSpatialDimension());
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateCurrentPosition() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
current_position->resize(nb_nodes);
Real * current_position_val = current_position->storage();
Real * position_val = mesh.getNodes().storage();
Real * displacement_val = displacement->storage();
/// compute current_position = initial_position + displacement
memcpy(current_position_val, position_val, nb_nodes*spatial_dimension*sizeof(Real));
for (UInt n = 0; n < nb_nodes*spatial_dimension; ++n) {
*current_position_val++ += *displacement_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initializeUpdateResidualData() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
residual->resize(nb_nodes);
/// copy the forces in residual for boundary conditions
memcpy(residual->storage(), force->storage(), nb_nodes*spatial_dimension*sizeof(Real));
// start synchronization
synch_registry->asynchronousSynchronize(_gst_smm_uv);
synch_registry->waitEndSynchronize(_gst_smm_uv);
updateCurrentPosition();
AKANTU_DEBUG_OUT();
}
+/*----------------------------------------------------------------------------*/
+void SolidMechanicsModel::reInitialize()
+{
+
+}
+
/* -------------------------------------------------------------------------- */
/* Explicit scheme */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* This function compute the second member of the motion equation. That is to
* say the sum of forces @f$ r = F_{ext} - F_{int} @f$. @f$ F_{ext} @f$ is given
* by the user in the force vector, and @f$ F_{int} @f$ is computed as @f$
* F_{int} = \int_{\Omega} N \sigma d\Omega@f$
*
*/
void SolidMechanicsModel::updateResidual(bool need_initialize) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Assemble the internal forces");
// f = f_ext - f_int
// f = f_ext
if(need_initialize) initializeUpdateResidualData();
AKANTU_DEBUG_INFO("Compute local stresses");
std::vector<Material *>::iterator mat_it;
for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
mat.computeAllStresses(_not_ghost);
}
#ifdef AKANTU_DAMAGE_NON_LOCAL
/* ------------------------------------------------------------------------ */
/* Computation of the non local part */
- 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) {
Material & mat = **mat_it;
mat.assembleResidual(_not_ghost);
}
AKANTU_DEBUG_INFO("Wait distant stresses");
// finalize communications
synch_registry->waitEndSynchronize(_gst_smm_stress);
AKANTU_DEBUG_INFO("Assemble residual for ghost elements");
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
mat.assembleResidual(_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::computeStresses() {
if (isExplicit()) {
// start synchronization
synch_registry->asynchronousSynchronize(_gst_smm_uv);
synch_registry->waitEndSynchronize(_gst_smm_uv);
// compute stresses on all local elements for each materials
std::vector<Material *>::iterator mat_it;
for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
mat.computeAllStresses(_not_ghost);
}
/* ------------------------------------------------------------------------ */
#ifdef AKANTU_DAMAGE_NON_LOCAL
/* Computation of the non local part */
- 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) {
Material & mat = **mat_it;
mat.computeAllStressesFromTangentModuli(_not_ghost);
}
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateResidualInternal() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Update the residual");
// f = f_ext - f_int - Ma - Cv = r - Ma - Cv;
if(method != _static) {
// f -= Ma
if(mass_matrix) {
// if full mass_matrix
Array<Real> * Ma = new Array<Real>(*acceleration, true, "Ma");
*Ma *= *mass_matrix;
/// \todo check unit conversion for implicit dynamics
// *Ma /= f_m2a
*residual -= *Ma;
delete Ma;
} else if (mass) {
// else lumped mass
UInt nb_nodes = acceleration->getSize();
UInt nb_degree_of_freedom = acceleration->getNbComponent();
Real * mass_val = mass->storage();
Real * accel_val = acceleration->storage();
Real * res_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
- if(!(*blocked_dofs_val)) {
- *res_val -= *accel_val * *mass_val /f_m2a;
- }
- blocked_dofs_val++;
- res_val++;
- mass_val++;
- accel_val++;
+ if(!(*blocked_dofs_val)) {
+ *res_val -= *accel_val * *mass_val /f_m2a;
+ }
+ blocked_dofs_val++;
+ res_val++;
+ mass_val++;
+ accel_val++;
}
} else {
AKANTU_DEBUG_ERROR("No function called to assemble the mass matrix.");
}
// f -= Cv
if(velocity_damping_matrix) {
Array<Real> * Cv = new Array<Real>(*velocity);
*Cv *= *velocity_damping_matrix;
*residual -= *Cv;
delete Cv;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateAcceleration() {
AKANTU_DEBUG_IN();
updateResidualInternal();
if(method == _explicit_lumped_mass) {
/* residual = residual_{n+1} - M * acceleration_n therefore
solution = increment acceleration not acceleration */
solveLumped(*increment_acceleration,
- *mass,
- *residual,
- *blocked_dofs,
- f_m2a);
+ *mass,
+ *residual,
+ *blocked_dofs,
+ f_m2a);
} else if (method == _explicit_consistent_mass) {
solve<NewmarkBeta::_acceleration_corrector>(*increment_acceleration);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::solveLumped(Array<Real> & x,
- const Array<Real> & A,
- const Array<Real> & b,
- const Array<bool> & blocked_dofs,
- Real alpha) {
+ const Array<Real> & A,
+ const Array<Real> & b,
+ const Array<bool> & blocked_dofs,
+ Real alpha) {
Real * A_val = A.storage();
Real * b_val = b.storage();
Real * x_val = x.storage();
bool * blocked_dofs_val = blocked_dofs.storage();
UInt nb_degrees_of_freedom = x.getSize() * x.getNbComponent();
for (UInt n = 0; n < nb_degrees_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*x_val = alpha * (*b_val / *A_val);
}
x_val++;
A_val++;
b_val++;
blocked_dofs_val++;
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::explicitPred() {
AKANTU_DEBUG_IN();
if(increment_flag) {
if(previous_displacement) increment->copy(*previous_displacement);
else increment->copy(*displacement);
}
AKANTU_DEBUG_ASSERT(integrator,"itegrator should have been allocated: "
- << "have called initExplicit ? "
- << "or initImplicit ?");
+ << "have called initExplicit ? "
+ << "or initImplicit ?");
integrator->integrationSchemePred(time_step,
- *displacement,
- *velocity,
- *acceleration,
- *blocked_dofs);
+ *displacement,
+ *velocity,
+ *acceleration,
+ *blocked_dofs);
if(increment_flag) {
Real * inc_val = increment->storage();
Real * dis_val = displacement->storage();
UInt nb_degree_of_freedom = displacement->getSize() * displacement->getNbComponent();
for (UInt n = 0; n < nb_degree_of_freedom; ++n) {
*inc_val = *dis_val - *inc_val;
inc_val++;
dis_val++;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::explicitCorr() {
AKANTU_DEBUG_IN();
integrator->integrationSchemeCorrAccel(time_step,
- *displacement,
- *velocity,
- *acceleration,
- *blocked_dofs,
- *increment_acceleration);
+ *displacement,
+ *velocity,
+ *acceleration,
+ *blocked_dofs,
+ *increment_acceleration);
if(previous_displacement) previous_displacement->copy(*displacement);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::solveStep() {
AKANTU_DEBUG_IN();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
this->explicitPred();
this->updateResidual();
this->updateAcceleration();
this->explicitCorr();
EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
/* Implicit scheme */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**
* Initialize the solver and create the sparse matrices needed.
*
*/
void SolidMechanicsModel::initSolver(__attribute__((unused)) SolverOptions & options) {
-#if !defined(AKANTU_USE_MUMPS) // or other solver in the future \todo add AKANTU_HAS_SOLVER in CMake
+#if !defined(AKANTU_USE_MUMPS) && !defined(AKANTU_USE_PETSC)// or other solver in the future \todo add AKANTU_HAS_SOLVER in CMake
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#else
UInt nb_global_nodes = mesh.getNbGlobalNodes();
delete jacobian_matrix;
std::stringstream sstr; sstr << id << ":jacobian_matrix";
- jacobian_matrix = new SparseMatrix(nb_global_nodes * spatial_dimension, _symmetric, sstr.str(), memory_id);
+#ifdef AKANTU_USE_PETSC
+ jacobian_matrix = new PETScMatrix(nb_global_nodes * spatial_dimension, _symmetric, sstr.str(), memory_id);
+#else
+ jacobian_matrix = new SparseMatrix(nb_global_nodes * spatial_dimension, _unsymmetric, sstr.str(), memory_id);
+#endif //AKANTU_USE PETSC
jacobian_matrix->buildProfile(mesh, *dof_synchronizer, spatial_dimension);
if (!isExplicit()) {
delete stiffness_matrix;
std::stringstream sstr_sti; sstr_sti << id << ":stiffness_matrix";
+#ifdef AKANTU_USE_PETSC
+ stiffness_matrix = new SparseMatrix(nb_global_nodes * spatial_dimension, _symmetric, sstr.str(), memory_id);
+ stiffness_matrix->buildProfile(mesh, *dof_synchronizer, spatial_dimension);
+#else
stiffness_matrix = new SparseMatrix(*jacobian_matrix, sstr_sti.str(), memory_id);
+#endif //AKANTU_USE_PETSC
}
-#ifdef AKANTU_USE_MUMPS
+ delete solver;
std::stringstream sstr_solv; sstr_solv << id << ":solver";
+#ifdef AKANTU_USE_PETSC
+ solver = new SolverPETSc(*jacobian_matrix, sstr_solv.str());
+#elif defined(AKANTU_USE_MUMPS)
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
-
dof_synchronizer->initScatterGatherCommunicationScheme();
#else
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#endif //AKANTU_USE_MUMPS
if(solver)
solver->initialize(options);
#endif //AKANTU_HAS_SOLVER
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initJacobianMatrix() {
-#ifdef AKANTU_USE_MUMPS
-
+#if defined(AKANTU_USE_MUMPS) && !defined(AKANTU_USE_PETSC)
+
// @todo make it more flexible: this is an ugly patch to treat the case of non
// fix profile of the K matrix
delete jacobian_matrix;
std::stringstream sstr_sti; sstr_sti << id << ":jacobian_matrix";
jacobian_matrix = new SparseMatrix(*stiffness_matrix, sstr_sti.str(), memory_id);
std::stringstream sstr_solv; sstr_solv << id << ":solver";
delete solver;
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
if(solver)
solver->initialize(_solver_no_options);
#else
- AKANTU_DEBUG_ERROR("You should at least activate one solver.");
+ AKANTU_DEBUG_ERROR("You need to activate the solver mumps.");
#endif
}
/* -------------------------------------------------------------------------- */
/**
* Initialize the implicit solver, either for dynamic or static cases,
*
* @param dynamic
*/
void SolidMechanicsModel::initImplicit(bool dynamic, SolverOptions & solver_options) {
AKANTU_DEBUG_IN();
method = dynamic ? _implicit_dynamic : _static;
if (!increment) setIncrementFlagOn();
initSolver(solver_options);
if(method == _implicit_dynamic) {
if(integrator) delete integrator;
integrator = new TrapezoidalRule2();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::initialAcceleration() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Solving Ma = f");
Solver * acc_solver = NULL;
std::stringstream sstr; sstr << id << ":tmp_mass_matrix";
SparseMatrix * tmp_mass = new SparseMatrix(*mass_matrix, sstr.str(), memory_id);
#ifdef AKANTU_USE_MUMPS
std::stringstream sstr_solver; sstr << id << ":solver_mass_matrix";
acc_solver = new SolverMumps(*mass_matrix, sstr_solver.str());
dof_synchronizer->initScatterGatherCommunicationScheme();
#else
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#endif //AKANTU_USE_MUMPS
acc_solver->initialize();
tmp_mass->applyBoundary(*blocked_dofs);
acc_solver->setRHS(*residual);
acc_solver->solve(*acceleration);
delete acc_solver;
delete tmp_mass;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleStiffnessMatrix() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Assemble the new stiffness matrix.");
stiffness_matrix->clear();
// call compute stiffness matrix on each local elements
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
(*mat_it)->assembleStiffnessMatrix(_not_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseMatrix & SolidMechanicsModel::initVelocityDampingMatrix() {
if(!velocity_damping_matrix)
velocity_damping_matrix =
new SparseMatrix(*jacobian_matrix, id + ":velocity_damping_matrix", memory_id);
return *velocity_damping_matrix;
}
/* -------------------------------------------------------------------------- */
template<>
bool SolidMechanicsModel::testConvergence<_scc_increment>(Real tolerance, Real & error){
AKANTU_DEBUG_IN();
UInt nb_nodes = displacement->getSize();
UInt nb_degree_of_freedom = displacement->getNbComponent();
error = 0;
Real norm[2] = {0., 0.};
Real * increment_val = increment->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
Real * displacement_val = displacement->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val) && is_local_node) {
- norm[0] += *increment_val * *increment_val;
- norm[1] += *displacement_val * *displacement_val;
+ norm[0] += *increment_val * *increment_val;
+ norm[1] += *displacement_val * *displacement_val;
}
blocked_dofs_val++;
increment_val++;
displacement_val++;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(norm, 2, _so_sum);
norm[0] = sqrt(norm[0]);
norm[1] = sqrt(norm[1]);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm[0]), "Something goes wrong in the solve phase");
if (norm[1] < Math::getTolerance()) {
error = norm[0];
AKANTU_DEBUG_OUT();
// cout<<"Error 1: "<<error<<endl;
return error < tolerance;
}
AKANTU_DEBUG_OUT();
if(norm[1] > Math::getTolerance())
error = norm[0] / norm[1];
else
error = norm[0]; //In case the total displacement is zero!
// cout<<"Error 2: "<<error<<endl;
return (error < tolerance);
}
/* -------------------------------------------------------------------------- */
template<>
bool SolidMechanicsModel::testConvergence<_scc_residual>(Real tolerance, Real & norm) {
AKANTU_DEBUG_IN();
-
-
UInt nb_nodes = residual->getSize();
+ UInt nb_degree_of_freedom = displacement->getNbComponent();
norm = 0;
Real * residual_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
if(is_local_node) {
- for (UInt d = 0; d < spatial_dimension; ++d) {
- if(!(*blocked_dofs_val)) {
- norm += *residual_val * *residual_val;
- }
- blocked_dofs_val++;
- residual_val++;
+ for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
+ if(!(*blocked_dofs_val)) {
+ norm += *residual_val * *residual_val;
+ }
+ blocked_dofs_val++;
+ residual_val++;
}
} else {
blocked_dofs_val += spatial_dimension;
residual_val += spatial_dimension;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum);
norm = sqrt(norm);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
AKANTU_DEBUG_OUT();
return (norm < tolerance);
}
/* -------------------------------------------------------------------------- */
template<>
bool SolidMechanicsModel::testConvergence<_scc_residual_mass_wgh>(Real tolerance,
- Real & norm) {
+ Real & norm) {
AKANTU_DEBUG_IN();
UInt nb_nodes = residual->getSize();
norm = 0;
Real * residual_val = residual->storage();
Real * mass_val = this->mass->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
if(is_local_node) {
for (UInt d = 0; d < spatial_dimension; ++d) {
- if(!(*blocked_dofs_val)) {
- norm += *residual_val * *residual_val/(*mass_val * *mass_val);
- }
- blocked_dofs_val++;
- residual_val++;
- mass_val++;
+ if(!(*blocked_dofs_val)) {
+ norm += *residual_val * *residual_val/(*mass_val * *mass_val);
+ }
+ blocked_dofs_val++;
+ residual_val++;
+ mass_val++;
}
} else {
blocked_dofs_val += spatial_dimension;
residual_val += spatial_dimension;
mass_val += spatial_dimension;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum);
norm = sqrt(norm);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
AKANTU_DEBUG_OUT();
return (norm < tolerance);
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::testConvergenceResidual(Real tolerance){
AKANTU_DEBUG_IN();
Real error=0;
bool res = this->testConvergence<_scc_residual>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::testConvergenceResidual(Real tolerance, Real & error){
AKANTU_DEBUG_IN();
bool res = this->testConvergence<_scc_residual>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::testConvergenceIncrement(Real tolerance){
AKANTU_DEBUG_IN();
Real error=0;
bool res = this->testConvergence<_scc_increment>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
bool SolidMechanicsModel::testConvergenceIncrement(Real tolerance, Real & error){
AKANTU_DEBUG_IN();
bool res = this->testConvergence<_scc_increment>(tolerance, error);
AKANTU_DEBUG_OUT();
return res;
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::implicitPred() {
AKANTU_DEBUG_IN();
- if(previous_displacement) previous_displacement->copy(*displacement);
-
if(method == _implicit_dynamic)
integrator->integrationSchemePred(time_step,
- *displacement,
- *velocity,
- *acceleration,
- *blocked_dofs);
+ *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);
+ *displacement,
+ *velocity,
+ *acceleration,
+ *blocked_dofs,
+ *increment);
} else {
UInt nb_nodes = displacement->getSize();
UInt nb_degree_of_freedom = displacement->getNbComponent() * nb_nodes;
Real * incr_val = increment->storage();
Real * disp_val = displacement->storage();
bool * boun_val = blocked_dofs->storage();
for (UInt j = 0; j < nb_degree_of_freedom; ++j, ++disp_val, ++incr_val, ++boun_val){
*incr_val *= (1. - *boun_val);
*disp_val += *incr_val;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateIncrement() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(previous_displacement,"The previous displacement has to be initialized."
- << " Are you working with Finite or Ineslactic deformations?");
+ << " Are you working with Finite or Ineslactic deformations?");
UInt nb_nodes = displacement->getSize();
UInt nb_degree_of_freedom = displacement->getNbComponent() * nb_nodes;
Real * incr_val = increment->storage();
Real * disp_val = displacement->storage();
Real * prev_disp_val = previous_displacement->storage();
for (UInt j = 0; j < nb_degree_of_freedom; ++j, ++disp_val, ++incr_val, ++prev_disp_val)
*incr_val = (*disp_val - *prev_disp_val);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updatePreviousDisplacement() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(previous_displacement,"The previous displacement has to be initialized."
- << " Are you working with Finite or Ineslactic deformations?");
+ << " 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?");
+ << " 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?");
+ << " Did you call initPBC?");
synch_registry->synchronize(_gst_smm_res);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::setIncrementFlagOn() {
AKANTU_DEBUG_IN();
if(!increment) {
UInt nb_nodes = mesh.getNbNodes();
std::stringstream sstr_inc; sstr_inc << id << ":increment";
increment = &(alloc<Real>(sstr_inc.str(), nb_nodes, spatial_dimension, 0.));
}
increment_flag = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getStableTimeStep() {
AKANTU_DEBUG_IN();
Real min_dt = getStableTimeStep(_not_ghost);
/// reduction min over all processors
StaticCommunicator::getStaticCommunicator().allReduce(&min_dt, 1, _so_min);
AKANTU_DEBUG_OUT();
return min_dt;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getStableTimeStep(const GhostType & ghost_type) {
AKANTU_DEBUG_IN();
Material ** mat_val = &(materials.at(0));
Real min_dt = std::numeric_limits<Real>::max();
updateCurrentPosition();
Element elem;
elem.ghost_type = ghost_type;
elem.kind = _ek_regular;
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_regular);
+ Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type, _ek_regular);
for(; it != end; ++it) {
elem.type = *it;
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(*it);
UInt nb_element = mesh.getNbElement(*it);
- Array<UInt>::iterator< Vector<UInt> > eibm =
- element_index_by_material(*it, ghost_type).begin(2);
+ 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);
+ X, *it, _not_ghost);
Array<Real>::matrix_iterator X_el =
X.begin(spatial_dimension, nb_nodes_per_element);
- for (UInt el = 0; el < nb_element; ++el, ++X_el, ++eibm) {
- elem.element = (*eibm)(1);
+ 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[(*eibm)(0)]->getCelerity(elem);
+ 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::getPotentialEnergy() {
- AKANTU_DEBUG_IN();
- Real energy = 0.;
-
- /// call update residual on each local elements
- std::vector<Material *>::iterator mat_it;
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
- energy += (*mat_it)->getPotentialEnergy();
- }
-
- /// reduction sum over all processors
- StaticCommunicator::getStaticCommunicator().allReduce(&energy, 1, _so_sum);
-
- AKANTU_DEBUG_OUT();
- return energy;
-}
-
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getKineticEnergy() {
AKANTU_DEBUG_IN();
if (!mass && !mass_matrix)
AKANTU_DEBUG_ERROR("No function called to assemble the mass matrix.");
Real ekin = 0.;
UInt nb_nodes = mesh.getNbNodes();
Real * vel_val = velocity->storage();
Real * mass_val = mass->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
Real mv2 = 0;
bool is_local_node = mesh.isLocalOrMasterNode(n);
bool is_not_pbc_slave_node = !isPBCSlaveNode(n);
bool count_node = is_local_node && is_not_pbc_slave_node;
for (UInt i = 0; i < spatial_dimension; ++i) {
if (count_node)
- mv2 += *vel_val * *vel_val * *mass_val;
+ mv2 += *vel_val * *vel_val * *mass_val;
vel_val++;
mass_val++;
}
ekin += mv2;
}
StaticCommunicator::getStaticCommunicator().allReduce(&ekin, 1, _so_sum);
AKANTU_DEBUG_OUT();
return ekin * .5;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getKineticEnergy(const ElementType & type, UInt index) {
AKANTU_DEBUG_IN();
- UInt nb_quadrature_points = getFEEngine().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);
Vector<Real> rho_v2(nb_quadrature_points);
- Real rho = materials[element_index_by_material(type)(index, 0)]->getRho();
+ Real rho = materials[material_index(type)(index)]->getRho();
for (UInt q = 0; vit != vend; ++vit, ++q) {
rho_v2(q) = rho * vit->dot(*vit);
}
AKANTU_DEBUG_OUT();
return .5*getFEEngine().integrate(rho_v2, type, index);
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getExternalWork() {
AKANTU_DEBUG_IN();
- Real * velo = velocity->storage();
- Real * forc = force->storage();
- Real * resi = residual->storage();
- bool * boun = blocked_dofs->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 = this->force->storage();
+ Real * resi = this->residual->storage();
+ bool * boun = this->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;
- else
- work += *forc * *velo * time_step;
+ if(*boun)
+ work -= *resi * *incr_or_velo;
+ else
+ 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"){
return getExternalWork();
}
Real energy = 0.;
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
energy += (*mat_it)->getEnergy(energy_id);
}
/// reduction sum over all processors
StaticCommunicator::getStaticCommunicator().allReduce(&energy, 1, _so_sum);
AKANTU_DEBUG_OUT();
return energy;
}
/* -------------------------------------------------------------------------- */
Real SolidMechanicsModel::getEnergy(const std::string & energy_id,
- const ElementType & type,
- UInt index){
+ const ElementType & type,
+ UInt index) {
AKANTU_DEBUG_IN();
if (energy_id == "kinetic") {
return getKineticEnergy(type, index);
}
std::vector<Material *>::iterator mat_it;
- Vector<UInt> mat = element_index_by_material(type, _not_ghost).begin(2)[index];
- Real energy = materials[mat(0)]->getEnergy(energy_id, type, mat(1));
+ UInt mat_index = this->material_index(type, _not_ghost)(index);
+ UInt mat_loc_num = this->material_local_numbering(type, _not_ghost)(index);
+ Real energy = this->materials[mat_index]->getEnergy(energy_id, type, mat_loc_num);
AKANTU_DEBUG_OUT();
return energy;
}
-
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModel::onNodesAdded(const Array<UInt> & nodes_list,
- __attribute__((unused)) const NewNodesEvent & event) {
+void SolidMechanicsModel::onElementsAdded(const Array<Element> & element_list,
+ const NewElementsEvent & event) {
AKANTU_DEBUG_IN();
- UInt nb_nodes = mesh.getNbNodes();
-
- if(displacement) displacement->resize(nb_nodes);
- if(mass ) mass ->resize(nb_nodes);
- if(velocity ) velocity ->resize(nb_nodes);
- if(acceleration) acceleration->resize(nb_nodes);
- if(force ) force ->resize(nb_nodes);
- if(residual ) residual ->resize(nb_nodes);
- if(blocked_dofs) blocked_dofs->resize(nb_nodes);
-
- if(previous_displacement) previous_displacement->resize(nb_nodes);
- if(increment_acceleration) increment_acceleration->resize(nb_nodes);
- if(increment) increment->resize(nb_nodes);
-
- if(current_position) current_position->resize(nb_nodes);
- delete dof_synchronizer;
- dof_synchronizer = new DOFSynchronizer(mesh, spatial_dimension);
- dof_synchronizer->initLocalDOFEquationNumbers();
- dof_synchronizer->initGlobalDOFEquationNumbers();
+ this->getFEEngine().initShapeFunctions(_not_ghost);
+ this->getFEEngine().initShapeFunctions(_ghost);
- std::vector<Material *>::iterator mat_it;
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
- (*mat_it)->onNodesAdded(nodes_list, event);
- }
-
- if (method != _explicit_lumped_mass) {
- delete stiffness_matrix;
- delete jacobian_matrix;
- delete solver;
- SolverOptions solver_options;
- initImplicit((method == _implicit_dynamic), solver_options);
+ for(UInt g = _not_ghost; g <= _ghost; ++g) {
+ GhostType gt = (GhostType) g;
+ Mesh::type_iterator it = this->mesh.firstType(spatial_dimension, gt, _ek_not_defined);
+ Mesh::type_iterator end = this->mesh.lastType(spatial_dimension, gt, _ek_not_defined);
+ for(; it != end; ++it) {
+ UInt nb_element = this->mesh.getNbElement(*it, gt);
+ if(!material_index.exists(*it, gt)) {
+ this->material_index .alloc(nb_element, 1, *it, gt);
+ this->material_local_numbering.alloc(nb_element, 1, *it, gt);
+ } else {
+ this->material_index (*it, gt).resize(nb_element);
+ this->material_local_numbering(*it, gt).resize(nb_element);
+ }
+ }
}
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModel::onElementsAdded(const Array<Element> & element_list,
- const NewElementsEvent & event) {
- AKANTU_DEBUG_IN();
-
- getFEEngine().initShapeFunctions(_not_ghost);
- getFEEngine().initShapeFunctions(_ghost);
-
Array<Element>::const_iterator<Element> it = element_list.begin();
Array<Element>::const_iterator<Element> end = element_list.end();
- /// \todo have rules to choose the correct material
- UInt mat_id = 0;
-
- UInt * mat_id_vect = NULL;
- try {
- const NewMaterialElementsEvent & event_mat = dynamic_cast<const NewMaterialElementsEvent &>(event);
- mat_id_vect = event_mat.getMaterialList().storage();
- } catch(...) { }
+ ElementTypeMapArray<UInt> filter("new_element_filter", this->getID());
for (UInt el = 0; it != end; ++it, ++el) {
const Element & elem = *it;
- if(mat_id_vect) mat_id = mat_id_vect[el];
- else mat_id = (*material_selector)(elem);
-
- Material & mat = *materials[mat_id];
+ if(!filter.exists(elem.type, elem.ghost_type))
+ filter.alloc(0, 1, elem.type, elem.ghost_type);
- UInt mat_index = mat.addElement(elem.type, elem.element, elem.ghost_type);
- Vector<UInt> id(2);
- id[0] = mat_id; id[1] = mat_index;
- if(!element_index_by_material.exists(elem.type, elem.ghost_type))
- element_index_by_material.alloc(0, 2, elem.type, elem.ghost_type);
-
- element_index_by_material(elem.type, elem.ghost_type).push_back(id);
+ filter(elem.type, elem.ghost_type).push_back(elem.element);
}
+ this->assignMaterialToElements(&filter);
+
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
(*mat_it)->onElementsAdded(element_list, event);
}
- if(method != _explicit_lumped_mass) AKANTU_DEBUG_TO_IMPLEMENT();
-
- assembleMassLumped();
+ if(method == _explicit_lumped_mass) this->assembleMassLumped();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onElementsRemoved(__attribute__((unused)) const Array<Element> & element_list,
- const ElementTypeMapArray<UInt> & new_numbering,
- const RemovedElementsEvent & event) {
- // MeshUtils::purifyMesh(mesh);
-
- getFEEngine().initShapeFunctions(_not_ghost);
- getFEEngine().initShapeFunctions(_ghost);
+ const ElementTypeMapArray<UInt> & new_numbering,
+ const RemovedElementsEvent & event) {
+ this->getFEEngine().initShapeFunctions(_not_ghost);
+ this->getFEEngine().initShapeFunctions(_ghost);
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
(*mat_it)->onElementsRemoved(element_list, new_numbering, event);
}
+
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModel::onNodesAdded(const Array<UInt> & nodes_list,
+ __attribute__((unused)) const NewNodesEvent & event) {
+ AKANTU_DEBUG_IN();
+ UInt nb_nodes = mesh.getNbNodes();
+
+ if(displacement) displacement->resize(nb_nodes);
+ if(mass ) mass ->resize(nb_nodes);
+ if(velocity ) velocity ->resize(nb_nodes);
+ if(acceleration) acceleration->resize(nb_nodes);
+ if(force ) force ->resize(nb_nodes);
+ if(residual ) residual ->resize(nb_nodes);
+ if(blocked_dofs) blocked_dofs->resize(nb_nodes);
+
+ if(previous_displacement) previous_displacement->resize(nb_nodes);
+ if(increment_acceleration) increment_acceleration->resize(nb_nodes);
+ if(increment) increment->resize(nb_nodes);
+
+ if(current_position) current_position->resize(nb_nodes);
+
+ std::vector<Material *>::iterator mat_it;
+ for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ (*mat_it)->onNodesAdded(nodes_list, event);
+ }
+
+ delete dof_synchronizer;
+ dof_synchronizer = new DOFSynchronizer(mesh, spatial_dimension);
+ dof_synchronizer->initLocalDOFEquationNumbers();
+ dof_synchronizer->initGlobalDOFEquationNumbers();
+
+ if (method != _explicit_lumped_mass) {
+ this->initSolver();
+ }
+
+ AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onNodesRemoved(__attribute__((unused)) const Array<UInt> & element_list,
- const Array<UInt> & new_numbering,
- __attribute__((unused)) const RemovedNodesEvent & event) {
+ const Array<UInt> & new_numbering,
+ __attribute__((unused)) const RemovedNodesEvent & event) {
if(displacement) mesh.removeNodesFromArray(*displacement, new_numbering);
if(mass ) mesh.removeNodesFromArray(*mass , new_numbering);
if(velocity ) mesh.removeNodesFromArray(*velocity , new_numbering);
if(acceleration) mesh.removeNodesFromArray(*acceleration, new_numbering);
if(force ) mesh.removeNodesFromArray(*force , new_numbering);
if(residual ) mesh.removeNodesFromArray(*residual , new_numbering);
if(blocked_dofs) mesh.removeNodesFromArray(*blocked_dofs, new_numbering);
if(increment_acceleration) mesh.removeNodesFromArray(*increment_acceleration, new_numbering);
if(increment) mesh.removeNodesFromArray(*increment , new_numbering);
delete dof_synchronizer;
dof_synchronizer = new DOFSynchronizer(mesh, spatial_dimension);
dof_synchronizer->initLocalDOFEquationNumbers();
dof_synchronizer->initGlobalDOFEquationNumbers();
-}
-
-/* -------------------------------------------------------------------------- */
-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_regular);
- Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type, _ek_regular);
- 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> & el_index_by_mat = element_index_by_material(type, ghost_type);
-
- for (UInt el = 0; el < nb_element; ++el) {
- element.element = el;
-
- UInt old_material = el_index_by_mat(el, 0);
- UInt new_material = (*material_selector)(element);
-
- if(old_material != new_material) {
- element_to_add [new_material].push_back(element);
- element_to_remove[old_material].push_back(element);
- }
- }
- }
- }
-
- std::vector<Material *>::iterator mat_it;
- UInt mat_index = 0;
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it, ++mat_index) {
- (*mat_it)->removeElements(element_to_remove[mat_index]);
- (*mat_it)->addElements (element_to_add[mat_index]);
+ if (method != _explicit_lumped_mass) {
+ this->initSolver();
}
- AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
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){
-
- 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];
- for (UInt m = 0; m < materials.size(); ++m)
- materials[m]->flattenInternal(field_name,*internal_flat,_not_ghost,kind);
-
- return *internal_flat;
+
+ typedef ElementTypeMapArray<Real>::type_iterator iterator;
+ iterator tit = internal_flat->firstType(spatial_dimension, ghost_type, kind);
+ iterator end = internal_flat->lastType(spatial_dimension, ghost_type, kind);
+
+ for (; tit != end; ++tit) {
+ ElementType type = *tit;
+ (*internal_flat)(type, ghost_type).clear();
+ }
+
+ for (UInt m = 0; m < materials.size(); ++m) {
+ if (materials[m]->isInternal<Real>(field_name, kind))
+ materials[m]->flattenInternal(field_name, *internal_flat, ghost_type,
+ kind);
+ }
+
+ return *internal_flat;
}
/* -------------------------------------------------------------------------- */
-void SolidMechanicsModel::flattenAllRegisteredInternals(const ElementKind & kind){
+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);
+ this->flattenInternal(it->first.first, kind);
++it;
}
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::onDump(){
this->flattenAllRegisteredInternals(_ek_regular);
}
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
dumper::Field * SolidMechanicsModel
-::createElementalField(const std::string & field_name,
- const std::string & group_name,
- bool padding_flag,
- const ElementKind & kind){
-
+::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,this->spatial_dimension,kind);
- else if(field_name == "element_index_by_material")
- field = mesh.createElementalField<UInt, Vector, dumper::ElementalField >(element_index_by_material,group_name,this->spatial_dimension,kind);
+ if(field_name == "partitions")
+ field = mesh.createElementalField<UInt, dumper::ElementPartitionField>(mesh.getConnectivities(),group_name,spatial_dimension,kind);
+ else if(field_name == "material_index")
+ field = mesh.createElementalField<UInt, Vector, dumper::ElementalField >(material_index,group_name,spatial_dimension,kind);
else {
+ // this copy of field_name is used to compute derivated data such as
+ // strain and von mises stress that are based on grad_u and stress
+ std::string field_name_copy(field_name);
- bool is_internal = this->isInternal(field_name,kind);
+ 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";
- if (is_internal) {
+ bool is_internal = this->isInternal(field_name_copy,kind);
- ElementTypeMap<UInt> nb_data_per_elem = this->getInternalDataPerElem(field_name,kind);
- ElementTypeMapArray<Real> & internal_flat = this->flattenInternal(field_name,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,
- this->spatial_dimension,kind,nb_data_per_elem);
-
+ 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 (this->spatial_dimension == 2) {
+ 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);
+ }
}
- // else if (field_name == "strain"){
- // if (this->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::ComputeFunctorInterface * foo =
dumper::HomogenizerProxy::createHomogenizer(*field);
field = dumper::FieldComputeProxy::createFieldCompute(field,*foo);
- }
+ }
}
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
-
+
std::map<std::string,Array<Real>* > real_nodal_fields;
real_nodal_fields["displacement" ] = displacement;
real_nodal_fields["mass" ] = mass;
real_nodal_fields["velocity" ] = velocity;
real_nodal_fields["acceleration" ] = acceleration;
real_nodal_fields["force" ] = force;
real_nodal_fields["residual" ] = residual;
real_nodal_fields["increment" ] = increment;
dumper::Field * field = NULL;
if (padding_flag)
- field = mesh.createNodalField(real_nodal_fields[field_name],group_name, 3);
+ field = mesh.createNodalField(real_nodal_fields[field_name], group_name, 3);
else
- field = mesh.createNodalField(real_nodal_fields[field_name],group_name);
-
+ field = mesh.createNodalField(real_nodal_fields[field_name], group_name);
+
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel::createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
-
+
std::map<std::string,Array<bool>* > uint_nodal_fields;
uint_nodal_fields["blocked_dofs" ] = blocked_dofs;
dumper::Field * field = NULL;
field = mesh.createNodalField(uint_nodal_fields[field_name],group_name);
return field;
}
/* -------------------------------------------------------------------------- */
#else
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel
-::createElementalField(const std::string & field_name,
+::createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
+ const UInt & spatial_dimension,
const ElementKind & kind){
return NULL;
}
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
return NULL;
}
/* -------------------------------------------------------------------------- */
dumper::Field * SolidMechanicsModel::createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
return NULL;
}
#endif
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(const std::string & dumper_name) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
- synch_registry->synchronize(_gst_for_dump);
mesh.dump(dumper_name);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(const std::string & dumper_name, UInt step) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
- synch_registry->synchronize(_gst_for_dump);
mesh.dump(dumper_name, step);
}
/* ------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(const std::string & dumper_name, Real time, UInt step) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
- synch_registry->synchronize(_gst_for_dump);
mesh.dump(dumper_name, time, step);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump() {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
mesh.dump();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(UInt step) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
mesh.dump(step);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::dump(Real time, UInt step) {
this->onDump();
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeDumpEvent());
mesh.dump(time, step);
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::computeCauchyStresses() {
AKANTU_DEBUG_IN();
// call compute stiffness matrix on each local elements
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
if(mat.isFiniteDeformation())
mat.computeAllCauchyStresses(_not_ghost);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::saveStressAndStrainBeforeDamage() {
EventManager::sendEvent(SolidMechanicsModelEvent::BeginningOfDamageIterationEvent());
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::updateEnergiesAfterDamage() {
EventManager::sendEvent(SolidMechanicsModelEvent::AfterDamageEvent());
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
stream << space << "Solid Mechanics Model [" << std::endl;
stream << space << " + id : " << id << std::endl;
stream << space << " + spatial dimension : " << spatial_dimension << std::endl;
stream << space << " + fem [" << std::endl;
getFEEngine().printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << " + nodals information [" << std::endl;
displacement->printself(stream, indent + 2);
mass ->printself(stream, indent + 2);
velocity ->printself(stream, indent + 2);
acceleration->printself(stream, indent + 2);
force ->printself(stream, indent + 2);
residual ->printself(stream, indent + 2);
blocked_dofs->printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
- stream << space << " + connectivity type information [" << std::endl;
- element_index_by_material.printself(stream, indent + 2);
+ stream << space << " + material information [" << std::endl;
+ material_index.printself(stream, indent + 2);
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << " + materials [" << std::endl;
std::vector<Material *>::const_iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
const Material & mat = *(*mat_it);
mat.printself(stream, indent + 1);
}
stream << space << AKANTU_INDENT << "]" << std::endl;
stream << space << "]" << std::endl;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model.hh b/src/model/solid_mechanics/solid_mechanics_model.hh
index 5209ed661..8f1e4d81d 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,737 +1,774 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLID_MECHANICS_MODEL_HH__
#define __AKANTU_SOLID_MECHANICS_MODEL_HH__
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_types.hh"
#include "model.hh"
#include "data_accessor.hh"
#include "mesh.hh"
#include "dumpable.hh"
#include "boundary_condition.hh"
#include "integrator_gauss.hh"
#include "shape_lagrange.hh"
#include "integration_scheme_2nd_order.hh"
#include "solver.hh"
#include "material_selector.hh"
#include "solid_mechanics_model_event_handler.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class Material;
class IntegrationScheme2ndOrder;
class SparseMatrix;
class DumperIOHelper;
+ class NonLocalManager;
}
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
struct SolidMechanicsModelOptions : public ModelOptions {
SolidMechanicsModelOptions(AnalysisMethod analysis_method = _explicit_lumped_mass,
bool no_init_materials = false) :
analysis_method(analysis_method),
no_init_materials(no_init_materials) { }
AnalysisMethod analysis_method;
bool no_init_materials;
};
extern const SolidMechanicsModelOptions default_solid_mechanics_model_options;
class SolidMechanicsModel : public Model,
public DataAccessor,
public MeshEventHandler,
public BoundaryCondition<SolidMechanicsModel>,
- public EventHandlerManager<SolidMechanicsModelEventHandler> {
+ public EventHandlerManager<SolidMechanicsModelEventHandler> {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
class NewMaterialElementsEvent : public NewElementsEvent {
public:
AKANTU_GET_MACRO_NOT_CONST(MaterialList, material, Array <UInt> &);
AKANTU_GET_MACRO(MaterialList, material, const Array <UInt> &);
protected:
Array <UInt> material;
};
typedef FEEngineTemplate <IntegratorGauss, ShapeLagrange> MyFEEngineType;
protected:
typedef EventHandlerManager <SolidMechanicsModelEventHandler> EventManager;
public:
SolidMechanicsModel(Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "solid_mechanics_model",
const MemoryID & memory_id = 0);
virtual ~SolidMechanicsModel();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize completely the model
virtual void initFull(const ModelOptions & options = default_solid_mechanics_model_options);
/// initialize the fem object needed for boundary conditions
void initFEEngineBoundary();
/// register the tags associated with the parallel synchronizer
- void initParallel(MeshPartition *partition, DataAccessor *data_accessor = NULL);
+ virtual void initParallel(MeshPartition *partition,
+ DataAccessor *data_accessor = NULL);
/// allocate all vectors
- void initArrays();
+ virtual void initArrays();
/// allocate all vectors
void initArraysPreviousDisplacment();
/// initialize all internal arrays for materials
virtual void initMaterials();
/// initialize the model
virtual void initModel();
/// init PBC synchronizer
void initPBC();
/// function to print the containt of the class
virtual void printself(std::ostream & stream, int indent = 0) const;
+ /// re-initialize model to set fields to 0
+ void reInitialize();
+
/* ------------------------------------------------------------------------ */
/* PBC */
/* ------------------------------------------------------------------------ */
public:
/// change the equation number for proper assembly when using PBC
- void changeEquationNumberforPBC(std::map <UInt, UInt> & pbc_pair);
+ // void changeEquationNumberforPBC(std::map <UInt, UInt> & pbc_pair);
/// synchronize Residual for output
void synchronizeResidual();
protected:
/// register PBC synchronizer
void registerPBCSynchronizer();
/* ------------------------------------------------------------------------ */
/* Explicit */
/* ------------------------------------------------------------------------ */
public:
/// initialize the stuff for the explicit scheme
void initExplicit(AnalysisMethod analysis_method = _explicit_lumped_mass);
bool isExplicit() {
return method == _explicit_lumped_mass || method == _explicit_consistent_mass;
}
/// initialize the array needed by updateResidual (residual, current_position)
void initializeUpdateResidualData();
/// update the current position vector
void updateCurrentPosition();
/// assemble the residual for the explicit scheme
virtual void updateResidual(bool need_initialize = true);
/**
* \brief compute the acceleration from the residual
* this function is the explicit equivalent to solveDynamic in implicit
* In the case of lumped mass just divide the residual by the mass
* In the case of not lumped mass call solveDynamic<_acceleration_corrector>
*/
void updateAcceleration();
-
+ ///Update the increment of displacement
void updateIncrement();
+ ///Copy the actuel displacement into previous displacement
void updatePreviousDisplacement();
+ ///Save stress and strain through EventManager
void saveStressAndStrainBeforeDamage();
+ ///Update energies through EventManager
void updateEnergiesAfterDamage();
/// Solve the system @f[ A x = \alpha b @f] with A a lumped matrix
void solveLumped(Array <Real> & x,
const Array <Real> & A,
const Array <Real> & b,
const Array <bool> & blocked_dofs,
Real alpha);
/// explicit integration predictor
void explicitPred();
/// explicit integration corrector
void explicitCorr();
public:
void solveStep();
/* ------------------------------------------------------------------------ */
/* Implicit */
/* ------------------------------------------------------------------------ */
public:
/// initialize the solver and the jacobian_matrix (called by initImplicit)
void initSolver(SolverOptions & options = _solver_no_options);
/// initialize the stuff for the implicit solver
void initImplicit(bool dynamic = false,
SolverOptions & solver_options = _solver_no_options);
/// solve Ma = f to get the initial acceleration
void initialAcceleration();
/// assemble the stiffness matrix
void assembleStiffnessMatrix();
public:
/**
* solve a step (predictor + convergence loop + corrector) using the
* the given convergence method (see akantu::SolveConvergenceMethod)
* and the given convergence criteria (see
* akantu::SolveConvergenceCriteria)
**/
template <SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance, UInt max_iteration = 100);
template <SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance,
Real & error,
UInt max_iteration = 100,
bool do_not_factorize = false);
public:
/**
* solve Ku = f using the the given convergence method (see
* akantu::SolveConvergenceMethod) and the given convergence
* criteria (see akantu::SolveConvergenceCriteria)
**/
template <SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool solveStatic(Real tolerance, UInt max_iteration,
bool do_not_factorize = false);
/// test if the system is converged
template <SolveConvergenceCriteria criteria>
bool testConvergence(Real tolerance, Real & error);
/// test the convergence (norm of increment)
bool testConvergenceIncrement(Real tolerance) __attribute__((deprecated));
bool testConvergenceIncrement(Real tolerance, Real & error) __attribute__((deprecated));
/// test the convergence (norm of residual)
bool testConvergenceResidual(Real tolerance) __attribute__((deprecated));
bool testConvergenceResidual(Real tolerance, Real & error) __attribute__((deprecated));
/// create and return the velocity damping matrix
SparseMatrix & initVelocityDampingMatrix();
/// implicit time integration predictor
void implicitPred();
/// implicit time integration corrector
void implicitCorr();
/// compute the Cauchy stress on user demand.
void computeCauchyStresses();
+ /// compute A and solve @f[ A\delta u = f_ext - f_int @f]
+ template <NewmarkBeta::IntegrationSchemeCorrectorType type>
+ void solve(Array<Real> &increment, Real block_val = 1.,
+ bool need_factorize = true, bool has_profile_changed = false);
+
protected:
/// finish the computation of residual to solve in increment
void updateResidualInternal();
/// compute the support reaction and store it in force
void updateSupportReaction();
-
-public:
-
- //protected: Daniel changed it just for a test
- /// 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,
- const Array<Real> &rhs = Array<Real>());
-
private:
/// re-initialize the J matrix (to use if the profile of K changed)
void initJacobianMatrix();
/* ------------------------------------------------------------------------ */
/* Explicit/Implicit */
/* ------------------------------------------------------------------------ */
public:
/// Update the stresses for the computation of the residual of the Stiffness
/// matrix in the case of finite deformation
void computeStresses();
/// synchronize the ghost element boundaries values
void synchronizeBoundaries();
/* ------------------------------------------------------------------------ */
/* Materials (solid_mechanics_model_material.cc) */
/* ------------------------------------------------------------------------ */
public:
/// registers all the custom materials of a given type present in the input file
template <typename M>
void registerNewCustomMaterials(const ID & mat_type);
/// register an empty material of a given type
template <typename M>
Material & registerNewEmptyMaterial(const std::string & name);
// /// Use a UIntData in the mesh to specify the material to use per element
// void setMaterialIDsFromIntData(const std::string & data_name);
/// reassigns materials depending on the material selector
virtual void reassignMaterial();
+ /// apply a constant eigen_grad_u on all quadrature points of a given material
+ virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const ID & material_name, const GhostType ghost_type = _not_ghost);
+
+
protected:
/// register a material in the dynamic database
template <typename M>
Material & registerNewMaterial(const ParserSection & mat_section);
/// read the material files to instantiate all the materials
void instantiateMaterials();
+ /// set the element_id_by_material and add the elements to the good materials
+ void assignMaterialToElements(const ElementTypeMapArray<UInt> * filter = NULL);
+
/* ------------------------------------------------------------------------ */
/* Mass (solid_mechanics_model_mass.cc) */
/* ------------------------------------------------------------------------ */
public:
/// assemble the lumped mass matrix
void assembleMassLumped();
/// assemble the mass matrix for consistent mass resolutions
void assembleMass();
protected:
/// assemble the lumped mass matrix for local and ghost elements
void assembleMassLumped(GhostType ghost_type);
/// assemble the mass matrix for either _ghost or _not_ghost elements
void assembleMass(GhostType ghost_type);
/// fill a vector of rho
void computeRho(Array <Real> & rho,
ElementType type,
GhostType ghost_type);
+ /// compute the kinetic energy
+ Real getKineticEnergy();
+ Real getKineticEnergy(const ElementType & type, UInt index);
+
+ /// compute the external work (for impose displacement, the velocity should be given too)
+ Real getExternalWork();
/* ------------------------------------------------------------------------ */
/* Data Accessor inherited members */
/* ------------------------------------------------------------------------ */
public:
+
inline virtual UInt getNbDataForElements(const Array <Element> & elements,
- SynchronizationTag tag) const;
+ SynchronizationTag tag) const;
inline virtual void packElementData(CommunicationBuffer & buffer,
const Array <Element> & elements,
SynchronizationTag tag) const;
inline virtual void unpackElementData(CommunicationBuffer & buffer,
const Array <Element> & elements,
SynchronizationTag tag);
inline virtual UInt getNbDataToPack(SynchronizationTag tag) const;
inline virtual UInt getNbDataToUnpack(SynchronizationTag tag) const;
inline virtual void packData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag) const;
inline virtual void unpackData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag);
protected:
inline void splitElementByMaterial(const Array <Element> & elements,
Array <Element> * elements_per_mat) const;
/* ------------------------------------------------------------------------ */
/* Mesh Event Handler inherited members */
/* ------------------------------------------------------------------------ */
protected:
virtual void onNodesAdded(const Array <UInt> & nodes_list,
const NewNodesEvent & event);
virtual void onNodesRemoved(const Array <UInt> & element_list,
const Array <UInt> & new_numbering,
const RemovedNodesEvent & event);
virtual void onElementsAdded(const Array <Element> & nodes_list,
const NewElementsEvent & event);
virtual void onElementsRemoved(const Array <Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event);
+ virtual void onElementsChanged(__attribute__((unused)) const Array<Element> & old_elements_list,
+ __attribute__((unused)) const Array<Element> & new_elements_list,
+ __attribute__((unused)) const ElementTypeMapArray<UInt> & new_numbering,
+ __attribute__((unused)) const ChangedElementsEvent & event) {};
+
+
/* ------------------------------------------------------------------------ */
/* Dumpable interface (kept for convenience) and dumper relative functions */
/* ------------------------------------------------------------------------ */
public:
virtual void onDump();
//! decide wether a field is a material internal or not
bool isInternal(const std::string & field_name, const ElementKind & element_kind);
+#ifndef SWIG
//! give the amount of data per element
- 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
+ //! flatten a given material internal field
ElementTypeMapArray<Real> & flattenInternal(const std::string & field_name,
- const ElementKind & kind);
+ 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,
+
+ virtual dumper::Field * createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
+ const UInt & spatial_dimension,
const ElementKind & kind);
-
-
virtual void dump(const std::string & dumper_name);
virtual void dump(const std::string & dumper_name, UInt step);
virtual void dump(const std::string & dumper_name, Real time, UInt step);
virtual void dump();
virtual void dump(UInt step);
virtual void dump(Real time, UInt step);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// return the dimension of the system space
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// get the current value of the time step
AKANTU_GET_MACRO(TimeStep, time_step, Real);
/// set the value of the time step
void setTimeStep(Real time_step);
+ /// return the of iterations done in the last solveStep
+ AKANTU_GET_MACRO(NumberIter, n_iter, UInt);
+
/// get the value of the conversion from forces/ mass to acceleration
AKANTU_GET_MACRO(F_M2A, f_m2a, Real);
/// set the value of the conversion from forces/ mass to acceleration
AKANTU_SET_MACRO(F_M2A, f_m2a, Real);
/// get the SolidMechanicsModel::displacement vector
AKANTU_GET_MACRO(Displacement, *displacement, Array <Real> &);
/// get the SolidMechanicsModel::previous_displacement vector
AKANTU_GET_MACRO(PreviousDisplacement, *previous_displacement, Array <Real> &);
/// get the SolidMechanicsModel::current_position vector \warn only consistent
/// after a call to SolidMechanicsModel::updateCurrentPosition
AKANTU_GET_MACRO(CurrentPosition, *current_position, const Array <Real> &);
/// get the SolidMechanicsModel::increment vector \warn only consistent if
/// SolidMechanicsModel::setIncrementFlagOn has been called before
AKANTU_GET_MACRO(Increment, *increment, Array <Real> &);
/// get the lumped SolidMechanicsModel::mass vector
AKANTU_GET_MACRO(Mass, *mass, Array <Real> &);
/// get the SolidMechanicsModel::velocity vector
AKANTU_GET_MACRO(Velocity, *velocity, Array <Real> &);
/// get the SolidMechanicsModel::acceleration vector, updated by
/// SolidMechanicsModel::updateAcceleration
AKANTU_GET_MACRO(Acceleration, *acceleration, Array <Real> &);
/// get the SolidMechanicsModel::force vector (boundary forces)
AKANTU_GET_MACRO(Force, *force, Array <Real> &);
/// get the SolidMechanicsModel::residual vector, computed by
/// SolidMechanicsModel::updateResidual
AKANTU_GET_MACRO(Residual, *residual, Array <Real> &);
/// get the SolidMechanicsModel::blocked_dofs vector
AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array <bool> &);
/// get the SolidMechnicsModel::incrementAcceleration vector
AKANTU_GET_MACRO(IncrementAcceleration, *increment_acceleration, Array <Real> &);
/// get the value of the SolidMechanicsModel::increment_flag
AKANTU_GET_MACRO(IncrementFlag, increment_flag, bool);
/// get a particular material (by material index)
inline Material & getMaterial(UInt mat_index);
/// get a particular material (by material index)
inline const Material & getMaterial(UInt mat_index) const;
/// get a particular material (by material name)
inline Material & getMaterial(const std::string & name);
/// get a particular material (by material name)
inline const Material & getMaterial(const std::string & name) const;
/// get a particular material id from is name
inline UInt getMaterialIndex(const std::string & name) const;
/// give the number of materials
inline UInt getNbMaterials() const {
return materials.size();
}
inline void setMaterialSelector(MaterialSelector & selector);
/// give the material internal index from its id
Int getInternalIndexFromID(const ID & id) const;
/// compute the stable time step
Real getStableTimeStep();
- /// compute the potential energy
- Real getPotentialEnergy();
-
- /// compute the kinetic energy
- Real getKineticEnergy();
- Real getKineticEnergy(const ElementType & type, UInt index);
-
- /// compute the external work (for impose displacement, the velocity should be given too)
- Real getExternalWork();
-
/// get the energies
Real getEnergy(const std::string & energy_id);
/// compute the energy for energy
Real getEnergy(const std::string & energy_id, const ElementType & type, UInt index);
/**
* @brief set the SolidMechanicsModel::increment_flag to on, the activate the
* update of the SolidMechanicsModel::increment vector
*/
void setIncrementFlagOn();
/// get the stiffness matrix
AKANTU_GET_MACRO(StiffnessMatrix, *stiffness_matrix, SparseMatrix &);
/// get the global jacobian matrix of the system
AKANTU_GET_MACRO(GlobalJacobianMatrix, *jacobian_matrix, const SparseMatrix &);
/// get the mass matrix
AKANTU_GET_MACRO(MassMatrix, *mass_matrix, SparseMatrix &);
/// get the velocity damping matrix
AKANTU_GET_MACRO(VelocityDampingMatrix, *velocity_damping_matrix, SparseMatrix &);
/// get the FEEngine object to integrate or interpolate on the boundary
inline FEEngine & getFEEngineBoundary(const ID & name = "");
/// get integrator
AKANTU_GET_MACRO(Integrator, *integrator, const IntegrationScheme2ndOrder &);
/// get access to the internal solver
AKANTU_GET_MACRO(Solver, *solver, Solver &);
/// get synchronizer
AKANTU_GET_MACRO(Synchronizer, *synch_parallel, const DistributedSynchronizer &);
- AKANTU_GET_MACRO(ElementIndexByMaterial, element_index_by_material, 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(ElementIndexByMaterial, element_index_by_material, UInt);
- AKANTU_GET_MACRO_BY_ELEMENT_TYPE(ElementIndexByMaterial, element_index_by_material, UInt);
+ AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialByElement, material_index, UInt);
+ AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialByElement, material_index, UInt);
+ AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialLocalNumbering, material_local_numbering, UInt);
+ AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialLocalNumbering, material_local_numbering, UInt);
/// Get the type of analysis method used
AKANTU_GET_MACRO(AnalysisMethod, method, AnalysisMethod);
+ /// get the non-local manager
+ AKANTU_GET_MACRO(NonLocalManager, *non_local_manager, NonLocalManager &);
template <int dim, class model_type>
friend struct ContactData;
template <int Dim, AnalysisMethod s, ContactResolutionMethod r>
friend class ContactResolution;
-
protected:
friend class Material;
- template <UInt DIM, template <UInt> class WeightFunction>
- friend class MaterialNonLocal;
protected:
/// compute the stable time step
Real getStableTimeStep(const GhostType & ghost_type);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
+ /// number of iterations
+ UInt n_iter;
+
/// time step
Real time_step;
/// conversion coefficient form force/mass to acceleration
Real f_m2a;
/// displacements array
Array <Real> *displacement;
/// displacements array at the previous time step (used in finite deformation)
Array <Real> *previous_displacement;
/// lumped mass array
Array <Real> *mass;
/// velocities array
Array <Real> *velocity;
/// accelerations array
Array <Real> *acceleration;
/// accelerations array
Array <Real> *increment_acceleration;
/// forces array
Array <Real> *force;
/// residuals array
Array <Real> *residual;
/// array specifing if a degree of freedom is blocked or not
Array <bool> *blocked_dofs;
/// array of current position used during update residual
Array <Real> *current_position;
/// mass matrix
SparseMatrix *mass_matrix;
/// velocity damping matrix
SparseMatrix *velocity_damping_matrix;
/// stiffness matrix
SparseMatrix *stiffness_matrix;
/// jacobian matrix @f[A = cM + dD + K@f] with @f[c = \frac{1}{\beta \Delta
/// t^2}, d = \frac{\gamma}{\beta \Delta t} @f]
SparseMatrix *jacobian_matrix;
- /// vectors containing local material element index for each global element index
- ElementTypeMapArray<UInt> element_index_by_material;
+ /// Arrays containing the material index for each element
+ ElementTypeMapArray<UInt> material_index;
+
+ /// Arrays containing the position in the element filter of the material (material's local numbering)
+ ElementTypeMapArray<UInt> material_local_numbering;
+#ifdef SWIGPYTHON
+public:
+#endif
/// list of used materials
std::vector <Material *> materials;
/// mapping between material name and material internal id
std::map <std::string, UInt> materials_names_to_id;
+#ifdef SWIGPYTHON
+protected:
+#endif
/// class defining of to choose a material
MaterialSelector *material_selector;
/// define if it is the default selector or not
bool is_default_material_selector;
/// integration scheme of second order used
IntegrationScheme2ndOrder *integrator;
/// increment of displacement
Array <Real> *increment;
/// flag defining if the increment must be computed or not
bool increment_flag;
/// solver for implicit
Solver *solver;
/// analysis method check the list in akantu::AnalysisMethod
AnalysisMethod method;
/// internal synchronizer for parallel computations
DistributedSynchronizer *synch_parallel;
/// tells if the material are instantiated
bool are_materials_instantiated;
/// map a registered internals to be flattened for dump purposes
std::map<std::pair<std::string,ElementKind>,ElementTypeMapArray<Real> *> registered_internals;
+
+ /// pointer to non-local manager: For non-local continuum damage computations
+ NonLocalManager * non_local_manager;
+
+ /// pointer to the pbc synchronizer
+ PBCSynchronizer * pbc_synch;
+
};
/* -------------------------------------------------------------------------- */
namespace BC {
namespace Neumann {
typedef FromHigherDim FromStress;
- typedef FromSameDim FromTraction;
+ typedef FromSameDim FromTraction;
}
}
__END_AKANTU__
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "parser.hh"
#include "material.hh"
__BEGIN_AKANTU__
#include "solid_mechanics_model_tmpl.hh"
#if defined (AKANTU_INCLUDE_INLINE_IMPL)
# include "solid_mechanics_model_inline_impl.cc"
#endif
/// standard output stream operator
inline std::ostream & operator << (std::ostream & stream, const SolidMechanicsModel &_this) {
_this.printself(stream);
return stream;
}
__END_AKANTU__
- #include "material_selector_tmpl.hh"
+#include "material_selector_tmpl.hh"
- #endif /* __AKANTU_SOLID_MECHANICS_MODEL_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 a77393efa..000000000
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive.cc
+++ /dev/null
@@ -1,906 +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,
- true);
-
-/* -------------------------------------------------------------------------- */
-
-SolidMechanicsModelCohesive::SolidMechanicsModelCohesive(Mesh & mesh,
- UInt dim,
- const ID & id,
- const MemoryID & memory_id) :
- SolidMechanicsModel(mesh, dim, id, memory_id),
- tangents("tangents", id),
- stress_on_facet("stress_on_facet", 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->stress_interpolation = smmc_options.stress_interpolation;
- this->is_extrinsic = smmc_options.extrinsic;
-
- if (!inserter)
- inserter = new CohesiveElementInserter(mesh, is_extrinsic, synch_parallel,
- id+":cohesive_element_inserter");
-
- SolidMechanicsModel::initFull(options);
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- if (facet_synchronizer != NULL)
- inserter->initParallel(facet_synchronizer);
-#endif
-
- if (is_extrinsic)
- initAutomaticInsertion();
-
- 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);
- }
- }
- }
- } else {
- 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> & el_id_by_mat = element_index_by_material(*first, *gt);
- Vector<UInt> el_mat(2); el_mat(0) = cohesive_index; el_mat(1) = 0;
- el_id_by_mat.set(el_mat);
- }
- }
- }
-
- 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::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();
-
- /// allocate stress_on_facet to store element stress on facets
- mesh.initElementTypeMapArray(stress_on_facet,
- spatial_dimension * spatial_dimension,
- spatial_dimension);
-
- Mesh::type_iterator it = mesh.firstType(spatial_dimension);
- Mesh::type_iterator last = mesh.lastType(spatial_dimension);
-
- for (; it != last; ++it) {
- ElementType type = *it;
- UInt nb_element = mesh.getNbElement(type);
-
- UInt nb_facet_per_elem = Mesh::getNbFacetsPerElement(type);
- ElementType type_facet = Mesh::getFacetType(type);
- UInt nb_quad_per_facet = getFEEngine("FacetsFEEngine").getNbQuadraturePoints(type_facet);
-
- stress_on_facet(type).resize(nb_quad_per_facet * nb_facet_per_elem * nb_element);
- }
-
- if (stress_interpolation)
- 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 = inserter->getMeshFacets();
- 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 =
- getFEEngine("FacetsFEEngine").getNormalsOnQuadPoints(facet_type);
-
- UInt nb_quad = normals.getSize();
-
- Array<Real> & tang = tangents(facet_type);
- tang.resize(nb_quad);
-
- Real * normal_it = normals.storage();
- Real * tangent_it = tang.storage();
-
- /// compute first tangent
- for (UInt q = 0; q < nb_quad; ++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 = tang.storage();
-
- for (UInt q = 0; q < nb_quad; ++q) {
- Math::normal3(normal_it, tangent_it, tangent_it + spatial_dimension);
- normal_it += spatial_dimension;
- tangent_it += tangent_components;
- }
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::averageStressOnFacets(UInt material_index) {
- AKANTU_DEBUG_IN();
-
- Mesh::type_iterator it = mesh.firstType(spatial_dimension);
- Mesh::type_iterator last = mesh.lastType(spatial_dimension);
-
- /// loop over element type
- for (; it != last; ++it) {
- ElementType type = *it;
- UInt nb_element = mesh.getNbElement(type);
- UInt nb_quad_per_element = getFEEngine().getNbQuadraturePoints(type);
- const Array<Real> & stress = materials[material_index]->getStress(type);
- Array<Real> & s_on_facet = stress_on_facet(type);
-
- UInt nb_facet_per_elem = Mesh::getNbFacetsPerElement(type);
- ElementType type_facet = Mesh::getFacetType(type);
- UInt nb_quad_per_facet = getFEEngine("FacetsFEEngine").getNbQuadraturePoints(type_facet);
- UInt nb_facet_quad_per_elem = nb_quad_per_facet * nb_facet_per_elem;
-
- Array<Real>::const_iterator<Matrix<Real> > stress_it
- = stress.begin(spatial_dimension, spatial_dimension);
- Array<Real>::iterator<Matrix<Real> > s_on_facet_it
- = s_on_facet.begin(spatial_dimension, spatial_dimension);
-
- Matrix<Real> average_stress(spatial_dimension, spatial_dimension);
-
- for (UInt el = 0; el < nb_element; ++el) {
-
- /// compute average stress
- average_stress.clear();
-
- for (UInt q = 0; q < nb_quad_per_element; ++q, ++stress_it)
- average_stress += *stress_it;
-
- average_stress /= nb_quad_per_element;
-
- /// store average stress
- for (UInt q = 0; q < nb_facet_quad_per_elem; ++q, ++s_on_facet_it)
- *s_on_facet_it = average_stress;
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::fillStressOnFacet() {
- AKANTU_DEBUG_IN();
-
- Mesh & mesh_facets = inserter->getMeshFacets();
- UInt sp2 = spatial_dimension * spatial_dimension;
- UInt sp4 = sp2 * 2;
-
- /// loop over materials
- for (UInt m = 0; m < materials.size(); ++m) {
- try {
- MaterialCohesive & mat __attribute__((unused)) =
- dynamic_cast<MaterialCohesive &>(*materials[m]);
- } catch(std::bad_cast&) {
-
- if (stress_interpolation)
- /// interpolate stress on facet quadrature points positions
- materials[m]->interpolateStress(stress_on_facet);
- else
- averageStressOnFacets(m);
-
- GhostType ghost_type = _not_ghost;
-
- Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
- Mesh::type_iterator last = mesh.lastType(spatial_dimension, ghost_type);
-
- /// loop over element type
- for (; it != last; ++it) {
- ElementType type = *it;
- UInt nb_element = mesh.getNbElement(type, ghost_type);
- if (nb_element == 0) continue;
-
- Array<Real> & stress_on_f = stress_on_facet(type, ghost_type);
-
- /// store the interpolated stresses on the facet_stress vector
- Array<Element> & facet_to_element =
- mesh_facets.getSubelementToElement(type, ghost_type);
-
- UInt nb_facet_per_elem = facet_to_element.getNbComponent();
-
- Array<Element>::iterator<Vector<Element> > facet_to_el_it =
- facet_to_element.begin(nb_facet_per_elem);
-
- Array<Real>::iterator< Matrix<Real> > stress_on_f_it =
- stress_on_f.begin(spatial_dimension, spatial_dimension);
-
- ElementType facet_type = _not_defined;
- GhostType facet_gt = _casper;
- Array<std::vector<Element> > * element_to_facet = NULL;
- Array<Real> * f_stress = NULL;
- Array<bool> * f_check = NULL;
- UInt nb_quad_per_facet = 0;
- UInt element_rank = 0;
-
- Element current_el(type, 0, ghost_type);
-
- for (UInt el = 0; el < nb_element; ++el, ++facet_to_el_it) {
- current_el.element = el;
- for (UInt f = 0; f < nb_facet_per_elem; ++f) {
- Element global_facet_elem = (*facet_to_el_it)(f);
- UInt global_facet = global_facet_elem.element;
-
- if (facet_type != global_facet_elem.type ||
- facet_gt != global_facet_elem.ghost_type) {
- facet_type = global_facet_elem.type;
- facet_gt = global_facet_elem.ghost_type;
-
- element_to_facet =
- &( mesh_facets.getElementToSubelement(facet_type, facet_gt) );
- f_stress = &( facet_stress(facet_type, facet_gt) );
-
- nb_quad_per_facet =
- getFEEngine("FacetsFEEngine").getNbQuadraturePoints(facet_type, facet_gt);
-
- f_check = &( inserter->getCheckFacets(facet_type, facet_gt) );
- }
-
- if (!(*f_check)(global_facet)) {
- stress_on_f_it += nb_quad_per_facet;
- continue;
- }
-
- for (UInt q = 0; q < nb_quad_per_facet; ++q, ++stress_on_f_it) {
-
- element_rank = (*element_to_facet)(global_facet)[0] != current_el;
-
- Matrix<Real> facet_stress_local(f_stress->storage()
- + (global_facet * nb_quad_per_facet + q) * sp4
- + element_rank * sp2,
- spatial_dimension,
- spatial_dimension);
-
- facet_stress_local = *stress_on_f_it;
- }
- }
- }
- }
- }
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::reassignMaterial() {
- AKANTU_DEBUG_IN();
-
- SolidMechanicsModel::reassignMaterial();
-
- 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_cohesive);
- Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive);
- 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> & el_index_by_mat = element_index_by_material(type, ghost_type);
-
- for (UInt el = 0; el < nb_element; ++el) {
- element.element = el;
-
- UInt old_material = el_index_by_mat(el, 0);
- UInt new_material = (*material_selector)(element);
-
- if(old_material != new_material) {
- element_to_add [new_material].push_back(element);
- element_to_remove[old_material].push_back(element);
- }
- }
- }
- }
-
- std::vector<Material *>::iterator mat_it;
- UInt mat_index = 0;
- for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it, ++mat_index) {
- (*mat_it)->removeElements(element_to_remove[mat_index]);
- (*mat_it)->addElements (element_to_add[mat_index]);
- }
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::checkCohesiveStress() {
- AKANTU_DEBUG_IN();
-
- fillStressOnFacet();
-
-#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
-
- 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&) { }
- }
-
- /// communicate data among processors
- synch_registry->synchronize(_gst_smmc_facets);
-
- /// insert cohesive elements
- inserter->insertElements();
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::onElementsAdded(const Array<Element> & element_list,
- const NewElementsEvent & event) {
- AKANTU_DEBUG_IN();
-
- SolidMechanicsModel::onElementsAdded(element_list, event);
-
- /// update shape functions
- getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
- getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
- updateCohesiveSynchronizers();
-#endif
-
- 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();
-
- ElementKind _element_kind = element_kind;
- if (dumper_name == "cohesive elements") {
- _element_kind = _ek_cohesive;
- }
- SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name,
- field_id,
- group_name,
- _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 a8bc4dfe7..000000000
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive.hh
+++ /dev/null
@@ -1,299 +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,
- bool stress_interpolation = true) :
- SolidMechanicsModelOptions(analysis_method, no_init_materials),
- extrinsic(extrinsic),
- stress_interpolation(stress_interpolation) {}
- bool extrinsic;
- bool stress_interpolation;
-};
-
-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:
-
- /// reassigns materials depending on the material selector
- virtual void reassignMaterial();
-
- /// 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
- void checkCohesiveStress();
-
- /// 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();
-
-private:
-
- /// initialize completely the model for extrinsic elements
- void initAutomaticInsertion();
-
- /// initialize stress interpolation
- void initStressInterpolation();
-
- /// compute facets' normals
- void computeNormals();
-
- /// resize facet stress
- void resizeFacetStress();
-
- /// init facets_check array
- void initFacetsCheck();
-
- /// fill stress_on_facet
- void fillStressOnFacet();
-
- /// compute average stress on elements
- void averageStressOnFacets(UInt material_index);
-
- /* ------------------------------------------------------------------------ */
- /* 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;
-
- /// list of stresses on facet quadrature points for every element
- ElementTypeMapArray<Real> stress_on_facet;
-
- /// 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;
-
- /// stress interpolation flag
- bool stress_interpolation;
-
- bool is_extrinsic;
-
- /// cohesive element inserter
- CohesiveElementInserter * inserter;
-
-#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
-#include "solid_mechanics_model_cohesive_parallel.hh"
-#endif
-
-};
-
-
-/* -------------------------------------------------------------------------- */
-/* inline functions */
-/* -------------------------------------------------------------------------- */
-
-#if defined (AKANTU_PARALLEL_COHESIVE_ELEMENT)
-# include "solid_mechanics_model_cohesive_inline_impl.cc"
-#endif
-
-/* -------------------------------------------------------------------------- */
-class DefaultMaterialCohesiveSelector : public DefaultMaterialSelector {
-public:
- DefaultMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model) :
- DefaultMaterialSelector(model.getElementIndexByMaterial()),
- 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;
-};
-
-
-/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const SolidMechanicsModelCohesive & _this)
-{
- _this.printself(stream);
- return stream;
-}
-
-
-__END_AKANTU__
-
-
-#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..c2fc756db
--- /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: 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().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..d285ef514
--- /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: 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 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..db65caf9c
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
@@ -0,0 +1,95 @@
+/**
+ * @file material_selector_cohesive.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+
+ * @date Thu Dec 10 10:27:02 2015
+ *
+ * @brief
+ *
+ * @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 "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..5f1580248
--- /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 Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date creation: Tue May 08 2012
+ * @date last modification: Tue Sep 02 2014
+ *
+ * @brief Material selectors for cohesive elements
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..335153da2
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
@@ -0,0 +1,751 @@
+/**
+ * @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, synch_parallel);
+#endif
+ initAutomaticInsertion();
+ } else {
+ // TODO think of something a bit mor consistant than just coding the first
+ // thing that comes in Fabian's head....
+ typedef ParserSection::const_section_iterator const_section_iterator;
+ std::pair<const_section_iterator, const_section_iterator> sub_sections =
+ this->parser->getSubSections(_st_mesh);
+
+ if (sub_sections.first != sub_sections.second) {
+ std::string cohesive_surfaces =
+ sub_sections.first->getParameter("cohesive_surfaces");
+ this->initIntrinsicCohesiveMaterials(cohesive_surfaces);
+ } else {
+ this->initIntrinsicCohesiveMaterials(cohesive_index);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(std::string cohesive_surfaces) {
+
+ AKANTU_DEBUG_IN();
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_synchronizer != NULL)
+ inserter->initParallel(facet_synchronizer, synch_parallel);
+#endif
+ std::istringstream split(cohesive_surfaces);
+ std::string physname;
+ while(std::getline(split,physname,',')){
+ AKANTU_DEBUG_INFO("Pre-inserting cohesive elements along facets from physical surface: "
+ << physname);
+ insertElementsFromMeshData(physname);
+ }
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_synchronizer != NULL){
+ facet_synchronizer-> asynchronousSynchronize(*inserter, _gst_ce_groups);
+ facet_synchronizer-> waitEndSynchronize(*inserter, _gst_ce_groups);
+ }
+#endif
+
+ SolidMechanicsModel::initMaterials();
+
+ if(is_default_material_selector) delete material_selector;
+ material_selector = new MeshDataMaterialCohesiveSelector(*this);
+ inserter->insertElements();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initIntrinsicCohesiveMaterials(UInt cohesive_index) {
+
+ AKANTU_DEBUG_IN();
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ Mesh::type_iterator first = mesh.firstType(spatial_dimension, *gt, _ek_cohesive);
+ Mesh::type_iterator last = mesh.lastType(spatial_dimension, *gt, _ek_cohesive);
+
+ for(;first != last; ++first) {
+ Array<UInt> & mat_indexes = this->material_index(*first, *gt);
+ Array<UInt> & mat_loc_num = this->material_local_numbering(*first, *gt);
+ mat_indexes.set(cohesive_index);
+ mat_loc_num.clear();
+ }
+ }
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_synchronizer != NULL)
+ inserter->initParallel(facet_synchronizer, synch_parallel);
+#endif
+
+ SolidMechanicsModel::initMaterials();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Initialize the model,basically it pre-compute the shapes, shapes derivatives
+ * and jacobian
+ *
+ */
+void SolidMechanicsModelCohesive::initModel() {
+ AKANTU_DEBUG_IN();
+
+ SolidMechanicsModel::initModel();
+
+ registerFEEngineObject<MyFEEngineCohesiveType>("CohesiveFEEngine", mesh, spatial_dimension);
+
+ /// add cohesive type connectivity
+ ElementType type = _not_defined;
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+
+ GhostType type_ghost = *gt;
+
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, type_ghost);
+ Mesh::type_iterator last = mesh.lastType(spatial_dimension, type_ghost);
+
+ for (; it != last; ++it) {
+ const Array<UInt> & connectivity = mesh.getConnectivity(*it, type_ghost);
+ if (connectivity.getSize() != 0) {
+ type = *it;
+ ElementType type_facet = Mesh::getFacetType(type);
+ ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
+ mesh.addConnectivityType(type_cohesive, type_ghost);
+ }
+ }
+ }
+
+ AKANTU_DEBUG_ASSERT(type != _not_defined, "No elements in the mesh");
+
+ getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
+ getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
+
+ registerFEEngineObject<MyFEEngineType>("FacetsFEEngine",
+ mesh.getMeshFacets(),
+ spatial_dimension - 1);
+
+ if (is_extrinsic) {
+ getFEEngine("FacetsFEEngine").initShapeFunctions(_not_ghost);
+ getFEEngine("FacetsFEEngine").initShapeFunctions(_ghost);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::limitInsertion(BC::Axis axis,
+ Real first_limit,
+ Real second_limit) {
+ AKANTU_DEBUG_IN();
+ inserter->setLimit(axis, first_limit, second_limit);
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::insertIntrinsicElements() {
+ AKANTU_DEBUG_IN();
+ inserter->insertIntrinsicElements();
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::insertElementsFromMeshData(std::string physname) {
+ AKANTU_DEBUG_IN();
+
+ UInt material_index = SolidMechanicsModel::getMaterialIndex(physname);
+ inserter->insertIntrinsicElements(physname, material_index);
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initAutomaticInsertion() {
+ AKANTU_DEBUG_IN();
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_stress_synchronizer != NULL) {
+ DataAccessor * data_accessor = this;
+ const ElementTypeMapArray<UInt> & rank_to_element = synch_parallel->getPrankToElement();
+
+ facet_stress_synchronizer->updateFacetStressSynchronizer(*inserter,
+ rank_to_element,
+ *data_accessor);
+ }
+#endif
+
+ inserter->getMeshFacets().initElementTypeMapArray(facet_stress,
+ 2 * spatial_dimension * spatial_dimension,
+ spatial_dimension - 1);
+
+ resizeFacetStress();
+
+ /// compute normals on facets
+ computeNormals();
+
+ initStressInterpolation();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::updateAutomaticInsertion() {
+ AKANTU_DEBUG_IN();
+
+ inserter->limitCheckFacets();
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (facet_stress_synchronizer != NULL) {
+ DataAccessor * data_accessor = this;
+ const ElementTypeMapArray<UInt> & rank_to_element = synch_parallel->getPrankToElement();
+
+ facet_stress_synchronizer->updateFacetStressSynchronizer(*inserter,
+ rank_to_element,
+ *data_accessor);
+ }
+#endif
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::initStressInterpolation() {
+ Mesh & mesh_facets = inserter->getMeshFacets();
+
+ /// compute quadrature points coordinates on facets
+ Array<Real> & position = mesh.getNodes();
+
+ ElementTypeMapArray<Real> quad_facets("quad_facets", id);
+ mesh_facets.initElementTypeMapArray(quad_facets,
+ spatial_dimension, spatial_dimension - 1);
+
+ getFEEngine("FacetsFEEngine").interpolateOnIntegrationPoints(position, quad_facets);
+
+ /// compute elements quadrature point positions and build
+ /// element-facet quadrature points data structure
+ ElementTypeMapArray<Real> elements_quad_facets("elements_quad_facets", id);
+
+ mesh.initElementTypeMapArray(elements_quad_facets,
+ spatial_dimension,
+ spatial_dimension);
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end(); ++gt) {
+
+ GhostType elem_gt = *gt;
+
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, elem_gt);
+ Mesh::type_iterator last = mesh.lastType(spatial_dimension, elem_gt);
+
+ for (; it != last; ++it) {
+ ElementType type = *it;
+ UInt nb_element = mesh.getNbElement(type, elem_gt);
+ if (nb_element == 0) continue;
+
+ /// compute elements' quadrature points and list of facet
+ /// quadrature points positions by element
+ Array<Element> & facet_to_element = mesh_facets.getSubelementToElement(type,
+ elem_gt);
+ UInt nb_facet_per_elem = facet_to_element.getNbComponent();
+
+ Array<Real> & el_q_facet = elements_quad_facets(type, elem_gt);
+
+ ElementType facet_type = Mesh::getFacetType(type);
+
+ UInt nb_quad_per_facet =
+ getFEEngine("FacetsFEEngine").getNbIntegrationPoints(facet_type);
+
+ el_q_facet.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet);
+
+ for (UInt el = 0; el < nb_element; ++el) {
+ for (UInt f = 0; f < nb_facet_per_elem; ++f) {
+ Element global_facet_elem = facet_to_element(el, f);
+ UInt global_facet = global_facet_elem.element;
+ GhostType facet_gt = global_facet_elem.ghost_type;
+ const Array<Real> & quad_f = quad_facets(facet_type, facet_gt);
+
+ for (UInt q = 0; q < nb_quad_per_facet; ++q) {
+ for (UInt s = 0; s < spatial_dimension; ++s) {
+ el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet
+ + f * nb_quad_per_facet + q, s)
+ = quad_f(global_facet * nb_quad_per_facet + q, s);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /// loop over non cohesive materials
+ for (UInt m = 0; m < materials.size(); ++m) {
+ try {
+ MaterialCohesive & mat __attribute__((unused)) =
+ dynamic_cast<MaterialCohesive &>(*materials[m]);
+ } catch(std::bad_cast&) {
+ /// initialize the interpolation function
+ materials[m]->initElementalFieldInterpolation(elements_quad_facets);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::updateResidual(bool need_initialize) {
+ AKANTU_DEBUG_IN();
+
+ if (need_initialize) initializeUpdateResidualData();
+
+ // f -= fint
+ std::vector<Material *>::iterator mat_it;
+ for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ try {
+ MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(**mat_it);
+ mat.computeTraction(_not_ghost);
+ } catch (std::bad_cast & bce) { }
+ }
+
+ SolidMechanicsModel::updateResidual(false);
+
+ if (isExplicit()){
+ for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ try {
+ MaterialCohesive & mat = dynamic_cast<MaterialCohesive &>(**mat_it);
+ mat.computeEnergies();
+ } catch (std::bad_cast & bce) { }
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::computeNormals() {
+ AKANTU_DEBUG_IN();
+
+ Mesh & mesh_facets = this->inserter->getMeshFacets();
+ this->getFEEngine("FacetsFEEngine").computeNormalsOnIntegrationPoints(_not_ghost);
+
+ /**
+ * @todo store tangents while computing normals instead of
+ * recomputing them as follows:
+ */
+ /* ------------------------------------------------------------------------ */
+ UInt tangent_components = spatial_dimension * (spatial_dimension - 1);
+
+ mesh_facets.initElementTypeMapArray(tangents,
+ tangent_components,
+ spatial_dimension - 1);
+
+ Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1);
+ Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1);
+
+ for (; it != last; ++it) {
+ ElementType facet_type = *it;
+
+ const Array<Real> & normals =
+ this->getFEEngine("FacetsFEEngine").getNormalsOnIntegrationPoints(facet_type);
+
+ Array<Real> & tangents = this->tangents(facet_type);
+
+ Math::compute_tangents(normals, tangents);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::interpolateStress() {
+
+ ElementTypeMapArray<Real> by_elem_result("temporary_stress_by_facets", id);
+
+ for (UInt m = 0; m < materials.size(); ++m) {
+ try {
+ MaterialCohesive & mat __attribute__((unused)) =
+ dynamic_cast<MaterialCohesive &>(*materials[m]);
+ } catch(std::bad_cast&) {
+ /// interpolate stress on facet quadrature points positions
+ materials[m]->interpolateStressOnFacets(facet_stress, by_elem_result);
+ }
+ }
+
+#if defined(AKANTU_DEBUG_TOOLS)
+ debug::element_manager.printData(debug::_dm_model_cohesive,
+ "Interpolated stresses before",
+ facet_stress);
+#endif
+
+ synch_registry->synchronize(_gst_smmc_facets_stress);
+
+#if defined(AKANTU_DEBUG_TOOLS)
+ debug::element_manager.printData(debug::_dm_model_cohesive,
+ "Interpolated stresses",
+ facet_stress);
+#endif
+}
+
+/* -------------------------------------------------------------------------- */
+UInt SolidMechanicsModelCohesive::checkCohesiveStress() {
+ interpolateStress();
+
+ for (UInt m = 0; m < materials.size(); ++m) {
+ try {
+ MaterialCohesive & mat_cohesive = dynamic_cast<MaterialCohesive &>(*materials[m]);
+ /// check which not ghost cohesive elements are to be created
+ mat_cohesive.checkInsertion();
+ } catch(std::bad_cast&) { }
+ }
+
+ /* if(static and extrinsic) {
+ check max mean stresses
+ and change inserter.getInsertionFacets(type_facet);
+ }
+ */
+
+ /// communicate data among processors
+ synch_registry->synchronize(_gst_smmc_facets);
+
+ /// insert cohesive elements
+ return inserter->insertElements();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::onElementsAdded(const Array<Element> & element_list,
+ const NewElementsEvent & event) {
+ AKANTU_DEBUG_IN();
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ updateCohesiveSynchronizers();
+#endif
+
+ SolidMechanicsModel::onElementsAdded(element_list, event);
+
+#if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
+ if (cohesive_distributed_synchronizer != NULL)
+ cohesive_distributed_synchronizer->computeAllBufferSizes(*this);
+#endif
+
+ /// update shape functions
+ getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
+ getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
+
+ if (is_extrinsic) resizeFacetStress();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::onNodesAdded(const Array<UInt> & doubled_nodes,
+ __attribute__((unused)) const NewNodesEvent & event) {
+ AKANTU_DEBUG_IN();
+
+ UInt nb_new_nodes = doubled_nodes.getSize();
+ Array<UInt> nodes_list(nb_new_nodes);
+
+ for (UInt n = 0; n < nb_new_nodes; ++n)
+ nodes_list(n) = doubled_nodes(n, 1);
+
+ SolidMechanicsModel::onNodesAdded(nodes_list, event);
+
+ for (UInt n = 0; n < nb_new_nodes; ++n) {
+
+ UInt old_node = doubled_nodes(n, 0);
+ UInt new_node = doubled_nodes(n, 1);
+
+ for (UInt dim = 0; dim < spatial_dimension; ++dim) {
+ (*displacement)(new_node, dim) = (*displacement)(old_node, dim);
+ (*velocity) (new_node, dim) = (*velocity) (old_node, dim);
+ (*acceleration)(new_node, dim) = (*acceleration)(old_node, dim);
+ (*blocked_dofs)(new_node, dim) = (*blocked_dofs)(old_node, dim);
+
+ if (current_position)
+ (*current_position)(new_node, dim) = (*current_position)(old_node, dim);
+
+ if (increment_acceleration)
+ (*increment_acceleration)(new_node, dim)
+ = (*increment_acceleration)(old_node, dim);
+
+ if (increment)
+ (*increment)(new_node, dim) = (*increment)(old_node, dim);
+
+ if (previous_displacement)
+ (*previous_displacement)(new_node, dim)
+ = (*previous_displacement)(old_node, dim);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::onEndSolveStep(const AnalysisMethod & method) {
+
+ AKANTU_DEBUG_IN();
+
+ /******************************************************************************
+ This is required because the Cauchy stress is the stress measure that is used
+ to check the insertion of cohesive elements
+ ******************************************************************************/
+
+ std::vector<Material *>::iterator mat_it;
+ for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ Material & mat = **mat_it;
+ if(mat.isFiniteDeformation())
+ mat.computeAllCauchyStresses(_not_ghost);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::printself(std::ostream & stream, int indent) const {
+ std::string space;
+ for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
+
+ stream << space << "SolidMechanicsModelCohesive [" << std::endl;
+
+ SolidMechanicsModel::printself(stream, indent + 1);
+
+ stream << space << "]" << std::endl;
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::resizeFacetStress() {
+ AKANTU_DEBUG_IN();
+
+ Mesh & mesh_facets = inserter->getMeshFacets();
+
+ for (ghost_type_t::iterator gt = ghost_type_t::begin();
+ gt != ghost_type_t::end();
+ ++gt) {
+ GhostType ghost_type = *gt;
+
+ Mesh::type_iterator it = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
+ Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
+ for(; it != end; ++it) {
+ ElementType type = *it;
+
+ UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
+
+ UInt nb_quadrature_points =
+ getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type, ghost_type);
+
+ UInt new_size = nb_facet * nb_quadrature_points;
+
+ facet_stress(type, ghost_type).resize(new_size);
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModelCohesive::addDumpGroupFieldToDumper(const std::string & dumper_name,
+ const std::string & field_id,
+ const std::string & group_name,
+ const ElementKind & element_kind,
+ bool padding_flag) {
+ AKANTU_DEBUG_IN();
+
+ UInt spatial_dimension = this->spatial_dimension;
+ ElementKind _element_kind = element_kind;
+ if (dumper_name == "cohesive elements") {
+ _element_kind = _ek_cohesive;
+ } else if (dumper_name == "facets") {
+ spatial_dimension = this->spatial_dimension - 1;
+ }
+ SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name,
+ field_id,
+ group_name,
+ spatial_dimension,
+ _element_kind,
+ padding_flag);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+void SolidMechanicsModelCohesive::onDump(){
+ this->flattenAllRegisteredInternals(_ek_cohesive);
+ SolidMechanicsModel::onDump();
+}
+
+/* -------------------------------------------------------------------------- */
+
+
+
+__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
new file mode 100644
index 000000000..cd3bbee92
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
@@ -0,0 +1,260 @@
+/**
+ * @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"
+#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..c3393e80a
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_inline_impl.cc
@@ -0,0 +1,304 @@
+/**
+ * @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,
+ 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_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..c8b7fc796
--- /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: 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(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..e5be8b93d
--- /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: 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(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..cf922d8ab
--- /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 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<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..26c64b5c7
--- /dev/null
+++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_model.hh
@@ -0,0 +1,166 @@
+/**
+ * @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/solid_mechanics_model_event_handler.hh b/src/model/solid_mechanics/solid_mechanics_model_event_handler.hh
index 47e8681f0..b785db245 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,108 @@
/**
* @file solid_mechanics_model_event_handler.hh
*
* @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
*
* @date creation: Fri Mar 14 2014
* @date last modification: Fri May 02 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 BeforeDumpEvent { BeforeDumpEvent() {} };
+ struct BeginningOfDamageIterationEvent { BeginningOfDamageIterationEvent() {} };
+ struct AfterDamageEvent { AfterDamageEvent() {} };
}
-
+/// akantu::SolidMechanicsModelEvent
class SolidMechanicsModelEventHandler {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
virtual ~SolidMechanicsModelEventHandler() {};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
protected:
-
+ ///Send what is before the solve step to the beginning of solve step through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::BeforeSolveStepEvent & event) {
onBeginningSolveStep(event.method);
}
+ ///Send what is after the solve step to the end of solve step through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::AfterSolveStepEvent & event) {
onEndSolveStep(event.method);
}
+ ///Send what is before dump to current dump through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::BeforeDumpEvent & event) {
onDump();
}
+ ///Send what is at the beginning of damage iteration to Damage iteration through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::BeginningOfDamageIterationEvent & event) {
onDamageIteration();
- }
+ }
+ ///Send what is after damage for the damage update through EventManager
inline void sendEvent(const SolidMechanicsModelEvent::AfterDamageEvent & event) {
onDamageUpdate();
}
template<class EventHandler>
friend class EventHandlerManager;
/* ------------------------------------------------------------------------ */
/* Interface */
/* ------------------------------------------------------------------------ */
public:
+ /// function to implement to react on akantu::BeforeSolveStepEvent
virtual void onBeginningSolveStep(__attribute__((unused)) const AnalysisMethod & method) {}
+ /// function to implement to react on akantu::AfterSolveStepEvent
virtual void onEndSolveStep(__attribute__((unused)) const AnalysisMethod & method) {}
+ /// function to implement to react on akantu::BeforeDumpEvent
virtual void onDump() {}
+ /// function to implement to react on akantu::BeginningOfDamageIterationEvent
virtual void onDamageIteration() {}
+ /// function to implement to react on akantu::AfterDamageEvent
virtual void onDamageUpdate() {}
};
__END_AKANTU__
#endif /* __AKANTU_SOLID_MECHANICS_MODEL_EVENT_HANDLER_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
index d4aece91b..2eaa07aa2 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
@@ -1,609 +1,657 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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> * elem_mat = NULL;
+ 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;
- elem_mat = &element_index_by_material(el.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 = (*elem_mat)(old_id, 1);
- elements_per_mat[(*elem_mat)(old_id, 0)].push_back(el);
+ 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() * 2 * sizeof(UInt);
+ size += elements.getSize() * sizeof(UInt);
break;
}
case _gst_smm_mass: {
size += nb_nodes_per_element * sizeof(Real) * spatial_dimension; // mass vector
break;
}
case _gst_smm_for_gradu: {
size += nb_nodes_per_element * spatial_dimension * sizeof(Real); // displacement
break;
}
case _gst_smm_boundary: {
// force, displacement, boundary
size += nb_nodes_per_element * spatial_dimension * (2 * sizeof(Real) + sizeof(bool));
break;
}
+ case _gst_for_dump: {
+ // displacement, velocity, acceleration, residual, force
+ size += nb_nodes_per_element * spatial_dimension * sizeof(Real) * 5;
+ break;
+ }
default: { }
}
if(tag != _gst_material_id) {
Array<Element> * elements_per_mat = new Array<Element>[materials.size()];
this->splitElementByMaterial(elements, elements_per_mat);
for (UInt i = 0; i < materials.size(); ++i) {
size += materials[i]->getNbDataForElements(elements_per_mat[i], tag);
}
delete [] elements_per_mat;
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void SolidMechanicsModel::packElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_material_id: {
- packElementalDataHelper(element_index_by_material, buffer, elements, false, getFEEngine());
+ packElementalDataHelper(material_index, buffer, elements, false, getFEEngine());
break;
}
case _gst_smm_mass: {
packNodalDataHelper(*mass, buffer, elements, mesh);
break;
}
case _gst_smm_for_gradu: {
packNodalDataHelper(*displacement, buffer, elements, mesh);
break;
}
+ case _gst_for_dump: {
+ packNodalDataHelper(*displacement, buffer, elements, mesh);
+ packNodalDataHelper(*velocity, buffer, elements, mesh);
+ packNodalDataHelper(*acceleration, buffer, elements, mesh);
+ packNodalDataHelper(*residual, buffer, elements, mesh);
+ packNodalDataHelper(*force, buffer, elements, mesh);
+ break;
+ }
case _gst_smm_boundary: {
packNodalDataHelper(*force, buffer, elements, mesh);
packNodalDataHelper(*velocity, buffer, elements, mesh);
packNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
break;
}
default: {
}
}
if(tag != _gst_material_id) {
Array<Element> * elements_per_mat = new Array<Element>[materials.size()];
splitElementByMaterial(elements, elements_per_mat);
for (UInt i = 0; i < materials.size(); ++i) {
materials[i]->packElementData(buffer, elements_per_mat[i], tag);
}
delete [] elements_per_mat;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline void SolidMechanicsModel::unpackElementData(CommunicationBuffer & buffer,
const Array<Element> & elements,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_material_id: {
- unpackElementalDataHelper(element_index_by_material, buffer, elements,
+ unpackElementalDataHelper(material_index, buffer, elements,
false, getFEEngine());
break;
}
case _gst_smm_mass: {
unpackNodalDataHelper(*mass, buffer, elements, mesh);
break;
}
case _gst_smm_for_gradu: {
unpackNodalDataHelper(*displacement, buffer, elements, mesh);
break;
}
+ case _gst_for_dump: {
+ unpackNodalDataHelper(*displacement, buffer, elements, mesh);
+ unpackNodalDataHelper(*velocity, buffer, elements, mesh);
+ unpackNodalDataHelper(*acceleration, buffer, elements, mesh);
+ unpackNodalDataHelper(*residual, buffer, elements, mesh);
+ unpackNodalDataHelper(*force, buffer, elements, mesh);
+ break;
+ }
case _gst_smm_boundary: {
unpackNodalDataHelper(*force, buffer, elements, mesh);
unpackNodalDataHelper(*velocity, buffer, elements, mesh);
unpackNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
break;
}
default: {
}
}
if(tag != _gst_material_id) {
Array<Element> * elements_per_mat = new Array<Element>[materials.size()];
splitElementByMaterial(elements, elements_per_mat);
for (UInt i = 0; i < materials.size(); ++i) {
materials[i]->unpackElementData(buffer, elements_per_mat[i], tag);
}
delete [] elements_per_mat;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
inline UInt SolidMechanicsModel::getNbDataToPack(SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
// UInt nb_nodes = mesh.getNbNodes();
switch(tag) {
case _gst_smm_uv: {
size += sizeof(Real) * spatial_dimension * 2;
break;
}
case _gst_smm_res: {
size += sizeof(Real) * spatial_dimension;
break;
}
case _gst_smm_mass: {
size += sizeof(Real) * spatial_dimension;
break;
}
case _gst_for_dump: {
size += sizeof(Real) * spatial_dimension * 5;
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline UInt SolidMechanicsModel::getNbDataToUnpack(SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
UInt size = 0;
// UInt nb_nodes = mesh.getNbNodes();
switch(tag) {
case _gst_smm_uv: {
size += sizeof(Real) * spatial_dimension * 2;
break;
}
case _gst_smm_res: {
size += sizeof(Real) * spatial_dimension;
break;
}
case _gst_smm_mass: {
size += sizeof(Real) * spatial_dimension;
break;
}
case _gst_for_dump: {
size += sizeof(Real) * spatial_dimension * 5;
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
return size;
}
/* -------------------------------------------------------------------------- */
inline void SolidMechanicsModel::packData(CommunicationBuffer & buffer,
const UInt index,
SynchronizationTag tag) const {
AKANTU_DEBUG_IN();
switch(tag) {
case _gst_smm_uv: {
Array<Real>::const_vector_iterator it_disp = displacement->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_velo = velocity->begin(spatial_dimension);
- buffer << it_disp[index];
- buffer << it_velo[index];
+ Vector<Real> disp(it_disp[index]); buffer << disp;
+ Vector<Real> velo(it_velo[index]); buffer << velo;
break;
}
case _gst_smm_res: {
Array<Real>::const_vector_iterator it_res = residual->begin(spatial_dimension);
- buffer << it_res[index];
+ 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);
- buffer << it_mass[index];
+ Vector<Real> mass(it_mass[index]); buffer << mass;
break;
}
case _gst_for_dump: {
Array<Real>::const_vector_iterator it_disp = displacement->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_velo = velocity->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_acce = acceleration->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_resi = residual->begin(spatial_dimension);
Array<Real>::const_vector_iterator it_forc = force->begin(spatial_dimension);
- buffer << it_disp[index];
- buffer << it_velo[index];
- buffer << it_acce[index];
- buffer << it_resi[index];
- buffer << it_forc[index];
+ 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);
- buffer >> it_disp[index];
- buffer >> it_velo[index];
+ Vector<Real> disp(it_disp[index]); buffer >> disp;
+ Vector<Real> velo(it_velo[index]); buffer >> velo;
break;
}
case _gst_smm_res: {
Array<Real>::vector_iterator it_res = residual->begin(spatial_dimension);
- buffer >> it_res[index];
+ 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);
- buffer >> it_mass[index];
+ Vector<Real> mass_v(it_mass[index]); buffer >> mass_v;
AKANTU_DEBUG_INFO("mass of node " << index << " is now " << (*mass)(index,0));
break;
}
case _gst_for_dump: {
Array<Real>::vector_iterator it_disp = displacement->begin(spatial_dimension);
Array<Real>::vector_iterator it_velo = velocity->begin(spatial_dimension);
Array<Real>::vector_iterator it_acce = acceleration->begin(spatial_dimension);
Array<Real>::vector_iterator it_resi = residual->begin(spatial_dimension);
Array<Real>::vector_iterator it_forc = force->begin(spatial_dimension);
- buffer >> it_disp[index];
- buffer >> it_velo[index];
- buffer >> it_acce[index];
- buffer >> it_resi[index];
- buffer >> it_forc[index];
+ Vector<Real> disp(it_disp[index]); buffer >> disp;
+ Vector<Real> velo(it_velo[index]); buffer >> velo;
+ Vector<Real> acce(it_acce[index]); buffer >> acce;
+ Vector<Real> resi(it_resi[index]); buffer >> resi;
+ Vector<Real> forc(it_forc[index]); buffer >> forc;
break;
}
default: {
AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
#include "sparse_matrix.hh"
#include "solver.hh"
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
template <NewmarkBeta::IntegrationSchemeCorrectorType type>
void SolidMechanicsModel::solve(Array<Real> &increment, Real block_val,
- bool need_factorize, bool has_profile_changed,
- const Array<Real> &rhs) {
-
+ bool need_factorize, bool has_profile_changed) {
+
if(has_profile_changed) {
this->initJacobianMatrix();
need_factorize = true;
}
updateResidualInternal(); //doesn't do anything for static
if(need_factorize) {
Real c = 0.,d = 0.,e = 0.;
if(method == _static) {
AKANTU_DEBUG_INFO("Solving K inc = r");
e = 1.;
} else {
AKANTU_DEBUG_INFO("Solving (c M + d C + e K) inc = r");
NewmarkBeta * nmb_int = dynamic_cast<NewmarkBeta *>(integrator);
c = nmb_int->getAccelerationCoefficient<type>(time_step);
d = nmb_int->getVelocityCoefficient<type>(time_step);
e = nmb_int->getDisplacementCoefficient<type>(time_step);
}
jacobian_matrix->clear();
// J = c M + d C + e K
if(stiffness_matrix)
jacobian_matrix->add(*stiffness_matrix, e);
if(mass_matrix)
jacobian_matrix->add(*mass_matrix, c);
#if !defined(AKANTU_NDEBUG)
- if(mass_matrix && AKANTU_DEBUG_TEST(dblDump))
- mass_matrix->saveMatrix("M.mtx");
+ if(mass_matrix && AKANTU_DEBUG_TEST(dblDump)) {
+ UInt prank = StaticCommunicator::getStaticCommunicator().whoAmI();
+ std::stringstream sstr; sstr << "M" << prank << ".mtx";
+ mass_matrix->saveMatrix(sstr.str());
+ }
#endif
if(velocity_damping_matrix)
jacobian_matrix->add(*velocity_damping_matrix, d);
jacobian_matrix->applyBoundary(*blocked_dofs, block_val);
#if !defined(AKANTU_NDEBUG)
- if(AKANTU_DEBUG_TEST(dblDump))
- jacobian_matrix->saveMatrix("J.mtx");
+ if(AKANTU_DEBUG_TEST(dblDump)) {
+ UInt prank = StaticCommunicator::getStaticCommunicator().whoAmI();
+ std::stringstream sstr; sstr << "J" << prank << ".mtx";
+ jacobian_matrix->saveMatrix(sstr.str());
+ }
#endif
+
solver->factorize();
}
- if (rhs.getSize() != 0)
- solver->setRHS(rhs);
- else
- solver->setRHS(*residual);
+ // if (rhs.getSize() != 0)
+ // solver->setRHS(rhs);
+ // else
+
+ solver->setOperators();
+
+ solver->setRHS(*residual);
// solve @f[ J \delta w = r @f]
solver->solve(increment);
UInt nb_nodes = displacement-> getSize();
UInt nb_degree_of_freedom = displacement->getNbComponent() * nb_nodes;
bool * blocked_dofs_val = blocked_dofs->storage();
Real * increment_val = increment.storage();
for (UInt j = 0; j < nb_degree_of_freedom;
++j,++increment_val, ++blocked_dofs_val) {
if ((*blocked_dofs_val))
*increment_val = 0.0;
}
}
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool SolidMechanicsModel::solveStatic(Real tolerance, UInt max_iteration,
bool do_not_factorize) {
AKANTU_DEBUG_INFO("Solving Ku = f");
AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
"You should first initialize the implicit solver and assemble the stiffness matrix by calling initImplicit");
AnalysisMethod analysis_method=method;
Real error = 0.;
method=_static;
bool converged = this->template solveStep<cmethod, criteria>(tolerance, error, max_iteration, do_not_factorize);
method=analysis_method;
return converged;
}
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool SolidMechanicsModel::solveStep(Real tolerance,
UInt max_iteration) {
Real error = 0.;
return this->template solveStep<cmethod,criteria>(tolerance,
error,
max_iteration);
}
/* -------------------------------------------------------------------------- */
template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria>
bool SolidMechanicsModel::solveStep(Real tolerance, Real & error, UInt max_iteration,
bool do_not_factorize) {
EventManager::sendEvent(SolidMechanicsModelEvent::BeforeSolveStepEvent(method));
this->implicitPred();
this->updateResidual();
AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL,
"You should first initialize the implicit solver and assemble the stiffness matrix");
bool need_factorize = !do_not_factorize;
if (method==_implicit_dynamic) {
AKANTU_DEBUG_ASSERT(mass_matrix != NULL,
"You should first initialize the implicit solver and assemble the mass matrix");
}
switch (cmethod) {
case _scm_newton_raphson_tangent:
case _scm_newton_raphson_tangent_not_computed:
break;
case _scm_newton_raphson_tangent_modified:
this->assembleStiffnessMatrix();
break;
default:
AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!");
}
- UInt iter = 0;
+ this->n_iter = 0;
bool converged = false;
error = 0.;
if(criteria == _scc_residual) {
converged = this->testConvergence<criteria> (tolerance, error);
- if(converged) return converged;
+ if (converged) {
+ EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
+
+ if(increment_flag && previous_displacement) {
+ this->updateIncrement();
+ }
+
+ if(previous_displacement) previous_displacement->copy(*displacement);
+ return converged;
+ }
}
do {
if (cmethod == _scm_newton_raphson_tangent)
this->assembleStiffnessMatrix();
solve<NewmarkBeta::_displacement_corrector> (*increment, 1., need_factorize);
this->implicitCorr();
if(criteria == _scc_residual) this->updateResidual();
converged = this->testConvergence<criteria> (tolerance, error);
if(criteria == _scc_increment && !converged) this->updateResidual();
//this->dump();
- iter++;
+ this->n_iter++;
AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration "
- << std::setw(std::log10(max_iteration)) << iter
+ << 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 && iter < max_iteration);
+ } while (!converged && this->n_iter < max_iteration);
// this makes sure that you have correct strains and stresses after the solveStep function (e.g., for dumping)
if(criteria == _scc_increment) this->updateResidual();
if (converged) {
EventManager::sendEvent(SolidMechanicsModelEvent::AfterSolveStepEvent(method));
- } else if(iter == max_iteration) {
+
+ if(increment_flag && previous_displacement) {
+ this->updateIncrement();
+ }
+
+ if(previous_displacement) previous_displacement->copy(*displacement);
+ } else if(this->n_iter == max_iteration) {
AKANTU_DEBUG_WARNING("[" << criteria << "] Convergence not reached after "
- << std::setw(std::log10(max_iteration)) << iter <<
- " iteration" << (iter == 1 ? "" : "s") << "!" << std::endl);
+ << std::setw(std::log10(max_iteration)) << this->n_iter <<
+ " iteration" << (this->n_iter == 1 ? "" : "s") << "!" << std::endl);
}
return converged;
}
+
diff --git a/src/model/solid_mechanics/solid_mechanics_model_mass.cc b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
index b3602402a..6f186e85e 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_mass.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_mass.cc
@@ -1,158 +1,158 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solid_mechanics_model.hh"
#include "material.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMassLumped() {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
if (!mass) {
std::stringstream sstr_mass; sstr_mass << id << ":mass";
mass = &(alloc<Real>(sstr_mass.str(), nb_nodes, spatial_dimension, 0));
} else
mass->clear();
assembleMassLumped(_not_ghost);
assembleMassLumped(_ghost);
/// for not connected nodes put mass to one in order to avoid
/// wrong range in paraview
Real * mass_values = mass->storage();
for (UInt i = 0; i < nb_nodes; ++i) {
if (fabs(mass_values[i]) < std::numeric_limits<Real>::epsilon() || Math::isnan(mass_values[i]))
mass_values[i] = 1.;
}
synch_registry->synchronize(_gst_smm_mass);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMassLumped(GhostType ghost_type) {
AKANTU_DEBUG_IN();
FEEngine & fem = getFEEngine();
Array<Real> rho_1(0,1);
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
computeRho(rho_1, type, ghost_type);
AKANTU_DEBUG_ASSERT(dof_synchronizer,
"DOFSynchronizer number must not be initialized");
fem.assembleFieldLumped(rho_1, spatial_dimension,*mass,
dof_synchronizer->getLocalDOFEquationNumbers(),
type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMass() {
AKANTU_DEBUG_IN();
if(!mass_matrix) {
std::stringstream sstr; sstr << id << ":mass_matrix";
mass_matrix = new SparseMatrix(*jacobian_matrix, sstr.str(), memory_id);
}
assembleMass(_not_ghost);
// assembleMass(_ghost);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::assembleMass(GhostType ghost_type) {
AKANTU_DEBUG_IN();
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
Array<Real> rho_1(0,1);
//UInt nb_element;
mass_matrix->clear();
Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
for(; it != end; ++it) {
ElementType type = *it;
computeRho(rho_1, type, ghost_type);
fem.assembleFieldMatrix(rho_1, spatial_dimension, *mass_matrix, type, ghost_type);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolidMechanicsModel::computeRho(Array<Real> & rho,
ElementType type,
GhostType ghost_type) {
AKANTU_DEBUG_IN();
- Material ** mat_val = &(materials.at(0));
+ Material ** mat_val = &(this->materials.at(0));
- FEEngine & fem = getFEEngine();
+ FEEngine & fem = this->getFEEngine();
UInt nb_element = fem.getMesh().getNbElement(type,ghost_type);
- Array<UInt> & elem_mat_val = element_index_by_material(type, ghost_type);
+ Array<UInt> & mat_indexes = this->material_index(type, ghost_type);
- UInt nb_quadrature_points = fem.getNbQuadraturePoints(type, ghost_type);
+ UInt nb_quadrature_points = fem.getNbIntegrationPoints(type);
rho.resize(nb_element * nb_quadrature_points);
Real * rho_1_val = rho.storage();
/// compute @f$ rho @f$ for each nodes of each element
for (UInt el = 0; el < nb_element; ++el) {
- Real mat_rho = mat_val[elem_mat_val(el, 0)]->getParam<Real>("rho"); /// here rho is constant in an element
+ Real mat_rho = mat_val[mat_indexes(el)]->getParam<Real>("rho"); /// here rho is constant in an element
for (UInt n = 0; n < nb_quadrature_points; ++n) {
*rho_1_val++ = mat_rho;
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_material.cc b/src/model/solid_mechanics/solid_mechanics_model_material.cc
index 049d66105..115c293c1 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_material.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_material.cc
@@ -1,219 +1,330 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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::initMaterials() {
- AKANTU_DEBUG_ASSERT(materials.size() != 0, "No material to initialize !");
- if(!are_materials_instantiated) instantiateMaterials();
+/* -------------------------------------------------------------------------- */
+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> & el_id_by_mat = element_index_by_material(*it, _not_ghost);
+ Array<UInt> & mat_indexes = material_index(*it, _not_ghost);
for (UInt el = 0; el < nb_element; ++el) {
- element.element = el;
+ if (filter != NULL)
+ element.element = (*filter_array)(el);
+ else
+ element.element = el;
+
UInt mat_index = (*material_selector)(element);
AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
- "The material selector returned an index that does not exists");
- el_id_by_mat(el, 0) = mat_index;
+ "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);
- Array<UInt> & el_id_by_mat = element_index_by_material(*it, gt);
+
+ const Array<UInt> * filter_array = NULL;
+ if (filter != NULL) {
+ filter_array = &((*filter)(*it, gt));
+ nb_element = filter_array->getSize();
+ }
+
+ Array<UInt> & mat_indexes = material_index(*it, gt);
+ Array<UInt> & mat_local_num = material_local_numbering(*it, gt);
for (UInt el = 0; el < nb_element; ++el) {
- UInt mat_index = el_id_by_mat(el, 0);
- UInt index = mat_val[mat_index]->addElement(*it, el, gt);
- el_id_by_mat(el, 1) = index;
+ UInt element;
+
+ if (filter != NULL) element = (*filter_array)(el);
+ else element = el;
+
+ UInt mat_index = mat_indexes(element);
+ UInt index = mat_val[mat_index]->addElement(*it, element, gt);
+ mat_local_num(element) = index;
}
}
}
+}
+
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModel::initMaterials() {
+ AKANTU_DEBUG_ASSERT(materials.size() != 0, "No material to initialize !");
+
+ if(!are_materials_instantiated) instantiateMaterials();
+
+ this->assignMaterialToElements();
std::vector<Material *>::iterator mat_it;
for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
/// init internals properties
(*mat_it)->initMaterial();
}
synch_registry->synchronize(_gst_smm_init_mat);
// initialize mass
switch(method) {
case _explicit_lumped_mass:
assembleMassLumped();
break;
case _explicit_consistent_mass:
case _implicit_dynamic:
assembleMass();
break;
case _static:
break;
default:
AKANTU_EXCEPTION("analysis method not recognised by SolidMechanicsModel");
break;
}
// initialize the previous displacement array if at least on material needs it
for (mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
Material & mat = **mat_it;
if (mat.isFiniteDeformation() || mat.isInelasticDeformation()) {
initArraysPreviousDisplacment();
break;
}
}
+
+
+#ifdef AKANTU_DAMAGE_NON_LOCAL
+ /// initialize the non-local manager for non-local computations
+ this->non_local_manager->init();
+#endif
}
/* -------------------------------------------------------------------------- */
Int SolidMechanicsModel::getInternalIndexFromID(const ID & id) const {
AKANTU_DEBUG_IN();
std::vector<Material *>::const_iterator first = materials.begin();
std::vector<Material *>::const_iterator last = materials.end();
for (; first != last; ++first)
if ((*first)->getID() == id) {
AKANTU_DEBUG_OUT();
return (first - materials.begin());
}
AKANTU_DEBUG_OUT();
return -1;
}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModel::reassignMaterial() {
+ AKANTU_DEBUG_IN();
+
+ std::vector< Array<Element> > element_to_add (materials.size());
+ std::vector< Array<Element> > element_to_remove(materials.size());
+
+ Element element;
+ for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ GhostType ghost_type = *gt;
+ element.ghost_type = ghost_type;
+
+ Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type, _ek_not_defined);
+ Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type, _ek_not_defined);
+ for(; it != end; ++it) {
+ ElementType type = *it;
+ element.type = type;
+ element.kind = Mesh::getKind(type);
+
+ UInt nb_element = mesh.getNbElement(type, ghost_type);
+ Array<UInt> & mat_indexes = material_index(type, ghost_type);
+
+ for (UInt el = 0; el < nb_element; ++el) {
+ element.element = el;
+
+ UInt old_material = mat_indexes(el);
+ UInt new_material = (*material_selector)(element);
+
+ if(old_material != new_material) {
+ element_to_add [new_material].push_back(element);
+ element_to_remove[old_material].push_back(element);
+ }
+ }
+ }
+ }
+
+ std::vector<Material *>::iterator mat_it;
+ UInt mat_index = 0;
+ for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it, ++mat_index) {
+ (*mat_it)->removeElements(element_to_remove[mat_index]);
+ (*mat_it)->addElements (element_to_add[mat_index]);
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolidMechanicsModel::applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u, const ID & material_name,
+ const GhostType ghost_type) {
+
+ AKANTU_DEBUG_ASSERT(prescribed_eigen_grad_u.size() == spatial_dimension * spatial_dimension,
+ "The prescribed grad_u is not of the good size");
+ std::vector<Material *>::iterator mat_it;
+ for(mat_it = materials.begin(); mat_it != materials.end(); ++mat_it) {
+ if ((*mat_it)->getName() == material_name)
+ (*mat_it)->applyEigenGradU(prescribed_eigen_grad_u, ghost_type);
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+
__END_AKANTU__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh b/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
index 851f71ae6..c39b04988 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_tmpl.hh
@@ -1,104 +1,106 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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 e4a0111be..557c0fd96 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model.cc
@@ -1,1147 +1,1148 @@
/**
* @file structural_mechanics_model.cc
*
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "structural_mechanics_model.hh"
#include "group_manager_inline_impl.cc"
#include "dumpable_inline_impl.hh"
#include "aka_math.hh"
#include "integration_scheme_2nd_order.hh"
#include "static_communicator.hh"
#include "sparse_matrix.hh"
#include "solver.hh"
#ifdef AKANTU_USE_MUMPS
#include "solver_mumps.hh"
#endif
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
# include "dumper_elemental_field.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
const StructuralMechanicsModelOptions default_structural_mechanics_model_options(_static);
/* -------------------------------------------------------------------------- */
StructuralMechanicsModel::StructuralMechanicsModel(Mesh & mesh,
UInt dim,
const ID & id,
const MemoryID & memory_id) :
Model(mesh, dim, id, memory_id),
time_step(NAN), f_m2a(1.0),
stress("stress", id, memory_id),
element_material("element_material", id, memory_id),
set_ID("beam sets", id, memory_id),
stiffness_matrix(NULL),
mass_matrix(NULL),
velocity_damping_matrix(NULL),
jacobian_matrix(NULL),
solver(NULL),
rotation_matrix("rotation_matices", id, memory_id),
increment_flag(false),
integrator(NULL) {
AKANTU_DEBUG_IN();
registerFEEngineObject<MyFEEngineType>("StructuralMechanicsFEEngine", mesh, spatial_dimension);
this->displacement_rotation = NULL;
this->mass = NULL;
this->velocity = NULL;
this->acceleration = NULL;
this->force_momentum = NULL;
this->residual = NULL;
this->blocked_dofs = NULL;
this->increment = NULL;
this->previous_displacement = NULL;
if(spatial_dimension == 2)
nb_degree_of_freedom = 3;
else if (spatial_dimension == 3)
nb_degree_of_freedom = 6;
else {
AKANTU_DEBUG_TO_IMPLEMENT();
}
this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_structural);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
StructuralMechanicsModel::~StructuralMechanicsModel() {
AKANTU_DEBUG_IN();
delete integrator;
delete solver;
delete stiffness_matrix;
delete jacobian_matrix;
delete mass_matrix;
delete velocity_damping_matrix;
AKANTU_DEBUG_OUT();
}
void StructuralMechanicsModel::setTimeStep(Real time_step) {
this->time_step = time_step;
#if defined(AKANTU_USE_IOHELPER)
this->mesh.getDumper().setTimeStep(time_step);
#endif
}
/* -------------------------------------------------------------------------- */
/* Initialisation */
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initFull(const ModelOptions & options) {
const StructuralMechanicsModelOptions & stmm_options =
dynamic_cast<const StructuralMechanicsModelOptions &>(options);
method = stmm_options.analysis_method;
initModel();
initArrays();
displacement_rotation->clear();
velocity ->clear();
acceleration ->clear();
force_momentum ->clear();
residual ->clear();
blocked_dofs ->clear();
increment ->clear();
Mesh::type_iterator it = getFEEngine().getMesh().firstType(spatial_dimension, _not_ghost, _ek_structural);
Mesh::type_iterator end = getFEEngine().getMesh().lastType(spatial_dimension, _not_ghost, _ek_structural);
for (; it != end; ++it) {
computeRotationMatrix(*it);
}
switch(method) {
case _implicit_dynamic:
initImplicit();
break;
case _static:
initSolver();
break;
default:
AKANTU_EXCEPTION("analysis method not recognised by StructuralMechanicsModel");
break;
}
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initArrays() {
AKANTU_DEBUG_IN();
UInt nb_nodes = getFEEngine().getMesh().getNbNodes();
std::stringstream sstr_disp; sstr_disp << id << ":displacement";
std::stringstream sstr_velo; sstr_velo << id << ":velocity";
std::stringstream sstr_acce; sstr_acce << id << ":acceleration";
std::stringstream sstr_forc; sstr_forc << id << ":force";
std::stringstream sstr_resi; sstr_resi << id << ":residual";
std::stringstream sstr_boun; sstr_boun << id << ":blocked_dofs";
std::stringstream sstr_incr; sstr_incr << id << ":increment";
displacement_rotation = &(alloc<Real>(sstr_disp.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
velocity = &(alloc<Real>(sstr_velo.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
acceleration = &(alloc<Real>(sstr_acce.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
force_momentum = &(alloc<Real>(sstr_forc.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
residual = &(alloc<Real>(sstr_resi.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
blocked_dofs = &(alloc<bool>(sstr_boun.str(), nb_nodes, nb_degree_of_freedom, false));
increment = &(alloc<Real>(sstr_incr.str(), nb_nodes, nb_degree_of_freedom, REAL_INIT_VALUE));
Mesh::type_iterator it = getFEEngine().getMesh().firstType(spatial_dimension, _not_ghost, _ek_structural);
Mesh::type_iterator end = getFEEngine().getMesh().lastType(spatial_dimension, _not_ghost, _ek_structural);
for (; it != end; ++it) {
UInt nb_element = getFEEngine().getMesh().getNbElement(*it);
- UInt nb_quadrature_points = getFEEngine().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);
}
dof_synchronizer = new DOFSynchronizer(getFEEngine().getMesh(), nb_degree_of_freedom);
dof_synchronizer->initLocalDOFEquationNumbers();
dof_synchronizer->initGlobalDOFEquationNumbers();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initModel() {
getFEEngine().initShapeFunctions(_not_ghost);
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initSolver(__attribute__((unused)) SolverOptions & options) {
AKANTU_DEBUG_IN();
const Mesh & mesh = getFEEngine().getMesh();
#if !defined(AKANTU_USE_MUMPS) // or other solver in the future \todo add AKANTU_HAS_SOLVER in CMake
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#else
UInt nb_global_node = mesh.getNbGlobalNodes();
std::stringstream sstr; sstr << id << ":jacobian_matrix";
jacobian_matrix = new SparseMatrix(nb_global_node * nb_degree_of_freedom, _symmetric, sstr.str(), memory_id);
jacobian_matrix->buildProfile(mesh, *dof_synchronizer, nb_degree_of_freedom);
std::stringstream sstr_sti; sstr_sti << id << ":stiffness_matrix";
stiffness_matrix = new SparseMatrix(*jacobian_matrix, sstr_sti.str(), memory_id);
#ifdef AKANTU_USE_MUMPS
std::stringstream sstr_solv; sstr_solv << id << ":solver";
solver = new SolverMumps(*jacobian_matrix, sstr_solv.str());
dof_synchronizer->initScatterGatherCommunicationScheme();
#else
AKANTU_DEBUG_ERROR("You should at least activate one solver.");
#endif //AKANTU_USE_MUMPS
solver->initialize(options);
#endif //AKANTU_HAS_SOLVER
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::initImplicit(bool dynamic, SolverOptions & solver_options) {
AKANTU_DEBUG_IN();
if (!increment) setIncrementFlagOn();
initSolver(solver_options);
if(integrator) delete integrator;
integrator = new TrapezoidalRule2();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize(const ElementType & type) {
UInt size;
#define GET_TANGENT_STIFFNESS_VOIGT_SIZE(type) \
size = getTangentStiffnessVoigtSize<type>();
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_TANGENT_STIFFNESS_VOIGT_SIZE);
#undef GET_TANGENT_STIFFNESS_VOIGT_SIZE
return size;
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::assembleStiffnessMatrix() {
AKANTU_DEBUG_IN();
stiffness_matrix->clear();
Mesh::type_iterator it = getFEEngine().getMesh().firstType(spatial_dimension, _not_ghost, _ek_structural);
Mesh::type_iterator end = getFEEngine().getMesh().lastType(spatial_dimension, _not_ghost, _ek_structural);
for (; it != end; ++it) {
ElementType type = *it;
#define ASSEMBLE_STIFFNESS_MATRIX(type) \
assembleStiffnessMatrix<type>();
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(ASSEMBLE_STIFFNESS_MATRIX);
#undef ASSEMBLE_STIFFNESS_MATRIX
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_2>(Array<Real> & rotations){
ElementType type = _bernoulli_beam_2;
Mesh & mesh = getFEEngine().getMesh();
UInt nb_element = mesh.getNbElement(type);
Array<UInt>::iterator< Vector<UInt> > connec_it = mesh.getConnectivity(type).begin(2);
Array<Real>::vector_iterator nodes_it = mesh.getNodes().begin(spatial_dimension);
Array<Real>::matrix_iterator R_it = rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
for (UInt e = 0; e < nb_element; ++e, ++R_it, ++connec_it) {
Matrix<Real> & R = *R_it;
Vector<UInt> & connec = *connec_it;
Vector<Real> x2;
x2 = nodes_it[connec(1)]; // X2
Vector<Real> x1;
x1 = nodes_it[connec(0)]; // X1
Real le = x1.distance(x2);
Real c = (x2(0) - x1(0)) / le;
Real s = (x2(1) - x1(1)) / le;
/// Definition of the rotation matrix
R(0,0) = c; R(0,1) = s; R(0,2) = 0.;
R(1,0) = -s; R(1,1) = c; R(1,2) = 0.;
R(2,0) = 0.; R(2,1) = 0.; R(2,2) = 1.;
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_3>(Array<Real> & rotations){
ElementType type = _bernoulli_beam_3;
Mesh & mesh = getFEEngine().getMesh();
UInt nb_element = mesh.getNbElement(type);
Array<Real>::vector_iterator n_it = mesh.getNormals(type).begin(spatial_dimension);
Array<UInt>::iterator< Vector<UInt> > connec_it = mesh.getConnectivity(type).begin(2);
Array<Real>::vector_iterator nodes_it = mesh.getNodes().begin(spatial_dimension);
Matrix<Real> Pe (spatial_dimension, spatial_dimension);
Matrix<Real> Pg (spatial_dimension, spatial_dimension);
Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension);
Vector<Real> x_n(spatial_dimension); // x vect n
Array<Real>::matrix_iterator R_it =
rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
for (UInt e=0 ; e < nb_element; ++e, ++n_it, ++connec_it, ++R_it) {
Vector<Real> & n = *n_it;
Matrix<Real> & R = *R_it;
Vector<UInt> & connec = *connec_it;
Vector<Real> x;
x = nodes_it[connec(1)]; // X2
Vector<Real> y;
y = nodes_it[connec(0)]; // X1
Real l = x.distance(y);
x -= y; // X2 - X1
x_n.crossProduct(x, n);
Pe.eye();
Pe(0, 0) *= l;
Pe(1, 1) *= -l;
Pg(0,0) = x(0); Pg(0,1) = x_n(0); Pg(0,2) = n(0);
Pg(1,0) = x(1); Pg(1,1) = x_n(1); Pg(1,2) = n(1);
Pg(2,0) = x(2); Pg(2,1) = x_n(2); Pg(2,2) = n(2);
inv_Pg.inverse(Pg);
Pe *= inv_Pg;
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
R(i, j) = Pe(i, j);
R(i + spatial_dimension,j + spatial_dimension) = Pe(i, j);
}
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeRotationMatrix<_kirchhoff_shell>(Array<Real> & rotations){
ElementType type = _kirchhoff_shell;
Mesh & mesh = getFEEngine().getMesh();
UInt nb_element = mesh.getNbElement(type);
Array<UInt>::iterator< Vector<UInt> > connec_it = mesh.getConnectivity(type).begin(3);
Array<Real>::vector_iterator nodes_it = mesh.getNodes().begin(spatial_dimension);
Matrix<Real> Pe (spatial_dimension, spatial_dimension);
Matrix<Real> Pg (spatial_dimension, spatial_dimension);
Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension);
Array<Real>::matrix_iterator R_it =
rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
for (UInt e=0 ; e < nb_element; ++e, ++connec_it, ++R_it) {
Pe.eye();
Matrix<Real> & R = *R_it;
Vector<UInt> & connec = *connec_it;
Vector<Real> x2;
x2 = nodes_it[connec(1)]; // X2
Vector<Real> x1;
x1 = nodes_it[connec(0)]; // X1
Vector<Real> x3;
x3 = nodes_it[connec(2)]; // X3
Vector<Real> Pg_col_1=x2-x1;
Vector<Real> Pg_col_2 = x3-x1;
Vector<Real> Pg_col_3(spatial_dimension);
Pg_col_3.crossProduct(Pg_col_1, Pg_col_2);
for (UInt i = 0; i <spatial_dimension; ++i) {
Pg(i,0) = Pg_col_1(i);
Pg(i,1) = Pg_col_2(i);
Pg(i,2) = Pg_col_3(i);
}
inv_Pg.inverse(Pg);
// Pe *= inv_Pg;
Pe.eye();
for (UInt i = 0; i < spatial_dimension; ++i) {
for (UInt j = 0; j < spatial_dimension; ++j) {
R(i, j) = Pe(i, j);
R(i + spatial_dimension,j + spatial_dimension) = Pe(i, j);
}
}
}
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::computeRotationMatrix(const ElementType & type) {
Mesh & mesh = getFEEngine().getMesh();
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_element = mesh.getNbElement(type);
if(!rotation_matrix.exists(type)) {
rotation_matrix.alloc(nb_element,
nb_degree_of_freedom*nb_nodes_per_element * nb_degree_of_freedom*nb_nodes_per_element,
type);
} else {
rotation_matrix(type).resize(nb_element);
}
rotation_matrix(type).clear();
Array<Real>rotations(nb_element, nb_degree_of_freedom * nb_degree_of_freedom);
rotations.clear();
#define COMPUTE_ROTATION_MATRIX(type) \
computeRotationMatrix<type>(rotations);
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_ROTATION_MATRIX);
#undef COMPUTE_ROTATION_MATRIX
Array<Real>::matrix_iterator R_it = rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
Array<Real>::matrix_iterator T_it =
rotation_matrix(type).begin(nb_degree_of_freedom*nb_nodes_per_element,
nb_degree_of_freedom*nb_nodes_per_element);
for (UInt el = 0; el < nb_element; ++el, ++R_it, ++T_it) {
Matrix<Real> & T = *T_it;
Matrix<Real> & R = *R_it;
T.clear();
for (UInt k = 0; k < nb_nodes_per_element; ++k){
for (UInt i = 0; i < nb_degree_of_freedom; ++i)
for (UInt j = 0; j < nb_degree_of_freedom; ++j)
T(k*nb_degree_of_freedom + i, k*nb_degree_of_freedom + j) = R(i, j);
}
}
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::computeStresses() {
AKANTU_DEBUG_IN();
Mesh::type_iterator it = getFEEngine().getMesh().firstType(spatial_dimension, _not_ghost, _ek_structural);
Mesh::type_iterator end = getFEEngine().getMesh().lastType(spatial_dimension, _not_ghost, _ek_structural);
for (; it != end; ++it) {
ElementType type = *it;
#define COMPUTE_STRESS_ON_QUAD(type) \
computeStressOnQuad<type>();
AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_STRESS_ON_QUAD);
#undef COMPUTE_STRESS_ON_QUAD
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::updateResidual() {
AKANTU_DEBUG_IN();
residual->copy(*force_momentum);
Array<Real> ku(*displacement_rotation, true);
ku *= *stiffness_matrix;
*residual -= ku;
this->updateResidualInternal();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::implicitPred() {
AKANTU_DEBUG_IN();
if(previous_displacement) previous_displacement->copy(*displacement_rotation);
if(method == _implicit_dynamic)
integrator->integrationSchemePred(time_step,
*displacement_rotation,
*velocity,
*acceleration,
*blocked_dofs);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::implicitCorr() {
AKANTU_DEBUG_IN();
Real * incr_val = increment->storage();
bool * boun_val = blocked_dofs->storage();
UInt nb_nodes = displacement_rotation->getSize();
for (UInt j = 0; j < nb_nodes * nb_degree_of_freedom; ++j, ++incr_val, ++boun_val){
*incr_val *= (1. - *boun_val);
}
if(method == _implicit_dynamic) {
integrator->integrationSchemeCorrDispl(time_step,
*displacement_rotation,
*velocity,
*acceleration,
*blocked_dofs,
*increment);
} else {
Real * disp_val = displacement_rotation->storage();
incr_val = increment->storage();
- for (UInt j = 0; j < nb_nodes *nb_degree_of_freedom; ++j, ++disp_val){
+ for (UInt j = 0; j < nb_nodes *nb_degree_of_freedom; ++j, ++disp_val, ++incr_val){
*disp_val += *incr_val;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::updateResidualInternal() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Update the residual");
// f = f_ext - f_int - Ma - Cv = r - Ma - Cv;
if(method != _static) {
// f -= Ma
if(mass_matrix) {
// if full mass_matrix
Array<Real> * Ma = new Array<Real>(*acceleration, true, "Ma");
*Ma *= *mass_matrix;
/// \todo check unit conversion for implicit dynamics
// *Ma /= f_m2a
*residual -= *Ma;
delete Ma;
} else if (mass) {
// else lumped mass
UInt nb_nodes = acceleration->getSize();
UInt nb_degree_of_freedom = acceleration->getNbComponent();
Real * mass_val = mass->storage();
Real * accel_val = acceleration->storage();
Real * res_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*res_val -= *accel_val * *mass_val /f_m2a;
}
blocked_dofs_val++;
res_val++;
mass_val++;
accel_val++;
}
} else {
AKANTU_DEBUG_ERROR("No function called to assemble the mass matrix.");
}
// f -= Cv
if(velocity_damping_matrix) {
Array<Real> * Cv = new Array<Real>(*velocity);
*Cv *= *velocity_damping_matrix;
*residual -= *Cv;
delete Cv;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::setIncrementFlagOn() {
AKANTU_DEBUG_IN();
if(!increment) {
UInt nb_nodes = mesh.getNbNodes();
std::stringstream sstr_inc; sstr_inc << id << ":increment";
increment = &(alloc<Real>(sstr_inc.str(), nb_nodes, spatial_dimension, 0.));
}
increment_flag = true;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void StructuralMechanicsModel::solve() {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_INFO("Solving an implicit step.");
UInt nb_nodes = displacement_rotation->getSize();
/// todo residual = force - Kxr * d_bloq
jacobian_matrix->copyContent(*stiffness_matrix);
jacobian_matrix->applyBoundary(*blocked_dofs);
jacobian_matrix->saveMatrix("Kbound.mtx");
increment->clear();
solver->setRHS(*residual);
solver->factorize();
solver->solve(*increment);
Real * increment_val = increment->storage();
Real * displacement_val = displacement_rotation->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) {
if(!(*blocked_dofs_val)) {
*displacement_val += *increment_val;
}
else {
*increment_val = 0.0;
}
displacement_val++;
blocked_dofs_val++;
increment_val++;
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<>
bool StructuralMechanicsModel::testConvergence<_scc_increment>(Real tolerance, Real & error){
AKANTU_DEBUG_IN();
UInt nb_nodes = displacement_rotation->getSize();
UInt nb_degree_of_freedom = displacement_rotation->getNbComponent();
error = 0;
Real norm[2] = {0., 0.};
Real * increment_val = increment->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
Real * displacement_val = displacement_rotation->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val)) {
norm[0] += *increment_val * *increment_val;
norm[1] += *displacement_val * *displacement_val;
}
blocked_dofs_val++;
increment_val++;
displacement_val++;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(norm, 2, _so_sum);
norm[0] = sqrt(norm[0]);
norm[1] = sqrt(norm[1]);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm[0]), "Something went wrong in the solve phase");
AKANTU_DEBUG_OUT();
if(norm[1] > Math::getTolerance())
error = norm[0] / norm[1];
else
error = norm[0]; //In case the total displacement is zero!
return (error < tolerance);
}
/* -------------------------------------------------------------------------- */
template<>
bool StructuralMechanicsModel::testConvergence<_scc_residual>(Real tolerance, Real & norm) {
AKANTU_DEBUG_IN();
UInt nb_nodes = residual->getSize();
norm = 0;
Real * residual_val = residual->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
if(is_local_node) {
- for (UInt d = 0; d < spatial_dimension; ++d) {
+ for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val)) {
norm += *residual_val * *residual_val;
}
blocked_dofs_val++;
residual_val++;
}
} else {
blocked_dofs_val += spatial_dimension;
residual_val += spatial_dimension;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum);
norm = sqrt(norm);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
AKANTU_DEBUG_OUT();
return (norm < tolerance);
}
/* -------------------------------------------------------------------------- */
bool StructuralMechanicsModel::testConvergenceIncrement(Real tolerance) {
Real error;
bool tmp = testConvergenceIncrement(tolerance, error);
AKANTU_DEBUG_INFO("Norm of increment : " << error);
return tmp;
}
/* -------------------------------------------------------------------------- */
bool StructuralMechanicsModel::testConvergenceIncrement(Real tolerance, Real & error) {
AKANTU_DEBUG_IN();
Mesh & mesh= getFEEngine().getMesh();
UInt nb_nodes = displacement_rotation->getSize();
UInt nb_degree_of_freedom = displacement_rotation->getNbComponent();
Real norm = 0;
Real * increment_val = increment->storage();
bool * blocked_dofs_val = blocked_dofs->storage();
for (UInt n = 0; n < nb_nodes; ++n) {
bool is_local_node = mesh.isLocalOrMasterNode(n);
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
if(!(*blocked_dofs_val) && is_local_node) {
norm += *increment_val * *increment_val;
}
blocked_dofs_val++;
increment_val++;
}
}
StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum);
error = sqrt(norm);
AKANTU_DEBUG_ASSERT(!Math::isnan(norm), "Something goes wrong in the solve phase");
AKANTU_DEBUG_OUT();
return (error < tolerance);
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_2>(Array<Real> & tangent_moduli) {
UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2);
- UInt nb_quadrature_points = getFEEngine().getNbQuadraturePoints(_bernoulli_beam_2);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2);
UInt tangent_size = 2;
Array<Real>::matrix_iterator D_it = tangent_moduli.begin(tangent_size, tangent_size);
Array<UInt> & el_mat = element_material(_bernoulli_beam_2, _not_ghost);
for (UInt e = 0; e < nb_element; ++e) {
UInt mat = el_mat(e);
Real E = materials[mat].E;
Real A = materials[mat].A;
Real I = materials[mat].I;
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
Matrix<Real> & D = *D_it;
D(0,0) = E * A;
D(1,1) = E * I;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_3>(Array<Real> & tangent_moduli) {
UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3);
- UInt nb_quadrature_points = getFEEngine().getNbQuadraturePoints(_bernoulli_beam_3);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3);
UInt tangent_size = 4;
Array<Real>::matrix_iterator D_it = tangent_moduli.begin(tangent_size, tangent_size);
for (UInt e = 0; e < nb_element; ++e) {
UInt mat = element_material(_bernoulli_beam_3, _not_ghost)(e);
Real E = materials[mat].E;
Real A = materials[mat].A;
Real Iz = materials[mat].Iz;
Real Iy = materials[mat].Iy;
Real GJ = materials[mat].GJ;
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
Matrix<Real> & D = *D_it;
D(0,0) = E * A;
D(1,1) = E * Iz;
D(2,2) = E * Iy;
D(3,3) = GJ;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::computeTangentModuli<_kirchhoff_shell>(Array<Real> & tangent_moduli) {
UInt nb_element = getFEEngine().getMesh().getNbElement(_kirchhoff_shell);
- UInt nb_quadrature_points = getFEEngine().getNbQuadraturePoints(_kirchhoff_shell);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_kirchhoff_shell);
UInt tangent_size = 6;
Array<Real>::matrix_iterator D_it = tangent_moduli.begin(tangent_size, tangent_size);
for (UInt e = 0; e < nb_element; ++e) {
UInt mat = element_material(_kirchhoff_shell, _not_ghost)(e);
Real E = materials[mat].E;
Real nu = materials[mat].nu;
Real t = materials[mat].t;
Real HH=E*t/(1-nu*nu);
Real DD=E*t*t*t/(12*(1-nu*nu));
for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
Matrix<Real> & D = *D_it;
D(0,0) = HH;
D(0,1) = HH*nu;
D(1,0) = HH*nu;
D(1,1) = HH;
D(2,2) = HH*(1-nu)/2;
D(3,3) = DD;
D(3,4) = DD*nu;
D(4,3) = DD*nu;
D(4,4) = DD;
D(5,5) = DD*(1-nu)/2;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix<_bernoulli_beam_2>(Array<Real> & b, bool local) {
UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_bernoulli_beam_2);
- UInt nb_quadrature_points = getFEEngine().getNbQuadraturePoints(_bernoulli_beam_2);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2);
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
Array<Real>::const_vector_iterator shape_Np = fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 0).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Mpp = fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 1).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Lpp = fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 2).begin(nb_nodes_per_element);
UInt tangent_size = getTangentStiffnessVoigtSize<_bernoulli_beam_2>();
UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom;
b.clear();
Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size);
for (UInt e = 0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quadrature_points; ++q) {
Matrix<Real> & B = *B_it;
const Vector<Real> & Np = *shape_Np;
const Vector<Real> & Lpp = *shape_Lpp;
const Vector<Real> & Mpp = *shape_Mpp;
B(0,0) = Np(0);
B(0,3) = Np(1);
B(1,1) = Mpp(0);
B(1,2) = Lpp(0);
B(1,4) = Mpp(1);
B(1,5) = Lpp(1);
++B_it;
++shape_Np;
++shape_Mpp;
++shape_Lpp;
}
// ++R_it;
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix<_bernoulli_beam_3>(Array<Real> & b, bool local) {
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_bernoulli_beam_3);
- UInt nb_quadrature_points = getFEEngine().getNbQuadraturePoints(_bernoulli_beam_3);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3);
Array<Real>::const_vector_iterator shape_Np = fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 0).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Mpp = fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 1).begin(nb_nodes_per_element);
Array<Real>::const_vector_iterator shape_Lpp = fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 2).begin(nb_nodes_per_element);
UInt tangent_size = getTangentStiffnessVoigtSize<_bernoulli_beam_3>();
UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom;
b.clear();
Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size);
for (UInt e = 0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quadrature_points; ++q) {
Matrix<Real> & B = *B_it;
const Vector<Real> & Np = *shape_Np;
const Vector<Real> & Lpp = *shape_Lpp;
const Vector<Real> & Mpp = *shape_Mpp;
B(0,0) = Np(0);
B(0,6) = Np(1);
B(1,1) = Mpp(0);
B(1,5) = Lpp(0);
B(1,7) = Mpp(1);
B(1,11) = Lpp(1);
B(2,2) = Mpp(0);
B(2,4) = -Lpp(0);
B(2,8) = Mpp(1);
B(2,10) = -Lpp(1);
B(3,3) = Np(0);
B(3,9) = Np(1);
++B_it;
++shape_Np;
++shape_Mpp;
++shape_Lpp;
}
}
}
/* -------------------------------------------------------------------------- */
template<>
void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix<_kirchhoff_shell>(Array<Real> & b, bool local) {
MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
UInt nb_element = getFEEngine().getMesh().getNbElement(_kirchhoff_shell);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_kirchhoff_shell);
- UInt nb_quadrature_points = getFEEngine().getNbQuadraturePoints(_kirchhoff_shell);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(_kirchhoff_shell);
Array<Real>::const_matrix_iterator shape_Np = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 0).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Nx1p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 1).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Nx2p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 2).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Nx3p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 3).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Ny1p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 4).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Ny2p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 5).begin(2,nb_nodes_per_element);
Array<Real>::const_matrix_iterator shape_Ny3p = fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 6).begin(2,nb_nodes_per_element);
UInt tangent_size = getTangentStiffnessVoigtSize<_kirchhoff_shell>();
UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom;
b.clear();
Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size);
for (UInt e = 0; e < nb_element; ++e) {
for (UInt q = 0; q < nb_quadrature_points; ++q) {
Matrix<Real> & B = *B_it;
const Matrix<Real> & Np = *shape_Np;
const Matrix<Real> & Nx1p = *shape_Nx1p;
const Matrix<Real> & Nx2p = *shape_Nx2p;
const Matrix<Real> & Nx3p = *shape_Nx3p;
const Matrix<Real> & Ny1p = *shape_Ny1p;
const Matrix<Real> & Ny2p = *shape_Ny2p;
const Matrix<Real> & Ny3p = *shape_Ny3p;
B(0,0) = Np(0,0);
B(0,6) = Np(0,1);
B(0,12) = Np(0,2);
B(1,1) = Np(1,0);
B(1,7) = Np(1,1);
B(1,13) = Np(1,2);
B(2,0) = Np(1,0);
B(2,1) = Np(0,0);
B(2,6) = Np(1,1);
B(2,7) = Np(0,1);
B(2,12) = Np(1,2);
B(2,13) = Np(0,2);
B(3,2) = Nx1p(0,0);
B(3,3) = Nx2p(0,0);
B(3,4) = Nx3p(0,0);
B(3,8) = Nx1p(0,1);
B(3,9) = Nx2p(0,1);
B(3,10) = Nx3p(0,1);
B(3,14) = Nx1p(0,2);
B(3,15) = Nx2p(0,2);
B(3,16) = Nx3p(0,2);
B(4,2) = Ny1p(1,0);
B(4,3) = Ny2p(1,0);
B(4,4) = Ny3p(1,0);
B(4,8) = Ny1p(1,1);
B(4,9) = Ny2p(1,1);
B(4,10) = Ny3p(1,1);
B(4,14) = Ny1p(1,2);
B(4,15) = Ny2p(1,2);
B(4,16) = Ny3p(1,2);
B(5,2) = Nx1p(1,0) + Ny1p(0,0);
B(5,3) = Nx2p(1,0) + Ny2p(0,0);
B(5,4) = Nx3p(1,0) + Ny3p(0,0);
B(5,8) = Nx1p(1,1) + Ny1p(0,1);
B(5,9) = Nx2p(1,1) + Ny2p(0,1);
B(5,10) = Nx3p(1,1) + Ny3p(0,1);
B(5,14) = Nx1p(1,2) + Ny1p(0,2);
B(5,15) = Nx2p(1,2) + Ny2p(0,2);
B(5,16) = Nx3p(1,2) + Ny3p(0,2);
++B_it;
++shape_Np;
++shape_Nx1p;
++shape_Nx2p;
++shape_Nx3p;
++shape_Ny1p;
++shape_Ny2p;
++shape_Ny3p;
}
}
}
/* -------------------------------------------------------------------------- */
dumper::Field * StructuralMechanicsModel
::createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
std::map<std::string,Array<bool>* > uint_nodal_fields;
uint_nodal_fields["blocked_dofs" ] = blocked_dofs;
dumper::Field * field = NULL;
field = mesh.createNodalField(uint_nodal_fields[field_name],group_name);
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * StructuralMechanicsModel
::createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag) {
UInt n;
if(spatial_dimension == 2) {
n = 2;
} else n = 3;
dumper::Field * field = NULL;
if (field_name == "displacement"){
field = mesh.createStridedNodalField(displacement_rotation,group_name,n,0,padding_flag);
}
if (field_name == "rotation"){
field = mesh.createStridedNodalField(displacement_rotation,group_name,
nb_degree_of_freedom-n,n,padding_flag);
}
if (field_name == "force"){
field = mesh.createStridedNodalField(force_momentum,group_name,n,0,padding_flag);
}
if (field_name == "momentum"){
field = mesh.createStridedNodalField(force_momentum,group_name,
nb_degree_of_freedom-n,n,padding_flag);
}
if (field_name == "residual"){
field = mesh.createNodalField(residual,group_name,padding_flag);
}
return field;
}
/* -------------------------------------------------------------------------- */
dumper::Field * StructuralMechanicsModel
::createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
- const ElementKind & kind){
+ const ElementKind & kind,
+ const std::string & fe_engine_id){
dumper::Field * field = NULL;
if(field_name == "element_index_by_material")
field = mesh.createElementalField<UInt, Vector, dumper::ElementalField >(field_name,group_name,this->spatial_dimension,kind);
return field;
}
/* -------------------------------------------------------------------------- */
__END_AKANTU__
diff --git a/src/model/structural_mechanics/structural_mechanics_model.hh b/src/model/structural_mechanics/structural_mechanics_model.hh
index 741652314..9a214db8e 100644
--- a/src/model/structural_mechanics/structural_mechanics_model.hh
+++ b/src/model/structural_mechanics/structural_mechanics_model.hh
@@ -1,400 +1,401 @@
/**
* @file structural_mechanics_model.hh
*
* @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>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Tue Sep 02 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__
#define __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "model.hh"
#include "integrator_gauss.hh"
#include "shape_linked.hh"
#include "aka_types.hh"
#include "dumpable.hh"
#include "solver.hh"
#include "integration_scheme_2nd_order.hh"
/* -------------------------------------------------------------------------- */
namespace akantu {
class SparseMatrix;
}
__BEGIN_AKANTU__
struct StructuralMaterial {
Real E;
Real A;
Real I;
Real Iz;
Real Iy;
Real GJ;
Real rho;
Real t;
Real nu;
};
struct StructuralMechanicsModelOptions : public ModelOptions {
StructuralMechanicsModelOptions(AnalysisMethod analysis_method = _static) :
analysis_method(analysis_method) {}
AnalysisMethod analysis_method;
};
extern const StructuralMechanicsModelOptions default_structural_mechanics_model_options;
class StructuralMechanicsModel : public Model {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
typedef FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural> MyFEEngineType;
StructuralMechanicsModel(Mesh & mesh,
UInt spatial_dimension = _all_dimensions,
const ID & id = "structural_mechanics_model",
const MemoryID & memory_id = 0);
virtual ~StructuralMechanicsModel();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize fully the model
void initFull(const ModelOptions & options = default_structural_mechanics_model_options);
/// initialize the internal vectors
void initArrays();
/// initialize the model
void initModel();
/// initialize the solver
void initSolver(SolverOptions & options = _solver_no_options);
/// initialize the stuff for the implicit solver
void initImplicit(bool dynamic = false,
SolverOptions & solver_options = _solver_no_options);
/// compute the stresses per elements
void computeStresses();
/// assemble the stiffness matrix
void assembleStiffnessMatrix();
/// assemble the mass matrix for consistent mass resolutions
void assembleMass();
/// implicit time integration predictor
void implicitPred();
/// implicit time integration corrector
void implicitCorr();
/// update the residual vector
void updateResidual();
/// solve the system
void solve();
bool testConvergenceIncrement(Real tolerance);
bool testConvergenceIncrement(Real tolerance, Real & error);
virtual void printself(std::ostream & stream, int indent = 0) const {};
void computeRotationMatrix(const ElementType & type);
protected:
UInt getTangentStiffnessVoigtSize(const ElementType & type);
/// compute Rotation Matrices
template<const ElementType type>
void computeRotationMatrix(Array<Real> & rotations) {};
/// compute A and solve @f[ A\delta u = f_ext - f_int @f]
template<NewmarkBeta::IntegrationSchemeCorrectorType type>
void solve(Array<Real> & increment, Real block_val = 1.);
/* ------------------------------------------------------------------------ */
/* Mass (structural_mechanics_model_mass.cc) */
/* ------------------------------------------------------------------------ */
/// assemble the mass matrix for either _ghost or _not_ghost elements
void assembleMass(GhostType ghost_type);
/// computes rho
void computeRho(Array<Real> & rho,
ElementType type,
GhostType ghost_type);
/// finish the computation of residual to solve in increment
void updateResidualInternal();
/* ------------------------------------------------------------------------ */
private:
template<ElementType type>
inline UInt getTangentStiffnessVoigtSize();
template <ElementType type>
void assembleStiffnessMatrix();
template <ElementType type>
void assembleMass();
template<ElementType type>
void computeStressOnQuad();
template <ElementType type>
void computeTangentModuli(Array<Real> & tangent_moduli);
template <ElementType type>
void transferBMatrixToSymVoigtBMatrix(Array<Real> & B, bool local = false);
template <ElementType type>
void transferNMatrixToSymVoigtNMatrix(Array<Real> & N_matrix);
/* ------------------------------------------------------------------------ */
/* Dumpable interface */
/* ------------------------------------------------------------------------ */
public:
virtual dumper::Field * createNodalFieldReal(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field * createNodalFieldBool(const std::string & field_name,
const std::string & group_name,
bool padding_flag);
virtual dumper::Field * createElementalField(const std::string & field_name,
const std::string & group_name,
bool padding_flag,
- const ElementKind & kind);
+ const ElementKind & kind,
+ const std::string & fe_engine_id = "");
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// set the value of the time step
void setTimeStep(Real time_step);
/// return the dimension of the system space
AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
/// get the StructuralMechanicsModel::displacement vector
AKANTU_GET_MACRO(Displacement, *displacement_rotation, Array<Real> &);
/// get the StructuralMechanicsModel::velocity vector
AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &);
/// get the StructuralMechanicsModel::acceleration vector, updated by
/// StructuralMechanicsModel::updateAcceleration
AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
/// get the StructuralMechanicsModel::force vector (boundary forces)
AKANTU_GET_MACRO(Force, *force_momentum, Array<Real> &);
/// get the StructuralMechanicsModel::residual vector, computed by StructuralMechanicsModel::updateResidual
AKANTU_GET_MACRO(Residual, *residual, const Array<Real> &);
/// get the StructuralMechanicsModel::boundary vector
AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(RotationMatrix, rotation_matrix, Real);
AKANTU_GET_MACRO(StiffnessMatrix, *stiffness_matrix, const SparseMatrix &);
AKANTU_GET_MACRO(MassMatrix, *mass_matrix, const SparseMatrix &);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(ElementMaterial, element_material, UInt);
AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Set_ID, set_ID, UInt);
void addMaterial(StructuralMaterial & material) { materials.push_back(material); }
/**
* @brief set the StructuralMechanicsModel::increment_flag to on, the activate the
* update of the StructuralMechanicsModel::increment vector
*/
void setIncrementFlagOn();
/* ------------------------------------------------------------------------ */
/* Boundaries (structural_mechanics_model_boundary.cc) */
/* ------------------------------------------------------------------------ */
public:
/// Compute Linear load function set in global axis
template <ElementType type>
void computeForcesByGlobalTractionArray(const Array<Real> & tractions);
/// Compute Linear load function set in local axis
template <ElementType type>
void computeForcesByLocalTractionArray(const Array<Real> & tractions);
/// compute force vector from a function(x,y,momentum) that describe stresses
template <ElementType type>
void computeForcesFromFunction(BoundaryFunction in_function,
BoundaryFunctionType function_type);
/**
* solve a step (predictor + convergence loop + corrector) using the
* the given convergence method (see akantu::SolveConvergenceMethod)
* and the given convergence criteria (see
* akantu::SolveConvergenceCriteria)
**/
template<SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance,
UInt max_iteration = 100);
template<SolveConvergenceMethod method, SolveConvergenceCriteria criteria>
bool solveStep(Real tolerance,
Real & error,
UInt max_iteration = 100);
/// test if the system is converged
template<SolveConvergenceCriteria criteria>
bool testConvergence(Real tolerance, Real & error);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// time step
Real time_step;
/// conversion coefficient form force/mass to acceleration
Real f_m2a;
/// displacements array
Array<Real> * displacement_rotation;
/// displacements array at the previous time step (used in finite deformation)
Array<Real> * previous_displacement;
/// velocities array
Array<Real> * velocity;
/// accelerations array
Array<Real> * acceleration;
/// forces array
Array<Real> * force_momentum;
/// lumped mass array
Array<Real> * mass;
/// stress arraz
ElementTypeMapArray<Real> stress;
/// residuals array
Array<Real> * residual;
/// boundaries array
Array<bool> * blocked_dofs;
/// position of a dof in the K matrix
Array<Int> * equation_number;
ElementTypeMapArray<UInt> element_material;
// Define sets of beams
ElementTypeMapArray<UInt> set_ID;
/// local equation_number to global
unordered_map<UInt, UInt>::type local_eq_num_to_global;
/// stiffness matrix
SparseMatrix * stiffness_matrix;
/// mass matrix
SparseMatrix * mass_matrix;
/// velocity damping matrix
SparseMatrix * velocity_damping_matrix;
/// jacobian matrix
SparseMatrix * jacobian_matrix;
/// increment of displacement
Array<Real> * increment;
/// solver for implicit
Solver * solver;
/// number of degre of freedom
UInt nb_degree_of_freedom;
// Rotation matrix
ElementTypeMapArray<Real> rotation_matrix;
/// analysis method check the list in akantu::AnalysisMethod
AnalysisMethod method;
/// flag defining if the increment must be computed or not
bool increment_flag;
/// integration scheme of second order used
IntegrationScheme2ndOrder * integrator;
/* -------------------------------------------------------------------------- */
std::vector<StructuralMaterial> materials;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "structural_mechanics_model_inline_impl.cc"
/// standard output stream operator
inline std::ostream & operator <<(std::ostream & stream, const StructuralMechanicsModel & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__ */
diff --git a/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc b/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
index db5463257..109cf54aa 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,614 @@
/**
* @file structural_mechanics_model_inline_impl.cc
*
* @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>
*
* @date creation: Fri Jul 15 2011
* @date last modification: Tue Sep 02 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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..30d2152a5 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
*
* @brief function handling mass computation
*
* @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 "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);
+ UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
Array<UInt> & el_mat = element_material(type, ghost_type);
for (UInt e = 0; e < nb_element; ++e){
UInt mat = el_mat(e);
Real rho_el = materials[mat].rho;
for (UInt q = e*nb_quadrature_points; q < e*nb_quadrature_points + nb_quadrature_points; ++q){
rho(q) = rho_el;
}
}
AKANTU_DEBUG_OUT();
}
__END_AKANTU__
diff --git a/src/python/python_functor.cc b/src/python/python_functor.cc
new file mode 100644
index 000000000..9e82870ca
--- /dev/null
+++ b/src/python/python_functor.cc
@@ -0,0 +1,76 @@
+/**
+ * @file python_functor.cc
+ *
+
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ *
+ *
+ * @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 "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..5237cef37
--- /dev/null
+++ b/src/python/python_functor.hh
@@ -0,0 +1,124 @@
+/**
+ * @file python_functor.hh
+ *
+
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ *
+ *
+ * @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_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..bd51e5f4c
--- /dev/null
+++ b/src/python/python_functor_inline_impl.cc
@@ -0,0 +1,244 @@
+#ifndef __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
+#define __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__
+/* -------------------------------------------------------------------------- */
+#include <numpy/arrayobject.h>
+#include "integration_point.hh"
+/* -------------------------------------------------------------------------- */
+__BEGIN_AKANTU__
+/* -------------------------------------------------------------------------- */
+
+
+
+template <typename T>
+inline int PythonFunctor::getPythonDataTypeCode() const{
+ AKANTU_EXCEPTION("undefined type");
+}
+
+/* -------------------------------------------------------------------------- */
+
+template <>
+inline int PythonFunctor::getPythonDataTypeCode<bool>() const{
+ int data_typecode = NPY_NOTYPE;
+ size_t s = sizeof(bool);
+ switch(s) {
+ case 1: data_typecode = NPY_BOOL; break;
+ case 2: data_typecode = NPY_UINT16; break;
+ case 4: data_typecode = NPY_UINT32; break;
+ case 8: data_typecode = NPY_UINT64; break;
+ }
+ return data_typecode;
+}
+/* -------------------------------------------------------------------------- */
+
+template <>
+inline int PythonFunctor::getPythonDataTypeCode<double>() const{
+ return NPY_DOUBLE;
+}
+
+/* -------------------------------------------------------------------------- */
+
+template <typename T>
+PyObject *PythonFunctor::convertToPython(const T & akantu_object) const{
+ AKANTU_DEBUG_TO_IMPLEMENT();
+}
+/* -------------------------------------------------------------------------- */
+
+template <>
+inline PyObject *PythonFunctor::convertToPython<double>(const double & akantu_object) const{
+ return PyFloat_FromDouble(akantu_object);
+}
+/* -------------------------------------------------------------------------- */
+
+template <>
+inline PyObject *PythonFunctor::convertToPython<UInt>(const UInt & akantu_object) const{
+ return PyInt_FromLong(akantu_object);
+}
+/* -------------------------------------------------------------------------- */
+
+template <>
+inline PyObject *PythonFunctor::convertToPython<bool>(const bool & akantu_object) const{
+ return PyBool_FromLong(long(akantu_object));
+}
+/* -------------------------------------------------------------------------- */
+
+template <typename T>
+inline PyObject *PythonFunctor::convertToPython(const std::vector<T> & array) const{
+ int data_typecode = getPythonDataTypeCode< T >();
+ npy_intp dims[1] = {int(array.size())};
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, data_typecode, const_cast<T*>(&array[0]));
+ PyArrayObject* res = (PyArrayObject*) obj;
+ return (PyObject*)res;
+}
+/* -------------------------------------------------------------------------- */
+
+template <typename T>
+PyObject *PythonFunctor::convertToPython(const Vector<T> & array) const{
+ int data_typecode = getPythonDataTypeCode< T >();
+ npy_intp dims[1] = {array.size()};
+ PyObject* obj = PyArray_SimpleNewFromData(1, dims, data_typecode, array.storage());
+ PyArrayObject* res = (PyArrayObject*) obj;
+ return (PyObject*)res;
+}
+/* -------------------------------------------------------------------------- */
+
+template <typename T>
+PyObject *PythonFunctor::convertToPython(const Matrix<T> & mat) const{
+ int data_typecode = getPythonDataTypeCode< T >();
+ npy_intp dims[2] = {mat.size(0),mat.size(1)};
+ PyObject* obj = PyArray_SimpleNewFromData(2, dims, data_typecode, mat.storage());
+ PyArrayObject* res = (PyArrayObject*) obj;
+ return (PyObject*)res;
+}
+/* -------------------------------------------------------------------------- */
+
+template <>
+inline PyObject *PythonFunctor::convertToPython<std::string>(const std::string & str) const{
+ return PyString_FromString(str.c_str());
+}
+/* -------------------------------------------------------------------------- */
+
+template <>
+inline PyObject *PythonFunctor::convertToPython<IntegrationPoint>(const IntegrationPoint & qp) const{
+
+ PyObject * input = PyDict_New();
+ PyObject * num_point = this->convertToPython(qp.num_point);
+ PyObject * global_num = this->convertToPython(qp.global_num);
+ PyObject * material_id = this->convertToPython(qp.material_id);
+ PyObject * position = this->convertToPython(qp.getPosition());
+ PyDict_SetItemString(input,"num_point",num_point);
+ PyDict_SetItemString(input,"global_num",global_num);
+ PyDict_SetItemString(input,"material_id",material_id);
+ PyDict_SetItemString(input,"position",position);
+ return input;
+}
+/* -------------------------------------------------------------------------- */
+
+
+inline PyObject * PythonFunctor::getPythonFunction(const std::string & functor_name) const{
+
+ if (!PyInstance_Check(this->python_obj))
+ AKANTU_EXCEPTION("Python object is not an instance");
+
+ // if (!PyDict_Check(this->python_obj))
+ // AKANTU_EXCEPTION("Python object is not a dictionary");
+
+ //PyObject * keys = PyDict_Keys(dict);
+ //PyObject_Print(keys, stdout, Py_PRINT_RAW);
+
+ PyObject * pFunctor = PyObject_GetAttrString(this->python_obj, functor_name.c_str());
+ if (!pFunctor) AKANTU_EXCEPTION("Python dictionary has no " << functor_name << " entry");
+
+ return pFunctor;
+}
+/* -------------------------------------------------------------------------- */
+
+inline void PythonFunctor::packArguments(std::vector<PyObject*> & pArgs)const {}
+
+/* -------------------------------------------------------------------------- */
+
+
+template<typename T, typename... Args>
+inline void PythonFunctor::packArguments(std::vector<PyObject*> & pArgs,
+ T & p,
+ Args&...params)const{
+
+ pArgs.push_back(this->convertToPython(p));
+ if (sizeof...(params) != 0)
+ this->packArguments(pArgs,params...);
+}
+
+/* -------------------------------------------------------------------------- */
+
+
+template <typename return_type, typename... Params>
+return_type PythonFunctor::callFunctor(const std::string & functor_name,
+ Params&... parameters) const{
+
+
+ _import_array();
+
+ std::vector<PyObject*> arg_vector;
+ this->packArguments(arg_vector,parameters...);
+
+ PyObject * pArgs = PyTuple_New(arg_vector.size());
+ for (UInt i = 0; i < arg_vector.size(); ++i) {
+ PyTuple_SetItem(pArgs,i,arg_vector[i]);
+ }
+
+ PyObject * kwargs = PyDict_New();
+
+ PyObject * pFunctor = getPythonFunction(functor_name);
+ PyObject * res = this->callFunctor(pFunctor,pArgs,kwargs);
+
+ // for (auto a: arg_vector) {
+ // // if (PyDict_Check(a)){
+ // // PyObject* values = PyDict_Values(a);
+ // // UInt sz = PyList_GET_SIZE(values);
+ // // for (UInt i = 0; i < sz; ++i) {
+ // // Py_XDECREF(PyList_GetItem(values,i));
+ // // }
+ // // }
+ // // Py_XDECREF(a);
+ // }
+ Py_XDECREF(pArgs);
+ Py_XDECREF(kwargs);
+
+ return this->convertToAkantu<return_type>(res);
+
+}
+
+/* -------------------------------------------------------------------------- */
+
+template <typename return_type>
+inline return_type PythonFunctor::convertToAkantu(PyObject * python_obj) const{
+
+ if (PyList_Check(python_obj)){
+ return this->convertListToAkantu<typename return_type::value_type>(python_obj);
+ }
+ AKANTU_DEBUG_TO_IMPLEMENT();
+}
+
+/* -------------------------------------------------------------------------- */
+
+template <>
+inline void PythonFunctor::convertToAkantu<void>(PyObject * python_obj) const{
+ if (python_obj != Py_None) AKANTU_DEBUG_WARNING("functor return a value while none was expected: ignored");
+}
+
+/* -------------------------------------------------------------------------- */
+
+
+template <>
+inline std::string PythonFunctor::convertToAkantu<std::string>(PyObject * python_obj) const{
+ if (!PyString_Check(python_obj)) AKANTU_EXCEPTION("cannot convert object to string");
+ return PyString_AsString(python_obj);
+}
+
+/* -------------------------------------------------------------------------- */
+
+template <>
+inline Real PythonFunctor::convertToAkantu<Real>(PyObject * python_obj) const{
+ if (!PyFloat_Check(python_obj)) AKANTU_EXCEPTION("cannot convert object to float");
+ return PyFloat_AsDouble(python_obj);
+}
+
+/* -------------------------------------------------------------------------- */
+
+template <typename T>
+inline std::vector<T> PythonFunctor::convertListToAkantu(PyObject * python_obj) const{
+
+ std::vector<T> res;
+ UInt size = PyList_Size(python_obj);
+ for (UInt i = 0; i < size; ++i) {
+ PyObject * item = PyList_GET_ITEM(python_obj,i);
+ res.push_back(this->convertToAkantu<T>(item));
+ }
+ return res;
+}
+
+/* -------------------------------------------------------------------------- */
+
+__END_AKANTU__
+
+
+#endif /* __AKANTU_PYTHON_FUNCTOR_INLINE_IMPL_CC__ */
diff --git a/src/solver/petsc_matrix.cc b/src/solver/petsc_matrix.cc
new file mode 100644
index 000000000..d6b7a9be5
--- /dev/null
+++ b/src/solver/petsc_matrix.cc
@@ -0,0 +1,643 @@
+/**
+ * @file petsc_matrix.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Mon Jul 21 17:40:41 2014
+ *
+ * @brief Implementation of PETSc matrix class
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "petsc_matrix.hh"
+#include "static_communicator.hh"
+#include "static_communicator_mpi.hh"
+#include "mpi_type_wrapper.hh"
+#include "dof_synchronizer.hh"
+#include "petsc_wrapper.hh"
+/* -------------------------------------------------------------------------- */
+#include <cstring>
+#include <petscsys.h>
+
+__BEGIN_AKANTU__
+
+#if not defined(PETSC_CLANGUAGE_CXX)
+int aka_PETScError(int ierr) {
+ CHKERRQ(ierr);
+ return 0;
+}
+#endif
+
+// struct PETScWrapper {
+// Mat mat;
+// AO ao;
+// ISLocalToGlobalMapping mapping;
+// /// pointer to the MPI communicator for PETSc commands
+// MPI_Comm communicator;
+// };
+
+/* -------------------------------------------------------------------------- */
+PETScMatrix::PETScMatrix(UInt size,
+ const SparseMatrixType & sparse_matrix_type,
+ const ID & id,
+ const MemoryID & memory_id) :
+ SparseMatrix(size, sparse_matrix_type, id, memory_id),
+ petsc_matrix_wrapper(new PETScMatrixWrapper),
+ d_nnz(0,1,"dnnz"),
+ o_nnz(0,1,"onnz"),
+ first_global_index(0),
+ is_petsc_matrix_initialized(false) {
+ AKANTU_DEBUG_IN();
+ StaticSolver::getStaticSolver().registerEventHandler(*this);
+ this->offset = 0;
+ this->init();
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+PETScMatrix::PETScMatrix(const SparseMatrix & matrix,
+ const ID & id,
+ const MemoryID & memory_id) :
+ SparseMatrix(matrix, id, memory_id),
+ petsc_matrix_wrapper(new PETScMatrixWrapper),
+ d_nnz(0,1,"dnnz"),
+ o_nnz(0,1,"onnz"),
+ first_global_index(0),
+ is_petsc_matrix_initialized(false) {
+ // AKANTU_DEBUG_IN();
+ // StaticSolver::getStaticSolver().registerEventHandler(*this);
+ // this->offset = 0;
+ // this->init();
+
+ // AKANTU_DEBUG_OUT();
+ AKANTU_DEBUG_TO_IMPLEMENT();
+}
+
+/* -------------------------------------------------------------------------- */
+PETScMatrix::~PETScMatrix() {
+ AKANTU_DEBUG_IN();
+
+ /// destroy all the PETSc data structures used for this matrix
+ this->destroyInternalData();
+ StaticSolver::getStaticSolver().unregisterEventHandler(*this);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void PETScMatrix::init() {
+ AKANTU_DEBUG_IN();
+
+ /// set the communicator that should be used by PETSc
+#if defined(AKANTU_USE_MPI)
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+ const StaticCommunicatorMPI & mpi_st_comm =
+ dynamic_cast<const StaticCommunicatorMPI &>(comm.getRealStaticCommunicator());
+ this->petsc_matrix_wrapper->communicator = mpi_st_comm.getMPITypeWrapper().getMPICommunicator();
+#else
+ this->petsc_matrix_wrapper->communicator = PETSC_COMM_SELF;
+#endif
+
+ PetscErrorCode ierr;
+
+ /// create the PETSc matrix object
+ ierr = MatCreate(this->petsc_matrix_wrapper->communicator, &(this->petsc_matrix_wrapper->mat)); CHKERRXX(ierr);
+
+
+ /**
+ * Set the matrix type
+ * @todo PETSc does currently not support a straightforward way to
+ * apply Dirichlet boundary conditions for MPISBAIJ
+ * matrices. Therefore always the entire matrix is allocated. It
+ * would be possible to use MATSBAIJ for sequential matrices in case
+ * memory becomes critical. Also, block matrices would give a much
+ * better performance. Modify this in the future!
+ */
+
+ ierr = MatSetType(this->petsc_matrix_wrapper->mat, MATAIJ); CHKERRXX(ierr);
+
+ this->is_petsc_matrix_initialized = true;
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * With this method each processor computes the dimensions of the
+ * local matrix, i.e. the part of the global matrix it is storing.
+ * @param dof_synchronizer dof synchronizer that maps the local
+ * dofs to the global dofs and the equation numbers, i.e., the
+ * position at which the dof is assembled in the matrix
+ */
+void PETScMatrix::setSize() {
+ AKANTU_DEBUG_IN();
+
+ PetscErrorCode ierr;
+
+ /// find the number of dofs corresponding to master or local nodes
+ UInt nb_dofs = this->dof_synchronizer->getNbDOFs();
+ UInt nb_local_master_dofs = 0;
+
+ /// create array to store the global equation number of all local and master dofs
+ Array<Int> local_master_eq_nbs(nb_dofs);
+ Array<Int>::scalar_iterator it_eq_nb = local_master_eq_nbs.begin();
+
+ /// get the pointer to the global equation number array
+ Int * eq_nb_val = this->dof_synchronizer->getGlobalDOFEquationNumbers().storage();
+
+ for (UInt i = 0; i <nb_dofs; ++i) {
+ if (this->dof_synchronizer->isLocalOrMasterDOF(i) ) {
+ *it_eq_nb = eq_nb_val[i];
+ ++it_eq_nb;
+ ++nb_local_master_dofs;
+ }
+ }
+
+ local_master_eq_nbs.resize(nb_local_master_dofs);
+
+ /// set the local size
+ this->local_size = nb_local_master_dofs;
+
+ /// resize PETSc matrix
+#if defined(AKANTU_USE_MPI)
+ ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size, this->local_size, this->size, this->size); CHKERRXX(ierr);
+#else
+ ierr = MatSetSizes(this->petsc_matrix_wrapper->mat, this->local_size, this->local_size); CHKERRXX(ierr);
+#endif
+
+ /// create mapping from akantu global numbering to petsc global numbering
+ this->createGlobalAkantuToPETScMap(local_master_eq_nbs.storage());
+
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * This method generates a mapping from the global Akantu equation
+ * numbering to the global PETSc dof ordering
+ * @param local_master_eq_nbs_ptr Int pointer to the array of equation
+ * numbers of all local or master dofs, i.e. the row indices of the
+ * local matrix
+ */
+void PETScMatrix::createGlobalAkantuToPETScMap(Int* local_master_eq_nbs_ptr) {
+ AKANTU_DEBUG_IN();
+
+ PetscErrorCode ierr;
+
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+ UInt rank = comm.whoAmI();
+
+ //initialize vector to store the number of local and master nodes that are assigned to each processor
+ Vector<UInt> master_local_ndofs_per_proc(nb_proc);
+
+ /// store the nb of master and local dofs on each processor
+ master_local_ndofs_per_proc(rank) = this->local_size;
+
+
+
+ /// exchange the information among all processors
+ comm.allGather(master_local_ndofs_per_proc.storage(), 1);
+
+ /// each processor creates a map for his akantu global dofs to the corresponding petsc global dofs
+
+ /// determine the PETSc-index for the first dof on each processor
+
+ for (UInt i = 0; i < rank; ++i) {
+ this->first_global_index += master_local_ndofs_per_proc(i);
+ }
+
+ /// create array for petsc ordering
+ Array<Int> petsc_dofs(this->local_size);
+ Array<Int>::scalar_iterator it_petsc_dofs = petsc_dofs.begin();
+
+ for (Int i = this->first_global_index; i < this->first_global_index + this->local_size; ++i, ++it_petsc_dofs) {
+ *it_petsc_dofs = i;
+ }
+
+ ierr = AOCreateBasic(this->petsc_matrix_wrapper->communicator, this->local_size, local_master_eq_nbs_ptr, petsc_dofs.storage(), &(this->petsc_matrix_wrapper->ao)); CHKERRXX(ierr);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+// void PETScMatrix::createLocalAkantuToPETScMap(const DOFSynchronizer & dof_synchronizer) {
+// AKANTU_DEBUG_IN();
+
+// AKANTU_DEBUG_ASSERT(this->petsc_matrix_wrapper->ao != NULL,
+// "You should first create a mapping from the global"
+// << " Akantu numbering to the global PETSc numbering");
+
+// PetscErrorCode ierr;
+
+// this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
+
+// /// get the number of dofs
+// Int nb_dofs = dof_synchronizer.getNbDOFs();
+
+// /// get the global equation numbers for each node
+// Array<Int> global_dof_equation_numbers = dof_synchronizer.getGlobalDOFEquationNumbers();
+
+// /// map the global dof equation numbers to the corresponding PETSc ordering
+// ierr = AOApplicationToPETSc(this->petsc_matrix_wrapper->ao, nb_dofs,
+// global_dof_equation_numbers.storage()); CHKERRXX(ierr);
+
+// /// create the mapping from the local Akantu ordering to the global PETSc ordering
+// ierr = ISLocalToGlobalMappingCreate(this->petsc_matrix_wrapper->communicator,
+// 1, nb_dofs, global_dof_equation_numbers.storage(),
+// PETSC_COPY_VALUES, &(this->petsc_matrix_wrapper-mapping)); CHKERRXX(ierr);
+
+// AKANTU_DEBUG_OUT();
+// }
+
+/* -------------------------------------------------------------------------- */
+/**
+ * This function creates the non-zero pattern of the PETSc matrix. In
+ * PETSc the parallel matrix is partitioned across processors such
+ * that the first m0 rows belong to process 0, the next m1 rows belong
+ * to process 1, the next m2 rows belong to process 2 etc.. where
+ * m0,m1,m2,.. are the input parameter 'm'. i.e each processor stores
+ * values corresponding to [m x N] submatrix
+ * (http://www.mcs.anl.gov/petsc/).
+ * @param mesh mesh discretizing the domain we want to analyze
+ * @param dof_synchronizer dof synchronizer that maps the local
+ * dofs to the global dofs and the equation numbers, i.e., the
+ * position at which the dof is assembled in the matrix
+ */
+
+void PETScMatrix::buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom) {
+ AKANTU_DEBUG_IN();
+
+ //clearProfile();
+ this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
+ this->setSize();
+ PetscErrorCode ierr;
+
+ /// resize arrays to store the number of nonzeros in each row
+ this->d_nnz.resize(this->local_size);
+ this->o_nnz.resize(this->local_size);
+
+ /// set arrays to zero everywhere
+ this->d_nnz.set(0);
+ this->o_nnz.set(0);
+
+
+ // if(irn_jcn_to_k) delete irn_jcn_to_k;
+ // irn_jcn_to_k = new std::map<std::pair<UInt, UInt>, UInt>;
+
+ coordinate_list_map::iterator irn_jcn_k_it;
+
+ Int * eq_nb_val = dof_synchronizer.getGlobalDOFEquationNumbers().storage();
+ UInt nb_global_dofs = dof_synchronizer.getNbGlobalDOFs();
+ Array<Int> index_pair(2);
+
+ /// Loop over all the ghost types
+ for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+ const GhostType & ghost_type = *gt;
+ Mesh::type_iterator it = mesh.firstType(mesh.getSpatialDimension(), ghost_type, _ek_not_defined);
+ Mesh::type_iterator end = mesh.lastType (mesh.getSpatialDimension(), ghost_type, _ek_not_defined);
+ for(; it != end; ++it) {
+ UInt nb_element = mesh.getNbElement(*it, ghost_type);
+ UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
+ UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
+
+ UInt * conn_val = mesh.getConnectivity(*it, ghost_type).storage();
+ Int * local_eq_nb_val = new Int[nb_degree_of_freedom * nb_nodes_per_element];
+
+
+ for (UInt e = 0; e < nb_element; ++e) {
+ Int * tmp_local_eq_nb_val = local_eq_nb_val;
+ for (UInt i = 0; i < nb_nodes_per_element; ++i) {
+ UInt n = conn_val[i];
+ for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
+ /**
+ * !!!!!!Careful!!!!!! This is a ugly fix. @todo this is a
+ * very ugly fix, because the offset for the global
+ * equation number, where the dof will be assembled, is
+ * hardcoded. In the future a class dof manager has to be
+ * added to Akantu to handle the mapping between the dofs
+ * and the equation numbers
+ *
+ */
+
+ *tmp_local_eq_nb_val++ = eq_nb_val[n * nb_degree_of_freedom + d] - (dof_synchronizer.isPureGhostDOF(n * nb_degree_of_freedom + d) ? nb_global_dofs : 0);
+
+ }
+ }
+
+
+ for (UInt i = 0; i < size_mat; ++i) {
+ Int c_irn = local_eq_nb_val[i];
+ UInt j_start = 0;
+ for (UInt j = j_start; j < size_mat; ++j) {
+ Int c_jcn = local_eq_nb_val[j];
+ index_pair(0) = c_irn;
+ index_pair(1) = c_jcn;
+ AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index_pair.storage());
+ if (index_pair(0) >= first_global_index && index_pair(0) < first_global_index + this->local_size) {
+ KeyCOO irn_jcn = keyPETSc(c_irn, c_jcn);
+ irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
+
+ if (irn_jcn_k_it == irn_jcn_k.end()) {
+ irn_jcn_k[irn_jcn] = nb_non_zero;
+
+
+ // check if node is slave node
+ if (index_pair(1) >= first_global_index && index_pair(1) < first_global_index + this->local_size)
+ this->d_nnz(index_pair(0) - first_global_index) += 1;
+ else
+ this->o_nnz(index_pair(0) - first_global_index) += 1;
+ nb_non_zero++;
+
+ }
+ }
+
+ }
+
+ }
+ conn_val += nb_nodes_per_element;
+ }
+
+ delete [] local_eq_nb_val;
+ }
+ }
+
+
+
+ // /// for pbc @todo correct it for parallel
+ // if(StaticCommunicator::getStaticCommunicator().getNbProc() == 1) {
+ // for (UInt i = 0; i < size; ++i) {
+ // KeyCOO irn_jcn = key(i, i);
+ // irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
+ // if(irn_jcn_k_it == irn_jcn_k.end()) {
+ // irn_jcn_k[irn_jcn] = nb_non_zero;
+ // irn.push_back(i + 1);
+ // jcn.push_back(i + 1);
+ // nb_non_zero++;
+ // }
+ // }
+ // }
+
+
+
+ // std::string mat_type;
+ // mat_type.resize(20, 'a');
+ // std::cout << "MatType: " << mat_type << std::endl;
+ // const char * mat_type_ptr = mat_type.c_str();
+ MatType type;
+ MatGetType(this->petsc_matrix_wrapper->mat, &type);
+ /// std::cout << "the matrix type is: " << type << std::endl;
+ /**
+ * PETSc will use only one of the following preallocation commands
+ * depending on the matrix type and ignore the rest. Note that for
+ * the block matrix format a block size of 1 is used. This might
+ * result in bad performance. @todo For better results implement
+ * buildProfile() with larger block size.
+ *
+ */
+ /// build profile:
+ if (strcmp(type, MATSEQAIJ) == 0) {
+ ierr = MatSeqAIJSetPreallocation(this->petsc_matrix_wrapper->mat,
+ 0, d_nnz.storage()); CHKERRXX(ierr);
+ } else if ((strcmp(type, MATMPIAIJ) == 0)) {
+ ierr = MatMPIAIJSetPreallocation(this->petsc_matrix_wrapper->mat,
+ 0, d_nnz.storage(), 0,
+ o_nnz.storage()); CHKERRXX(ierr);
+ } else {
+ AKANTU_DEBUG_ERROR("The type " << type << " of PETSc matrix is not handled by"
+ << " akantu in the preallocation step");
+ }
+
+ //ierr = MatSeqSBAIJSetPreallocation(this->petsc_matrix_wrapper->mat, 1,
+ // 0, d_nnz.storage()); CHKERRXX(ierr);
+
+ if (this->sparse_matrix_type==_symmetric) {
+ /// set flag for symmetry to enable ICC/Cholesky preconditioner
+ ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_SYMMETRIC, PETSC_TRUE); CHKERRXX(ierr);
+ /// set flag for symmetric positive definite
+ ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_SPD, PETSC_TRUE); CHKERRXX(ierr);
+ }
+ /// once the profile has been build ignore any new nonzero locations
+ ierr = MatSetOption(this->petsc_matrix_wrapper->mat, MAT_NEW_NONZERO_LOCATIONS, PETSC_TRUE); CHKERRXX(ierr);
+
+ AKANTU_DEBUG_OUT();
+}
+
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Method to save the nonzero pattern and the values stored at each position
+ * @param filename name of the file in which the information will be stored
+ */
+void PETScMatrix::saveMatrix(const std::string & filename) const{
+ AKANTU_DEBUG_IN();
+
+ PetscErrorCode ierr;
+
+ /// create Petsc viewer
+ PetscViewer viewer;
+ ierr = PetscViewerASCIIOpen(this->petsc_matrix_wrapper->communicator, filename.c_str(), &viewer); CHKERRXX(ierr);
+
+ /// set the format
+ PetscViewerSetFormat(viewer, PETSC_VIEWER_DEFAULT); CHKERRXX(ierr);
+ /// save the matrix
+ /// @todo Write should be done in serial -> might cause problems
+ ierr = MatView(this->petsc_matrix_wrapper->mat, viewer); CHKERRXX(ierr);
+
+ /// destroy the viewer
+ ierr = PetscViewerDestroy(&viewer); CHKERRXX(ierr);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Method to add an Akantu sparse matrix to the PETSc matrix
+ * @param matrix Akantu sparse matrix to be added
+ * @param alpha the factor specifying how many times the matrix should be added
+ */
+void PETScMatrix::add(const SparseMatrix & matrix, Real alpha) {
+ PetscErrorCode ierr;
+ // AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
+ // "The two matrix don't have the same profiles");
+
+ Real val_to_add = 0;
+ Array<Int> index(2);
+ for (UInt n = 0; n < matrix.getNbNonZero(); ++n) {
+ UInt mat_to_add_offset = matrix.getOffset();
+ index(0) = matrix.getIRN()(n)-mat_to_add_offset;
+ index(1) = matrix.getJCN()(n)-mat_to_add_offset;
+ AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index.storage());
+ if (this->sparse_matrix_type == _symmetric && index(0) > index(1))
+ std::swap(index(0), index(1));
+
+ val_to_add = matrix.getA()(n) * alpha;
+ /// MatSetValue might be very slow for MATBAIJ, might need to use MatSetValuesBlocked
+ ierr = MatSetValue(this->petsc_matrix_wrapper->mat, index(0), index(1), val_to_add, ADD_VALUES); CHKERRXX(ierr);
+ /// chek if sparse matrix to be added is symmetric. In this case
+ /// the value also needs to be added at the transposed location in
+ /// the matrix because PETSc is using the full profile, also for symmetric matrices
+ if (matrix.getSparseMatrixType() == _symmetric && index(0) != index(1))
+ ierr = MatSetValue(this->petsc_matrix_wrapper->mat, index(1), index(0), val_to_add, ADD_VALUES); CHKERRXX(ierr);
+ }
+
+ this->performAssembly();
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Method to add another PETSc matrix to this PETSc matrix
+ * @param matrix PETSc matrix to be added
+ * @param alpha the factor specifying how many times the matrix should be added
+ */
+void PETScMatrix::add(const PETScMatrix & matrix, Real alpha) {
+ PetscErrorCode ierr;
+
+ ierr = MatAXPY(this->petsc_matrix_wrapper->mat, alpha, matrix.petsc_matrix_wrapper->mat, SAME_NONZERO_PATTERN); CHKERRXX(ierr);
+
+
+ this->performAssembly();
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * MatSetValues() generally caches the values. The matrix is ready to
+ * use only after MatAssemblyBegin() and MatAssemblyEnd() have been
+ * called. (http://www.mcs.anl.gov/petsc/)
+ */
+void PETScMatrix::performAssembly() {
+ PetscErrorCode ierr;
+ ierr = MatAssemblyBegin(this->petsc_matrix_wrapper->mat, MAT_FINAL_ASSEMBLY); CHKERRXX(ierr);
+ ierr = MatAssemblyEnd(this->petsc_matrix_wrapper->mat, MAT_FINAL_ASSEMBLY); CHKERRXX(ierr);
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Method is called when the static solver is destroyed, just before
+ * PETSc is finalized. So all PETSc objects need to be destroyed at
+ * this point.
+ */
+void PETScMatrix::beforeStaticSolverDestroy() {
+ AKANTU_DEBUG_IN();
+
+ try{
+ this->destroyInternalData();
+ } catch(...) {}
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+ /// destroy all the PETSc data structures used for this matrix
+void PETScMatrix::destroyInternalData() {
+ AKANTU_DEBUG_IN();
+
+ if(this->is_petsc_matrix_initialized) {
+
+ PetscErrorCode ierr;
+
+ ierr = MatDestroy(&(this->petsc_matrix_wrapper->mat)); CHKERRXX(ierr);
+ delete petsc_matrix_wrapper;
+
+ this->is_petsc_matrix_initialized = false;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+
+/* -------------------------------------------------------------------------- */
+/// access K(i, j). Works only for dofs on this processor!!!!
+Real PETScMatrix::operator()(UInt i, UInt j) const{
+ AKANTU_DEBUG_IN();
+
+ AKANTU_DEBUG_ASSERT(this->dof_synchronizer->isLocalOrMasterDOF(i) && this->dof_synchronizer->isLocalOrMasterDOF(j), "Operator works only for dofs on this processor");
+
+ Array<Int> index(2,1);
+ index(0) = this->dof_synchronizer->getDOFGlobalID(i);
+ index(1) = this->dof_synchronizer->getDOFGlobalID(j);
+ AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, 2, index.storage());
+
+ Real value = 0;
+
+ PetscErrorCode ierr;
+ /// @todo MatGetValue might be very slow for MATBAIJ, might need to use MatGetValuesBlocked
+ ierr = MatGetValues(this->petsc_matrix_wrapper->mat, 1, &index(0), 1, &index(1), &value); CHKERRXX(ierr);
+
+
+ AKANTU_DEBUG_OUT();
+
+
+ return value;
+
+}
+
+/* -------------------------------------------------------------------------- */
+/**
+ * Apply Dirichlet boundary conditions by zeroing the rows and columns which correspond to blocked dofs
+ * @param boundary array of booleans which are true if the dof at this position is blocked
+ * @param block_val the value in the diagonal entry of blocked rows
+ */
+void PETScMatrix::applyBoundary(const Array<bool> & boundary, Real block_val) {
+ AKANTU_DEBUG_IN();
+
+ PetscErrorCode ierr;
+
+ /// get the global equation numbers to find the rows that need to be zeroed for the blocked dofs
+ Int * eq_nb_val = dof_synchronizer->getGlobalDOFEquationNumbers().storage();
+
+ /// every processor calls the MatSetZero() only for his local or master dofs. This assures that not two processors or more try to zero the same row
+ UInt nb_component = boundary.getNbComponent();
+ UInt size = boundary.getSize();
+ Int nb_blocked_local_master_eq_nb = 0;
+ Array<Int> blocked_local_master_eq_nb(this->local_size);
+ Int * blocked_lm_eq_nb_ptr = blocked_local_master_eq_nb.storage();
+
+ for (UInt i = 0; i < size; ++i) {
+ for (UInt j = 0; j < nb_component; ++j) {
+ UInt local_dof = i * nb_component + j;
+ if (boundary(i, j) == true && this->dof_synchronizer->isLocalOrMasterDOF(local_dof)) {
+ Int global_eq_nb = *eq_nb_val;
+ *blocked_lm_eq_nb_ptr = global_eq_nb;
+ ++nb_blocked_local_master_eq_nb;
+ ++blocked_lm_eq_nb_ptr;
+ }
+ ++eq_nb_val;
+ }
+ }
+ blocked_local_master_eq_nb.resize(nb_blocked_local_master_eq_nb);
+
+
+ ierr = AOApplicationToPetsc(this->petsc_matrix_wrapper->ao, nb_blocked_local_master_eq_nb, blocked_local_master_eq_nb.storage() ); CHKERRXX(ierr);
+ ierr = MatZeroRowsColumns(this->petsc_matrix_wrapper->mat, nb_blocked_local_master_eq_nb, blocked_local_master_eq_nb.storage(), block_val, 0, 0); CHKERRXX(ierr);
+
+ this->performAssembly();
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+/// set all entries to zero while keeping the same nonzero pattern
+void PETScMatrix::clear() {
+ MatZeroEntries(this->petsc_matrix_wrapper->mat);
+}
+
+__END_AKANTU__
diff --git a/src/solver/petsc_matrix.hh b/src/solver/petsc_matrix.hh
new file mode 100644
index 000000000..d09eae806
--- /dev/null
+++ b/src/solver/petsc_matrix.hh
@@ -0,0 +1,146 @@
+/**
+ * @file petsc_matrix.hh
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Mon Jul 21 14:49:49 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_PETSC_MATRIX_HH__
+#define __AKANTU_PETSC_MATRIX_HH__
+
+/* -------------------------------------------------------------------------- */
+#include "sparse_matrix.hh"
+#include "static_communicator.hh"
+#include "static_solver.hh"
+
+/* -------------------------------------------------------------------------- */
+__BEGIN_AKANTU__
+
+class PETScMatrixWrapper;
+
+class PETScMatrix : public SparseMatrix, StaticSolverEventHandler {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+ PETScMatrix(UInt size,
+ const SparseMatrixType & sparse_matrix_type,
+ const ID & id = "petsc_matrix",
+ const MemoryID & memory_id = 0);
+
+ PETScMatrix(const SparseMatrix & matrix,
+ const ID & id = "petsc_matrix",
+ const MemoryID & memory_id = 0);
+
+ virtual ~PETScMatrix();
+
+
+private:
+ /// init internal PETSc matrix
+ void init();
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ /// set the matrix to 0
+ virtual void clear();
+
+ /// fill the profil of the matrix
+ virtual void buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom);
+
+ /// modify the matrix to "remove" the blocked dof
+ virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
+
+ /// save the matrix in a ASCII file format
+ virtual void saveMatrix(const std::string & filename) const;
+
+ /// add a sparse matrix assuming the profile are the same
+ virtual void add(const SparseMatrix & matrix, Real alpha);
+ /// add a petsc matrix assuming the profile are the same
+ virtual void add(const PETScMatrix & matrix, Real alpha);
+
+
+ virtual void beforeStaticSolverDestroy();
+
+ Real operator()(UInt i, UInt j) const;
+
+protected:
+ inline KeyCOO keyPETSc(UInt i, UInt j) const {
+ return std::make_pair(i, j);
+ }
+
+private:
+ virtual void destroyInternalData();
+
+ /// set the size of the PETSc matrix
+ void setSize();
+ void createGlobalAkantuToPETScMap(Int* local_master_eq_nbs_ptr);
+ void createLocalAkantuToPETScMap(const DOFSynchronizer & dof_synchronizer);
+ /// perform assembly so that matrix is ready for use
+ void performAssembly();
+ /* ------------------------------------------------------------------------ */
+ /* Accessors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ AKANTU_GET_MACRO(PETScMatrixWrapper, petsc_matrix_wrapper, PETScMatrixWrapper*);
+ AKANTU_GET_MACRO(LocalSize, local_size, Int);
+ /// AKANTU_GET_MACRO(LocalSize, local_size, Int);
+
+
+public:
+
+ /* ------------------------------------------------------------------------ */
+ /* Class Members */
+ /* ------------------------------------------------------------------------ */
+
+
+private:
+ /// store the PETSc structures
+ PETScMatrixWrapper * petsc_matrix_wrapper;
+
+ /// size of the diagonal part of the matrix partition
+ Int local_size;
+
+ /// number of nonzeros in every row of the diagonal part
+ Array<Int> d_nnz;
+
+ /// number of nonzeros in every row of the off-diagonal part
+ Array<Int> o_nnz;
+
+ /// the global index of the first local row
+ Int first_global_index;
+
+ /// bool to indicate if the matrix data has been initialized by calling MatCreate
+
+ bool is_petsc_matrix_initialized;
+
+};
+
+__END_AKANTU__
+
+#endif /* __AKANTU_PETSC_MATRIX_HH__ */
diff --git a/src/solver/petsc_wrapper.hh b/src/solver/petsc_wrapper.hh
new file mode 100644
index 000000000..10ce09906
--- /dev/null
+++ b/src/solver/petsc_wrapper.hh
@@ -0,0 +1,73 @@
+/**
+ * @file petsc_wrapper.hh
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Mon Jul 21 17:40:41 2014
+ *
+ * @brief Wrapper of PETSc structures
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#ifndef __AKANTU_PETSC_WRAPPER_HH__
+#define __AKANTU_PETSC_WRAPPER_HH__
+
+/* -------------------------------------------------------------------------- */
+#include <mpi.h>
+#include <petscmat.h>
+#include <petscvec.h>
+#include <petscao.h>
+#include <petscis.h>
+#include <petscksp.h>
+
+__BEGIN_AKANTU__
+
+struct PETScMatrixWrapper {
+ Mat mat;
+ AO ao;
+ ISLocalToGlobalMapping mapping;
+ /// pointer to the MPI communicator for PETSc commands
+ MPI_Comm communicator;
+};
+
+struct PETScSolverWrapper {
+ KSP ksp;
+ Vec solution;
+ Vec rhs;
+ /// pointer to the MPI communicator for PETSc commands
+ MPI_Comm communicator;
+};
+
+#if not defined(PETSC_CLANGUAGE_CXX)
+extern int aka_PETScError(int ierr);
+
+# define CHKERRXX(x) do { \
+ int error = aka_PETScError(x); \
+ if(error != 0) { \
+ AKANTU_EXCEPTION("Error in PETSC"); \
+ } \
+ } while(0)
+
+#endif
+
+__END_AKANTU__
+
+#endif /* __AKANTU_PETSC_WRAPPER_HH__ */
diff --git a/src/solver/solver.cc b/src/solver/solver.cc
index 865e7fbfa..2cb5865f9 100644
--- a/src/solver/solver.cc
+++ b/src/solver/solver.cc
@@ -1,59 +1,88 @@
/**
* @file solver.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Wed Nov 13 2013
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "solver.hh"
+#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
SolverOptions _solver_no_options(true);
/* -------------------------------------------------------------------------- */
Solver::Solver(SparseMatrix & matrix,
const ID & id,
const MemoryID & memory_id) :
- Memory(id, memory_id), matrix(&matrix), is_matrix_allocated(false), mesh(NULL),
- communicator(StaticCommunicator::getStaticCommunicator()){
+ Memory(id, memory_id), StaticSolverEventHandler(),
+ matrix(&matrix),
+ is_matrix_allocated(false),
+ mesh(NULL),
+ communicator(StaticCommunicator::getStaticCommunicator()),
+ solution(NULL),
+ synch_registry(NULL) {
AKANTU_DEBUG_IN();
-
+ StaticSolver::getStaticSolver().registerEventHandler(*this);
+ //createSynchronizerRegistry();
+ this->synch_registry = new SynchronizerRegistry(*this);
+ synch_registry->registerSynchronizer(this->matrix->getDOFSynchronizer(), _gst_solver_solution);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Solver::~Solver() {
AKANTU_DEBUG_IN();
+ this->destroyInternalData();
+ delete synch_registry;
+ StaticSolver::getStaticSolver().unregisterEventHandler(*this);
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void Solver::beforeStaticSolverDestroy() {
+ AKANTU_DEBUG_IN();
+
+ try{
+ this->destroyInternalData();
+ } catch(...) {}
+
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
+void Solver::createSynchronizerRegistry() {
+ //this->synch_registry = new SynchronizerRegistry(this);
+}
+
+
__END_AKANTU__
diff --git a/src/solver/solver.hh b/src/solver/solver.hh
index 2b148aea6..2667fb700 100644
--- a/src/solver/solver.hh
+++ b/src/solver/solver.hh
@@ -1,125 +1,167 @@
/**
* @file solver.hh
*
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_HH__
#define __AKANTU_SOLVER_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_memory.hh"
#include "aka_array.hh"
#include "sparse_matrix.hh"
#include "mesh.hh"
#include "static_communicator.hh"
+#include "static_solver.hh"
+#include "data_accessor.hh"
+#include "synchronizer_registry.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class SolverOptions {
public:
- SolverOptions(bool no_option = false) : no_option(no_option) { }
+ SolverOptions(bool no_option = false) // : no_option(no_option)
+ { }
virtual ~SolverOptions() {}
private:
- bool no_option;
+ //bool no_option;
};
extern SolverOptions _solver_no_options;
-class Solver : protected Memory {
+class Solver : protected Memory,
+ public StaticSolverEventHandler,
+ public DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
Solver(SparseMatrix & matrix,
const ID & id = "solver",
const MemoryID & memory_id = 0);
virtual ~Solver();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// initialize the solver
virtual void initialize(SolverOptions & options = _solver_no_options) = 0;
+ virtual void setOperators() {};
virtual void analysis() {};
virtual void factorize() {};
/// solve
virtual void solve(Array<Real> & solution) = 0;
virtual void solve() = 0;
- virtual void setRHS(const Array<Real> & rhs) = 0;
+ virtual void setRHS(Array<Real> & rhs) = 0;
/// function to print the contain of the class
// virtual void printself(std::ostream & stream, int indent = 0) const;
+protected:
+ virtual void destroyInternalData() {};
+
+public:
+ virtual void beforeStaticSolverDestroy();
+
+ void createSynchronizerRegistry();
+ /* ------------------------------------------------------------------------ */
+ /* Data Accessor inherited members */
+ /* ------------------------------------------------------------------------ */
+public:
+ inline virtual UInt getNbDataForDOFs(const Array <UInt> & dofs,
+ SynchronizationTag tag) const;
+
+ inline virtual void packDOFData(CommunicationBuffer & buffer,
+ const Array<UInt> & dofs,
+ SynchronizationTag tag) const;
+
+ inline virtual void unpackDOFData(CommunicationBuffer & buffer,
+ const Array<UInt> & dofs,
+ SynchronizationTag tag);
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(RHS, *rhs, Array<Real> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// the matrix
SparseMatrix * matrix;
/// is sparse matrix allocated
bool is_matrix_allocated;
/// the right hand side
Array<Real> * rhs;
/// mesh
const Mesh * mesh;
/// pointer to the communicator
StaticCommunicator & communicator;
+
+ /// the solution obtained from the solve step
+ Array<Real> * solution;
+
+ /// synchronizer registry
+ SynchronizerRegistry * synch_registry;
+
};
+/* -------------------------------------------------------------------------- */
+/* inline functions */
+/* -------------------------------------------------------------------------- */
+
+#include "solver_inline_impl.cc"
__END_AKANTU__
#endif /* __AKANTU_SOLVER_HH__ */
diff --git a/src/solver/solver_inline_impl.cc b/src/solver/solver_inline_impl.cc
new file mode 100644
index 000000000..7c47a285c
--- /dev/null
+++ b/src/solver/solver_inline_impl.cc
@@ -0,0 +1,81 @@
+/**
+ * @file solver_inline_impl.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Thu Nov 13 14:43:41 2014
+ *
+ * @brief implementation of solver inline functions
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+inline UInt Solver::getNbDataForDOFs(const Array<UInt> & dofs,
+ SynchronizationTag tag) const {
+ AKANTU_DEBUG_IN();
+
+ UInt size = 0;
+
+ switch(tag) {
+ case _gst_solver_solution: {
+ size += dofs.getSize() * sizeof(Real);
+ break;
+ }
+ default: { }
+ }
+
+ AKANTU_DEBUG_OUT();
+ return size;
+}
+
+/* -------------------------------------------------------------------------- */
+inline void Solver::packDOFData(CommunicationBuffer & buffer,
+ const Array<UInt> & dofs,
+ SynchronizationTag tag) const {
+ AKANTU_DEBUG_IN();
+
+ switch(tag) {
+ case _gst_solver_solution: {
+ packDOFDataHelper(*solution, buffer, dofs);
+ break;
+ }
+ default: {
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+inline void Solver::unpackDOFData(CommunicationBuffer & buffer,
+ const Array<UInt> & dofs,
+ SynchronizationTag tag) {
+ AKANTU_DEBUG_IN();
+
+ switch(tag) {
+ case _gst_solver_solution: {
+ unpackDOFDataHelper(*solution, buffer, dofs);
+ break;
+ }
+ default: {
+ }
+ }
+
+ AKANTU_DEBUG_OUT();
+}
diff --git a/src/solver/solver_mumps.cc b/src/solver/solver_mumps.cc
index 69bbb50cb..217ed1745 100644
--- a/src/solver/solver_mumps.cc
+++ b/src/solver/solver_mumps.cc
@@ -1,392 +1,389 @@
/**
* @file solver_mumps.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Mon Sep 15 2014
*
* @brief implem of SolverMumps class
*
* @section LICENSE
*
* Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
* @section DESCRIPTION
*
* @subsection Ctrl_param Control parameters
*
* ICNTL(1),
* ICNTL(2),
* ICNTL(3) : output streams for error, diagnostics, and global messages
*
* ICNTL(4) : verbose level : 0 no message - 4 all messages
*
* ICNTL(5) : type of matrix, 0 assembled, 1 elementary
*
* ICNTL(6) : control the permutation and scaling(default 7) see mumps doc for
* more information
*
* ICNTL(7) : determine the pivot order (default 7) see mumps doc for more
* information
*
* ICNTL(8) : describe the scaling method used
*
* ICNTL(9) : 1 solve A x = b, 0 solve At x = b
*
* ICNTL(10) : number of iterative refinement when NRHS = 1
*
* ICNTL(11) : > 0 return statistics
*
* ICNTL(12) : only used for SYM = 2, ordering strategy
*
* ICNTL(13) :
*
* ICNTL(14) : percentage of increase of the estimated working space
*
* ICNTL(15-17) : not used
*
* ICNTL(18) : only used if ICNTL(5) = 0, 0 matrix centralized, 1 structure on
* host and mumps give the mapping, 2 structure on host and distributed matrix
* for facto, 3 distributed matrix
*
* ICNTL(19) : > 0, Shur complement returned
*
* ICNTL(20) : 0 rhs dense, 1 rhs sparse
*
* ICNTL(21) : 0 solution in rhs, 1 solution distributed in ISOL_loc and SOL_loc
* allocated by user
*
* ICNTL(22) : 0 in-core, 1 out-of-core
*
* ICNTL(23) : maximum memory allocatable by mumps pre proc
*
* ICNTL(24) : controls the detection of "null pivot rows"
*
* ICNTL(25) :
*
* ICNTL(26) :
*
* ICNTL(27) :
*
* ICNTL(28) : 0 automatic choice, 1 sequential analysis, 2 parallel analysis
*
* ICNTL(29) : 0 automatic choice, 1 PT-Scotch, 2 ParMetis
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#if defined(AKANTU_USE_MPI)
# include "static_communicator_mpi.hh"
# include "mpi_type_wrapper.hh"
#endif
#include "solver_mumps.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
// static std::ostream & operator <<(std::ostream & stream, const DMUMPS_STRUC_C & _this) {
// stream << "DMUMPS Data [" << std::endl;
// stream << " + job : " << _this.job << std::endl;
// stream << " + par : " << _this.par << std::endl;
// stream << " + sym : " << _this.sym << std::endl;
// stream << " + comm_fortran : " << _this.comm_fortran << std::endl;
// stream << " + nz : " << _this.nz << std::endl;
// stream << " + irn : " << _this.irn << std::endl;
// stream << " + jcn : " << _this.jcn << std::endl;
// stream << " + nz_loc : " << _this.nz_loc << std::endl;
// stream << " + irn_loc : " << _this.irn_loc << std::endl;
// stream << " + jcn_loc : " << _this.jcn_loc << std::endl;
// stream << "]";
// return stream;
// }
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SolverMumps::SolverMumps(SparseMatrix & matrix,
const ID & id,
const MemoryID & memory_id) :
Solver(matrix, id, memory_id), is_mumps_data_initialized(false), rhs_is_local(true) {
AKANTU_DEBUG_IN();
#ifdef AKANTU_USE_MPI
parallel_method = SolverMumpsOptions::_fully_distributed;
#else //AKANTU_USE_MPI
parallel_method = SolverMumpsOptions::_not_parallel;
#endif //AKANTU_USE_MPI
- CommunicatorEventHandler & comm_event_handler = *this;
-
- communicator.registerEventHandler(comm_event_handler);
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SolverMumps::~SolverMumps() {
AKANTU_DEBUG_IN();
- this->destroyMumpsData();
+
+ this->destroyInternalData();
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void SolverMumps::destroyMumpsData() {
+void SolverMumps::destroyInternalData() {
AKANTU_DEBUG_IN();
-
+
if(this->is_mumps_data_initialized) {
this->mumps_data.job = _smj_destroy; // destroy
dmumps_c(&this->mumps_data);
this->is_mumps_data_initialized = false;
}
AKANTU_DEBUG_OUT();
}
-/* -------------------------------------------------------------------------- */
-void SolverMumps::onCommunicatorFinalize(const StaticCommunicator & comm) {
- AKANTU_DEBUG_IN();
-
- try{
- destroyMumpsData();
- } catch(...) {}
-
- AKANTU_DEBUG_OUT();
-}
/* -------------------------------------------------------------------------- */
void SolverMumps::initMumpsData() {
// Default Scaling
icntl(8) = 77;
// Assembled matrix
icntl(5) = 0;
/// Default centralized dense second member
icntl(20) = 0;
icntl(21) = 0;
icntl(28) = 0; //automatic choice for analysis analysis
switch(this->parallel_method) {
case SolverMumpsOptions::_fully_distributed:
icntl(18) = 3; //fully distributed
this->mumps_data.nz_loc = matrix->getNbNonZero();
this->mumps_data.irn_loc = matrix->getIRN().storage();
this->mumps_data.jcn_loc = matrix->getJCN().storage();
break;
case SolverMumpsOptions::_not_parallel:
case SolverMumpsOptions::_master_slave_distributed:
icntl(18) = 0; //centralized
if(prank == 0) {
this->mumps_data.nz = matrix->getNbNonZero();
this->mumps_data.irn = matrix->getIRN().storage();
this->mumps_data.jcn = matrix->getJCN().storage();
} else {
this->mumps_data.nz = 0;
this->mumps_data.irn = NULL;
this->mumps_data.jcn = NULL;
}
break;
default:
AKANTU_DEBUG_ERROR("This case should not happen!!");
}
}
/* -------------------------------------------------------------------------- */
void SolverMumps::initialize(SolverOptions & options) {
AKANTU_DEBUG_IN();
if(SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options)) {
this->parallel_method = opt->parallel_method;
}
this->mumps_data.par = 1; // The host is part of computations
switch(this->parallel_method) {
case SolverMumpsOptions::_not_parallel: break;
case SolverMumpsOptions::_master_slave_distributed:
this->mumps_data.par = 0; // The host is not part of the computations
case SolverMumpsOptions::_fully_distributed:
#ifdef AKANTU_USE_MPI
const StaticCommunicatorMPI & mpi_st_comm = dynamic_cast<const StaticCommunicatorMPI &>(communicator.getRealStaticCommunicator());
this->mumps_data.comm_fortran = MPI_Comm_c2f(mpi_st_comm.getMPITypeWrapper().getMPICommunicator());
#endif
break;
}
this->mumps_data.sym = 2 * (matrix->getSparseMatrixType() == _symmetric);
this->prank = communicator.whoAmI();
this->mumps_data.job = _smj_initialize; //initialize
dmumps_c(&this->mumps_data);
this->is_mumps_data_initialized = true;
/* ------------------------------------------------------------------------ */
UInt size = matrix->getSize();
if(prank == 0) {
std::stringstream sstr_rhs; sstr_rhs << id << ":rhs";
this->rhs = &(alloc<Real>(sstr_rhs.str(), size, 1, 0.));
} else {
this->rhs = NULL;
}
this->mumps_data.nz_alloc = 0;
this->mumps_data.n = size;
/* ------------------------------------------------------------------------ */
// Output setup
if(AKANTU_DEBUG_TEST(dblTrace)) {
icntl(1) = 6;
icntl(2) = 2;
icntl(3) = 2;
icntl(4) = 4;
} else {
/// No outputs
icntl(1) = 6; // error output
icntl(2) = 0; // dignostics output
icntl(3) = 0; // informations
icntl(4) = 0; // no outputs
}
if(AKANTU_DEBUG_TEST(dblDump)) {
strcpy(this->mumps_data.write_problem, "mumps_matrix.mtx");
}
this->analysis();
// icntl(14) = 80;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
-void SolverMumps::setRHS(const Array<Real> & rhs) {
+void SolverMumps::setRHS(Array<Real> & rhs) {
if(prank == 0) {
- std::copy(rhs.storage(), rhs.storage() + this->rhs->getSize(), this->rhs->storage());
+ //std::copy(rhs.storage(), rhs.storage() + this->rhs->getSize(), this->rhs->storage());
- // DebugLevel dbl = debug::getDebugLevel();
-// debug::setDebugLevel(dblError);
-// matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
-// debug::setDebugLevel(dbl);
+ DebugLevel dbl = debug::getDebugLevel();
+ debug::setDebugLevel(dblError);
+ matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
+ debug::setDebugLevel(dbl);
} else {
this->matrix->getDOFSynchronizer().gather(rhs, 0);
}
}
/* -------------------------------------------------------------------------- */
void SolverMumps::analysis() {
AKANTU_DEBUG_IN();
initMumpsData();
this->mumps_data.job = _smj_analyze; //analyze
dmumps_c(&this->mumps_data);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::factorize() {
AKANTU_DEBUG_IN();
if(parallel_method == SolverMumpsOptions::_fully_distributed)
this->mumps_data.a_loc = this->matrix->getA().storage();
else {
if(prank == 0)
this->mumps_data.a = this->matrix->getA().storage();
}
if(prank == 0) {
this->mumps_data.rhs = this->rhs->storage();
}
this->mumps_data.job = _smj_factorize; // factorize
dmumps_c(&this->mumps_data);
this->printError();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::solve() {
AKANTU_DEBUG_IN();
if(prank == 0) {
this->mumps_data.rhs = this->rhs->storage();
}
this->mumps_data.job = _smj_solve; // solve
dmumps_c(&this->mumps_data);
this->printError();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::solve(Array<Real> & solution) {
AKANTU_DEBUG_IN();
this->solve();
if(prank == 0) {
-// matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
- std::copy(this->rhs->storage(), this->rhs->storage() + this->rhs->getSize(), solution.storage());
+ matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
+// std::copy(this->rhs->storage(), this->rhs->storage() + this->rhs->getSize(), solution.storage());
} else {
this->matrix->getDOFSynchronizer().scatter(solution, 0);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SolverMumps::printError() {
- if(info(1) != 0) {
- communicator.allReduce(&info(1), 1, _so_min);
- switch(info(1)) {
+ Int _info_v[2];
+ _info_v[0] = info(1); // to get errors
+ _info_v[1] = -info(1); // to get warnings
+ communicator.allReduce(_info_v, 2, _so_min);
+ _info_v[1] = -_info_v[1];
+
+ if(_info_v[0] < 0) { // < 0 is an error
+ switch(_info_v[0]) {
case -10: AKANTU_DEBUG_ERROR("The matrix is singular"); break;
case -9: {
icntl(14) += 10;
if(icntl(14) != 90) {
//std::cout << "Dynamic memory increase of 10%" << std::endl;
+ AKANTU_DEBUG_WARNING("MUMPS dynamic memory is insufficient it will be increased of 10%");
this->analysis();
this->factorize();
this->solve();
} else {
AKANTU_DEBUG_ERROR("The MUMPS workarray is too small INFO(2)=" << info(2) << "No further increase possible"); break;
}
}
default:
- AKANTU_DEBUG_ERROR("Error in mumps during solve process, check mumps user guide INFO(1) ="
- << info(1));
+ AKANTU_DEBUG_ERROR("Error in mumps during solve process, check mumps user guide INFO(1) = "
+ << _info_v[1]);
}
+ } else if (_info_v[1] > 0) {
+ AKANTU_DEBUG_WARNING("Warning in mumps during solve process, check mumps user guide INFO(1) = "
+ << _info_v[1]);
}
}
__END_AKANTU__
diff --git a/src/solver/solver_mumps.hh b/src/solver/solver_mumps.hh
index c8fc336e0..c843439d1 100644
--- a/src/solver/solver_mumps.hh
+++ b/src/solver/solver_mumps.hh
@@ -1,157 +1,154 @@
/**
* @file solver_mumps.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Mon Sep 15 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SOLVER_MUMPS_HH__
#define __AKANTU_SOLVER_MUMPS_HH__
#include <dmumps_c.h>
#include "solver.hh"
#include "static_communicator.hh"
__BEGIN_AKANTU__
class SolverMumpsOptions : public SolverOptions {
public:
enum ParallelMethod {
_not_parallel,
_fully_distributed,
_master_slave_distributed
};
SolverMumpsOptions(ParallelMethod parallel_method = _fully_distributed) :
SolverOptions(),
parallel_method(parallel_method) { }
private:
friend class SolverMumps;
ParallelMethod parallel_method;
};
-class SolverMumps : public Solver, public CommunicatorEventHandler {
+class SolverMumps : public Solver {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
SolverMumps(SparseMatrix & sparse_matrix,
const ID & id = "solver_mumps",
const MemoryID & memory_id = 0);
virtual ~SolverMumps();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// build the profile and do the analysis part
- void initialize(SolverOptions & options = _solver_no_options);
+ virtual void initialize(SolverOptions & options = _solver_no_options);
void initializeSlave(SolverOptions & options = _solver_no_options);
/// analysis (symbolic facto + permutations)
- void analysis();
+ virtual void analysis();
/// factorize the matrix
- void factorize();
+ virtual void factorize();
/// solve the system
- void solve(Array<Real> & solution);
- void solve();
+ virtual void solve(Array<Real> & solution);
+ virtual void solve();
void solveSlave();
- virtual void setRHS(const Array<Real> & rhs);
-
-
- virtual void onCommunicatorFinalize(const StaticCommunicator & communicator);
+ virtual void setRHS(Array<Real> & rhs);
private:
/// print the error if any happened in mumps
void printError();
/// clean the mumps info
- void destroyMumpsData();
+ virtual void destroyInternalData();
/// set internal values;
void initMumpsData();
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
private:
/// access the control variable
inline Int & icntl(UInt i) {
return mumps_data.icntl[i - 1];
}
/// access the results info
inline Int & info(UInt i) {
return mumps_data.info[i - 1];
}
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
/// mumps data
DMUMPS_STRUC_C mumps_data;
/// specify if the mumps_data are initialized or not
bool is_mumps_data_initialized;
UInt prank;
/* ------------------------------------------------------------------------ */
/* Local types */
/* ------------------------------------------------------------------------ */
private:
SolverMumpsOptions::ParallelMethod parallel_method;
bool rhs_is_local;
enum SolverMumpsJob {
_smj_initialize = -1,
_smj_analyze = 1,
_smj_factorize = 2,
_smj_solve = 3,
_smj_analyze_factorize = 4,
_smj_factorize_solve = 5,
_smj_complete = 6, // analyze, factorize, solve
_smj_destroy = -2
};
};
__END_AKANTU__
#endif /* __AKANTU_SOLVER_MUMPS_HH__ */
diff --git a/src/solver/solver_petsc.cc b/src/solver/solver_petsc.cc
new file mode 100644
index 000000000..0c7f9f61e
--- /dev/null
+++ b/src/solver/solver_petsc.cc
@@ -0,0 +1,1109 @@
+/**
+ * @file solver_petsc.cc
+ *
+ * @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
+ *
+ * @brief Solver class implementation for the petsc solver
+ *
+ * @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 <petscksp.h>
+#include "solver_petsc.hh"
+#include "petsc_wrapper.hh"
+#include "petsc_matrix.hh"
+#include "static_communicator.hh"
+#include "static_communicator_mpi.hh"
+#include "mpi_type_wrapper.hh"
+#include "dof_synchronizer.hh"
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+SolverPETSc::SolverPETSc(SparseMatrix & matrix,
+ const ID & id,
+ const MemoryID & memory_id) :
+ Solver(matrix, id, memory_id), is_petsc_data_initialized(false),
+ petsc_solver_wrapper(new PETScSolverWrapper) {
+}
+
+/* -------------------------------------------------------------------------- */
+SolverPETSc::~SolverPETSc() {
+ AKANTU_DEBUG_IN();
+
+ this->destroyInternalData();
+
+ AKANTU_DEBUG_OUT();
+ }
+/* -------------------------------------------------------------------------- */
+void SolverPETSc::destroyInternalData() {
+ AKANTU_DEBUG_IN();
+
+ if(this->is_petsc_data_initialized) {
+ PetscErrorCode ierr;
+ ierr = KSPDestroy(&(this->petsc_solver_wrapper->ksp)); CHKERRXX(ierr);
+ ierr = VecDestroy(&(this->petsc_solver_wrapper->rhs)); CHKERRXX(ierr);
+ ierr = VecDestroy(&(this->petsc_solver_wrapper->solution)); CHKERRXX(ierr);
+ delete petsc_solver_wrapper;
+
+ this->is_petsc_data_initialized = false;
+ }
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolverPETSc::initialize(SolverOptions & options) {
+ AKANTU_DEBUG_IN();
+
+#if defined(AKANTU_USE_MPI)
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+ const StaticCommunicatorMPI & mpi_st_comm =
+ dynamic_cast<const StaticCommunicatorMPI &>(comm.getRealStaticCommunicator());
+ this->petsc_solver_wrapper->communicator = mpi_st_comm.getMPITypeWrapper().getMPICommunicator();
+#else
+ this->petsc_solver_wrapper->communicator = PETSC_COMM_SELF;
+#endif
+
+ PetscErrorCode ierr;
+ PETScMatrix * petsc_matrix = static_cast<PETScMatrix*>(this->matrix);
+ /// create a solver context
+ ierr = KSPCreate(this->petsc_solver_wrapper->communicator, &(this->petsc_solver_wrapper->ksp)); CHKERRXX(ierr);
+
+ /// create the PETSc vector for the right-hand side
+ ierr = VecCreate(this->petsc_solver_wrapper->communicator, &(this->petsc_solver_wrapper->rhs)); CHKERRXX(ierr);
+
+ ierr = VecSetSizes((this->petsc_solver_wrapper->rhs),
+ petsc_matrix->getLocalSize(),
+ petsc_matrix->getSize()); CHKERRXX(ierr);
+ ierr = VecSetFromOptions((this->petsc_solver_wrapper->rhs)); CHKERRXX(ierr);
+
+ /// create the PETSc vector for the solution
+ ierr = VecDuplicate((this->petsc_solver_wrapper->rhs), &(this->petsc_solver_wrapper->solution)); CHKERRXX(ierr);
+ /// set the solution to zero
+ ierr = VecZeroEntries(this->petsc_solver_wrapper->solution);
+ this->is_petsc_data_initialized = true;
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolverPETSc::setRHS(Array<Real> & rhs) {
+ PetscErrorCode ierr;
+ PETScMatrix * petsc_matrix = static_cast<PETScMatrix*>(this->matrix);
+
+ UInt nb_component = rhs.getNbComponent();
+ UInt size = rhs.getSize();
+ for (UInt i = 0; i < size; ++i) {
+ for (UInt j = 0; j < nb_component; ++j) {
+ UInt i_local = i * nb_component + j;
+ if (this->matrix->getDOFSynchronizer().isLocalOrMasterDOF(i_local)) {
+ Int i_global = this->matrix->getDOFSynchronizer().getDOFGlobalID(i_local);
+ AOApplicationToPetsc(petsc_matrix->getPETScMatrixWrapper()->ao, 1, &(i_global) );
+ ierr = VecSetValue((this->petsc_solver_wrapper->rhs), i_global, rhs(i,j), INSERT_VALUES); CHKERRXX(ierr);
+ }
+ }
+ }
+
+ ierr = VecAssemblyBegin(this->petsc_solver_wrapper->rhs); CHKERRXX(ierr);
+ ierr = VecAssemblyEnd(this->petsc_solver_wrapper->rhs); CHKERRXX(ierr);
+ /// ierr = VecCopy((this->petsc_solver_wrapper->rhs), (this->petsc_solver_wrapper->solution)); CHKERRXX(ierr);
+
+
+}
+
+/* -------------------------------------------------------------------------- */
+void SolverPETSc::solve() {
+ AKANTU_DEBUG_IN();
+
+ PetscErrorCode ierr;
+ ierr = KSPSolve(this->petsc_solver_wrapper->ksp, this->petsc_solver_wrapper->rhs, this->petsc_solver_wrapper->solution); CHKERRXX(ierr);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolverPETSc::solve(Array<Real> & solution) {
+ AKANTU_DEBUG_IN();
+
+ this->solution = &solution;
+ this->solve();
+
+ PetscErrorCode ierr;
+ PETScMatrix * petsc_matrix = static_cast<PETScMatrix*>(this->matrix);
+
+
+ // ierr = VecGetOwnershipRange(this->petsc_solver_wrapper->solution, solution_begin, solution_end); CHKERRXX(ierr);
+ // ierr = VecGetArray(this->petsc_solver_wrapper->solution, PetscScalar **array); CHKERRXX(ierr);
+ UInt nb_component = solution.getNbComponent();
+ UInt size = solution.getSize();
+
+ for (UInt i = 0; i < size; ++i) {
+ for (UInt j = 0; j < nb_component; ++j) {
+ UInt i_local = i * nb_component + j;
+ if (this->matrix->getDOFSynchronizer().isLocalOrMasterDOF(i_local)) {
+ Int i_global = this->matrix->getDOFSynchronizer().getDOFGlobalID(i_local);
+ ierr = AOApplicationToPetsc(petsc_matrix->getPETScMatrixWrapper()->ao, 1, &(i_global) ); CHKERRXX(ierr);
+ ierr = VecGetValues(this->petsc_solver_wrapper->solution, 1, &i_global, &solution(i,j)); CHKERRXX(ierr);
+
+ }
+ }
+ }
+ synch_registry->synchronize(_gst_solver_solution);
+
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void SolverPETSc::setOperators() {
+ AKANTU_DEBUG_IN();
+ PetscErrorCode ierr;
+ /// set the matrix that defines the linear system and the matrix for preconditioning (here they are the same)
+ PETScMatrix * petsc_matrix = static_cast<PETScMatrix*>(this->matrix);
+
+#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
+ ierr = KSPSetOperators(this->petsc_solver_wrapper->ksp, petsc_matrix->getPETScMatrixWrapper()->mat, petsc_matrix->getPETScMatrixWrapper()->mat); CHKERRXX(ierr);
+#else
+ ierr = KSPSetOperators(this->petsc_solver_wrapper->ksp, petsc_matrix->getPETScMatrixWrapper()->mat, petsc_matrix->getPETScMatrixWrapper()->mat, SAME_NONZERO_PATTERN); CHKERRXX(ierr);
+#endif
+ /// If this is not called the solution vector is zeroed in the call to KSPSolve().
+ ierr = KSPSetInitialGuessNonzero(this->petsc_solver_wrapper->ksp, PETSC_TRUE); CHKERRXX(ierr);
+ ierr = KSPSetFromOptions(this->petsc_solver_wrapper->ksp); CHKERRXX(ierr);
+
+ AKANTU_DEBUG_OUT();
+}
+/* -------------------------------------------------------------------------- */
+// void finalize_petsc() {
+
+// static bool finalized = false;
+// if (!finalized) {
+
+// cout<<"*** INFO *** PETSc is finalizing..."<<endl;
+// // finalize PETSc
+// PetscErrorCode ierr = PetscFinalize();CHKERRCONTINUE(ierr);
+// finalized = true;
+// }
+// }
+
+
+// SolverPETSc::sparse_vector_type
+// SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& AA,
+// const SolverPETSc::sparse_vector_type& bb) {
+
+
+// #ifdef CPPUTILS_VERBOSE
+// // parallel output stream
+// Output_stream out;
+// // timer
+// cpputils::ctimer timer;
+// out<<"Inside PETSc solver: "<<timer<<endl;
+// #endif
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Inside operator()(const sparse_matrix_type&, const sparse_vector_type&)... "<<timer<<endl;
+// #endif
+
+// assert(AA.rows() == bb.size());
+
+// // KSP ksp; //!< linear solver context
+
+// Vec b; /* RHS */
+// PC pc; /* preconditioner context */
+// PetscErrorCode ierr;
+// PetscInt nlocal;
+// PetscInt n = bb.size();
+// VecScatter ctx;
+
+// /*
+// Create vectors. Note that we form 1 vector from scratch and
+// then duplicate as needed. For this simple case let PETSc decide how
+// many elements of the vector are stored on each processor. The second
+// argument to VecSetSizes() below causes PETSc to decide.
+// */
+// ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRCONTINUE(ierr);
+// ierr = VecSetSizes(b,PETSC_DECIDE,n);CHKERRCONTINUE(ierr);
+// ierr = VecSetFromOptions(b);CHKERRCONTINUE(ierr);
+// if (!allocated_) {
+// ierr = VecDuplicate(b,&x_);CHKERRCONTINUE(ierr);
+// } else
+// VecZeroEntries(x_);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Vectors created... "<<timer<<endl;
+// #endif
+
+
+// /* Set hight-hand-side vector */
+// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
+// int row = it->first;
+// ierr = VecSetValues(b, 1, &row, &it->second, ADD_VALUES);
+// }
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Right hand side set... "<<timer<<endl;
+// #endif
+
+
+// /*
+// Assemble vector, using the 2-step process:
+// VecAssemblyBegin(), VecAssemblyEnd()
+// Computations can be done while messages are in transition
+// by placing code between these two statements.
+// */
+// ierr = VecAssemblyBegin(b);CHKERRCONTINUE(ierr);
+// ierr = VecAssemblyEnd(b);CHKERRCONTINUE(ierr);
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Right-hand-side vector assembled... "<<timer<<endl;
+
+// ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
+
+// Vec b_all;
+// ierr = VecScatterCreateToAll(b, &ctx, &b_all);CHKERRCONTINUE(ierr);
+// ierr = VecScatterBegin(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+// ierr = VecScatterEnd(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+
+// value_type nrm;
+// VecNorm(b_all,NORM_2,&nrm);
+// out<<" Norm of right hand side... "<<nrm<<endl;
+// #endif
+
+// /* Identify the starting and ending mesh points on each
+// processor for the interior part of the mesh. We let PETSc decide
+// above. */
+
+// // PetscInt rstart,rend;
+// // ierr = VecGetOwnershipRange(x_,&rstart,&rend);CHKERRCONTINUE(ierr);
+// ierr = VecGetLocalSize(x_,&nlocal);CHKERRCONTINUE(ierr);
+
+
+// /*
+// Create matrix. When using MatCreate(), the matrix format can
+// be specified at runtime.
+
+// Performance tuning note: For problems of substantial size,
+// preallocation of matrix memory is crucial for attaining good
+// performance. See the matrix chapter of the users manual for details.
+
+// We pass in nlocal as the "local" size of the matrix to force it
+// to have the same parallel layout as the vector created above.
+// */
+// if (!allocated_) {
+
+// ierr = MatCreate(PETSC_COMM_WORLD,&A_);CHKERRCONTINUE(ierr);
+// ierr = MatSetSizes(A_,nlocal,nlocal,n,n);CHKERRCONTINUE(ierr);
+// ierr = MatSetFromOptions(A_);CHKERRCONTINUE(ierr);
+// ierr = MatSetUp(A_);CHKERRCONTINUE(ierr);
+// } else {
+// // zero-out matrix
+// MatZeroEntries(A_);
+// }
+
+
+// /*
+// Assemble matrix.
+
+// The linear system is distributed across the processors by
+// chunks of contiguous rows, which correspond to contiguous
+// sections of the mesh on which the problem is discretized.
+// For matrix assembly, each processor contributes entries for
+// the part that it owns locally.
+// */
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Zeroed-out sparse matrix entries... "<<timer<<endl;
+// #endif
+
+// for (sparse_matrix_type::const_hash_iterator it = AA.map_.begin(); it != AA.map_.end(); ++it) {
+
+// // get subscripts
+// std::pair<size_t,size_t> subs = AA.unhash(it->first);
+// PetscInt row = subs.first;
+// PetscInt col = subs.second;
+// ierr = MatSetValues(A_, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
+// }
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Filled sparse matrix... "<<timer<<endl;
+// #endif
+
+
+
+
+// /* Assemble the matrix */
+// ierr = MatAssemblyBegin(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+// ierr = MatAssemblyEnd(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+
+
+// if (!allocated_) {
+// // set after the first MatAssemblyEnd
+// // ierr = MatSetOption(A_, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE);CHKERRCONTINUE(ierr);
+// ierr = MatSetOption(A_, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRCONTINUE(ierr);
+// }
+
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Sparse matrix assembled... "<<timer<<endl;
+// // view matrix
+// MatView(A_, PETSC_VIEWER_STDOUT_WORLD);
+
+// MatNorm(A_,NORM_FROBENIUS,&nrm);
+// out<<" Norm of stiffness matrix... "<<nrm<<endl;
+// #endif
+
+// /*
+// Set operators. Here the matrix that defines the linear system
+// also serves as the preconditioning matrix.
+// */
+// // ierr = KSPSetOperators(ksp,A_,A_,DIFFERENT_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
+// ierr = KSPSetOperators(ksp_,A_,A_,SAME_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
+
+
+// //
+// // /*
+// // Set runtime options, e.g.,
+// // -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
+// // These options will override those specified above as long as
+// // KSPSetFromOptions() is called _after_ any other customization
+// // routines.
+// // */
+// // ierr = KSPSetFromOptions(ksp);CHKERRCONTINUE(ierr);
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Solving system... "<<timer<<endl;
+// #endif
+
+
+// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Solve the linear system
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+// /*
+// Solve linear system
+// */
+// ierr = KSPSolve(ksp_,b,x_);CHKERRCONTINUE(ierr);
+
+
+// #ifdef CPPUTILS_VERBOSE
+
+// /*
+// View solver info; we could instead use the option -ksp_view to
+// print this info to the screen at the conclusion of KSPSolve().
+// */
+// ierr = KSPView(ksp_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
+
+// int iter;
+// KSPGetIterationNumber(ksp_, &iter);
+// out<<" System solved in "<<iter<<" iterations... "<<timer<<endl;
+// KSPConvergedReason reason;
+// ierr = KSPGetConvergedReason(ksp_,&reason);CHKERRCONTINUE(ierr);
+// if (reason < 0)
+// out<<"*** WARNING *** PETSc solver diverged with flag ";
+// else
+// out<<"*** INFO *** PETSc solver converged with flag ";
+
+// if (reason == KSP_CONVERGED_RTOL)
+// out<<"KSP_CONVERGED_RTOL"<<endl;
+// else if (reason == KSP_CONVERGED_ATOL)
+// out<<"KSP_CONVERGED_ATOL"<<endl;
+// else if (reason == KSP_CONVERGED_ITS)
+// out<<"KSP_CONVERGED_ITS"<<endl;
+// else if (reason == KSP_CONVERGED_CG_NEG_CURVE)
+// out<<"KSP_CONVERGED_CG_NEG_CURVE"<<endl;
+// else if (reason == KSP_CONVERGED_CG_CONSTRAINED)
+// out<<"KSP_CONVERGED_CG_CONSTRAINED"<<endl;
+// else if (reason == KSP_CONVERGED_STEP_LENGTH)
+// out<<"KSP_CONVERGED_STEP_LENGTH"<<endl;
+// else if (reason == KSP_CONVERGED_HAPPY_BREAKDOWN)
+// out<<"KSP_CONVERGED_HAPPY_BREAKDOWN"<<endl;
+// else if (reason == KSP_DIVERGED_NULL)
+// out<<"KSP_DIVERGED_NULL"<<endl;
+// else if (reason == KSP_DIVERGED_ITS)
+// out<<"KSP_DIVERGED_ITS"<<endl;
+// else if (reason == KSP_DIVERGED_DTOL)
+// out<<"KSP_DIVERGED_DTOL"<<endl;
+// else if (reason == KSP_DIVERGED_BREAKDOWN)
+// out<<"KSP_DIVERGED_BREAKDOWN"<<endl;
+// else if (reason == KSP_DIVERGED_BREAKDOWN_BICG)
+// out<<"KSP_DIVERGED_BREAKDOWN_BICG"<<endl;
+// else if (reason == KSP_DIVERGED_NONSYMMETRIC)
+// out<<"KSP_DIVERGED_NONSYMMETRIC"<<endl;
+// else if (reason == KSP_DIVERGED_INDEFINITE_PC)
+// out<<"KSP_DIVERGED_INDEFINITE_PC"<<endl;
+// else if (reason == KSP_DIVERGED_NAN)
+// out<<"KSP_DIVERGED_NAN"<<endl;
+// else if (reason == KSP_DIVERGED_INDEFINITE_MAT)
+// out<<"KSP_DIVERGED_INDEFINITE_MAT"<<endl;
+// else if (reason == KSP_CONVERGED_ITERATING)
+// out<<"KSP_CONVERGED_ITERATING"<<endl;
+
+// PetscReal rnorm;
+// ierr = KSPGetResidualNorm(ksp_,&rnorm);CHKERRCONTINUE(ierr);
+
+// out<<"PETSc last residual norm computed: "<<rnorm<<endl;
+
+// ierr = VecView(x_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
+
+// VecNorm(x_,NORM_2,&nrm);
+// out<<" Norm of solution vector... "<<nrm<<endl;
+
+// #endif
+
+
+
+// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Check solution and clean up
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+// Vec x_all;
+
+// ierr = VecScatterCreateToAll(x_, &ctx, &x_all);CHKERRCONTINUE(ierr);
+// ierr = VecScatterBegin(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+// ierr = VecScatterEnd(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Solution vector scattered... "<<timer<<endl;
+// VecNorm(x_all,NORM_2,&nrm);
+// out<<" Norm of scattered vector... "<<nrm<<endl;
+// // ierr = VecView(x_all,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
+// #endif
+
+// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Get values from solution and store them in the object that will be
+// returned
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+// sparse_vector_type xx(bb.size());
+
+// /* Set solution vector */
+// double zero = 0.;
+// double val;
+// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
+// int row = it->first;
+// ierr = VecGetValues(x_all, 1, &row, &val);
+// if (val != zero)
+// xx[row] = val;
+// }
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Solution vector copied... "<<timer<<endl;
+// // out<<" Norm of copied solution vector... "<<norm(xx, Insert_t)<<endl;
+// #endif
+
+
+// /*
+// Free work space. All PETSc objects should be destroyed when they
+// are no longer needed.
+// */
+// ierr = VecDestroy(&b);CHKERRCONTINUE(ierr);
+// // ierr = KSPDestroy(&ksp);CHKERRCONTINUE(ierr);
+
+// // set allocated flag
+// if (!allocated_) {
+// allocated_ = true;
+// }
+
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+
+// return xx;
+// }
+
+// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& KKpf, const SolverPETSc::sparse_matrix_type& KKpp, const SolverPETSc::sparse_vector_type& UUp) {
+
+// #ifdef CPPUTILS_VERBOSE
+// // parallel output stream
+// Output_stream out;
+// // timer
+// cpputils::ctimer timer;
+// out<<"Inside SolverPETSc::operator()(const sparse_matrix&, const sparse_matrix&, const sparse_vector&). "<<timer<<endl;
+// #endif
+
+// Mat Kpf, Kpp;
+// Vec Up, Pf, Pp;
+
+// PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&Kpf);CHKERRCONTINUE(ierr);
+// ierr = MatCreate(PETSC_COMM_WORLD,&Kpp);CHKERRCONTINUE(ierr);
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Allocating memory... "<<timer<<endl;
+// #endif
+
+// ierr = MatSetFromOptions(Kpf);CHKERRCONTINUE(ierr);
+// ierr = MatSetFromOptions(Kpp);CHKERRCONTINUE(ierr);
+
+// ierr = MatSetSizes(Kpf,PETSC_DECIDE,PETSC_DECIDE, KKpf.rows(), KKpf.columns());CHKERRCONTINUE(ierr);
+// ierr = MatSetSizes(Kpp,PETSC_DECIDE,PETSC_DECIDE, KKpp.rows(), KKpp.columns());CHKERRCONTINUE(ierr);
+
+// // get number of non-zeros in both diagonal and non-diagonal portions of the matrix
+
+// std::pair<size_t,size_t> Kpf_nz = KKpf.non_zero_off_diagonal();
+// std::pair<size_t,size_t> Kpp_nz = KKpp.non_zero_off_diagonal();
+
+// ierr = MatMPIAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL, Kpf_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
+// ierr = MatMPIAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL, Kpp_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
+// ierr = MatSeqAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL); CHKERRCONTINUE(ierr);
+// ierr = MatSeqAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL); CHKERRCONTINUE(ierr);
+
+// for (sparse_matrix_type::const_hash_iterator it = KKpf.map_.begin(); it != KKpf.map_.end(); ++it) {
+
+// // get subscripts
+// std::pair<size_t,size_t> subs = KKpf.unhash(it->first);
+// int row = subs.first;
+// int col = subs.second;
+// ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
+// }
+
+// for (sparse_matrix_type::const_hash_iterator it = KKpp.map_.begin(); it != KKpp.map_.end(); ++it) {
+
+// // get subscripts
+// std::pair<size_t,size_t> subs = KKpp.unhash(it->first);
+// int row = subs.first;
+// int col = subs.second;
+// ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
+// }
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Filled sparse matrices... "<<timer<<endl;
+// #endif
+
+
+// /*
+// Assemble matrix, using the 2-step process:
+// MatAssemblyBegin(), MatAssemblyEnd()
+// Computations can be done while messages are in transition
+// by placing code between these two statements.
+// */
+// ierr = MatAssemblyBegin(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+// ierr = MatAssemblyBegin(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+// ierr = MatAssemblyEnd(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+// ierr = MatAssemblyEnd(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Sparse matrices assembled... "<<timer<<endl;
+// #endif
+
+// ierr = VecCreate(PETSC_COMM_WORLD,&Up);CHKERRCONTINUE(ierr);
+// ierr = VecSetSizes(Up,PETSC_DECIDE, UUp.size());CHKERRCONTINUE(ierr);
+// ierr = VecSetFromOptions(Up);CHKERRCONTINUE(ierr);
+
+// ierr = VecCreate(PETSC_COMM_WORLD,&Pf);CHKERRCONTINUE(ierr);
+// ierr = VecSetSizes(Pf,PETSC_DECIDE, KKpf.rows());CHKERRCONTINUE(ierr);
+// ierr = VecSetFromOptions(Pf);CHKERRCONTINUE(ierr);
+// ierr = VecDuplicate(Pf,&Pp);CHKERRCONTINUE(ierr);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Vectors created... "<<timer<<endl;
+// #endif
+
+
+// /* Set hight-hand-side vector */
+// for (sparse_vector_type::const_hash_iterator it = UUp.map_.begin(); it != UUp.map_.end(); ++it) {
+// int row = it->first;
+// ierr = VecSetValues(Up, 1, &row, &it->second, ADD_VALUES);
+// }
+
+// /*
+// Assemble vector, using the 2-step process:
+// VecAssemblyBegin(), VecAssemblyEnd()
+// Computations can be done while messages are in transition
+// by placing code between these two statements.
+// */
+// ierr = VecAssemblyBegin(Up);CHKERRCONTINUE(ierr);
+// ierr = VecAssemblyEnd(Up);CHKERRCONTINUE(ierr);
+
+// // add Kpf*Uf
+// ierr = MatMult(Kpf, x_, Pf);
+
+// // add Kpp*Up
+// ierr = MatMultAdd(Kpp, Up, Pf, Pp);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Matrices multiplied... "<<timer<<endl;
+// #endif
+
+
+// VecScatter ctx;
+// Vec Pp_all;
+
+// ierr = VecScatterCreateToAll(Pp, &ctx, &Pp_all);CHKERRCONTINUE(ierr);
+// ierr = VecScatterBegin(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+// ierr = VecScatterEnd(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Vector scattered... "<<timer<<endl;
+// #endif
+
+// /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// Get values from solution and store them in the object that will be
+// returned
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+// sparse_vector_type pp(KKpf.rows());
+
+// // get reaction vector
+// for (int i=0; i<KKpf.rows(); ++i) {
+
+// PetscScalar v;
+// ierr = VecGetValues(Pp_all, 1, &i, &v);
+// if (v != PetscScalar())
+// pp[i] = v;
+// }
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Vector copied... "<<timer<<endl;
+// #endif
+
+// ierr = MatDestroy(&Kpf);CHKERRCONTINUE(ierr);
+// ierr = MatDestroy(&Kpp);CHKERRCONTINUE(ierr);
+// ierr = VecDestroy(&Up);CHKERRCONTINUE(ierr);
+// ierr = VecDestroy(&Pf);CHKERRCONTINUE(ierr);
+// ierr = VecDestroy(&Pp);CHKERRCONTINUE(ierr);
+// ierr = VecDestroy(&Pp_all);CHKERRCONTINUE(ierr);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+
+// return pp;
+// }
+
+
+
+// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const SolverPETSc::sparse_vector_type& aa, const SolverPETSc::sparse_vector_type& bb) {
+
+// assert(aa.size() == bb.size());
+
+// #ifdef CPPUTILS_VERBOSE
+// // parallel output stream
+// Output_stream out;
+// // timer
+// cpputils::ctimer timer;
+// out<<"Inside SolverPETSc::operator()(const sparse_vector&, const sparse_vector&). "<<timer<<endl;
+// #endif
+
+// Vec r;
+
+// PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
+// ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
+// ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Vectors created... "<<timer<<endl;
+// #endif
+
+// // set values
+// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
+// int row = it->first;
+// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
+// }
+// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
+// int row = it->first;
+// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
+// }
+
+// /*
+// Assemble vector, using the 2-step process:
+// VecAssemblyBegin(), VecAssemblyEnd()
+// Computations can be done while messages are in transition
+// by placing code between these two statements.
+// */
+// ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
+// ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
+
+
+// sparse_vector_type rr(aa.size());
+
+// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
+// int row = it->first;
+// ierr = VecGetValues(r, 1, &row, &rr[row]);
+// }
+// for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
+// int row = it->first;
+// ierr = VecGetValues(r, 1, &row, &rr[row]);
+// }
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Vector copied... "<<timer<<endl;
+// #endif
+
+// ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+
+// return rr;
+// }
+
+// SolverPETSc::value_type SolverPETSc::norm(const SolverPETSc::sparse_matrix_type& aa, Element_insertion_type flag) {
+
+// #ifdef CPPUTILS_VERBOSE
+// // parallel output stream
+// Output_stream out;
+// // timer
+// cpputils::ctimer timer;
+// out<<"Inside SolverPETSc::norm(const sparse_matrix&). "<<timer<<endl;
+// #endif
+
+// Mat r;
+
+// PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
+// ierr = MatSetSizes(r,PETSC_DECIDE,PETSC_DECIDE, aa.rows(), aa.columns());CHKERRCONTINUE(ierr);
+// ierr = MatSetFromOptions(r);CHKERRCONTINUE(ierr);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Matrix created... "<<timer<<endl;
+// #endif
+
+// // set values
+// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
+// // get subscripts
+// std::pair<size_t,size_t> subs = aa.unhash(it->first);
+// int row = subs.first;
+// int col = subs.second;
+
+// if (flag == Add_t)
+// ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, ADD_VALUES);
+// else if (flag == Insert_t)
+// ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, INSERT_VALUES);
+// CHKERRCONTINUE(ierr);
+// }
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Matrix filled..."<<timer<<endl;
+// #endif
+
+// /*
+// Assemble vector, using the 2-step process:
+// VecAssemblyBegin(), VecAssemblyEnd()
+// Computations can be done while messages are in transition
+// by placing code between these two statements.
+// */
+// ierr = MatAssemblyBegin(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+// ierr = MatAssemblyEnd(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+
+// value_type nrm;
+
+// MatNorm(r,NORM_FROBENIUS,&nrm);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Norm computed... "<<timer<<endl;
+// #endif
+
+// ierr = MatDestroy(&r);CHKERRCONTINUE(ierr);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+
+// return nrm;
+// }
+
+
+// SolverPETSc::value_type SolverPETSc::norm(const SolverPETSc::sparse_vector_type& aa, Element_insertion_type flag) {
+
+// #ifdef CPPUTILS_VERBOSE
+// // parallel output stream
+// Output_stream out;
+// // timer
+// cpputils::ctimer timer;
+// out<<"Inside SolverPETSc::norm(const sparse_vector&). "<<timer<<endl;
+// #endif
+
+// Vec r;
+
+// PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
+// ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
+// ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Vector created... "<<timer<<endl;
+// #endif
+
+// // set values
+// for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
+// int row = it->first;
+// if (flag == Add_t)
+// ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
+// else if (flag == Insert_t)
+// ierr = VecSetValues(r, 1, &row, &it->second, INSERT_VALUES);
+// CHKERRCONTINUE(ierr);
+// }
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Vector filled..."<<timer<<endl;
+// #endif
+
+// /*
+// Assemble vector, using the 2-step process:
+// VecAssemblyBegin(), VecAssemblyEnd()
+// Computations can be done while messages are in transition
+// by placing code between these two statements.
+// */
+// ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
+// ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
+
+// value_type nrm;
+
+// VecNorm(r,NORM_2,&nrm);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Norm computed... "<<timer<<endl;
+// #endif
+
+// ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
+
+// #ifdef CPPUTILS_VERBOSE
+// out<<" Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+
+// return nrm;
+
+// }
+
+
+
+// //
+// ///* -------------------------------------------------------------------------- */
+// //SolverMumps::SolverMumps(SparseMatrix & matrix,
+// // const ID & id,
+// // const MemoryID & memory_id) :
+// //Solver(matrix, id, memory_id), is_mumps_data_initialized(false), rhs_is_local(true) {
+// // AKANTU_DEBUG_IN();
+// //
+// //#ifdef AKANTU_USE_MPI
+// // parallel_method = SolverMumpsOptions::_fully_distributed;
+// //#else //AKANTU_USE_MPI
+// // parallel_method = SolverMumpsOptions::_master_slave_distributed;
+// //#endif //AKANTU_USE_MPI
+// //
+// // CommunicatorEventHandler & comm_event_handler = *this;
+// //
+// // communicator.registerEventHandler(comm_event_handler);
+// //
+// // AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //SolverMumps::~SolverMumps() {
+// // AKANTU_DEBUG_IN();
+// //
+// // AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::destroyMumpsData() {
+// // AKANTU_DEBUG_IN();
+// //
+// // if(is_mumps_data_initialized) {
+// // mumps_data.job = _smj_destroy; // destroy
+// // dmumps_c(&mumps_data);
+// // is_mumps_data_initialized = false;
+// // }
+// //
+// // AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::onCommunicatorFinalize(const StaticCommunicator & comm) {
+// // AKANTU_DEBUG_IN();
+// //
+// // try{
+// // const StaticCommunicatorMPI & comm_mpi =
+// // dynamic_cast<const StaticCommunicatorMPI &>(comm.getRealStaticCommunicator());
+// // if(mumps_data.comm_fortran == MPI_Comm_c2f(comm_mpi.getMPICommunicator()))
+// // destroyMumpsData();
+// // } catch(...) {}
+// //
+// // AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::initMumpsData(SolverMumpsOptions::ParallelMethod parallel_method) {
+// // switch(parallel_method) {
+// // case SolverMumpsOptions::_fully_distributed:
+// // icntl(18) = 3; //fully distributed
+// // icntl(28) = 0; //automatic choice
+// //
+// // mumps_data.nz_loc = matrix->getNbNonZero();
+// // mumps_data.irn_loc = matrix->getIRN().values;
+// // mumps_data.jcn_loc = matrix->getJCN().values;
+// // break;
+// // case SolverMumpsOptions::_master_slave_distributed:
+// // if(prank == 0) {
+// // mumps_data.nz = matrix->getNbNonZero();
+// // mumps_data.irn = matrix->getIRN().values;
+// // mumps_data.jcn = matrix->getJCN().values;
+// // } else {
+// // mumps_data.nz = 0;
+// // mumps_data.irn = NULL;
+// // mumps_data.jcn = NULL;
+// //
+// // icntl(18) = 0; //centralized
+// // icntl(28) = 0; //sequential analysis
+// // }
+// // break;
+// // }
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::initialize(SolverOptions & options) {
+// // AKANTU_DEBUG_IN();
+// //
+// // mumps_data.par = 1;
+// //
+// // if(SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options)) {
+// // if(opt->parallel_method == SolverMumpsOptions::_master_slave_distributed) {
+// // mumps_data.par = 0;
+// // }
+// // }
+// //
+// // mumps_data.sym = 2 * (matrix->getSparseMatrixType() == _symmetric);
+// // prank = communicator.whoAmI();
+// //#ifdef AKANTU_USE_MPI
+// // mumps_data.comm_fortran = MPI_Comm_c2f(dynamic_cast<const StaticCommunicatorMPI &>(communicator.getRealStaticCommunicator()).getMPICommunicator());
+// //#endif
+// //
+// // if(AKANTU_DEBUG_TEST(dblTrace)) {
+// // icntl(1) = 2;
+// // icntl(2) = 2;
+// // icntl(3) = 2;
+// // icntl(4) = 4;
+// // }
+// //
+// // mumps_data.job = _smj_initialize; //initialize
+// // dmumps_c(&mumps_data);
+// // is_mumps_data_initialized = true;
+// //
+// // /* ------------------------------------------------------------------------ */
+// // UInt size = matrix->getSize();
+// //
+// // if(prank == 0) {
+// // std::stringstream sstr_rhs; sstr_rhs << id << ":rhs";
+// // rhs = &(alloc<Real>(sstr_rhs.str(), size, 1, REAL_INIT_VALUE));
+// // } else {
+// // rhs = NULL;
+// // }
+// //
+// // /// No outputs
+// // icntl(1) = 0;
+// // icntl(2) = 0;
+// // icntl(3) = 0;
+// // icntl(4) = 0;
+// // mumps_data.nz_alloc = 0;
+// //
+// // if (AKANTU_DEBUG_TEST(dblDump)) icntl(4) = 4;
+// //
+// // mumps_data.n = size;
+// //
+// // if(AKANTU_DEBUG_TEST(dblDump)) {
+// // strcpy(mumps_data.write_problem, "mumps_matrix.mtx");
+// // }
+// //
+// // /* ------------------------------------------------------------------------ */
+// // // Default Scaling
+// // icntl(8) = 77;
+// //
+// // icntl(5) = 0; // Assembled matrix
+// //
+// // SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options);
+// // if(opt)
+// // parallel_method = opt->parallel_method;
+// //
+// // initMumpsData(parallel_method);
+// //
+// // mumps_data.job = _smj_analyze; //analyze
+// // dmumps_c(&mumps_data);
+// //
+// // AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::setRHS(Array<Real> & rhs) {
+// // if(prank == 0) {
+// // matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
+// // } else {
+// // matrix->getDOFSynchronizer().gather(rhs, 0);
+// // }
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::solve() {
+// // AKANTU_DEBUG_IN();
+// //
+// // if(parallel_method == SolverMumpsOptions::_fully_distributed)
+// // mumps_data.a_loc = matrix->getA().values;
+// // else
+// // if(prank == 0) {
+// // mumps_data.a = matrix->getA().values;
+// // }
+// //
+// // if(prank == 0) {
+// // mumps_data.rhs = rhs->values;
+// // }
+// //
+// // /// Default centralized dense second member
+// // icntl(20) = 0;
+// // icntl(21) = 0;
+// //
+// // mumps_data.job = _smj_factorize_solve; //solve
+// // dmumps_c(&mumps_data);
+// //
+// // AKANTU_DEBUG_ASSERT(info(1) != -10, "Singular matrix");
+// // AKANTU_DEBUG_ASSERT(info(1) == 0,
+// // "Error in mumps during solve process, check mumps user guide INFO(1) ="
+// // << info(1));
+// //
+// // AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::solve(Array<Real> & solution) {
+// // AKANTU_DEBUG_IN();
+// //
+// // solve();
+// //
+// // if(prank == 0) {
+// // matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
+// // } else {
+// // matrix->getDOFSynchronizer().scatter(solution, 0);
+// // }
+// //
+// // AKANTU_DEBUG_OUT();
+// //}
+
+__END_AKANTU__
+
diff --git a/src/solver/solver_petsc.hh b/src/solver/solver_petsc.hh
new file mode 100644
index 000000000..5016c98f7
--- /dev/null
+++ b/src/solver/solver_petsc.hh
@@ -0,0 +1,166 @@
+/**
+ * @file solver_petsc.hh
+ *
+ # @author Alejandro M. Aragón <alejandro.aragon@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
+ *
+ * @brief Solver class interface for the petsc solver
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#ifndef __AKANTU_SOLVER_PETSC_HH__
+#define __AKANTU_SOLVER_PETSC_HH__
+
+/* -------------------------------------------------------------------------- */
+#include "solver.hh"
+
+
+/* -------------------------------------------------------------------------- */
+__BEGIN_AKANTU__
+
+class PETScSolverWrapper;
+
+class SolverPETSc : public Solver {
+
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+
+ SolverPETSc(SparseMatrix & sparse_matrix,
+ const ID & id = "solver_petsc",
+ const MemoryID & memory_id = 0);
+
+ virtual ~SolverPETSc();
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// create the solver context and set the matrices
+ virtual void initialize(SolverOptions & options = _solver_no_options);
+ virtual void setOperators();
+ virtual void setRHS(Array<Real> & rhs);
+ virtual void solve();
+ virtual void solve(Array<Real> & solution);
+private:
+ /// clean the petsc data
+ virtual void destroyInternalData();
+
+private:
+
+ /// specify if the petsc_data is initialized or not
+ bool is_petsc_data_initialized;
+
+ /// store the PETSc structures
+ PETScSolverWrapper * petsc_solver_wrapper;
+
+
+
+};
+
+
+// SolverPETSc(int argc, char *argv[]) : allocated_(false) {
+
+// /*
+// Set linear solver defaults for this problem (optional).
+// - By extracting the KSP and PC contexts from the KSP context,
+// we can then directly call any KSP and PC routines to set
+// various options.
+// - The following four statements are optional; all of these
+// parameters could alternatively be specified at runtime via
+// KSPSetFromOptions();
+// */
+// // ierr = KSPGetPC(ksp_,&pc);CHKERRCONTINUE(ierr);
+// // ierr = PCSetType(pc,PCILU);CHKERRCONTINUE(ierr);
+// // ierr = PCSetType(pc,PCJACOBI);CHKERRCONTINUE(ierr);
+// ierr = KSPSetTolerances(ksp_,1.e-5,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRCONTINUE(ierr);
+// }
+
+// //! Overload operator() to solve system of linear equations
+// sparse_vector_type operator()(const sparse_matrix_type& AA, const sparse_vector_type& bb);
+
+// //! Overload operator() to obtain reaction vector
+// sparse_vector_type operator()(const sparse_matrix_type& Kpf, const sparse_matrix_type& Kpp, const sparse_vector_type& Up);
+
+// //! Overload operator() to obtain the addition two vectors
+// sparse_vector_type operator()(const sparse_vector_type& aa, const sparse_vector_type& bb);
+
+// value_type norm(const sparse_matrix_type& aa, Element_insertion_type it = Add_t);
+
+// value_type norm(const sparse_vector_type& aa, Element_insertion_type it = Add_t);
+
+// // NOTE: the destructor will return an error if it is called after MPI_Finalize is
+// // called because it uses collect communication to free-up allocated memory.
+// ~SolverPETSc() {
+
+// static bool exit = false;
+// if (!exit) {
+// // add finalize PETSc function at exit
+// atexit(finalize);
+// exit = true;
+// }
+
+// if (allocated_) {
+// PetscErrorCode ierr = MatDestroy(&A_);CHKERRCONTINUE(ierr);
+// ierr = VecDestroy(&x_);CHKERRCONTINUE(ierr);
+// ierr = KSPDestroy(&ksp_);CHKERRCONTINUE(ierr);
+// }
+// }
+
+// /* from the PETSc library, these are the options that can be passed
+// to the command line
+
+// Options Database Keys
+
+// -options_table - Calls PetscOptionsView()
+// -options_left - Prints unused options that remain in the database
+// -objects_left - Prints list of all objects that have not been freed
+// -mpidump - Calls PetscMPIDump()
+// -malloc_dump - Calls PetscMallocDump()
+// -malloc_info - Prints total memory usage
+// -malloc_log - Prints summary of memory usage
+
+// Options Database Keys for Profiling
+
+// -log_summary [filename] - Prints summary of flop and timing information to screen.
+// If the filename is specified the summary is written to the file. See PetscLogView().
+// -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen.
+// -log_all [filename] - Logs extensive profiling information See PetscLogDump().
+// -log [filename] - Logs basic profiline information See PetscLogDump().
+// -log_sync - Log the synchronization in scatters, inner products and norms
+// -log_mpe [filename] - Creates a logfile viewable by the utility Upshot/Nupshot (in MPICH distribution)
+// }
+// }
+// };
+
+
+
+
+
+
+__END_AKANTU__
+
+#endif /* __AKANTU_SOLVER_PETSC_HH__ */
diff --git a/src/solver/sparse_matrix.cc b/src/solver/sparse_matrix.cc
index 7b4ee0611..c2b3c78e6 100644
--- a/src/solver/sparse_matrix.cc
+++ b/src/solver/sparse_matrix.cc
@@ -1,664 +1,625 @@
/**
* @file sparse_matrix.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Mon Sep 15 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <fstream>
/* -------------------------------------------------------------------------- */
#include "sparse_matrix.hh"
#include "static_communicator.hh"
#include "dof_synchronizer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
SparseMatrix::SparseMatrix(UInt size,
const SparseMatrixType & sparse_matrix_type,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
sparse_matrix_type(sparse_matrix_type),
size(size),
nb_non_zero(0),
- irn(0,1,"irn"), jcn(0,1,"jcn"), a(0,1,"A") {
+ irn(0,1,"irn"), jcn(0,1,"jcn"), a(0,1,"A"), offset(1) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
nb_proc = comm.getNbProc();
dof_synchronizer = NULL;
irn_save = NULL;
jcn_save = NULL;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseMatrix::SparseMatrix(const SparseMatrix & matrix,
const ID & id,
const MemoryID & memory_id) :
Memory(id, memory_id),
sparse_matrix_type(matrix.sparse_matrix_type),
size(matrix.size),
nb_proc(matrix.nb_proc),
nb_non_zero(matrix.nb_non_zero),
irn(matrix.irn, true), jcn(matrix.jcn, true), a(matrix.getA(), true),
- irn_jcn_k(matrix.irn_jcn_k) {
+ irn_jcn_k(matrix.irn_jcn_k), offset(1) {
AKANTU_DEBUG_IN();
size_save = 0;
irn_save = NULL;
jcn_save = NULL;
dof_synchronizer = matrix.dof_synchronizer;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
SparseMatrix::~SparseMatrix() {
AKANTU_DEBUG_IN();
// if (irn_jcn_to_k) delete irn_jcn_to_k;
if(irn_save) delete irn_save;
if(jcn_save) delete jcn_save;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom) {
AKANTU_DEBUG_IN();
// if(irn_jcn_to_k) delete irn_jcn_to_k;
// irn_jcn_to_k = new std::map<std::pair<UInt, UInt>, UInt>;
clearProfile();
this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
coordinate_list_map::iterator irn_jcn_k_it;
Int * eq_nb_val = dof_synchronizer.getGlobalDOFEquationNumbers().storage();
Mesh::type_iterator it = mesh.firstType(mesh.getSpatialDimension(), _not_ghost, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType (mesh.getSpatialDimension(), _not_ghost, _ek_not_defined);
for(; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it);
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
UInt * conn_val = mesh.getConnectivity(*it, _not_ghost).storage();
Int * local_eq_nb_val = new Int[nb_degree_of_freedom * nb_nodes_per_element];
for (UInt e = 0; e < nb_element; ++e) {
Int * tmp_local_eq_nb_val = local_eq_nb_val;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
UInt n = conn_val[i];
for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
*tmp_local_eq_nb_val++ = eq_nb_val[n * nb_degree_of_freedom + d];
}
// memcpy(tmp_local_eq_nb_val, eq_nb_val + n * nb_degree_of_freedom, nb_degree_of_freedom * sizeof(Int));
// tmp_local_eq_nb_val += nb_degree_of_freedom;
}
for (UInt i = 0; i < size_mat; ++i) {
UInt c_irn = local_eq_nb_val[i];
- if(c_irn < size) {
+ if(c_irn < this->size) {
UInt j_start = (sparse_matrix_type == _symmetric) ? i : 0;
for (UInt j = j_start; j < size_mat; ++j) {
UInt c_jcn = local_eq_nb_val[j];
- if(c_jcn < size) {
+ if(c_jcn < this->size) {
KeyCOO irn_jcn = key(c_irn, c_jcn);
irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
if (irn_jcn_k_it == irn_jcn_k.end()) {
irn_jcn_k[irn_jcn] = nb_non_zero;
irn.push_back(c_irn + 1);
jcn.push_back(c_jcn + 1);
nb_non_zero++;
}
}
}
}
}
conn_val += nb_nodes_per_element;
}
delete [] local_eq_nb_val;
}
/// for pbc @todo correct it for parallel
if(StaticCommunicator::getStaticCommunicator().getNbProc() == 1) {
for (UInt i = 0; i < size; ++i) {
KeyCOO irn_jcn = key(i, i);
irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
if(irn_jcn_k_it == irn_jcn_k.end()) {
irn_jcn_k[irn_jcn] = nb_non_zero;
irn.push_back(i + 1);
jcn.push_back(i + 1);
nb_non_zero++;
}
}
}
+ else { // for pbc in parallel
+ for (UInt n=0; n<mesh.getNbNodes(); ++n) {
+ for (UInt d=0; d<nb_degree_of_freedom; ++d) {
+ if (mesh.isLocalOrMasterNode(n)) {
+ UInt i = mesh.getNodeGlobalId(n) * nb_degree_of_freedom + d;
+
+ KeyCOO irn_jcn = key(i, i);
+ irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
+ if(irn_jcn_k_it == irn_jcn_k.end()) {
+ irn_jcn_k[irn_jcn] = nb_non_zero;
+ irn.push_back(i + 1);
+ jcn.push_back(i + 1);
+ nb_non_zero++;
+ }
+ }
+ }
+ }
+ }
a.resize(nb_non_zero);
AKANTU_DEBUG_OUT();
}
///* -------------------------------------------------------------------------- */
//void SparseMatrix::applyBoundaryNormal(Array<bool> & boundary_normal, Array<Real> & EulerAngles, Array<Real> & rhs, const Array<Real> & matrix, Array<Real> & rhs_rotated) {
// AKANTU_DEBUG_IN();
//
//
// const UInt dim = nb_degree_of_freedom;
// const UInt nb_nodes = boundary_normal.getSize();
// Matrix<Real> Ti(dim, dim);
// Matrix<Real> Tj(dim, dim);
// Matrix<Real> small_matrix(dim, dim);
// Matrix<Real> Ti_small_matrix(dim, dim);
// Matrix<Real> Ti_small_matrix_Tj(dim, dim);
// Matrix<Real> small_rhs(dim, 1);
// Matrix<Real> Ti_small_rhs(dim, 1);
// //Transformation matrix based on euler angles X_1Y_2Z_3
//
// const DOFSynchronizer::GlobalEquationNumberMap & local_eq_num_to_global = dof_synchronizer->getGlobalEquationNumberToLocal();
//
// Int * irn_val = irn.storage();
// Int * jcn_val = jcn.storage();
// Int * eq_nb_val = dof_synchronizer->getGlobalDOFEquationNumbers().storage();
// Int * eq_nb_rhs_val = dof_synchronizer->getLocalDOFEquationNumbers().storage();
//
// Array<bool> * nodes_rotated = new Array<bool > (nb_nodes, dim, "nodes_rotated");
// nodes_rotated->clear();
//
// Array<Int> * local_eq_nb_val_node_i = new Array<Int > (1, nb_degree_of_freedom, "local_eq_nb_val_node_i");
// local_eq_nb_val_node_i->clear();
// Array<Int> * local_eq_nb_val_node_j = new Array<Int > (1, nb_degree_of_freedom, "local_eq_nb_val_node_j");
// local_eq_nb_val_node_j->clear();
//
// for (UInt i = 0; i < nb_non_zero; ++i) {
// UInt ni = local_eq_num_to_global.find(*irn_val - 1)->second;
// UInt node_i = (ni - ni % nb_degree_of_freedom) / nb_degree_of_freedom;
// UInt nj = local_eq_num_to_global.find(*jcn_val - 1)->second;
// UInt node_j = (nj - nj % nb_degree_of_freedom) / nb_degree_of_freedom;
// bool constrain_ij = false;
// for (UInt j = 0; j < dim; j++){
// if ( (boundary_normal(node_i, j) || boundary_normal(node_j, j)) ) {
// constrain_ij = true;
// break;
// }
// }
//
// if(constrain_ij){
// if(dim==2){
// Real Theta=EulerAngles(node_i,0);
// Ti(0,0)=cos(Theta);
// Ti(0,1)=-sin(Theta);
// Ti(1,1)=cos(Theta);
// Ti(1,0)=sin(Theta);
//
// Theta=EulerAngles(node_j,0);
// Tj(0,0)=cos(Theta);
// Tj(0,1)=-sin(Theta);
// Tj(1,1)=cos(Theta);
// Tj(1,0)=sin(Theta);
// }
// else if(dim==3){
// Real Theta_x=EulerAngles(node_i,0);
// Real Theta_y=EulerAngles(node_i,1);
// Real Theta_z=EulerAngles(node_i,2);
//
// Ti(0,0)=cos(Theta_y)*cos(Theta_z);
// Ti(0,1)=-cos(Theta_y)*sin(Theta_z);
// Ti(0,2)=sin(Theta_y);
// Ti(1,0)=cos(Theta_x)*sin(Theta_z)+cos(Theta_z)*sin(Theta_x)*sin(Theta_y);
// Ti(1,1)=cos(Theta_x)*cos(Theta_z)-sin(Theta_x)*sin(Theta_y)*sin(Theta_z);
// Ti(1,2)=-cos(Theta_y)*sin(Theta_x);
// Ti(2,0)=sin(Theta_x)*sin(Theta_z)-cos(Theta_x)*cos(Theta_z)*sin(Theta_y);
// Ti(2,1)=cos(Theta_z)*sin(Theta_x)+cos(Theta_x)*sin(Theta_y)*sin(Theta_z);
// Ti(2,2)=cos(Theta_x)*cos(Theta_y);
//
// Theta_x=EulerAngles(node_j,0);
// Theta_y=EulerAngles(node_j,1);
// Theta_z=EulerAngles(node_j,2);
//
// Tj(0,0)=cos(Theta_y)*cos(Theta_z);
// Tj(0,1)=-cos(Theta_y)*sin(Theta_z);
// Tj(0,2)=sin(Theta_y);
// Tj(1,0)=cos(Theta_x)*sin(Theta_z)+cos(Theta_z)*sin(Theta_x)*sin(Theta_y);
// Tj(1,1)=cos(Theta_x)*cos(Theta_z)-sin(Theta_x)*sin(Theta_y)*sin(Theta_z);
// Tj(1,2)=-cos(Theta_y)*sin(Theta_x);
// Tj(2,0)=sin(Theta_x)*sin(Theta_z)-cos(Theta_x)*cos(Theta_z)*sin(Theta_y);
// Tj(2,1)=cos(Theta_z)*sin(Theta_x)+cos(Theta_x)*sin(Theta_y)*sin(Theta_z);
// Tj(2,2)=cos(Theta_x)*cos(Theta_y);
// }
// for (UInt j = 0; j < nb_degree_of_freedom; ++j){
// local_eq_nb_val_node_i->storage()[j] = eq_nb_val[node_i * nb_degree_of_freedom + j];
// local_eq_nb_val_node_j->storage()[j] = eq_nb_val[node_j * nb_degree_of_freedom + j];
// }
// for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
// for (UInt k = 0; k < nb_degree_of_freedom; ++k) {
// KeyCOO jcn_irn = key(local_eq_nb_val_node_i->storage()[j], local_eq_nb_val_node_j->storage()[k]);
// coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
// small_matrix(j, k) = matrix.storage()[irn_jcn_k_it->second];
// }
// small_rhs(j,0)=rhs.storage()[eq_nb_rhs_val[node_i*dim+j]];
// }
//
// Ti_small_matrix.mul < false, false > (Ti, small_matrix);
// Ti_small_matrix_Tj.mul < false, true> (Ti_small_matrix, Tj);
// Ti_small_rhs.mul<false, false>(Ti, small_rhs);
//
// /*for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
// for (UInt k = 0; k < nb_degree_of_freedom; ++k) {
// KeyCOO jcn_irn = key(local_eq_nb_val_node_i->storage()[j], local_eq_nb_val_node_j->storage()[k]);
// coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
// a.storage()[irn_jcn_k_it->second] = T_small_matrix_T(j,k);
// }
// if(node_constrain==node_i && !( nodes_rotated->storage()[node_i]))
// rhs.storage()[eq_nb_rhs_val[node_i*dim+j]]=T_small_rhs(j,0);
// }*/
// KeyCOO jcn_irn = key(ni, nj);
// coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
// a.storage()[irn_jcn_k_it->second] = Ti_small_matrix_Tj(ni % nb_degree_of_freedom, nj % nb_degree_of_freedom);
// //this->saveMatrix("stiffness_partial.out");
// if (!(nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]])) {
// rhs_rotated.storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = Ti_small_rhs(ni % nb_degree_of_freedom, 0);
// nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = true;
// }
// }
// else{
// if (!(nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]])) {
// rhs_rotated.storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = rhs.storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]];
// nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = true;
// }
// }
// irn_val++;
// jcn_val++;
// }
//
// delete local_eq_nb_val_node_i;
// delete local_eq_nb_val_node_j;
// delete nodes_rotated;
// this->saveMatrix("stiffness_rotated.out");
// applyBoundary(boundary_normal);
//
// /*Real norm = 0;
// UInt n_zeros = 0;
// for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
// norm += Normal.storage()[j] * Normal.storage()[j];
// if (std::abs(Normal.storage()[j]) < Math::getTolerance())
// n_zeros++;
// }
// norm = sqrt(norm);
// AKANTU_DEBUG_ASSERT(norm > Math::getTolerance(), "The normal is not right");
// for (UInt j = 0; j < nb_degree_of_freedom; ++j)
// Normal.storage()[j] /= norm;
//
// if (n_zeros == nb_degree_of_freedom - 1) {
// UInt nb_nodes = boundary_normal.getSize();
// for (UInt i = 0; i < nb_nodes; ++i) {
// if (boundary_normal(i, 0))
// for (UInt j = 0; j < nb_degree_of_freedom; ++j)
// boundary(i, j) += Normal(0, j);
// }
// } else {
//
// const DOFSynchronizer::GlobalEquationNumberMap & local_eq_num_to_global = dof_synchronizer->getGlobalEquationNumberToLocal();
//
// Int * irn_val = irn.storage();
// Int * eq_nb_val = dof_synchronizer->getGlobalDOFEquationNumbers().storage();
// Array<Int> * local_eq_nb_val = new Array<Int > (1, nb_degree_of_freedom, "local_eq_nb_val");
// local_eq_nb_val->clear();
// UInt nb_nodes = boundary_normal.getSize();
// Array<bool> * node_set = new Array<bool > (nb_nodes, 1, "node_set");
// node_set->clear();
//
// for (UInt i = 0; i < nb_non_zero; ++i) {
// UInt ni = local_eq_num_to_global.find(*irn_val - 1)->second;
// UInt node_i = (ni - ni % nb_degree_of_freedom) / nb_degree_of_freedom;
// if (boundary_normal.storage()[ni]) {
// if ((!number.storage()[ni]) && (!node_set->storage()[node_i])) {
// UInt normal_component_i = ni % nb_degree_of_freedom; //DOF of node node_i to be removed
// if (std::abs(Normal.storage()[normal_component_i]) > Math::getTolerance()) {
// for (UInt j = 0; j < nb_degree_of_freedom; ++j)
// local_eq_nb_val->storage()[j] = eq_nb_val[node_i * nb_degree_of_freedom + j];
//
// UInt DOF_remove = local_eq_nb_val->storage()[normal_component_i];
// KeyCOO jcn_irn = key(DOF_remove, DOF_remove);
// coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
//
// Real aii = a.storage()[irn_jcn_k_it->second];
// Real normal_constant = (1 - aii) / (Normal.storage()[normal_component_i] * Normal.storage()[normal_component_i]);
//
// for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
// UInt line_j = local_eq_nb_val->storage()[j];
// for (UInt k = 0; k < nb_degree_of_freedom; ++k) {
// UInt column_k = local_eq_nb_val->storage()[k];
// jcn_irn = key(line_j, column_k);
// if ((line_j == column_k) && (line_j == DOF_remove))
// a.storage()[irn_jcn_k_it->second] = 1;
// else
// a.storage()[irn_jcn_k_it->second] += Normal.storage()[j] * Normal.storage()[k] * normal_constant;
// }
// }
//
// number.storage()[ni]++;
// node_set->storage()[node_i] = false;
// }
// }
// }
// irn_val++;
// }
//
// delete local_eq_nb_val;
// delete node_set;
// }*/
// AKANTU_DEBUG_OUT();
//}
/* -------------------------------------------------------------------------- */
void SparseMatrix::applyBoundary(const Array<bool> & boundary, Real block_val) {
AKANTU_DEBUG_IN();
const DOFSynchronizer::GlobalEquationNumberMap & local_eq_num_to_global = dof_synchronizer->getGlobalEquationNumberToLocal();
Int * irn_val = irn.storage();
Int * jcn_val = jcn.storage();
Real * a_val = a.storage();
for (UInt i = 0; i < nb_non_zero; ++i) {
/// @todo fix this hack, put here for the implementation of augmented
/// lagrangian contact
if (local_eq_num_to_global.find(*irn_val - 1) == local_eq_num_to_global.end())
continue;
if (local_eq_num_to_global.find(*jcn_val - 1) == local_eq_num_to_global.end())
continue;
UInt ni = local_eq_num_to_global.find(*irn_val - 1)->second;
UInt nj = local_eq_num_to_global.find(*jcn_val - 1)->second;
if(boundary.storage()[ni] || boundary.storage()[nj]) {
if (*irn_val != *jcn_val) {
*a_val = 0;
} else {
if(dof_synchronizer->getDOFTypes()(ni) >= 0) {
*a_val = 0;
} else {
*a_val = block_val;
}
}
}
irn_val++; jcn_val++; a_val++;
}
AKANTU_DEBUG_OUT();
}
-/* -------------------------------------------------------------------------- */
-void SparseMatrix::removeBoundary(const Array<bool> & boundary) {
- AKANTU_DEBUG_IN();
-
- if(irn_save) delete irn_save;
- if(jcn_save) delete jcn_save;
-
- irn_save = new Array<Int>(irn, true);
- jcn_save = new Array<Int>(jcn, true);
-
- UInt n = boundary.getSize()*boundary.getNbComponent();
-
- UInt * perm = new UInt[n];
-
- size_save = size;
- size = 0;
- for (UInt i = 0; i < n; ++i) {
- if(!boundary.storage()[i]) {
- perm[i] = size;
- // std::cout << "perm["<< i <<"] = " << size << std::endl;
- size++;
- }
- }
-
- for (UInt i = 0; i < nb_non_zero;) {
- if(boundary.storage()[irn(i) - 1] || boundary.storage()[jcn(i) - 1]) {
- irn.erase(i);
- jcn.erase(i);
- a.erase(i);
- nb_non_zero--;
- } else {
- irn(i) = perm[irn(i) - 1] + 1;
- jcn(i) = perm[jcn(i) - 1] + 1;
- i++;
- }
- }
-
- delete [] perm;
-
- AKANTU_DEBUG_OUT();
-}
-
-/* -------------------------------------------------------------------------- */
-void SparseMatrix::restoreProfile() {
- AKANTU_DEBUG_IN();
-
- irn.resize(irn_save->getSize());
- jcn.resize(jcn_save->getSize());
-
- nb_non_zero = irn.getSize();
- a.resize(nb_non_zero);
- size = size_save;
-
- memcpy(irn.storage(), irn_save->storage(), irn.getSize()*sizeof(Int));
- memcpy(jcn.storage(), jcn_save->storage(), jcn.getSize()*sizeof(Int));
-
- delete irn_save; irn_save = NULL;
- delete jcn_save; jcn_save = NULL;
-
- AKANTU_DEBUG_OUT();
-}
-
/* -------------------------------------------------------------------------- */
void SparseMatrix::saveProfile(const std::string & filename) const {
AKANTU_DEBUG_IN();
std::ofstream outfile;
outfile.open(filename.c_str());
outfile << "%%MatrixMarket matrix coordinate pattern";
if(sparse_matrix_type == _symmetric) outfile << " symmetric";
else outfile << " general";
outfile << std::endl;
UInt m = size;
outfile << m << " " << m << " " << nb_non_zero << std::endl;
for (UInt i = 0; i < nb_non_zero; ++i) {
outfile << irn.storage()[i] << " " << jcn.storage()[i] << " 1" << std::endl;
}
outfile.close();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::saveMatrix(const std::string & filename) const {
AKANTU_DEBUG_IN();
std::ofstream outfile;
outfile.precision(std::numeric_limits<Real>::digits10);
outfile.open(filename.c_str());
outfile << "%%MatrixMarket matrix coordinate real";
if(sparse_matrix_type == _symmetric) outfile << " symmetric";
else outfile << " general";
outfile << std::endl;
outfile << size << " " << size << " " << nb_non_zero << std::endl;
for (UInt i = 0; i < nb_non_zero; ++i) {
outfile << irn(i) << " " << jcn(i) << " " << a(i) << std::endl;
}
outfile.close();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat) {
AKANTU_DEBUG_IN();
// AKANTU_DEBUG_ASSERT((vect.getSize()*vect.getNbComponent() == mat.getSize()) &&
// (vect.getNbComponent() == mat.getNbDegreOfFreedom()),
// "The size of the matrix and the vector do not match");
const SparseMatrixType & sparse_matrix_type = mat.getSparseMatrixType();
DOFSynchronizer * dof_synchronizer = mat.getDOFSynchronizerPointer();
UInt nb_non_zero = mat.getNbNonZero();
Real * tmp = new Real [vect.getNbComponent() * vect.getSize()];
std::fill_n(tmp, vect.getNbComponent() * vect.getSize(), 0);
Int * i_val = mat.getIRN().storage();
Int * j_val = mat.getJCN().storage();
Real * a_val = mat.getA().storage();
Real * vect_val = vect.storage();
for (UInt k = 0; k < nb_non_zero; ++k) {
UInt i = *(i_val++);
UInt j = *(j_val++);
Real a = *(a_val++);
UInt local_i = i - 1;
UInt local_j = j - 1;
if(dof_synchronizer) {
local_i = dof_synchronizer->getDOFLocalID(local_i);
local_j = dof_synchronizer->getDOFLocalID(local_j);
}
tmp[local_i] += a * vect_val[local_j];
if((sparse_matrix_type == _symmetric) && (local_i != local_j))
tmp[local_j] += a * vect_val[local_i];
}
memcpy(vect_val, tmp, vect.getNbComponent() * vect.getSize() * sizeof(Real));
delete [] tmp;
if(dof_synchronizer)
dof_synchronizer->reduceSynchronize<AddOperation>(vect);
AKANTU_DEBUG_OUT();
return vect;
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::copyContent(const SparseMatrix & matrix) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
"The to matrix don't have the same profiles");
memcpy(a.storage(), matrix.getA().storage(), nb_non_zero * sizeof(Real));
AKANTU_DEBUG_OUT();
}
///* -------------------------------------------------------------------------- */
//void SparseMatrix::copyProfile(const SparseMatrix & matrix) {
// AKANTU_DEBUG_IN();
// irn = matrix.irn;
// jcn = matrix.jcn;
// nb_non_zero = matrix.nb_non_zero;
// irn_jcn_k = matrix.irn_jcn_k;
// a.resize(nb_non_zero);
// AKANTU_DEBUG_OUT();
//}
/* -------------------------------------------------------------------------- */
void SparseMatrix::add(const SparseMatrix & matrix, Real alpha) {
AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
"The to matrix don't have the same profiles");
Real * a_val = a.storage();
Real * b_val = matrix.a.storage();
for (UInt n = 0; n < nb_non_zero; ++n) {
*a_val++ += alpha * *b_val++;
}
}
/* -------------------------------------------------------------------------- */
void SparseMatrix::lump(Array<Real> & lumped) {
AKANTU_DEBUG_IN();
UInt vect_size = size / lumped.getNbComponent();
if(dof_synchronizer) vect_size = dof_synchronizer->getNbDOFs() / lumped.getNbComponent();
lumped.resize(vect_size);
lumped.clear();
Int * i_val = irn.storage();
Int * j_val = jcn.storage();
Real * a_val = a.storage();
Real * vect_val = lumped.storage();
for (UInt k = 0; k < nb_non_zero; ++k) {
UInt i = *(i_val++);
UInt j = *(j_val++);
Real a = *(a_val++);
UInt local_i = i - 1;
UInt local_j = j - 1;
if(dof_synchronizer) {
local_i = dof_synchronizer->getDOFLocalID(local_i);
local_j = dof_synchronizer->getDOFLocalID(local_j);
}
vect_val[local_i] += a;
if(sparse_matrix_type == _symmetric && (i != j))
vect_val[local_j] += a;
}
if(dof_synchronizer)
dof_synchronizer->reduceSynchronize<AddOperation>(lumped);
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
+void SparseMatrix::clear() {
+ memset(a.storage(), 0, nb_non_zero*sizeof(Real));
+}
+
__END_AKANTU__
diff --git a/src/solver/sparse_matrix.hh b/src/solver/sparse_matrix.hh
index 21e06031a..99bdf4966 100644
--- a/src/solver/sparse_matrix.hh
+++ b/src/solver/sparse_matrix.hh
@@ -1,252 +1,239 @@
/**
* @file sparse_matrix.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Dec 13 2010
* @date last modification: Mon Sep 15 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_SPARSE_MATRIX_HH__
#define __AKANTU_SPARSE_MATRIX_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
/* -------------------------------------------------------------------------- */
-#ifndef __INTEL_COMPILER
-namespace std {
- namespace tr1 {
- template<typename a, typename b>
- struct hash< std::pair<a, b> > {
- private:
- const hash<a> ah;
- const hash<b> bh;
- public:
- hash() : ah(), bh() {}
- size_t operator()(const std::pair<a, b> &p) const {
- size_t seed = ah(p.first);
- return bh(p.second) + 0x9e3779b9 + (seed<<6) + (seed>>2);
- }
- };
- }
-} // namespaces
-#endif
__BEGIN_AKANTU__
class DOFSynchronizer;
-class SparseMatrix : private Memory {
+class SparseMatrix : protected Memory {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
- SparseMatrix(UInt size,
- const SparseMatrixType & sparse_matrix_type,
- const ID & id = "sparse_matrix",
- const MemoryID & memory_id = 0);
+ SparseMatrix(UInt size, const SparseMatrixType & sparse_matrix_type,
+ const ID & id = "sparse_matrix", const MemoryID & memory_id = 0);
- SparseMatrix(const SparseMatrix & matrix,
- const ID & id = "sparse_matrix",
- const MemoryID & memory_id = 0);
+ SparseMatrix(const SparseMatrix & matrix, const ID & id = "sparse_matrix",
+ const MemoryID & memory_id = 0);
virtual ~SparseMatrix();
typedef std::pair<UInt, UInt> KeyCOO;
typedef unordered_map<KeyCOO, UInt>::type coordinate_list_map;
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/// remove the existing profile
inline void clearProfile();
-
+
/// add a non-zero element
virtual UInt addToProfile(UInt i, UInt j);
/// set the matrix to 0
- inline void clear();
+ 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; }
-
- void buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom);
+ 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.);
-
-// /// modify the matrix to "remove" the blocked dof
-// void applyBoundaryNormal(Array<bool> & boundary_normal, Array<Real> & EulerAngles, Array<Real> & rhs, const Array<Real> & matrix, Array<Real> & rhs_rotated);
+ virtual void buildProfile(const Mesh & mesh,
+ const DOFSynchronizer & dof_synchronizer,
+ UInt nb_degree_of_freedom);
/// modify the matrix to "remove" the blocked dof
- virtual void removeBoundary(const Array<bool> & boundary);
+ virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
- /// restore the profile that was before removing the boundaries
- virtual void restoreProfile();
+ // /// modify the matrix to "remove" the blocked dof
+ // void applyBoundaryNormal(Array<bool> & boundary_normal, Array<Real> &
+ // EulerAngles, Array<Real> & rhs, const Array<Real> & matrix, Array<Real> &
+ // rhs_rotated);
/// save the profil in a file using the MatrixMarket file format
virtual void saveProfile(const std::string & filename) const;
/// save the matrix in a file using the MatrixMarket file format
virtual void saveMatrix(const std::string & filename) const;
/// copy assuming the profile are the same
virtual void copyContent(const SparseMatrix & matrix);
-
+
/// copy profile
-// void copyProfile(const SparseMatrix & matrix);
+ // void copyProfile(const SparseMatrix & matrix);
/// add matrix assuming the profile are the same
virtual void add(const SparseMatrix & matrix, Real alpha);
/// diagonal lumping
virtual void lump(Array<Real> & lumped);
/// function to print the contain of the class
- //virtual void printself(std::ostream & stream, int indent = 0) const;
+ // virtual void printself(std::ostream & stream, int indent = 0) const;
protected:
inline KeyCOO key(UInt i, UInt j) const {
- if(sparse_matrix_type == _symmetric && (i > j))
+ if (sparse_matrix_type == _symmetric && (i > j))
return std::make_pair(j, i);
return std::make_pair(i, j);
}
-
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/// return the values at potition i, j
inline Real operator()(UInt i, UInt j) const;
inline Real & operator()(UInt i, UInt j);
AKANTU_GET_MACRO(IRN, irn, const Array<Int> &);
AKANTU_GET_MACRO(JCN, jcn, const Array<Int> &);
AKANTU_GET_MACRO(A, a, const Array<Real> &);
AKANTU_GET_MACRO(NbNonZero, nb_non_zero, UInt);
AKANTU_GET_MACRO(Size, size, UInt);
- AKANTU_GET_MACRO(SparseMatrixType, sparse_matrix_type, const SparseMatrixType &);
+ AKANTU_GET_MACRO(SparseMatrixType, sparse_matrix_type,
+ const SparseMatrixType &);
+
+ AKANTU_GET_MACRO(Offset, offset, UInt);
const DOFSynchronizer & getDOFSynchronizer() const {
AKANTU_DEBUG_ASSERT(dof_synchronizer != NULL,
- "DOFSynchronizer not initialized in the SparseMatrix!");
+ "DOFSynchronizer not initialized in the SparseMatrix!");
+ return *dof_synchronizer;
+ }
+
+ DOFSynchronizer & getDOFSynchronizer() {
+ AKANTU_DEBUG_ASSERT(dof_synchronizer != NULL,
+ "DOFSynchronizer not initialized in the SparseMatrix!");
return *dof_synchronizer;
}
private:
AKANTU_GET_MACRO(DOFSynchronizerPointer, dof_synchronizer, DOFSynchronizer *);
friend Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
protected:
/// id of the SparseMatrix
ID id;
/// sparce matrix type
SparseMatrixType sparse_matrix_type;
/// Mesh corresponding to the profile
// const Mesh * mesh;
/// Size of the matrix
UInt size;
/// number of processors
UInt nb_proc;
/// number of non zero element
UInt nb_non_zero;
/// row indexes
Array<Int> irn;
/// column indexes
Array<Int> jcn;
/// values : A[k] = Matrix[irn[k]][jcn[k]]
Array<Real> a;
-
/// saved row indexes
Array<Int> * irn_save;
/// saved column indexes
Array<Int> * jcn_save;
/// saved size
UInt size_save;
/// information to know where to assemble an element in a global sparse matrix
// ElementTypeMapArray<UInt> element_to_sparse_profile;
/* map for (i,j) -> k correspondence \warning std::map are slow
- * \todo improve with hash_map (non standard in stl) or unordered_map (boost or C++0x)
+ * \todo improve with hash_map (non standard in stl) or unordered_map (boost
+ * or C++0x)
*/
coordinate_list_map irn_jcn_k;
DOFSynchronizer * dof_synchronizer;
// std::map<std::pair<UInt, UInt>, UInt> * irn_jcn_to_k;
-};
+ /// offset to inidcate whether row and column indices start at 0 (C/C++) or 1
+ /// (Fortran)
+ UInt offset;
+};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
-#if defined (AKANTU_INCLUDE_INLINE_IMPL)
-# include "sparse_matrix_inline_impl.cc"
+#if defined(AKANTU_INCLUDE_INLINE_IMPL)
+#include "sparse_matrix_inline_impl.cc"
#endif
// /// standard output stream operator
-// inline std::ostream & operator <<(std::ostream & stream, const SparseMatrix & _this)
+// inline std::ostream & operator <<(std::ostream & stream, const SparseMatrix &
+// _this)
// {
// _this.printself(stream);
// return stream;
// }
Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat);
-
__END_AKANTU__
#endif /* __AKANTU_SPARSE_MATRIX_HH__ */
diff --git a/src/solver/sparse_matrix_inline_impl.cc b/src/solver/sparse_matrix_inline_impl.cc
index abfa0540e..dfaf5baa1 100644
--- a/src/solver/sparse_matrix_inline_impl.cc
+++ b/src/solver/sparse_matrix_inline_impl.cc
@@ -1,145 +1,141 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
inline UInt SparseMatrix::addToProfile(UInt i, UInt j) {
KeyCOO jcn_irn = key(i, j);
coordinate_list_map::iterator it = irn_jcn_k.find(jcn_irn);
if (!(it == irn_jcn_k.end()))
return it->second;
// AKANTU_DEBUG_ASSERT(irn_jcn_k.find(jcn_irn) == irn_jcn_k.end(),
// "Couple (i,j) = (" << i << "," << j << ") already in the profile");
irn.push_back(i + 1);
jcn.push_back(j + 1);
// a.resize(a.getSize() + 1);
Real zero = 0;
a.push_back(zero);
irn_jcn_k[jcn_irn] = nb_non_zero;
nb_non_zero++;
return nb_non_zero - 1;
}
/* -------------------------------------------------------------------------- */
inline void SparseMatrix::clearProfile() {
irn_jcn_k.clear();
irn.resize(0);
jcn.resize(0);
a.resize(0);
nb_non_zero = 0;
}
-/* -------------------------------------------------------------------------- */
-inline void SparseMatrix::clear() {
- memset(a.storage(), 0, nb_non_zero*sizeof(Real));
-}
/* -------------------------------------------------------------------------- */
inline void SparseMatrix::addToMatrix(UInt i, UInt j, Real value) {
KeyCOO jcn_irn = key(i, j);
coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
AKANTU_DEBUG_ASSERT(irn_jcn_k_it != irn_jcn_k.end(),
"Couple (i,j) = (" << i << "," << j << ") does not exist in the profile");
a.storage()[irn_jcn_k_it->second] += value;
}
/* -------------------------------------------------------------------------- */
inline Real SparseMatrix::operator()(UInt i, UInt j) const {
KeyCOO jcn_irn = key(i, j);
coordinate_list_map::const_iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
if(irn_jcn_k_it == irn_jcn_k.end()) return 0;
return a.storage()[irn_jcn_k_it->second];
}
/* -------------------------------------------------------------------------- */
inline Real & SparseMatrix::operator()(UInt i, UInt j) {
KeyCOO jcn_irn = key(i, j);
coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
AKANTU_DEBUG_ASSERT(irn_jcn_k_it != irn_jcn_k.end(),
"Couple (i,j) = (" << i << "," << j << ") does not exist in the profile");
return a.storage()[irn_jcn_k_it->second];
}
/* -------------------------------------------------------------------------- */
// inline void SparseMatrix::addToMatrixSym(const Array<Real> & local_matrix,
// const Element & element) {
// AKANTU_DEBUG_ASSERT(element_to_sparse_profile[element.type] != NULL,
// "No profile stored for this kind of element call first buildProfile()");
// UInt nb_values_per_elem = element_to_sparse_profile[element.type]->getNbComponent();
// UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(element.type);
// Real * mat_val = local_matrix.storage();
// UInt * elem_to_sparse_val = element_to_sparse_profile[element.type]->values + element.element * nb_values_per_elem;
// Real * a_val = a.storage();
// for (UInt j = 0; j < nb_nodes_per_element * nb_degree_of_freedom; ++j) {
// UInt i_end = (sparse_matrix_type == _symmetric) ? j + 1 :
// nb_nodes_per_element * nb_degree_of_freedom;
// for (UInt i = 0; i < i_end; ++i) {
// UInt k = *(elem_to_sparse_val++);
// a_val[k] += *(mat_val++);
// }
// }
// }
/* -------------------------------------------------------------------------- */
// inline void SparseMatrix::addToMatrix(Real * local_matrix,
// const Element & element,
// UInt nb_nodes_per_element) {
// AKANTU_DEBUG_ASSERT(element_to_sparse_profile[element.type] != NULL,
// "No profile stored for this kind of element call first buildProfile()");
// UInt nb_values_per_elem = element_to_sparse_profile[element.type]->getNbComponent();
// // UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(element.type);
// Real * mat_val = local_matrix;
// UInt * elem_to_sparse_val = element_to_sparse_profile[element.type]->values + element.element * nb_values_per_elem;
// Real * a_val = a.storage();
// for (UInt i = 0; i < nb_nodes_per_element * nb_degree_of_freedom; ++i) {
// UInt j_start = (sparse_matrix_type == _symmetric) ? i : 0;
// UInt elem_to_sparse_i = i * nb_nodes_per_element * nb_degree_of_freedom;
// for (UInt j = j_start; j < nb_nodes_per_element * nb_degree_of_freedom; ++j) {
// UInt k = elem_to_sparse_val[elem_to_sparse_i + j];
// a_val[k] += mat_val[elem_to_sparse_i + j];
// }
// }
// }
diff --git a/src/solver/static_solver.cc b/src/solver/static_solver.cc
new file mode 100644
index 000000000..9358381c5
--- /dev/null
+++ b/src/solver/static_solver.cc
@@ -0,0 +1,112 @@
+/**
+ * @file static_solver.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Jul 30 15:35:01 2014
+ *
+ * @brief implementation of the static solver
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "static_solver.hh"
+/* -------------------------------------------------------------------------- */
+#ifdef AKANTU_USE_PETSC
+#include <petscsys.h>
+#endif
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+StaticSolver::StaticSolver() : CommunicatorEventHandler(), is_initialized(false) {
+ StaticCommunicator::getStaticCommunicator().registerEventHandler(*this);
+}
+
+
+/* -------------------------------------------------------------------------- */
+StaticSolver::~StaticSolver() {
+ --this->nb_references;
+ if(this->nb_references == 0) {
+ StaticCommunicator::getStaticCommunicator().unregisterEventHandler(*this);
+ delete this->static_solver;
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+StaticSolver & StaticSolver::getStaticSolver() {
+ if(nb_references == 0)
+ static_solver = new StaticSolver();
+ ++nb_references;
+ return *static_solver;
+}
+
+#ifdef AKANTU_USE_PETSC
+#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
+static PetscErrorCode PETScErrorHandler(MPI_Comm,
+ int line, const char * dir, const char *file,
+ PetscErrorCode number,
+ PetscErrorType type,
+ const char *message,
+ void *) {
+ AKANTU_DEBUG_ERROR("An error occured in PETSc in file \"" << file << ":" << line << "\" - PetscErrorCode "<< number << " - \""<< message << "\"");
+}
+#else
+static PetscErrorCode PETScErrorHandler(MPI_Comm,
+ int line, const char * func, const char * dir, const char *file,
+ PetscErrorCode number,
+ PetscErrorType type,
+ const char *message,
+ void *) {
+ AKANTU_DEBUG_ERROR("An error occured in PETSc in file \"" << file << ":" << line << "\" - PetscErrorCode "<< number << " - \""<< message << "\"");
+}
+#endif
+#endif
+
+/* -------------------------------------------------------------------------- */
+void StaticSolver::initialize(int & argc, char ** & argv) {
+ if (this->is_initialized) return;
+ // AKANTU_DEBUG_ASSERT(this->is_initialized != true, "The static solver has already been initialized");
+#ifdef AKANTU_USE_PETSC
+ PetscErrorCode petsc_error = PetscInitialize(&argc, &argv, NULL, NULL);
+ if(petsc_error != 0) {
+ AKANTU_DEBUG_ERROR("An error occured while initializing Petsc (PetscErrorCode "<< petsc_error << ")");
+ }
+ PetscPushErrorHandler(PETScErrorHandler, NULL);
+#endif
+
+ this->is_initialized = true;
+ }
+
+/* -------------------------------------------------------------------------- */
+void StaticSolver::finalize() {
+ ParentEventHandler::sendEvent(StaticSolverEvent::BeforeStaticSolverDestroyEvent());
+
+
+ AKANTU_DEBUG_ASSERT(this->is_initialized == true, "The static solver has not been initialized");
+#ifdef AKANTU_USE_PETSC
+ PetscFinalize();
+#endif
+
+ this->is_initialized = false;
+}
+
+__END_AKANTU__
diff --git a/src/solver/static_solver.hh b/src/solver/static_solver.hh
new file mode 100644
index 000000000..73923f221
--- /dev/null
+++ b/src/solver/static_solver.hh
@@ -0,0 +1,108 @@
+/**
+ * @file static_solver.hh
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Jul 30 14:44:12 2014
+ *
+ * @brief Class handeling the initialization of external solvers
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "aka_common.hh"
+#include "static_communicator.hh"
+
+
+#ifndef __AKANTU_STATIC_SOLVER_HH__
+#define __AKANTU_STATIC_SOLVER_HH__
+
+__BEGIN_AKANTU__
+
+namespace StaticSolverEvent {
+ struct BeforeStaticSolverDestroyEvent {
+ BeforeStaticSolverDestroyEvent() {}
+ };
+}
+
+class StaticSolverEventHandler {
+ /* ------------------------------------------------------------------------ */
+ /* Constructors/Destructors */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual ~StaticSolverEventHandler() {};
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+protected:
+ inline void sendEvent(const StaticSolverEvent::BeforeStaticSolverDestroyEvent & event) {
+ this->beforeStaticSolverDestroy();
+ }
+
+ template<class EventHandler> friend class EventHandlerManager;
+
+ /* ------------------------------------------------------------------------ */
+ /* Interface */
+ /* ------------------------------------------------------------------------ */
+public:
+ virtual void beforeStaticSolverDestroy() {}
+};
+
+
+
+class StaticSolver : public CommunicatorEventHandler,
+ public EventHandlerManager<StaticSolverEventHandler> {
+ typedef EventHandlerManager<StaticSolverEventHandler> ParentEventHandler;
+ /* ------------------------------------------------------------------------ */
+ /* Constructors */
+ /* ------------------------------------------------------------------------ */
+private:
+ StaticSolver();
+
+public:
+ ~StaticSolver();
+
+ /* ------------------------------------------------------------------------ */
+ /// get an instance to the static solver
+ static StaticSolver & getStaticSolver();
+
+ /* ------------------------------------------------------------------------ */
+ /* Methods */
+ /* ------------------------------------------------------------------------ */
+public:
+ /// initialize what is needed for the compiled solver interfaces
+ void initialize(int & argc, char ** & argv);
+
+ /// finalize what is needed for the compiled solver interfaces
+ void finalize();
+
+ /* ------------------------------------------------------------------------ */
+ /* Members */
+ /* ------------------------------------------------------------------------ */
+private:
+ bool is_initialized;
+ static UInt nb_references;
+ static StaticSolver * static_solver;
+};
+
+__END_AKANTU__
+
+
+#endif /* __AKANTU_STATIC_SOLVER_HH__ */
diff --git a/src/synchronizer/data_accessor.hh b/src/synchronizer/data_accessor.hh
index 8324bdc8c..d9834cfe8 100644
--- a/src/synchronizer/data_accessor.hh
+++ b/src/synchronizer/data_accessor.hh
@@ -1,217 +1,268 @@
/**
* @file data_accessor.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jun 16 2011
* @date last modification: Thu Jun 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_DATA_ACCESSOR_HH__
#define __AKANTU_DATA_ACCESSOR_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "fe_engine.hh"
#include "communication_buffer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
class DataAccessor {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
DataAccessor();
virtual ~DataAccessor();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/**
* @brief get the number of data to exchange for a given akantu::Element and a
* given akantu::SynchronizationTag
*/
virtual UInt getNbDataForElements(__attribute__((unused)) const Array<Element> & elements,
__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
+ /**
+ * @brief get the number of data to exchange for a given degree of freedom and a
+ * given akantu::SynchronizationTag
+ */
+ virtual UInt getNbDataForDOFs(__attribute__((unused)) const Array<UInt> & dofs,
+ __attribute__((unused)) SynchronizationTag tag) const {
+ AKANTU_DEBUG_TO_IMPLEMENT();
+ }
+
/**
* @brief get the number of data to send for a given
* akantu::SynchronizationTag
*/
virtual UInt getNbDataToPack(__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief get the number of data to receive for a given
* akantu::SynchronizationTag
*/
virtual UInt getNbDataToUnpack(__attribute__((unused)) SynchronizationTag tag) const {
AKANTU_DEBUG_TO_IMPLEMENT();
}
/**
* @brief pack the data for a given akantu::Element and a given
* akantu::SynchronizationTag
*/
virtual void packElementData(__attribute__((unused)) CommunicationBuffer & buffer,
- __attribute__((unused)) const Array<Element> & element,
- __attribute__((unused)) SynchronizationTag tag) const {
+ __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 {
+ 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) {
+ 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>
- inline void unpackElementalDataHelper(ElementTypeMapArray<T> & data_to_unpack,
+ 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);
+
+ template<typename T>
+ static inline void packDOFDataHelper(const Array<T> & data_to_pack,
+ CommunicationBuffer & buffer,
+ const Array<UInt> & dofs) {
+ packUnpackDOFDataHelper<T, true>(const_cast<Array<T> &>(data_to_pack),
+ buffer,
+ dofs);
+ }
+
+ template<typename T>
+ static inline void unpackDOFDataHelper(Array<T> & data_to_unpack,
+ CommunicationBuffer & buffer,
+ const Array<UInt> & dofs) {
+ packUnpackDOFDataHelper<T, false>(data_to_unpack,
+ buffer,
+ dofs);
}
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "data_accessor_inline_impl.cc"
// /// standard output stream operator
// inline std::ostream & operator <<(std::ostream & stream, const DataAccessor & _this)
// {
// _this.printself(stream);
// return stream;
// }
__END_AKANTU__
#endif /* __AKANTU_DATA_ACCESSOR_HH__ */
diff --git a/src/synchronizer/data_accessor_inline_impl.cc b/src/synchronizer/data_accessor_inline_impl.cc
index dc8c0b6dc..dda6c4860 100644
--- a/src/synchronizer/data_accessor_inline_impl.cc
+++ b/src/synchronizer/data_accessor_inline_impl.cc
@@ -1,107 +1,125 @@
/**
* @file data_accessor_inline_impl.cc
*
* @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
*
* @brief Implementation of the inline functions of the DataAccessor 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/>.
*
*/
/* -------------------------------------------------------------------------- */
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 c497e7069..6e37e198f 100644
--- a/src/synchronizer/distributed_synchronizer.cc
+++ b/src/synchronizer/distributed_synchronizer.cc
@@ -1,1652 +1,1722 @@
/**
* @file distributed_synchronizer.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
* @author Marco Vocialta <marco.vocialta@epfl.ch>
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jun 16 2011
* @date last modification: Fri Sep 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "distributed_synchronizer.hh"
#include "static_communicator.hh"
#include "mesh_utils.hh"
#include "mesh_data.hh"
#include "element_group.hh"
/* -------------------------------------------------------------------------- */
#include <map>
#include <iostream>
#include <algorithm>
#if defined(AKANTU_DEBUG_TOOLS)
# include "aka_debug_tools.hh"
#endif
/* -------------------------------------------------------------------------- */
__BEGIN_AKANTU__
/* -------------------------------------------------------------------------- */
DistributedSynchronizer::DistributedSynchronizer(Mesh & mesh,
SynchronizerID id,
- MemoryID memory_id) :
+ MemoryID memory_id,
+ const bool register_to_event_manager) :
Synchronizer(id, memory_id),
mesh(mesh),
- static_communicator(&StaticCommunicator::getStaticCommunicator()),
prank_to_element("prank_to_element", id)
{
AKANTU_DEBUG_IN();
nb_proc = static_communicator->getNbProc();
rank = static_communicator->whoAmI();
send_element = new Array<Element>[nb_proc];
recv_element = new Array<Element>[nb_proc];
- 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;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
DistributedSynchronizer * DistributedSynchronizer::
createDistributedSynchronizerMesh(Mesh & mesh,
const MeshPartition * partition,
UInt root,
SynchronizerID id,
MemoryID memory_id) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
DistributedSynchronizer & communicator = *(new DistributedSynchronizer(mesh, id, memory_id));
if(nb_proc == 1) return &communicator;
UInt * local_connectivity = NULL;
UInt * local_partitions = NULL;
Array<UInt> * old_nodes = mesh.getNodesGlobalIdsPointer();
old_nodes->resize(0);
Array<Real> * nodes = mesh.getNodesPointer();
UInt spatial_dimension = nodes->getNbComponent();
mesh.synchronizeGroupNames();
/* ------------------------------------------------------------------------ */
/* Local (rank == root) */
/* ------------------------------------------------------------------------ */
if(my_rank == root) {
AKANTU_DEBUG_ASSERT(partition->getNbPartition() == nb_proc,
"The number of partition does not match the number of processors: " <<
partition->getNbPartition() << " != " << nb_proc);
/**
* connectivity and communications scheme construction
*/
Mesh::type_iterator it = mesh.firstType(_all_dimensions,
_not_ghost,
_ek_not_defined);
Mesh::type_iterator end = mesh.lastType(_all_dimensions,
_not_ghost,
_ek_not_defined);
UInt count = 0;
/* --- MAIN LOOP ON TYPES --- */
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_element = mesh.getNbElement(*it);
UInt nb_local_element[nb_proc];
UInt nb_ghost_element[nb_proc];
UInt nb_element_to_send[nb_proc];
memset(nb_local_element, 0, nb_proc*sizeof(UInt));
memset(nb_ghost_element, 0, nb_proc*sizeof(UInt));
memset(nb_element_to_send, 0, nb_proc*sizeof(UInt));
/// \todo change this ugly way to avoid a problem if an element
/// type is present in the mesh but not in the partitions
const Array<UInt> * tmp_partition_num = NULL;
try {
tmp_partition_num = &partition->getPartition(type, _not_ghost);
} catch(...) {
continue;
}
const Array<UInt> & partition_num = *tmp_partition_num;
const CSR<UInt> & ghost_partition = partition->getGhostPartitionCSR()(type, _not_ghost);
/* -------------------------------------------------------------------- */
/// constructing the reordering structures
for (UInt el = 0; el < nb_element; ++el) {
nb_local_element[partition_num(el)]++;
for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
part != ghost_partition.end(el);
++part) {
nb_ghost_element[*part]++;
}
nb_element_to_send[partition_num(el)] += ghost_partition.getNbCols(el) + 1;
}
/// allocating buffers
UInt * buffers[nb_proc];
UInt * buffers_tmp[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
UInt size = nb_nodes_per_element * (nb_local_element[p] +
nb_ghost_element[p]);
buffers[p] = new UInt[size];
buffers_tmp[p] = buffers[p];
}
/// copying the local connectivity
UInt * conn_val = mesh.getConnectivity(type, _not_ghost).storage();
for (UInt el = 0; el < nb_element; ++el) {
memcpy(buffers_tmp[partition_num(el)],
conn_val + el * nb_nodes_per_element,
nb_nodes_per_element * sizeof(UInt));
buffers_tmp[partition_num(el)] += nb_nodes_per_element;
}
/// copying the connectivity of ghost element
for (UInt el = 0; el < nb_element; ++el) {
for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
part != ghost_partition.end(el);
++part) {
UInt proc = *part;
memcpy(buffers_tmp[proc],
conn_val + el * nb_nodes_per_element,
nb_nodes_per_element * sizeof(UInt));
buffers_tmp[proc] += nb_nodes_per_element;
}
}
/// tag info
std::vector<std::string> tag_names;
mesh.getMeshData().getTagNames(tag_names, type);
UInt nb_tags = tag_names.size();
/* -------->>>>-SIZE + CONNECTIVITY------------------------------------ */
/// send all connectivity and ghost information to all processors
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
UInt size[5];
size[0] = (UInt) type;
size[1] = nb_local_element[p];
size[2] = nb_ghost_element[p];
size[3] = nb_element_to_send[p];
size[4] = nb_tags;
AKANTU_DEBUG_INFO("Sending connectivities informations to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_SIZES) <<")");
comm.send(size, 5, p, Tag::genTag(my_rank, count, TAG_SIZES));
AKANTU_DEBUG_INFO("Sending connectivities to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_CONNECTIVITY) <<")");
requests.push_back(comm.asyncSend(buffers[p],
nb_nodes_per_element * (nb_local_element[p] +
nb_ghost_element[p]),
p, Tag::genTag(my_rank, count, TAG_CONNECTIVITY)));
} else {
local_connectivity = buffers[p];
}
}
/// create the renumbered connectivity
AKANTU_DEBUG_INFO("Renumbering local connectivities");
MeshUtils::renumberMeshNodes(mesh,
local_connectivity,
nb_local_element[root],
nb_ghost_element[root],
type,
*old_nodes);
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
for (UInt p = 0; p < nb_proc; ++p) {
delete [] buffers[p];
}
/* -------------------------------------------------------------------- */
for (UInt p = 0; p < nb_proc; ++p) {
buffers[p] = new UInt[nb_ghost_element[p] + nb_element_to_send[p]];
buffers_tmp[p] = buffers[p];
}
/// splitting the partition information to send them to processors
UInt count_by_proc[nb_proc];
memset(count_by_proc, 0, nb_proc*sizeof(UInt));
for (UInt el = 0; el < nb_element; ++el) {
*(buffers_tmp[partition_num(el)]++) = ghost_partition.getNbCols(el);
UInt i(0);
for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
part != ghost_partition.end(el);
++part, ++i) {
*(buffers_tmp[partition_num(el)]++) = *part;
}
}
for (UInt el = 0; el < nb_element; ++el) {
UInt i(0);
for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
part != ghost_partition.end(el);
++part, ++i) {
*(buffers_tmp[*part]++) = partition_num(el);
}
}
/* -------->>>>-PARTITIONS--------------------------------------------- */
/// last data to compute the communication scheme
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
AKANTU_DEBUG_INFO("Sending partition informations to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_PARTITIONS) <<")");
requests.push_back(comm.asyncSend(buffers[p],
nb_element_to_send[p] + nb_ghost_element[p],
p, Tag::genTag(my_rank, count, TAG_PARTITIONS)));
} else {
local_partitions = buffers[p];
}
}
if(Mesh::getSpatialDimension(type) == mesh.getSpatialDimension()) {
AKANTU_DEBUG_INFO("Creating communications scheme");
communicator.fillCommunicationScheme(local_partitions,
nb_local_element[root],
nb_ghost_element[root],
type);
}
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
for (UInt p = 0; p < nb_proc; ++p) {
delete [] buffers[p];
}
/* -------------------------------------------------------------------- */
/// send data assossiated to the mesh
/* -------->>>>-TAGS--------------------------------------------------- */
synchronizeTagsSend(communicator, root, mesh, nb_tags, type,
partition_num,
ghost_partition,
nb_local_element[root],
nb_ghost_element[root]);
/* -------------------------------------------------------------------- */
/// send data assossiated to groups
/* -------->>>>-GROUPS------------------------------------------------- */
synchronizeElementGroups(communicator, root, mesh, type,
partition_num,
ghost_partition,
nb_element);
++count;
}
/* -------->>>>-SIZE----------------------------------------------------- */
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
UInt size[5];
size[0] = (UInt) _not_defined;
size[1] = 0;
size[2] = 0;
size[3] = 0;
size[4] = 0;
AKANTU_DEBUG_INFO("Sending empty connectivities informations to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_SIZES) <<")");
comm.send(size, 5, p, Tag::genTag(my_rank, count, TAG_SIZES));
}
}
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/**
* Nodes coordinate construction and synchronization
*/
std::multimap< UInt, std::pair<UInt, UInt> > nodes_to_proc;
/// get the list of nodes to send and send them
Real * local_nodes = NULL;
UInt nb_nodes_per_proc[nb_proc];
UInt * nodes_per_proc[nb_proc];
comm.broadcast(&(mesh.nb_global_nodes), 1, root);
/* --------<<<<-NB_NODES + NODES----------------------------------------- */
for (UInt p = 0; p < nb_proc; ++p) {
UInt nb_nodes = 0;
// UInt * buffer;
if(p != root) {
AKANTU_DEBUG_INFO("Receiving number of nodes from proc " << p << " TAG("<< Tag::genTag(p, 0, TAG_NB_NODES) <<")");
comm.receive(&nb_nodes, 1, p, Tag::genTag(p, 0, TAG_NB_NODES));
nodes_per_proc[p] = new UInt[nb_nodes];
nb_nodes_per_proc[p] = nb_nodes;
AKANTU_DEBUG_INFO("Receiving list of nodes from proc " << p << " TAG("<< Tag::genTag(p, 0, TAG_NODES) <<")");
comm.receive(nodes_per_proc[p], nb_nodes, p, Tag::genTag(p, 0, TAG_NODES));
} else {
nb_nodes = old_nodes->getSize();
nb_nodes_per_proc[p] = nb_nodes;
nodes_per_proc[p] = old_nodes->storage();
}
/// get the coordinates for the selected nodes
Real * nodes_to_send = new Real[nb_nodes * spatial_dimension];
Real * nodes_to_send_tmp = nodes_to_send;
for (UInt n = 0; n < nb_nodes; ++n) {
memcpy(nodes_to_send_tmp,
nodes->storage() + spatial_dimension * nodes_per_proc[p][n],
spatial_dimension * sizeof(Real));
// nodes_to_proc.insert(std::make_pair(buffer[n], std::make_pair(p, n)));
nodes_to_send_tmp += spatial_dimension;
}
/* -------->>>>-COORDINATES-------------------------------------------- */
if(p != root) { /// send them for distant processors
AKANTU_DEBUG_INFO("Sending coordinates to proc " << p << " TAG("<< Tag::genTag(my_rank, 0, TAG_COORDINATES) <<")");
comm.send(nodes_to_send, nb_nodes * spatial_dimension, p, Tag::genTag(my_rank, 0, TAG_COORDINATES));
delete [] nodes_to_send;
} else { /// save them for local processor
local_nodes = nodes_to_send;
}
}
/// construct the local nodes coordinates
UInt nb_nodes = old_nodes->getSize();
nodes->resize(nb_nodes);
memcpy(nodes->storage(), local_nodes, nb_nodes * spatial_dimension * sizeof(Real));
delete [] local_nodes;
Array<Int> * nodes_type_per_proc[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
nodes_type_per_proc[p] = new Array<Int>(nb_nodes_per_proc[p]);
}
communicator.fillNodesType(mesh);
/* --------<<<<-NODES_TYPE-1--------------------------------------------- */
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
AKANTU_DEBUG_INFO("Receiving first nodes types from proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_NODES_TYPE) <<")");
comm.receive(nodes_type_per_proc[p]->storage(),
nb_nodes_per_proc[p], p, Tag::genTag(p, 0, TAG_NODES_TYPE));
} else {
nodes_type_per_proc[p]->copy(mesh.getNodesType());
}
for (UInt n = 0; n < nb_nodes_per_proc[p]; ++n) {
if((*nodes_type_per_proc[p])(n) == -2)
nodes_to_proc.insert(std::make_pair(nodes_per_proc[p][n], std::make_pair(p, n)));
}
}
std::multimap< UInt, std::pair<UInt, UInt> >::iterator it_node;
std::pair< std::multimap< UInt, std::pair<UInt, UInt> >::iterator,
std::multimap< UInt, std::pair<UInt, UInt> >::iterator > it_range;
for (UInt i = 0; i < mesh.nb_global_nodes; ++i) {
it_range = nodes_to_proc.equal_range(i);
if(it_range.first == nodes_to_proc.end() || it_range.first->first != i) continue;
UInt node_type = (it_range.first)->second.first;
for (it_node = it_range.first; it_node != it_range.second; ++it_node) {
UInt proc = it_node->second.first;
UInt node = it_node->second.second;
if(proc != node_type)
nodes_type_per_proc[proc]->storage()[node] = node_type;
}
}
/* -------->>>>-NODES_TYPE-2--------------------------------------------- */
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
AKANTU_DEBUG_INFO("Sending nodes types to proc " << p << " TAG("<< Tag::genTag(my_rank, 0, TAG_NODES_TYPE) <<")");
requests.push_back(comm.asyncSend(nodes_type_per_proc[p]->storage(),
nb_nodes_per_proc[p], p, Tag::genTag(my_rank, 0, TAG_NODES_TYPE)));
} else {
mesh.getNodesTypePointer()->copy(*nodes_type_per_proc[p]);
}
}
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) delete [] nodes_per_proc[p];
delete nodes_type_per_proc[p];
}
/* -------->>>>-NODE GROUPS --------------------------------------------- */
synchronizeNodeGroupsMaster(communicator, root, mesh);
/* ---------------------------------------------------------------------- */
/* Distant (rank != root) */
/* ---------------------------------------------------------------------- */
} else {
/**
* connectivity and communications scheme construction on distant processors
*/
ElementType type = _not_defined;
UInt count = 0;
do {
/* --------<<<<-SIZE--------------------------------------------------- */
UInt size[5] = { 0 };
comm.receive(size, 5, root, Tag::genTag(root, count, TAG_SIZES));
type = (ElementType) size[0];
UInt nb_local_element = size[1];
UInt nb_ghost_element = size[2];
UInt nb_element_to_send = size[3];
UInt nb_tags = size[4];
if(type != _not_defined) {
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
/* --------<<<<-CONNECTIVITY----------------------------------------- */
local_connectivity = new UInt[(nb_local_element + nb_ghost_element) *
nb_nodes_per_element];
AKANTU_DEBUG_INFO("Receiving connectivities from proc " << root);
comm.receive(local_connectivity, nb_nodes_per_element * (nb_local_element +
nb_ghost_element),
root, Tag::genTag(root, count, TAG_CONNECTIVITY));
AKANTU_DEBUG_INFO("Renumbering local connectivities");
MeshUtils::renumberMeshNodes(mesh,
local_connectivity,
nb_local_element,
nb_ghost_element,
type,
*old_nodes);
delete [] local_connectivity;
/* --------<<<<-PARTITIONS--------------------------------------------- */
local_partitions = new UInt[nb_element_to_send + nb_ghost_element * 2];
AKANTU_DEBUG_INFO("Receiving partition informations from proc " << root);
comm.receive(local_partitions,
nb_element_to_send + nb_ghost_element * 2,
root, Tag::genTag(root, count, TAG_PARTITIONS));
if(Mesh::getSpatialDimension(type) == mesh.getSpatialDimension()) {
AKANTU_DEBUG_INFO("Creating communications scheme");
communicator.fillCommunicationScheme(local_partitions,
nb_local_element,
nb_ghost_element,
type);
}
delete [] local_partitions;
/* --------<<<<-TAGS------------------------------------------------- */
synchronizeTagsRecv(communicator, root, mesh, nb_tags, type,
nb_local_element,
nb_ghost_element);
/* --------<<<<-GROUPS----------------------------------------------- */
synchronizeElementGroups(communicator, root, mesh, type);
}
++count;
} while(type != _not_defined);
/**
* Nodes coordinate construction and synchronization on distant processors
*/
comm.broadcast(&(mesh.nb_global_nodes), 1, root);
/* -------->>>>-NB_NODES + NODES----------------------------------------- */
AKANTU_DEBUG_INFO("Sending list of nodes to proc " << root);
UInt nb_nodes = old_nodes->getSize();
comm.send(&nb_nodes, 1, root, Tag::genTag(my_rank, 0, TAG_NB_NODES));
comm.send(old_nodes->storage(), nb_nodes, root, Tag::genTag(my_rank, 0, TAG_NODES));
/* --------<<<<-COORDINATES---------------------------------------------- */
nodes->resize(nb_nodes);
AKANTU_DEBUG_INFO("Receiving coordinates from proc " << root);
comm.receive(nodes->storage(), nb_nodes * spatial_dimension, root, Tag::genTag(root, 0, TAG_COORDINATES));
communicator.fillNodesType(mesh);
/* -------->>>>-NODES_TYPE-1--------------------------------------------- */
Int * nodes_types = mesh.getNodesTypePointer()->storage();
AKANTU_DEBUG_INFO("Sending first nodes types to proc " << root);
comm.send(nodes_types, nb_nodes,
root, Tag::genTag(my_rank, 0, TAG_NODES_TYPE));
/* --------<<<<-NODES_TYPE-2--------------------------------------------- */
AKANTU_DEBUG_INFO("Receiving nodes types from proc " << root);
comm.receive(nodes_types, nb_nodes,
root, Tag::genTag(root, 0, TAG_NODES_TYPE));
/* --------<<<<-NODE GROUPS --------------------------------------------- */
synchronizeNodeGroupsSlaves(communicator, root, mesh);
}
MeshUtils::fillElementToSubElementsData(mesh);
mesh.is_distributed = true;
AKANTU_DEBUG_OUT();
return &communicator;
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::fillTagBuffer(const MeshData & mesh_data,
DynamicCommunicationBuffer * buffers,
const std::string & tag_name,
const ElementType & el_type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition) {
#define AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA(r, extra_param, elem) \
case BOOST_PP_TUPLE_ELEM(2, 0, elem) : { \
fillTagBufferTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(mesh_data, buffers, tag_name, el_type, partition_num, ghost_partition); \
break; \
} \
MeshDataTypeCode data_type_code = mesh_data.getTypeCode(tag_name);
switch(data_type_code) {
BOOST_PP_SEQ_FOR_EACH(AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA, , AKANTU_MESH_DATA_TYPES)
default : AKANTU_DEBUG_ERROR("Could not obtain the type of tag" << tag_name << "!"); break;
}
#undef AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::fillNodesType(Mesh & mesh) {
AKANTU_DEBUG_IN();
UInt nb_nodes = mesh.getNbNodes();
Int * nodes_type = mesh.getNodesTypePointer()->storage();
UInt * nodes_set = new UInt[nb_nodes];
std::fill_n(nodes_set, nb_nodes, 0);
const UInt NORMAL_SET = 1;
const UInt GHOST_SET = 2;
bool * already_seen = new bool[nb_nodes];
for(UInt g = _not_ghost; g <= _ghost; ++g) {
GhostType gt = (GhostType) g;
UInt set = NORMAL_SET;
if (gt == _ghost) set = GHOST_SET;
std::fill_n(already_seen, nb_nodes, false);
Mesh::type_iterator it = mesh.firstType(_all_dimensions, gt, _ek_not_defined);
Mesh::type_iterator end = mesh.lastType(_all_dimensions, gt, _ek_not_defined);
for(; it != end; ++it) {
ElementType type = *it;
UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
UInt nb_element = mesh.getNbElement(type, gt);
Array<UInt>::iterator< Vector<UInt> > conn_it = mesh.getConnectivity(type, gt).begin(nb_nodes_per_element);
for (UInt e = 0; e < nb_element; ++e, ++conn_it) {
Vector<UInt> & conn = *conn_it;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
AKANTU_DEBUG_ASSERT(conn(n) < nb_nodes, "Node " << conn(n)
<< " bigger than number of nodes " << nb_nodes);
if(!already_seen[conn(n)]) {
nodes_set[conn(n)] += set;
already_seen[conn(n)] = true;
}
}
}
}
}
delete [] already_seen;
for (UInt i = 0; i < nb_nodes; ++i) {
if(nodes_set[i] == NORMAL_SET) nodes_type[i] = -1;
else if(nodes_set[i] == GHOST_SET) nodes_type[i] = -3;
else if(nodes_set[i] == (GHOST_SET + NORMAL_SET)) nodes_type[i] = -2;
}
delete [] nodes_set;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::fillCommunicationScheme(const UInt * partition,
UInt nb_local_element,
UInt nb_ghost_element,
ElementType type) {
AKANTU_DEBUG_IN();
Element element;
element.type = type;
element.kind = Mesh::getKind(type);
const UInt * part = partition;
part = partition;
for (UInt lel = 0; lel < nb_local_element; ++lel) {
UInt nb_send = *part; part++;
element.element = lel;
element.ghost_type = _not_ghost;
for (UInt p = 0; p < nb_send; ++p) {
UInt proc = *part; part++;
AKANTU_DEBUG(dblAccessory, "Must send : " << element << " to proc " << proc);
(send_element[proc]).push_back(element);
}
}
for (UInt gel = 0; gel < nb_ghost_element; ++gel) {
UInt proc = *part; part++;
element.element = gel;
element.ghost_type = _ghost;
AKANTU_DEBUG(dblAccessory, "Must recv : " << element << " from proc " << proc);
recv_element[proc].push_back(element);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::asynchronousSynchronize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
if (communications.find(tag) == communications.end())
computeBufferSize(data_accessor, tag);
Communication & communication = communications[tag];
AKANTU_DEBUG_ASSERT(communication.send_requests.size() == 0,
"There must be some pending sending communications. Tag is " << tag);
std::map<SynchronizationTag, UInt>::iterator t_it = tag_counter.find(tag);
UInt counter = 0;
if(t_it == tag_counter.end()) {
tag_counter[tag] = 0;
} else {
counter = ++(t_it->second);
}
for (UInt p = 0; p < nb_proc; ++p) {
UInt ssize = communication.size_to_send[p];
if(p == rank || ssize == 0) continue;
CommunicationBuffer & buffer = communication.send_buffer[p];
buffer.resize(ssize);
+
+ Tag comm_tag = Tag::genTag(rank, counter, tag);
+ buffer << int(comm_tag);
+
#ifndef AKANTU_NDEBUG
UInt nb_elements = send_element[p].getSize();
AKANTU_DEBUG_INFO("Packing data for proc " << p
<< " (" << ssize << "/" << nb_elements
<<" data to send/elements)");
/// pack barycenters in debug mode
Array<Element>::const_iterator<Element> bit = send_element[p].begin();
Array<Element>::const_iterator<Element> bend = send_element[p].end();
for (; bit != bend; ++bit) {
const Element & element = *bit;
Vector<Real> barycenter(mesh.getSpatialDimension());
mesh.getBarycenter(element.element, element.type, barycenter.storage(), element.ghost_type);
buffer << barycenter;
}
#endif
data_accessor.packElementData(buffer, send_element[p], tag);
AKANTU_DEBUG_ASSERT(buffer.getPackedSize() == ssize,
"a problem have been introduced with "
<< "false sent sizes declaration "
<< buffer.getPackedSize() << " != " << ssize);
AKANTU_DEBUG_INFO("Posting send to proc " << p
<< " (tag: " << tag << " - " << ssize << " data to send)"
- << " [" << Tag::genTag(rank, counter, tag) << "]");
+ << " [ " << comm_tag << ":" << std::hex << int(this->genTagFromID(tag)) << " ]");
communication.send_requests.push_back(static_communicator->asyncSend(buffer.storage(),
ssize,
p,
- Tag::genTag(rank, counter, tag)));
+ this->genTagFromID(tag)));
}
AKANTU_DEBUG_ASSERT(communication.recv_requests.size() == 0,
"There must be some pending receive communications");
for (UInt p = 0; p < nb_proc; ++p) {
UInt rsize = communication.size_to_receive[p];
if(p == rank || rsize == 0) continue;
CommunicationBuffer & buffer = communication.recv_buffer[p];
buffer.resize(rsize);
+ Tag comm_tag = Tag::genTag(rank, counter, tag);
+ buffer << int(comm_tag);
+
AKANTU_DEBUG_INFO("Posting receive from proc " << p
<< " (tag: " << tag << " - " << rsize << " data to receive) "
- << " [" << Tag::genTag(p, counter, tag) << "]");
+ << " [ " << comm_tag << ":" << std::hex << int(this->genTagFromID(tag)) << " ]");
communication.recv_requests.push_back(static_communicator->asyncReceive(buffer.storage(),
rsize,
p,
- Tag::genTag(p, counter, tag)));
+ this->genTagFromID(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);
- }
-#endif
-
-
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::waitEndSynchronize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
AKANTU_DEBUG_ASSERT(communications.find(tag) != communications.end(), "No communication with the tag \""
<< tag <<"\" started");
Communication & communication = communications[tag];
std::vector<CommunicationRequest *> req_not_finished;
std::vector<CommunicationRequest *> * req_not_finished_tmp = &req_not_finished;
std::vector<CommunicationRequest *> * recv_requests_tmp = &(communication.recv_requests);
// static_communicator->waitAll(recv_requests);
while(!recv_requests_tmp->empty()) {
for (std::vector<CommunicationRequest *>::iterator req_it = recv_requests_tmp->begin();
req_it != recv_requests_tmp->end() ; ++req_it) {
CommunicationRequest * req = *req_it;
if(static_communicator->testRequest(req)) {
UInt proc = req->getSource();
AKANTU_DEBUG_INFO("Unpacking data coming from proc " << proc);
CommunicationBuffer & buffer = communication.recv_buffer[proc];
+ int _tag; buffer >> _tag;
+ Tag comm_tag(_tag);
+
#ifndef AKANTU_NDEBUG
Array<Element>::const_iterator<Element> bit = recv_element[proc].begin();
Array<Element>::const_iterator<Element> bend = recv_element[proc].end();
UInt spatial_dimension = mesh.getSpatialDimension();
for (; bit != bend; ++bit) {
const Element & element = *bit;
Vector<Real> barycenter_loc(spatial_dimension);
mesh.getBarycenter(element.element,
element.type,
barycenter_loc.storage(),
element.ghost_type);
Vector<Real> barycenter(spatial_dimension);
buffer >> barycenter;
Real tolerance = Math::getTolerance();
Real bary_norm = barycenter.norm();
for (UInt i = 0; i < spatial_dimension; ++i) {
- if((std::abs((barycenter(i) - barycenter_loc(i))/bary_norm) <= tolerance) ||
- (std::abs(barycenter_loc(i)) <= 0 && std::abs(barycenter(i)) <= tolerance)) continue;
+ 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))/barycenter_loc(i))
- << "] - tag: " << tag);
+ << std::abs((barycenter(i) - barycenter_loc(i))/bary_norm)
+ << "] - tag: " << tag
+ << " comm_tag[ " << comm_tag << " ]");
}
}
#endif
data_accessor.unpackElementData(buffer, recv_element[proc], tag);
buffer.resize(0);
AKANTU_DEBUG_ASSERT(buffer.getLeftToUnpack() == 0,
"all data have not been unpacked: "
- << buffer.getLeftToUnpack() << " bytes left");
+ << buffer.getLeftToUnpack() << " bytes left"
+ << " [ " << comm_tag << " ]");
static_communicator->freeCommunicationRequest(req);
} else {
req_not_finished_tmp->push_back(req);
}
}
std::vector<CommunicationRequest *> * swap = req_not_finished_tmp;
req_not_finished_tmp = recv_requests_tmp;
recv_requests_tmp = swap;
req_not_finished_tmp->clear();
}
AKANTU_DEBUG_INFO("Waiting that every send requests are received");
static_communicator->waitAll(communication.send_requests);
for (std::vector<CommunicationRequest *>::iterator req_it = communication.send_requests.begin();
req_it != communication.send_requests.end() ; ++req_it) {
CommunicationRequest & req = *(*req_it);
if(static_communicator->testRequest(&req)) {
UInt proc = req.getDestination();
CommunicationBuffer & buffer = communication.send_buffer[proc];
buffer.resize(0);
static_communicator->freeCommunicationRequest(&req);
}
}
communication.send_requests.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::computeBufferSize(DataAccessor & data_accessor,
SynchronizationTag tag) {
AKANTU_DEBUG_IN();
communications[tag].resize(nb_proc);
for (UInt p = 0; p < nb_proc; ++p) {
UInt ssend = 0;
UInt sreceive = 0;
if(p != rank) {
if(send_element[p].getSize() != 0) {
+ ssend += sizeof(int); // sizeof(int) is for the communication tag
#ifndef AKANTU_NDEBUG
ssend += send_element[p].getSize() * mesh.getSpatialDimension() * sizeof(Real);
#endif
ssend += data_accessor.getNbDataForElements(send_element[p], tag);
AKANTU_DEBUG_INFO("I have " << ssend << "(" << ssend / 1024.
<< "kB - "<< send_element[p].getSize() <<" element(s)) data to send to " << p << " for tag "
<< tag);
}
if(recv_element[p].getSize() != 0) {
+ sreceive += sizeof(int); // sizeof(int) is for the communication tag
#ifndef AKANTU_NDEBUG
sreceive += recv_element[p].getSize() * mesh.getSpatialDimension() * sizeof(Real);
#endif
sreceive += data_accessor.getNbDataForElements(recv_element[p], tag);
AKANTU_DEBUG_INFO("I have " << sreceive << "(" << sreceive / 1024.
<< "kB - "<< recv_element[p].getSize() <<" element(s)) data to receive for tag "
<< tag);
}
}
communications[tag].size_to_send [p] = ssend;
communications[tag].size_to_receive[p] = sreceive;
}
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
+void DistributedSynchronizer::computeAllBufferSizes(DataAccessor & data_accessor) {
+ std::map<SynchronizationTag, Communication>::iterator it = this->communications.begin();
+ std::map<SynchronizationTag, Communication>::iterator end = this->communications.end();
+
+ for (; it != end; ++it) {
+ SynchronizationTag tag = it->first;
+ this->computeBufferSize(data_accessor, tag);
+ }
+
+}
+
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::printself(std::ostream & stream, int indent) const {
std::string space;
for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
Int prank = StaticCommunicator::getStaticCommunicator().whoAmI();
Int psize = StaticCommunicator::getStaticCommunicator().getNbProc();
stream << "[" << prank << "/" << psize << "]" << space << "DistributedSynchronizer [" << std::endl;
for (UInt p = 0; p < nb_proc; ++p) {
if (p == UInt(prank)) continue;
stream << "[" << prank << "/" << psize << "]" << space
<< " + Communication to proc " << p << " [" << std::endl;
if(AKANTU_DEBUG_TEST(dblDump)) {
stream << "[" << prank << "/" << psize << "]" << space
<< " - Element to send to proc " << p << " [" << std::endl;
Array<Element>::iterator<Element> it_el = send_element[p].begin();
Array<Element>::iterator<Element> end_el = send_element[p].end();
for(;it_el != end_el; ++it_el)
stream << "[" << prank << "/" << psize << "]" << space << " " << *it_el << std::endl;
stream << "[" << prank << "/" << psize << "]" << space << " ]" << std::endl;
stream << "[" << prank << "/" << psize << "]" << space
<< " - Element to recv from proc " << p << " [" << std::endl;
it_el = recv_element[p].begin();
end_el = recv_element[p].end();
for(;it_el != end_el; ++it_el)
stream << "[" << prank << "/" << psize << "]"
<< space << " " << *it_el << std::endl;
stream << "[" << prank << "/" << psize << "]" << space << " ]" << std::endl;
}
std::map< SynchronizationTag, Communication>::const_iterator it = communications.begin();
std::map< SynchronizationTag, Communication>::const_iterator end = communications.end();
for (; it != end; ++it) {
const SynchronizationTag & tag = it->first;
const Communication & communication = it->second;
UInt ssend = communication.size_to_send[p];
UInt sreceive = communication.size_to_receive[p];
stream << "[" << prank << "/" << psize << "]" << space << " - Tag " << tag << " -> " << ssend << "byte(s) -- <- " << sreceive << "byte(s)" << std::endl;
}
}
}
/* -------------------------------------------------------------------------- */
-void DistributedSynchronizer::onElementsRemoved(const Array<Element> & element_to_remove,
- const ElementTypeMapArray<UInt> & new_numbering,
- __attribute__((unused)) const RemovedElementsEvent & event) {
- AKANTU_DEBUG_IN();
-
- StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
- UInt psize = comm.getNbProc();
- UInt prank = comm.whoAmI();
+void DistributedSynchronizer::substituteElements(const std::map<Element, Element> & old_to_new_elements) {
+ // substitute old elements with new ones
+ std::map<Element, Element>::const_iterator found_element_it;
+ std::map<Element, Element>::const_iterator found_element_end = old_to_new_elements.end();
- std::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);
- }
+ 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;
}
- 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);
- }
-
- 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::type_iterator it = mesh.firstType(spatial_dimension,
_not_ghost,
_ek_not_defined);
Mesh::type_iterator end = mesh.lastType(spatial_dimension,
_not_ghost,
_ek_not_defined);
/// assign prank to all not ghost elements
for (; it != end; ++it) {
UInt nb_element = mesh.getNbElement(*it);
Array<UInt> & prank_to_el = prank_to_element(*it);
for (UInt el = 0; el < nb_element; ++el) {
prank_to_el(el) = rank;
}
}
/// assign prank to all ghost elements
for (UInt p = 0; p < nb_proc; ++p) {
UInt nb_ghost_element = recv_element[p].getSize();
for (UInt el = 0; el < nb_ghost_element; ++el) {
UInt element = recv_element[p](el).element;
ElementType type = recv_element[p](el).type;
GhostType ghost_type = recv_element[p](el).ghost_type;
Array<UInt> & prank_to_el = prank_to_element(type, ghost_type);
prank_to_el(element) = p;
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::filterElementsByKind(DistributedSynchronizer * new_synchronizer,
ElementKind kind) {
AKANTU_DEBUG_IN();
Array<Element> * newsy_send_element = new_synchronizer->send_element;
Array<Element> * newsy_recv_element = new_synchronizer->recv_element;
Array<Element> * new_send_element = new Array<Element>[nb_proc];
Array<Element> * new_recv_element = new Array<Element>[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
/// send element copying part
new_send_element[p].resize(0);
for (UInt el = 0; el < send_element[p].getSize(); ++el) {
Element & element = send_element[p](el);
if (element.kind == kind)
newsy_send_element[p].push_back(element);
else
new_send_element[p].push_back(element);
}
/// recv element copying part
new_recv_element[p].resize(0);
for (UInt el = 0; el < recv_element[p].getSize(); ++el) {
Element & element = recv_element[p](el);
if (element.kind == kind)
newsy_recv_element[p].push_back(element);
else
new_recv_element[p].push_back(element);
}
}
/// deleting and reassigning old pointers
delete [] send_element;
delete [] recv_element;
send_element = new_send_element;
recv_element = new_recv_element;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::reset() {
AKANTU_DEBUG_IN();
for (UInt p = 0; p < nb_proc; ++p) {
send_element[p].resize(0);
recv_element[p].resize(0);
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeTagsSend(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
UInt nb_tags,
const ElementType & type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition,
UInt nb_local_element,
UInt nb_ghost_element) {
AKANTU_DEBUG_IN();
static UInt count = 0;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
if(nb_tags == 0) {
AKANTU_DEBUG_OUT();
return;
}
UInt mesh_data_sizes_buffer_length;
MeshData & mesh_data = mesh.getMeshData();
/// tag info
std::vector<std::string> tag_names;
mesh.getMeshData().getTagNames(tag_names, type);
// Make sure the tags are sorted (or at least not in random order),
// because they come from a map !!
std::sort(tag_names.begin(), tag_names.end());
// Sending information about the tags in mesh_data: name, data type and
// number of components of the underlying array associated to the current type
DynamicCommunicationBuffer mesh_data_sizes_buffer;
std::vector<std::string>::const_iterator names_it = tag_names.begin();
std::vector<std::string>::const_iterator names_end = tag_names.end();
for(;names_it != names_end; ++names_it) {
mesh_data_sizes_buffer << *names_it;
mesh_data_sizes_buffer << mesh_data.getTypeCode(*names_it);
mesh_data_sizes_buffer << mesh_data.getNbComponent(*names_it, type);
}
mesh_data_sizes_buffer_length = mesh_data_sizes_buffer.getSize();
AKANTU_DEBUG_INFO("Broadcasting the size of the information about the mesh data tags: (" << mesh_data_sizes_buffer_length << ")." );
comm.broadcast(&mesh_data_sizes_buffer_length, 1, root);
AKANTU_DEBUG_INFO("Broadcasting the information about the mesh data tags, addr " << (void*)mesh_data_sizes_buffer.storage());
if(mesh_data_sizes_buffer_length !=0)
comm.broadcast(mesh_data_sizes_buffer.storage(), mesh_data_sizes_buffer.getSize(), root);
if(mesh_data_sizes_buffer_length !=0) {
//Sending the actual data to each processor
- DynamicCommunicationBuffer buffers[nb_proc];
+ DynamicCommunicationBuffer * buffers = new DynamicCommunicationBuffer[nb_proc];
std::vector<std::string>::const_iterator names_it = tag_names.begin();
std::vector<std::string>::const_iterator names_end = tag_names.end();
// Loop over each tag for the current type
for(;names_it != names_end; ++names_it) {
// Type code of the current tag (i.e. the tag named *names_it)
communicator.fillTagBuffer(mesh_data,
buffers,
*names_it,
type,
partition_num,
ghost_partition);
}
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p != root) {
AKANTU_DEBUG_INFO("Sending " << buffers[p].getSize() << " bytes of mesh data to proc " << p << " TAG("<< Tag::genTag(my_rank, count, TAG_MESH_DATA) <<")");
requests.push_back(comm.asyncSend(buffers[p].storage(),
buffers[p].getSize(), p, Tag::genTag(my_rank, count, TAG_MESH_DATA)));
}
}
names_it = tag_names.begin();
// Loop over each tag for the current type
for(;names_it != names_end; ++names_it) {
// Reinitializing the mesh data on the master
communicator.populateMeshData(mesh_data,
buffers[root],
*names_it,
type,
mesh_data.getTypeCode(*names_it),
mesh_data.getNbComponent(*names_it, type),
nb_local_element,
nb_ghost_element);
}
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
+ delete [] buffers;
}
++count;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeTagsRecv(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
UInt nb_tags,
const ElementType & type,
UInt nb_local_element,
UInt nb_ghost_element) {
AKANTU_DEBUG_IN();
static UInt count = 0;
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
if(nb_tags == 0) {
AKANTU_DEBUG_OUT();
return;
}
/* --------<<<<-TAGS------------------------------------------------- */
UInt mesh_data_sizes_buffer_length = 0;
CommunicationBuffer mesh_data_sizes_buffer;
MeshData & mesh_data = mesh.getMeshData();
AKANTU_DEBUG_INFO("Receiving the size of the information about the mesh data tags.");
comm.broadcast(&mesh_data_sizes_buffer_length, 1, root);
if(mesh_data_sizes_buffer_length != 0) {
mesh_data_sizes_buffer.resize(mesh_data_sizes_buffer_length);
AKANTU_DEBUG_INFO("Receiving the information about the mesh data tags, addr " << (void*)mesh_data_sizes_buffer.storage());
comm.broadcast(mesh_data_sizes_buffer.storage(), mesh_data_sizes_buffer_length, root);
AKANTU_DEBUG_INFO("Size of the information about the mesh data: " << mesh_data_sizes_buffer_length);
std::vector<std::string> tag_names;
std::vector<MeshDataTypeCode> tag_type_codes;
std::vector<UInt> tag_nb_component;
tag_names.resize(nb_tags);
tag_type_codes.resize(nb_tags);
tag_nb_component.resize(nb_tags);
CommunicationBuffer mesh_data_buffer;
UInt type_code_int;
for(UInt i(0); i < nb_tags; ++i) {
mesh_data_sizes_buffer >> tag_names[i];
mesh_data_sizes_buffer >> type_code_int;
tag_type_codes[i] = static_cast<MeshDataTypeCode>(type_code_int);
mesh_data_sizes_buffer >> tag_nb_component[i];
}
std::vector<std::string>::const_iterator names_it = tag_names.begin();
std::vector<std::string>::const_iterator names_end = tag_names.end();
CommunicationStatus mesh_data_comm_status;
AKANTU_DEBUG_INFO("Checking size of data to receive for mesh data TAG("
<< Tag::genTag(root, count, TAG_MESH_DATA) << ")");
comm.probe<char>(root, Tag::genTag(root, count, TAG_MESH_DATA), mesh_data_comm_status);
UInt mesh_data_buffer_size(mesh_data_comm_status.getSize());
AKANTU_DEBUG_INFO("Receiving " << mesh_data_buffer_size
<< " bytes of mesh data TAG("
<< Tag::genTag(root, count, TAG_MESH_DATA) << ")");
mesh_data_buffer.resize(mesh_data_buffer_size);
comm.receive(mesh_data_buffer.storage(),
mesh_data_buffer_size,
root,
Tag::genTag(root, count, TAG_MESH_DATA));
// Loop over each tag for the current type
UInt k(0);
for(; names_it != names_end; ++names_it, ++k) {
communicator.populateMeshData(mesh_data, mesh_data_buffer,
*names_it, type,
tag_type_codes[k],
tag_nb_component[k],
nb_local_element, nb_ghost_element);
}
}
++count;
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class CommunicationBuffer>
void DistributedSynchronizer::fillElementGroupsFromBuffer(DistributedSynchronizer & communicator,
Mesh & mesh,
const ElementType & type,
CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
Element el;
el.type = type;
for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
UInt nb_element = mesh.getNbElement(type, *gt);
el.ghost_type = *gt;
for (UInt e = 0; e < nb_element; ++e) {
el.element = e;
std::vector<std::string> element_to_group;
buffer >> element_to_group;
AKANTU_DEBUG_ASSERT(e < mesh.getNbElement(type, *gt), "The mesh does not have the element " << e);
std::vector<std::string>::iterator it = element_to_group.begin();
std::vector<std::string>::iterator end = element_to_group.end();
for (; it != end; ++it) {
mesh.getElementGroup(*it).add(el, false, false);
}
}
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeElementGroups(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
const ElementType & type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition,
UInt nb_element) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
- DynamicCommunicationBuffer buffers[nb_proc];
+ DynamicCommunicationBuffer * buffers = new DynamicCommunicationBuffer[nb_proc];
typedef std::vector< std::vector<std::string> > ElementToGroup;
ElementToGroup element_to_group;
element_to_group.resize(nb_element);
GroupManager::const_element_group_iterator egi = mesh.element_group_begin();
GroupManager::const_element_group_iterator ege = mesh.element_group_end();
for (; egi != ege; ++egi) {
ElementGroup & eg = *(egi->second);
std::string name = egi->first;
ElementGroup::const_element_iterator eit = eg.element_begin(type, _not_ghost);
ElementGroup::const_element_iterator eend = eg.element_end(type, _not_ghost);
for (; eit != eend; ++eit) {
element_to_group[*eit].push_back(name);
}
eit = eg.element_begin(type, _not_ghost);
if(eit != eend)
const_cast<Array<UInt> &>(eg.getElements(type)).empty();
}
/// preparing the buffers
const UInt * part = partition_num.storage();
/// copying the data, element by element
ElementToGroup::const_iterator data_it = element_to_group.begin();
ElementToGroup::const_iterator data_end = element_to_group.end();
for (; data_it != data_end; ++part, ++data_it) {
buffers[*part] << *data_it;
}
data_it = element_to_group.begin();
/// copying the data for the ghost element
for (UInt el(0); data_it != data_end; ++data_it, ++el) {
CSR<UInt>::const_iterator it = ghost_partition.begin(el);
CSR<UInt>::const_iterator end = ghost_partition.end(el);
for (;it != end; ++it) {
UInt proc = *it;
buffers[proc] << *data_it;
}
}
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank) continue;
AKANTU_DEBUG_INFO("Sending element groups to proc " << p
<< " TAG("<< Tag::genTag(my_rank, p, TAG_ELEMENT_GROUP) <<")");
requests.push_back(comm.asyncSend(buffers[p].storage(),
buffers[p].getSize(),
p,
Tag::genTag(my_rank, p, TAG_ELEMENT_GROUP)));
}
fillElementGroupsFromBuffer(communicator, mesh, type, buffers[my_rank]);
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
-
+ delete [] buffers;
+
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeElementGroups(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
const ElementType & type) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt my_rank = comm.whoAmI();
AKANTU_DEBUG_INFO("Receiving element groups from proc " << root
<< " TAG("<< Tag::genTag(root, my_rank, TAG_ELEMENT_GROUP) <<")");
CommunicationStatus status;
comm.probe<char>(root, Tag::genTag(root, my_rank, TAG_ELEMENT_GROUP), status);
CommunicationBuffer buffer(status.getSize());
comm.receive(buffer.storage(), buffer.getSize(), root, Tag::genTag(root, my_rank, TAG_ELEMENT_GROUP));
fillElementGroupsFromBuffer(communicator, mesh, type, buffer);
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
template<class CommunicationBuffer>
void DistributedSynchronizer::fillNodeGroupsFromBuffer(DistributedSynchronizer & communicator,
Mesh & mesh,
CommunicationBuffer & buffer) {
AKANTU_DEBUG_IN();
std::vector< std::vector<std::string> > node_to_group;
buffer >> node_to_group;
AKANTU_DEBUG_ASSERT(node_to_group.size() == mesh.getNbGlobalNodes(),
"Not the good amount of nodes where transmitted");
const Array<UInt> & global_nodes = mesh.getGlobalNodesIds();
Array<UInt>::const_scalar_iterator nbegin = global_nodes.begin();
Array<UInt>::const_scalar_iterator nit = global_nodes.begin();
Array<UInt>::const_scalar_iterator nend = global_nodes.end();
for (; nit != nend; ++nit) {
std::vector<std::string>::iterator it = node_to_group[*nit].begin();
std::vector<std::string>::iterator end = node_to_group[*nit].end();
for (; it != end; ++it) {
mesh.getNodeGroup(*it).add(nit - nbegin, false);
}
}
GroupManager::const_node_group_iterator ngi = mesh.node_group_begin();
GroupManager::const_node_group_iterator nge = mesh.node_group_end();
for (; ngi != nge; ++ngi) {
NodeGroup & ng = *(ngi->second);
ng.optimize();
}
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeNodeGroupsMaster(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt nb_proc = comm.getNbProc();
UInt my_rank = comm.whoAmI();
UInt nb_total_nodes = mesh.getNbGlobalNodes();
DynamicCommunicationBuffer buffer;
typedef std::vector< std::vector<std::string> > NodeToGroup;
NodeToGroup node_to_group;
node_to_group.resize(nb_total_nodes);
GroupManager::const_node_group_iterator ngi = mesh.node_group_begin();
GroupManager::const_node_group_iterator nge = mesh.node_group_end();
for (; ngi != nge; ++ngi) {
NodeGroup & ng = *(ngi->second);
std::string name = ngi->first;
NodeGroup::const_node_iterator nit = ng.begin();
NodeGroup::const_node_iterator nend = ng.end();
for (; nit != nend; ++nit) {
node_to_group[*nit].push_back(name);
}
nit = ng.begin();
if(nit != nend)
ng.empty();
}
buffer << node_to_group;
std::vector<CommunicationRequest *> requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank) continue;
AKANTU_DEBUG_INFO("Sending node groups to proc " << p
<< " TAG("<< Tag::genTag(my_rank, p, TAG_NODE_GROUP) <<")");
requests.push_back(comm.asyncSend(buffer.storage(),
buffer.getSize(),
p,
Tag::genTag(my_rank, p, TAG_NODE_GROUP)));
}
fillNodeGroupsFromBuffer(communicator, mesh, buffer);
comm.waitAll(requests);
comm.freeCommunicationRequest(requests);
requests.clear();
AKANTU_DEBUG_OUT();
}
/* -------------------------------------------------------------------------- */
void DistributedSynchronizer::synchronizeNodeGroupsSlaves(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh) {
AKANTU_DEBUG_IN();
StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
UInt my_rank = comm.whoAmI();
AKANTU_DEBUG_INFO("Receiving node groups from proc " << root
<< " TAG("<< Tag::genTag(root, my_rank, TAG_NODE_GROUP) <<")");
CommunicationStatus status;
comm.probe<char>(root, Tag::genTag(root, my_rank, TAG_NODE_GROUP), status);
CommunicationBuffer buffer(status.getSize());
comm.receive(buffer.storage(), buffer.getSize(), root, Tag::genTag(root, my_rank, TAG_NODE_GROUP));
fillNodeGroupsFromBuffer(communicator, mesh, buffer);
AKANTU_DEBUG_OUT();
}
+/* -------------------------------------------------------------------------- */
+void DistributedSynchronizer::removeElements(const Array<Element> & element_to_remove) {
+ AKANTU_DEBUG_IN();
+
+ StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+
+ std::vector<CommunicationRequest *> isend_requests;
+ Array<UInt> * list_of_el = new Array<UInt>[nb_proc];
+ // Handling ghost elements
+ for (UInt p = 0; p < nb_proc; ++p) {
+ if (p == rank) continue;
+
+ Array<Element> & recv = recv_element[p];
+ if(recv.getSize() == 0) continue;
+
+ Array<Element>::iterator<Element> recv_begin = recv.begin();
+ Array<Element>::iterator<Element> recv_end = recv.end();
+
+ Array<Element>::const_iterator<Element> er_it = element_to_remove.begin();
+ Array<Element>::const_iterator<Element> er_end = element_to_remove.end();
+
+ Array<UInt> & list = list_of_el[p];
+ for (UInt i = 0; recv_begin != recv_end; ++i, ++recv_begin) {
+ const Element & el = *recv_begin;
+ Array<Element>::const_iterator<Element> pos = std::find(er_it, er_end, el);
+ if(pos == er_end) {
+ list.push_back(i);
+ }
+ }
+
+ if(list.getSize() == recv.getSize())
+ list.push_back(UInt(0));
+ else list.push_back(UInt(-1));
+
+ AKANTU_DEBUG_INFO("Sending a message of size " << list.getSize() << " to proc " << p << " TAG(" << this->genTagFromID(0) << ")");
+ isend_requests.push_back(comm.asyncSend(list.storage(), list.getSize(),
+ p, this->genTagFromID(0)));
+
+ list.erase(list.getSize() - 1);
+
+ if (list.getSize() == recv.getSize()) continue;
+
+ Array<Element> new_recv;
+ for (UInt nr = 0; nr < list.getSize(); ++nr) {
+ Element & el = recv(list(nr));
+ new_recv.push_back(el);
+ }
+
+ AKANTU_DEBUG_INFO("I had " << recv.getSize() << " elements to recv from proc " << p << " and "
+ << list.getSize() << " elements to keep. I have "
+ << new_recv.getSize() << " elements left.");
+ recv.copy(new_recv);
+ }
+
+ for (UInt p = 0; p < nb_proc; ++p) {
+ if (p == rank) continue;
+ Array<Element> & send = send_element[p];
+
+ if(send.getSize() == 0) continue;
+
+ CommunicationStatus status;
+ AKANTU_DEBUG_INFO("Getting number of elements of proc " << p << " not needed anymore TAG("<< this->genTagFromID(0) <<")");
+ comm.probe<UInt>(p, this->genTagFromID(0), status);
+ Array<UInt> list(status.getSize());
+
+ AKANTU_DEBUG_INFO("Receiving list of elements (" << status.getSize() - 1
+ << " elements) no longer needed by proc " << p
+ << " TAG("<< this->genTagFromID(0) <<")");
+ comm.receive(list.storage(), list.getSize(),
+ p, this->genTagFromID(0));
+
+ if(list.getSize() == 1 && list(0) == 0) continue;
+
+ list.erase(list.getSize() - 1);
+
+ if (list.getSize() == send.getSize()) continue;
+
+ Array<Element> new_send;
+ for (UInt ns = 0; ns < list.getSize(); ++ns) {
+ Element & el = send(list(ns));
+ new_send.push_back(el);
+ }
+
+ AKANTU_DEBUG_INFO("I had " << send.getSize() << " elements to send to proc " << p << " and "
+ << list.getSize() << " elements to keep. I have "
+ << new_send.getSize() << " elements left.");
+ send.copy(new_send);
+ }
+
+ comm.waitAll(isend_requests);
+ comm.freeCommunicationRequest(isend_requests);
+
+ delete [] list_of_el;
+ AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+void DistributedSynchronizer::renumberElements(const ElementTypeMapArray<UInt> & new_numbering) {
+ // Handling ghost elements
+ for (UInt p = 0; p < nb_proc; ++p) {
+ if (p == rank) continue;
+
+ Array<Element> & recv = recv_element[p];
+
+ for (UInt i = 0; i < recv.getSize(); ++i) {
+ Element & el = recv(i);
+ el.element = new_numbering(el.type, el.ghost_type)(el.element);
+ }
+
+ Array<Element> & send = send_element[p];
+
+ for (UInt i = 0; i < send.getSize(); ++i) {
+ Element & el = send(i);
+ el.element = new_numbering(el.type, el.ghost_type)(el.element);
+ }
+ }
+}
+
+
__END_AKANTU__
diff --git a/src/synchronizer/distributed_synchronizer.hh b/src/synchronizer/distributed_synchronizer.hh
index 64976adad..6206401c2 100644
--- a/src/synchronizer/distributed_synchronizer.hh
+++ b/src/synchronizer/distributed_synchronizer.hh
@@ -1,293 +1,300 @@
/**
* @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 Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Thu Jun 16 2011
* @date last modification: Fri Sep 05 2014
*
* @brief wrapper to 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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 "static_communicator.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);
/* ------------------------------------------------------------------------ */
/* Inherited from Synchronizer */
/* ------------------------------------------------------------------------ */
/// asynchronous synchronization of ghosts
void asynchronousSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
/// wait end of asynchronous synchronization of ghosts
void waitEndSynchronize(DataAccessor & data_accessor,SynchronizationTag tag);
/// build processor to element corrispondance
void buildPrankToElement();
virtual void printself(std::ostream & stream, int indent = 0) const;
+ /// mesh event handler onElementsChanged
+ virtual void onElementsChanged(const Array<Element> & old_elements_list,
+ const Array<Element> & new_elements_list,
+ const ElementTypeMapArray<UInt> & new_numbering,
+ const ChangedElementsEvent & event);
+
/// mesh event handler onRemovedElement
virtual void onElementsRemoved(const Array<Element> & element_list,
const ElementTypeMapArray<UInt> & new_numbering,
const RemovedElementsEvent & event);
+ /// mesh event handler onNodesAdded
+ virtual void onNodesAdded (const Array<UInt> & nodes_list,
+ const NewNodesEvent & event) {};
+
+ /// mesh event handler onRemovedNodes
+ virtual void onNodesRemoved(const Array<UInt> & nodes_list,
+ const Array<UInt> & new_numbering,
+ const RemovedNodesEvent & event) {};
+
+ /// mesh event handler onElementsAdded
+ virtual void onElementsAdded (const Array<Element> & elements_list,
+ const NewElementsEvent & event) {};
/// filter elements of a certain kind and copy them into a new synchronizer
void filterElementsByKind(DistributedSynchronizer * new_synchronizer,
ElementKind kind);
/// reset send and recv element lists
void reset();
/// compute buffer size for a given tag and data accessor
void computeBufferSize(DataAccessor & data_accessor, SynchronizationTag tag);
+ /// recalculate buffer sizes for all tags
+ void computeAllBufferSizes(DataAccessor & data_accessor);
+
+ /// remove elements from the synchronizer without renumbering them
+ void removeElements(const Array<Element> & element_to_remove);
+
+ /// renumber the elements in the synchronizer
+ void renumberElements(const ElementTypeMapArray<UInt> & new_numbering);
+
+
protected:
/// fill the nodes type vector
void fillNodesType(Mesh & mesh);
void fillNodesType(const MeshData & mesh_data,
DynamicCommunicationBuffer * buffers,
const std::string & tag_name,
const ElementType & el_type,
const Array<UInt> & partition_num);
template<typename T>
void fillTagBufferTemplated(const MeshData & mesh_data,
DynamicCommunicationBuffer * buffers,
const std::string & tag_name,
const ElementType & el_type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition);
void fillTagBuffer(const MeshData & mesh_data,
DynamicCommunicationBuffer * buffers,
const std::string & tag_name,
const ElementType & el_type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition);
template<typename T, typename BufferType>
void populateMeshDataTemplated(MeshData & mesh_data,
BufferType & buffer,
const std::string & tag_name,
const ElementType & el_type,
UInt nb_component,
UInt nb_local_element,
UInt nb_ghost_element);
template <typename BufferType>
void populateMeshData(MeshData & mesh_data,
BufferType & buffer,
const std::string & tag_name,
const ElementType & el_type,
const MeshDataTypeCode & type_code,
UInt nb_component,
UInt nb_local_element,
UInt nb_ghost_element);
/// fill the communications array of a distributedSynchronizer based on a partition array
void fillCommunicationScheme(const UInt * partition,
UInt nb_local_element,
UInt nb_ghost_element,
ElementType type);
/// function that handels the MeshData to be split (root side)
static void synchronizeTagsSend(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
UInt nb_tags,
const ElementType & type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition,
UInt nb_local_element,
UInt nb_ghost_element);
/// function that handles the MeshData to be split (other nodes)
static void synchronizeTagsRecv(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
UInt nb_tags,
const ElementType & type,
UInt nb_local_element,
UInt nb_ghost_element);
/// function that handles the preexisting groups in the mesh
static void synchronizeElementGroups(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
const ElementType & type,
const Array<UInt> & partition_num,
const CSR<UInt> & ghost_partition,
UInt nb_element);
/// function that handles the preexisting groups in the mesh
static void synchronizeElementGroups(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh,
const ElementType & type);
template<class CommunicationBuffer>
static void fillElementGroupsFromBuffer(DistributedSynchronizer & communicator,
Mesh & mesh,
const ElementType & type,
CommunicationBuffer & buffer);
/// function that handles the preexisting groups in the mesh
static void synchronizeNodeGroupsMaster(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh);
/// function that handles the preexisting groups in the mesh
static void synchronizeNodeGroupsSlaves(DistributedSynchronizer & communicator,
UInt root,
Mesh & mesh);
template<class CommunicationBuffer>
static void fillNodeGroupsFromBuffer(DistributedSynchronizer & communicator,
Mesh & mesh,
CommunicationBuffer & buffer);
+ /// substitute elements in the send and recv arrays
+ void substituteElements(const std::map<Element, Element> & old_to_new_elements);
+
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
AKANTU_GET_MACRO(PrankToElement, prank_to_element, const ElementTypeMapArray<UInt> &);
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
enum CommTags {
TAG_SIZES = 0,
TAG_CONNECTIVITY = 1,
TAG_DATA = 2,
TAG_PARTITIONS = 3,
TAG_NB_NODES = 4,
TAG_NODES = 5,
TAG_COORDINATES = 6,
TAG_NODES_TYPE = 7,
TAG_MESH_DATA = 8,
TAG_ELEMENT_GROUP = 9,
TAG_NODE_GROUP = 10,
};
protected:
/// reference to the underlying mesh
Mesh & mesh;
- /// the static memory instance
- StaticCommunicator * static_communicator;
-
- class Communication {
- public:
- void resize(UInt size) {
- send_buffer.resize(size);
- recv_buffer.resize(size);
- size_to_send .resize(size);
- size_to_receive.resize(size);
- }
-
- public:
- /// size of data to send to each processor
- std::vector<UInt> size_to_send;
- /// size of data to recv to each processor
- std::vector<UInt> size_to_receive;
- std::vector< CommunicationBuffer > send_buffer;
- std::vector< CommunicationBuffer > recv_buffer;
-
- std::vector<CommunicationRequest *> send_requests;
- std::vector<CommunicationRequest *> recv_requests;
- };
-
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/dof_synchronizer.cc b/src/synchronizer/dof_synchronizer.cc
index d15d02d0a..6375af800 100644
--- a/src/synchronizer/dof_synchronizer.cc
+++ b/src/synchronizer/dof_synchronizer.cc
@@ -1,258 +1,501 @@
/**
* @file dof_synchronizer.cc
*
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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;
- communicator = &StaticCommunicator::getStaticCommunicator();
+ gather_scatter_scheme_initialized = false;
- prank = communicator->whoAmI();
- psize = communicator->getNbProc();
+ 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(communicator->asyncSend(&nb_master_dofs, 1, sendto, 0));
+ requests.push_back(static_communicator->asyncSend(&nb_master_dofs, 1, sendto, 0));
if(nb_master_dofs != 0) {
- AKANTU_DEBUG(dblInfo, "Sending "<< nb_master_dofs << " nodes to " << sendto + 1);
- requests.push_back(communicator->asyncSend(send_buffer, nb_master_dofs, 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));
}
- communicator->receive(&nb_slave_dofs, 1, recvfrom, 0);
+
+ /// 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 << " nodes 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();
- communicator->receive(recv_buffer, nb_slave_dofs, recvfrom, 1);
+ 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]];
}
- communicator->waitAll(requests);
- communicator->freeCommunicationRequest(requests);
+ 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();
- communicator->allGather(nb_dof_per_proc, 1);
+ 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 (UInt p = 0; p < psize; ++p) nb_values[p] = nb_dof_per_proc[p] * 2;
+ 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;
- communicator->allGatherV(buffer, nb_values);
+ 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 4678ab578..435f246c1 100644
--- a/src/synchronizer/dof_synchronizer.hh
+++ b/src/synchronizer/dof_synchronizer.hh
@@ -1,210 +1,244 @@
/**
* @file dof_synchronizer.hh
*
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 {
+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;
- StaticCommunicator * communicator;
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 2f253fcd2..ee040e3b4 100644
--- a/src/synchronizer/dof_synchronizer_inline_impl.cc
+++ b/src/synchronizer/dof_synchronizer_inline_impl.cc
@@ -1,289 +1,315 @@
/**
* @file dof_synchronizer_inline_impl.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jun 17 2011
* @date last modification: Thu Jun 05 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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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];
- communicator->receive(buffer, nb_dofs, p, 0);
+ 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)
- communicator->send(buffer, nb_local_dofs, root, 0);
+ 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++];
}
- communicator->send(send_buffer, nb_local_dof + nb_needed_dof, p, 0);
+ 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];
- communicator->receive(buffer, nb_local_dofs + nb_needed_dofs, root, 0);
+ 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 = communicator->asyncSend(send_buffer, nb_slave_dofs, sendto , 0);
- if(nb_master_dofs != 0) communicator->receive(recv_buffer, nb_master_dofs, recvfrom, 0);
+ 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) {
- communicator->wait(request);
- communicator->freeCommunicationRequest(request);
+ 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 = communicator->asyncSend(send_buffer, nb_master_dofs, sendto , 0);
- if(nb_slave_dofs != 0) communicator->receive(recv_buffer, nb_slave_dofs, recvfrom, 0);
+ 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) {
- communicator->wait(request);
- communicator->freeCommunicationRequest(request);
+ 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.hh b/src/synchronizer/filtered_synchronizer.hh
index c4a4d85de..c508fb3b4 100644
--- a/src/synchronizer/filtered_synchronizer.hh
+++ b/src/synchronizer/filtered_synchronizer.hh
@@ -1,98 +1,100 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 426117c90..9c804c4f5 100644
--- a/src/synchronizer/grid_synchronizer.cc
+++ b/src/synchronizer/grid_synchronizer.cc
@@ -1,509 +1,549 @@
/**
* @file grid_synchronizer.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Oct 03 2011
* @date last modification: Thu Jun 05 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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) {
+ 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,
- MemoryID memory_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));
+ GridSynchronizer & communicator = *(new GridSynchronizer(mesh, id, memory_id,
+ register_to_event_manager));
if(nb_proc == 1) return &communicator;
UInt spatial_dimension = mesh.getSpatialDimension();
Real * bounding_boxes = new Real[2 * spatial_dimension * nb_proc];
Real * my_bounding_box = bounding_boxes + 2 * spatial_dimension * my_rank;
// mesh.getLocalLowerBounds(my_bounding_box);
// mesh.getLocalUpperBounds(my_bounding_box + spatial_dimension);
const Vector<Real> & lower = grid.getLowerBounds();
const Vector<Real> & upper = grid.getUpperBounds();
const Vector<Real> & spacing = grid.getSpacing();
for (UInt i = 0; i < spatial_dimension; ++i) {
my_bounding_box[i ] = lower(i) - spacing(i);
my_bounding_box[spatial_dimension + i] = upper(i) + spacing(i);
}
AKANTU_DEBUG_INFO("Exchange of bounding box to detect the overlapping regions.");
comm.allGather(bounding_boxes, spatial_dimension * 2);
bool * intersects_proc = new bool[nb_proc];
std::fill_n(intersects_proc, nb_proc, true);
Int * first_cells = new Int[3 * nb_proc];
Int * last_cells = new Int[3 * nb_proc];
std::fill_n(first_cells, 3 * nb_proc, 0);
std::fill_n(first_cells, 3 * nb_proc, 0);
ElementTypeMapArray<UInt> ** element_per_proc = new ElementTypeMapArray<UInt>* [nb_proc];
for (UInt p = 0; p < nb_proc; ++p) element_per_proc[p] = NULL;
// check the overlapping between my box and the one from other processors
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank) continue;
Real * proc_bounding_box = bounding_boxes + 2 * spatial_dimension * p;
bool intersects = false;
Int * first_cell_p = first_cells + p * spatial_dimension;
Int * last_cell_p = last_cells + p * spatial_dimension;
for (UInt s = 0; s < spatial_dimension; ++s) {
// check overlapping of grid
intersects = Math::intersects(my_bounding_box[s],
my_bounding_box[spatial_dimension + s],
proc_bounding_box[s],
proc_bounding_box[spatial_dimension + s]);
intersects_proc[p] &= intersects;
if(intersects) {
AKANTU_DEBUG_INFO("I intersects with processor " << p << " in direction " << s);
// is point 1 of proc p in the dimension s in the range ?
bool point1 = Math::is_in_range(proc_bounding_box[s],
my_bounding_box[s],
my_bounding_box[s+spatial_dimension]);
// is point 2 of proc p in the dimension s in the range ?
bool point2 = Math::is_in_range(proc_bounding_box[s+spatial_dimension],
my_bounding_box[s],
my_bounding_box[s+spatial_dimension]);
Real start = 0.;
Real end = 0.;
if(point1 && !point2) {
/* |-----------| my_bounding_box(i)
* |-----------| proc_bounding_box(i)
* 1 2
*/
start = proc_bounding_box[s];
end = my_bounding_box[s+spatial_dimension];
AKANTU_DEBUG_INFO("Intersection scheme 1 in direction " << s << " with processor " << p << " [" << start << ", " << end <<"]");
} else if(point1 && point2) {
/* |-----------------| my_bounding_box(i)
* |-----------| proc_bounding_box(i)
* 1 2
*/
start = proc_bounding_box[s];
end = proc_bounding_box[s+spatial_dimension];
AKANTU_DEBUG_INFO("Intersection scheme 2 in direction " << s << " with processor " << p << " [" << start << ", " << end << "]");
} else if(!point1 && point2) {
/* |-----------| my_bounding_box(i)
* |-----------| proc_bounding_box(i)
* 1 2
*/
start = my_bounding_box[s];
end = proc_bounding_box[s+spatial_dimension];
AKANTU_DEBUG_INFO("Intersection scheme 3 in direction " << s << " with processor " << p << " [" << start << ", " << end <<"]");
} else {
/* |-----------| my_bounding_box(i)
* |-----------------| proc_bounding_box(i)
* 1 2
*/
start = my_bounding_box[s];
end = my_bounding_box[s+spatial_dimension];
AKANTU_DEBUG_INFO("Intersection scheme 4 in direction " << s << " with processor " << p << " [" << start << ", " << end <<"]");
}
first_cell_p[s] = grid.getCellID(start, s);
last_cell_p [s] = grid.getCellID(end, s);
}
}
//create the list of cells in the overlapping
typedef typename SpatialGrid<E>::CellID CellID;
std::vector<CellID> * cell_ids = new std::vector<CellID>;
if(intersects_proc[p]) {
AKANTU_DEBUG_INFO("I intersects with processor " << p);
CellID cell_id(spatial_dimension);
// for (UInt i = 0; i < spatial_dimension; ++i) {
// if(first_cell_p[i] != 0) --first_cell_p[i];
// if(last_cell_p[i] != 0) ++last_cell_p[i];
// }
for (Int fd = first_cell_p[0]; fd <= last_cell_p[0]; ++fd) {
cell_id.setID(0, fd);
if(spatial_dimension == 1) {
cell_ids->push_back(cell_id);
}
else {
for (Int sd = first_cell_p[1]; sd <= last_cell_p[1] ; ++sd) {
cell_id.setID(1, sd);
if(spatial_dimension == 2) {
cell_ids->push_back(cell_id);
} else {
for (Int ld = first_cell_p[2]; ld <= last_cell_p[2] ; ++ld) {
cell_id.setID(2, ld);
cell_ids->push_back(cell_id);
}
}
}
}
}
// get the list of elements in the cells of the overlapping
typename std::vector<CellID>::iterator cur_cell_id = cell_ids->begin();
typename std::vector<CellID>::iterator last_cell_id = cell_ids->end();
std::set<Element> * to_send = new std::set<Element>();
for (; cur_cell_id != last_cell_id; ++cur_cell_id) {
typename SpatialGrid<E>::Cell::const_iterator cur_elem = grid.beginCell(*cur_cell_id);
typename SpatialGrid<E>::Cell::const_iterator last_elem = grid.endCell(*cur_cell_id);
for (; cur_elem != last_elem; ++cur_elem) {
to_send->insert(*cur_elem);
}
}
AKANTU_DEBUG_INFO("I have prepared " << to_send->size() << " elements to send to processor " << p);
std::stringstream sstr; sstr << "element_per_proc_" << p;
element_per_proc[p] = new ElementTypeMapArray<UInt>(sstr.str(), id);
ElementTypeMapArray<UInt> & elempproc = *(element_per_proc[p]);
typename std::set<Element>::iterator elem = to_send->begin();
typename std::set<Element>::iterator last_elem = to_send->end();
for (; elem != last_elem; ++elem) {
ElementType type = elem->type;
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
// /!\ this part must be slow due to the access in the ElementTypeMapArray<UInt>
- if(!elempproc.exists(type))
+ if(!elempproc.exists(type, _not_ghost))
elempproc.alloc(0, nb_nodes_per_element, type, _not_ghost);
UInt global_connect[nb_nodes_per_element];
UInt * local_connect = mesh.getConnectivity(type).storage() + elem->element * nb_nodes_per_element;
for (UInt i = 0; i < nb_nodes_per_element; ++i) {
global_connect[i] = mesh.getNodeGlobalId(local_connect[i]);
AKANTU_DEBUG_ASSERT(global_connect[i] < mesh.getNbGlobalNodes(),
"This global node send in the connectivity does not seem correct "
<< global_connect[i] << " corresponding to "
<< local_connect[i] << " from element " << elem->element);
}
elempproc(type).push_back(global_connect);
communicator.send_element[p].push_back(*elem);
}
delete to_send;
}
delete cell_ids;
}
delete [] first_cells;
delete [] last_cells;
delete [] bounding_boxes;
AKANTU_DEBUG_INFO("I have finished to compute intersection,"
<< " no it's time to communicate with my neighbors");
/**
* Sending loop, sends the connectivity asynchronously to all concerned proc
*/
std::vector<CommunicationRequest *> isend_requests;
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank) continue;
if(intersects_proc[p]) {
ElementTypeMapArray<UInt> & elempproc = *(element_per_proc[p]);
ElementTypeMapArray<UInt>::type_iterator it_type = elempproc.firstType(_all_dimensions, _not_ghost);
ElementTypeMapArray<UInt>::type_iterator last_type = elempproc.lastType (_all_dimensions, _not_ghost);
UInt count = 0;
for (; it_type != last_type; ++it_type) {
Array<UInt> & conn = elempproc(*it_type, _not_ghost);
UInt info[2];
info[0] = (UInt) *it_type;
info[1] = conn.getSize() * conn.getNbComponent();
AKANTU_DEBUG_INFO("I have " << conn.getSize() << " elements of type " << *it_type
<< " to send to processor " << p
<< " (communication tag : " << Tag::genTag(my_rank, count, DATA_TAG) << ")");
isend_requests.push_back(comm.asyncSend(info, 2, p, Tag::genTag(my_rank, count, SIZE_TAG)));
- if(info[1])
+ if(info[1] != 0)
isend_requests.push_back(comm.asyncSend<UInt>(conn.storage(),
info[1],
p, Tag::genTag(my_rank, count, DATA_TAG)));
++count;
}
UInt info[2];
info[0] = (UInt) _not_defined;
info[1] = 0;
isend_requests.push_back(comm.asyncSend(info, 2, p, Tag::genTag(my_rank, count, SIZE_TAG)));
}
}
/**
* Receives the connectivity and store them in the ghosts elements
*/
Array<UInt> & global_nodes_ids = const_cast<Array<UInt> &>(mesh.getGlobalNodesIds());
Array<Int> & nodes_type = const_cast<Array<Int> &>(const_cast<const Mesh &>(mesh).getNodesType());
std::vector<CommunicationRequest *> isend_nodes_requests;
UInt nb_nodes_to_recv[nb_proc];
UInt nb_total_nodes_to_recv = 0;
UInt nb_current_nodes = global_nodes_ids.getSize();
NewNodesEvent new_nodes;
NewElementsEvent new_elements;
Array<UInt> * ask_nodes_per_proc = new Array<UInt>[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
nb_nodes_to_recv[p] = 0;
if(p == my_rank) continue;
Array<UInt> & ask_nodes = ask_nodes_per_proc[p];
UInt count = 0;
if(intersects_proc[p]) {
ElementType type = _not_defined;
do {
UInt info[2] = { 0 };
comm.receive(info, 2, p, Tag::genTag(p, count, SIZE_TAG));
type = (ElementType) info[0];
if(type != _not_defined) {
UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);;
UInt nb_element = info[1] / nb_nodes_per_element;
Array<UInt> tmp_conn(nb_element, nb_nodes_per_element);
tmp_conn.clear();
- if(info[1])
+ if(info[1] != 0)
comm.receive<UInt>(tmp_conn.storage(), info[1], p, Tag::genTag(p, count, DATA_TAG));
AKANTU_DEBUG_INFO("I will receive " << nb_element << " elements of type " << ElementType(info[0])
<< " from processor " << p
<< " (communication tag : " << Tag::genTag(p, count, DATA_TAG) << ")");
Array<UInt> & ghost_connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(type, _ghost));
UInt nb_ghost_element = ghost_connectivity.getSize();
Element element(type, 0, _ghost);
UInt conn[nb_nodes_per_element];
for (UInt el = 0; el < nb_element; ++el) {
UInt nb_node_to_ask_for_elem = 0;
for (UInt n = 0; n < nb_nodes_per_element; ++n) {
UInt gn = tmp_conn(el, n);
UInt ln = global_nodes_ids.find(gn);
AKANTU_DEBUG_ASSERT(gn < mesh.getNbGlobalNodes(), "This global node seems not correct " << gn << " from element " << el << " node " << n);
if(ln == UInt(-1)) {
global_nodes_ids.push_back(gn);
nodes_type.push_back(-3); // pure ghost node
ln = nb_current_nodes;
new_nodes.getList().push_back(ln);
++nb_current_nodes;
ask_nodes.push_back(gn);
++nb_node_to_ask_for_elem;
}
conn[n] = ln;
}
// all the nodes are already known locally, the element should already exists
UInt c = UInt(-1);
if(nb_node_to_ask_for_elem == 0) {
c = ghost_connectivity.find(conn);
element.element = c;
}
if(c == UInt(-1)) {
element.element = nb_ghost_element;
++nb_ghost_element;
ghost_connectivity.push_back(conn);
new_elements.getList().push_back(element);
}
communicator.recv_element[p].push_back(element);
}
}
count++;
} while(type != _not_defined);
AKANTU_DEBUG_INFO("I have " << ask_nodes.getSize()
<< " missing nodes for elements coming from processor " << p
<< " (communication tag : " << Tag::genTag(my_rank, 0, ASK_NODES_TAG) << ")");
+ ask_nodes.push_back(UInt(-1));
+
isend_nodes_requests.push_back(comm.asyncSend(ask_nodes.storage(), ask_nodes.getSize(),
p, Tag::genTag(my_rank, 0, ASK_NODES_TAG)));
- nb_nodes_to_recv[p] = ask_nodes.getSize();
- nb_total_nodes_to_recv += ask_nodes.getSize();
+ nb_nodes_to_recv[p] = ask_nodes.getSize() - 1;
+ nb_total_nodes_to_recv += nb_nodes_to_recv[p];
}
}
comm.waitAll(isend_requests);
comm.freeCommunicationRequest(isend_requests);
for (UInt p = 0; p < nb_proc; ++p) {
if(element_per_proc[p]) delete element_per_proc[p];
}
delete [] element_per_proc;
/**
* Sends requested nodes to proc
*/
Array<Real> & nodes = const_cast<Array<Real> &>(mesh.getNodes());
UInt nb_nodes = nodes.getSize();
std::vector<CommunicationRequest *> isend_coordinates_requests;
Array<Real> * nodes_to_send_per_proc = new Array<Real>[nb_proc];
for (UInt p = 0; p < nb_proc; ++p) {
if(p == my_rank || !intersects_proc[p]) continue;
Array<UInt> asked_nodes;
CommunicationStatus status;
AKANTU_DEBUG_INFO("Waiting list of nodes to send to processor " << p
<< "(communication tag : " << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
comm.probe<UInt>(p, Tag::genTag(p, 0, ASK_NODES_TAG), status);
UInt nb_nodes_to_send = status.getSize();
asked_nodes.resize(nb_nodes_to_send);
- AKANTU_DEBUG_INFO("I have " << nb_nodes_to_send
+ AKANTU_DEBUG_INFO("I have " << nb_nodes_to_send - 1
<< " nodes to send to processor " << p
<< " (communication tag : " << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
AKANTU_DEBUG_INFO("Getting list of nodes to send to processor " << p
<< " (communication tag : " << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
comm.receive(asked_nodes.storage(), nb_nodes_to_send, p, Tag::genTag(p, 0, ASK_NODES_TAG));
+ nb_nodes_to_send--;
+ asked_nodes.resize(nb_nodes_to_send);
+
Array<Real> & nodes_to_send = nodes_to_send_per_proc[p];
nodes_to_send.extendComponentsInterlaced(spatial_dimension, 1);
for (UInt n = 0; n < nb_nodes_to_send; ++n) {
UInt ln = global_nodes_ids.find(asked_nodes(n));
AKANTU_DEBUG_ASSERT(ln != UInt(-1), "The node [" << asked_nodes(n) << "] requested by proc " << p << " was not found locally!");
nodes_to_send.push_back(nodes.storage() + ln * spatial_dimension);
}
- AKANTU_DEBUG_INFO("Sending the nodes to processor " << p
- << " (communication tag : " << Tag::genTag(p, 0, ASK_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)
+ else {
+ AKANTU_DEBUG_INFO("No nodes to send to processor " << p);
+ }
+#endif
}
comm.waitAll(isend_nodes_requests);
comm.freeCommunicationRequest(isend_nodes_requests);
delete [] ask_nodes_per_proc;
nodes.resize(nb_total_nodes_to_recv + nb_nodes);
for (UInt p = 0; p < nb_proc; ++p) {
if((p != my_rank) && (nb_nodes_to_recv[p] > 0)) {
- AKANTU_DEBUG_INFO("Receiving the nodes from processor " << p
- << " (communication tag : " << Tag::genTag(p, 0, ASK_NODES_TAG) << ")");
+ AKANTU_DEBUG_INFO("Receiving the " << nb_nodes_to_recv[p] << " nodes from processor " << p
+ << " (communication tag : " << Tag::genTag(p, 0, SEND_NODES_TAG) << ")");
comm.receive(nodes.storage() + nb_nodes * spatial_dimension,
nb_nodes_to_recv[p] * spatial_dimension,
p, Tag::genTag(p, 0, SEND_NODES_TAG));
nb_nodes += nb_nodes_to_recv[p];
}
+#if not defined (AKANTU_NDEBUG)
+ else {
+ if(p != my_rank) {
+ AKANTU_DEBUG_INFO("No nodes to receive from processor " << p);
+ }
+ }
+#endif
+
}
comm.waitAll(isend_coordinates_requests);
comm.freeCommunicationRequest(isend_coordinates_requests);
delete [] nodes_to_send_per_proc;
+ // Register the tags if any
+ if(synchronizer_registry) {
+ std::set<SynchronizationTag>::const_iterator it = tags_to_register.begin();
+ std::set<SynchronizationTag>::const_iterator end = tags_to_register.end();
+ for (; it != end; ++it) {
+ synchronizer_registry->registerSynchronizer(communicator, *it);
+ }
+ }
+
mesh.sendEvent(new_nodes);
mesh.sendEvent(new_elements);
delete [] intersects_proc;
AKANTU_DEBUG_OUT();
return &communicator;
}
/* -------------------------------------------------------------------------- */
template GridSynchronizer *
-GridSynchronizer::createGridSynchronizer<QuadraturePoint>(Mesh & mesh,
- const SpatialGrid<QuadraturePoint> & grid,
- SynchronizerID id,
- 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,
- MemoryID memory_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 8f381fd2d..22331a268 100644
--- a/src/synchronizer/grid_synchronizer.hh
+++ b/src/synchronizer/grid_synchronizer.hh
@@ -1,92 +1,101 @@
/**
* @file grid_synchronizer.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Oct 03 2011
* @date last modification: Thu Feb 21 2013
*
* @brief synchronizer based in RegularGrid
*
* @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 "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",
- MemoryID memory_id = 0);
+ SynchronizerRegistry * synch_registry = NULL,
+ const std::set<SynchronizationTag> & tags_to_register = std::set<SynchronizationTag>(),
+ MemoryID memory_id = 0, const bool register_to_event_manager = true);
protected:
+ /// Define the tags that will be used in the send and receive instructions
enum CommTags {
SIZE_TAG = 0,
DATA_TAG = 1,
ASK_NODES_TAG = 2,
SEND_NODES_TAG = 3
};
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
};
__END_AKANTU__
#endif /* __AKANTU_GRID_SYNCHRONIZER_HH__ */
diff --git a/src/synchronizer/mpi_type_wrapper.hh b/src/synchronizer/mpi_type_wrapper.hh
index 58ef3719d..d633f76e7 100644
--- a/src/synchronizer/mpi_type_wrapper.hh
+++ b/src/synchronizer/mpi_type_wrapper.hh
@@ -1,79 +1,79 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <mpi.h>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "static_communicator_mpi.hh"
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_MPI_TYPE_WRAPPER_HH__
#define __AKANTU_MPI_TYPE_WRAPPER_HH__
__BEGIN_AKANTU__
class MPITypeWrapper {
public:
MPITypeWrapper(StaticCommunicatorMPI & static_comm) : static_comm(static_comm) {
}
template<typename T>
static inline MPI_Datatype getMPIDatatype();
inline void setMPICommunicator(MPI_Comm comm) {
communicator = comm;
- Int prank, psize;
+ 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/real_static_communicator.hh b/src/synchronizer/real_static_communicator.hh
index ee06e11af..aed480b2d 100644
--- a/src/synchronizer/real_static_communicator.hh
+++ b/src/synchronizer/real_static_communicator.hh
@@ -1,98 +1,108 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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.hh b/src/synchronizer/static_communicator.hh
index fbceb7391..3031cc36c 100644
--- a/src/synchronizer/static_communicator.hh
+++ b/src/synchronizer/static_communicator.hh
@@ -1,208 +1,215 @@
/**
* @file static_communicator.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Wed Sep 01 2010
* @date last modification: Mon Jul 21 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STATIC_COMMUNICATOR_HH__
#define __AKANTU_STATIC_COMMUNICATOR_HH__
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "aka_event_handler_manager.hh"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#define AKANTU_COMMUNICATOR_LIST_0 BOOST_PP_SEQ_NIL
#include "static_communicator_dummy.hh"
-#define AKANTU_COMMUNICATOR_LIST_1 \
- BOOST_PP_SEQ_PUSH_BACK(AKANTU_COMMUNICATOR_LIST_0, \
- (_communicator_dummy, (StaticCommunicatorDummy, BOOST_PP_NIL)))
+#define AKANTU_COMMUNICATOR_LIST_1 \
+ BOOST_PP_SEQ_PUSH_BACK(AKANTU_COMMUNICATOR_LIST_0, \
+ (_communicator_dummy, (StaticCommunicatorDummy, BOOST_PP_NIL)))
#if defined(AKANTU_USE_MPI)
# include "static_communicator_mpi.hh"
-# define AKANTU_COMMUNICATOR_LIST_ALL \
- BOOST_PP_SEQ_PUSH_BACK(AKANTU_COMMUNICATOR_LIST_1, \
- (_communicator_mpi, (StaticCommunicatorMPI, BOOST_PP_NIL)))
+# 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) {}
const StaticCommunicator & communicator;
};
class CommunicatorEventHandler {
public:
virtual ~CommunicatorEventHandler() {}
virtual void onCommunicatorFinalize(__attribute__((unused)) const StaticCommunicator & communicator) { }
-protected:
+private:
inline void sendEvent(const FinalizeCommunicatorEvent & event) {
onCommunicatorFinalize(event.communicator);
}
template<class EventHandler>
friend class EventHandlerManager;
};
-
class StaticCommunicator : public EventHandlerManager<CommunicatorEventHandler>{
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
protected:
StaticCommunicator(int & argc, char ** & argv,
- CommunicatorType type = _communicator_mpi);
+ CommunicatorType type = _communicator_mpi);
public:
virtual ~StaticCommunicator() {
FinalizeCommunicatorEvent *event = new FinalizeCommunicatorEvent(*this);
this->sendEvent(*event);
- delete event;
+ delete event;
delete real_static_communicator;
+ is_instantiated = false;
+ StaticCommunicator::static_communicator = NULL;
+
};
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
/* ------------------------------------------------------------------------ */
/* Point to Point */
/* ------------------------------------------------------------------------ */
template<typename T> inline void send(T * buffer, Int size,
- Int receiver, Int tag);
+ Int receiver, Int tag);
template<typename T> inline void receive(T * buffer, Int size,
- Int sender, Int tag);
+ Int sender, Int tag);
template<typename T> inline CommunicationRequest * asyncSend(T * buffer,
- Int size,
- Int receiver,
- Int tag);
+ Int size,
+ Int receiver,
+ Int tag);
template<typename T> inline CommunicationRequest * asyncReceive(T * buffer,
- Int size,
- Int sender,
- Int tag);
+ Int size,
+ Int sender,
+ Int tag);
template<typename T> inline void probe(Int sender, Int tag,
CommunicationStatus & status);
/* ------------------------------------------------------------------------ */
/* Collectives */
/* ------------------------------------------------------------------------ */
- template<typename T> inline void allReduce(T * values, Int nb_values,
- const SynchronizerOperation & op);
-
- template<typename T> inline void allGather(T * values, Int nb_values);
- template<typename T> inline void allGatherV(T * values, Int * nb_values);
-
- template<typename T> inline void gather(T * values, Int nb_values,
- Int root = 0);
- template<typename T> inline void gatherV(T * values, Int * nb_values,
- Int root = 0);
- template<typename T> inline void broadcast(T * values, Int nb_values,
- Int root = 0);
+ template<typename T> inline void reduce(T * values, int nb_values,
+ const SynchronizerOperation & op,
+ int root = 0);
+ template<typename T> inline void allReduce(T * values, int nb_values,
+ const SynchronizerOperation & op);
+
+ template<typename T> inline void allGather(T * values, int nb_values);
+ template<typename T> inline void allGatherV(T * values, int * nb_values);
+
+ template<typename T> inline void gather(T * values, int nb_values,
+ int root = 0);
+ template<typename T> inline void gatherV(T * values, int * nb_values,
+ int root = 0);
+ template<typename T> inline void broadcast(T * values, int nb_values,
+ int root = 0);
inline void barrier();
/* ------------------------------------------------------------------------ */
/* Request handling */
/* ------------------------------------------------------------------------ */
inline bool testRequest(CommunicationRequest * request);
inline void wait(CommunicationRequest * request);
inline void waitAll(std::vector<CommunicationRequest *> & requests);
inline void freeCommunicationRequest(CommunicationRequest * request);
inline void freeCommunicationRequest(std::vector<CommunicationRequest *> & requests);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
virtual Int getNbProc() const { return real_static_communicator->psize; };
virtual Int whoAmI() const { return real_static_communicator->prank; };
AKANTU_GET_MACRO(RealStaticCommunicator, *real_static_communicator, const RealStaticCommunicator &);
AKANTU_GET_MACRO_NOT_CONST(RealStaticCommunicator, *real_static_communicator, RealStaticCommunicator &);
template<class Comm>
Comm & getRealStaticCommunicator() { return dynamic_cast<Comm &>(*real_static_communicator); }
static StaticCommunicator & getStaticCommunicator(CommunicatorType type = _communicator_mpi);
static StaticCommunicator & getStaticCommunicator(int & argc, char ** & argv,
- CommunicatorType type = _communicator_mpi);
+ CommunicatorType type = _communicator_mpi);
static bool isInstantiated() { return is_instantiated; };
+ int getMaxTag();
+ int getMinTag();
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
static bool is_instantiated;
static StaticCommunicator * static_communicator;
RealStaticCommunicator * real_static_communicator;
CommunicatorType real_type;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "static_communicator_inline_impl.hh"
/* -------------------------------------------------------------------------- */
/* Inline Functions ArrayBase */
/* -------------------------------------------------------------------------- */
inline std::ostream & operator<<(std::ostream & stream, const CommunicationRequest & _this)
{
_this.printself(stream);
return stream;
}
__END_AKANTU__
#endif /* __AKANTU_STATIC_COMMUNICATOR_HH__ */
diff --git a/src/synchronizer/static_communicator_dummy.hh b/src/synchronizer/static_communicator_dummy.hh
index 4bcbb13d9..37f0a492f 100644
--- a/src/synchronizer/static_communicator_dummy.hh
+++ b/src/synchronizer/static_communicator_dummy.hh
@@ -1,151 +1,158 @@
/**
* @file static_communicator_dummy.hh
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date Wed Sep 01 17:57:12 2010
*
* @brief Class handling the parallel communications
*
* @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/>.
*
*/
/* -------------------------------------------------------------------------- */
#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 8b7dd7506..63e6c1d61 100644
--- a/src/synchronizer/static_communicator_inline_impl.hh
+++ b/src/synchronizer/static_communicator_inline_impl.hh
@@ -1,160 +1,177 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* 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::allReduce(T * values, Int nb_values,
+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) {
+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) {
+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) {
+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) {
+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) {
+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 441a3fcb0..99cc61b08 100644
--- a/src/synchronizer/static_communicator_mpi.cc
+++ b/src/synchronizer/static_communicator_mpi.cc
@@ -1,396 +1,495 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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);
}
mpi_data = new MPITypeWrapper(*this);
mpi_data->setMPICommunicator(MPI_COMM_WORLD);
}
/* -------------------------------------------------------------------------- */
-StaticCommunicatorMPI::~StaticCommunicatorMPI() {
- MPI_Finalize();
-}
+StaticCommunicatorMPI::~StaticCommunicatorMPI() { 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>
-void StaticCommunicatorMPI::allReduce(T * values, Int nb_values,
- const SynchronizerOperation & op) {
+template <typename T>
+void StaticCommunicatorMPI::reduce(T * values, int nb_values,
+ const SynchronizerOperation & op, int root) {
+ MPI_Comm communicator = mpi_data->getMPICommunicator();
+ MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>();
+
+#if !defined(AKANTU_NDEBUG)
+ int ret =
+#endif
+ MPI_Reduce(MPI_IN_PLACE, values, nb_values, type,
+ MPITypeWrapper::getMPISynchronizerOperation(op), root,
+ communicator);
+ AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Allreduce.");
+}
+
+/* -------------------------------------------------------------------------- */
+template <typename T>
+void StaticCommunicatorMPI::allReduce(T * values, int nb_values,
+ const SynchronizerOperation & op) {
MPI_Comm communicator = mpi_data->getMPICommunicator();
MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>();
#if !defined(AKANTU_NDEBUG)
int ret =
#endif
- MPI_Allreduce(MPI_IN_PLACE, values, nb_values, type,
- MPITypeWrapper::getMPISynchronizerOperation(op),
- communicator);
+ MPI_Allreduce(MPI_IN_PLACE, values, nb_values, type,
+ MPITypeWrapper::getMPISynchronizerOperation(op),
+ communicator);
AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Allreduce.");
}
/* -------------------------------------------------------------------------- */
-template<typename T>
-void StaticCommunicatorMPI::allGather(T * values, Int nb_values) {
+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>
-void StaticCommunicatorMPI::allGatherV(T * values, Int * nb_values) {
+template <typename T>
+void StaticCommunicatorMPI::allGatherV(T * values, int * nb_values) {
MPI_Comm communicator = mpi_data->getMPICommunicator();
- Int * displs = new Int[psize];
+ int * displs = new int[psize];
displs[0] = 0;
- for (Int i = 1; i < psize; ++i) {
- displs[i] = displs[i-1] + nb_values[i-1];
+ for (int i = 1; i < psize; ++i) {
+ displs[i] = displs[i - 1] + nb_values[i - 1];
}
MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>();
#if !defined(AKANTU_NDEBUG)
int ret =
#endif
- MPI_Allgatherv(MPI_IN_PLACE, *nb_values, type, values, nb_values, displs, type, communicator);
+ 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>
-void StaticCommunicatorMPI::gather(T * values, Int nb_values, Int root) {
+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>
-void StaticCommunicatorMPI::gatherV(T * values, Int * nb_values, Int root) {
+template <typename T>
+void StaticCommunicatorMPI::gatherV(T * values, int * nb_values, int root) {
MPI_Comm communicator = mpi_data->getMPICommunicator();
- Int * displs = NULL;
- if(prank == root) {
- displs = new Int[psize];
+ int * displs = NULL;
+ if (prank == root) {
+ displs = new int[psize];
displs[0] = 0;
- for (Int i = 1; i < psize; ++i) {
- displs[i] = displs[i-1] + nb_values[i-1];
+ for (int i = 1; i < psize; ++i) {
+ displs[i] = displs[i - 1] + nb_values[i - 1];
}
}
T * send_buf = NULL, * recv_buf = NULL;
- if(prank == root) {
- send_buf = (T *) MPI_IN_PLACE;
+ 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>
-void StaticCommunicatorMPI::broadcast(T * values, Int nb_values, Int root) {
+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<Real>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<float>() {
+ return MPI_FLOAT;
+}
+
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<double>() {
return MPI_DOUBLE;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<UInt>() {
- return MPI_UNSIGNED;
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<long double>() {
+ return MPI_LONG_DOUBLE;
}
-template<>
-MPI_Datatype MPITypeWrapper::getMPIDatatype<Int>() {
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<signed int>() {
return MPI_INT;
}
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned int>() {
+ return MPI_UNSIGNED;
+}
+
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<signed long int>() {
+ return MPI_LONG;
+}
+
+template <> MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned long int>() {
+ return MPI_UNSIGNED_LONG;
+}
+
+template <>
+MPI_Datatype MPITypeWrapper::getMPIDatatype<signed long long int>() {
+ return MPI_LONG_LONG;
+}
+
+template <>
+MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned long long int>() {
+ return MPI_UNSIGNED_LONG_LONG;
+}
+
+template <>
+MPI_Datatype MPITypeWrapper::getMPIDatatype<SCMinMaxLoc<double, int> >() {
+ return MPI_DOUBLE_INT;
+}
+
+template <>
+MPI_Datatype MPITypeWrapper::getMPIDatatype<SCMinMaxLoc<float, int> >() {
+ return MPI_FLOAT_INT;
+}
+
/* -------------------------------------------------------------------------- */
/* Template instantiation */
/* -------------------------------------------------------------------------- */
-#define AKANTU_MPI_COMM_INSTANTIATE(T) \
- template void StaticCommunicatorMPI::send<T> (T * buffer, Int size, Int receiver, Int tag); \
- template void StaticCommunicatorMPI::receive<T>(T * buffer, Int size, Int sender, Int tag); \
- template CommunicationRequest * StaticCommunicatorMPI::asyncSend<T> (T * buffer, Int size, Int receiver, Int tag); \
- template CommunicationRequest * StaticCommunicatorMPI::asyncReceive<T>(T * buffer, Int size, Int sender, Int tag); \
- template void StaticCommunicatorMPI::probe<T>(Int sender, Int tag, CommunicationStatus & status); \
- template void StaticCommunicatorMPI::allGather<T> (T * values, Int nb_values); \
- template void StaticCommunicatorMPI::allGatherV<T>(T * values, Int * nb_values); \
- template void StaticCommunicatorMPI::gather<T> (T * values, Int nb_values, Int root); \
- template void StaticCommunicatorMPI::gatherV<T>(T * values, Int * nb_values, Int root); \
- template void StaticCommunicatorMPI::broadcast<T>(T * values, Int nb_values, Int root); \
- template void StaticCommunicatorMPI::allReduce<T>(T * values, Int nb_values, const SynchronizerOperation & op);
-
+#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 f02393427..6f93f977a 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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Akantu. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#ifndef __AKANTU_STATIC_COMMUNICATOR_MPI_HH__
#define __AKANTU_STATIC_COMMUNICATOR_MPI_HH__
/* -------------------------------------------------------------------------- */
#include "real_static_communicator.hh"
/* -------------------------------------------------------------------------- */
#include <vector>
__BEGIN_AKANTU__
class MPITypeWrapper;
/* -------------------------------------------------------------------------- */
class StaticCommunicatorMPI : public RealStaticCommunicator {
/* ------------------------------------------------------------------------ */
/* Constructors/Destructors */
/* ------------------------------------------------------------------------ */
public:
StaticCommunicatorMPI(int & argc, char ** & argv);
virtual ~StaticCommunicatorMPI();
/* ------------------------------------------------------------------------ */
/* Methods */
/* ------------------------------------------------------------------------ */
public:
template<typename T> void send (T * buffer, Int size, Int receiver, Int tag);
template<typename T> void receive(T * buffer, Int size, Int sender, Int tag);
template<typename T> CommunicationRequest * asyncSend (T * buffer, Int size,
Int receiver, Int tag);
template<typename T> CommunicationRequest * asyncReceive(T * buffer, Int size,
Int sender, Int tag);
template<typename T> void probe(Int sender, Int tag,
CommunicationStatus & status);
- template<typename T> void allGather (T * values, Int nb_values);
- template<typename T> void allGatherV(T * values, Int * nb_values);
+ template<typename T> void 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 waitAll(std::vector<CommunicationRequest *> & requests);
void barrier();
- template<typename T> void allReduce(T * values, Int nb_values,
+ template<typename T> void reduce(T * values, int nb_values,
+ const SynchronizerOperation & op,
+ int root);
+ template<typename T> void allReduce(T * values, int nb_values,
const SynchronizerOperation & op);
/* ------------------------------------------------------------------------ */
/* Accessors */
/* ------------------------------------------------------------------------ */
public:
const MPITypeWrapper & getMPITypeWrapper() const { return *mpi_data; }
MPITypeWrapper & getMPITypeWrapper() { return *mpi_data; }
+ int getMinTag();
+ int getMaxTag();
+
private:
void setRank(int prank) { this->prank = prank; }
void setSize(int psize) { this->psize = psize; }
/* ------------------------------------------------------------------------ */
/* Class Members */
/* ------------------------------------------------------------------------ */
private:
friend class MPITypeWrapper;
MPITypeWrapper * mpi_data;
};
/* -------------------------------------------------------------------------- */
/* inline functions */
/* -------------------------------------------------------------------------- */
#include "static_communicator_mpi_inline_impl.hh"
__END_AKANTU__
#endif /* __AKANTU_STATIC_COMMUNICATOR_MPI_HH__ */
diff --git a/src/synchronizer/synchronizer.cc b/src/synchronizer/synchronizer.cc
index beab3974c..bcd018f79 100644
--- a/src/synchronizer/synchronizer.cc
+++ b/src/synchronizer/synchronizer.cc
@@ -1,56 +1,57 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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) {
+ 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 a4b4c232f..4d84441b5 100644
--- a/src/synchronizer/synchronizer.hh
+++ b/src/synchronizer/synchronizer.hh
@@ -1,133 +1,173 @@
/**
* @file synchronizer.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@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
*
* @brief interface for communicator and pbc 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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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) {}
- template<typename CommTag>
+ operator int() { return int(tag); } // remove the sign bit
+
+ 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_receive.resize(size);
+ }
+
+ public:
+ /// size of data to send to each processor
+ std::vector<UInt> size_to_send;
+ /// size of data to recv to each processor
+ std::vector<UInt> size_to_receive;
+ std::vector<CommunicationBuffer> send_buffer;
+ std::vector<CommunicationBuffer> recv_buffer;
+
+ std::vector<CommunicationRequest *> send_requests;
+ std::vector<CommunicationRequest *> recv_requests;
+ };
+
/// id of the synchronizer
SynchronizerID id;
/// message counter per tag
std::map<SynchronizationTag, UInt> tag_counter;
-};
+ /// the static memory instance
+ StaticCommunicator * static_communicator;
+};
/// standard output stream operator
-inline std::ostream & operator <<(std::ostream & stream, const Synchronizer & _this)
-{
+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..e09eefcee 100644
--- a/src/synchronizer/synchronizer_registry.cc
+++ b/src/synchronizer/synchronizer_registry.cc
@@ -1,128 +1,128 @@
/**
* @file synchronizer_registry.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Thu Jun 16 2011
* @date last modification: Tue Nov 06 2012
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 7b116afef..5e7e09617 100644
--- a/src/synchronizer/synchronizer_registry.hh
+++ b/src/synchronizer/synchronizer_registry.hh
@@ -1,115 +1,115 @@
/**
* @file synchronizer_registry.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date creation: Thu Jun 16 2011
* @date last modification: Tue Nov 06 2012
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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 85989d289..ac9efb28a 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,85 +1,85 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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_fem "Test finite element functionalties")
+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" PACKAGE mumps)
+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" PACKAGE contact)
-
-add_akantu_test(test_surface_extraction "Test mesh utils surface extraction")
-add_akantu_test(test_synchronizer "Test synchronizers" PACKAGE parallel)
+add_akantu_test(test_contact "Test the contact part of Akantu")
+add_akantu_test(test_geometry "Test the geometry module of Akantu")
+add_akantu_test(test_synchronizer "Test synchronizers")
+add_akantu_test(test_python_interface "Test python interface")
file(GLOB_RECURSE __all_files "*.*")
set(_all_files)
foreach(_file ${__all_files})
if("${_file}" MATCHES "${PROJECT_SOURCE_DIR}/test")
file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_file})
list(APPEND _all_files ${__file})
endif()
endforeach()
file(GLOB_RECURSE __all_files "*CMakeLists.txt")
foreach(_file ${__all_files})
if("${_file}" MATCHES "${PROJECT_SOURCE_DIR}/test")
file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_file})
list(APPEND _cmakes ${__file})
endif()
endforeach()
list(APPEND AKANTU_TESTS_FILES ${_cmakes})
foreach(_file ${_all_files})
list(FIND AKANTU_TESTS_FILES ${_file} _ret)
if(_ret EQUAL -1)
list(APPEND AKANTU_TESTS_EXCLUDE_FILES /${_file})
endif()
endforeach()
set(AKANTU_TESTS_EXCLUDE_FILES ${AKANTU_TESTS_EXCLUDE_FILES} PARENT_SCOPE)
#foreach(f ${AKANTU_TESTS_EXCLUDE_FILES})
# message(${f})
#endforeach()
diff --git a/test/test_common/CMakeLists.txt b/test/test_common/CMakeLists.txt
index 96213e2cf..37f5501a2 100644
--- a/test/test_common/CMakeLists.txt
+++ b/test/test_common/CMakeLists.txt
@@ -1,38 +1,41 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Jul 30 2012
# @date last modification: Fri Feb 21 2014
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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_grid_mesh circle.geo 2 1)
add_akantu_test(test_vector "Test akantu vector")
-register_test(test_csr test_csr.cc)
+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)
\ No newline at end of file
+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_grid.cc b/test/test_common/test_grid.cc
index d34767c67..d8c06d1ca 100644
--- a/test/test_common/test_grid.cc
+++ b/test/test_common/test_grid.cc
@@ -1,107 +1,107 @@
/**
* @file test_grid.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Mon Aug 06 2012
* @date last modification: Mon Jun 23 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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
+ // 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_types.cc b/test/test_common/test_types.cc
new file mode 100644
index 000000000..53bb2dcc5
--- /dev/null
+++ b/test/test_common/test_types.cc
@@ -0,0 +1,348 @@
+/**
+ * @file test_types.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date Mon May 4 14:02:59 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "aka_common.hh"
+#include "aka_types.hh"
+
+#include <stdexcept>
+#include <iostream>
+#include <sstream>
+
+using namespace akantu;
+
+
+const Real tolerance = 1e-15;
+
+std::string itoa(UInt a) {
+ std::stringstream sstr;
+ sstr << a;
+ return sstr.str();
+}
+
+UInt testcounter = 0;
+
+struct wrap_error : std::runtime_error {
+ wrap_error(const std::string & msg) : std::runtime_error(msg) {}
+};
+
+struct size_error : std::runtime_error {
+ size_error(const std::string & msg) : std::runtime_error(msg) {}
+};
+
+struct data_error : std::runtime_error {
+ data_error(const std::string & msg, UInt i) : std::runtime_error(msg), index(i) {}
+ UInt index;
+};
+
+
+template<class type>
+void compare_storages_with_ref(const type & a, Real * ref, UInt size, UInt line, const std::string & txt) {
+ std::cout << std::setw(3) << (testcounter++) << ": " << std::setw(10) << txt << " - " << a
+ << " - wrapped: " << std::boolalpha << a.isWrapped() << std::endl;
+
+ if (a.size() != size)
+ throw size_error("the size is not correct " + itoa(a.size()) +
+ " instead of " + itoa(size) +
+ " [Test at line: " + itoa(line) + "]");
+
+ Real * a_ptr = a.storage();
+ for (UInt i = 0; i < a.size(); ++i) {
+ if (!((std::abs(a_ptr[i]) < tolerance && std::abs(ref[i]) < tolerance) ||
+ std::abs((a_ptr[i] - ref[i])/ a_ptr[i]) < tolerance)) {
+ std::stringstream txt;
+ txt << " std::abs(" << a_ptr[i] << " - " << ref[i]
+ << " [= " << std::abs(a_ptr[i] - ref[i]) << "] ) > " << tolerance;
+ throw data_error("storage differs at index " + itoa(i) +
+ " [Test at line: " + itoa(line) + "]" + txt.str(),
+ i);
+ }
+ }
+
+ if (a_ptr == ref && !a.isWrapped())
+ throw wrap_error("the storage should be wrapped but it is not [Test at line: " + itoa(line) + "]");
+ if (a_ptr != ref && a.isWrapped())
+ throw wrap_error("the storage should not be wrapped but it is [Test at line: " + itoa(line) + "]");
+}
+
+#define COMPARE(a, aref, txt) \
+ compare_storages_with_ref(a, \
+ aref, \
+ sizeof(aref)/sizeof(aref[0]), \
+ __LINE__, \
+ txt)
+#define COMPARE_STORAGE(a, aref, txt) \
+ compare_storages_with_ref(a, \
+ aref.storage(), \
+ aref.size(), \
+ __LINE__, \
+ txt)
+
+const UInt ref_size = 10;
+
+/* -------------------------------------------------------------------------- */
+void test_constructor() {
+ std::cout << "=== Test constructors ===" << std::endl;
+ Real ref1[ref_size] = { 0. };
+ Real ref2[ref_size] = { 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58, 1563.58 };
+ Real ref3[ref_size] = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
+
+ std::cout << "-- Vectors: " << std::endl;
+ Vector<Real> v1(ref_size); COMPARE ( v1, ref1, "normal" );
+ Vector<Real> v2(ref_size, 1563.58); COMPARE ( v2, ref2, "defval" );
+ Vector<Real> v3(ref3, ref_size); COMPARE ( v3, ref3, "wrapped" );
+ Vector<Real> v3dcw(v3); COMPARE ( v3dcw, ref3, "wdeepcopy" );
+ Vector<Real> v3scw(v3, false); COMPARE ( v3scw, ref3, "wshallow" );
+ Vector<Real> v3dc(v3dcw); COMPARE_STORAGE( v3dc, v3dcw, "deepcopy" );
+ Vector<Real> v3sc(v3dcw, false); COMPARE_STORAGE( v3sc, v3dcw, "shallow" );
+ VectorProxy<Real> vp1(ref3, ref_size);
+ Vector<Real> v4(vp1); COMPARE ( v4, ref3, "proxyptr" );
+ VectorProxy<Real> vp2(v3dcw);
+ Vector<Real> v5(vp2); COMPARE_STORAGE( v5, v3dcw, "proxyvdc" );
+ VectorProxy<Real> vp3(v3scw);
+ Vector<Real> v6(vp3); COMPARE ( v6, ref3, "proxyvsc" );
+
+ /* ------------------------------------------------------------------------ */
+ std::cout << "-- Matrices: " << std::endl;
+ Matrix<Real> m1(5, 2); COMPARE ( m1, ref1 , "normal" );
+ Matrix<Real> m1t(2, 5); COMPARE ( m1t, ref1 , "tnormal" );
+ Matrix<Real> m2(5, 2, 1563.58); COMPARE ( m2, ref2 , "defval" );
+ Matrix<Real> m2t(2, 5, 1563.58); COMPARE ( m2t, ref2 , "tdefval" );
+ Matrix<Real> m3(ref3, 5, 2); COMPARE ( m3, ref3 , "wrapped" );
+ Matrix<Real> m3t(ref3, 2, 5); COMPARE ( m3t, ref3 , "twrapped" );
+ Matrix<Real> m3dcw(m3); COMPARE ( m3dcw, ref3 , "wdeepcopy" );
+ Matrix<Real> m3scw(m3, false); COMPARE ( m3scw, ref3 , "wshallow" );
+ Matrix<Real> m3dc(m3dcw); COMPARE_STORAGE( m3dc, m3dcw , "deepcopy" );
+ Matrix<Real> m3sc(m3dcw, false); COMPARE_STORAGE( m3sc, m3dcw , "shallow" );
+ Matrix<Real> m3tdcw(m3t); COMPARE (m3tdcw, ref3 , "twdeepcopy");
+ Matrix<Real> m3tscw(m3t, false); COMPARE (m3tscw, ref3 , "twshallow" );
+ Matrix<Real> m3tdc(m3tdcw); COMPARE_STORAGE( m3tdc, m3tdcw, "tdeepcopy" );
+ Matrix<Real> m3tsc(m3tdcw, false); COMPARE_STORAGE( m3tsc, m3tdcw, "tshallow" );
+ MatrixProxy<Real> mp1(ref3, 5, 2);
+ Matrix<Real> m4(mp1); COMPARE ( m4, ref3, "proxyptr" );
+ MatrixProxy<Real> mp2(m3dcw);
+ Matrix<Real> m5(mp2); COMPARE_STORAGE( m5, m3dcw, "proxyvdc" );
+ MatrixProxy<Real> mp3(m3scw);
+ Matrix<Real> m6(mp3); COMPARE ( m6, ref3, "proxyvsc" );
+ MatrixProxy<Real> mp1t(ref3, 2, 5);
+ Matrix<Real> m4t(mp1t); COMPARE ( m4t, ref3, "tproxyptr" );
+ MatrixProxy<Real> mp2t(m3tdcw);
+ Matrix<Real> m5t(mp2t); COMPARE_STORAGE( m5t, m3tdcw, "tproxyvdc" );
+ MatrixProxy<Real> mp3t(m3tscw);
+ Matrix<Real> m6t(mp3t); COMPARE ( m6t, ref3, "tproxyvsc" );
+}
+
+/* -------------------------------------------------------------------------- */
+void test_equal_and_accessors() {
+ std::cout << "=== Test operator=() ===" << std::endl;
+ Real ref[ref_size] = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
+ Real mod[ref_size] = { 98.7982, 72.1227, 19.7815, 57.6722, 47.1088, 14.9865, 13.3171, 62.7973, 33.9493, 98.3052 };
+
+ std::cout << "-- Vectors: " << std::endl;
+ Vector<Real> v (ref, ref_size);
+ Vector<Real> vm(mod, ref_size);
+ Vector<Real> vref1(v);
+ Vector<Real> v1;
+ v1 = vref1; COMPARE_STORAGE(v1, vref1, "simple=" );
+ for (UInt i = 0; i < ref_size; ++i) v1 (i) = mod[i]; COMPARE (v1, mod, "s_acces" );
+ COMPARE_STORAGE(vref1, v, "refcheck1");
+
+ Vector<Real> v2 = vref1; COMPARE_STORAGE(v2, vref1, "construc=");
+ for (UInt i = 0; i < ref_size; ++i) v2 (i) = mod[i]; COMPARE (v2, mod, "c_acces" );
+ COMPARE_STORAGE(vref1, v, "refcheck2");
+
+ Vector<Real> vref2(vref1, false);
+ Vector<Real> v1w;
+ v1w = vref2; COMPARE_STORAGE(v1w, vref1, "w_simple=" );
+ for (UInt i = 0; i < ref_size; ++i) v1w(i) = mod[i]; COMPARE (v1w, mod, "ws_acces" );
+ try { COMPARE(vref2, ref, "refcheck3"); } catch(wrap_error &) {}
+
+ Vector<Real> v2w = vref2; COMPARE_STORAGE(v2w, vref1, "w_constru=");
+ for (UInt i = 0; i < ref_size; ++i) v2w(i) = mod[i]; COMPARE (v2w, mod, "wc_acces" );
+ try { COMPARE(vref2, ref, "refcheck4"); } catch(wrap_error &) {}
+
+ VectorProxy<Real> vp1(vref1);
+ Vector<Real> v3;
+ v3 = vp1; COMPARE_STORAGE(v3, vref1, "p_simple=" );
+ for (UInt i = 0; i < ref_size; ++i) v3(i) = mod[i]; COMPARE (v3, mod, "ps_acces" );
+ COMPARE_STORAGE(vref1, v, "refcheck5");
+
+ Vector<Real> v4 = vp1; COMPARE_STORAGE(v4, vref1, "p_constru=");
+ for (UInt i = 0; i < ref_size; ++i) v4(i) = mod[i];
+ try { COMPARE(v4, mod, "pc_acces" ); } catch (wrap_error &) {}
+
+ COMPARE(vref1, mod, "refcheck6");
+ try { COMPARE(vref2, mod, "refcheck7"); } catch(wrap_error &) {}
+
+ vref2 = v;
+
+ VectorProxy<Real> vp2(vref2);
+ Vector<Real> v3w;
+ v3w = vp2; COMPARE_STORAGE(v3w, vref1, "pw_simpl=");
+ for (UInt i = 0; i < ref_size; ++i) v3w(i) = mod[i]; COMPARE (v3w, mod, "pws_acces");
+ try { COMPARE(vref2, ref, "refcheck8"); } catch(wrap_error &) {}
+
+ Vector<Real> v4w = vp2; COMPARE_STORAGE( v4w, vref1, "pw_constr=");
+ for (UInt i = 0; i < ref_size; ++i) v4w(i) = mod[i];
+ try { COMPARE(v4w, mod, "pwc_acces"); } catch (wrap_error &) {}
+ COMPARE_STORAGE(v4w, vref2, "refcheck9");
+ try { COMPARE(vref2, mod, "refcheck10"); } catch(wrap_error &) {}
+
+ vref1 = v;
+
+ Real store[ref_size] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
+ Vector<Real> vs(store, 10);
+ VectorProxy<Real> vp3(vs);
+ vp3 = vref1;
+ try { COMPARE_STORAGE(vs, vref1, "vp_equal_v"); } catch(wrap_error &) {}
+
+ Vector<Real> vref3(vm);
+ VectorProxy<Real> vp4(vref3);
+ vp3 = vp4;
+ try { COMPARE(vs, mod, "vp_equal_vp"); } catch(wrap_error &) {}
+
+ /* ------------------------------------------------------------------------ */
+ std::cout << "-- Matrices: " << std::endl;
+
+ Matrix<Real> m (ref, 5, 2);
+ Matrix<Real> mt(ref, 2, 5);
+
+ Matrix<Real> m1 (5, 2);
+ Matrix<Real> m1t(2, 5);
+
+ for (UInt i = 0; i < 5; ++i) {
+ for (UInt j = 0; j < 2; ++j) {
+ m1(i, j) = ref[i + j*5];
+ m1t(j, i) = ref[j + i*2];
+ }
+ }
+ COMPARE_STORAGE( m1, m, "access" );
+ COMPARE_STORAGE(m1t, m, "t_access");
+
+ Matrix<Real> mm (mod, 5, 2);
+ Matrix<Real> mmt(mod, 2, 5);
+
+ Matrix<Real> m2(m);
+ Matrix<Real> m3(m);
+ for (UInt j = 0; j < 2; ++j) {
+ Vector<Real> v = m2(j);
+ for (UInt i = 0; i < 5; ++i)
+ v(i) = mm(i, j);
+ }
+ COMPARE_STORAGE(m2, mm, "slicing");
+
+ for (UInt j = 0; j < 2; ++j)
+ m3(j) = mm(j);
+
+ COMPARE_STORAGE(m3, mm, "slic_slic");
+ COMPARE(mm, mod, "refcheck");
+
+
+ Real mod_1[ref_size] = { 98.7982, 72.1227, 197.815, 57.6722, 47.1088, 14.9865, 13.3171, 627.973, 33.9493, 98.3052 };
+
+ Matrix<Real> m4 (mm);
+ m4 (2,0) = 197.815;
+ m4 (2,1) = 627.973;
+ COMPARE(m4, mod_1, "partial");
+
+ Matrix<Real> m4t(mmt);
+ m4t(0,1) = 197.815;
+ m4t(1,3) = 627.973;
+ COMPARE(m4t, mod_1, "t_partial");
+}
+
+/* -------------------------------------------------------------------------- */
+void test_simple_operators() {
+ std::cout << "=== Test simple operation ===" << std::endl;
+ Real ref[ref_size] = { 23.1594, 79.6184, 77.9052, 47.9922, 12.8674, 37.1445, 64.8991, 80.3364, 98.4064, 73.7858 };
+ Real mod[ref_size] = { 98.7982, 72.1227, 19.7815, 57.6722, 47.1088, 14.9865, 13.3171, 62.7973, 33.9493, 98.3052 };
+
+ Real ref_div[ref_size] = { 1.163905920192984e+00, 4.001326766509196e+00,
+ 3.915227661071464e+00, 2.411910744798472e+00,
+ 6.466680068348578e-01, 1.866745401547894e+00,
+ 3.261589104432606e+00, 4.037410795054780e+00,
+ 4.945542265554328e+00, 3.708201829329581e+00 };
+ Real ref_tim[ref_size] = { 4.608257412000000e+02, 1.584246923200000e+03,
+ 1.550157669600000e+03, 9.549487955999999e+02,
+ 2.560355252000000e+02, 7.391012610000000e+02,
+ 1.291362291800000e+03, 1.598533687200000e+03,
+ 1.958090547200000e+03, 1.468189848400000e+03 };
+ Real ref_p_mod[ref_size] = { 1.219576000000000e+02, 1.517411000000000e+02,
+ 9.768670000000000e+01, 1.056644000000000e+02,
+ 5.997620000000001e+01, 5.213100000000000e+01,
+ 7.821620000000000e+01, 1.431337000000000e+02,
+ 1.323557000000000e+02, 1.720910000000000e+02 };
+ Real ref_m_mod[ref_size] = { -7.563879999999999e+01, 7.495699999999999e+00,
+ 5.812369999999999e+01, -9.680000000000000e+00,
+ -3.424140000000000e+01, 2.215800000000000e+01,
+ 5.158200000000001e+01, 1.753910000000000e+01,
+ 6.445710000000000e+01, -2.451940000000000e+01 };
+ std::cout << "-- Vectors: " << std::endl;
+ Vector<Real> v (ref, ref_size);
+ Vector<Real> vm(mod, ref_size);
+ Vector<Real> vref(v);
+ Vector<Real> vmod(vm);
+
+ Vector<Real> v1 = vref / 19.898; COMPARE(v1, ref_div, "v / s" );
+ Vector<Real> v2 = vref * 19.898; COMPARE(v2, ref_tim, "v * s" );
+ Vector<Real> v3 = 19.898 * vref; COMPARE(v3, ref_tim, "s * v" );
+ Vector<Real> v4 = vref + vmod; COMPARE(v4, ref_p_mod, "v1 + v2" );
+ Vector<Real> v5 = vref - vmod; COMPARE(v5, ref_m_mod, "v1 - v2" );
+ Vector<Real> v6 = vref; v6 *= 19.898; COMPARE(v6, ref_tim, "v *= s" );
+ Vector<Real> v7 = vref; v7 /= 19.898; COMPARE(v7, ref_div, "v /= s" );
+ Vector<Real> v8 = vref; v8 += vmod; COMPARE(v8, ref_p_mod, "v1 += v2");
+ Vector<Real> v9 = vref; v9 -= vmod; COMPARE(v9, ref_m_mod, "v1 -= v2");
+
+ std::cout << "-- Matrices: " << std::endl;
+ Matrix<Real> m (ref, 5, 2);
+ Matrix<Real> mm(mod, 5, 2);
+ Matrix<Real> mref(m);
+ Matrix<Real> mmod(mm);
+
+ Matrix<Real> m1 = mref / 19.898; COMPARE(m1, ref_div, "m / s" );
+ Matrix<Real> m2 = mref * 19.898; COMPARE(m2, ref_tim, "m * s" );
+ Matrix<Real> m3 = 19.898 * mref; COMPARE(m3, ref_tim, "s * m" );
+ Matrix<Real> m4 = mref + mmod; COMPARE(m4, ref_p_mod, "m1 + m2" );
+ Matrix<Real> m5 = mref - mmod; COMPARE(m5, ref_m_mod, "m1 - m2" );
+ Matrix<Real> m6 = mref; m6 *= 19.898; COMPARE(m6, ref_tim, "m *= s" );
+ Matrix<Real> m7 = mref; m7 /= 19.898; COMPARE(m7, ref_div, "m /= s" );
+ Matrix<Real> m8 = mref; m8 += mmod; COMPARE(m8, ref_p_mod, "m1 += m2");
+ Matrix<Real> m9 = mref; m9 -= mmod; COMPARE(m9, ref_m_mod, "m1 -= m2");
+}
+
+
+/* -------------------------------------------------------------------------- */
+int main(int argc, char *argv[]) {
+ test_constructor();
+ test_equal_and_accessors();
+ test_simple_operators();
+
+
+ return 0;
+}
diff --git a/test/test_common/test_vector/CMakeLists.txt b/test/test_common/test_vector/CMakeLists.txt
index 48f14d2dd..1f7ec426d 100644
--- a/test/test_common/test_vector/CMakeLists.txt
+++ b/test/test_common/test_vector/CMakeLists.txt
@@ -1,35 +1,35 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Fri Sep 03 2010
# @date last modification: Tue Nov 06 2012
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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)
-register_test(test_vector_iterator test_vector_iterator.cc)
-register_test(test_matrix test_matrix.cc)
+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_contact/CMakeLists.txt b/test/test_contact/CMakeLists.txt
index fe66b716e..050465450 100644
--- a/test/test_contact/CMakeLists.txt
+++ b/test/test_contact/CMakeLists.txt
@@ -1,115 +1,124 @@
#===============================================================================
# @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
+ DEPENDS hertz_2D_mesh_test
FILES_TO_COPY steel.dat
-)
+ PACKAGE contact
+ )
add_mesh(hertz_3D_mesh_test hertz_3D.geo 3 1)
register_test(test_hertz_3D
SOURCES hertz_3D.cc
FILES_TO_COPY steel.dat hertz_3D.msh
-)
+ PACKAGE contact
+ )
add_mesh(offset_1slave_mesh offset_1slave.geo 2 1)
register_test(test_offset_1slave
SOURCES offset_1slave.cc
- DEPENDENCIES offset_1slave_mesh
+ DEPENDS offset_1slave_mesh
FILES_TO_COPY steel.dat
-)
+ PACKAGE contact
+ )
add_mesh(offset_2slaves_mesh offset_2slaves.geo 2 1)
register_test(test_offset_2slaves
SOURCES offset_2slaves.cc
- DEPENDENCIES offset_2slaves_mesh
+ DEPENDS offset_2slaves_mesh
FILES_TO_COPY steel.dat
-)
+ PACKAGE contact
+ )
#===============================================================================
# Alain Curnier suggested tests
add_mesh(acurnier_2D_1_mesh acurnier_2D_1.geo 2 1)
register_test(test_acurnier_2D_1
SOURCES acurnier_2D_1.cc
- DEPENDENCIES acurnier_2D_1_mesh
+ DEPENDS acurnier_2D_1_mesh
FILES_TO_COPY material.dat
-)
+ PACKAGE contact
+ )
add_mesh(acurnier_2D_2_mesh acurnier_2D_2.geo 2 1)
register_test(test_acurnier_2D_2
SOURCES acurnier_2D_2.cc
- DEPENDENCIES acurnier_2D_2_mesh
+ DEPENDS acurnier_2D_2_mesh
FILES_TO_COPY material.dat
-)
+ PACKAGE contact
+ )
add_mesh(acurnier_2D_3_mesh acurnier_2D_3.geo 2 1)
register_test(test_acurnier_2D_3
SOURCES acurnier_2D_3.cc
- DEPENDENCIES acurnier_2D_3_mesh
+ DEPENDS acurnier_2D_3_mesh
FILES_TO_COPY material.dat
-)
+ PACKAGE contact
+ )
add_mesh(acurnier_3D_1_mesh acurnier_3D_1.geo 3 1)
register_test(test_acurnier_3D_1
SOURCES acurnier_3D_1.cc
- DEPENDENCIES acurnier_3D_1_mesh
+ DEPENDS acurnier_3D_1_mesh
FILES_TO_COPY material.dat
-)
+ PACKAGE contact
+ )
add_mesh(acurnier_3D_2_mesh acurnier_3D_2.geo 3 1)
register_test(test_acurnier_3D_2
SOURCES acurnier_3D_2.cc
- DEPENDENCIES acurnier_3D_2_mesh
+ DEPENDS acurnier_3D_2_mesh
FILES_TO_COPY material.dat
-)
+ PACKAGE contact
+ )
add_mesh(acurnier_3D_3_mesh acurnier_3D_3.geo 3 1)
register_test(test_acurnier_3D_3
SOURCES acurnier_3D_3.cc
- DEPENDENCIES acurnier_3D_3_mesh
+ DEPENDS acurnier_3D_3_mesh
FILES_TO_COPY material.dat
-)
-
+ PACKAGE contact
+ )
diff --git a/test/test_fe_engine/CMakeLists.txt b/test/test_fe_engine/CMakeLists.txt
new file mode 100644
index 000000000..220d485e9
--- /dev/null
+++ b/test/test_fe_engine/CMakeLists.txt
@@ -0,0 +1,92 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+#
+# @date creation: Fri Sep 03 2010
+# @date last modification: Fri May 30 2014
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+#===============================================================================
+function(register_fem_test operation type)
+ set(_target test_${operation}${type})
+
+ register_test(${_target}
+ SOURCES test_${operation}.cc
+ FILES_TO_COPY ${type}.msh
+ COMPILE_OPTIONS TYPE=${type}
+ PACKAGE core
+ )
+endfunction()
+
+#===============================================================================
+package_get_element_types(core _types)
+
+foreach(_type ${_types})
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_type}.msh)
+ register_fem_test(fe_engine_precomputation ${_type})
+ register_fem_test(interpolate ${_type})
+ register_fem_test(gradient ${_type})
+ register_fem_test(integrate ${_type})
+ register_fem_test(inverse_map ${_type})
+ else()
+ if(NOT ${_type} STREQUAL _point_1)
+ message("The mesh ${_type}.msh is missing, the fe_engine test cannot be activated without it")
+ endif()
+ endif()
+endforeach()
+
+
+#register_test(test_interpolate_bernoulli_beam_2 test_interpolate_bernoulli_beam_2.cc)
+#add_mesh(test_fem_circle_1_mesh circle.geo 2 1 OUTPUT circle1.msh)
+#add_mesh(test_fem_circle_2_mesh circle.geo 2 2 OUTPUT circle2.msh)
+
+# Tests for class MeshData
+macro(register_typed_test test_name type value1 value2)
+ set(target test_${test_name}_${type})
+ register_test(${target}
+ SOURCES test_${test_name}.cc
+ COMPILE_OPTIONS "TYPE=${type};VALUE1=${value1};VALUE2=${value2}"
+ PACKAGE core
+ )
+endmacro()
+
+register_typed_test(mesh_data string \"5\" \"10\")
+register_typed_test(mesh_data UInt 5 10)
+
+add_mesh(test_boundary_msh cube.geo 3 1)
+add_mesh(test_boundary_msh_physical_names cube_physical_names.geo 3 1)
+
+register_test(test_mesh_boundary
+ SOURCES test_mesh_boundary.cc
+ DEPENDS test_boundary_msh test_boundary_msh_physical_names
+ PACKAGE core)
+
+register_test(test_facet_element_mapping
+ SOURCES test_facet_element_mapping.cc
+ DEPENDS test_boundary_msh_physical_names
+ PACKAGE core)
+
diff --git a/test/test_fe_engine/_b_beam_2.msh b/test/test_fe_engine/_b_beam_2.msh
new file mode 100644
index 000000000..5b33d3f1b
--- /dev/null
+++ b/test/test_fe_engine/_b_beam_2.msh
@@ -0,0 +1,16 @@
+$MeshFormat
+2.1 0 8
+$EndMeshFormat
+$Nodes
+4
+1 2 1 0
+2 4 1 0
+3 6 1 0
+4 8 1 0
+$EndNodes
+$Elements
+3
+1 1 3 1 1 0 1 2
+2 1 3 1 1 0 2 3
+3 1 3 1 1 0 3 4
+$EndElements
diff --git a/test/test_fe_engine/_hexahedron_20.msh b/test/test_fe_engine/_hexahedron_20.msh
new file mode 100644
index 000000000..8b3304b52
--- /dev/null
+++ b/test/test_fe_engine/_hexahedron_20.msh
@@ -0,0 +1,154 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+81
+1 -0.5 -0.5 -0.5
+2 0.5 -0.5 -0.5
+3 -0.5 0.5 -0.5
+4 0.5 0.5 -0.5
+5 -0.5 -0.5 0.5
+6 0.5 -0.5 0.5
+7 0.5 0.5 0.5
+8 -0.5 0.5 0.5
+9 0 -0.5 -0.5
+10 -0.2499999999999021 -0.5 -0.5
+11 0.25 -0.5 -0.5
+12 0 0.5 -0.5
+13 -0.2499999999999021 0.5 -0.5
+14 0.25 0.5 -0.5
+15 -0.5 0 -0.5
+16 -0.5 -0.2499999999999021 -0.5
+17 -0.5 0.25 -0.5
+18 0.5 0 -0.5
+19 0.5 -0.2499999999999021 -0.5
+20 0.5 0.25 -0.5
+21 0 -0.5 0.5
+22 -0.2499999999999021 -0.5 0.5
+23 0.25 -0.5 0.5
+24 0.5 0 0.5
+25 0.5 -0.2499999999999021 0.5
+26 0.5 0.25 0.5
+27 0 0.5 0.5
+28 0.2499999999999021 0.5 0.5
+29 -0.25 0.5 0.5
+30 -0.5 0 0.5
+31 -0.5 0.2499999999999021 0.5
+32 -0.5 -0.25 0.5
+33 -0.5 -0.5 0
+34 -0.5 -0.5 -0.2499999999999021
+35 -0.5 -0.5 0.25
+36 0.5 -0.5 0
+37 0.5 -0.5 -0.2499999999999021
+38 0.5 -0.5 0.25
+39 0.5 0.5 0
+40 0.5 0.5 -0.2499999999999021
+41 0.5 0.5 0.25
+42 -0.5 0.5 0
+43 -0.5 0.5 -0.2499999999999021
+44 -0.5 0.5 0.25
+45 0 0 -0.5
+46 0 -0.25 -0.5
+47 -0.25 0 -0.5
+48 0 0.25 -0.5
+49 0.25 0 -0.5
+50 0 -0.5 0
+51 0 -0.5 -0.25
+52 -0.25 -0.5 0
+53 0 -0.5 0.25
+54 0.25 -0.5 0
+55 0.5 0 0
+56 0.5 0 -0.25
+57 0.5 -0.25 0
+58 0.5 0 0.25
+59 0.5 0.25 0
+60 0 0.5 0
+61 -0.25 0.5 0
+62 0 0.5 -0.25
+63 0 0.5 0.25
+64 0.25 0.5 0
+65 -0.5 0 0
+66 -0.5 -0.25 0
+67 -0.5 0 -0.25
+68 -0.5 0 0.25
+69 -0.5 0.25 0
+70 0 0 0.5
+71 0 -0.25 0.5
+72 -0.25 0 0.5
+73 0 0.25 0.5
+74 0.25 0 0.5
+75 0 0 0
+76 0 0 -0.25
+77 0 -0.25 0
+78 -0.25 0 0
+79 0 0 0.25
+80 0 0.25 0
+81 0.25 0 0
+$EndNodes
+$Elements
+64
+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 10 7
+8 15 2 0 14 8
+9 8 2 0 1 1 9 10
+10 8 2 0 1 9 2 11
+11 8 2 0 2 3 12 13
+12 8 2 0 2 12 4 14
+13 8 2 0 3 1 15 16
+14 8 2 0 3 15 3 17
+15 8 2 0 4 2 18 19
+16 8 2 0 4 18 4 20
+17 8 2 0 7 5 21 22
+18 8 2 0 7 21 6 23
+19 8 2 0 8 6 24 25
+20 8 2 0 8 24 7 26
+21 8 2 0 9 7 27 28
+22 8 2 0 9 27 8 29
+23 8 2 0 10 8 30 31
+24 8 2 0 10 30 5 32
+25 8 2 0 12 1 33 34
+26 8 2 0 12 33 5 35
+27 8 2 0 13 2 36 37
+28 8 2 0 13 36 6 38
+29 8 2 0 17 4 39 40
+30 8 2 0 17 39 7 41
+31 8 2 0 21 3 42 43
+32 8 2 0 21 42 8 44
+33 16 2 0 5 1 9 45 15 10 46 47 16
+34 16 2 0 5 15 45 12 3 47 48 13 17
+35 16 2 0 5 9 2 18 45 11 19 49 46
+36 16 2 0 5 45 18 4 12 49 20 14 48
+37 16 2 0 14 1 9 50 33 10 51 52 34
+38 16 2 0 14 33 50 21 5 52 53 22 35
+39 16 2 0 14 9 2 36 50 11 37 54 51
+40 16 2 0 14 50 36 6 21 54 38 23 53
+41 16 2 0 18 2 18 55 36 19 56 57 37
+42 16 2 0 18 36 55 24 6 57 58 25 38
+43 16 2 0 18 18 4 39 55 20 40 59 56
+44 16 2 0 18 55 39 7 24 59 41 26 58
+45 16 2 0 22 3 42 60 12 43 61 62 13
+46 16 2 0 22 42 8 27 60 44 29 63 61
+47 16 2 0 22 12 60 39 4 62 64 40 14
+48 16 2 0 22 60 27 7 39 63 28 41 64
+49 16 2 0 26 1 33 65 15 34 66 67 16
+50 16 2 0 26 33 5 30 65 35 32 68 66
+51 16 2 0 26 15 65 42 3 67 69 43 17
+52 16 2 0 26 65 30 8 42 68 31 44 69
+53 16 2 0 27 5 21 70 30 22 71 72 32
+54 16 2 0 27 30 70 27 8 72 73 29 31
+55 16 2 0 27 21 6 24 70 23 25 74 71
+56 16 2 0 27 70 24 7 27 74 26 28 73
+57 17 2 0 1 1 9 45 15 33 50 75 65 10 16 34 46 51 47 76 67 52 66 77 78
+58 17 2 0 1 33 50 75 65 5 21 70 30 52 66 35 77 53 78 79 68 22 32 71 72
+59 17 2 0 1 15 45 12 3 65 75 60 42 47 17 67 48 76 13 62 43 78 69 80 61
+60 17 2 0 1 65 75 60 42 30 70 27 8 78 69 68 80 79 61 63 44 72 31 73 29
+61 17 2 0 1 9 2 18 45 50 36 55 75 11 46 51 19 37 49 56 76 54 77 57 81
+62 17 2 0 1 50 36 55 75 21 6 24 70 54 77 53 57 38 81 58 79 23 71 25 74
+63 17 2 0 1 45 18 4 12 75 55 39 60 49 48 76 20 56 14 40 62 81 80 59 64
+64 17 2 0 1 75 55 39 60 70 24 7 27 81 80 79 59 58 64 41 63 74 73 26 28
+$EndElements
diff --git a/test/test_fem/_hexahedron_8.msh b/test/test_fe_engine/_hexahedron_8.msh
similarity index 100%
rename from test/test_fem/_hexahedron_8.msh
rename to test/test_fe_engine/_hexahedron_8.msh
diff --git a/test/test_fe_engine/_pentahedron_15.msh b/test/test_fe_engine/_pentahedron_15.msh
new file mode 100644
index 000000000..a75af84a5
--- /dev/null
+++ b/test/test_fe_engine/_pentahedron_15.msh
@@ -0,0 +1,74 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+57
+1 0 0 -1
+2 1 0 -1
+3 0 1 -1
+4 0 0 1
+5 1 0 1
+6 0 1 1
+7 0.5 0 -1
+8 0 0.5 -1
+9 0 0 0
+10 0.5 0.5 -1
+11 1 0 0
+12 0 1 0
+13 0.5 0 1
+14 0 0.5 1
+15 0.5 0.5 1
+16 0.5 0 0
+17 0 0.5 0
+18 0.5 0.5 0
+19 0.25 0 -1
+20 0 0.25 -1
+21 0 0 -0.5
+22 0.25 0.25 -1
+23 0.5 0 -0.5
+24 0 0.5 -0.5
+25 0.25 0 0
+26 0 0.25 0
+27 0.25 0.25 0
+28 0 0 0.5
+29 0.5 0 0.5
+30 0 0.5 0.5
+31 0.25 0 1
+32 0 0.25 1
+33 0.25 0.25 1
+34 0.75 0 -1
+35 0.5 0.25 -1
+36 0.75 0.25 -1
+37 1 0 -0.5
+38 0.5 0.5 -0.5
+39 0.75 0 0
+40 0.5 0.25 0
+41 0.75 0.25 0
+42 1 0 0.5
+43 0.5 0.5 0.5
+44 0.75 0 1
+45 0.5 0.25 1
+46 0.75 0.25 1
+47 0.25 0.5 -1
+48 0 0.75 -1
+49 0.25 0.75 -1
+50 0 1 -0.5
+51 0.25 0.5 0
+52 0 0.75 0
+53 0.25 0.75 0
+54 0 1 0.5
+55 0.25 0.5 1
+56 0 0.75 1
+57 0.25 0.75 1
+$EndNodes
+$Elements
+8
+1 18 2 1 1 1 7 8 9 16 17 19 20 21 22 23 24 25 26 27
+2 18 2 1 1 9 16 17 4 13 14 25 26 28 27 29 30 31 32 33
+3 18 2 1 1 7 2 10 16 11 18 34 35 23 36 37 38 39 40 41
+4 18 2 1 1 16 11 18 13 5 15 39 40 29 41 42 43 44 45 46
+5 18 2 1 1 8 10 3 17 18 12 47 48 24 49 38 50 51 52 53
+6 18 2 1 1 17 18 12 14 15 6 51 52 30 53 43 54 55 56 57
+7 18 2 1 1 10 8 7 18 17 16 47 35 38 22 24 23 51 40 27
+8 18 2 1 1 18 17 16 15 14 13 51 40 43 27 30 29 55 45 33
+$EndElements
diff --git a/test/test_fe_engine/_pentahedron_6.msh b/test/test_fe_engine/_pentahedron_6.msh
new file mode 100644
index 000000000..a8f6ef2cf
--- /dev/null
+++ b/test/test_fe_engine/_pentahedron_6.msh
@@ -0,0 +1,148 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+75
+1 0 0 -1
+2 1 0 -1
+3 0 1 -1
+4 0 0 1
+5 1 0 1
+6 0 1 1
+7 0.5 0 -1
+8 0 0.5 -1
+9 0 0 0
+10 0.5 0.5 -1
+11 1 0 0
+12 0 1 0
+13 0.5 0 1
+14 0 0.5 1
+15 0.5 0.5 1
+16 0.5 0 0
+17 0 0.5 0
+18 0.5 0.5 0
+19 0.25 0 -1
+20 0 0.25 -1
+21 0 0 -0.5
+22 0.25 0.25 -1
+23 0.5 0 -0.5
+24 0 0.5 -0.5
+25 0.25 0 0
+26 0 0.25 0
+27 0.25 0.25 0
+28 0.25 0 -0.5
+29 0 0.25 -0.5
+30 0.25 0.25 -0.5
+31 0 0 0.5
+32 0.5 0 0.5
+33 0 0.5 0.5
+34 0.25 0 1
+35 0 0.25 1
+36 0.25 0.25 1
+37 0.25 0 0.5
+38 0 0.25 0.5
+39 0.25 0.25 0.5
+40 0.75 0 -1
+41 0.5 0.25 -1
+42 0.75 0.25 -1
+43 1 0 -0.5
+44 0.5 0.5 -0.5
+45 0.75 0 0
+46 0.5 0.25 0
+47 0.75 0.25 0
+48 0.75 0 -0.5
+49 0.5 0.25 -0.5
+50 0.75 0.25 -0.5
+51 1 0 0.5
+52 0.5 0.5 0.5
+53 0.75 0 1
+54 0.5 0.25 1
+55 0.75 0.25 1
+56 0.75 0 0.5
+57 0.5 0.25 0.5
+58 0.75 0.25 0.5
+59 0.25 0.5 -1
+60 0 0.75 -1
+61 0.25 0.75 -1
+62 0 1 -0.5
+63 0.25 0.5 0
+64 0 0.75 0
+65 0.25 0.75 0
+66 0.25 0.5 -0.5
+67 0 0.75 -0.5
+68 0.25 0.75 -0.5
+69 0 1 0.5
+70 0.25 0.5 1
+71 0 0.75 1
+72 0.25 0.75 1
+73 0.25 0.5 0.5
+74 0 0.75 0.5
+75 0.25 0.75 0.5
+$EndNodes
+$Elements
+64
+1 6 2 1 1 1 19 20 21 28 29
+2 6 2 1 1 21 28 29 9 25 26
+3 6 2 1 1 19 7 22 28 23 30
+4 6 2 1 1 28 23 30 25 16 27
+5 6 2 1 1 20 22 8 29 30 24
+6 6 2 1 1 29 30 24 26 27 17
+7 6 2 1 1 22 20 19 30 29 28
+8 6 2 1 1 30 29 28 27 26 25
+9 6 2 1 1 9 25 26 31 37 38
+10 6 2 1 1 31 37 38 4 34 35
+11 6 2 1 1 25 16 27 37 32 39
+12 6 2 1 1 37 32 39 34 13 36
+13 6 2 1 1 26 27 17 38 39 33
+14 6 2 1 1 38 39 33 35 36 14
+15 6 2 1 1 27 26 25 39 38 37
+16 6 2 1 1 39 38 37 36 35 34
+17 6 2 1 1 7 40 41 23 48 49
+18 6 2 1 1 23 48 49 16 45 46
+19 6 2 1 1 40 2 42 48 43 50
+20 6 2 1 1 48 43 50 45 11 47
+21 6 2 1 1 41 42 10 49 50 44
+22 6 2 1 1 49 50 44 46 47 18
+23 6 2 1 1 42 41 40 50 49 48
+24 6 2 1 1 50 49 48 47 46 45
+25 6 2 1 1 16 45 46 32 56 57
+26 6 2 1 1 32 56 57 13 53 54
+27 6 2 1 1 45 11 47 56 51 58
+28 6 2 1 1 56 51 58 53 5 55
+29 6 2 1 1 46 47 18 57 58 52
+30 6 2 1 1 57 58 52 54 55 15
+31 6 2 1 1 47 46 45 58 57 56
+32 6 2 1 1 58 57 56 55 54 53
+33 6 2 1 1 8 59 60 24 66 67
+34 6 2 1 1 24 66 67 17 63 64
+35 6 2 1 1 59 10 61 66 44 68
+36 6 2 1 1 66 44 68 63 18 65
+37 6 2 1 1 60 61 3 67 68 62
+38 6 2 1 1 67 68 62 64 65 12
+39 6 2 1 1 61 60 59 68 67 66
+40 6 2 1 1 68 67 66 65 64 63
+41 6 2 1 1 17 63 64 33 73 74
+42 6 2 1 1 33 73 74 14 70 71
+43 6 2 1 1 63 18 65 73 52 75
+44 6 2 1 1 73 52 75 70 15 72
+45 6 2 1 1 64 65 12 74 75 69
+46 6 2 1 1 74 75 69 71 72 6
+47 6 2 1 1 65 64 63 75 74 73
+48 6 2 1 1 75 74 73 72 71 70
+49 6 2 1 1 10 59 41 44 66 49
+50 6 2 1 1 44 66 49 18 63 46
+51 6 2 1 1 59 8 22 66 24 30
+52 6 2 1 1 66 24 30 63 17 27
+53 6 2 1 1 41 22 7 49 30 23
+54 6 2 1 1 49 30 23 46 27 16
+55 6 2 1 1 22 41 59 30 49 66
+56 6 2 1 1 30 49 66 27 46 63
+57 6 2 1 1 18 63 46 52 73 57
+58 6 2 1 1 52 73 57 15 70 54
+59 6 2 1 1 63 17 27 73 33 39
+60 6 2 1 1 73 33 39 70 14 36
+61 6 2 1 1 46 27 16 57 39 32
+62 6 2 1 1 57 39 32 54 36 13
+63 6 2 1 1 27 46 63 39 57 73
+64 6 2 1 1 39 57 73 36 54 70
+$EndElements
diff --git a/test/test_fem/_quadrangle_4.msh b/test/test_fe_engine/_quadrangle_4.msh
similarity index 100%
rename from test/test_fem/_quadrangle_4.msh
rename to test/test_fe_engine/_quadrangle_4.msh
diff --git a/test/test_fem/_quadrangle_8.msh b/test/test_fe_engine/_quadrangle_8.msh
similarity index 100%
rename from test/test_fem/_quadrangle_8.msh
rename to test/test_fe_engine/_quadrangle_8.msh
diff --git a/test/test_fem/_segment_2.msh b/test/test_fe_engine/_segment_2.msh
similarity index 100%
rename from test/test_fem/_segment_2.msh
rename to test/test_fe_engine/_segment_2.msh
diff --git a/test/test_fem/_segment_3.msh b/test/test_fe_engine/_segment_3.msh
similarity index 100%
rename from test/test_fem/_segment_3.msh
rename to test/test_fe_engine/_segment_3.msh
diff --git a/test/test_fem/_tetrahedron_10.msh b/test/test_fe_engine/_tetrahedron_10.msh
similarity index 100%
rename from test/test_fem/_tetrahedron_10.msh
rename to test/test_fe_engine/_tetrahedron_10.msh
diff --git a/test/test_fem/_tetrahedron_4.msh b/test/test_fe_engine/_tetrahedron_4.msh
similarity index 100%
rename from test/test_fem/_tetrahedron_4.msh
rename to test/test_fe_engine/_tetrahedron_4.msh
diff --git a/test/test_fem/_triangle_3.msh b/test/test_fe_engine/_triangle_3.msh
similarity index 100%
rename from test/test_fem/_triangle_3.msh
rename to test/test_fe_engine/_triangle_3.msh
diff --git a/test/test_fem/_triangle_6.msh b/test/test_fe_engine/_triangle_6.msh
similarity index 100%
rename from test/test_fem/_triangle_6.msh
rename to test/test_fe_engine/_triangle_6.msh
diff --git a/test/test_fe_engine/circle.geo b/test/test_fe_engine/circle.geo
new file mode 100644
index 000000000..741251d60
--- /dev/null
+++ b/test/test_fe_engine/circle.geo
@@ -0,0 +1,16 @@
+h = 0.1;
+
+Point(1) = {1.0, 0.0, 0.0,h};
+Point(2) = {0.0, 1.0, 0.0,h};
+Point(3) = {-1.0, 0.0, 0.0,h};
+Point(4) = {0.0, -1.0, 0.0,h};
+Point(5) = {0.0, 0.0, 0.0,h};
+
+Circle(1) = {1, 5, 2};
+Circle(2) = {2, 5, 3};
+Circle(3) = {3, 5, 4};
+Circle(4) = {4, 5, 1};
+
+Line Loop(5) = {2, 3, 4, 1};
+
+Plane Surface(6) = {5};
diff --git a/test/test_fe_engine/cube.geo b/test/test_fe_engine/cube.geo
new file mode 100644
index 000000000..f6886ced7
--- /dev/null
+++ b/test/test_fe_engine/cube.geo
@@ -0,0 +1,14 @@
+
+Point(1) = {-0.5, -0.5, -0.5, 1.0};
+l[] = Extrude {1, 0, 0} {
+ Point{1}; Layers {2};
+};
+s[] = Extrude {0, 1, 0} {
+ Line{l[1]}; Layers {2}; Recombine;
+};
+Extrude {0, 0, 1} {
+ Surface{s[1]}; Layers{2}; Recombine;
+}
+
+
+Mesh.SecondOrderIncomplete = 1;
diff --git a/test/test_fem/cube_physical_names.geo b/test/test_fe_engine/cube_physical_names.geo
similarity index 100%
rename from test/test_fem/cube_physical_names.geo
rename to test/test_fe_engine/cube_physical_names.geo
diff --git a/test/test_fem/generate_test b/test/test_fe_engine/generate_test
similarity index 100%
rename from test/test_fem/generate_test
rename to test/test_fe_engine/generate_test
diff --git a/test/test_fe_engine/hexa_structured.geo b/test/test_fe_engine/hexa_structured.geo
new file mode 100644
index 000000000..0cc869dac
--- /dev/null
+++ b/test/test_fe_engine/hexa_structured.geo
@@ -0,0 +1,40 @@
+h = 0.25;
+
+Point(1) = {0.0, 0.0, 0.0, h};
+Point(2) = {1.0, 0.0, 0.0, h};
+Point(3) = {0.0, 1.0, 0.0, h};
+Point(4) = {1.0, 1.0, 0.0, h};
+Point(5) = {0.0, 0.0, 1.0, h};
+Point(6) = {1.0, 0.0, 1.0, h};
+Point(7) = {0.0, 1.0, 1.0, h};
+Point(8) = {1.0, 1.0, 1.0, h};
+
+Line(1) = {7, 8};
+Line(2) = {8, 4};
+Line(3) = {4, 3};
+Line(4) = {3, 7};
+Line(5) = {1, 5};
+Line(6) = {5, 6};
+Line(7) = {6, 2};
+Line(8) = {2, 1};
+Line(9) = {3, 1};
+Line(10) = {7, 5};
+Line(11) = {8, 6};
+Line(12) = {4, 2};
+Line Loop(13) = {1, 11, -6, -10};
+Plane Surface(14) = {13};
+Line Loop(15) = {3, 4, 1, 2};
+Plane Surface(16) = {15};
+Line Loop(17) = {6, 7, 8, 5};
+Plane Surface(18) = {17};
+Line Loop(19) = {3, 9, -8, -12};
+Plane Surface(20) = {19};
+Line Loop(21) = {4, 10, -5, -9};
+Plane Surface(22) = {21};
+Line Loop(23) = {11, 7, -12, -2};
+Plane Surface(24) = {23};
+Surface Loop(25) = {24, 14, 16, 20, 22, 18};
+Volume(26) = {25};
+Transfinite Surface "*";
+Recombine Surface "*";
+Transfinite Volume "*";
diff --git a/test/test_fe_engine/line.geo b/test/test_fe_engine/line.geo
new file mode 100644
index 000000000..eadb01c2c
--- /dev/null
+++ b/test/test_fe_engine/line.geo
@@ -0,0 +1,9 @@
+// Mesh size
+h = 0.1;
+
+Lx = 1;
+
+Point(1) = { 0.0, 0.0, 0.0, h};
+Point(2) = { Lx, 0.0, 0.0, h};
+
+Line(1) = {1,2};
diff --git a/test/test_fe_engine/square.geo b/test/test_fe_engine/square.geo
new file mode 100644
index 000000000..22f23a1e9
--- /dev/null
+++ b/test/test_fe_engine/square.geo
@@ -0,0 +1,31 @@
+// Mesh size
+h = 1; // 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};
+Transfinite Surface {101};
+Transfinite Line {103, 101} = 10 Using Progression 1;
+Transfinite Line {104, 102} = 10 Using Progression 1;
diff --git a/test/test_fe_engine/square_structured.geo b/test/test_fe_engine/square_structured.geo
new file mode 100644
index 000000000..abbcf174d
--- /dev/null
+++ b/test/test_fe_engine/square_structured.geo
@@ -0,0 +1,16 @@
+// Gmsh project created on Wed Dec 8 09:32:40 2010
+lc = 0.4;
+Point(1) = {0, 0, 0, lc};
+Point(2) = {1, 0, 0, lc};
+Point(3) = {1, 1, 0, lc};
+Point(4) = {0, 1, 0, lc};
+Line(1) = {1, 2};
+Line(2) = {2, 3};
+Line(3) = {3, 4};
+Line(4) = {4, 1};
+Line Loop(5) = {3, 4, 1, 2};
+Plane Surface(6) = {5};
+Transfinite Surface "*";
+Recombine Surface "*";
+
+Mesh.SecondOrderIncomplete = 1;
\ No newline at end of file
diff --git a/test/test_fem/test_facet_element_mapping.cc b/test/test_fe_engine/test_facet_element_mapping.cc
similarity index 100%
rename from test/test_fem/test_facet_element_mapping.cc
rename to test/test_fe_engine/test_facet_element_mapping.cc
diff --git a/test/test_fe_engine/test_fe_engine_precomputation.cc b/test/test_fe_engine/test_fe_engine_precomputation.cc
new file mode 100644
index 000000000..26728e7e2
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation.cc
@@ -0,0 +1,63 @@
+/**
+ * @file test_interpolate.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Jun 17 2011
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_hexahedron_20.verified b/test/test_fe_engine/test_fe_engine_precomputation_hexahedron_20.verified
new file mode 100644
index 000000000..a9e2bc66a
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_hexahedron_20.verified
@@ -0,0 +1,119 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 3
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 3
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_point_1) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_point_1
+ + size : 8
+ + nb_component : 1
+ + allocated size : 2000
+ + memory size : 7.81KiByte
+ + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
+ ]
+ ]
+ (not_ghost:_segment_3) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_segment_3
+ + size : 24
+ + nb_component : 3
+ + allocated size : 2000
+ + memory size : 23.44KiByte
+ + values : {{0, 8, 9}, {8, 1, 10}, {2, 11, 12}, {11, 3, 13}, {0, 14, 15}, {14, 2, 16}, {1, 17, 18}, {17, 3, 19}, {4, 20, 21}, {20, 5, 22}, {5, 23, 24}, {23, 6, 25}, {6, 26, 27}, {26, 7, 28}, {7, 29, 30}, {29, 4, 31}, {0, 32, 33}, {32, 4, 34}, {1, 35, 36}, {35, 5, 37}, {3, 38, 39}, {38, 6, 40}, {2, 41, 42}, {41, 7, 43}}
+ ]
+ ]
+ (not_ghost:_quadrangle_8) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_quadrangle_8
+ + size : 24
+ + nb_component : 8
+ + allocated size : 2000
+ + memory size : 62.50KiByte
+ + values : {{0, 8, 44, 14, 9, 45, 46, 15}, {14, 44, 11, 2, 46, 47, 12, 16}, {8, 1, 17, 44, 10, 18, 48, 45}, {44, 17, 3, 11, 48, 19, 13, 47}, {0, 8, 49, 32, 9, 50, 51, 33}, {32, 49, 20, 4, 51, 52, 21, 34}, {8, 1, 35, 49, 10, 36, 53, 50}, {49, 35, 5, 20, 53, 37, 22, 52}, {1, 17, 54, 35, 18, 55, 56, 36}, {35, 54, 23, 5, 56, 57, 24, 37}, {17, 3, 38, 54, 19, 39, 58, 55}, {54, 38, 6, 23, 58, 40, 25, 57}, {2, 41, 59, 11, 42, 60, 61, 12}, {41, 7, 26, 59, 43, 28, 62, 60}, {11, 59, 38, 3, 61, 63, 39, 13}, {59, 26, 6, 38, 62, 27, 40, 63}, {0, 32, 64, 14, 33, 65, 66, 15}, {32, 4, 29, 64, 34, 31, 67, 65}, {14, 64, 41, 2, 66, 68, 42, 16}, {64, 29, 7, 41, 67, 30, 43, 68}, {4, 20, 69, 29, 21, 70, 71, 31}, {29, 69, 26, 7, 71, 72, 28, 30}, {20, 5, 23, 69, 22, 24, 73, 70}, {69, 23, 6, 26, 73, 25, 27, 72}}
+ ]
+ ]
+ (not_ghost:_hexahedron_20) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_hexahedron_20
+ + size : 8
+ + nb_component : 20
+ + allocated size : 2000
+ + memory size : 156.25KiByte
+ + values : {{0, 8, 44, 14, 32, 49, 74, 64, 9, 45, 46, 15, 33, 50, 75, 66, 51, 76, 77, 65}, {32, 49, 74, 64, 4, 20, 69, 29, 51, 76, 77, 65, 34, 52, 78, 67, 21, 70, 71, 31}, {14, 44, 11, 2, 64, 74, 59, 41, 46, 47, 12, 16, 66, 75, 61, 42, 77, 79, 60, 68}, {64, 74, 59, 41, 29, 69, 26, 7, 77, 79, 60, 68, 67, 78, 62, 43, 71, 72, 28, 30}, {8, 1, 17, 44, 49, 35, 54, 74, 10, 18, 48, 45, 50, 36, 55, 75, 53, 56, 80, 76}, {49, 35, 54, 74, 20, 5, 23, 69, 53, 56, 80, 76, 52, 37, 57, 78, 22, 24, 73, 70}, {44, 17, 3, 11, 74, 54, 38, 59, 48, 19, 13, 47, 75, 55, 39, 61, 80, 58, 63, 79}, {74, 54, 38, 59, 69, 23, 6, 26, 80, 58, 63, 79, 78, 57, 40, 62, 73, 25, 27, 72}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_hexahedron_20)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_serendip_hexahedron_20) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_serendip_hexahedron_20
+ + size : 216
+ + nb_component : 20
+ + allocated size : 216
+ + memory size : 33.75KiByte
+ + values : {{0.22619, -0.10873, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.0061895, -0.0312702, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04}, {-0.17746, -0.17746, -0.1, -0.1, -0.1, -0.1, -0.0225403, -0.0225403, 0.787298, 0.17746, 0.1, 0.17746, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403}, {-0.10873, 0.22619, -0.10873, -0.0312702, -0.0312702, -0.10873, -0.0312702, -0.0061895, 0.314919, 0.314919, 0.04, 0.04, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067}, {-0.17746, -0.1, -0.1, -0.17746, -0.1, -0.0225403, -0.0225403, -0.1, 0.17746, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1}, {-0.271825, -0.271825, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.0781754, -0.0781754, 0.443649, 0.443649, 0.443649, 0.443649, 0.1, 0.1, 0.1, 0.1, 0.0563508, 0.0563508, 0.0563508, 0.0563508}, {-0.1, -0.17746, -0.17746, -0.1, -0.0225403, -0.1, -0.1, -0.0225403, 0.17746, 0.787298, 0.17746, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017}, {-0.10873, -0.0312702, -0.10873, 0.22619, -0.0312702, -0.0061895, -0.0312702, -0.10873, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.00508067, 0.00508067, 0.04, 0.04}, {-0.1, -0.1, -0.17746, -0.17746, -0.0225403, -0.0225403, -0.1, -0.1, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403}, {-0.0312702, -0.10873, 0.22619, -0.10873, -0.0061895, -0.0312702, -0.10873, -0.0312702, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067}, {-0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.787298, 0.1, 0.0127017, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746}, {-0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, 0.443649, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1}, {-0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.787298, 0.1, 0.0127017, 0.17746, 0.17746, 0.0225403, 0.0225403}, {-0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1, 0.443649}, {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25}, {-0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508}, {-0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.0127017, 0.1, 0.787298, 0.0225403, 0.0225403, 0.17746, 0.17746}, {-0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1}, {-0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0127017, 0.1, 0.787298, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403}, {-0.10873, -0.0312702, -0.0061895, -0.0312702, 0.22619, -0.10873, -0.0312702, -0.10873, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919}, {-0.1, -0.1, -0.0225403, -0.0225403, -0.17746, -0.17746, -0.1, -0.1, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.787298, 0.17746, 0.1, 0.17746}, {-0.0312702, -0.10873, -0.0312702, -0.0061895, -0.10873, 0.22619, -0.10873, -0.0312702, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.314919, 0.314919, 0.04, 0.04}, {-0.1, -0.0225403, -0.0225403, -0.1, -0.17746, -0.1, -0.1, -0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298}, {-0.0781754, -0.0781754, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.271825, -0.271825, 0.0563508, 0.0563508, 0.0563508, 0.0563508, 0.1, 0.1, 0.1, 0.1, 0.443649, 0.443649, 0.443649, 0.443649}, {-0.0225403, -0.1, -0.1, -0.0225403, -0.1, -0.17746, -0.17746, -0.1, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.17746, 0.787298, 0.17746, 0.1}, {-0.0312702, -0.0061895, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.10873, 0.22619, 0.00508067, 0.00508067, 0.04, 0.04, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919}, {-0.0225403, -0.0225403, -0.1, -0.1, -0.1, -0.1, -0.17746, -0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298, 0.17746}, {-0.0061895, -0.0312702, -0.10873, -0.0312702, -0.0312702, -0.10873, 0.22619, -0.10873, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04}, {0.22619, -0.10873, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.0061895, -0.0312702, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04}, {-0.17746, -0.17746, -0.1, -0.1, -0.1, -0.1, -0.0225403, -0.0225403, 0.787298, 0.17746, 0.1, 0.17746, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403}, {-0.10873, 0.22619, -0.10873, -0.0312702, -0.0312702, -0.10873, -0.0312702, -0.0061895, 0.314919, 0.314919, 0.04, 0.04, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067}, {-0.17746, -0.1, -0.1, -0.17746, -0.1, -0.0225403, -0.0225403, -0.1, 0.17746, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1}, {-0.271825, -0.271825, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.0781754, -0.0781754, 0.443649, 0.443649, 0.443649, 0.443649, 0.1, 0.1, 0.1, 0.1, 0.0563508, 0.0563508, 0.0563508, 0.0563508}, {-0.1, -0.17746, -0.17746, -0.1, -0.0225403, -0.1, -0.1, -0.0225403, 0.17746, 0.787298, 0.17746, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017}, {-0.10873, -0.0312702, -0.10873, 0.22619, -0.0312702, -0.0061895, -0.0312702, -0.10873, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.00508067, 0.00508067, 0.04, 0.04}, {-0.1, -0.1, -0.17746, -0.17746, -0.0225403, -0.0225403, -0.1, -0.1, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403}, {-0.0312702, -0.10873, 0.22619, -0.10873, -0.0061895, -0.0312702, -0.10873, -0.0312702, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067}, {-0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.787298, 0.1, 0.0127017, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746}, {-0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, 0.443649, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1}, {-0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.787298, 0.1, 0.0127017, 0.17746, 0.17746, 0.0225403, 0.0225403}, {-0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1, 0.443649}, {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25}, {-0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508}, {-0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.0127017, 0.1, 0.787298, 0.0225403, 0.0225403, 0.17746, 0.17746}, {-0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1}, {-0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0127017, 0.1, 0.787298, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403}, {-0.10873, -0.0312702, -0.0061895, -0.0312702, 0.22619, -0.10873, -0.0312702, -0.10873, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919}, {-0.1, -0.1, -0.0225403, -0.0225403, -0.17746, -0.17746, -0.1, -0.1, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.787298, 0.17746, 0.1, 0.17746}, {-0.0312702, -0.10873, -0.0312702, -0.0061895, -0.10873, 0.22619, -0.10873, -0.0312702, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.314919, 0.314919, 0.04, 0.04}, {-0.1, -0.0225403, -0.0225403, -0.1, -0.17746, -0.1, -0.1, -0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298}, {-0.0781754, -0.0781754, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.271825, -0.271825, 0.0563508, 0.0563508, 0.0563508, 0.0563508, 0.1, 0.1, 0.1, 0.1, 0.443649, 0.443649, 0.443649, 0.443649}, {-0.0225403, -0.1, -0.1, -0.0225403, -0.1, -0.17746, -0.17746, -0.1, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.17746, 0.787298, 0.17746, 0.1}, {-0.0312702, -0.0061895, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.10873, 0.22619, 0.00508067, 0.00508067, 0.04, 0.04, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919}, {-0.0225403, -0.0225403, -0.1, -0.1, -0.1, -0.1, -0.17746, -0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298, 0.17746}, {-0.0061895, -0.0312702, -0.10873, -0.0312702, -0.0312702, -0.10873, 0.22619, -0.10873, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04}, {0.22619, -0.10873, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.0061895, -0.0312702, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04}, {-0.17746, -0.17746, -0.1, -0.1, -0.1, -0.1, -0.0225403, -0.0225403, 0.787298, 0.17746, 0.1, 0.17746, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403}, {-0.10873, 0.22619, -0.10873, -0.0312702, -0.0312702, -0.10873, -0.0312702, -0.0061895, 0.314919, 0.314919, 0.04, 0.04, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067}, {-0.17746, -0.1, -0.1, -0.17746, -0.1, -0.0225403, -0.0225403, -0.1, 0.17746, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1}, {-0.271825, -0.271825, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.0781754, -0.0781754, 0.443649, 0.443649, 0.443649, 0.443649, 0.1, 0.1, 0.1, 0.1, 0.0563508, 0.0563508, 0.0563508, 0.0563508}, {-0.1, -0.17746, -0.17746, -0.1, -0.0225403, -0.1, -0.1, -0.0225403, 0.17746, 0.787298, 0.17746, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017}, {-0.10873, -0.0312702, -0.10873, 0.22619, -0.0312702, -0.0061895, -0.0312702, -0.10873, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.00508067, 0.00508067, 0.04, 0.04}, {-0.1, -0.1, -0.17746, -0.17746, -0.0225403, -0.0225403, -0.1, -0.1, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403}, {-0.0312702, -0.10873, 0.22619, -0.10873, -0.0061895, -0.0312702, -0.10873, -0.0312702, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067}, {-0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.787298, 0.1, 0.0127017, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746}, {-0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, 0.443649, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1}, {-0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.787298, 0.1, 0.0127017, 0.17746, 0.17746, 0.0225403, 0.0225403}, {-0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1, 0.443649}, {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25}, {-0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508}, {-0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.0127017, 0.1, 0.787298, 0.0225403, 0.0225403, 0.17746, 0.17746}, {-0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1}, {-0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0127017, 0.1, 0.787298, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403}, {-0.10873, -0.0312702, -0.0061895, -0.0312702, 0.22619, -0.10873, -0.0312702, -0.10873, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919}, {-0.1, -0.1, -0.0225403, -0.0225403, -0.17746, -0.17746, -0.1, -0.1, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.787298, 0.17746, 0.1, 0.17746}, {-0.0312702, -0.10873, -0.0312702, -0.0061895, -0.10873, 0.22619, -0.10873, -0.0312702, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.314919, 0.314919, 0.04, 0.04}, {-0.1, -0.0225403, -0.0225403, -0.1, -0.17746, -0.1, -0.1, -0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298}, {-0.0781754, -0.0781754, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.271825, -0.271825, 0.0563508, 0.0563508, 0.0563508, 0.0563508, 0.1, 0.1, 0.1, 0.1, 0.443649, 0.443649, 0.443649, 0.443649}, {-0.0225403, -0.1, -0.1, -0.0225403, -0.1, -0.17746, -0.17746, -0.1, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.17746, 0.787298, 0.17746, 0.1}, {-0.0312702, -0.0061895, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.10873, 0.22619, 0.00508067, 0.00508067, 0.04, 0.04, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919}, {-0.0225403, -0.0225403, -0.1, -0.1, -0.1, -0.1, -0.17746, -0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298, 0.17746}, {-0.0061895, -0.0312702, -0.10873, -0.0312702, -0.0312702, -0.10873, 0.22619, -0.10873, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04}, {0.22619, -0.10873, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.0061895, -0.0312702, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04}, {-0.17746, -0.17746, -0.1, -0.1, -0.1, -0.1, -0.0225403, -0.0225403, 0.787298, 0.17746, 0.1, 0.17746, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403}, {-0.10873, 0.22619, -0.10873, -0.0312702, -0.0312702, -0.10873, -0.0312702, -0.0061895, 0.314919, 0.314919, 0.04, 0.04, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067}, {-0.17746, -0.1, -0.1, -0.17746, -0.1, -0.0225403, -0.0225403, -0.1, 0.17746, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1}, {-0.271825, -0.271825, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.0781754, -0.0781754, 0.443649, 0.443649, 0.443649, 0.443649, 0.1, 0.1, 0.1, 0.1, 0.0563508, 0.0563508, 0.0563508, 0.0563508}, {-0.1, -0.17746, -0.17746, -0.1, -0.0225403, -0.1, -0.1, -0.0225403, 0.17746, 0.787298, 0.17746, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017}, {-0.10873, -0.0312702, -0.10873, 0.22619, -0.0312702, -0.0061895, -0.0312702, -0.10873, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.00508067, 0.00508067, 0.04, 0.04}, {-0.1, -0.1, -0.17746, -0.17746, -0.0225403, -0.0225403, -0.1, -0.1, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403}, {-0.0312702, -0.10873, 0.22619, -0.10873, -0.0061895, -0.0312702, -0.10873, -0.0312702, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067}, {-0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.787298, 0.1, 0.0127017, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746}, {-0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, 0.443649, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1}, {-0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.787298, 0.1, 0.0127017, 0.17746, 0.17746, 0.0225403, 0.0225403}, {-0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1, 0.443649}, {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25}, {-0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508}, {-0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.0127017, 0.1, 0.787298, 0.0225403, 0.0225403, 0.17746, 0.17746}, {-0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1}, {-0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0127017, 0.1, 0.787298, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403}, {-0.10873, -0.0312702, -0.0061895, -0.0312702, 0.22619, -0.10873, -0.0312702, -0.10873, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919}, {-0.1, -0.1, -0.0225403, -0.0225403, -0.17746, -0.17746, -0.1, -0.1, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.787298, 0.17746, 0.1, 0.17746}, {-0.0312702, -0.10873, -0.0312702, -0.0061895, -0.10873, 0.22619, -0.10873, -0.0312702, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.314919, 0.314919, 0.04, 0.04}, {-0.1, -0.0225403, -0.0225403, -0.1, -0.17746, -0.1, -0.1, -0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298}, {-0.0781754, -0.0781754, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.271825, -0.271825, 0.0563508, 0.0563508, 0.0563508, 0.0563508, 0.1, 0.1, 0.1, 0.1, 0.443649, 0.443649, 0.443649, 0.443649}, {-0.0225403, -0.1, -0.1, -0.0225403, -0.1, -0.17746, -0.17746, -0.1, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.17746, 0.787298, 0.17746, 0.1}, {-0.0312702, -0.0061895, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.10873, 0.22619, 0.00508067, 0.00508067, 0.04, 0.04, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919}, {-0.0225403, -0.0225403, -0.1, -0.1, -0.1, -0.1, -0.17746, -0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298, 0.17746}, {-0.0061895, -0.0312702, -0.10873, -0.0312702, -0.0312702, -0.10873, 0.22619, -0.10873, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04}, {0.22619, -0.10873, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.0061895, -0.0312702, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04}, {-0.17746, -0.17746, -0.1, -0.1, -0.1, -0.1, -0.0225403, -0.0225403, 0.787298, 0.17746, 0.1, 0.17746, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403}, {-0.10873, 0.22619, -0.10873, -0.0312702, -0.0312702, -0.10873, -0.0312702, -0.0061895, 0.314919, 0.314919, 0.04, 0.04, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067}, {-0.17746, -0.1, -0.1, -0.17746, -0.1, -0.0225403, -0.0225403, -0.1, 0.17746, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1}, {-0.271825, -0.271825, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.0781754, -0.0781754, 0.443649, 0.443649, 0.443649, 0.443649, 0.1, 0.1, 0.1, 0.1, 0.0563508, 0.0563508, 0.0563508, 0.0563508}, {-0.1, -0.17746, -0.17746, -0.1, -0.0225403, -0.1, -0.1, -0.0225403, 0.17746, 0.787298, 0.17746, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017}, {-0.10873, -0.0312702, -0.10873, 0.22619, -0.0312702, -0.0061895, -0.0312702, -0.10873, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.00508067, 0.00508067, 0.04, 0.04}, {-0.1, -0.1, -0.17746, -0.17746, -0.0225403, -0.0225403, -0.1, -0.1, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403}, {-0.0312702, -0.10873, 0.22619, -0.10873, -0.0061895, -0.0312702, -0.10873, -0.0312702, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067}, {-0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.787298, 0.1, 0.0127017, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746}, {-0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, 0.443649, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1}, {-0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.787298, 0.1, 0.0127017, 0.17746, 0.17746, 0.0225403, 0.0225403}, {-0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1, 0.443649}, {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25}, {-0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508}, {-0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.0127017, 0.1, 0.787298, 0.0225403, 0.0225403, 0.17746, 0.17746}, {-0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1}, {-0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0127017, 0.1, 0.787298, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403}, {-0.10873, -0.0312702, -0.0061895, -0.0312702, 0.22619, -0.10873, -0.0312702, -0.10873, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919}, {-0.1, -0.1, -0.0225403, -0.0225403, -0.17746, -0.17746, -0.1, -0.1, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.787298, 0.17746, 0.1, 0.17746}, {-0.0312702, -0.10873, -0.0312702, -0.0061895, -0.10873, 0.22619, -0.10873, -0.0312702, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.314919, 0.314919, 0.04, 0.04}, {-0.1, -0.0225403, -0.0225403, -0.1, -0.17746, -0.1, -0.1, -0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298}, {-0.0781754, -0.0781754, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.271825, -0.271825, 0.0563508, 0.0563508, 0.0563508, 0.0563508, 0.1, 0.1, 0.1, 0.1, 0.443649, 0.443649, 0.443649, 0.443649}, {-0.0225403, -0.1, -0.1, -0.0225403, -0.1, -0.17746, -0.17746, -0.1, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.17746, 0.787298, 0.17746, 0.1}, {-0.0312702, -0.0061895, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.10873, 0.22619, 0.00508067, 0.00508067, 0.04, 0.04, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919}, {-0.0225403, -0.0225403, -0.1, -0.1, -0.1, -0.1, -0.17746, -0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298, 0.17746}, {-0.0061895, -0.0312702, -0.10873, -0.0312702, -0.0312702, -0.10873, 0.22619, -0.10873, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04}, {0.22619, -0.10873, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.0061895, -0.0312702, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04}, {-0.17746, -0.17746, -0.1, -0.1, -0.1, -0.1, -0.0225403, -0.0225403, 0.787298, 0.17746, 0.1, 0.17746, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403}, {-0.10873, 0.22619, -0.10873, -0.0312702, -0.0312702, -0.10873, -0.0312702, -0.0061895, 0.314919, 0.314919, 0.04, 0.04, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067}, {-0.17746, -0.1, -0.1, -0.17746, -0.1, -0.0225403, -0.0225403, -0.1, 0.17746, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1}, {-0.271825, -0.271825, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.0781754, -0.0781754, 0.443649, 0.443649, 0.443649, 0.443649, 0.1, 0.1, 0.1, 0.1, 0.0563508, 0.0563508, 0.0563508, 0.0563508}, {-0.1, -0.17746, -0.17746, -0.1, -0.0225403, -0.1, -0.1, -0.0225403, 0.17746, 0.787298, 0.17746, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017}, {-0.10873, -0.0312702, -0.10873, 0.22619, -0.0312702, -0.0061895, -0.0312702, -0.10873, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.00508067, 0.00508067, 0.04, 0.04}, {-0.1, -0.1, -0.17746, -0.17746, -0.0225403, -0.0225403, -0.1, -0.1, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403}, {-0.0312702, -0.10873, 0.22619, -0.10873, -0.0061895, -0.0312702, -0.10873, -0.0312702, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067}, {-0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.787298, 0.1, 0.0127017, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746}, {-0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, 0.443649, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1}, {-0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.787298, 0.1, 0.0127017, 0.17746, 0.17746, 0.0225403, 0.0225403}, {-0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1, 0.443649}, {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25}, {-0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508}, {-0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.0127017, 0.1, 0.787298, 0.0225403, 0.0225403, 0.17746, 0.17746}, {-0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1}, {-0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0127017, 0.1, 0.787298, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403}, {-0.10873, -0.0312702, -0.0061895, -0.0312702, 0.22619, -0.10873, -0.0312702, -0.10873, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919}, {-0.1, -0.1, -0.0225403, -0.0225403, -0.17746, -0.17746, -0.1, -0.1, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.787298, 0.17746, 0.1, 0.17746}, {-0.0312702, -0.10873, -0.0312702, -0.0061895, -0.10873, 0.22619, -0.10873, -0.0312702, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.314919, 0.314919, 0.04, 0.04}, {-0.1, -0.0225403, -0.0225403, -0.1, -0.17746, -0.1, -0.1, -0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298}, {-0.0781754, -0.0781754, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.271825, -0.271825, 0.0563508, 0.0563508, 0.0563508, 0.0563508, 0.1, 0.1, 0.1, 0.1, 0.443649, 0.443649, 0.443649, 0.443649}, {-0.0225403, -0.1, -0.1, -0.0225403, -0.1, -0.17746, -0.17746, -0.1, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.17746, 0.787298, 0.17746, 0.1}, {-0.0312702, -0.0061895, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.10873, 0.22619, 0.00508067, 0.00508067, 0.04, 0.04, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919}, {-0.0225403, -0.0225403, -0.1, -0.1, -0.1, -0.1, -0.17746, -0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298, 0.17746}, {-0.0061895, -0.0312702, -0.10873, -0.0312702, -0.0312702, -0.10873, 0.22619, -0.10873, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04}, {0.22619, -0.10873, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.0061895, -0.0312702, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04}, {-0.17746, -0.17746, -0.1, -0.1, -0.1, -0.1, -0.0225403, -0.0225403, 0.787298, 0.17746, 0.1, 0.17746, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403}, {-0.10873, 0.22619, -0.10873, -0.0312702, -0.0312702, -0.10873, -0.0312702, -0.0061895, 0.314919, 0.314919, 0.04, 0.04, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067}, {-0.17746, -0.1, -0.1, -0.17746, -0.1, -0.0225403, -0.0225403, -0.1, 0.17746, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1}, {-0.271825, -0.271825, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.0781754, -0.0781754, 0.443649, 0.443649, 0.443649, 0.443649, 0.1, 0.1, 0.1, 0.1, 0.0563508, 0.0563508, 0.0563508, 0.0563508}, {-0.1, -0.17746, -0.17746, -0.1, -0.0225403, -0.1, -0.1, -0.0225403, 0.17746, 0.787298, 0.17746, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017}, {-0.10873, -0.0312702, -0.10873, 0.22619, -0.0312702, -0.0061895, -0.0312702, -0.10873, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.00508067, 0.00508067, 0.04, 0.04}, {-0.1, -0.1, -0.17746, -0.17746, -0.0225403, -0.0225403, -0.1, -0.1, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403}, {-0.0312702, -0.10873, 0.22619, -0.10873, -0.0061895, -0.0312702, -0.10873, -0.0312702, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067}, {-0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.787298, 0.1, 0.0127017, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746}, {-0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, 0.443649, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1}, {-0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.787298, 0.1, 0.0127017, 0.17746, 0.17746, 0.0225403, 0.0225403}, {-0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1, 0.443649}, {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25}, {-0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508}, {-0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.0127017, 0.1, 0.787298, 0.0225403, 0.0225403, 0.17746, 0.17746}, {-0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1}, {-0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0127017, 0.1, 0.787298, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403}, {-0.10873, -0.0312702, -0.0061895, -0.0312702, 0.22619, -0.10873, -0.0312702, -0.10873, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919}, {-0.1, -0.1, -0.0225403, -0.0225403, -0.17746, -0.17746, -0.1, -0.1, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.787298, 0.17746, 0.1, 0.17746}, {-0.0312702, -0.10873, -0.0312702, -0.0061895, -0.10873, 0.22619, -0.10873, -0.0312702, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.314919, 0.314919, 0.04, 0.04}, {-0.1, -0.0225403, -0.0225403, -0.1, -0.17746, -0.1, -0.1, -0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298}, {-0.0781754, -0.0781754, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.271825, -0.271825, 0.0563508, 0.0563508, 0.0563508, 0.0563508, 0.1, 0.1, 0.1, 0.1, 0.443649, 0.443649, 0.443649, 0.443649}, {-0.0225403, -0.1, -0.1, -0.0225403, -0.1, -0.17746, -0.17746, -0.1, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.17746, 0.787298, 0.17746, 0.1}, {-0.0312702, -0.0061895, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.10873, 0.22619, 0.00508067, 0.00508067, 0.04, 0.04, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919}, {-0.0225403, -0.0225403, -0.1, -0.1, -0.1, -0.1, -0.17746, -0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298, 0.17746}, {-0.0061895, -0.0312702, -0.10873, -0.0312702, -0.0312702, -0.10873, 0.22619, -0.10873, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04}, {0.22619, -0.10873, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.0061895, -0.0312702, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04}, {-0.17746, -0.17746, -0.1, -0.1, -0.1, -0.1, -0.0225403, -0.0225403, 0.787298, 0.17746, 0.1, 0.17746, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403}, {-0.10873, 0.22619, -0.10873, -0.0312702, -0.0312702, -0.10873, -0.0312702, -0.0061895, 0.314919, 0.314919, 0.04, 0.04, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067}, {-0.17746, -0.1, -0.1, -0.17746, -0.1, -0.0225403, -0.0225403, -0.1, 0.17746, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1}, {-0.271825, -0.271825, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.0781754, -0.0781754, 0.443649, 0.443649, 0.443649, 0.443649, 0.1, 0.1, 0.1, 0.1, 0.0563508, 0.0563508, 0.0563508, 0.0563508}, {-0.1, -0.17746, -0.17746, -0.1, -0.0225403, -0.1, -0.1, -0.0225403, 0.17746, 0.787298, 0.17746, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.0225403, 0.0127017}, {-0.10873, -0.0312702, -0.10873, 0.22619, -0.0312702, -0.0061895, -0.0312702, -0.10873, 0.04, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.00508067, 0.00508067, 0.04, 0.04}, {-0.1, -0.1, -0.17746, -0.17746, -0.0225403, -0.0225403, -0.1, -0.1, 0.1, 0.17746, 0.787298, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403}, {-0.0312702, -0.10873, 0.22619, -0.10873, -0.0061895, -0.0312702, -0.10873, -0.0312702, 0.04, 0.314919, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.04, 0.00508067}, {-0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.787298, 0.1, 0.0127017, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746}, {-0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, 0.443649, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1}, {-0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.1, 0.787298, 0.1, 0.0127017, 0.17746, 0.17746, 0.0225403, 0.0225403}, {-0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, 0.1, 0.0563508, 0.1, 0.443649, 0.443649, 0.0563508, 0.0563508, 0.443649, 0.1, 0.0563508, 0.1, 0.443649}, {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25}, {-0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508}, {-0.1, -0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.0127017, 0.1, 0.787298, 0.0225403, 0.0225403, 0.17746, 0.17746}, {-0.0781754, -0.0781754, -0.271825, -0.271825, -0.0781754, -0.0781754, -0.271825, -0.271825, 0.0563508, 0.1, 0.443649, 0.1, 0.0563508, 0.0563508, 0.443649, 0.443649, 0.0563508, 0.1, 0.443649, 0.1}, {-0.0225403, -0.1, -0.17746, -0.1, -0.0225403, -0.1, -0.17746, -0.1, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0127017, 0.1, 0.787298, 0.1, 0.0225403, 0.17746, 0.17746, 0.0225403}, {-0.10873, -0.0312702, -0.0061895, -0.0312702, 0.22619, -0.10873, -0.0312702, -0.10873, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919}, {-0.1, -0.1, -0.0225403, -0.0225403, -0.17746, -0.17746, -0.1, -0.1, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.0225403, 0.787298, 0.17746, 0.1, 0.17746}, {-0.0312702, -0.10873, -0.0312702, -0.0061895, -0.10873, 0.22619, -0.10873, -0.0312702, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.00508067, 0.314919, 0.314919, 0.04, 0.04}, {-0.1, -0.0225403, -0.0225403, -0.1, -0.17746, -0.1, -0.1, -0.17746, 0.0225403, 0.0127017, 0.0225403, 0.1, 0.17746, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298}, {-0.0781754, -0.0781754, -0.0781754, -0.0781754, -0.271825, -0.271825, -0.271825, -0.271825, 0.0563508, 0.0563508, 0.0563508, 0.0563508, 0.1, 0.1, 0.1, 0.1, 0.443649, 0.443649, 0.443649, 0.443649}, {-0.0225403, -0.1, -0.1, -0.0225403, -0.1, -0.17746, -0.17746, -0.1, 0.0225403, 0.1, 0.0225403, 0.0127017, 0.0225403, 0.17746, 0.17746, 0.0225403, 0.17746, 0.787298, 0.17746, 0.1}, {-0.0312702, -0.0061895, -0.0312702, -0.10873, -0.10873, -0.0312702, -0.10873, 0.22619, 0.00508067, 0.00508067, 0.04, 0.04, 0.04, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919}, {-0.0225403, -0.0225403, -0.1, -0.1, -0.1, -0.1, -0.17746, -0.17746, 0.0127017, 0.0225403, 0.1, 0.0225403, 0.0225403, 0.0225403, 0.17746, 0.17746, 0.1, 0.17746, 0.787298, 0.17746}, {-0.0061895, -0.0312702, -0.10873, -0.0312702, -0.0312702, -0.10873, 0.22619, -0.10873, 0.00508067, 0.04, 0.04, 0.00508067, 0.00508067, 0.04, 0.314919, 0.04, 0.04, 0.314919, 0.314919, 0.04}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_serendip_hexahedron_20) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_serendip_hexahedron_20
+ + size : 216
+ + nb_component : 60
+ + allocated size : 216
+ + memory size : 101.25KiByte
+ + values : {{-3.30411, -3.30411, -3.30411, -1.5746, -0.109839, -0.109839, -0.509839, -0.509839, 0.0254033, -0.109839, -1.5746, -0.109839, -0.109839, -0.109839, -1.5746, -0.509839, 0.0254033, -0.509839, -0.104113, -0.104113, -0.104113, 0.0254033, -0.509839, -0.509839, 4.87871, -0.709839, -0.709839, 0.709839, 0.619677, -0.0901613, 0.619677, 0.709839, -0.0901613, -0.709839, 4.87871, -0.709839, -0.709839, -0.709839, 4.87871, 0.709839, -0.0901613, 0.619677, 0.0901613, 0.0901613, 0.0787093, -0.0901613, 0.709839, 0.619677, 0.619677, -0.0901613, 0.709839, 0.0901613, 0.0787093, 0.0901613, 0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.619677, 0.709839}, {-0.864758, -1.1746, -1.1746, 0.864758, -1.1746, -1.1746, -0.2, -1.5746, 0.0254033, 0.2, -1.5746, 0.0254033, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.5746, -0.064758, -0.374597, -0.374597, 0.064758, -0.374597, -0.374597, -2.46669e-13, -1.7746, -1.7746, 0.709839, 2.74919, -0.4, 1.07669e-13, 1.7746, -0.225403, -0.709839, 2.74919, -0.4, -0.709839, -0.4, 2.74919, 0.709839, -0.4, 2.74919, 0.0901613, 0.4, 0.349193, -0.0901613, 0.4, 0.349193, 1.07669e-13, -0.225403, 1.7746, 0.0901613, 0.349193, 0.4, 3.1331e-14, 0.225403, 0.225403, -0.0901613, 0.349193, 0.4}, {1.5746, -0.109839, -0.109839, 3.30411, -3.30411, -3.30411, 0.109839, -1.5746, -0.109839, 0.509839, -0.509839, 0.0254033, 0.509839, 0.0254033, -0.509839, 0.109839, -0.109839, -1.5746, -0.0254033, -0.509839, -0.509839, 0.104113, -0.104113, -0.104113, -4.87871, -0.709839, -0.709839, 0.709839, 4.87871, -0.709839, -0.619677, 0.709839, -0.0901613, -0.709839, 0.619677, -0.0901613, -0.709839, -0.0901613, 0.619677, 0.709839, -0.709839, 4.87871, 0.0901613, 0.709839, 0.619677, -0.0901613, 0.0901613, 0.0787093, -0.619677, -0.0901613, 0.709839, 0.0901613, 0.619677, 0.709839, -0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.0787093, 0.0901613}, {-1.1746, -0.864758, -1.1746, -1.5746, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.1746, 0.864758, -1.1746, 0.0254033, 0.2, -1.5746, -0.374597, 0.064758, -0.374597, -0.374597, -0.064758, -0.374597, 0.0254033, -0.2, -1.5746, 2.74919, -0.709839, -0.4, 1.7746, 1.07669e-13, -0.225403, 2.74919, 0.709839, -0.4, -1.7746, -2.46669e-13, -1.7746, -0.4, -0.709839, 2.74919, 0.4, -0.0901613, 0.349193, 0.4, 0.0901613, 0.349193, -0.4, 0.709839, 2.74919, 0.349193, -0.0901613, 0.4, 0.225403, 3.1331e-14, 0.225403, 0.349193, 0.0901613, 0.4, -0.225403, 1.07669e-13, 1.7746}, {0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, 0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -3.47499e-13, -1.7746, -1, 1.7746, 2.69173e-13, -1, 2.69173e-13, 1.7746, -1, -1.7746, -3.47499e-13, -1, -0.4, -0.4, 1.54919, 0.4, -0.4, 1.54919, 0.4, 0.4, 1.54919, -0.4, 0.4, 1.54919, -6.89741e-19, -0.225403, 1, 0.225403, 7.83269e-14, 1, 7.83269e-14, 0.225403, 1, -0.225403, -6.89741e-19, 1}, {1.5746, 0.2, 0.0254033, 1.1746, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.5746, -0.2, 0.0254033, 0.374597, 0.064758, -0.374597, -0.0254033, 0.2, -1.5746, -0.0254033, -0.2, -1.5746, 0.374597, -0.064758, -0.374597, -2.74919, -0.709839, -0.4, 1.7746, 1.07671e-13, -1.7746, -2.74919, 0.709839, -0.4, -1.7746, -1.25324e-13, -0.225403, -0.4, -0.0901613, 0.349193, 0.4, -0.709839, 2.74919, 0.4, 0.709839, 2.74919, -0.4, 0.0901613, 0.349193, -0.349193, -0.0901613, 0.4, 0.225403, 3.13286e-14, 1.7746, -0.349193, 0.0901613, 0.4, -0.225403, -1.36761e-14, 0.225403}, {-0.109839, 1.5746, -0.109839, -0.509839, 0.509839, 0.0254033, -1.5746, 0.109839, -0.109839, -3.30411, 3.30411, -3.30411, 0.0254033, 0.509839, -0.509839, -0.104113, 0.104113, -0.104113, -0.509839, -0.0254033, -0.509839, -0.109839, 0.109839, -1.5746, 0.619677, -0.709839, -0.0901613, 0.709839, -0.619677, -0.0901613, 4.87871, 0.709839, -0.709839, -0.709839, -4.87871, -0.709839, -0.0901613, -0.709839, 0.619677, 0.0901613, -0.0901613, 0.0787093, 0.709839, 0.0901613, 0.619677, -0.709839, 0.709839, 4.87871, 0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.0787093, 0.0901613, 0.619677, 0.0901613, 0.709839, -0.0901613, -0.619677, 0.709839}, {0.2, 1.5746, 0.0254033, -0.2, 1.5746, 0.0254033, 0.864758, 1.1746, -1.1746, -0.864758, 1.1746, -1.1746, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, -0.374597, -0.2, -0.0254033, -1.5746, 0.2, -0.0254033, -1.5746, -1.25324e-13, -1.7746, -0.225403, 0.709839, -2.74919, -0.4, 1.07671e-13, 1.7746, -1.7746, -0.709839, -2.74919, -0.4, -0.0901613, -0.4, 0.349193, 0.0901613, -0.4, 0.349193, 0.709839, 0.4, 2.74919, -0.709839, 0.4, 2.74919, -1.36761e-14, -0.225403, 0.225403, 0.0901613, -0.349193, 0.4, 3.13286e-14, 0.225403, 1.7746, -0.0901613, -0.349193, 0.4}, {0.509839, 0.509839, 0.0254033, 0.109839, 1.5746, -0.109839, 3.30411, 3.30411, -3.30411, 1.5746, 0.109839, -0.109839, 0.104113, 0.104113, -0.104113, -0.0254033, 0.509839, -0.509839, 0.109839, 0.109839, -1.5746, 0.509839, -0.0254033, -0.509839, -0.619677, -0.709839, -0.0901613, 0.709839, -4.87871, -0.709839, -4.87871, 0.709839, -0.709839, -0.709839, -0.619677, -0.0901613, -0.0901613, -0.0901613, 0.0787093, 0.0901613, -0.709839, 0.619677, 0.709839, 0.709839, 4.87871, -0.709839, 0.0901613, 0.619677, -0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.619677, 0.709839, -0.619677, 0.0901613, 0.709839, -0.0901613, -0.0787093, 0.0901613}, {-1.1746, -1.1746, -0.864758, -1.5746, 0.0254033, 0.2, -0.374597, -0.374597, 0.064758, 0.0254033, -1.5746, 0.2, -1.1746, -1.1746, 0.864758, -1.5746, 0.0254033, -0.2, -0.374597, -0.374597, -0.064758, 0.0254033, -1.5746, -0.2, 2.74919, -0.4, -0.709839, 0.4, 0.349193, -0.0901613, 0.349193, 0.4, -0.0901613, -0.4, 2.74919, -0.709839, -1.7746, -1.7746, -2.46669e-13, 1.7746, -0.225403, 1.07558e-13, 0.225403, 0.225403, 3.1331e-14, -0.225403, 1.7746, 1.0778e-13, 2.74919, -0.4, 0.709839, 0.4, 0.349193, 0.0901613, 0.349193, 0.4, 0.0901613, -0.4, 2.74919, 0.709839}, {0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, 0.2, -1.2746, 0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, -0.2, -0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -3.47527e-13, -1, -1.7746, 0.4, 1.54919, -0.4, 2.70658e-17, 1, -0.225403, -0.4, 1.54919, -0.4, -1.7746, -1, -3.47416e-13, 1.7746, -1, 2.69256e-13, 0.225403, 1, 7.82437e-14, -0.225403, 1, -8.39565e-17, 2.69145e-13, -1, 1.7746, 0.4, 1.54919, 0.4, 7.83547e-14, 1, 0.225403, -0.4, 1.54919, 0.4}, {1.5746, 0.0254033, 0.2, 1.1746, -1.1746, -0.864758, -0.0254033, -1.5746, 0.2, 0.374597, -0.374597, 0.064758, 1.5746, 0.0254033, -0.2, 1.1746, -1.1746, 0.864758, -0.0254033, -1.5746, -0.2, 0.374597, -0.374597, -0.064758, -2.74919, -0.4, -0.709839, 0.4, 2.74919, -0.709839, -0.349193, 0.4, -0.0901613, -0.4, 0.349193, -0.0901613, -1.7746, -0.225403, -1.25324e-13, 1.7746, -1.7746, 1.07671e-13, 0.225403, 1.7746, 3.13286e-14, -0.225403, 0.225403, -1.36761e-14, -2.74919, -0.4, 0.709839, 0.4, 2.74919, 0.709839, -0.349193, 0.4, 0.0901613, -0.4, 0.349193, 0.0901613}, {-0.274597, 0.2, 0.2, -1.2746, 0.2, 0.2, -1.2746, -0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -0.2, -0.2, -0.274597, -0.2, -0.2, 1.54919, -0.4, -0.4, 1, 2.70658e-17, -0.225403, 1.54919, 0.4, -0.4, -1, -3.47527e-13, -1.7746, -1, -1.7746, -3.47416e-13, 1, -0.225403, -8.39565e-17, 1, 0.225403, 7.82437e-14, -1, 1.7746, 2.69256e-13, 1.54919, -0.4, 0.4, 1, 7.83547e-14, 0.225403, 1.54919, 0.4, 0.4, -1, 2.69145e-13, 1.7746}, {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, -1.95843e-13, -1, -1, 1, 0, -1, 0, 1, -1, -1, -1.95843e-13, -1, -1, -1, -1.95843e-13, 1, -1, 0, 1, 1, 1.95843e-13, -1, 1, 0, 0, -1, 1, 1, 1.95843e-13, 1, 1.95843e-13, 1, 1, -1, 0, 1}, {1.2746, 0.2, 0.2, 0.274597, 0.2, 0.2, 0.274597, -0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -0.2, -0.2, 1.2746, -0.2, -0.2, -1.54919, -0.4, -0.4, 1, -4.38246e-17, -1.7746, -1.54919, 0.4, -0.4, -1, -4.41431e-14, -0.225403, -1, -0.225403, -4.41708e-14, 1, -1.7746, -1.60691e-17, 1, 1.7746, 7.83978e-14, -1, 0.225403, -3.42109e-14, -1.54919, -0.4, 0.4, 1, 7.83701e-14, 1.7746, -1.54919, 0.4, 0.4, -1, -3.41832e-14, 0.225403}, {0.0254033, 1.5746, 0.2, -0.374597, 0.374597, 0.064758, -1.5746, -0.0254033, 0.2, -1.1746, 1.1746, -0.864758, 0.0254033, 1.5746, -0.2, -0.374597, 0.374597, -0.064758, -1.5746, -0.0254033, -0.2, -1.1746, 1.1746, 0.864758, 0.349193, -0.4, -0.0901613, 0.4, -0.349193, -0.0901613, 2.74919, 0.4, -0.709839, -0.4, -2.74919, -0.709839, -0.225403, -1.7746, -1.25324e-13, 0.225403, -0.225403, -1.36761e-14, 1.7746, 0.225403, 3.13286e-14, -1.7746, 1.7746, 1.07671e-13, 0.349193, -0.4, 0.0901613, 0.4, -0.349193, 0.0901613, 2.74919, 0.4, 0.709839, -0.4, -2.74919, 0.709839}, {0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, 0.2, 0.274597, 0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, -0.2, -0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -4.41431e-14, -1, -0.225403, 0.4, -1.54919, -0.4, -4.38246e-17, 1, -1.7746, -0.4, -1.54919, -0.4, -0.225403, -1, -4.41708e-14, 0.225403, -1, -3.42109e-14, 1.7746, 1, 7.83978e-14, -1.7746, 1, -1.60691e-17, -3.41832e-14, -1, 0.225403, 0.4, -1.54919, 0.4, 7.83701e-14, 1, 1.7746, -0.4, -1.54919, 0.4}, {0.374597, 0.374597, 0.064758, -0.0254033, 1.5746, 0.2, 1.1746, 1.1746, -0.864758, 1.5746, -0.0254033, 0.2, 0.374597, 0.374597, -0.064758, -0.0254033, 1.5746, -0.2, 1.1746, 1.1746, 0.864758, 1.5746, -0.0254033, -0.2, -0.349193, -0.4, -0.0901613, 0.4, -2.74919, -0.709839, -2.74919, 0.4, -0.709839, -0.4, -0.349193, -0.0901613, -0.225403, -0.225403, -3.97269e-15, 0.225403, -1.7746, -1.36243e-14, 1.7746, 1.7746, 3.12769e-14, -1.7746, 0.225403, -1.36799e-14, -0.349193, -0.4, 0.0901613, 0.4, -2.74919, 0.709839, -2.74919, 0.4, 0.709839, -0.4, -0.349193, 0.0901613}, {-0.109839, -0.109839, 1.5746, -0.509839, 0.0254033, 0.509839, -0.104113, -0.104113, 0.104113, 0.0254033, -0.509839, 0.509839, -3.30411, -3.30411, 3.30411, -1.5746, -0.109839, 0.109839, -0.509839, -0.509839, -0.0254033, -0.109839, -1.5746, 0.109839, 0.619677, -0.0901613, -0.709839, 0.0901613, 0.0787093, -0.0901613, 0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.619677, -0.709839, -0.709839, -0.709839, -4.87871, 0.709839, -0.0901613, -0.619677, 0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.709839, -0.619677, 4.87871, -0.709839, 0.709839, 0.709839, 0.619677, 0.0901613, 0.619677, 0.709839, 0.0901613, -0.709839, 4.87871, 0.709839}, {0.2, 0.0254033, 1.5746, -0.2, 0.0254033, 1.5746, -0.064758, -0.374597, 0.374597, 0.064758, -0.374597, 0.374597, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.1746, -0.2, -1.5746, -0.0254033, 0.2, -1.5746, -0.0254033, -1.25324e-13, -0.225403, -1.7746, 0.0901613, 0.349193, -0.4, -1.36761e-14, 0.225403, -0.225403, -0.0901613, 0.349193, -0.4, -0.709839, -0.4, -2.74919, 0.709839, -0.4, -2.74919, 0.0901613, 0.4, -0.349193, -0.0901613, 0.4, -0.349193, 1.07671e-13, -1.7746, 1.7746, 0.709839, 2.74919, 0.4, 3.13286e-14, 1.7746, 0.225403, -0.709839, 2.74919, 0.4}, {0.509839, 0.0254033, 0.509839, 0.109839, -0.109839, 1.5746, -0.0254033, -0.509839, 0.509839, 0.104113, -0.104113, 0.104113, 1.5746, -0.109839, 0.109839, 3.30411, -3.30411, 3.30411, 0.109839, -1.5746, 0.109839, 0.509839, -0.509839, -0.0254033, -0.619677, -0.0901613, -0.709839, 0.0901613, 0.619677, -0.709839, -0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.0787093, -0.0901613, -0.709839, -0.0901613, -0.619677, 0.709839, -0.709839, -4.87871, 0.0901613, 0.709839, -0.619677, -0.0901613, 0.0901613, -0.0787093, -4.87871, -0.709839, 0.709839, 0.709839, 4.87871, 0.709839, -0.619677, 0.709839, 0.0901613, -0.709839, 0.619677, 0.0901613}, {0.0254033, 0.2, 1.5746, -0.374597, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, 0.0254033, -0.2, 1.5746, -1.1746, -0.864758, 1.1746, -1.5746, 0.2, -0.0254033, -1.5746, -0.2, -0.0254033, -1.1746, 0.864758, 1.1746, 0.349193, -0.0901613, -0.4, 0.225403, -1.36698e-14, -0.225403, 0.349193, 0.0901613, -0.4, -0.225403, -1.25275e-13, -1.7746, -0.4, -0.709839, -2.74919, 0.4, -0.0901613, -0.349193, 0.4, 0.0901613, -0.349193, -0.4, 0.709839, -2.74919, 2.74919, -0.709839, 0.4, 1.7746, 3.13223e-14, 0.225403, 2.74919, 0.709839, 0.4, -1.7746, 1.07622e-13, 1.7746}, {0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, 0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -4.41431e-14, -0.225403, -1, 0.225403, -3.41832e-14, -1, -3.41832e-14, 0.225403, -1, -0.225403, -4.41431e-14, -1, -0.4, -0.4, -1.54919, 0.4, -0.4, -1.54919, 0.4, 0.4, -1.54919, -0.4, 0.4, -1.54919, -4.38246e-17, -1.7746, 1, 1.7746, 7.83701e-14, 1, 7.83701e-14, 1.7746, 1, -1.7746, -4.38246e-17, 1}, {0.374597, 0.064758, 0.374597, -0.0254033, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, 0.374597, -0.064758, 0.374597, 1.5746, 0.2, -0.0254033, 1.1746, -0.864758, 1.1746, 1.1746, 0.864758, 1.1746, 1.5746, -0.2, -0.0254033, -0.349193, -0.0901613, -0.4, 0.225403, -1.36736e-14, -1.7746, -0.349193, 0.0901613, -0.4, -0.225403, -3.97894e-15, -0.225403, -0.4, -0.0901613, -0.349193, 0.4, -0.709839, -2.74919, 0.4, 0.709839, -2.74919, -0.4, 0.0901613, -0.349193, -2.74919, -0.709839, 0.4, 1.7746, 3.13261e-14, 1.7746, -2.74919, 0.709839, 0.4, -1.7746, -1.36736e-14, 0.225403}, {0.0254033, 0.509839, 0.509839, -0.104113, 0.104113, 0.104113, -0.509839, -0.0254033, 0.509839, -0.109839, 0.109839, 1.5746, -0.109839, 1.5746, 0.109839, -0.509839, 0.509839, -0.0254033, -1.5746, 0.109839, 0.109839, -3.30411, 3.30411, 3.30411, 0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.619677, 0.0901613, -0.709839, -0.0901613, -0.619677, -0.709839, -0.0901613, -0.709839, -0.619677, 0.0901613, -0.0901613, -0.0787093, 0.709839, 0.0901613, -0.619677, -0.709839, 0.709839, -4.87871, 0.619677, -0.709839, 0.0901613, 0.709839, -0.619677, 0.0901613, 4.87871, 0.709839, 0.709839, -0.709839, -4.87871, 0.709839}, {0.064758, 0.374597, 0.374597, -0.064758, 0.374597, 0.374597, -0.2, -0.0254033, 1.5746, 0.2, -0.0254033, 1.5746, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, -0.0254033, 0.864758, 1.1746, 1.1746, -0.864758, 1.1746, 1.1746, -3.97894e-15, -0.225403, -0.225403, 0.0901613, -0.349193, -0.4, -1.36736e-14, 0.225403, -1.7746, -0.0901613, -0.349193, -0.4, -0.0901613, -0.4, -0.349193, 0.0901613, -0.4, -0.349193, 0.709839, 0.4, -2.74919, -0.709839, 0.4, -2.74919, -1.36736e-14, -1.7746, 0.225403, 0.709839, -2.74919, 0.4, 3.13261e-14, 1.7746, 1.7746, -0.709839, -2.74919, 0.4}, {0.104113, 0.104113, 0.104113, -0.0254033, 0.509839, 0.509839, 0.109839, 0.109839, 1.5746, 0.509839, -0.0254033, 0.509839, 0.509839, 0.509839, -0.0254033, 0.109839, 1.5746, 0.109839, 3.30411, 3.30411, 3.30411, 1.5746, 0.109839, 0.109839, -0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.619677, -0.709839, -0.619677, 0.0901613, -0.709839, -0.0901613, -0.0787093, -0.0901613, -0.0901613, -0.0901613, -0.0787093, 0.0901613, -0.709839, -0.619677, 0.709839, 0.709839, -4.87871, -0.709839, 0.0901613, -0.619677, -0.619677, -0.709839, 0.0901613, 0.709839, -4.87871, 0.709839, -4.87871, 0.709839, 0.709839, -0.709839, -0.619677, 0.0901613}, {-3.30411, -3.30411, -3.30411, -1.5746, -0.109839, -0.109839, -0.509839, -0.509839, 0.0254033, -0.109839, -1.5746, -0.109839, -0.109839, -0.109839, -1.5746, -0.509839, 0.0254033, -0.509839, -0.104113, -0.104113, -0.104113, 0.0254033, -0.509839, -0.509839, 4.87871, -0.709839, -0.709839, 0.709839, 0.619677, -0.0901613, 0.619677, 0.709839, -0.0901613, -0.709839, 4.87871, -0.709839, -0.709839, -0.709839, 4.87871, 0.709839, -0.0901613, 0.619677, 0.0901613, 0.0901613, 0.0787093, -0.0901613, 0.709839, 0.619677, 0.619677, -0.0901613, 0.709839, 0.0901613, 0.0787093, 0.0901613, 0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.619677, 0.709839}, {-0.864758, -1.1746, -1.1746, 0.864758, -1.1746, -1.1746, -0.2, -1.5746, 0.0254033, 0.2, -1.5746, 0.0254033, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.5746, -0.064758, -0.374597, -0.374597, 0.064758, -0.374597, -0.374597, 0, -1.7746, -1.7746, 0.709839, 2.74919, -0.4, 0, 1.7746, -0.225403, -0.709839, 2.74919, -0.4, -0.709839, -0.4, 2.74919, 0.709839, -0.4, 2.74919, 0.0901613, 0.4, 0.349193, -0.0901613, 0.4, 0.349193, 0, -0.225403, 1.7746, 0.0901613, 0.349193, 0.4, 0, 0.225403, 0.225403, -0.0901613, 0.349193, 0.4}, {1.5746, -0.109839, -0.109839, 3.30411, -3.30411, -3.30411, 0.109839, -1.5746, -0.109839, 0.509839, -0.509839, 0.0254033, 0.509839, 0.0254033, -0.509839, 0.109839, -0.109839, -1.5746, -0.0254033, -0.509839, -0.509839, 0.104113, -0.104113, -0.104113, -4.87871, -0.709839, -0.709839, 0.709839, 4.87871, -0.709839, -0.619677, 0.709839, -0.0901613, -0.709839, 0.619677, -0.0901613, -0.709839, -0.0901613, 0.619677, 0.709839, -0.709839, 4.87871, 0.0901613, 0.709839, 0.619677, -0.0901613, 0.0901613, 0.0787093, -0.619677, -0.0901613, 0.709839, 0.0901613, 0.619677, 0.709839, -0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.0787093, 0.0901613}, {-1.1746, -0.864758, -1.1746, -1.5746, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.1746, 0.864758, -1.1746, 0.0254033, 0.2, -1.5746, -0.374597, 0.064758, -0.374597, -0.374597, -0.064758, -0.374597, 0.0254033, -0.2, -1.5746, 2.74919, -0.709839, -0.4, 1.7746, 1.56568e-14, -0.225403, 2.74919, 0.709839, -0.4, -1.7746, -1.57123e-14, -1.7746, -0.4, -0.709839, 2.74919, 0.4, -0.0901613, 0.349193, 0.4, 0.0901613, 0.349193, -0.4, 0.709839, 2.74919, 0.349193, -0.0901613, 0.4, 0.225403, 1.99573e-15, 0.225403, 0.349193, 0.0901613, 0.4, -0.225403, -1.94022e-15, 1.7746}, {0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, 0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, 0, -1.7746, -1, 1.7746, 3.91577e-14, -1, 0, 1.7746, -1, -1.7746, -3.91577e-14, -1, -0.4, -0.4, 1.54919, 0.4, -0.4, 1.54919, 0.4, 0.4, 1.54919, -0.4, 0.4, 1.54919, 0, -0.225403, 1, 0.225403, 4.97368e-15, 1, 0, 0.225403, 1, -0.225403, -4.97368e-15, 1}, {1.5746, 0.2, 0.0254033, 1.1746, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.5746, -0.2, 0.0254033, 0.374597, 0.064758, -0.374597, -0.0254033, 0.2, -1.5746, -0.0254033, -0.2, -1.5746, 0.374597, -0.064758, -0.374597, -2.74919, -0.709839, -0.4, 1.7746, 1.56631e-14, -1.7746, -2.74919, 0.709839, -0.4, -1.7746, -1.56631e-14, -0.225403, -0.4, -0.0901613, 0.349193, 0.4, -0.709839, 2.74919, 0.4, 0.709839, 2.74919, -0.4, 0.0901613, 0.349193, -0.349193, -0.0901613, 0.4, 0.225403, 1.98947e-15, 1.7746, -0.349193, 0.0901613, 0.4, -0.225403, -1.98947e-15, 0.225403}, {-0.109839, 1.5746, -0.109839, -0.509839, 0.509839, 0.0254033, -1.5746, 0.109839, -0.109839, -3.30411, 3.30411, -3.30411, 0.0254033, 0.509839, -0.509839, -0.104113, 0.104113, -0.104113, -0.509839, -0.0254033, -0.509839, -0.109839, 0.109839, -1.5746, 0.619677, -0.709839, -0.0901613, 0.709839, -0.619677, -0.0901613, 4.87871, 0.709839, -0.709839, -0.709839, -4.87871, -0.709839, -0.0901613, -0.709839, 0.619677, 0.0901613, -0.0901613, 0.0787093, 0.709839, 0.0901613, 0.619677, -0.709839, 0.709839, 4.87871, 0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.0787093, 0.0901613, 0.619677, 0.0901613, 0.709839, -0.0901613, -0.619677, 0.709839}, {0.2, 1.5746, 0.0254033, -0.2, 1.5746, 0.0254033, 0.864758, 1.1746, -1.1746, -0.864758, 1.1746, -1.1746, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, -0.374597, -0.2, -0.0254033, -1.5746, 0.2, -0.0254033, -1.5746, 0, -1.7746, -0.225403, 0.709839, -2.74919, -0.4, 0, 1.7746, -1.7746, -0.709839, -2.74919, -0.4, -0.0901613, -0.4, 0.349193, 0.0901613, -0.4, 0.349193, 0.709839, 0.4, 2.74919, -0.709839, 0.4, 2.74919, 0, -0.225403, 0.225403, 0.0901613, -0.349193, 0.4, 0, 0.225403, 1.7746, -0.0901613, -0.349193, 0.4}, {0.509839, 0.509839, 0.0254033, 0.109839, 1.5746, -0.109839, 3.30411, 3.30411, -3.30411, 1.5746, 0.109839, -0.109839, 0.104113, 0.104113, -0.104113, -0.0254033, 0.509839, -0.509839, 0.109839, 0.109839, -1.5746, 0.509839, -0.0254033, -0.509839, -0.619677, -0.709839, -0.0901613, 0.709839, -4.87871, -0.709839, -4.87871, 0.709839, -0.709839, -0.709839, -0.619677, -0.0901613, -0.0901613, -0.0901613, 0.0787093, 0.0901613, -0.709839, 0.619677, 0.709839, 0.709839, 4.87871, -0.709839, 0.0901613, 0.619677, -0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.619677, 0.709839, -0.619677, 0.0901613, 0.709839, -0.0901613, -0.0787093, 0.0901613}, {-1.1746, -1.1746, -0.864758, -1.5746, 0.0254033, 0.2, -0.374597, -0.374597, 0.064758, 0.0254033, -1.5746, 0.2, -1.1746, -1.1746, 0.864758, -1.5746, 0.0254033, -0.2, -0.374597, -0.374597, -0.064758, 0.0254033, -1.5746, -0.2, 2.74919, -0.4, -0.709839, 0.4, 0.349193, -0.0901613, 0.349193, 0.4, -0.0901613, -0.4, 2.74919, -0.709839, -1.7746, -1.7746, 1.23334e-13, 1.7746, -0.225403, -1.23445e-13, 0.225403, 0.225403, -1.56655e-14, -0.225403, 1.7746, 1.57765e-14, 2.74919, -0.4, 0.709839, 0.4, 0.349193, 0.0901613, 0.349193, 0.4, 0.0901613, -0.4, 2.74919, 0.709839}, {0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, 0.2, -1.2746, 0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, -0.2, -0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, 0, -1, -1.7746, 0.4, 1.54919, -0.4, 0, 1, -0.225403, -0.4, 1.54919, -0.4, -1.7746, -1, 3.08336e-13, 1.7746, -1, -3.08336e-13, 0.225403, 1, -3.91638e-14, -0.225403, 1, 3.91638e-14, 0, -1, 1.7746, 0.4, 1.54919, 0.4, 0, 1, 0.225403, -0.4, 1.54919, 0.4}, {1.5746, 0.0254033, 0.2, 1.1746, -1.1746, -0.864758, -0.0254033, -1.5746, 0.2, 0.374597, -0.374597, 0.064758, 1.5746, 0.0254033, -0.2, 1.1746, -1.1746, 0.864758, -0.0254033, -1.5746, -0.2, 0.374597, -0.374597, -0.064758, -2.74919, -0.4, -0.709839, 0.4, 2.74919, -0.709839, -0.349193, 0.4, -0.0901613, -0.4, 0.349193, -0.0901613, -1.7746, -0.225403, 1.23347e-13, 1.7746, -1.7746, -1.23236e-13, 0.225403, 1.7746, -1.5764e-14, -0.225403, 0.225403, 1.5653e-14, -2.74919, -0.4, 0.709839, 0.4, 2.74919, 0.709839, -0.349193, 0.4, 0.0901613, -0.4, 0.349193, 0.0901613}, {-0.274597, 0.2, 0.2, -1.2746, 0.2, 0.2, -1.2746, -0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -0.2, -0.2, -0.274597, -0.2, -0.2, 1.54919, -0.4, -0.4, 1, 3.91631e-14, -0.225403, 1.54919, 0.4, -0.4, -1, -3.91631e-14, -1.7746, -1, -1.7746, 3.91909e-14, 1, -0.225403, -3.91909e-14, 1, 0.225403, -3.91909e-14, -1, 1.7746, 3.91909e-14, 1.54919, -0.4, 0.4, 1, 3.91631e-14, 0.225403, 1.54919, 0.4, 0.4, -1, -3.91631e-14, 1.7746}, {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, -1, -1, 1, 9.78939e-14, -1, 0, 1, -1, -1, -9.78939e-14, -1, -1, -1, 9.79217e-14, 1, -1, -9.79217e-14, 1, 1, -9.79217e-14, -1, 1, 9.79217e-14, 0, -1, 1, 1, 9.78939e-14, 1, 0, 1, 1, -1, -9.78939e-14, 1}, {1.2746, 0.2, 0.2, 0.274597, 0.2, 0.2, 0.274597, -0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -0.2, -0.2, 1.2746, -0.2, -0.2, -1.54919, -0.4, -0.4, 1, 3.91631e-14, -1.7746, -1.54919, 0.4, -0.4, -1, -3.91631e-14, -0.225403, -1, -0.225403, 3.91631e-14, 1, -1.7746, -3.91631e-14, 1, 1.7746, -3.91631e-14, -1, 0.225403, 3.91631e-14, -1.54919, -0.4, 0.4, 1, 3.91631e-14, 1.7746, -1.54919, 0.4, 0.4, -1, -3.91631e-14, 0.225403}, {0.0254033, 1.5746, 0.2, -0.374597, 0.374597, 0.064758, -1.5746, -0.0254033, 0.2, -1.1746, 1.1746, -0.864758, 0.0254033, 1.5746, -0.2, -0.374597, 0.374597, -0.064758, -1.5746, -0.0254033, -0.2, -1.1746, 1.1746, 0.864758, 0.349193, -0.4, -0.0901613, 0.4, -0.349193, -0.0901613, 2.74919, 0.4, -0.709839, -0.4, -2.74919, -0.709839, -0.225403, -1.7746, 1.98947e-15, 0.225403, -0.225403, -1.98947e-15, 1.7746, 0.225403, -1.56631e-14, -1.7746, 1.7746, 1.56631e-14, 0.349193, -0.4, 0.0901613, 0.4, -0.349193, 0.0901613, 2.74919, 0.4, 0.709839, -0.4, -2.74919, 0.709839}, {0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, 0.2, 0.274597, 0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, -0.2, -0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, 0, -1, -0.225403, 0.4, -1.54919, -0.4, 0, 1, -1.7746, -0.4, -1.54919, -0.4, -0.225403, -1, 4.97993e-15, 0.225403, -1, -4.97993e-15, 1.7746, 1, -3.92069e-14, -1.7746, 1, 3.92069e-14, 0, -1, 0.225403, 0.4, -1.54919, 0.4, 0, 1, 1.7746, -0.4, -1.54919, 0.4}, {0.374597, 0.374597, 0.064758, -0.0254033, 1.5746, 0.2, 1.1746, 1.1746, -0.864758, 1.5746, -0.0254033, 0.2, 0.374597, 0.374597, -0.064758, -0.0254033, 1.5746, -0.2, 1.1746, 1.1746, 0.864758, 1.5746, -0.0254033, -0.2, -0.349193, -0.4, -0.0901613, 0.4, -2.74919, -0.709839, -2.74919, 0.4, -0.709839, -0.4, -0.349193, -0.0901613, -0.225403, -0.225403, 1.99573e-15, 0.225403, -1.7746, -1.94022e-15, 1.7746, 1.7746, -1.57123e-14, -1.7746, 0.225403, 1.56568e-14, -0.349193, -0.4, 0.0901613, 0.4, -2.74919, 0.709839, -2.74919, 0.4, 0.709839, -0.4, -0.349193, 0.0901613}, {-0.109839, -0.109839, 1.5746, -0.509839, 0.0254033, 0.509839, -0.104113, -0.104113, 0.104113, 0.0254033, -0.509839, 0.509839, -3.30411, -3.30411, 3.30411, -1.5746, -0.109839, 0.109839, -0.509839, -0.509839, -0.0254033, -0.109839, -1.5746, 0.109839, 0.619677, -0.0901613, -0.709839, 0.0901613, 0.0787093, -0.0901613, 0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.619677, -0.709839, -0.709839, -0.709839, -4.87871, 0.709839, -0.0901613, -0.619677, 0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.709839, -0.619677, 4.87871, -0.709839, 0.709839, 0.709839, 0.619677, 0.0901613, 0.619677, 0.709839, 0.0901613, -0.709839, 4.87871, 0.709839}, {0.2, 0.0254033, 1.5746, -0.2, 0.0254033, 1.5746, -0.064758, -0.374597, 0.374597, 0.064758, -0.374597, 0.374597, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.1746, -0.2, -1.5746, -0.0254033, 0.2, -1.5746, -0.0254033, 0, -0.225403, -1.7746, 0.0901613, 0.349193, -0.4, 0, 0.225403, -0.225403, -0.0901613, 0.349193, -0.4, -0.709839, -0.4, -2.74919, 0.709839, -0.4, -2.74919, 0.0901613, 0.4, -0.349193, -0.0901613, 0.4, -0.349193, 0, -1.7746, 1.7746, 0.709839, 2.74919, 0.4, 0, 1.7746, 0.225403, -0.709839, 2.74919, 0.4}, {0.509839, 0.0254033, 0.509839, 0.109839, -0.109839, 1.5746, -0.0254033, -0.509839, 0.509839, 0.104113, -0.104113, 0.104113, 1.5746, -0.109839, 0.109839, 3.30411, -3.30411, 3.30411, 0.109839, -1.5746, 0.109839, 0.509839, -0.509839, -0.0254033, -0.619677, -0.0901613, -0.709839, 0.0901613, 0.619677, -0.709839, -0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.0787093, -0.0901613, -0.709839, -0.0901613, -0.619677, 0.709839, -0.709839, -4.87871, 0.0901613, 0.709839, -0.619677, -0.0901613, 0.0901613, -0.0787093, -4.87871, -0.709839, 0.709839, 0.709839, 4.87871, 0.709839, -0.619677, 0.709839, 0.0901613, -0.709839, 0.619677, 0.0901613}, {0.0254033, 0.2, 1.5746, -0.374597, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, 0.0254033, -0.2, 1.5746, -1.1746, -0.864758, 1.1746, -1.5746, 0.2, -0.0254033, -1.5746, -0.2, -0.0254033, -1.1746, 0.864758, 1.1746, 0.349193, -0.0901613, -0.4, 0.225403, 1.56655e-14, -0.225403, 0.349193, 0.0901613, -0.4, -0.225403, -1.56655e-14, -1.7746, -0.4, -0.709839, -2.74919, 0.4, -0.0901613, -0.349193, 0.4, 0.0901613, -0.349193, -0.4, 0.709839, -2.74919, 2.74919, -0.709839, 0.4, 1.7746, 1.23334e-13, 0.225403, 2.74919, 0.709839, 0.4, -1.7746, -1.23334e-13, 1.7746}, {0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, 0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, 0, -0.225403, -1, 0.225403, 3.91638e-14, -1, 0, 0.225403, -1, -0.225403, -3.91638e-14, -1, -0.4, -0.4, -1.54919, 0.4, -0.4, -1.54919, 0.4, 0.4, -1.54919, -0.4, 0.4, -1.54919, 0, -1.7746, 1, 1.7746, 3.08336e-13, 1, 0, 1.7746, 1, -1.7746, -3.08336e-13, 1}, {0.374597, 0.064758, 0.374597, -0.0254033, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, 0.374597, -0.064758, 0.374597, 1.5746, 0.2, -0.0254033, 1.1746, -0.864758, 1.1746, 1.1746, 0.864758, 1.1746, 1.5746, -0.2, -0.0254033, -0.349193, -0.0901613, -0.4, 0.225403, 1.56655e-14, -1.7746, -0.349193, 0.0901613, -0.4, -0.225403, -1.56655e-14, -0.225403, -0.4, -0.0901613, -0.349193, 0.4, -0.709839, -2.74919, 0.4, 0.709839, -2.74919, -0.4, 0.0901613, -0.349193, -2.74919, -0.709839, 0.4, 1.7746, 1.23334e-13, 1.7746, -2.74919, 0.709839, 0.4, -1.7746, -1.23334e-13, 0.225403}, {0.0254033, 0.509839, 0.509839, -0.104113, 0.104113, 0.104113, -0.509839, -0.0254033, 0.509839, -0.109839, 0.109839, 1.5746, -0.109839, 1.5746, 0.109839, -0.509839, 0.509839, -0.0254033, -1.5746, 0.109839, 0.109839, -3.30411, 3.30411, 3.30411, 0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.619677, 0.0901613, -0.709839, -0.0901613, -0.619677, -0.709839, -0.0901613, -0.709839, -0.619677, 0.0901613, -0.0901613, -0.0787093, 0.709839, 0.0901613, -0.619677, -0.709839, 0.709839, -4.87871, 0.619677, -0.709839, 0.0901613, 0.709839, -0.619677, 0.0901613, 4.87871, 0.709839, 0.709839, -0.709839, -4.87871, 0.709839}, {0.064758, 0.374597, 0.374597, -0.064758, 0.374597, 0.374597, -0.2, -0.0254033, 1.5746, 0.2, -0.0254033, 1.5746, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, -0.0254033, 0.864758, 1.1746, 1.1746, -0.864758, 1.1746, 1.1746, 0, -0.225403, -0.225403, 0.0901613, -0.349193, -0.4, 0, 0.225403, -1.7746, -0.0901613, -0.349193, -0.4, -0.0901613, -0.4, -0.349193, 0.0901613, -0.4, -0.349193, 0.709839, 0.4, -2.74919, -0.709839, 0.4, -2.74919, 0, -1.7746, 0.225403, 0.709839, -2.74919, 0.4, 0, 1.7746, 1.7746, -0.709839, -2.74919, 0.4}, {0.104113, 0.104113, 0.104113, -0.0254033, 0.509839, 0.509839, 0.109839, 0.109839, 1.5746, 0.509839, -0.0254033, 0.509839, 0.509839, 0.509839, -0.0254033, 0.109839, 1.5746, 0.109839, 3.30411, 3.30411, 3.30411, 1.5746, 0.109839, 0.109839, -0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.619677, -0.709839, -0.619677, 0.0901613, -0.709839, -0.0901613, -0.0787093, -0.0901613, -0.0901613, -0.0901613, -0.0787093, 0.0901613, -0.709839, -0.619677, 0.709839, 0.709839, -4.87871, -0.709839, 0.0901613, -0.619677, -0.619677, -0.709839, 0.0901613, 0.709839, -4.87871, 0.709839, -4.87871, 0.709839, 0.709839, -0.709839, -0.619677, 0.0901613}, {-3.30411, -3.30411, -3.30411, -1.5746, -0.109839, -0.109839, -0.509839, -0.509839, 0.0254033, -0.109839, -1.5746, -0.109839, -0.109839, -0.109839, -1.5746, -0.509839, 0.0254033, -0.509839, -0.104113, -0.104113, -0.104113, 0.0254033, -0.509839, -0.509839, 4.87871, -0.709839, -0.709839, 0.709839, 0.619677, -0.0901613, 0.619677, 0.709839, -0.0901613, -0.709839, 4.87871, -0.709839, -0.709839, -0.709839, 4.87871, 0.709839, -0.0901613, 0.619677, 0.0901613, 0.0901613, 0.0787093, -0.0901613, 0.709839, 0.619677, 0.619677, -0.0901613, 0.709839, 0.0901613, 0.0787093, 0.0901613, 0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.619677, 0.709839}, {-0.864758, -1.1746, -1.1746, 0.864758, -1.1746, -1.1746, -0.2, -1.5746, 0.0254033, 0.2, -1.5746, 0.0254033, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.5746, -0.064758, -0.374597, -0.374597, 0.064758, -0.374597, -0.374597, -1.56631e-14, -1.7746, -1.7746, 0.709839, 2.74919, -0.4, -1.98947e-15, 1.7746, -0.225403, -0.709839, 2.74919, -0.4, -0.709839, -0.4, 2.74919, 0.709839, -0.4, 2.74919, 0.0901613, 0.4, 0.349193, -0.0901613, 0.4, 0.349193, 1.56631e-14, -0.225403, 1.7746, 0.0901613, 0.349193, 0.4, 1.98947e-15, 0.225403, 0.225403, -0.0901613, 0.349193, 0.4}, {1.5746, -0.109839, -0.109839, 3.30411, -3.30411, -3.30411, 0.109839, -1.5746, -0.109839, 0.509839, -0.509839, 0.0254033, 0.509839, 0.0254033, -0.509839, 0.109839, -0.109839, -1.5746, -0.0254033, -0.509839, -0.509839, 0.104113, -0.104113, -0.104113, -4.87871, -0.709839, -0.709839, 0.709839, 4.87871, -0.709839, -0.619677, 0.709839, -0.0901613, -0.709839, 0.619677, -0.0901613, -0.709839, -0.0901613, 0.619677, 0.709839, -0.709839, 4.87871, 0.0901613, 0.709839, 0.619677, -0.0901613, 0.0901613, 0.0787093, -0.619677, -0.0901613, 0.709839, 0.0901613, 0.619677, 0.709839, -0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.0787093, 0.0901613}, {-1.1746, -0.864758, -1.1746, -1.5746, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.1746, 0.864758, -1.1746, 0.0254033, 0.2, -1.5746, -0.374597, 0.064758, -0.374597, -0.374597, -0.064758, -0.374597, 0.0254033, -0.2, -1.5746, 2.74919, -0.709839, -0.4, 1.7746, -1.07669e-13, -0.225403, 2.74919, 0.709839, -0.4, -1.7746, 2.46669e-13, -1.7746, -0.4, -0.709839, 2.74919, 0.4, -0.0901613, 0.349193, 0.4, 0.0901613, 0.349193, -0.4, 0.709839, 2.74919, 0.349193, -0.0901613, 0.4, 0.225403, -3.1331e-14, 0.225403, 0.349193, 0.0901613, 0.4, -0.225403, -1.07669e-13, 1.7746}, {0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, 0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -3.91631e-14, -1.7746, -1, 1.7746, -2.69173e-13, -1, -3.91631e-14, 1.7746, -1, -1.7746, 3.47499e-13, -1, -0.4, -0.4, 1.54919, 0.4, -0.4, 1.54919, 0.4, 0.4, 1.54919, -0.4, 0.4, 1.54919, 3.91631e-14, -0.225403, 1, 0.225403, -7.83269e-14, 1, 3.91631e-14, 0.225403, 1, -0.225403, 6.89741e-19, 1}, {1.5746, 0.2, 0.0254033, 1.1746, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.5746, -0.2, 0.0254033, 0.374597, 0.064758, -0.374597, -0.0254033, 0.2, -1.5746, -0.0254033, -0.2, -1.5746, 0.374597, -0.064758, -0.374597, -2.74919, -0.709839, -0.4, 1.7746, -1.07671e-13, -1.7746, -2.74919, 0.709839, -0.4, -1.7746, 1.25324e-13, -0.225403, -0.4, -0.0901613, 0.349193, 0.4, -0.709839, 2.74919, 0.4, 0.709839, 2.74919, -0.4, 0.0901613, 0.349193, -0.349193, -0.0901613, 0.4, 0.225403, -3.13286e-14, 1.7746, -0.349193, 0.0901613, 0.4, -0.225403, 1.36761e-14, 0.225403}, {-0.109839, 1.5746, -0.109839, -0.509839, 0.509839, 0.0254033, -1.5746, 0.109839, -0.109839, -3.30411, 3.30411, -3.30411, 0.0254033, 0.509839, -0.509839, -0.104113, 0.104113, -0.104113, -0.509839, -0.0254033, -0.509839, -0.109839, 0.109839, -1.5746, 0.619677, -0.709839, -0.0901613, 0.709839, -0.619677, -0.0901613, 4.87871, 0.709839, -0.709839, -0.709839, -4.87871, -0.709839, -0.0901613, -0.709839, 0.619677, 0.0901613, -0.0901613, 0.0787093, 0.709839, 0.0901613, 0.619677, -0.709839, 0.709839, 4.87871, 0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.0787093, 0.0901613, 0.619677, 0.0901613, 0.709839, -0.0901613, -0.619677, 0.709839}, {0.2, 1.5746, 0.0254033, -0.2, 1.5746, 0.0254033, 0.864758, 1.1746, -1.1746, -0.864758, 1.1746, -1.1746, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, -0.374597, -0.2, -0.0254033, -1.5746, 0.2, -0.0254033, -1.5746, -1.56655e-14, -1.7746, -0.225403, 0.709839, -2.74919, -0.4, -1.23334e-13, 1.7746, -1.7746, -0.709839, -2.74919, -0.4, -0.0901613, -0.4, 0.349193, 0.0901613, -0.4, 0.349193, 0.709839, 0.4, 2.74919, -0.709839, 0.4, 2.74919, 1.56655e-14, -0.225403, 0.225403, 0.0901613, -0.349193, 0.4, 1.23334e-13, 0.225403, 1.7746, -0.0901613, -0.349193, 0.4}, {0.509839, 0.509839, 0.0254033, 0.109839, 1.5746, -0.109839, 3.30411, 3.30411, -3.30411, 1.5746, 0.109839, -0.109839, 0.104113, 0.104113, -0.104113, -0.0254033, 0.509839, -0.509839, 0.109839, 0.109839, -1.5746, 0.509839, -0.0254033, -0.509839, -0.619677, -0.709839, -0.0901613, 0.709839, -4.87871, -0.709839, -4.87871, 0.709839, -0.709839, -0.709839, -0.619677, -0.0901613, -0.0901613, -0.0901613, 0.0787093, 0.0901613, -0.709839, 0.619677, 0.709839, 0.709839, 4.87871, -0.709839, 0.0901613, 0.619677, -0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.619677, 0.709839, -0.619677, 0.0901613, 0.709839, -0.0901613, -0.0787093, 0.0901613}, {-1.1746, -1.1746, -0.864758, -1.5746, 0.0254033, 0.2, -0.374597, -0.374597, 0.064758, 0.0254033, -1.5746, 0.2, -1.1746, -1.1746, 0.864758, -1.5746, 0.0254033, -0.2, -0.374597, -0.374597, -0.064758, 0.0254033, -1.5746, -0.2, 2.74919, -0.4, -0.709839, 0.4, 0.349193, -0.0901613, 0.349193, 0.4, -0.0901613, -0.4, 2.74919, -0.709839, -1.7746, -1.7746, -1.56631e-14, 1.7746, -0.225403, 1.56631e-14, 0.225403, 0.225403, 1.98947e-15, -0.225403, 1.7746, -1.98947e-15, 2.74919, -0.4, 0.709839, 0.4, 0.349193, 0.0901613, 0.349193, 0.4, 0.0901613, -0.4, 2.74919, 0.709839}, {0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, 0.2, -1.2746, 0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, -0.2, -0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -3.91577e-14, -1, -1.7746, 0.4, 1.54919, -0.4, -4.97368e-15, 1, -0.225403, -0.4, 1.54919, -0.4, -1.7746, -1, -3.92069e-14, 1.7746, -1, 3.92069e-14, 0.225403, 1, 4.97993e-15, -0.225403, 1, -4.97993e-15, 3.91577e-14, -1, 1.7746, 0.4, 1.54919, 0.4, 4.97368e-15, 1, 0.225403, -0.4, 1.54919, 0.4}, {1.5746, 0.0254033, 0.2, 1.1746, -1.1746, -0.864758, -0.0254033, -1.5746, 0.2, 0.374597, -0.374597, 0.064758, 1.5746, 0.0254033, -0.2, 1.1746, -1.1746, 0.864758, -0.0254033, -1.5746, -0.2, 0.374597, -0.374597, -0.064758, -2.74919, -0.4, -0.709839, 0.4, 2.74919, -0.709839, -0.349193, 0.4, -0.0901613, -0.4, 0.349193, -0.0901613, -1.7746, -0.225403, -1.56631e-14, 1.7746, -1.7746, 1.56631e-14, 0.225403, 1.7746, 1.98947e-15, -0.225403, 0.225403, -1.98947e-15, -2.74919, -0.4, 0.709839, 0.4, 2.74919, 0.709839, -0.349193, 0.4, 0.0901613, -0.4, 0.349193, 0.0901613}, {-0.274597, 0.2, 0.2, -1.2746, 0.2, 0.2, -1.2746, -0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -0.2, -0.2, -0.274597, -0.2, -0.2, 1.54919, -0.4, -0.4, 1, -2.70658e-17, -0.225403, 1.54919, 0.4, -0.4, -1, 3.47527e-13, -1.7746, -1, -1.7746, -3.90799e-14, 1, -0.225403, 3.90799e-14, 1, 0.225403, 3.90799e-14, -1, 1.7746, -3.90799e-14, 1.54919, -0.4, 0.4, 1, -7.83547e-14, 0.225403, 1.54919, 0.4, 0.4, -1, -2.69145e-13, 1.7746}, {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, -9.78939e-14, -1, -1, 1, -2.77556e-17, -1, -9.78939e-14, 1, -1, -1, 1.95816e-13, -1, -1, -1, -9.79217e-14, 1, -1, 9.79217e-14, 1, 1, 9.79217e-14, -1, 1, -9.79217e-14, 9.78939e-14, -1, 1, 1, -1.95816e-13, 1, 9.78939e-14, 1, 1, -1, 2.77556e-17, 1}, {1.2746, 0.2, 0.2, 0.274597, 0.2, 0.2, 0.274597, -0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -0.2, -0.2, 1.2746, -0.2, -0.2, -1.54919, -0.4, -0.4, 1, -5.43032e-18, -1.7746, -1.54919, 0.4, -0.4, -1, 4.41368e-14, -0.225403, -1, -0.225403, -3.91909e-14, 1, -1.7746, 3.91909e-14, 1, 1.7746, 3.91909e-14, -1, 0.225403, -3.91909e-14, -1.54919, -0.4, 0.4, 1, -7.83208e-14, 1.7746, -1.54919, 0.4, 0.4, -1, 3.41894e-14, 0.225403}, {0.0254033, 1.5746, 0.2, -0.374597, 0.374597, 0.064758, -1.5746, -0.0254033, 0.2, -1.1746, 1.1746, -0.864758, 0.0254033, 1.5746, -0.2, -0.374597, 0.374597, -0.064758, -1.5746, -0.0254033, -0.2, -1.1746, 1.1746, 0.864758, 0.349193, -0.4, -0.0901613, 0.4, -0.349193, -0.0901613, 2.74919, 0.4, -0.709839, -0.4, -2.74919, -0.709839, -0.225403, -1.7746, -1.55303e-14, 0.225403, -0.225403, 1.56968e-14, 1.7746, 0.225403, 1.23414e-13, -1.7746, 1.7746, -1.23581e-13, 0.349193, -0.4, 0.0901613, 0.4, -0.349193, 0.0901613, 2.74919, 0.4, 0.709839, -0.4, -2.74919, 0.709839}, {0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, 0.2, 0.274597, 0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, -0.2, -0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -3.91638e-14, -1, -0.225403, 0.4, -1.54919, -0.4, -3.08336e-13, 1, -1.7746, -0.4, -1.54919, -0.4, -0.225403, -1, -3.91638e-14, 0.225403, -1, 3.91638e-14, 1.7746, 1, 3.08336e-13, -1.7746, 1, -3.08336e-13, 3.91638e-14, -1, 0.225403, 0.4, -1.54919, 0.4, 3.08336e-13, 1, 1.7746, -0.4, -1.54919, 0.4}, {0.374597, 0.374597, 0.064758, -0.0254033, 1.5746, 0.2, 1.1746, 1.1746, -0.864758, 1.5746, -0.0254033, 0.2, 0.374597, 0.374597, -0.064758, -0.0254033, 1.5746, -0.2, 1.1746, 1.1746, 0.864758, 1.5746, -0.0254033, -0.2, -0.349193, -0.4, -0.0901613, 0.4, -2.74919, -0.709839, -2.74919, 0.4, -0.709839, -0.4, -0.349193, -0.0901613, -0.225403, -0.225403, -1.56843e-14, 0.225403, -1.7746, 1.55178e-14, 1.7746, 1.7746, 1.23482e-13, -1.7746, 0.225403, -1.23316e-13, -0.349193, -0.4, 0.0901613, 0.4, -2.74919, 0.709839, -2.74919, 0.4, 0.709839, -0.4, -0.349193, 0.0901613}, {-0.109839, -0.109839, 1.5746, -0.509839, 0.0254033, 0.509839, -0.104113, -0.104113, 0.104113, 0.0254033, -0.509839, 0.509839, -3.30411, -3.30411, 3.30411, -1.5746, -0.109839, 0.109839, -0.509839, -0.509839, -0.0254033, -0.109839, -1.5746, 0.109839, 0.619677, -0.0901613, -0.709839, 0.0901613, 0.0787093, -0.0901613, 0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.619677, -0.709839, -0.709839, -0.709839, -4.87871, 0.709839, -0.0901613, -0.619677, 0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.709839, -0.619677, 4.87871, -0.709839, 0.709839, 0.709839, 0.619677, 0.0901613, 0.619677, 0.709839, 0.0901613, -0.709839, 4.87871, 0.709839}, {0.2, 0.0254033, 1.5746, -0.2, 0.0254033, 1.5746, -0.064758, -0.374597, 0.374597, 0.064758, -0.374597, 0.374597, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.1746, -0.2, -1.5746, -0.0254033, 0.2, -1.5746, -0.0254033, -1.56631e-14, -0.225403, -1.7746, 0.0901613, 0.349193, -0.4, -1.98947e-15, 0.225403, -0.225403, -0.0901613, 0.349193, -0.4, -0.709839, -0.4, -2.74919, 0.709839, -0.4, -2.74919, 0.0901613, 0.4, -0.349193, -0.0901613, 0.4, -0.349193, 1.56631e-14, -1.7746, 1.7746, 0.709839, 2.74919, 0.4, 1.98947e-15, 1.7746, 0.225403, -0.709839, 2.74919, 0.4}, {0.509839, 0.0254033, 0.509839, 0.109839, -0.109839, 1.5746, -0.0254033, -0.509839, 0.509839, 0.104113, -0.104113, 0.104113, 1.5746, -0.109839, 0.109839, 3.30411, -3.30411, 3.30411, 0.109839, -1.5746, 0.109839, 0.509839, -0.509839, -0.0254033, -0.619677, -0.0901613, -0.709839, 0.0901613, 0.619677, -0.709839, -0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.0787093, -0.0901613, -0.709839, -0.0901613, -0.619677, 0.709839, -0.709839, -4.87871, 0.0901613, 0.709839, -0.619677, -0.0901613, 0.0901613, -0.0787093, -4.87871, -0.709839, 0.709839, 0.709839, 4.87871, 0.709839, -0.619677, 0.709839, 0.0901613, -0.709839, 0.619677, 0.0901613}, {0.0254033, 0.2, 1.5746, -0.374597, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, 0.0254033, -0.2, 1.5746, -1.1746, -0.864758, 1.1746, -1.5746, 0.2, -0.0254033, -1.5746, -0.2, -0.0254033, -1.1746, 0.864758, 1.1746, 0.349193, -0.0901613, -0.4, 0.225403, 1.36823e-14, -0.225403, 0.349193, 0.0901613, -0.4, -0.225403, 1.25373e-13, -1.7746, -0.4, -0.709839, -2.74919, 0.4, -0.0901613, -0.349193, 0.4, 0.0901613, -0.349193, -0.4, 0.709839, -2.74919, 2.74919, -0.709839, 0.4, 1.7746, -3.13349e-14, 0.225403, 2.74919, 0.709839, 0.4, -1.7746, -1.07721e-13, 1.7746}, {0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, 0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -3.91631e-14, -0.225403, -1, 0.225403, 3.41832e-14, -1, -3.91631e-14, 0.225403, -1, -0.225403, 4.41431e-14, -1, -0.4, -0.4, -1.54919, 0.4, -0.4, -1.54919, 0.4, 0.4, -1.54919, -0.4, 0.4, -1.54919, 3.91631e-14, -1.7746, 1, 1.7746, -7.83701e-14, 1, 3.91631e-14, 1.7746, 1, -1.7746, 4.38246e-17, 1}, {0.374597, 0.064758, 0.374597, -0.0254033, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, 0.374597, -0.064758, 0.374597, 1.5746, 0.2, -0.0254033, 1.1746, -0.864758, 1.1746, 1.1746, 0.864758, 1.1746, 1.5746, -0.2, -0.0254033, -0.349193, -0.0901613, -0.4, 0.225403, 1.36736e-14, -1.7746, -0.349193, 0.0901613, -0.4, -0.225403, 3.97894e-15, -0.225403, -0.4, -0.0901613, -0.349193, 0.4, -0.709839, -2.74919, 0.4, 0.709839, -2.74919, -0.4, 0.0901613, -0.349193, -2.74919, -0.709839, 0.4, 1.7746, -3.13261e-14, 1.7746, -2.74919, 0.709839, 0.4, -1.7746, 1.36736e-14, 0.225403}, {0.0254033, 0.509839, 0.509839, -0.104113, 0.104113, 0.104113, -0.509839, -0.0254033, 0.509839, -0.109839, 0.109839, 1.5746, -0.109839, 1.5746, 0.109839, -0.509839, 0.509839, -0.0254033, -1.5746, 0.109839, 0.109839, -3.30411, 3.30411, 3.30411, 0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.619677, 0.0901613, -0.709839, -0.0901613, -0.619677, -0.709839, -0.0901613, -0.709839, -0.619677, 0.0901613, -0.0901613, -0.0787093, 0.709839, 0.0901613, -0.619677, -0.709839, 0.709839, -4.87871, 0.619677, -0.709839, 0.0901613, 0.709839, -0.619677, 0.0901613, 4.87871, 0.709839, 0.709839, -0.709839, -4.87871, 0.709839}, {0.064758, 0.374597, 0.374597, -0.064758, 0.374597, 0.374597, -0.2, -0.0254033, 1.5746, 0.2, -0.0254033, 1.5746, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, -0.0254033, 0.864758, 1.1746, 1.1746, -0.864758, 1.1746, 1.1746, -1.56655e-14, -0.225403, -0.225403, 0.0901613, -0.349193, -0.4, -1.23334e-13, 0.225403, -1.7746, -0.0901613, -0.349193, -0.4, -0.0901613, -0.4, -0.349193, 0.0901613, -0.4, -0.349193, 0.709839, 0.4, -2.74919, -0.709839, 0.4, -2.74919, 1.56655e-14, -1.7746, 0.225403, 0.709839, -2.74919, 0.4, 1.23334e-13, 1.7746, 1.7746, -0.709839, -2.74919, 0.4}, {0.104113, 0.104113, 0.104113, -0.0254033, 0.509839, 0.509839, 0.109839, 0.109839, 1.5746, 0.509839, -0.0254033, 0.509839, 0.509839, 0.509839, -0.0254033, 0.109839, 1.5746, 0.109839, 3.30411, 3.30411, 3.30411, 1.5746, 0.109839, 0.109839, -0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.619677, -0.709839, -0.619677, 0.0901613, -0.709839, -0.0901613, -0.0787093, -0.0901613, -0.0901613, -0.0901613, -0.0787093, 0.0901613, -0.709839, -0.619677, 0.709839, 0.709839, -4.87871, -0.709839, 0.0901613, -0.619677, -0.619677, -0.709839, 0.0901613, 0.709839, -4.87871, 0.709839, -4.87871, 0.709839, 0.709839, -0.709839, -0.619677, 0.0901613}, {-3.30411, -3.30411, -3.30411, -1.5746, -0.109839, -0.109839, -0.509839, -0.509839, 0.0254033, -0.109839, -1.5746, -0.109839, -0.109839, -0.109839, -1.5746, -0.509839, 0.0254033, -0.509839, -0.104113, -0.104113, -0.104113, 0.0254033, -0.509839, -0.509839, 4.87871, -0.709839, -0.709839, 0.709839, 0.619677, -0.0901613, 0.619677, 0.709839, -0.0901613, -0.709839, 4.87871, -0.709839, -0.709839, -0.709839, 4.87871, 0.709839, -0.0901613, 0.619677, 0.0901613, 0.0901613, 0.0787093, -0.0901613, 0.709839, 0.619677, 0.619677, -0.0901613, 0.709839, 0.0901613, 0.0787093, 0.0901613, 0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.619677, 0.709839}, {-0.864758, -1.1746, -1.1746, 0.864758, -1.1746, -1.1746, -0.2, -1.5746, 0.0254033, 0.2, -1.5746, 0.0254033, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.5746, -0.064758, -0.374597, -0.374597, 0.064758, -0.374597, -0.374597, 1.56631e-14, -1.7746, -1.7746, 0.709839, 2.74919, -0.4, -1.56631e-14, 1.7746, -0.225403, -0.709839, 2.74919, -0.4, -0.709839, -0.4, 2.74919, 0.709839, -0.4, 2.74919, 0.0901613, 0.4, 0.349193, -0.0901613, 0.4, 0.349193, 1.98947e-15, -0.225403, 1.7746, 0.0901613, 0.349193, 0.4, -1.98947e-15, 0.225403, 0.225403, -0.0901613, 0.349193, 0.4}, {1.5746, -0.109839, -0.109839, 3.30411, -3.30411, -3.30411, 0.109839, -1.5746, -0.109839, 0.509839, -0.509839, 0.0254033, 0.509839, 0.0254033, -0.509839, 0.109839, -0.109839, -1.5746, -0.0254033, -0.509839, -0.509839, 0.104113, -0.104113, -0.104113, -4.87871, -0.709839, -0.709839, 0.709839, 4.87871, -0.709839, -0.619677, 0.709839, -0.0901613, -0.709839, 0.619677, -0.0901613, -0.709839, -0.0901613, 0.619677, 0.709839, -0.709839, 4.87871, 0.0901613, 0.709839, 0.619677, -0.0901613, 0.0901613, 0.0787093, -0.619677, -0.0901613, 0.709839, 0.0901613, 0.619677, 0.709839, -0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.0787093, 0.0901613}, {-1.1746, -0.864758, -1.1746, -1.5746, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.1746, 0.864758, -1.1746, 0.0254033, 0.2, -1.5746, -0.374597, 0.064758, -0.374597, -0.374597, -0.064758, -0.374597, 0.0254033, -0.2, -1.5746, 2.74919, -0.709839, -0.4, 1.7746, -6.2562e-18, -0.225403, 2.74919, 0.709839, -0.4, -1.7746, -4.9255e-17, -1.7746, -0.4, -0.709839, 2.74919, 0.4, -0.0901613, 0.349193, 0.4, 0.0901613, 0.349193, -0.4, 0.709839, 2.74919, 0.349193, -0.0901613, 0.4, 0.225403, 6.2562e-18, 0.225403, 0.349193, 0.0901613, 0.4, -0.225403, 4.9255e-17, 1.7746}, {0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, 0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, 3.91577e-14, -1.7746, -1, 1.7746, 0, -1, -3.91577e-14, 1.7746, -1, -1.7746, 0, -1, -0.4, -0.4, 1.54919, 0.4, -0.4, 1.54919, 0.4, 0.4, 1.54919, -0.4, 0.4, 1.54919, 4.97368e-15, -0.225403, 1, 0.225403, 0, 1, -4.97368e-15, 0.225403, 1, -0.225403, 0, 1}, {1.5746, 0.2, 0.0254033, 1.1746, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.5746, -0.2, 0.0254033, 0.374597, 0.064758, -0.374597, -0.0254033, 0.2, -1.5746, -0.0254033, -0.2, -1.5746, 0.374597, -0.064758, -0.374597, -2.74919, -0.709839, -0.4, 1.7746, 0, -1.7746, -2.74919, 0.709839, -0.4, -1.7746, 0, -0.225403, -0.4, -0.0901613, 0.349193, 0.4, -0.709839, 2.74919, 0.4, 0.709839, 2.74919, -0.4, 0.0901613, 0.349193, -0.349193, -0.0901613, 0.4, 0.225403, 0, 1.7746, -0.349193, 0.0901613, 0.4, -0.225403, 0, 0.225403}, {-0.109839, 1.5746, -0.109839, -0.509839, 0.509839, 0.0254033, -1.5746, 0.109839, -0.109839, -3.30411, 3.30411, -3.30411, 0.0254033, 0.509839, -0.509839, -0.104113, 0.104113, -0.104113, -0.509839, -0.0254033, -0.509839, -0.109839, 0.109839, -1.5746, 0.619677, -0.709839, -0.0901613, 0.709839, -0.619677, -0.0901613, 4.87871, 0.709839, -0.709839, -0.709839, -4.87871, -0.709839, -0.0901613, -0.709839, 0.619677, 0.0901613, -0.0901613, 0.0787093, 0.709839, 0.0901613, 0.619677, -0.709839, 0.709839, 4.87871, 0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.0787093, 0.0901613, 0.619677, 0.0901613, 0.709839, -0.0901613, -0.619677, 0.709839}, {0.2, 1.5746, 0.0254033, -0.2, 1.5746, 0.0254033, 0.864758, 1.1746, -1.1746, -0.864758, 1.1746, -1.1746, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, -0.374597, -0.2, -0.0254033, -1.5746, 0.2, -0.0254033, -1.5746, 1.56631e-14, -1.7746, -0.225403, 0.709839, -2.74919, -0.4, -1.56631e-14, 1.7746, -1.7746, -0.709839, -2.74919, -0.4, -0.0901613, -0.4, 0.349193, 0.0901613, -0.4, 0.349193, 0.709839, 0.4, 2.74919, -0.709839, 0.4, 2.74919, 1.98947e-15, -0.225403, 0.225403, 0.0901613, -0.349193, 0.4, -1.98947e-15, 0.225403, 1.7746, -0.0901613, -0.349193, 0.4}, {0.509839, 0.509839, 0.0254033, 0.109839, 1.5746, -0.109839, 3.30411, 3.30411, -3.30411, 1.5746, 0.109839, -0.109839, 0.104113, 0.104113, -0.104113, -0.0254033, 0.509839, -0.509839, 0.109839, 0.109839, -1.5746, 0.509839, -0.0254033, -0.509839, -0.619677, -0.709839, -0.0901613, 0.709839, -4.87871, -0.709839, -4.87871, 0.709839, -0.709839, -0.709839, -0.619677, -0.0901613, -0.0901613, -0.0901613, 0.0787093, 0.0901613, -0.709839, 0.619677, 0.709839, 0.709839, 4.87871, -0.709839, 0.0901613, 0.619677, -0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.619677, 0.709839, -0.619677, 0.0901613, 0.709839, -0.0901613, -0.0787093, 0.0901613}, {-1.1746, -1.1746, -0.864758, -1.5746, 0.0254033, 0.2, -0.374597, -0.374597, 0.064758, 0.0254033, -1.5746, 0.2, -1.1746, -1.1746, 0.864758, -1.5746, 0.0254033, -0.2, -0.374597, -0.374597, -0.064758, 0.0254033, -1.5746, -0.2, 2.74919, -0.4, -0.709839, 0.4, 0.349193, -0.0901613, 0.349193, 0.4, -0.0901613, -0.4, 2.74919, -0.709839, -1.7746, -1.7746, -1.23236e-13, 1.7746, -0.225403, -1.5764e-14, 0.225403, 0.225403, 1.5653e-14, -0.225403, 1.7746, 1.23347e-13, 2.74919, -0.4, 0.709839, 0.4, 0.349193, 0.0901613, 0.349193, 0.4, 0.0901613, -0.4, 2.74919, 0.709839}, {0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, 0.2, -1.2746, 0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, -0.2, -0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, 3.91631e-14, -1, -1.7746, 0.4, 1.54919, -0.4, -3.91631e-14, 1, -0.225403, -0.4, 1.54919, -0.4, -1.7746, -1, -3.91631e-14, 1.7746, -1, -3.91631e-14, 0.225403, 1, 3.91631e-14, -0.225403, 1, 3.91631e-14, 3.91631e-14, -1, 1.7746, 0.4, 1.54919, 0.4, -3.91631e-14, 1, 0.225403, -0.4, 1.54919, 0.4}, {1.5746, 0.0254033, 0.2, 1.1746, -1.1746, -0.864758, -0.0254033, -1.5746, 0.2, 0.374597, -0.374597, 0.064758, 1.5746, 0.0254033, -0.2, 1.1746, -1.1746, 0.864758, -0.0254033, -1.5746, -0.2, 0.374597, -0.374597, -0.064758, -2.74919, -0.4, -0.709839, 0.4, 2.74919, -0.709839, -0.349193, 0.4, -0.0901613, -0.4, 0.349193, -0.0901613, -1.7746, -0.225403, -1.98947e-15, 1.7746, -1.7746, -1.56631e-14, 0.225403, 1.7746, 1.56631e-14, -0.225403, 0.225403, 1.98947e-15, -2.74919, -0.4, 0.709839, 0.4, 2.74919, 0.709839, -0.349193, 0.4, 0.0901613, -0.4, 0.349193, 0.0901613}, {-0.274597, 0.2, 0.2, -1.2746, 0.2, 0.2, -1.2746, -0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -0.2, -0.2, -0.274597, -0.2, -0.2, 1.54919, -0.4, -0.4, 1, 0, -0.225403, 1.54919, 0.4, -0.4, -1, 0, -1.7746, -1, -1.7746, -3.08336e-13, 1, -0.225403, -3.91638e-14, 1, 0.225403, 3.91638e-14, -1, 1.7746, 3.08336e-13, 1.54919, -0.4, 0.4, 1, 0, 0.225403, 1.54919, 0.4, 0.4, -1, 0, 1.7746}, {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, 9.78939e-14, -1, -1, 1, 0, -1, -9.78939e-14, 1, -1, -1, 0, -1, -1, -1, -9.78939e-14, 1, -1, -9.78939e-14, 1, 1, 9.78939e-14, -1, 1, 9.78939e-14, 9.78939e-14, -1, 1, 1, 0, 1, -9.78939e-14, 1, 1, -1, 0, 1}, {1.2746, 0.2, 0.2, 0.274597, 0.2, 0.2, 0.274597, -0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -0.2, -0.2, 1.2746, -0.2, -0.2, -1.54919, -0.4, -0.4, 1, 0, -1.7746, -1.54919, 0.4, -0.4, -1, 0, -0.225403, -1, -0.225403, -4.97368e-15, 1, -1.7746, -3.91577e-14, 1, 1.7746, 3.91577e-14, -1, 0.225403, 4.97368e-15, -1.54919, -0.4, 0.4, 1, 0, 1.7746, -1.54919, 0.4, 0.4, -1, 0, 0.225403}, {0.0254033, 1.5746, 0.2, -0.374597, 0.374597, 0.064758, -1.5746, -0.0254033, 0.2, -1.1746, 1.1746, -0.864758, 0.0254033, 1.5746, -0.2, -0.374597, 0.374597, -0.064758, -1.5746, -0.0254033, -0.2, -1.1746, 1.1746, 0.864758, 0.349193, -0.4, -0.0901613, 0.4, -0.349193, -0.0901613, 2.74919, 0.4, -0.709839, -0.4, -2.74919, -0.709839, -0.225403, -1.7746, -1.23199e-13, 0.225403, -0.225403, -1.56342e-14, 1.7746, 0.225403, 1.57453e-14, -1.7746, 1.7746, 1.23088e-13, 0.349193, -0.4, 0.0901613, 0.4, -0.349193, 0.0901613, 2.74919, 0.4, 0.709839, -0.4, -2.74919, 0.709839}, {0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, 0.2, 0.274597, 0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, -0.2, -0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, 3.91631e-14, -1, -0.225403, 0.4, -1.54919, -0.4, -3.91631e-14, 1, -1.7746, -0.4, -1.54919, -0.4, -0.225403, -1, -3.91631e-14, 0.225403, -1, -3.91631e-14, 1.7746, 1, 3.91631e-14, -1.7746, 1, 3.91631e-14, 3.91631e-14, -1, 0.225403, 0.4, -1.54919, 0.4, -3.91631e-14, 1, 1.7746, -0.4, -1.54919, 0.4}, {0.374597, 0.374597, 0.064758, -0.0254033, 1.5746, 0.2, 1.1746, 1.1746, -0.864758, 1.5746, -0.0254033, 0.2, 0.374597, 0.374597, -0.064758, -0.0254033, 1.5746, -0.2, 1.1746, 1.1746, 0.864758, 1.5746, -0.0254033, -0.2, -0.349193, -0.4, -0.0901613, 0.4, -2.74919, -0.709839, -2.74919, 0.4, -0.709839, -0.4, -0.349193, -0.0901613, -0.225403, -0.225403, -2.00824e-15, 0.225403, -1.7746, -1.58108e-14, 1.7746, 1.7746, 1.58108e-14, -1.7746, 0.225403, 2.00824e-15, -0.349193, -0.4, 0.0901613, 0.4, -2.74919, 0.709839, -2.74919, 0.4, 0.709839, -0.4, -0.349193, 0.0901613}, {-0.109839, -0.109839, 1.5746, -0.509839, 0.0254033, 0.509839, -0.104113, -0.104113, 0.104113, 0.0254033, -0.509839, 0.509839, -3.30411, -3.30411, 3.30411, -1.5746, -0.109839, 0.109839, -0.509839, -0.509839, -0.0254033, -0.109839, -1.5746, 0.109839, 0.619677, -0.0901613, -0.709839, 0.0901613, 0.0787093, -0.0901613, 0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.619677, -0.709839, -0.709839, -0.709839, -4.87871, 0.709839, -0.0901613, -0.619677, 0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.709839, -0.619677, 4.87871, -0.709839, 0.709839, 0.709839, 0.619677, 0.0901613, 0.619677, 0.709839, 0.0901613, -0.709839, 4.87871, 0.709839}, {0.2, 0.0254033, 1.5746, -0.2, 0.0254033, 1.5746, -0.064758, -0.374597, 0.374597, 0.064758, -0.374597, 0.374597, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.1746, -0.2, -1.5746, -0.0254033, 0.2, -1.5746, -0.0254033, 1.56655e-14, -0.225403, -1.7746, 0.0901613, 0.349193, -0.4, -1.56655e-14, 0.225403, -0.225403, -0.0901613, 0.349193, -0.4, -0.709839, -0.4, -2.74919, 0.709839, -0.4, -2.74919, 0.0901613, 0.4, -0.349193, -0.0901613, 0.4, -0.349193, 1.23334e-13, -1.7746, 1.7746, 0.709839, 2.74919, 0.4, -1.23334e-13, 1.7746, 0.225403, -0.709839, 2.74919, 0.4}, {0.509839, 0.0254033, 0.509839, 0.109839, -0.109839, 1.5746, -0.0254033, -0.509839, 0.509839, 0.104113, -0.104113, 0.104113, 1.5746, -0.109839, 0.109839, 3.30411, -3.30411, 3.30411, 0.109839, -1.5746, 0.109839, 0.509839, -0.509839, -0.0254033, -0.619677, -0.0901613, -0.709839, 0.0901613, 0.619677, -0.709839, -0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.0787093, -0.0901613, -0.709839, -0.0901613, -0.619677, 0.709839, -0.709839, -4.87871, 0.0901613, 0.709839, -0.619677, -0.0901613, 0.0901613, -0.0787093, -4.87871, -0.709839, 0.709839, 0.709839, 4.87871, 0.709839, -0.619677, 0.709839, 0.0901613, -0.709839, 0.619677, 0.0901613}, {0.0254033, 0.2, 1.5746, -0.374597, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, 0.0254033, -0.2, 1.5746, -1.1746, -0.864758, 1.1746, -1.5746, 0.2, -0.0254033, -1.5746, -0.2, -0.0254033, -1.1746, 0.864758, 1.1746, 0.349193, -0.0901613, -0.4, 0.225403, 0, -0.225403, 0.349193, 0.0901613, -0.4, -0.225403, 0, -1.7746, -0.4, -0.709839, -2.74919, 0.4, -0.0901613, -0.349193, 0.4, 0.0901613, -0.349193, -0.4, 0.709839, -2.74919, 2.74919, -0.709839, 0.4, 1.7746, 0, 0.225403, 2.74919, 0.709839, 0.4, -1.7746, 0, 1.7746}, {0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, 0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, 3.91638e-14, -0.225403, -1, 0.225403, 0, -1, -3.91638e-14, 0.225403, -1, -0.225403, 0, -1, -0.4, -0.4, -1.54919, 0.4, -0.4, -1.54919, 0.4, 0.4, -1.54919, -0.4, 0.4, -1.54919, 3.08336e-13, -1.7746, 1, 1.7746, 0, 1, -3.08336e-13, 1.7746, 1, -1.7746, 0, 1}, {0.374597, 0.064758, 0.374597, -0.0254033, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, 0.374597, -0.064758, 0.374597, 1.5746, 0.2, -0.0254033, 1.1746, -0.864758, 1.1746, 1.1746, 0.864758, 1.1746, 1.5746, -0.2, -0.0254033, -0.349193, -0.0901613, -0.4, 0.225403, 0, -1.7746, -0.349193, 0.0901613, -0.4, -0.225403, 0, -0.225403, -0.4, -0.0901613, -0.349193, 0.4, -0.709839, -2.74919, 0.4, 0.709839, -2.74919, -0.4, 0.0901613, -0.349193, -2.74919, -0.709839, 0.4, 1.7746, 0, 1.7746, -2.74919, 0.709839, 0.4, -1.7746, 0, 0.225403}, {0.0254033, 0.509839, 0.509839, -0.104113, 0.104113, 0.104113, -0.509839, -0.0254033, 0.509839, -0.109839, 0.109839, 1.5746, -0.109839, 1.5746, 0.109839, -0.509839, 0.509839, -0.0254033, -1.5746, 0.109839, 0.109839, -3.30411, 3.30411, 3.30411, 0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.619677, 0.0901613, -0.709839, -0.0901613, -0.619677, -0.709839, -0.0901613, -0.709839, -0.619677, 0.0901613, -0.0901613, -0.0787093, 0.709839, 0.0901613, -0.619677, -0.709839, 0.709839, -4.87871, 0.619677, -0.709839, 0.0901613, 0.709839, -0.619677, 0.0901613, 4.87871, 0.709839, 0.709839, -0.709839, -4.87871, 0.709839}, {0.064758, 0.374597, 0.374597, -0.064758, 0.374597, 0.374597, -0.2, -0.0254033, 1.5746, 0.2, -0.0254033, 1.5746, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, -0.0254033, 0.864758, 1.1746, 1.1746, -0.864758, 1.1746, 1.1746, 1.56655e-14, -0.225403, -0.225403, 0.0901613, -0.349193, -0.4, -1.56655e-14, 0.225403, -1.7746, -0.0901613, -0.349193, -0.4, -0.0901613, -0.4, -0.349193, 0.0901613, -0.4, -0.349193, 0.709839, 0.4, -2.74919, -0.709839, 0.4, -2.74919, 1.23334e-13, -1.7746, 0.225403, 0.709839, -2.74919, 0.4, -1.23334e-13, 1.7746, 1.7746, -0.709839, -2.74919, 0.4}, {0.104113, 0.104113, 0.104113, -0.0254033, 0.509839, 0.509839, 0.109839, 0.109839, 1.5746, 0.509839, -0.0254033, 0.509839, 0.509839, 0.509839, -0.0254033, 0.109839, 1.5746, 0.109839, 3.30411, 3.30411, 3.30411, 1.5746, 0.109839, 0.109839, -0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.619677, -0.709839, -0.619677, 0.0901613, -0.709839, -0.0901613, -0.0787093, -0.0901613, -0.0901613, -0.0901613, -0.0787093, 0.0901613, -0.709839, -0.619677, 0.709839, 0.709839, -4.87871, -0.709839, 0.0901613, -0.619677, -0.619677, -0.709839, 0.0901613, 0.709839, -4.87871, 0.709839, -4.87871, 0.709839, 0.709839, -0.709839, -0.619677, 0.0901613}, {-3.30411, -3.30411, -3.30411, -1.5746, -0.109839, -0.109839, -0.509839, -0.509839, 0.0254033, -0.109839, -1.5746, -0.109839, -0.109839, -0.109839, -1.5746, -0.509839, 0.0254033, -0.509839, -0.104113, -0.104113, -0.104113, 0.0254033, -0.509839, -0.509839, 4.87871, -0.709839, -0.709839, 0.709839, 0.619677, -0.0901613, 0.619677, 0.709839, -0.0901613, -0.709839, 4.87871, -0.709839, -0.709839, -0.709839, 4.87871, 0.709839, -0.0901613, 0.619677, 0.0901613, 0.0901613, 0.0787093, -0.0901613, 0.709839, 0.619677, 0.619677, -0.0901613, 0.709839, 0.0901613, 0.0787093, 0.0901613, 0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.619677, 0.709839}, {-0.864758, -1.1746, -1.1746, 0.864758, -1.1746, -1.1746, -0.2, -1.5746, 0.0254033, 0.2, -1.5746, 0.0254033, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.5746, -0.064758, -0.374597, -0.374597, 0.064758, -0.374597, -0.374597, 2.46669e-13, -1.7746, -1.7746, 0.709839, 2.74919, -0.4, -1.07669e-13, 1.7746, -0.225403, -0.709839, 2.74919, -0.4, -0.709839, -0.4, 2.74919, 0.709839, -0.4, 2.74919, 0.0901613, 0.4, 0.349193, -0.0901613, 0.4, 0.349193, -1.07669e-13, -0.225403, 1.7746, 0.0901613, 0.349193, 0.4, -3.1331e-14, 0.225403, 0.225403, -0.0901613, 0.349193, 0.4}, {1.5746, -0.109839, -0.109839, 3.30411, -3.30411, -3.30411, 0.109839, -1.5746, -0.109839, 0.509839, -0.509839, 0.0254033, 0.509839, 0.0254033, -0.509839, 0.109839, -0.109839, -1.5746, -0.0254033, -0.509839, -0.509839, 0.104113, -0.104113, -0.104113, -4.87871, -0.709839, -0.709839, 0.709839, 4.87871, -0.709839, -0.619677, 0.709839, -0.0901613, -0.709839, 0.619677, -0.0901613, -0.709839, -0.0901613, 0.619677, 0.709839, -0.709839, 4.87871, 0.0901613, 0.709839, 0.619677, -0.0901613, 0.0901613, 0.0787093, -0.619677, -0.0901613, 0.709839, 0.0901613, 0.619677, 0.709839, -0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.0787093, 0.0901613}, {-1.1746, -0.864758, -1.1746, -1.5746, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.1746, 0.864758, -1.1746, 0.0254033, 0.2, -1.5746, -0.374597, 0.064758, -0.374597, -0.374597, -0.064758, -0.374597, 0.0254033, -0.2, -1.5746, 2.74919, -0.709839, -0.4, 1.7746, -1.98947e-15, -0.225403, 2.74919, 0.709839, -0.4, -1.7746, -1.56631e-14, -1.7746, -0.4, -0.709839, 2.74919, 0.4, -0.0901613, 0.349193, 0.4, 0.0901613, 0.349193, -0.4, 0.709839, 2.74919, 0.349193, -0.0901613, 0.4, 0.225403, 1.98947e-15, 0.225403, 0.349193, 0.0901613, 0.4, -0.225403, 1.56631e-14, 1.7746}, {0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, 0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, 3.47499e-13, -1.7746, -1, 1.7746, -3.91631e-14, -1, -2.69173e-13, 1.7746, -1, -1.7746, -3.91631e-14, -1, -0.4, -0.4, 1.54919, 0.4, -0.4, 1.54919, 0.4, 0.4, 1.54919, -0.4, 0.4, 1.54919, 6.89741e-19, -0.225403, 1, 0.225403, 3.91631e-14, 1, -7.83269e-14, 0.225403, 1, -0.225403, 3.91631e-14, 1}, {1.5746, 0.2, 0.0254033, 1.1746, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.5746, -0.2, 0.0254033, 0.374597, 0.064758, -0.374597, -0.0254033, 0.2, -1.5746, -0.0254033, -0.2, -1.5746, 0.374597, -0.064758, -0.374597, -2.74919, -0.709839, -0.4, 1.7746, -1.23334e-13, -1.7746, -2.74919, 0.709839, -0.4, -1.7746, -1.56655e-14, -0.225403, -0.4, -0.0901613, 0.349193, 0.4, -0.709839, 2.74919, 0.4, 0.709839, 2.74919, -0.4, 0.0901613, 0.349193, -0.349193, -0.0901613, 0.4, 0.225403, 1.23334e-13, 1.7746, -0.349193, 0.0901613, 0.4, -0.225403, 1.56655e-14, 0.225403}, {-0.109839, 1.5746, -0.109839, -0.509839, 0.509839, 0.0254033, -1.5746, 0.109839, -0.109839, -3.30411, 3.30411, -3.30411, 0.0254033, 0.509839, -0.509839, -0.104113, 0.104113, -0.104113, -0.509839, -0.0254033, -0.509839, -0.109839, 0.109839, -1.5746, 0.619677, -0.709839, -0.0901613, 0.709839, -0.619677, -0.0901613, 4.87871, 0.709839, -0.709839, -0.709839, -4.87871, -0.709839, -0.0901613, -0.709839, 0.619677, 0.0901613, -0.0901613, 0.0787093, 0.709839, 0.0901613, 0.619677, -0.709839, 0.709839, 4.87871, 0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.0787093, 0.0901613, 0.619677, 0.0901613, 0.709839, -0.0901613, -0.619677, 0.709839}, {0.2, 1.5746, 0.0254033, -0.2, 1.5746, 0.0254033, 0.864758, 1.1746, -1.1746, -0.864758, 1.1746, -1.1746, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, -0.374597, -0.2, -0.0254033, -1.5746, 0.2, -0.0254033, -1.5746, 1.25324e-13, -1.7746, -0.225403, 0.709839, -2.74919, -0.4, -1.07671e-13, 1.7746, -1.7746, -0.709839, -2.74919, -0.4, -0.0901613, -0.4, 0.349193, 0.0901613, -0.4, 0.349193, 0.709839, 0.4, 2.74919, -0.709839, 0.4, 2.74919, 1.36761e-14, -0.225403, 0.225403, 0.0901613, -0.349193, 0.4, -3.13286e-14, 0.225403, 1.7746, -0.0901613, -0.349193, 0.4}, {0.509839, 0.509839, 0.0254033, 0.109839, 1.5746, -0.109839, 3.30411, 3.30411, -3.30411, 1.5746, 0.109839, -0.109839, 0.104113, 0.104113, -0.104113, -0.0254033, 0.509839, -0.509839, 0.109839, 0.109839, -1.5746, 0.509839, -0.0254033, -0.509839, -0.619677, -0.709839, -0.0901613, 0.709839, -4.87871, -0.709839, -4.87871, 0.709839, -0.709839, -0.709839, -0.619677, -0.0901613, -0.0901613, -0.0901613, 0.0787093, 0.0901613, -0.709839, 0.619677, 0.709839, 0.709839, 4.87871, -0.709839, 0.0901613, 0.619677, -0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.619677, 0.709839, -0.619677, 0.0901613, 0.709839, -0.0901613, -0.0787093, 0.0901613}, {-1.1746, -1.1746, -0.864758, -1.5746, 0.0254033, 0.2, -0.374597, -0.374597, 0.064758, 0.0254033, -1.5746, 0.2, -1.1746, -1.1746, 0.864758, -1.5746, 0.0254033, -0.2, -0.374597, -0.374597, -0.064758, 0.0254033, -1.5746, -0.2, 2.74919, -0.4, -0.709839, 0.4, 0.349193, -0.0901613, 0.349193, 0.4, -0.0901613, -0.4, 2.74919, -0.709839, -1.7746, -1.7746, -1.56631e-14, 1.7746, -0.225403, -1.98947e-15, 0.225403, 0.225403, 1.98947e-15, -0.225403, 1.7746, 1.56631e-14, 2.74919, -0.4, 0.709839, 0.4, 0.349193, 0.0901613, 0.349193, 0.4, 0.0901613, -0.4, 2.74919, 0.709839}, {0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, 0.2, -1.2746, 0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, -0.2, -0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, 3.47527e-13, -1, -1.7746, 0.4, 1.54919, -0.4, -2.70658e-17, 1, -0.225403, -0.4, 1.54919, -0.4, -1.7746, -1, -3.93019e-14, 1.7746, -1, -3.93019e-14, 0.225403, 1, 3.93019e-14, -0.225403, 1, 3.93019e-14, -2.69145e-13, -1, 1.7746, 0.4, 1.54919, 0.4, -7.83547e-14, 1, 0.225403, -0.4, 1.54919, 0.4}, {1.5746, 0.0254033, 0.2, 1.1746, -1.1746, -0.864758, -0.0254033, -1.5746, 0.2, 0.374597, -0.374597, 0.064758, 1.5746, 0.0254033, -0.2, 1.1746, -1.1746, 0.864758, -0.0254033, -1.5746, -0.2, 0.374597, -0.374597, -0.064758, -2.74919, -0.4, -0.709839, 0.4, 2.74919, -0.709839, -0.349193, 0.4, -0.0901613, -0.4, 0.349193, -0.0901613, -1.7746, -0.225403, -1.58008e-14, 1.7746, -1.7746, -1.23088e-13, 0.225403, 1.7746, 1.23255e-13, -0.225403, 0.225403, 1.56342e-14, -2.74919, -0.4, 0.709839, 0.4, 2.74919, 0.709839, -0.349193, 0.4, 0.0901613, -0.4, 0.349193, 0.0901613}, {-0.274597, 0.2, 0.2, -1.2746, 0.2, 0.2, -1.2746, -0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -0.2, -0.2, -0.274597, -0.2, -0.2, 1.54919, -0.4, -0.4, 1, -4.97993e-15, -0.225403, 1.54919, 0.4, -0.4, -1, -3.92069e-14, -1.7746, -1, -1.7746, -3.92069e-14, 1, -0.225403, -4.97993e-15, 1, 0.225403, 4.97993e-15, -1, 1.7746, 3.92069e-14, 1.54919, -0.4, 0.4, 1, 4.97993e-15, 0.225403, 1.54919, 0.4, 0.4, -1, 3.92069e-14, 1.7746}, {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, 1.95816e-13, -1, -1, 1, -9.79217e-14, -1, -2.77556e-17, 1, -1, -1, -9.79217e-14, -1, -1, -1, -9.79217e-14, 1, -1, -9.79217e-14, 1, 1, 9.79217e-14, -1, 1, 9.79217e-14, 2.77556e-17, -1, 1, 1, 9.79217e-14, 1, -1.95816e-13, 1, 1, -1, 9.79217e-14, 1}, {1.2746, 0.2, 0.2, 0.274597, 0.2, 0.2, 0.274597, -0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -0.2, -0.2, 1.2746, -0.2, -0.2, -1.54919, -0.4, -0.4, 1, -3.08336e-13, -1.7746, -1.54919, 0.4, -0.4, -1, -3.91638e-14, -0.225403, -1, -0.225403, -3.91638e-14, 1, -1.7746, -3.08336e-13, 1, 1.7746, 3.08336e-13, -1, 0.225403, 3.91638e-14, -1.54919, -0.4, 0.4, 1, 3.08336e-13, 1.7746, -1.54919, 0.4, 0.4, -1, 3.91638e-14, 0.225403}, {0.0254033, 1.5746, 0.2, -0.374597, 0.374597, 0.064758, -1.5746, -0.0254033, 0.2, -1.1746, 1.1746, -0.864758, 0.0254033, 1.5746, -0.2, -0.374597, 0.374597, -0.064758, -1.5746, -0.0254033, -0.2, -1.1746, 1.1746, 0.864758, 0.349193, -0.4, -0.0901613, 0.4, -0.349193, -0.0901613, 2.74919, 0.4, -0.709839, -0.4, -2.74919, -0.709839, -0.225403, -1.7746, -1.56631e-14, 0.225403, -0.225403, -1.98947e-15, 1.7746, 0.225403, 1.98947e-15, -1.7746, 1.7746, 1.56631e-14, 0.349193, -0.4, 0.0901613, 0.4, -0.349193, 0.0901613, 2.74919, 0.4, 0.709839, -0.4, -2.74919, 0.709839}, {0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, 0.2, 0.274597, 0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, -0.2, -0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, 4.41431e-14, -1, -0.225403, 0.4, -1.54919, -0.4, 4.38246e-17, 1, -1.7746, -0.4, -1.54919, -0.4, -0.225403, -1, -3.91909e-14, 0.225403, -1, -3.91909e-14, 1.7746, 1, 3.91909e-14, -1.7746, 1, 3.91909e-14, 3.41832e-14, -1, 0.225403, 0.4, -1.54919, 0.4, -7.83701e-14, 1, 1.7746, -0.4, -1.54919, 0.4}, {0.374597, 0.374597, 0.064758, -0.0254033, 1.5746, 0.2, 1.1746, 1.1746, -0.864758, 1.5746, -0.0254033, 0.2, 0.374597, 0.374597, -0.064758, -0.0254033, 1.5746, -0.2, 1.1746, 1.1746, 0.864758, 1.5746, -0.0254033, -0.2, -0.349193, -0.4, -0.0901613, 0.4, -2.74919, -0.709839, -2.74919, 0.4, -0.709839, -0.4, -0.349193, -0.0901613, -0.225403, -0.225403, -1.56405e-14, 0.225403, -1.7746, -1.23304e-13, 1.7746, 1.7746, 1.23137e-13, -1.7746, 0.225403, 1.5807e-14, -0.349193, -0.4, 0.0901613, 0.4, -2.74919, 0.709839, -2.74919, 0.4, 0.709839, -0.4, -0.349193, 0.0901613}, {-0.109839, -0.109839, 1.5746, -0.509839, 0.0254033, 0.509839, -0.104113, -0.104113, 0.104113, 0.0254033, -0.509839, 0.509839, -3.30411, -3.30411, 3.30411, -1.5746, -0.109839, 0.109839, -0.509839, -0.509839, -0.0254033, -0.109839, -1.5746, 0.109839, 0.619677, -0.0901613, -0.709839, 0.0901613, 0.0787093, -0.0901613, 0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.619677, -0.709839, -0.709839, -0.709839, -4.87871, 0.709839, -0.0901613, -0.619677, 0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.709839, -0.619677, 4.87871, -0.709839, 0.709839, 0.709839, 0.619677, 0.0901613, 0.619677, 0.709839, 0.0901613, -0.709839, 4.87871, 0.709839}, {0.2, 0.0254033, 1.5746, -0.2, 0.0254033, 1.5746, -0.064758, -0.374597, 0.374597, 0.064758, -0.374597, 0.374597, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.1746, -0.2, -1.5746, -0.0254033, 0.2, -1.5746, -0.0254033, 1.25324e-13, -0.225403, -1.7746, 0.0901613, 0.349193, -0.4, 1.36761e-14, 0.225403, -0.225403, -0.0901613, 0.349193, -0.4, -0.709839, -0.4, -2.74919, 0.709839, -0.4, -2.74919, 0.0901613, 0.4, -0.349193, -0.0901613, 0.4, -0.349193, -1.07671e-13, -1.7746, 1.7746, 0.709839, 2.74919, 0.4, -3.13286e-14, 1.7746, 0.225403, -0.709839, 2.74919, 0.4}, {0.509839, 0.0254033, 0.509839, 0.109839, -0.109839, 1.5746, -0.0254033, -0.509839, 0.509839, 0.104113, -0.104113, 0.104113, 1.5746, -0.109839, 0.109839, 3.30411, -3.30411, 3.30411, 0.109839, -1.5746, 0.109839, 0.509839, -0.509839, -0.0254033, -0.619677, -0.0901613, -0.709839, 0.0901613, 0.619677, -0.709839, -0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.0787093, -0.0901613, -0.709839, -0.0901613, -0.619677, 0.709839, -0.709839, -4.87871, 0.0901613, 0.709839, -0.619677, -0.0901613, 0.0901613, -0.0787093, -4.87871, -0.709839, 0.709839, 0.709839, 4.87871, 0.709839, -0.619677, 0.709839, 0.0901613, -0.709839, 0.619677, 0.0901613}, {0.0254033, 0.2, 1.5746, -0.374597, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, 0.0254033, -0.2, 1.5746, -1.1746, -0.864758, 1.1746, -1.5746, 0.2, -0.0254033, -1.5746, -0.2, -0.0254033, -1.1746, 0.864758, 1.1746, 0.349193, -0.0901613, -0.4, 0.225403, -1.98322e-15, -0.225403, 0.349193, 0.0901613, -0.4, -0.225403, -1.56138e-14, -1.7746, -0.4, -0.709839, -2.74919, 0.4, -0.0901613, -0.349193, 0.4, 0.0901613, -0.349193, -0.4, 0.709839, -2.74919, 2.74919, -0.709839, 0.4, 1.7746, 1.98322e-15, 0.225403, 2.74919, 0.709839, 0.4, -1.7746, 1.56138e-14, 1.7746}, {0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, 0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, 4.41431e-14, -0.225403, -1, 0.225403, -3.91631e-14, -1, 3.41832e-14, 0.225403, -1, -0.225403, -3.91631e-14, -1, -0.4, -0.4, -1.54919, 0.4, -0.4, -1.54919, 0.4, 0.4, -1.54919, -0.4, 0.4, -1.54919, 4.38246e-17, -1.7746, 1, 1.7746, 3.91631e-14, 1, -7.83701e-14, 1.7746, 1, -1.7746, 3.91631e-14, 1}, {0.374597, 0.064758, 0.374597, -0.0254033, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, 0.374597, -0.064758, 0.374597, 1.5746, 0.2, -0.0254033, 1.1746, -0.864758, 1.1746, 1.1746, 0.864758, 1.1746, 1.5746, -0.2, -0.0254033, -0.349193, -0.0901613, -0.4, 0.225403, -1.23334e-13, -1.7746, -0.349193, 0.0901613, -0.4, -0.225403, -1.56655e-14, -0.225403, -0.4, -0.0901613, -0.349193, 0.4, -0.709839, -2.74919, 0.4, 0.709839, -2.74919, -0.4, 0.0901613, -0.349193, -2.74919, -0.709839, 0.4, 1.7746, 1.23334e-13, 1.7746, -2.74919, 0.709839, 0.4, -1.7746, 1.56655e-14, 0.225403}, {0.0254033, 0.509839, 0.509839, -0.104113, 0.104113, 0.104113, -0.509839, -0.0254033, 0.509839, -0.109839, 0.109839, 1.5746, -0.109839, 1.5746, 0.109839, -0.509839, 0.509839, -0.0254033, -1.5746, 0.109839, 0.109839, -3.30411, 3.30411, 3.30411, 0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.619677, 0.0901613, -0.709839, -0.0901613, -0.619677, -0.709839, -0.0901613, -0.709839, -0.619677, 0.0901613, -0.0901613, -0.0787093, 0.709839, 0.0901613, -0.619677, -0.709839, 0.709839, -4.87871, 0.619677, -0.709839, 0.0901613, 0.709839, -0.619677, 0.0901613, 4.87871, 0.709839, 0.709839, -0.709839, -4.87871, 0.709839}, {0.064758, 0.374597, 0.374597, -0.064758, 0.374597, 0.374597, -0.2, -0.0254033, 1.5746, 0.2, -0.0254033, 1.5746, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, -0.0254033, 0.864758, 1.1746, 1.1746, -0.864758, 1.1746, 1.1746, 3.97894e-15, -0.225403, -0.225403, 0.0901613, -0.349193, -0.4, 1.36736e-14, 0.225403, -1.7746, -0.0901613, -0.349193, -0.4, -0.0901613, -0.4, -0.349193, 0.0901613, -0.4, -0.349193, 0.709839, 0.4, -2.74919, -0.709839, 0.4, -2.74919, 1.36736e-14, -1.7746, 0.225403, 0.709839, -2.74919, 0.4, -3.13261e-14, 1.7746, 1.7746, -0.709839, -2.74919, 0.4}, {0.104113, 0.104113, 0.104113, -0.0254033, 0.509839, 0.509839, 0.109839, 0.109839, 1.5746, 0.509839, -0.0254033, 0.509839, 0.509839, 0.509839, -0.0254033, 0.109839, 1.5746, 0.109839, 3.30411, 3.30411, 3.30411, 1.5746, 0.109839, 0.109839, -0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.619677, -0.709839, -0.619677, 0.0901613, -0.709839, -0.0901613, -0.0787093, -0.0901613, -0.0901613, -0.0901613, -0.0787093, 0.0901613, -0.709839, -0.619677, 0.709839, 0.709839, -4.87871, -0.709839, 0.0901613, -0.619677, -0.619677, -0.709839, 0.0901613, 0.709839, -4.87871, 0.709839, -4.87871, 0.709839, 0.709839, -0.709839, -0.619677, 0.0901613}, {-3.30411, -3.30411, -3.30411, -1.5746, -0.109839, -0.109839, -0.509839, -0.509839, 0.0254033, -0.109839, -1.5746, -0.109839, -0.109839, -0.109839, -1.5746, -0.509839, 0.0254033, -0.509839, -0.104113, -0.104113, -0.104113, 0.0254033, -0.509839, -0.509839, 4.87871, -0.709839, -0.709839, 0.709839, 0.619677, -0.0901613, 0.619677, 0.709839, -0.0901613, -0.709839, 4.87871, -0.709839, -0.709839, -0.709839, 4.87871, 0.709839, -0.0901613, 0.619677, 0.0901613, 0.0901613, 0.0787093, -0.0901613, 0.709839, 0.619677, 0.619677, -0.0901613, 0.709839, 0.0901613, 0.0787093, 0.0901613, 0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.619677, 0.709839}, {-0.864758, -1.1746, -1.1746, 0.864758, -1.1746, -1.1746, -0.2, -1.5746, 0.0254033, 0.2, -1.5746, 0.0254033, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.5746, -0.064758, -0.374597, -0.374597, 0.064758, -0.374597, -0.374597, 1.56631e-14, -1.7746, -1.7746, 0.709839, 2.74919, -0.4, -1.56631e-14, 1.7746, -0.225403, -0.709839, 2.74919, -0.4, -0.709839, -0.4, 2.74919, 0.709839, -0.4, 2.74919, 0.0901613, 0.4, 0.349193, -0.0901613, 0.4, 0.349193, 1.98947e-15, -0.225403, 1.7746, 0.0901613, 0.349193, 0.4, -1.98947e-15, 0.225403, 0.225403, -0.0901613, 0.349193, 0.4}, {1.5746, -0.109839, -0.109839, 3.30411, -3.30411, -3.30411, 0.109839, -1.5746, -0.109839, 0.509839, -0.509839, 0.0254033, 0.509839, 0.0254033, -0.509839, 0.109839, -0.109839, -1.5746, -0.0254033, -0.509839, -0.509839, 0.104113, -0.104113, -0.104113, -4.87871, -0.709839, -0.709839, 0.709839, 4.87871, -0.709839, -0.619677, 0.709839, -0.0901613, -0.709839, 0.619677, -0.0901613, -0.709839, -0.0901613, 0.619677, 0.709839, -0.709839, 4.87871, 0.0901613, 0.709839, 0.619677, -0.0901613, 0.0901613, 0.0787093, -0.619677, -0.0901613, 0.709839, 0.0901613, 0.619677, 0.709839, -0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.0787093, 0.0901613}, {-1.1746, -0.864758, -1.1746, -1.5746, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.1746, 0.864758, -1.1746, 0.0254033, 0.2, -1.5746, -0.374597, 0.064758, -0.374597, -0.374597, -0.064758, -0.374597, 0.0254033, -0.2, -1.5746, 2.74919, -0.709839, -0.4, 1.7746, -6.2562e-18, -0.225403, 2.74919, 0.709839, -0.4, -1.7746, -4.9255e-17, -1.7746, -0.4, -0.709839, 2.74919, 0.4, -0.0901613, 0.349193, 0.4, 0.0901613, 0.349193, -0.4, 0.709839, 2.74919, 0.349193, -0.0901613, 0.4, 0.225403, 6.2562e-18, 0.225403, 0.349193, 0.0901613, 0.4, -0.225403, 4.9255e-17, 1.7746}, {0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, 0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, 3.91577e-14, -1.7746, -1, 1.7746, 0, -1, -3.91577e-14, 1.7746, -1, -1.7746, 0, -1, -0.4, -0.4, 1.54919, 0.4, -0.4, 1.54919, 0.4, 0.4, 1.54919, -0.4, 0.4, 1.54919, 4.97368e-15, -0.225403, 1, 0.225403, 0, 1, -4.97368e-15, 0.225403, 1, -0.225403, 0, 1}, {1.5746, 0.2, 0.0254033, 1.1746, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.5746, -0.2, 0.0254033, 0.374597, 0.064758, -0.374597, -0.0254033, 0.2, -1.5746, -0.0254033, -0.2, -1.5746, 0.374597, -0.064758, -0.374597, -2.74919, -0.709839, -0.4, 1.7746, 0, -1.7746, -2.74919, 0.709839, -0.4, -1.7746, 0, -0.225403, -0.4, -0.0901613, 0.349193, 0.4, -0.709839, 2.74919, 0.4, 0.709839, 2.74919, -0.4, 0.0901613, 0.349193, -0.349193, -0.0901613, 0.4, 0.225403, 0, 1.7746, -0.349193, 0.0901613, 0.4, -0.225403, 0, 0.225403}, {-0.109839, 1.5746, -0.109839, -0.509839, 0.509839, 0.0254033, -1.5746, 0.109839, -0.109839, -3.30411, 3.30411, -3.30411, 0.0254033, 0.509839, -0.509839, -0.104113, 0.104113, -0.104113, -0.509839, -0.0254033, -0.509839, -0.109839, 0.109839, -1.5746, 0.619677, -0.709839, -0.0901613, 0.709839, -0.619677, -0.0901613, 4.87871, 0.709839, -0.709839, -0.709839, -4.87871, -0.709839, -0.0901613, -0.709839, 0.619677, 0.0901613, -0.0901613, 0.0787093, 0.709839, 0.0901613, 0.619677, -0.709839, 0.709839, 4.87871, 0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.0787093, 0.0901613, 0.619677, 0.0901613, 0.709839, -0.0901613, -0.619677, 0.709839}, {0.2, 1.5746, 0.0254033, -0.2, 1.5746, 0.0254033, 0.864758, 1.1746, -1.1746, -0.864758, 1.1746, -1.1746, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, -0.374597, -0.2, -0.0254033, -1.5746, 0.2, -0.0254033, -1.5746, 1.56631e-14, -1.7746, -0.225403, 0.709839, -2.74919, -0.4, -1.56631e-14, 1.7746, -1.7746, -0.709839, -2.74919, -0.4, -0.0901613, -0.4, 0.349193, 0.0901613, -0.4, 0.349193, 0.709839, 0.4, 2.74919, -0.709839, 0.4, 2.74919, 1.98947e-15, -0.225403, 0.225403, 0.0901613, -0.349193, 0.4, -1.98947e-15, 0.225403, 1.7746, -0.0901613, -0.349193, 0.4}, {0.509839, 0.509839, 0.0254033, 0.109839, 1.5746, -0.109839, 3.30411, 3.30411, -3.30411, 1.5746, 0.109839, -0.109839, 0.104113, 0.104113, -0.104113, -0.0254033, 0.509839, -0.509839, 0.109839, 0.109839, -1.5746, 0.509839, -0.0254033, -0.509839, -0.619677, -0.709839, -0.0901613, 0.709839, -4.87871, -0.709839, -4.87871, 0.709839, -0.709839, -0.709839, -0.619677, -0.0901613, -0.0901613, -0.0901613, 0.0787093, 0.0901613, -0.709839, 0.619677, 0.709839, 0.709839, 4.87871, -0.709839, 0.0901613, 0.619677, -0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.619677, 0.709839, -0.619677, 0.0901613, 0.709839, -0.0901613, -0.0787093, 0.0901613}, {-1.1746, -1.1746, -0.864758, -1.5746, 0.0254033, 0.2, -0.374597, -0.374597, 0.064758, 0.0254033, -1.5746, 0.2, -1.1746, -1.1746, 0.864758, -1.5746, 0.0254033, -0.2, -0.374597, -0.374597, -0.064758, 0.0254033, -1.5746, -0.2, 2.74919, -0.4, -0.709839, 0.4, 0.349193, -0.0901613, 0.349193, 0.4, -0.0901613, -0.4, 2.74919, -0.709839, -1.7746, -1.7746, 1.55646e-14, 1.7746, -0.225403, 1.97696e-15, 0.225403, 0.225403, -1.97696e-15, -0.225403, 1.7746, -1.55646e-14, 2.74919, -0.4, 0.709839, 0.4, 0.349193, 0.0901613, 0.349193, 0.4, 0.0901613, -0.4, 2.74919, 0.709839}, {0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, 0.2, -1.2746, 0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, -0.2, -0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, 3.91631e-14, -1, -1.7746, 0.4, 1.54919, -0.4, -3.91631e-14, 1, -0.225403, -0.4, 1.54919, -0.4, -1.7746, -1, 3.91631e-14, 1.7746, -1, 3.91631e-14, 0.225403, 1, -3.91631e-14, -0.225403, 1, -3.91631e-14, 3.91631e-14, -1, 1.7746, 0.4, 1.54919, 0.4, -3.91631e-14, 1, 0.225403, -0.4, 1.54919, 0.4}, {1.5746, 0.0254033, 0.2, 1.1746, -1.1746, -0.864758, -0.0254033, -1.5746, 0.2, 0.374597, -0.374597, 0.064758, 1.5746, 0.0254033, -0.2, 1.1746, -1.1746, 0.864758, -0.0254033, -1.5746, -0.2, 0.374597, -0.374597, -0.064758, -2.74919, -0.4, -0.709839, 0.4, 2.74919, -0.709839, -0.349193, 0.4, -0.0901613, -0.4, 0.349193, -0.0901613, -1.7746, -0.225403, 1.55303e-14, 1.7746, -1.7746, 1.23581e-13, 0.225403, 1.7746, -1.23414e-13, -0.225403, 0.225403, -1.56968e-14, -2.74919, -0.4, 0.709839, 0.4, 2.74919, 0.709839, -0.349193, 0.4, 0.0901613, -0.4, 0.349193, 0.0901613}, {-0.274597, 0.2, 0.2, -1.2746, 0.2, 0.2, -1.2746, -0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -0.2, -0.2, -0.274597, -0.2, -0.2, 1.54919, -0.4, -0.4, 1, 0, -0.225403, 1.54919, 0.4, -0.4, -1, 0, -1.7746, -1, -1.7746, 3.92069e-14, 1, -0.225403, 4.97993e-15, 1, 0.225403, -4.97993e-15, -1, 1.7746, -3.92069e-14, 1.54919, -0.4, 0.4, 1, 0, 0.225403, 1.54919, 0.4, 0.4, -1, 0, 1.7746}, {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, 9.78939e-14, -1, -1, 1, 0, -1, -9.78939e-14, 1, -1, -1, 0, -1, -1, -1, 9.79217e-14, 1, -1, 9.79217e-14, 1, 1, -9.79217e-14, -1, 1, -9.79217e-14, 9.78939e-14, -1, 1, 1, 0, 1, -9.78939e-14, 1, 1, -1, 0, 1}, {1.2746, 0.2, 0.2, 0.274597, 0.2, 0.2, 0.274597, -0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -0.2, -0.2, 1.2746, -0.2, -0.2, -1.54919, -0.4, -0.4, 1, 0, -1.7746, -1.54919, 0.4, -0.4, -1, 0, -0.225403, -1, -0.225403, 3.91638e-14, 1, -1.7746, 3.08336e-13, 1, 1.7746, -3.08336e-13, -1, 0.225403, -3.91638e-14, -1.54919, -0.4, 0.4, 1, 0, 1.7746, -1.54919, 0.4, 0.4, -1, 0, 0.225403}, {0.0254033, 1.5746, 0.2, -0.374597, 0.374597, 0.064758, -1.5746, -0.0254033, 0.2, -1.1746, 1.1746, -0.864758, 0.0254033, 1.5746, -0.2, -0.374597, 0.374597, -0.064758, -1.5746, -0.0254033, -0.2, -1.1746, 1.1746, 0.864758, 0.349193, -0.4, -0.0901613, 0.4, -0.349193, -0.0901613, 2.74919, 0.4, -0.709839, -0.4, -2.74919, -0.709839, -0.225403, -1.7746, 1.56631e-14, 0.225403, -0.225403, 1.98947e-15, 1.7746, 0.225403, -1.98947e-15, -1.7746, 1.7746, -1.56631e-14, 0.349193, -0.4, 0.0901613, 0.4, -0.349193, 0.0901613, 2.74919, 0.4, 0.709839, -0.4, -2.74919, 0.709839}, {0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, 0.2, 0.274597, 0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, -0.2, -0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, 3.91631e-14, -1, -0.225403, 0.4, -1.54919, -0.4, -3.91631e-14, 1, -1.7746, -0.4, -1.54919, -0.4, -0.225403, -1, 3.91631e-14, 0.225403, -1, 3.91631e-14, 1.7746, 1, -3.91631e-14, -1.7746, 1, -3.91631e-14, 3.91631e-14, -1, 0.225403, 0.4, -1.54919, 0.4, -3.91631e-14, 1, 1.7746, -0.4, -1.54919, 0.4}, {0.374597, 0.374597, 0.064758, -0.0254033, 1.5746, 0.2, 1.1746, 1.1746, -0.864758, 1.5746, -0.0254033, 0.2, 0.374597, 0.374597, -0.064758, -0.0254033, 1.5746, -0.2, 1.1746, 1.1746, 0.864758, 1.5746, -0.0254033, -0.2, -0.349193, -0.4, -0.0901613, 0.4, -2.74919, -0.709839, -2.74919, 0.4, -0.709839, -0.4, -0.349193, -0.0901613, -0.225403, -0.225403, 1.56905e-14, 0.225403, -1.7746, 1.23365e-13, 1.7746, 1.7746, -1.23531e-13, -1.7746, 0.225403, -1.5524e-14, -0.349193, -0.4, 0.0901613, 0.4, -2.74919, 0.709839, -2.74919, 0.4, 0.709839, -0.4, -0.349193, 0.0901613}, {-0.109839, -0.109839, 1.5746, -0.509839, 0.0254033, 0.509839, -0.104113, -0.104113, 0.104113, 0.0254033, -0.509839, 0.509839, -3.30411, -3.30411, 3.30411, -1.5746, -0.109839, 0.109839, -0.509839, -0.509839, -0.0254033, -0.109839, -1.5746, 0.109839, 0.619677, -0.0901613, -0.709839, 0.0901613, 0.0787093, -0.0901613, 0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.619677, -0.709839, -0.709839, -0.709839, -4.87871, 0.709839, -0.0901613, -0.619677, 0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.709839, -0.619677, 4.87871, -0.709839, 0.709839, 0.709839, 0.619677, 0.0901613, 0.619677, 0.709839, 0.0901613, -0.709839, 4.87871, 0.709839}, {0.2, 0.0254033, 1.5746, -0.2, 0.0254033, 1.5746, -0.064758, -0.374597, 0.374597, 0.064758, -0.374597, 0.374597, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.1746, -0.2, -1.5746, -0.0254033, 0.2, -1.5746, -0.0254033, 1.56655e-14, -0.225403, -1.7746, 0.0901613, 0.349193, -0.4, -1.56655e-14, 0.225403, -0.225403, -0.0901613, 0.349193, -0.4, -0.709839, -0.4, -2.74919, 0.709839, -0.4, -2.74919, 0.0901613, 0.4, -0.349193, -0.0901613, 0.4, -0.349193, 1.23334e-13, -1.7746, 1.7746, 0.709839, 2.74919, 0.4, -1.23334e-13, 1.7746, 0.225403, -0.709839, 2.74919, 0.4}, {0.509839, 0.0254033, 0.509839, 0.109839, -0.109839, 1.5746, -0.0254033, -0.509839, 0.509839, 0.104113, -0.104113, 0.104113, 1.5746, -0.109839, 0.109839, 3.30411, -3.30411, 3.30411, 0.109839, -1.5746, 0.109839, 0.509839, -0.509839, -0.0254033, -0.619677, -0.0901613, -0.709839, 0.0901613, 0.619677, -0.709839, -0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.0787093, -0.0901613, -0.709839, -0.0901613, -0.619677, 0.709839, -0.709839, -4.87871, 0.0901613, 0.709839, -0.619677, -0.0901613, 0.0901613, -0.0787093, -4.87871, -0.709839, 0.709839, 0.709839, 4.87871, 0.709839, -0.619677, 0.709839, 0.0901613, -0.709839, 0.619677, 0.0901613}, {0.0254033, 0.2, 1.5746, -0.374597, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, 0.0254033, -0.2, 1.5746, -1.1746, -0.864758, 1.1746, -1.5746, 0.2, -0.0254033, -1.5746, -0.2, -0.0254033, -1.1746, 0.864758, 1.1746, 0.349193, -0.0901613, -0.4, 0.225403, 0, -0.225403, 0.349193, 0.0901613, -0.4, -0.225403, 0, -1.7746, -0.4, -0.709839, -2.74919, 0.4, -0.0901613, -0.349193, 0.4, 0.0901613, -0.349193, -0.4, 0.709839, -2.74919, 2.74919, -0.709839, 0.4, 1.7746, 0, 0.225403, 2.74919, 0.709839, 0.4, -1.7746, 0, 1.7746}, {0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, 0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, 3.91638e-14, -0.225403, -1, 0.225403, 0, -1, -3.91638e-14, 0.225403, -1, -0.225403, 0, -1, -0.4, -0.4, -1.54919, 0.4, -0.4, -1.54919, 0.4, 0.4, -1.54919, -0.4, 0.4, -1.54919, 3.08336e-13, -1.7746, 1, 1.7746, 0, 1, -3.08336e-13, 1.7746, 1, -1.7746, 0, 1}, {0.374597, 0.064758, 0.374597, -0.0254033, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, 0.374597, -0.064758, 0.374597, 1.5746, 0.2, -0.0254033, 1.1746, -0.864758, 1.1746, 1.1746, 0.864758, 1.1746, 1.5746, -0.2, -0.0254033, -0.349193, -0.0901613, -0.4, 0.225403, 0, -1.7746, -0.349193, 0.0901613, -0.4, -0.225403, 0, -0.225403, -0.4, -0.0901613, -0.349193, 0.4, -0.709839, -2.74919, 0.4, 0.709839, -2.74919, -0.4, 0.0901613, -0.349193, -2.74919, -0.709839, 0.4, 1.7746, 0, 1.7746, -2.74919, 0.709839, 0.4, -1.7746, 0, 0.225403}, {0.0254033, 0.509839, 0.509839, -0.104113, 0.104113, 0.104113, -0.509839, -0.0254033, 0.509839, -0.109839, 0.109839, 1.5746, -0.109839, 1.5746, 0.109839, -0.509839, 0.509839, -0.0254033, -1.5746, 0.109839, 0.109839, -3.30411, 3.30411, 3.30411, 0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.619677, 0.0901613, -0.709839, -0.0901613, -0.619677, -0.709839, -0.0901613, -0.709839, -0.619677, 0.0901613, -0.0901613, -0.0787093, 0.709839, 0.0901613, -0.619677, -0.709839, 0.709839, -4.87871, 0.619677, -0.709839, 0.0901613, 0.709839, -0.619677, 0.0901613, 4.87871, 0.709839, 0.709839, -0.709839, -4.87871, 0.709839}, {0.064758, 0.374597, 0.374597, -0.064758, 0.374597, 0.374597, -0.2, -0.0254033, 1.5746, 0.2, -0.0254033, 1.5746, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, -0.0254033, 0.864758, 1.1746, 1.1746, -0.864758, 1.1746, 1.1746, 1.56655e-14, -0.225403, -0.225403, 0.0901613, -0.349193, -0.4, -1.56655e-14, 0.225403, -1.7746, -0.0901613, -0.349193, -0.4, -0.0901613, -0.4, -0.349193, 0.0901613, -0.4, -0.349193, 0.709839, 0.4, -2.74919, -0.709839, 0.4, -2.74919, 1.23334e-13, -1.7746, 0.225403, 0.709839, -2.74919, 0.4, -1.23334e-13, 1.7746, 1.7746, -0.709839, -2.74919, 0.4}, {0.104113, 0.104113, 0.104113, -0.0254033, 0.509839, 0.509839, 0.109839, 0.109839, 1.5746, 0.509839, -0.0254033, 0.509839, 0.509839, 0.509839, -0.0254033, 0.109839, 1.5746, 0.109839, 3.30411, 3.30411, 3.30411, 1.5746, 0.109839, 0.109839, -0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.619677, -0.709839, -0.619677, 0.0901613, -0.709839, -0.0901613, -0.0787093, -0.0901613, -0.0901613, -0.0901613, -0.0787093, 0.0901613, -0.709839, -0.619677, 0.709839, 0.709839, -4.87871, -0.709839, 0.0901613, -0.619677, -0.619677, -0.709839, 0.0901613, 0.709839, -4.87871, 0.709839, -4.87871, 0.709839, 0.709839, -0.709839, -0.619677, 0.0901613}, {-3.30411, -3.30411, -3.30411, -1.5746, -0.109839, -0.109839, -0.509839, -0.509839, 0.0254033, -0.109839, -1.5746, -0.109839, -0.109839, -0.109839, -1.5746, -0.509839, 0.0254033, -0.509839, -0.104113, -0.104113, -0.104113, 0.0254033, -0.509839, -0.509839, 4.87871, -0.709839, -0.709839, 0.709839, 0.619677, -0.0901613, 0.619677, 0.709839, -0.0901613, -0.709839, 4.87871, -0.709839, -0.709839, -0.709839, 4.87871, 0.709839, -0.0901613, 0.619677, 0.0901613, 0.0901613, 0.0787093, -0.0901613, 0.709839, 0.619677, 0.619677, -0.0901613, 0.709839, 0.0901613, 0.0787093, 0.0901613, 0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.619677, 0.709839}, {-0.864758, -1.1746, -1.1746, 0.864758, -1.1746, -1.1746, -0.2, -1.5746, 0.0254033, 0.2, -1.5746, 0.0254033, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.5746, -0.064758, -0.374597, -0.374597, 0.064758, -0.374597, -0.374597, 1.56631e-14, -1.7746, -1.7746, 0.709839, 2.74919, -0.4, 1.98947e-15, 1.7746, -0.225403, -0.709839, 2.74919, -0.4, -0.709839, -0.4, 2.74919, 0.709839, -0.4, 2.74919, 0.0901613, 0.4, 0.349193, -0.0901613, 0.4, 0.349193, -1.56631e-14, -0.225403, 1.7746, 0.0901613, 0.349193, 0.4, -1.98947e-15, 0.225403, 0.225403, -0.0901613, 0.349193, 0.4}, {1.5746, -0.109839, -0.109839, 3.30411, -3.30411, -3.30411, 0.109839, -1.5746, -0.109839, 0.509839, -0.509839, 0.0254033, 0.509839, 0.0254033, -0.509839, 0.109839, -0.109839, -1.5746, -0.0254033, -0.509839, -0.509839, 0.104113, -0.104113, -0.104113, -4.87871, -0.709839, -0.709839, 0.709839, 4.87871, -0.709839, -0.619677, 0.709839, -0.0901613, -0.709839, 0.619677, -0.0901613, -0.709839, -0.0901613, 0.619677, 0.709839, -0.709839, 4.87871, 0.0901613, 0.709839, 0.619677, -0.0901613, 0.0901613, 0.0787093, -0.619677, -0.0901613, 0.709839, 0.0901613, 0.619677, 0.709839, -0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.0787093, 0.0901613}, {-1.1746, -0.864758, -1.1746, -1.5746, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.1746, 0.864758, -1.1746, 0.0254033, 0.2, -1.5746, -0.374597, 0.064758, -0.374597, -0.374597, -0.064758, -0.374597, 0.0254033, -0.2, -1.5746, 2.74919, -0.709839, -0.4, 1.7746, 1.98947e-15, -0.225403, 2.74919, 0.709839, -0.4, -1.7746, 1.56631e-14, -1.7746, -0.4, -0.709839, 2.74919, 0.4, -0.0901613, 0.349193, 0.4, 0.0901613, 0.349193, -0.4, 0.709839, 2.74919, 0.349193, -0.0901613, 0.4, 0.225403, -1.98947e-15, 0.225403, 0.349193, 0.0901613, 0.4, -0.225403, -1.56631e-14, 1.7746}, {0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, 0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, 3.91631e-14, -1.7746, -1, 1.7746, 3.91631e-14, -1, 3.91631e-14, 1.7746, -1, -1.7746, 3.91631e-14, -1, -0.4, -0.4, 1.54919, 0.4, -0.4, 1.54919, 0.4, 0.4, 1.54919, -0.4, 0.4, 1.54919, -3.91631e-14, -0.225403, 1, 0.225403, -3.91631e-14, 1, -3.91631e-14, 0.225403, 1, -0.225403, -3.91631e-14, 1}, {1.5746, 0.2, 0.0254033, 1.1746, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.5746, -0.2, 0.0254033, 0.374597, 0.064758, -0.374597, -0.0254033, 0.2, -1.5746, -0.0254033, -0.2, -1.5746, 0.374597, -0.064758, -0.374597, -2.74919, -0.709839, -0.4, 1.7746, 1.23334e-13, -1.7746, -2.74919, 0.709839, -0.4, -1.7746, 1.56655e-14, -0.225403, -0.4, -0.0901613, 0.349193, 0.4, -0.709839, 2.74919, 0.4, 0.709839, 2.74919, -0.4, 0.0901613, 0.349193, -0.349193, -0.0901613, 0.4, 0.225403, -1.23334e-13, 1.7746, -0.349193, 0.0901613, 0.4, -0.225403, -1.56655e-14, 0.225403}, {-0.109839, 1.5746, -0.109839, -0.509839, 0.509839, 0.0254033, -1.5746, 0.109839, -0.109839, -3.30411, 3.30411, -3.30411, 0.0254033, 0.509839, -0.509839, -0.104113, 0.104113, -0.104113, -0.509839, -0.0254033, -0.509839, -0.109839, 0.109839, -1.5746, 0.619677, -0.709839, -0.0901613, 0.709839, -0.619677, -0.0901613, 4.87871, 0.709839, -0.709839, -0.709839, -4.87871, -0.709839, -0.0901613, -0.709839, 0.619677, 0.0901613, -0.0901613, 0.0787093, 0.709839, 0.0901613, 0.619677, -0.709839, 0.709839, 4.87871, 0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.0787093, 0.0901613, 0.619677, 0.0901613, 0.709839, -0.0901613, -0.619677, 0.709839}, {0.2, 1.5746, 0.0254033, -0.2, 1.5746, 0.0254033, 0.864758, 1.1746, -1.1746, -0.864758, 1.1746, -1.1746, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, -0.374597, -0.2, -0.0254033, -1.5746, 0.2, -0.0254033, -1.5746, 1.56655e-14, -1.7746, -0.225403, 0.709839, -2.74919, -0.4, 1.23334e-13, 1.7746, -1.7746, -0.709839, -2.74919, -0.4, -0.0901613, -0.4, 0.349193, 0.0901613, -0.4, 0.349193, 0.709839, 0.4, 2.74919, -0.709839, 0.4, 2.74919, -1.56655e-14, -0.225403, 0.225403, 0.0901613, -0.349193, 0.4, -1.23334e-13, 0.225403, 1.7746, -0.0901613, -0.349193, 0.4}, {0.509839, 0.509839, 0.0254033, 0.109839, 1.5746, -0.109839, 3.30411, 3.30411, -3.30411, 1.5746, 0.109839, -0.109839, 0.104113, 0.104113, -0.104113, -0.0254033, 0.509839, -0.509839, 0.109839, 0.109839, -1.5746, 0.509839, -0.0254033, -0.509839, -0.619677, -0.709839, -0.0901613, 0.709839, -4.87871, -0.709839, -4.87871, 0.709839, -0.709839, -0.709839, -0.619677, -0.0901613, -0.0901613, -0.0901613, 0.0787093, 0.0901613, -0.709839, 0.619677, 0.709839, 0.709839, 4.87871, -0.709839, 0.0901613, 0.619677, -0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.619677, 0.709839, -0.619677, 0.0901613, 0.709839, -0.0901613, -0.0787093, 0.0901613}, {-1.1746, -1.1746, -0.864758, -1.5746, 0.0254033, 0.2, -0.374597, -0.374597, 0.064758, 0.0254033, -1.5746, 0.2, -1.1746, -1.1746, 0.864758, -1.5746, 0.0254033, -0.2, -0.374597, -0.374597, -0.064758, 0.0254033, -1.5746, -0.2, 2.74919, -0.4, -0.709839, 0.4, 0.349193, -0.0901613, 0.349193, 0.4, -0.0901613, -0.4, 2.74919, -0.709839, -1.7746, -1.7746, 0, 1.7746, -0.225403, 0, 0.225403, 0.225403, 0, -0.225403, 1.7746, 0, 2.74919, -0.4, 0.709839, 0.4, 0.349193, 0.0901613, 0.349193, 0.4, 0.0901613, -0.4, 2.74919, 0.709839}, {0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, 0.2, -1.2746, 0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, -0.2, -0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, 3.91577e-14, -1, -1.7746, 0.4, 1.54919, -0.4, 4.97368e-15, 1, -0.225403, -0.4, 1.54919, -0.4, -1.7746, -1, 0, 1.7746, -1, 0, 0.225403, 1, 0, -0.225403, 1, 0, -3.91577e-14, -1, 1.7746, 0.4, 1.54919, 0.4, -4.97368e-15, 1, 0.225403, -0.4, 1.54919, 0.4}, {1.5746, 0.0254033, 0.2, 1.1746, -1.1746, -0.864758, -0.0254033, -1.5746, 0.2, 0.374597, -0.374597, 0.064758, 1.5746, 0.0254033, -0.2, 1.1746, -1.1746, 0.864758, -0.0254033, -1.5746, -0.2, 0.374597, -0.374597, -0.064758, -2.74919, -0.4, -0.709839, 0.4, 2.74919, -0.709839, -0.349193, 0.4, -0.0901613, -0.4, 0.349193, -0.0901613, -1.7746, -0.225403, -1.47765e-16, 1.7746, -1.7746, 1.47765e-16, 0.225403, 1.7746, 1.87686e-17, -0.225403, 0.225403, -1.87686e-17, -2.74919, -0.4, 0.709839, 0.4, 2.74919, 0.709839, -0.349193, 0.4, 0.0901613, -0.4, 0.349193, 0.0901613}, {-0.274597, 0.2, 0.2, -1.2746, 0.2, 0.2, -1.2746, -0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -0.2, -0.2, -0.274597, -0.2, -0.2, 1.54919, -0.4, -0.4, 1, 4.97993e-15, -0.225403, 1.54919, 0.4, -0.4, -1, 3.92069e-14, -1.7746, -1, -1.7746, 0, 1, -0.225403, 0, 1, 0.225403, 0, -1, 1.7746, 0, 1.54919, -0.4, 0.4, 1, -4.97993e-15, 0.225403, 1.54919, 0.4, 0.4, -1, -3.92069e-14, 1.7746}, {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, 9.78939e-14, -1, -1, 1, 9.79217e-14, -1, 9.78939e-14, 1, -1, -1, 9.79217e-14, -1, -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 1, 0, -9.78939e-14, -1, 1, 1, -9.79217e-14, 1, -9.78939e-14, 1, 1, -1, -9.79217e-14, 1}, {1.2746, 0.2, 0.2, 0.274597, 0.2, 0.2, 0.274597, -0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -0.2, -0.2, 1.2746, -0.2, -0.2, -1.54919, -0.4, -0.4, 1, 3.08336e-13, -1.7746, -1.54919, 0.4, -0.4, -1, 3.91638e-14, -0.225403, -1, -0.225403, 0, 1, -1.7746, 0, 1, 1.7746, 0, -1, 0.225403, 0, -1.54919, -0.4, 0.4, 1, -3.08336e-13, 1.7746, -1.54919, 0.4, 0.4, -1, -3.91638e-14, 0.225403}, {0.0254033, 1.5746, 0.2, -0.374597, 0.374597, 0.064758, -1.5746, -0.0254033, 0.2, -1.1746, 1.1746, -0.864758, 0.0254033, 1.5746, -0.2, -0.374597, 0.374597, -0.064758, -1.5746, -0.0254033, -0.2, -1.1746, 1.1746, 0.864758, 0.349193, -0.4, -0.0901613, 0.4, -0.349193, -0.0901613, 2.74919, 0.4, -0.709839, -0.4, -2.74919, -0.709839, -0.225403, -1.7746, 1.47765e-16, 0.225403, -0.225403, 1.87686e-17, 1.7746, 0.225403, -1.87686e-17, -1.7746, 1.7746, -1.47765e-16, 0.349193, -0.4, 0.0901613, 0.4, -0.349193, 0.0901613, 2.74919, 0.4, 0.709839, -0.4, -2.74919, 0.709839}, {0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, 0.2, 0.274597, 0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, -0.2, -0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, 3.91638e-14, -1, -0.225403, 0.4, -1.54919, -0.4, 3.08336e-13, 1, -1.7746, -0.4, -1.54919, -0.4, -0.225403, -1, 0, 0.225403, -1, 0, 1.7746, 1, 0, -1.7746, 1, 0, -3.91638e-14, -1, 0.225403, 0.4, -1.54919, 0.4, -3.08336e-13, 1, 1.7746, -0.4, -1.54919, 0.4}, {0.374597, 0.374597, 0.064758, -0.0254033, 1.5746, 0.2, 1.1746, 1.1746, -0.864758, 1.5746, -0.0254033, 0.2, 0.374597, 0.374597, -0.064758, -0.0254033, 1.5746, -0.2, 1.1746, 1.1746, 0.864758, 1.5746, -0.0254033, -0.2, -0.349193, -0.4, -0.0901613, 0.4, -2.74919, -0.709839, -2.74919, 0.4, -0.709839, -0.4, -0.349193, -0.0901613, -0.225403, -0.225403, -6.16298e-33, 0.225403, -1.7746, -1.66533e-16, 1.7746, 1.7746, 4.93038e-32, -1.7746, 0.225403, 1.66533e-16, -0.349193, -0.4, 0.0901613, 0.4, -2.74919, 0.709839, -2.74919, 0.4, 0.709839, -0.4, -0.349193, 0.0901613}, {-0.109839, -0.109839, 1.5746, -0.509839, 0.0254033, 0.509839, -0.104113, -0.104113, 0.104113, 0.0254033, -0.509839, 0.509839, -3.30411, -3.30411, 3.30411, -1.5746, -0.109839, 0.109839, -0.509839, -0.509839, -0.0254033, -0.109839, -1.5746, 0.109839, 0.619677, -0.0901613, -0.709839, 0.0901613, 0.0787093, -0.0901613, 0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.619677, -0.709839, -0.709839, -0.709839, -4.87871, 0.709839, -0.0901613, -0.619677, 0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.709839, -0.619677, 4.87871, -0.709839, 0.709839, 0.709839, 0.619677, 0.0901613, 0.619677, 0.709839, 0.0901613, -0.709839, 4.87871, 0.709839}, {0.2, 0.0254033, 1.5746, -0.2, 0.0254033, 1.5746, -0.064758, -0.374597, 0.374597, 0.064758, -0.374597, 0.374597, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.1746, -0.2, -1.5746, -0.0254033, 0.2, -1.5746, -0.0254033, 1.56631e-14, -0.225403, -1.7746, 0.0901613, 0.349193, -0.4, 1.98947e-15, 0.225403, -0.225403, -0.0901613, 0.349193, -0.4, -0.709839, -0.4, -2.74919, 0.709839, -0.4, -2.74919, 0.0901613, 0.4, -0.349193, -0.0901613, 0.4, -0.349193, -1.56631e-14, -1.7746, 1.7746, 0.709839, 2.74919, 0.4, -1.98947e-15, 1.7746, 0.225403, -0.709839, 2.74919, 0.4}, {0.509839, 0.0254033, 0.509839, 0.109839, -0.109839, 1.5746, -0.0254033, -0.509839, 0.509839, 0.104113, -0.104113, 0.104113, 1.5746, -0.109839, 0.109839, 3.30411, -3.30411, 3.30411, 0.109839, -1.5746, 0.109839, 0.509839, -0.509839, -0.0254033, -0.619677, -0.0901613, -0.709839, 0.0901613, 0.619677, -0.709839, -0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.0787093, -0.0901613, -0.709839, -0.0901613, -0.619677, 0.709839, -0.709839, -4.87871, 0.0901613, 0.709839, -0.619677, -0.0901613, 0.0901613, -0.0787093, -4.87871, -0.709839, 0.709839, 0.709839, 4.87871, 0.709839, -0.619677, 0.709839, 0.0901613, -0.709839, 0.619677, 0.0901613}, {0.0254033, 0.2, 1.5746, -0.374597, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, 0.0254033, -0.2, 1.5746, -1.1746, -0.864758, 1.1746, -1.5746, 0.2, -0.0254033, -1.5746, -0.2, -0.0254033, -1.1746, 0.864758, 1.1746, 0.349193, -0.0901613, -0.4, 0.225403, 1.99573e-15, -0.225403, 0.349193, 0.0901613, -0.4, -0.225403, 1.57123e-14, -1.7746, -0.4, -0.709839, -2.74919, 0.4, -0.0901613, -0.349193, 0.4, 0.0901613, -0.349193, -0.4, 0.709839, -2.74919, 2.74919, -0.709839, 0.4, 1.7746, -1.99573e-15, 0.225403, 2.74919, 0.709839, 0.4, -1.7746, -1.57123e-14, 1.7746}, {0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, 0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, 3.91631e-14, -0.225403, -1, 0.225403, 3.91631e-14, -1, 3.91631e-14, 0.225403, -1, -0.225403, 3.91631e-14, -1, -0.4, -0.4, -1.54919, 0.4, -0.4, -1.54919, 0.4, 0.4, -1.54919, -0.4, 0.4, -1.54919, -3.91631e-14, -1.7746, 1, 1.7746, -3.91631e-14, 1, -3.91631e-14, 1.7746, 1, -1.7746, -3.91631e-14, 1}, {0.374597, 0.064758, 0.374597, -0.0254033, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, 0.374597, -0.064758, 0.374597, 1.5746, 0.2, -0.0254033, 1.1746, -0.864758, 1.1746, 1.1746, 0.864758, 1.1746, 1.5746, -0.2, -0.0254033, -0.349193, -0.0901613, -0.4, 0.225403, 1.23334e-13, -1.7746, -0.349193, 0.0901613, -0.4, -0.225403, 1.56655e-14, -0.225403, -0.4, -0.0901613, -0.349193, 0.4, -0.709839, -2.74919, 0.4, 0.709839, -2.74919, -0.4, 0.0901613, -0.349193, -2.74919, -0.709839, 0.4, 1.7746, -1.23334e-13, 1.7746, -2.74919, 0.709839, 0.4, -1.7746, -1.56655e-14, 0.225403}, {0.0254033, 0.509839, 0.509839, -0.104113, 0.104113, 0.104113, -0.509839, -0.0254033, 0.509839, -0.109839, 0.109839, 1.5746, -0.109839, 1.5746, 0.109839, -0.509839, 0.509839, -0.0254033, -1.5746, 0.109839, 0.109839, -3.30411, 3.30411, 3.30411, 0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.619677, 0.0901613, -0.709839, -0.0901613, -0.619677, -0.709839, -0.0901613, -0.709839, -0.619677, 0.0901613, -0.0901613, -0.0787093, 0.709839, 0.0901613, -0.619677, -0.709839, 0.709839, -4.87871, 0.619677, -0.709839, 0.0901613, 0.709839, -0.619677, 0.0901613, 4.87871, 0.709839, 0.709839, -0.709839, -4.87871, 0.709839}, {0.064758, 0.374597, 0.374597, -0.064758, 0.374597, 0.374597, -0.2, -0.0254033, 1.5746, 0.2, -0.0254033, 1.5746, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, -0.0254033, 0.864758, 1.1746, 1.1746, -0.864758, 1.1746, 1.1746, 1.56655e-14, -0.225403, -0.225403, 0.0901613, -0.349193, -0.4, 1.23334e-13, 0.225403, -1.7746, -0.0901613, -0.349193, -0.4, -0.0901613, -0.4, -0.349193, 0.0901613, -0.4, -0.349193, 0.709839, 0.4, -2.74919, -0.709839, 0.4, -2.74919, -1.56655e-14, -1.7746, 0.225403, 0.709839, -2.74919, 0.4, -1.23334e-13, 1.7746, 1.7746, -0.709839, -2.74919, 0.4}, {0.104113, 0.104113, 0.104113, -0.0254033, 0.509839, 0.509839, 0.109839, 0.109839, 1.5746, 0.509839, -0.0254033, 0.509839, 0.509839, 0.509839, -0.0254033, 0.109839, 1.5746, 0.109839, 3.30411, 3.30411, 3.30411, 1.5746, 0.109839, 0.109839, -0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.619677, -0.709839, -0.619677, 0.0901613, -0.709839, -0.0901613, -0.0787093, -0.0901613, -0.0901613, -0.0901613, -0.0787093, 0.0901613, -0.709839, -0.619677, 0.709839, 0.709839, -4.87871, -0.709839, 0.0901613, -0.619677, -0.619677, -0.709839, 0.0901613, 0.709839, -4.87871, 0.709839, -4.87871, 0.709839, 0.709839, -0.709839, -0.619677, 0.0901613}, {-3.30411, -3.30411, -3.30411, -1.5746, -0.109839, -0.109839, -0.509839, -0.509839, 0.0254033, -0.109839, -1.5746, -0.109839, -0.109839, -0.109839, -1.5746, -0.509839, 0.0254033, -0.509839, -0.104113, -0.104113, -0.104113, 0.0254033, -0.509839, -0.509839, 4.87871, -0.709839, -0.709839, 0.709839, 0.619677, -0.0901613, 0.619677, 0.709839, -0.0901613, -0.709839, 4.87871, -0.709839, -0.709839, -0.709839, 4.87871, 0.709839, -0.0901613, 0.619677, 0.0901613, 0.0901613, 0.0787093, -0.0901613, 0.709839, 0.619677, 0.619677, -0.0901613, 0.709839, 0.0901613, 0.0787093, 0.0901613, 0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.619677, 0.709839}, {-0.864758, -1.1746, -1.1746, 0.864758, -1.1746, -1.1746, -0.2, -1.5746, 0.0254033, 0.2, -1.5746, 0.0254033, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.5746, -0.064758, -0.374597, -0.374597, 0.064758, -0.374597, -0.374597, 0, -1.7746, -1.7746, 0.709839, 2.74919, -0.4, 0, 1.7746, -0.225403, -0.709839, 2.74919, -0.4, -0.709839, -0.4, 2.74919, 0.709839, -0.4, 2.74919, 0.0901613, 0.4, 0.349193, -0.0901613, 0.4, 0.349193, 0, -0.225403, 1.7746, 0.0901613, 0.349193, 0.4, 0, 0.225403, 0.225403, -0.0901613, 0.349193, 0.4}, {1.5746, -0.109839, -0.109839, 3.30411, -3.30411, -3.30411, 0.109839, -1.5746, -0.109839, 0.509839, -0.509839, 0.0254033, 0.509839, 0.0254033, -0.509839, 0.109839, -0.109839, -1.5746, -0.0254033, -0.509839, -0.509839, 0.104113, -0.104113, -0.104113, -4.87871, -0.709839, -0.709839, 0.709839, 4.87871, -0.709839, -0.619677, 0.709839, -0.0901613, -0.709839, 0.619677, -0.0901613, -0.709839, -0.0901613, 0.619677, 0.709839, -0.709839, 4.87871, 0.0901613, 0.709839, 0.619677, -0.0901613, 0.0901613, 0.0787093, -0.619677, -0.0901613, 0.709839, 0.0901613, 0.619677, 0.709839, -0.0787093, 0.0901613, 0.0901613, -0.0901613, 0.0787093, 0.0901613}, {-1.1746, -0.864758, -1.1746, -1.5746, 0.2, 0.0254033, -1.5746, -0.2, 0.0254033, -1.1746, 0.864758, -1.1746, 0.0254033, 0.2, -1.5746, -0.374597, 0.064758, -0.374597, -0.374597, -0.064758, -0.374597, 0.0254033, -0.2, -1.5746, 2.74919, -0.709839, -0.4, 1.7746, 1.56568e-14, -0.225403, 2.74919, 0.709839, -0.4, -1.7746, -1.57123e-14, -1.7746, -0.4, -0.709839, 2.74919, 0.4, -0.0901613, 0.349193, 0.4, 0.0901613, 0.349193, -0.4, 0.709839, 2.74919, 0.349193, -0.0901613, 0.4, 0.225403, 1.99573e-15, 0.225403, 0.349193, 0.0901613, 0.4, -0.225403, -1.94022e-15, 1.7746}, {0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, 0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, 0, -1.7746, -1, 1.7746, 3.91577e-14, -1, 0, 1.7746, -1, -1.7746, -3.91577e-14, -1, -0.4, -0.4, 1.54919, 0.4, -0.4, 1.54919, 0.4, 0.4, 1.54919, -0.4, 0.4, 1.54919, 0, -0.225403, 1, 0.225403, 4.97368e-15, 1, 0, 0.225403, 1, -0.225403, -4.97368e-15, 1}, {1.5746, 0.2, 0.0254033, 1.1746, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.5746, -0.2, 0.0254033, 0.374597, 0.064758, -0.374597, -0.0254033, 0.2, -1.5746, -0.0254033, -0.2, -1.5746, 0.374597, -0.064758, -0.374597, -2.74919, -0.709839, -0.4, 1.7746, 1.56631e-14, -1.7746, -2.74919, 0.709839, -0.4, -1.7746, -1.56631e-14, -0.225403, -0.4, -0.0901613, 0.349193, 0.4, -0.709839, 2.74919, 0.4, 0.709839, 2.74919, -0.4, 0.0901613, 0.349193, -0.349193, -0.0901613, 0.4, 0.225403, 1.98947e-15, 1.7746, -0.349193, 0.0901613, 0.4, -0.225403, -1.98947e-15, 0.225403}, {-0.109839, 1.5746, -0.109839, -0.509839, 0.509839, 0.0254033, -1.5746, 0.109839, -0.109839, -3.30411, 3.30411, -3.30411, 0.0254033, 0.509839, -0.509839, -0.104113, 0.104113, -0.104113, -0.509839, -0.0254033, -0.509839, -0.109839, 0.109839, -1.5746, 0.619677, -0.709839, -0.0901613, 0.709839, -0.619677, -0.0901613, 4.87871, 0.709839, -0.709839, -0.709839, -4.87871, -0.709839, -0.0901613, -0.709839, 0.619677, 0.0901613, -0.0901613, 0.0787093, 0.709839, 0.0901613, 0.619677, -0.709839, 0.709839, 4.87871, 0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.0787093, 0.0901613, 0.619677, 0.0901613, 0.709839, -0.0901613, -0.619677, 0.709839}, {0.2, 1.5746, 0.0254033, -0.2, 1.5746, 0.0254033, 0.864758, 1.1746, -1.1746, -0.864758, 1.1746, -1.1746, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, -0.374597, -0.2, -0.0254033, -1.5746, 0.2, -0.0254033, -1.5746, 0, -1.7746, -0.225403, 0.709839, -2.74919, -0.4, 0, 1.7746, -1.7746, -0.709839, -2.74919, -0.4, -0.0901613, -0.4, 0.349193, 0.0901613, -0.4, 0.349193, 0.709839, 0.4, 2.74919, -0.709839, 0.4, 2.74919, 0, -0.225403, 0.225403, 0.0901613, -0.349193, 0.4, 0, 0.225403, 1.7746, -0.0901613, -0.349193, 0.4}, {0.509839, 0.509839, 0.0254033, 0.109839, 1.5746, -0.109839, 3.30411, 3.30411, -3.30411, 1.5746, 0.109839, -0.109839, 0.104113, 0.104113, -0.104113, -0.0254033, 0.509839, -0.509839, 0.109839, 0.109839, -1.5746, 0.509839, -0.0254033, -0.509839, -0.619677, -0.709839, -0.0901613, 0.709839, -4.87871, -0.709839, -4.87871, 0.709839, -0.709839, -0.709839, -0.619677, -0.0901613, -0.0901613, -0.0901613, 0.0787093, 0.0901613, -0.709839, 0.619677, 0.709839, 0.709839, 4.87871, -0.709839, 0.0901613, 0.619677, -0.0787093, -0.0901613, 0.0901613, 0.0901613, -0.619677, 0.709839, -0.619677, 0.0901613, 0.709839, -0.0901613, -0.0787093, 0.0901613}, {-1.1746, -1.1746, -0.864758, -1.5746, 0.0254033, 0.2, -0.374597, -0.374597, 0.064758, 0.0254033, -1.5746, 0.2, -1.1746, -1.1746, 0.864758, -1.5746, 0.0254033, -0.2, -0.374597, -0.374597, -0.064758, 0.0254033, -1.5746, -0.2, 2.74919, -0.4, -0.709839, 0.4, 0.349193, -0.0901613, 0.349193, 0.4, -0.0901613, -0.4, 2.74919, -0.709839, -1.7746, -1.7746, -1.56631e-14, 1.7746, -0.225403, 1.56631e-14, 0.225403, 0.225403, 1.98947e-15, -0.225403, 1.7746, -1.98947e-15, 2.74919, -0.4, 0.709839, 0.4, 0.349193, 0.0901613, 0.349193, 0.4, 0.0901613, -0.4, 2.74919, 0.709839}, {0.2, -0.274597, 0.2, -0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, 0.2, -1.2746, 0.2, 0.2, -0.274597, -0.2, -0.2, -0.274597, -0.2, -0.2, -1.2746, -0.2, 0.2, -1.2746, -0.2, 0, -1, -1.7746, 0.4, 1.54919, -0.4, 0, 1, -0.225403, -0.4, 1.54919, -0.4, -1.7746, -1, -3.91577e-14, 1.7746, -1, 3.91577e-14, 0.225403, 1, 4.97368e-15, -0.225403, 1, -4.97368e-15, 0, -1, 1.7746, 0.4, 1.54919, 0.4, 0, 1, 0.225403, -0.4, 1.54919, 0.4}, {1.5746, 0.0254033, 0.2, 1.1746, -1.1746, -0.864758, -0.0254033, -1.5746, 0.2, 0.374597, -0.374597, 0.064758, 1.5746, 0.0254033, -0.2, 1.1746, -1.1746, 0.864758, -0.0254033, -1.5746, -0.2, 0.374597, -0.374597, -0.064758, -2.74919, -0.4, -0.709839, 0.4, 2.74919, -0.709839, -0.349193, 0.4, -0.0901613, -0.4, 0.349193, -0.0901613, -1.7746, -0.225403, -1.58108e-14, 1.7746, -1.7746, 1.58108e-14, 0.225403, 1.7746, 2.00824e-15, -0.225403, 0.225403, -2.00824e-15, -2.74919, -0.4, 0.709839, 0.4, 2.74919, 0.709839, -0.349193, 0.4, 0.0901613, -0.4, 0.349193, 0.0901613}, {-0.274597, 0.2, 0.2, -1.2746, 0.2, 0.2, -1.2746, -0.2, 0.2, -0.274597, -0.2, 0.2, -0.274597, 0.2, -0.2, -1.2746, 0.2, -0.2, -1.2746, -0.2, -0.2, -0.274597, -0.2, -0.2, 1.54919, -0.4, -0.4, 1, 3.91631e-14, -0.225403, 1.54919, 0.4, -0.4, -1, -3.91631e-14, -1.7746, -1, -1.7746, -3.91631e-14, 1, -0.225403, 3.91631e-14, 1, 0.225403, 3.91631e-14, -1, 1.7746, -3.91631e-14, 1.54919, -0.4, 0.4, 1, 3.91631e-14, 0.225403, 1.54919, 0.4, 0.4, -1, -3.91631e-14, 1.7746}, {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, -1, -1, 1, 9.78939e-14, -1, 0, 1, -1, -1, -9.78939e-14, -1, -1, -1, -9.78939e-14, 1, -1, 9.78939e-14, 1, 1, 9.78939e-14, -1, 1, -9.78939e-14, 0, -1, 1, 1, 9.78939e-14, 1, 0, 1, 1, -1, -9.78939e-14, 1}, {1.2746, 0.2, 0.2, 0.274597, 0.2, 0.2, 0.274597, -0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, -0.2, -0.2, 1.2746, -0.2, -0.2, -1.54919, -0.4, -0.4, 1, 3.91631e-14, -1.7746, -1.54919, 0.4, -0.4, -1, -3.91631e-14, -0.225403, -1, -0.225403, -3.91631e-14, 1, -1.7746, 3.91631e-14, 1, 1.7746, 3.91631e-14, -1, 0.225403, -3.91631e-14, -1.54919, -0.4, 0.4, 1, 3.91631e-14, 1.7746, -1.54919, 0.4, 0.4, -1, -3.91631e-14, 0.225403}, {0.0254033, 1.5746, 0.2, -0.374597, 0.374597, 0.064758, -1.5746, -0.0254033, 0.2, -1.1746, 1.1746, -0.864758, 0.0254033, 1.5746, -0.2, -0.374597, 0.374597, -0.064758, -1.5746, -0.0254033, -0.2, -1.1746, 1.1746, 0.864758, 0.349193, -0.4, -0.0901613, 0.4, -0.349193, -0.0901613, 2.74919, 0.4, -0.709839, -0.4, -2.74919, -0.709839, -0.225403, -1.7746, -1.55178e-14, 0.225403, -0.225403, 1.56843e-14, 1.7746, 0.225403, 1.23316e-13, -1.7746, 1.7746, -1.23482e-13, 0.349193, -0.4, 0.0901613, 0.4, -0.349193, 0.0901613, 2.74919, 0.4, 0.709839, -0.4, -2.74919, 0.709839}, {0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, -0.2, 0.274597, 0.2, 0.2, 0.274597, 0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, -0.2, -0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, 0, -1, -0.225403, 0.4, -1.54919, -0.4, 0, 1, -1.7746, -0.4, -1.54919, -0.4, -0.225403, -1, -3.91638e-14, 0.225403, -1, 3.91638e-14, 1.7746, 1, 3.08336e-13, -1.7746, 1, -3.08336e-13, 0, -1, 0.225403, 0.4, -1.54919, 0.4, 0, 1, 1.7746, -0.4, -1.54919, 0.4}, {0.374597, 0.374597, 0.064758, -0.0254033, 1.5746, 0.2, 1.1746, 1.1746, -0.864758, 1.5746, -0.0254033, 0.2, 0.374597, 0.374597, -0.064758, -0.0254033, 1.5746, -0.2, 1.1746, 1.1746, 0.864758, 1.5746, -0.0254033, -0.2, -0.349193, -0.4, -0.0901613, 0.4, -2.74919, -0.709839, -2.74919, 0.4, -0.709839, -0.4, -0.349193, -0.0901613, -0.225403, -0.225403, -1.56655e-14, 0.225403, -1.7746, 1.5499e-14, 1.7746, 1.7746, 1.23334e-13, -1.7746, 0.225403, -1.23168e-13, -0.349193, -0.4, 0.0901613, 0.4, -2.74919, 0.709839, -2.74919, 0.4, 0.709839, -0.4, -0.349193, 0.0901613}, {-0.109839, -0.109839, 1.5746, -0.509839, 0.0254033, 0.509839, -0.104113, -0.104113, 0.104113, 0.0254033, -0.509839, 0.509839, -3.30411, -3.30411, 3.30411, -1.5746, -0.109839, 0.109839, -0.509839, -0.509839, -0.0254033, -0.109839, -1.5746, 0.109839, 0.619677, -0.0901613, -0.709839, 0.0901613, 0.0787093, -0.0901613, 0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.619677, -0.709839, -0.709839, -0.709839, -4.87871, 0.709839, -0.0901613, -0.619677, 0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.709839, -0.619677, 4.87871, -0.709839, 0.709839, 0.709839, 0.619677, 0.0901613, 0.619677, 0.709839, 0.0901613, -0.709839, 4.87871, 0.709839}, {0.2, 0.0254033, 1.5746, -0.2, 0.0254033, 1.5746, -0.064758, -0.374597, 0.374597, 0.064758, -0.374597, 0.374597, -0.864758, -1.1746, 1.1746, 0.864758, -1.1746, 1.1746, -0.2, -1.5746, -0.0254033, 0.2, -1.5746, -0.0254033, 0, -0.225403, -1.7746, 0.0901613, 0.349193, -0.4, 0, 0.225403, -0.225403, -0.0901613, 0.349193, -0.4, -0.709839, -0.4, -2.74919, 0.709839, -0.4, -2.74919, 0.0901613, 0.4, -0.349193, -0.0901613, 0.4, -0.349193, 0, -1.7746, 1.7746, 0.709839, 2.74919, 0.4, 0, 1.7746, 0.225403, -0.709839, 2.74919, 0.4}, {0.509839, 0.0254033, 0.509839, 0.109839, -0.109839, 1.5746, -0.0254033, -0.509839, 0.509839, 0.104113, -0.104113, 0.104113, 1.5746, -0.109839, 0.109839, 3.30411, -3.30411, 3.30411, 0.109839, -1.5746, 0.109839, 0.509839, -0.509839, -0.0254033, -0.619677, -0.0901613, -0.709839, 0.0901613, 0.619677, -0.709839, -0.0787093, 0.0901613, -0.0901613, -0.0901613, 0.0787093, -0.0901613, -0.709839, -0.0901613, -0.619677, 0.709839, -0.709839, -4.87871, 0.0901613, 0.709839, -0.619677, -0.0901613, 0.0901613, -0.0787093, -4.87871, -0.709839, 0.709839, 0.709839, 4.87871, 0.709839, -0.619677, 0.709839, 0.0901613, -0.709839, 0.619677, 0.0901613}, {0.0254033, 0.2, 1.5746, -0.374597, 0.064758, 0.374597, -0.374597, -0.064758, 0.374597, 0.0254033, -0.2, 1.5746, -1.1746, -0.864758, 1.1746, -1.5746, 0.2, -0.0254033, -1.5746, -0.2, -0.0254033, -1.1746, 0.864758, 1.1746, 0.349193, -0.0901613, -0.4, 0.225403, 1.56655e-14, -0.225403, 0.349193, 0.0901613, -0.4, -0.225403, -1.56655e-14, -1.7746, -0.4, -0.709839, -2.74919, 0.4, -0.0901613, -0.349193, 0.4, 0.0901613, -0.349193, -0.4, 0.709839, -2.74919, 2.74919, -0.709839, 0.4, 1.7746, 1.23334e-13, 0.225403, 2.74919, 0.709839, 0.4, -1.7746, -1.23334e-13, 1.7746}, {0.2, 0.2, 1.2746, -0.2, 0.2, 1.2746, -0.2, -0.2, 1.2746, 0.2, -0.2, 1.2746, 0.2, 0.2, 0.274597, -0.2, 0.2, 0.274597, -0.2, -0.2, 0.274597, 0.2, -0.2, 0.274597, 0, -0.225403, -1, 0.225403, 3.91638e-14, -1, 0, 0.225403, -1, -0.225403, -3.91638e-14, -1, -0.4, -0.4, -1.54919, 0.4, -0.4, -1.54919, 0.4, 0.4, -1.54919, -0.4, 0.4, -1.54919, 0, -1.7746, 1, 1.7746, 3.08336e-13, 1, 0, 1.7746, 1, -1.7746, -3.08336e-13, 1}, {0.374597, 0.064758, 0.374597, -0.0254033, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, 0.374597, -0.064758, 0.374597, 1.5746, 0.2, -0.0254033, 1.1746, -0.864758, 1.1746, 1.1746, 0.864758, 1.1746, 1.5746, -0.2, -0.0254033, -0.349193, -0.0901613, -0.4, 0.225403, 1.56655e-14, -1.7746, -0.349193, 0.0901613, -0.4, -0.225403, -1.56655e-14, -0.225403, -0.4, -0.0901613, -0.349193, 0.4, -0.709839, -2.74919, 0.4, 0.709839, -2.74919, -0.4, 0.0901613, -0.349193, -2.74919, -0.709839, 0.4, 1.7746, 1.23334e-13, 1.7746, -2.74919, 0.709839, 0.4, -1.7746, -1.23334e-13, 0.225403}, {0.0254033, 0.509839, 0.509839, -0.104113, 0.104113, 0.104113, -0.509839, -0.0254033, 0.509839, -0.109839, 0.109839, 1.5746, -0.109839, 1.5746, 0.109839, -0.509839, 0.509839, -0.0254033, -1.5746, 0.109839, 0.109839, -3.30411, 3.30411, 3.30411, 0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.0787093, -0.0901613, 0.619677, 0.0901613, -0.709839, -0.0901613, -0.619677, -0.709839, -0.0901613, -0.709839, -0.619677, 0.0901613, -0.0901613, -0.0787093, 0.709839, 0.0901613, -0.619677, -0.709839, 0.709839, -4.87871, 0.619677, -0.709839, 0.0901613, 0.709839, -0.619677, 0.0901613, 4.87871, 0.709839, 0.709839, -0.709839, -4.87871, 0.709839}, {0.064758, 0.374597, 0.374597, -0.064758, 0.374597, 0.374597, -0.2, -0.0254033, 1.5746, 0.2, -0.0254033, 1.5746, 0.2, 1.5746, -0.0254033, -0.2, 1.5746, -0.0254033, 0.864758, 1.1746, 1.1746, -0.864758, 1.1746, 1.1746, 0, -0.225403, -0.225403, 0.0901613, -0.349193, -0.4, 0, 0.225403, -1.7746, -0.0901613, -0.349193, -0.4, -0.0901613, -0.4, -0.349193, 0.0901613, -0.4, -0.349193, 0.709839, 0.4, -2.74919, -0.709839, 0.4, -2.74919, 0, -1.7746, 0.225403, 0.709839, -2.74919, 0.4, 0, 1.7746, 1.7746, -0.709839, -2.74919, 0.4}, {0.104113, 0.104113, 0.104113, -0.0254033, 0.509839, 0.509839, 0.109839, 0.109839, 1.5746, 0.509839, -0.0254033, 0.509839, 0.509839, 0.509839, -0.0254033, 0.109839, 1.5746, 0.109839, 3.30411, 3.30411, 3.30411, 1.5746, 0.109839, 0.109839, -0.0787093, -0.0901613, -0.0901613, 0.0901613, -0.619677, -0.709839, -0.619677, 0.0901613, -0.709839, -0.0901613, -0.0787093, -0.0901613, -0.0901613, -0.0901613, -0.0787093, 0.0901613, -0.709839, -0.619677, 0.709839, 0.709839, -4.87871, -0.709839, 0.0901613, -0.619677, -0.619677, -0.709839, 0.0901613, 0.709839, -4.87871, 0.709839, -4.87871, 0.709839, 0.709839, -0.709839, -0.619677, 0.0901613}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_hexahedron_20) [
+ Array<double> [
+ + id : my_fem:jacobians:_hexahedron_20
+ + size : 216
+ + nb_component : 1
+ + allocated size : 216
+ + memory size : 1.69KiByte
+ + values : {{0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00685871}, {0.0109739}, {0.00685871}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00685871}, {0.0109739}, {0.00685871}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00685871}, {0.0109739}, {0.00685871}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00685871}, {0.0109739}, {0.00685871}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00685871}, {0.0109739}, {0.00685871}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00685871}, {0.0109739}, {0.00685871}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00685871}, {0.0109739}, {0.00685871}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00685871}, {0.0109739}, {0.00685871}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00685871}, {0.00428669}, {0.00267918}, {0.00428669}, {0.00267918}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_hexahedron_8.verified b/test/test_fe_engine/test_fe_engine_precomputation_hexahedron_8.verified
new file mode 100644
index 000000000..d891f113a
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_hexahedron_8.verified
@@ -0,0 +1,119 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 3
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 3
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_point_1) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_point_1
+ + size : 8
+ + nb_component : 1
+ + allocated size : 2000
+ + memory size : 7.81KiByte
+ + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
+ ]
+ ]
+ (not_ghost:_segment_2) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_segment_2
+ + size : 48
+ + nb_component : 2
+ + allocated size : 2000
+ + memory size : 15.62KiByte
+ + values : {{6, 8}, {8, 9}, {9, 10}, {10, 7}, {7, 11}, {11, 12}, {12, 13}, {13, 3}, {3, 14}, {14, 15}, {15, 16}, {16, 2}, {2, 17}, {17, 18}, {18, 19}, {19, 6}, {0, 20}, {20, 21}, {21, 22}, {22, 4}, {4, 23}, {23, 24}, {24, 25}, {25, 5}, {5, 26}, {26, 27}, {27, 28}, {28, 1}, {1, 29}, {29, 30}, {30, 31}, {31, 0}, {2, 32}, {32, 33}, {33, 34}, {34, 0}, {6, 35}, {35, 36}, {36, 37}, {37, 4}, {7, 38}, {38, 39}, {39, 40}, {40, 5}, {3, 41}, {41, 42}, {42, 43}, {43, 1}}
+ ]
+ ]
+ (not_ghost:_quadrangle_4) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_quadrangle_4
+ + size : 96
+ + nb_component : 4
+ + allocated size : 2000
+ + memory size : 31.25KiByte
+ + values : {{6, 8, 44, 35}, {35, 44, 45, 36}, {36, 45, 46, 37}, {37, 46, 23, 4}, {8, 9, 47, 44}, {44, 47, 48, 45}, {45, 48, 49, 46}, {46, 49, 24, 23}, {9, 10, 50, 47}, {47, 50, 51, 48}, {48, 51, 52, 49}, {49, 52, 25, 24}, {10, 7, 38, 50}, {50, 38, 39, 51}, {51, 39, 40, 52}, {52, 40, 5, 25}, {3, 14, 53, 13}, {13, 53, 54, 12}, {12, 54, 55, 11}, {11, 55, 10, 7}, {14, 15, 56, 53}, {53, 56, 57, 54}, {54, 57, 58, 55}, {55, 58, 9, 10}, {15, 16, 59, 56}, {56, 59, 60, 57}, {57, 60, 61, 58}, {58, 61, 8, 9}, {16, 2, 17, 59}, {59, 17, 18, 60}, {60, 18, 19, 61}, {61, 19, 6, 8}, {4, 23, 62, 22}, {22, 62, 63, 21}, {21, 63, 64, 20}, {20, 64, 31, 0}, {23, 24, 65, 62}, {62, 65, 66, 63}, {63, 66, 67, 64}, {64, 67, 30, 31}, {24, 25, 68, 65}, {65, 68, 69, 66}, {66, 69, 70, 67}, {67, 70, 29, 30}, {25, 5, 26, 68}, {68, 26, 27, 69}, {69, 27, 28, 70}, {70, 28, 1, 29}, {3, 14, 71, 41}, {41, 71, 72, 42}, {42, 72, 73, 43}, {43, 73, 29, 1}, {14, 15, 74, 71}, {71, 74, 75, 72}, {72, 75, 76, 73}, {73, 76, 30, 29}, {15, 16, 77, 74}, {74, 77, 78, 75}, {75, 78, 79, 76}, {76, 79, 31, 30}, {16, 2, 32, 77}, {77, 32, 33, 78}, {78, 33, 34, 79}, {79, 34, 0, 31}, {2, 17, 80, 32}, {32, 80, 81, 33}, {33, 81, 82, 34}, {34, 82, 20, 0}, {17, 18, 83, 80}, {80, 83, 84, 81}, {81, 84, 85, 82}, {82, 85, 21, 20}, {18, 19, 86, 83}, {83, 86, 87, 84}, {84, 87, 88, 85}, {85, 88, 22, 21}, {19, 6, 35, 86}, {86, 35, 36, 87}, {87, 36, 37, 88}, {88, 37, 4, 22}, {7, 38, 89, 11}, {11, 89, 90, 12}, {12, 90, 91, 13}, {13, 91, 41, 3}, {38, 39, 92, 89}, {89, 92, 93, 90}, {90, 93, 94, 91}, {91, 94, 42, 41}, {39, 40, 95, 92}, {92, 95, 96, 93}, {93, 96, 97, 94}, {94, 97, 43, 42}, {40, 5, 26, 95}, {95, 26, 27, 96}, {96, 27, 28, 97}, {97, 28, 1, 43}}
+ ]
+ ]
+ (not_ghost:_hexahedron_8) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_hexahedron_8
+ + size : 64
+ + nb_component : 8
+ + allocated size : 2000
+ + memory size : 62.50KiByte
+ + values : {{89, 38, 7, 11, 98, 50, 10, 55}, {98, 50, 10, 55, 99, 47, 9, 58}, {99, 47, 9, 58, 100, 44, 8, 61}, {100, 44, 8, 61, 86, 35, 6, 19}, {90, 89, 11, 12, 101, 98, 55, 54}, {101, 98, 55, 54, 102, 99, 58, 57}, {102, 99, 58, 57, 103, 100, 61, 60}, {103, 100, 61, 60, 83, 86, 19, 18}, {91, 90, 12, 13, 104, 101, 54, 53}, {104, 101, 54, 53, 105, 102, 57, 56}, {105, 102, 57, 56, 106, 103, 60, 59}, {106, 103, 60, 59, 80, 83, 18, 17}, {41, 91, 13, 3, 71, 104, 53, 14}, {71, 104, 53, 14, 74, 105, 56, 15}, {74, 105, 56, 15, 77, 106, 59, 16}, {77, 106, 59, 16, 32, 80, 17, 2}, {92, 39, 38, 89, 107, 51, 50, 98}, {107, 51, 50, 98, 108, 48, 47, 99}, {108, 48, 47, 99, 109, 45, 44, 100}, {109, 45, 44, 100, 87, 36, 35, 86}, {93, 92, 89, 90, 110, 107, 98, 101}, {110, 107, 98, 101, 111, 108, 99, 102}, {111, 108, 99, 102, 112, 109, 100, 103}, {112, 109, 100, 103, 84, 87, 86, 83}, {94, 93, 90, 91, 113, 110, 101, 104}, {113, 110, 101, 104, 114, 111, 102, 105}, {114, 111, 102, 105, 115, 112, 103, 106}, {115, 112, 103, 106, 81, 84, 83, 80}, {42, 94, 91, 41, 72, 113, 104, 71}, {72, 113, 104, 71, 75, 114, 105, 74}, {75, 114, 105, 74, 78, 115, 106, 77}, {78, 115, 106, 77, 33, 81, 80, 32}, {95, 40, 39, 92, 116, 52, 51, 107}, {116, 52, 51, 107, 117, 49, 48, 108}, {117, 49, 48, 108, 118, 46, 45, 109}, {118, 46, 45, 109, 88, 37, 36, 87}, {96, 95, 92, 93, 119, 116, 107, 110}, {119, 116, 107, 110, 120, 117, 108, 111}, {120, 117, 108, 111, 121, 118, 109, 112}, {121, 118, 109, 112, 85, 88, 87, 84}, {97, 96, 93, 94, 122, 119, 110, 113}, {122, 119, 110, 113, 123, 120, 111, 114}, {123, 120, 111, 114, 124, 121, 112, 115}, {124, 121, 112, 115, 82, 85, 84, 81}, {43, 97, 94, 42, 73, 122, 113, 72}, {73, 122, 113, 72, 76, 123, 114, 75}, {76, 123, 114, 75, 79, 124, 115, 78}, {79, 124, 115, 78, 34, 82, 81, 33}, {26, 5, 40, 95, 68, 25, 52, 116}, {68, 25, 52, 116, 65, 24, 49, 117}, {65, 24, 49, 117, 62, 23, 46, 118}, {62, 23, 46, 118, 22, 4, 37, 88}, {27, 26, 95, 96, 69, 68, 116, 119}, {69, 68, 116, 119, 66, 65, 117, 120}, {66, 65, 117, 120, 63, 62, 118, 121}, {63, 62, 118, 121, 21, 22, 88, 85}, {28, 27, 96, 97, 70, 69, 119, 122}, {70, 69, 119, 122, 67, 66, 120, 123}, {67, 66, 120, 123, 64, 63, 121, 124}, {64, 63, 121, 124, 20, 21, 85, 82}, {1, 28, 97, 43, 29, 70, 122, 73}, {29, 70, 122, 73, 30, 67, 123, 76}, {30, 67, 123, 76, 31, 64, 124, 79}, {31, 64, 124, 79, 0, 20, 82, 34}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_hexahedron_8)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_hexahedron_8) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_lagrange_hexahedron_8
+ + size : 512
+ + nb_component : 8
+ + allocated size : 512
+ + memory size : 32.00KiByte
+ + values : {{0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}, {0.490563, 0.131446, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.00943739, 0.0352208}, {0.131446, 0.490563, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.0352208, 0.00943739}, {0.131446, 0.0352208, 0.131446, 0.490563, 0.0352208, 0.00943739, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.490563, 0.131446, 0.00943739, 0.0352208, 0.131446, 0.0352208}, {0.131446, 0.0352208, 0.00943739, 0.0352208, 0.490563, 0.131446, 0.0352208, 0.131446}, {0.0352208, 0.131446, 0.0352208, 0.00943739, 0.131446, 0.490563, 0.131446, 0.0352208}, {0.0352208, 0.00943739, 0.0352208, 0.131446, 0.131446, 0.0352208, 0.131446, 0.490563}, {0.00943739, 0.0352208, 0.131446, 0.0352208, 0.0352208, 0.131446, 0.490563, 0.131446}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_hexahedron_8) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_lagrange_hexahedron_8
+ + size : 512
+ + nb_component : 24
+ + allocated size : 512
+ + memory size : 96.00KiByte
+ + values : {{2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}, {2.48803, -2.48803, -2.48803, 0.666667, -0.666667, 2.48803, 0.178633, 0.666667, 0.666667, 0.666667, 2.48803, -0.666667, -2.48803, -0.666667, -0.666667, -0.666667, -0.178633, 0.666667, -0.178633, 0.178633, 0.178633, -0.666667, 0.666667, -0.178633}, {0.666667, -0.666667, -2.48803, 2.48803, -2.48803, 2.48803, 0.666667, 2.48803, 0.666667, 0.178633, 0.666667, -0.666667, -0.666667, -0.178633, -0.666667, -2.48803, -0.666667, 0.666667, -0.666667, 0.666667, 0.178633, -0.178633, 0.178633, -0.178633}, {0.666667, -2.48803, -0.666667, 0.178633, -0.666667, 0.666667, 0.666667, 0.666667, 2.48803, 2.48803, 2.48803, -2.48803, -0.666667, -0.666667, -0.178633, -0.178633, -0.178633, 0.178633, -0.666667, 0.178633, 0.666667, -2.48803, 0.666667, -0.666667}, {0.178633, -0.666667, -0.666667, 0.666667, -2.48803, 0.666667, 2.48803, 2.48803, 2.48803, 0.666667, 0.666667, -2.48803, -0.178633, -0.178633, -0.178633, -0.666667, -0.666667, 0.178633, -2.48803, 0.666667, 0.666667, -0.666667, 0.178633, -0.666667}, {2.48803, -0.666667, -0.666667, 0.666667, -0.178633, 0.666667, 0.178633, 0.178633, 0.178633, 0.666667, 0.666667, -0.178633, -2.48803, -2.48803, -2.48803, -0.666667, -0.666667, 2.48803, -0.178633, 0.666667, 0.666667, -0.666667, 2.48803, -0.666667}, {0.666667, -0.178633, -0.666667, 2.48803, -0.666667, 0.666667, 0.666667, 0.666667, 0.178633, 0.178633, 0.178633, -0.178633, -0.666667, -0.666667, -2.48803, -2.48803, -2.48803, 2.48803, -0.666667, 2.48803, 0.666667, -0.178633, 0.666667, -0.666667}, {0.666667, -0.666667, -0.178633, 0.178633, -0.178633, 0.178633, 0.666667, 0.178633, 0.666667, 2.48803, 0.666667, -0.666667, -0.666667, -2.48803, -0.666667, -0.178633, -0.666667, 0.666667, -0.666667, 0.666667, 2.48803, -2.48803, 2.48803, -2.48803}, {0.178633, -0.178633, -0.178633, 0.666667, -0.666667, 0.178633, 2.48803, 0.666667, 0.666667, 0.666667, 0.178633, -0.666667, -0.178633, -0.666667, -0.666667, -0.666667, -2.48803, 0.666667, -2.48803, 2.48803, 2.48803, -0.666667, 0.666667, -2.48803}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_hexahedron_8) [
+ Array<double> [
+ + id : my_fem:jacobians:_hexahedron_8
+ + size : 512
+ + nb_component : 1
+ + allocated size : 512
+ + memory size : 4.00KiByte
+ + values : {{0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195313}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195312}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}, {0.00195313}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_pentahedron_15.verified b/test/test_fe_engine/test_fe_engine_precomputation_pentahedron_15.verified
new file mode 100644
index 000000000..300221832
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_pentahedron_15.verified
@@ -0,0 +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 : 57
+ + 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, 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.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}, {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.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, 1, 0.5}, {0.25, 0.5, 1}, {0, 0.75, 1}, {0.25, 0.75, 1}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_pentahedron_15) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_pentahedron_15
+ + size : 8
+ + nb_component : 15
+ + allocated size : 2000
+ + memory size : 117.19KiByte
+ + values : {{6, 7, 0, 15, 16, 8, 21, 19, 18, 22, 23, 20, 26, 25, 24}, {15, 16, 8, 12, 13, 3, 26, 25, 24, 28, 29, 27, 32, 31, 30}, {1, 9, 6, 10, 17, 15, 35, 34, 33, 36, 37, 22, 40, 39, 38}, {10, 17, 15, 4, 14, 12, 40, 39, 38, 41, 42, 28, 45, 44, 43}, {9, 2, 7, 17, 11, 16, 48, 47, 46, 37, 49, 23, 52, 51, 50}, {17, 11, 16, 14, 5, 13, 52, 51, 50, 42, 53, 29, 56, 55, 54}, {7, 6, 9, 16, 15, 17, 21, 34, 46, 23, 22, 37, 26, 39, 50}, {16, 15, 17, 13, 12, 14, 26, 39, 50, 29, 28, 42, 32, 44, 54}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_pentahedron_15)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_pentahedron_15) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_lagrange_pentahedron_15
+ + size : 64
+ + nb_component : 15
+ + allocated size : 64
+ + memory size : 7.50KiByte
+ + values : {{-0.198742, -0.198742, -0.198742, -0.134592, -0.134592, -0.134592, 0.350522, 0.350522, 0.350522, 0.222222, 0.222222, 0.222222, 0.0939222, 0.0939222, 0.0939222}, {-0.105359, -0.161308, -0.161308, -0.174641, -0.0920257, -0.0920257, 0.378564, 0.126188, 0.378564, 0.4, 0.133333, 0.133333, 0.101436, 0.033812, 0.101436}, {-0.161308, -0.105359, -0.161308, -0.0920257, -0.174641, -0.0920257, 0.378564, 0.378564, 0.126188, 0.133333, 0.4, 0.133333, 0.101436, 0.101436, 0.033812}, {-0.161308, -0.161308, -0.105359, -0.0920257, -0.0920257, -0.174641, 0.126188, 0.378564, 0.378564, 0.133333, 0.133333, 0.4, 0.033812, 0.101436, 0.101436}, {-0.134592, -0.134592, -0.134592, -0.198742, -0.198742, -0.198742, 0.0939222, 0.0939222, 0.0939222, 0.222222, 0.222222, 0.222222, 0.350522, 0.350522, 0.350522}, {-0.174641, -0.0920257, -0.0920257, -0.105359, -0.161308, -0.161308, 0.101436, 0.033812, 0.101436, 0.4, 0.133333, 0.133333, 0.378564, 0.126188, 0.378564}, {-0.0920257, -0.174641, -0.0920257, -0.161308, -0.105359, -0.161308, 0.101436, 0.101436, 0.033812, 0.133333, 0.4, 0.133333, 0.378564, 0.378564, 0.126188}, {-0.0920257, -0.0920257, -0.174641, -0.161308, -0.161308, -0.105359, 0.033812, 0.101436, 0.101436, 0.133333, 0.133333, 0.4, 0.126188, 0.378564, 0.378564}, {-0.198742, -0.198742, -0.198742, -0.134592, -0.134592, -0.134592, 0.350522, 0.350522, 0.350522, 0.222222, 0.222222, 0.222222, 0.0939222, 0.0939222, 0.0939222}, {-0.105359, -0.161308, -0.161308, -0.174641, -0.0920257, -0.0920257, 0.378564, 0.126188, 0.378564, 0.4, 0.133333, 0.133333, 0.101436, 0.033812, 0.101436}, {-0.161308, -0.105359, -0.161308, -0.0920257, -0.174641, -0.0920257, 0.378564, 0.378564, 0.126188, 0.133333, 0.4, 0.133333, 0.101436, 0.101436, 0.033812}, {-0.161308, -0.161308, -0.105359, -0.0920257, -0.0920257, -0.174641, 0.126188, 0.378564, 0.378564, 0.133333, 0.133333, 0.4, 0.033812, 0.101436, 0.101436}, {-0.134592, -0.134592, -0.134592, -0.198742, -0.198742, -0.198742, 0.0939222, 0.0939222, 0.0939222, 0.222222, 0.222222, 0.222222, 0.350522, 0.350522, 0.350522}, {-0.174641, -0.0920257, -0.0920257, -0.105359, -0.161308, -0.161308, 0.101436, 0.033812, 0.101436, 0.4, 0.133333, 0.133333, 0.378564, 0.126188, 0.378564}, {-0.0920257, -0.174641, -0.0920257, -0.161308, -0.105359, -0.161308, 0.101436, 0.101436, 0.033812, 0.133333, 0.4, 0.133333, 0.378564, 0.378564, 0.126188}, {-0.0920257, -0.0920257, -0.174641, -0.161308, -0.161308, -0.105359, 0.033812, 0.101436, 0.101436, 0.133333, 0.133333, 0.4, 0.126188, 0.378564, 0.378564}, {-0.198742, -0.198742, -0.198742, -0.134592, -0.134592, -0.134592, 0.350522, 0.350522, 0.350522, 0.222222, 0.222222, 0.222222, 0.0939222, 0.0939222, 0.0939222}, {-0.105359, -0.161308, -0.161308, -0.174641, -0.0920257, -0.0920257, 0.378564, 0.126188, 0.378564, 0.4, 0.133333, 0.133333, 0.101436, 0.033812, 0.101436}, {-0.161308, -0.105359, -0.161308, -0.0920257, -0.174641, -0.0920257, 0.378564, 0.378564, 0.126188, 0.133333, 0.4, 0.133333, 0.101436, 0.101436, 0.033812}, {-0.161308, -0.161308, -0.105359, -0.0920257, -0.0920257, -0.174641, 0.126188, 0.378564, 0.378564, 0.133333, 0.133333, 0.4, 0.033812, 0.101436, 0.101436}, {-0.134592, -0.134592, -0.134592, -0.198742, -0.198742, -0.198742, 0.0939222, 0.0939222, 0.0939222, 0.222222, 0.222222, 0.222222, 0.350522, 0.350522, 0.350522}, {-0.174641, -0.0920257, -0.0920257, -0.105359, -0.161308, -0.161308, 0.101436, 0.033812, 0.101436, 0.4, 0.133333, 0.133333, 0.378564, 0.126188, 0.378564}, {-0.0920257, -0.174641, -0.0920257, -0.161308, -0.105359, -0.161308, 0.101436, 0.101436, 0.033812, 0.133333, 0.4, 0.133333, 0.378564, 0.378564, 0.126188}, {-0.0920257, -0.0920257, -0.174641, -0.161308, -0.161308, -0.105359, 0.033812, 0.101436, 0.101436, 0.133333, 0.133333, 0.4, 0.126188, 0.378564, 0.378564}, {-0.198742, -0.198742, -0.198742, -0.134592, -0.134592, -0.134592, 0.350522, 0.350522, 0.350522, 0.222222, 0.222222, 0.222222, 0.0939222, 0.0939222, 0.0939222}, {-0.105359, -0.161308, -0.161308, -0.174641, -0.0920257, -0.0920257, 0.378564, 0.126188, 0.378564, 0.4, 0.133333, 0.133333, 0.101436, 0.033812, 0.101436}, {-0.161308, -0.105359, -0.161308, -0.0920257, -0.174641, -0.0920257, 0.378564, 0.378564, 0.126188, 0.133333, 0.4, 0.133333, 0.101436, 0.101436, 0.033812}, {-0.161308, -0.161308, -0.105359, -0.0920257, -0.0920257, -0.174641, 0.126188, 0.378564, 0.378564, 0.133333, 0.133333, 0.4, 0.033812, 0.101436, 0.101436}, {-0.134592, -0.134592, -0.134592, -0.198742, -0.198742, -0.198742, 0.0939222, 0.0939222, 0.0939222, 0.222222, 0.222222, 0.222222, 0.350522, 0.350522, 0.350522}, {-0.174641, -0.0920257, -0.0920257, -0.105359, -0.161308, -0.161308, 0.101436, 0.033812, 0.101436, 0.4, 0.133333, 0.133333, 0.378564, 0.126188, 0.378564}, {-0.0920257, -0.174641, -0.0920257, -0.161308, -0.105359, -0.161308, 0.101436, 0.101436, 0.033812, 0.133333, 0.4, 0.133333, 0.378564, 0.378564, 0.126188}, {-0.0920257, -0.0920257, -0.174641, -0.161308, -0.161308, -0.105359, 0.033812, 0.101436, 0.101436, 0.133333, 0.133333, 0.4, 0.126188, 0.378564, 0.378564}, {-0.198742, -0.198742, -0.198742, -0.134592, -0.134592, -0.134592, 0.350522, 0.350522, 0.350522, 0.222222, 0.222222, 0.222222, 0.0939222, 0.0939222, 0.0939222}, {-0.105359, -0.161308, -0.161308, -0.174641, -0.0920257, -0.0920257, 0.378564, 0.126188, 0.378564, 0.4, 0.133333, 0.133333, 0.101436, 0.033812, 0.101436}, {-0.161308, -0.105359, -0.161308, -0.0920257, -0.174641, -0.0920257, 0.378564, 0.378564, 0.126188, 0.133333, 0.4, 0.133333, 0.101436, 0.101436, 0.033812}, {-0.161308, -0.161308, -0.105359, -0.0920257, -0.0920257, -0.174641, 0.126188, 0.378564, 0.378564, 0.133333, 0.133333, 0.4, 0.033812, 0.101436, 0.101436}, {-0.134592, -0.134592, -0.134592, -0.198742, -0.198742, -0.198742, 0.0939222, 0.0939222, 0.0939222, 0.222222, 0.222222, 0.222222, 0.350522, 0.350522, 0.350522}, {-0.174641, -0.0920257, -0.0920257, -0.105359, -0.161308, -0.161308, 0.101436, 0.033812, 0.101436, 0.4, 0.133333, 0.133333, 0.378564, 0.126188, 0.378564}, {-0.0920257, -0.174641, -0.0920257, -0.161308, -0.105359, -0.161308, 0.101436, 0.101436, 0.033812, 0.133333, 0.4, 0.133333, 0.378564, 0.378564, 0.126188}, {-0.0920257, -0.0920257, -0.174641, -0.161308, -0.161308, -0.105359, 0.033812, 0.101436, 0.101436, 0.133333, 0.133333, 0.4, 0.126188, 0.378564, 0.378564}, {-0.198742, -0.198742, -0.198742, -0.134592, -0.134592, -0.134592, 0.350522, 0.350522, 0.350522, 0.222222, 0.222222, 0.222222, 0.0939222, 0.0939222, 0.0939222}, {-0.105359, -0.161308, -0.161308, -0.174641, -0.0920257, -0.0920257, 0.378564, 0.126188, 0.378564, 0.4, 0.133333, 0.133333, 0.101436, 0.033812, 0.101436}, {-0.161308, -0.105359, -0.161308, -0.0920257, -0.174641, -0.0920257, 0.378564, 0.378564, 0.126188, 0.133333, 0.4, 0.133333, 0.101436, 0.101436, 0.033812}, {-0.161308, -0.161308, -0.105359, -0.0920257, -0.0920257, -0.174641, 0.126188, 0.378564, 0.378564, 0.133333, 0.133333, 0.4, 0.033812, 0.101436, 0.101436}, {-0.134592, -0.134592, -0.134592, -0.198742, -0.198742, -0.198742, 0.0939222, 0.0939222, 0.0939222, 0.222222, 0.222222, 0.222222, 0.350522, 0.350522, 0.350522}, {-0.174641, -0.0920257, -0.0920257, -0.105359, -0.161308, -0.161308, 0.101436, 0.033812, 0.101436, 0.4, 0.133333, 0.133333, 0.378564, 0.126188, 0.378564}, {-0.0920257, -0.174641, -0.0920257, -0.161308, -0.105359, -0.161308, 0.101436, 0.101436, 0.033812, 0.133333, 0.4, 0.133333, 0.378564, 0.378564, 0.126188}, {-0.0920257, -0.0920257, -0.174641, -0.161308, -0.161308, -0.105359, 0.033812, 0.101436, 0.101436, 0.133333, 0.133333, 0.4, 0.126188, 0.378564, 0.378564}, {-0.198742, -0.198742, -0.198742, -0.134592, -0.134592, -0.134592, 0.350522, 0.350522, 0.350522, 0.222222, 0.222222, 0.222222, 0.0939222, 0.0939222, 0.0939222}, {-0.105359, -0.161308, -0.161308, -0.174641, -0.0920257, -0.0920257, 0.378564, 0.126188, 0.378564, 0.4, 0.133333, 0.133333, 0.101436, 0.033812, 0.101436}, {-0.161308, -0.105359, -0.161308, -0.0920257, -0.174641, -0.0920257, 0.378564, 0.378564, 0.126188, 0.133333, 0.4, 0.133333, 0.101436, 0.101436, 0.033812}, {-0.161308, -0.161308, -0.105359, -0.0920257, -0.0920257, -0.174641, 0.126188, 0.378564, 0.378564, 0.133333, 0.133333, 0.4, 0.033812, 0.101436, 0.101436}, {-0.134592, -0.134592, -0.134592, -0.198742, -0.198742, -0.198742, 0.0939222, 0.0939222, 0.0939222, 0.222222, 0.222222, 0.222222, 0.350522, 0.350522, 0.350522}, {-0.174641, -0.0920257, -0.0920257, -0.105359, -0.161308, -0.161308, 0.101436, 0.033812, 0.101436, 0.4, 0.133333, 0.133333, 0.378564, 0.126188, 0.378564}, {-0.0920257, -0.174641, -0.0920257, -0.161308, -0.105359, -0.161308, 0.101436, 0.101436, 0.033812, 0.133333, 0.4, 0.133333, 0.378564, 0.378564, 0.126188}, {-0.0920257, -0.0920257, -0.174641, -0.161308, -0.161308, -0.105359, 0.033812, 0.101436, 0.101436, 0.133333, 0.133333, 0.4, 0.126188, 0.378564, 0.378564}, {-0.198742, -0.198742, -0.198742, -0.134592, -0.134592, -0.134592, 0.350522, 0.350522, 0.350522, 0.222222, 0.222222, 0.222222, 0.0939222, 0.0939222, 0.0939222}, {-0.105359, -0.161308, -0.161308, -0.174641, -0.0920257, -0.0920257, 0.378564, 0.126188, 0.378564, 0.4, 0.133333, 0.133333, 0.101436, 0.033812, 0.101436}, {-0.161308, -0.105359, -0.161308, -0.0920257, -0.174641, -0.0920257, 0.378564, 0.378564, 0.126188, 0.133333, 0.4, 0.133333, 0.101436, 0.101436, 0.033812}, {-0.161308, -0.161308, -0.105359, -0.0920257, -0.0920257, -0.174641, 0.126188, 0.378564, 0.378564, 0.133333, 0.133333, 0.4, 0.033812, 0.101436, 0.101436}, {-0.134592, -0.134592, -0.134592, -0.198742, -0.198742, -0.198742, 0.0939222, 0.0939222, 0.0939222, 0.222222, 0.222222, 0.222222, 0.350522, 0.350522, 0.350522}, {-0.174641, -0.0920257, -0.0920257, -0.105359, -0.161308, -0.161308, 0.101436, 0.033812, 0.101436, 0.4, 0.133333, 0.133333, 0.378564, 0.126188, 0.378564}, {-0.0920257, -0.174641, -0.0920257, -0.161308, -0.105359, -0.161308, 0.101436, 0.101436, 0.033812, 0.133333, 0.4, 0.133333, 0.378564, 0.378564, 0.126188}, {-0.0920257, -0.0920257, -0.174641, -0.161308, -0.161308, -0.105359, 0.033812, 0.101436, 0.101436, 0.133333, 0.133333, 0.4, 0.126188, 0.378564, 0.378564}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_pentahedron_15) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_lagrange_pentahedron_15
+ + size : 64
+ + nb_component : 45
+ + allocated size : 64
+ + memory size : 22.50KiByte
+ + values : {{-0.140883, 1.21587e-16, -0.273789, 1.21587e-16, -0.140883, -0.273789, 0.140883, 0.140883, -0.273789, -0.525783, 2.20273e-16, -0.496011, 2.20273e-16, -0.525783, -0.496011, 0.525783, 0.525783, -0.496011, 2.10313, 2.10313, -0.444444, -2.10313, 1.97373e-16, -0.444444, 1.97373e-16, -2.10313, -0.444444, 1.33333, -3.4186e-16, 0.7698, -3.4186e-16, 1.33333, 0.7698, -1.33333, -1.33333, 0.7698, 0.563533, 0.563533, 0.444444, -0.563533, -1.97373e-16, 0.444444, -1.97373e-16, -0.563533, 0.444444}, {1.54162, 0, -0.81282, -4.92673e-17, -0.982137, -0.11094, 0.982137, 0.982137, -0.11094, -0.074957, 0, -0.57282, -1.55849e-16, -0.751197, -0.35094, 0.751197, 0.751197, -0.35094, 1.26188, 3.78564, -0.48, -1.26188, 0, -0.16, -2.52376, -3.78564, -0.48, 1.33333, 0, 1.38564, 2.05116e-16, 1.33333, 0.46188, -1.33333, -1.33333, 0.46188, 0.33812, 1.01436, 0.48, -0.33812, 0, 0.16, -0.67624, -1.01436, 0.48}, {-0.982137, -4.92673e-17, -0.11094, 0, 1.54162, -0.81282, 0.982137, 0.982137, -0.11094, -0.751197, -1.55849e-16, -0.35094, 0, -0.074957, -0.57282, 0.751197, 0.751197, -0.35094, 3.78564, 1.26188, -0.48, -3.78564, -2.52376, -0.48, 0, -1.26188, -0.16, 1.33333, 2.05116e-16, 0.46188, 0, 1.33333, 1.38564, -1.33333, -1.33333, 0.46188, 1.01436, 0.33812, 0.48, -1.01436, -0.67624, 0.48, 0, -0.33812, 0.16}, {-0.982137, 4.92673e-17, -0.11094, 4.92673e-17, -0.982137, -0.11094, -1.54162, -1.54162, -0.81282, -0.751197, 1.55849e-16, -0.35094, 1.55849e-16, -0.751197, -0.35094, 0.074957, 0.074957, -0.57282, 1.26188, 1.26188, -0.16, -1.26188, 2.52376, -0.48, 2.52376, -1.26188, -0.48, 1.33333, -2.05116e-16, 0.46188, -2.05116e-16, 1.33333, 0.46188, -1.33333, -1.33333, 1.38564, 0.33812, 0.33812, 0.16, -0.33812, 0.67624, 0.48, 0.67624, -0.33812, 0.48}, {-0.525783, -5.50683e-17, 0.496011, -5.50683e-17, -0.525783, 0.496011, 0.525783, 0.525783, 0.496011, -0.140883, -3.03967e-17, 0.273789, -3.03967e-17, -0.140883, 0.273789, 0.140883, 0.140883, 0.273789, 0.563533, 0.563533, -0.444444, -0.563533, 4.93432e-17, -0.444444, 4.93432e-17, -0.563533, -0.444444, 1.33333, 8.5465e-17, -0.7698, 8.5465e-17, 1.33333, -0.7698, -1.33333, -1.33333, -0.7698, 2.10313, 2.10313, 0.444444, -2.10313, -4.93432e-17, 0.444444, -4.93432e-17, -2.10313, 0.444444}, {-0.074957, 0, 0.57282, 3.89622e-17, -0.751197, 0.35094, 0.751197, 0.751197, 0.35094, 1.54162, 0, 0.81282, 1.23168e-17, -0.982137, 0.11094, 0.982137, 0.982137, 0.11094, 0.33812, 1.01436, -0.48, -0.33812, 0, -0.16, -0.67624, -1.01436, -0.48, 1.33333, 0, -1.38564, -5.1279e-17, 1.33333, -0.46188, -1.33333, -1.33333, -0.46188, 1.26188, 3.78564, 0.48, -1.26188, 0, 0.16, -2.52376, -3.78564, 0.48}, {-0.751197, 7.79244e-17, 0.35094, 0, -0.074957, 0.57282, 0.751197, 0.751197, 0.35094, -0.982137, 2.46337e-17, 0.11094, 0, 1.54162, 0.81282, 0.982137, 0.982137, 0.11094, 1.01436, 0.33812, -0.48, -1.01436, -0.67624, -0.48, 0, -0.33812, -0.16, 1.33333, -1.02558e-16, -0.46188, 0, 1.33333, -1.38564, -1.33333, -1.33333, -0.46188, 3.78564, 1.26188, 0.48, -3.78564, -2.52376, 0.48, 0, -1.26188, 0.16}, {-0.751197, -3.89622e-17, 0.35094, -3.89622e-17, -0.751197, 0.35094, 0.074957, 0.074957, 0.57282, -0.982137, -1.23168e-17, 0.11094, -1.23168e-17, -0.982137, 0.11094, -1.54162, -1.54162, 0.81282, 0.33812, 0.33812, -0.16, -0.33812, 0.67624, -0.48, 0.67624, -0.33812, -0.48, 1.33333, 5.1279e-17, -0.46188, 5.1279e-17, 1.33333, -0.46188, -1.33333, -1.33333, -1.38564, 1.26188, 1.26188, 0.16, -1.26188, 2.52376, 0.48, 2.52376, -1.26188, 0.48}, {-0.140883, -3.03967e-17, -0.273789, -3.03967e-17, -0.140883, -0.273789, 0.140883, 0.140883, -0.273789, -0.525783, -5.50683e-17, -0.496011, -5.50683e-17, -0.525783, -0.496011, 0.525783, 0.525783, -0.496011, 2.10313, 2.10313, -0.444444, -2.10313, -4.93432e-17, -0.444444, -4.93432e-17, -2.10313, -0.444444, 1.33333, 8.5465e-17, 0.7698, 8.5465e-17, 1.33333, 0.7698, -1.33333, -1.33333, 0.7698, 0.563533, 0.563533, 0.444444, -0.563533, 4.93432e-17, 0.444444, 4.93432e-17, -0.563533, 0.444444}, {1.54162, 0, -0.81282, 1.23168e-17, -0.982137, -0.11094, 0.982137, 0.982137, -0.11094, -0.074957, 0, -0.57282, 3.89622e-17, -0.751197, -0.35094, 0.751197, 0.751197, -0.35094, 1.26188, 3.78564, -0.48, -1.26188, 0, -0.16, -2.52376, -3.78564, -0.48, 1.33333, 0, 1.38564, -5.1279e-17, 1.33333, 0.46188, -1.33333, -1.33333, 0.46188, 0.33812, 1.01436, 0.48, -0.33812, 0, 0.16, -0.67624, -1.01436, 0.48}, {-0.982137, 1.84752e-17, -0.11094, 0, 1.54162, -0.81282, 0.982137, 0.982137, -0.11094, -0.751197, 5.84433e-17, -0.35094, 0, -0.074957, -0.57282, 0.751197, 0.751197, -0.35094, 3.78564, 1.26188, -0.48, -3.78564, -2.52376, -0.48, 0, -1.26188, -0.16, 1.33333, -7.69185e-17, 0.46188, 0, 1.33333, 1.38564, -1.33333, -1.33333, 0.46188, 1.01436, 0.33812, 0.48, -1.01436, -0.67624, 0.48, 0, -0.33812, 0.16}, {-0.982137, -1.23168e-17, -0.11094, -1.23168e-17, -0.982137, -0.11094, -1.54162, -1.54162, -0.81282, -0.751197, -3.89622e-17, -0.35094, -3.89622e-17, -0.751197, -0.35094, 0.074957, 0.074957, -0.57282, 1.26188, 1.26188, -0.16, -1.26188, 2.52376, -0.48, 2.52376, -1.26188, -0.48, 1.33333, 5.1279e-17, 0.46188, 5.1279e-17, 1.33333, 0.46188, -1.33333, -1.33333, 1.38564, 0.33812, 0.33812, 0.16, -0.33812, 0.67624, 0.48, 0.67624, -0.33812, 0.48}, {-0.525783, 2.20273e-16, 0.496011, 2.20273e-16, -0.525783, 0.496011, 0.525783, 0.525783, 0.496011, -0.140883, 1.21587e-16, 0.273789, 1.21587e-16, -0.140883, 0.273789, 0.140883, 0.140883, 0.273789, 0.563533, 0.563533, -0.444444, -0.563533, -1.97373e-16, -0.444444, -1.97373e-16, -0.563533, -0.444444, 1.33333, -3.4186e-16, -0.7698, -3.4186e-16, 1.33333, -0.7698, -1.33333, -1.33333, -0.7698, 2.10313, 2.10313, 0.444444, -2.10313, 1.97373e-16, 0.444444, 1.97373e-16, -2.10313, 0.444444}, {-0.074957, 0, 0.57282, -1.55849e-16, -0.751197, 0.35094, 0.751197, 0.751197, 0.35094, 1.54162, 0, 0.81282, -4.92673e-17, -0.982137, 0.11094, 0.982137, 0.982137, 0.11094, 0.33812, 1.01436, -0.48, -0.33812, 0, -0.16, -0.67624, -1.01436, -0.48, 1.33333, 0, -1.38564, 2.05116e-16, 1.33333, -0.46188, -1.33333, -1.33333, -0.46188, 1.26188, 3.78564, 0.48, -1.26188, 0, 0.16, -2.52376, -3.78564, 0.48}, {-0.751197, -1.55849e-16, 0.35094, 0, -0.074957, 0.57282, 0.751197, 0.751197, 0.35094, -0.982137, -4.92673e-17, 0.11094, 0, 1.54162, 0.81282, 0.982137, 0.982137, 0.11094, 1.01436, 0.33812, -0.48, -1.01436, -0.67624, -0.48, 0, -0.33812, -0.16, 1.33333, 2.05116e-16, -0.46188, 0, 1.33333, -1.38564, -1.33333, -1.33333, -0.46188, 3.78564, 1.26188, 0.48, -3.78564, -2.52376, 0.48, 0, -1.26188, 0.16}, {-0.751197, 1.55849e-16, 0.35094, 1.55849e-16, -0.751197, 0.35094, 0.074957, 0.074957, 0.57282, -0.982137, 4.92673e-17, 0.11094, 4.92673e-17, -0.982137, 0.11094, -1.54162, -1.54162, 0.81282, 0.33812, 0.33812, -0.16, -0.33812, 0.67624, -0.48, 0.67624, -0.33812, -0.48, 1.33333, -2.05116e-16, -0.46188, -2.05116e-16, 1.33333, -0.46188, -1.33333, -1.33333, -1.38564, 1.26188, 1.26188, 0.16, -1.26188, 2.52376, 0.48, 2.52376, -1.26188, 0.48}, {-0.140883, 9.03044e-17, -0.273789, 1.21587e-16, -0.140883, -0.273789, 0.140883, 0.140883, -0.273789, -0.525783, 1.03526e-16, -0.496011, 2.20273e-16, -0.525783, -0.496011, 0.525783, 0.525783, -0.496011, 2.10313, 2.10313, -0.444444, -2.10313, -2.69617e-16, -0.444444, 1.97373e-16, -2.10313, -0.444444, 1.33333, -4.58006e-17, 0.7698, -3.4186e-16, 1.33333, 0.7698, -1.33333, -1.33333, 0.7698, 0.563533, 0.563533, 0.444444, -0.563533, -3.22502e-16, 0.444444, -1.97373e-16, -0.563533, 0.444444}, {1.54162, 0, -0.81282, -4.92673e-17, -0.982137, -0.11094, 0.982137, 0.982137, -0.11094, -0.074957, 0, -0.57282, -1.55849e-16, -0.751197, -0.35094, 0.751197, 0.751197, -0.35094, 1.26188, 3.78564, -0.48, -1.26188, 0, -0.16, -2.52376, -3.78564, -0.48, 1.33333, 0, 1.38564, 2.05116e-16, 1.33333, 0.46188, -1.33333, -1.33333, 0.46188, 0.33812, 1.01436, 0.48, -0.33812, 0, 0.16, -0.67624, -1.01436, 0.48}, {-0.982137, 2.7785e-16, -0.11094, 0, 1.54162, -0.81282, 0.982137, 0.982137, -0.11094, -0.751197, 9.435e-17, -0.35094, 0, -0.074957, -0.57282, 0.751197, 0.751197, -0.35094, 3.78564, 1.26188, -0.48, -3.78564, -2.52376, -0.48, 0, -1.26188, -0.16, 1.33333, -2.38973e-16, 0.46188, 0, 1.33333, 1.38564, -1.33333, -1.33333, 0.46188, 1.01436, 0.33812, 0.48, -1.01436, -0.67624, 0.48, 0, -0.33812, 0.16}, {-0.982137, -3.32369e-16, -0.11094, 4.92673e-17, -0.982137, -0.11094, -1.54162, -1.54162, -0.81282, -0.751197, -1.3605e-16, -0.35094, 1.55849e-16, -0.751197, -0.35094, 0.074957, 0.074957, -0.57282, 1.26188, 1.26188, -0.16, -1.26188, 2.52376, -0.48, 2.52376, -1.26188, -0.48, 1.33333, 3.12988e-16, 0.46188, -2.05116e-16, 1.33333, 0.46188, -1.33333, -1.33333, 1.38564, 0.33812, 0.33812, 0.16, -0.33812, 0.67624, 0.48, 0.67624, -0.33812, 0.48}, {-0.525783, -1.71816e-16, 0.496011, -5.50683e-17, -0.525783, 0.496011, 0.525783, 0.525783, 0.496011, -0.140883, -6.16791e-17, 0.273789, -3.03967e-17, -0.140883, 0.273789, 0.140883, 0.140883, 0.273789, 0.563533, 0.563533, -0.444444, -0.563533, -7.57862e-17, -0.444444, 4.93432e-17, -0.563533, -0.444444, 1.33333, 3.81524e-16, -0.7698, 8.5465e-17, 1.33333, -0.7698, -1.33333, -1.33333, -0.7698, 2.10313, 2.10313, 0.444444, -2.10313, -5.16333e-16, 0.444444, -4.93432e-17, -2.10313, 0.444444}, {-0.074957, 0, 0.57282, 3.89622e-17, -0.751197, 0.35094, 0.751197, 0.751197, 0.35094, 1.54162, 0, 0.81282, 1.23168e-17, -0.982137, 0.11094, 0.982137, 0.982137, 0.11094, 0.33812, 1.01436, -0.48, -0.33812, 0, -0.16, -0.67624, -1.01436, -0.48, 1.33333, 0, -1.38564, -5.1279e-17, 1.33333, -0.46188, -1.33333, -1.33333, -0.46188, 1.26188, 3.78564, 0.48, -1.26188, 0, 0.16, -2.52376, -3.78564, 0.48}, {-0.751197, 2.44724e-16, 0.35094, 0, -0.074957, 0.57282, 0.751197, 0.751197, 0.35094, -0.982137, 2.42712e-16, 0.11094, 0, 1.54162, 0.81282, 0.982137, 0.982137, 0.11094, 1.01436, 0.33812, -0.48, -1.01436, -0.67624, -0.48, 0, -0.33812, -0.16, 1.33333, -3.98617e-16, -0.46188, 0, 1.33333, -1.38564, -1.33333, -1.33333, -0.46188, 3.78564, 1.26188, 0.48, -3.78564, -2.52376, 0.48, 0, -1.26188, 0.16}, {-0.751197, -3.7256e-16, 0.35094, -3.89622e-17, -0.751197, 0.35094, 0.074957, 0.074957, 0.57282, -0.982137, -4.48473e-16, 0.11094, -1.23168e-17, -0.982137, 0.11094, -1.54162, -1.54162, 0.81282, 0.33812, 0.33812, -0.16, -0.33812, 0.67624, -0.48, 0.67624, -0.33812, -0.48, 1.33333, 6.43398e-16, -0.46188, 5.1279e-17, 1.33333, -0.46188, -1.33333, -1.33333, -1.38564, 1.26188, 1.26188, 0.16, -1.26188, 2.52376, 0.48, 2.52376, -1.26188, 0.48}, {-0.140883, -6.16791e-17, -0.273789, -3.03967e-17, -0.140883, -0.273789, 0.140883, 0.140883, -0.273789, -0.525783, -1.71816e-16, -0.496011, -5.50683e-17, -0.525783, -0.496011, 0.525783, 0.525783, -0.496011, 2.10313, 2.10313, -0.444444, -2.10313, -5.16333e-16, -0.444444, -4.93432e-17, -2.10313, -0.444444, 1.33333, 3.81524e-16, 0.7698, 8.5465e-17, 1.33333, 0.7698, -1.33333, -1.33333, 0.7698, 0.563533, 0.563533, 0.444444, -0.563533, -7.57862e-17, 0.444444, 4.93432e-17, -0.563533, 0.444444}, {1.54162, 0, -0.81282, 1.23168e-17, -0.982137, -0.11094, 0.982137, 0.982137, -0.11094, -0.074957, 0, -0.57282, 3.89622e-17, -0.751197, -0.35094, 0.751197, 0.751197, -0.35094, 1.26188, 3.78564, -0.48, -1.26188, 0, -0.16, -2.52376, -3.78564, -0.48, 1.33333, 0, 1.38564, -5.1279e-17, 1.33333, 0.46188, -1.33333, -1.33333, 0.46188, 0.33812, 1.01436, 0.48, -0.33812, 0, 0.16, -0.67624, -1.01436, 0.48}, {-0.982137, 3.45592e-16, -0.11094, 0, 1.54162, -0.81282, 0.982137, 0.982137, -0.11094, -0.751197, 3.08642e-16, -0.35094, 0, -0.074957, -0.57282, 0.751197, 0.751197, -0.35094, 3.78564, 1.26188, -0.48, -3.78564, -2.52376, -0.48, 0, -1.26188, -0.16, 1.33333, -5.21008e-16, 0.46188, 0, 1.33333, 1.38564, -1.33333, -1.33333, 0.46188, 1.01436, 0.33812, 0.48, -1.01436, -0.67624, 0.48, 0, -0.33812, 0.16}, {-0.982137, -3.93954e-16, -0.11094, -1.23168e-17, -0.982137, -0.11094, -1.54162, -1.54162, -0.81282, -0.751197, -3.30861e-16, -0.35094, -3.89622e-17, -0.751197, -0.35094, 0.074957, 0.074957, -0.57282, 1.26188, 1.26188, -0.16, -1.26188, 2.52376, -0.48, 2.52376, -1.26188, -0.48, 1.33333, 5.69383e-16, 0.46188, 5.1279e-17, 1.33333, 0.46188, -1.33333, -1.33333, 1.38564, 0.33812, 0.33812, 0.16, -0.33812, 0.67624, 0.48, 0.67624, -0.33812, 0.48}, {-0.525783, 1.03526e-16, 0.496011, 2.20273e-16, -0.525783, 0.496011, 0.525783, 0.525783, 0.496011, -0.140883, 9.03044e-17, 0.273789, 1.21587e-16, -0.140883, 0.273789, 0.140883, 0.140883, 0.273789, 0.563533, 0.563533, -0.444444, -0.563533, -3.22502e-16, -0.444444, -1.97373e-16, -0.563533, -0.444444, 1.33333, -4.58006e-17, -0.7698, -3.4186e-16, 1.33333, -0.7698, -1.33333, -1.33333, -0.7698, 2.10313, 2.10313, 0.444444, -2.10313, -2.69617e-16, 0.444444, 1.97373e-16, -2.10313, 0.444444}, {-0.074957, 0, 0.57282, -1.55849e-16, -0.751197, 0.35094, 0.751197, 0.751197, 0.35094, 1.54162, 0, 0.81282, -4.92673e-17, -0.982137, 0.11094, 0.982137, 0.982137, 0.11094, 0.33812, 1.01436, -0.48, -0.33812, 0, -0.16, -0.67624, -1.01436, -0.48, 1.33333, 0, -1.38564, 2.05116e-16, 1.33333, -0.46188, -1.33333, -1.33333, -0.46188, 1.26188, 3.78564, 0.48, -1.26188, 0, 0.16, -2.52376, -3.78564, 0.48}, {-0.751197, 1.09504e-17, 0.35094, 0, -0.074957, 0.57282, 0.751197, 0.751197, 0.35094, -0.982137, 1.68811e-16, 0.11094, 0, 1.54162, 0.81282, 0.982137, 0.982137, 0.11094, 1.01436, 0.33812, -0.48, -1.01436, -0.67624, -0.48, 0, -0.33812, -0.16, 1.33333, -9.09435e-17, -0.46188, 0, 1.33333, -1.38564, -1.33333, -1.33333, -0.46188, 3.78564, 1.26188, 0.48, -3.78564, -2.52376, 0.48, 0, -1.26188, 0.16}, {-0.751197, -1.7775e-16, 0.35094, 1.55849e-16, -0.751197, 0.35094, 0.074957, 0.074957, 0.57282, -0.982137, -3.86889e-16, 0.11094, 4.92673e-17, -0.982137, 0.11094, -1.54162, -1.54162, 0.81282, 0.33812, 0.33812, -0.16, -0.33812, 0.67624, -0.48, 0.67624, -0.33812, -0.48, 1.33333, 3.87003e-16, -0.46188, -2.05116e-16, 1.33333, -0.46188, -1.33333, -1.33333, -1.38564, 1.26188, 1.26188, 0.16, -1.26188, 2.52376, 0.48, 2.52376, -1.26188, 0.48}, {-0.140883, 1.21587e-16, -0.273789, 9.03044e-17, -0.140883, -0.273789, 0.140883, 0.140883, -0.273789, -0.525783, 2.20273e-16, -0.496011, 1.03526e-16, -0.525783, -0.496011, 0.525783, 0.525783, -0.496011, 2.10313, 2.10313, -0.444444, -2.10313, 1.97373e-16, -0.444444, -2.69617e-16, -2.10313, -0.444444, 1.33333, -3.4186e-16, 0.7698, -4.58006e-17, 1.33333, 0.7698, -1.33333, -1.33333, 0.7698, 0.563533, 0.563533, 0.444444, -0.563533, -1.97373e-16, 0.444444, -3.22502e-16, -0.563533, 0.444444}, {1.54162, 0, -0.81282, 2.7785e-16, -0.982137, -0.11094, 0.982137, 0.982137, -0.11094, -0.074957, 0, -0.57282, 9.435e-17, -0.751197, -0.35094, 0.751197, 0.751197, -0.35094, 1.26188, 3.78564, -0.48, -1.26188, 0, -0.16, -2.52376, -3.78564, -0.48, 1.33333, 0, 1.38564, -2.38973e-16, 1.33333, 0.46188, -1.33333, -1.33333, 0.46188, 0.33812, 1.01436, 0.48, -0.33812, 0, 0.16, -0.67624, -1.01436, 0.48}, {-0.982137, -4.92673e-17, -0.11094, 0, 1.54162, -0.81282, 0.982137, 0.982137, -0.11094, -0.751197, -1.55849e-16, -0.35094, 0, -0.074957, -0.57282, 0.751197, 0.751197, -0.35094, 3.78564, 1.26188, -0.48, -3.78564, -2.52376, -0.48, 0, -1.26188, -0.16, 1.33333, 2.05116e-16, 0.46188, 0, 1.33333, 1.38564, -1.33333, -1.33333, 0.46188, 1.01436, 0.33812, 0.48, -1.01436, -0.67624, 0.48, 0, -0.33812, 0.16}, {-0.982137, 4.92673e-17, -0.11094, -3.32369e-16, -0.982137, -0.11094, -1.54162, -1.54162, -0.81282, -0.751197, 1.55849e-16, -0.35094, -1.3605e-16, -0.751197, -0.35094, 0.074957, 0.074957, -0.57282, 1.26188, 1.26188, -0.16, -1.26188, 2.52376, -0.48, 2.52376, -1.26188, -0.48, 1.33333, -2.05116e-16, 0.46188, 3.12988e-16, 1.33333, 0.46188, -1.33333, -1.33333, 1.38564, 0.33812, 0.33812, 0.16, -0.33812, 0.67624, 0.48, 0.67624, -0.33812, 0.48}, {-0.525783, -5.50683e-17, 0.496011, -1.71816e-16, -0.525783, 0.496011, 0.525783, 0.525783, 0.496011, -0.140883, -3.03967e-17, 0.273789, -6.16791e-17, -0.140883, 0.273789, 0.140883, 0.140883, 0.273789, 0.563533, 0.563533, -0.444444, -0.563533, 4.93432e-17, -0.444444, -7.57862e-17, -0.563533, -0.444444, 1.33333, 8.5465e-17, -0.7698, 3.81524e-16, 1.33333, -0.7698, -1.33333, -1.33333, -0.7698, 2.10313, 2.10313, 0.444444, -2.10313, -4.93432e-17, 0.444444, -5.16333e-16, -2.10313, 0.444444}, {-0.074957, 0, 0.57282, 2.05761e-16, -0.751197, 0.35094, 0.751197, 0.751197, 0.35094, 1.54162, 0, 0.81282, 2.30395e-16, -0.982137, 0.11094, 0.982137, 0.982137, 0.11094, 0.33812, 1.01436, -0.48, -0.33812, 0, -0.16, -0.67624, -1.01436, -0.48, 1.33333, 0, -1.38564, -3.47338e-16, 1.33333, -0.46188, -1.33333, -1.33333, -0.46188, 1.26188, 3.78564, 0.48, -1.26188, 0, 0.16, -2.52376, -3.78564, 0.48}, {-0.751197, 7.79244e-17, 0.35094, 0, -0.074957, 0.57282, 0.751197, 0.751197, 0.35094, -0.982137, 2.46337e-17, 0.11094, 0, 1.54162, 0.81282, 0.982137, 0.982137, 0.11094, 1.01436, 0.33812, -0.48, -1.01436, -0.67624, -0.48, 0, -0.33812, -0.16, 1.33333, -1.02558e-16, -0.46188, 0, 1.33333, -1.38564, -1.33333, -1.33333, -0.46188, 3.78564, 1.26188, 0.48, -3.78564, -2.52376, 0.48, 0, -1.26188, 0.16}, {-0.751197, -3.89622e-17, 0.35094, -3.7256e-16, -0.751197, 0.35094, 0.074957, 0.074957, 0.57282, -0.982137, -1.23168e-17, 0.11094, -4.48473e-16, -0.982137, 0.11094, -1.54162, -1.54162, 0.81282, 0.33812, 0.33812, -0.16, -0.33812, 0.67624, -0.48, 0.67624, -0.33812, -0.48, 1.33333, 5.1279e-17, -0.46188, 6.43398e-16, 1.33333, -0.46188, -1.33333, -1.33333, -1.38564, 1.26188, 1.26188, 0.16, -1.26188, 2.52376, 0.48, 2.52376, -1.26188, 0.48}, {-0.140883, -3.03967e-17, -0.273789, -6.16791e-17, -0.140883, -0.273789, 0.140883, 0.140883, -0.273789, -0.525783, -5.50683e-17, -0.496011, -1.71816e-16, -0.525783, -0.496011, 0.525783, 0.525783, -0.496011, 2.10313, 2.10313, -0.444444, -2.10313, -4.93432e-17, -0.444444, -5.16333e-16, -2.10313, -0.444444, 1.33333, 8.5465e-17, 0.7698, 3.81524e-16, 1.33333, 0.7698, -1.33333, -1.33333, 0.7698, 0.563533, 0.563533, 0.444444, -0.563533, 4.93432e-17, 0.444444, -7.57862e-17, -0.563533, 0.444444}, {1.54162, 0, -0.81282, 3.39434e-16, -0.982137, -0.11094, 0.982137, 0.982137, -0.11094, -0.074957, 0, -0.57282, 2.89161e-16, -0.751197, -0.35094, 0.751197, 0.751197, -0.35094, 1.26188, 3.78564, -0.48, -1.26188, 0, -0.16, -2.52376, -3.78564, -0.48, 1.33333, 0, 1.38564, -4.95368e-16, 1.33333, 0.46188, -1.33333, -1.33333, 0.46188, 0.33812, 1.01436, 0.48, -0.33812, 0, 0.16, -0.67624, -1.01436, 0.48}, {-0.982137, 1.84752e-17, -0.11094, 0, 1.54162, -0.81282, 0.982137, 0.982137, -0.11094, -0.751197, 5.84433e-17, -0.35094, 0, -0.074957, -0.57282, 0.751197, 0.751197, -0.35094, 3.78564, 1.26188, -0.48, -3.78564, -2.52376, -0.48, 0, -1.26188, -0.16, 1.33333, -7.69185e-17, 0.46188, 0, 1.33333, 1.38564, -1.33333, -1.33333, 0.46188, 1.01436, 0.33812, 0.48, -1.01436, -0.67624, 0.48, 0, -0.33812, 0.16}, {-0.982137, -1.23168e-17, -0.11094, -3.93954e-16, -0.982137, -0.11094, -1.54162, -1.54162, -0.81282, -0.751197, -3.89622e-17, -0.35094, -3.30861e-16, -0.751197, -0.35094, 0.074957, 0.074957, -0.57282, 1.26188, 1.26188, -0.16, -1.26188, 2.52376, -0.48, 2.52376, -1.26188, -0.48, 1.33333, 5.1279e-17, 0.46188, 5.69383e-16, 1.33333, 0.46188, -1.33333, -1.33333, 1.38564, 0.33812, 0.33812, 0.16, -0.33812, 0.67624, 0.48, 0.67624, -0.33812, 0.48}, {-0.525783, 2.20273e-16, 0.496011, 1.03526e-16, -0.525783, 0.496011, 0.525783, 0.525783, 0.496011, -0.140883, 1.21587e-16, 0.273789, 9.03044e-17, -0.140883, 0.273789, 0.140883, 0.140883, 0.273789, 0.563533, 0.563533, -0.444444, -0.563533, -1.97373e-16, -0.444444, -3.22502e-16, -0.563533, -0.444444, 1.33333, -3.4186e-16, -0.7698, -4.58006e-17, 1.33333, -0.7698, -1.33333, -1.33333, -0.7698, 2.10313, 2.10313, 0.444444, -2.10313, 1.97373e-16, 0.444444, -2.69617e-16, -2.10313, 0.444444}, {-0.074957, 0, 0.57282, 1.09504e-17, -0.751197, 0.35094, 0.751197, 0.751197, 0.35094, 1.54162, 0, 0.81282, 1.68811e-16, -0.982137, 0.11094, 0.982137, 0.982137, 0.11094, 0.33812, 1.01436, -0.48, -0.33812, 0, -0.16, -0.67624, -1.01436, -0.48, 1.33333, 0, -1.38564, -9.09435e-17, 1.33333, -0.46188, -1.33333, -1.33333, -0.46188, 1.26188, 3.78564, 0.48, -1.26188, 0, 0.16, -2.52376, -3.78564, 0.48}, {-0.751197, -1.55849e-16, 0.35094, 0, -0.074957, 0.57282, 0.751197, 0.751197, 0.35094, -0.982137, -4.92673e-17, 0.11094, 0, 1.54162, 0.81282, 0.982137, 0.982137, 0.11094, 1.01436, 0.33812, -0.48, -1.01436, -0.67624, -0.48, 0, -0.33812, -0.16, 1.33333, 2.05116e-16, -0.46188, 0, 1.33333, -1.38564, -1.33333, -1.33333, -0.46188, 3.78564, 1.26188, 0.48, -3.78564, -2.52376, 0.48, 0, -1.26188, 0.16}, {-0.751197, 1.55849e-16, 0.35094, -1.7775e-16, -0.751197, 0.35094, 0.074957, 0.074957, 0.57282, -0.982137, 4.92673e-17, 0.11094, -3.86889e-16, -0.982137, 0.11094, -1.54162, -1.54162, 0.81282, 0.33812, 0.33812, -0.16, -0.33812, 0.67624, -0.48, 0.67624, -0.33812, -0.48, 1.33333, -2.05116e-16, -0.46188, 3.87003e-16, 1.33333, -0.46188, -1.33333, -1.33333, -1.38564, 1.26188, 1.26188, 0.16, -1.26188, 2.52376, 0.48, 2.52376, -1.26188, 0.48}, {0.140883, -1.52869e-16, -0.273789, -1.52869e-16, 0.140883, -0.273789, -0.140883, -0.140883, -0.273789, 0.525783, -3.37021e-16, -0.496011, -3.37021e-16, 0.525783, -0.496011, -0.525783, -0.525783, -0.496011, -2.10313, -2.10313, -0.444444, 2.10313, -6.64362e-16, -0.444444, -6.64362e-16, 2.10313, -0.444444, -1.33333, 6.3792e-16, 0.7698, 6.3792e-16, -1.33333, 0.7698, 1.33333, 1.33333, 0.7698, -0.563533, -0.563533, 0.444444, 0.563533, 7.22435e-17, 0.444444, 7.22435e-17, 0.563533, 0.444444}, {-1.54162, 0, -0.81282, 4.30904e-16, 0.982137, -0.11094, -0.982137, -0.982137, -0.11094, 0.074957, 0, -0.57282, 4.47747e-16, 0.751197, -0.35094, -0.751197, -0.751197, -0.35094, -1.26188, -3.78564, -0.48, 1.26188, 0, -0.16, 2.52376, 3.78564, -0.48, -1.33333, 0, 1.38564, -7.2322e-16, -1.33333, 0.46188, 1.33333, 1.33333, 0.46188, -0.33812, -1.01436, 0.48, 0.33812, 0, 0.16, 0.67624, 1.01436, 0.48}, {0.982137, 4.44534e-16, -0.11094, 0, -1.54162, -0.81282, -0.982137, -0.982137, -0.11094, 0.751197, 4.58172e-16, -0.35094, 0, 0.074957, -0.57282, -0.751197, -0.751197, -0.35094, -3.78564, -1.26188, -0.48, 3.78564, 2.52376, -0.48, 0, 1.26188, -0.16, -1.33333, -7.41724e-16, 0.46188, 0, -1.33333, 1.38564, 1.33333, 1.33333, 0.46188, -1.01436, -0.33812, 0.48, 1.01436, 0.67624, 0.48, 0, 0.33812, 0.16}, {0.982137, -4.17274e-16, -0.11094, -4.30904e-16, 0.982137, -0.11094, 1.54162, 1.54162, -0.81282, 0.751197, -4.37322e-16, -0.35094, -4.47747e-16, 0.751197, -0.35094, -0.074957, -0.074957, -0.57282, -1.26188, -1.26188, -0.16, 1.26188, -2.52376, -0.48, -2.52376, 1.26188, -0.48, -1.33333, 7.04716e-16, 0.46188, 7.2322e-16, -1.33333, 0.46188, 1.33333, 1.33333, 1.38564, -0.33812, -0.33812, 0.16, 0.33812, -0.67624, 0.48, -0.67624, 0.33812, 0.48}, {0.525783, -6.16791e-17, 0.496011, -6.16791e-17, 0.525783, 0.496011, -0.525783, -0.525783, 0.496011, 0.140883, -8.85671e-19, 0.273789, -8.85671e-19, 0.140883, 0.273789, -0.140883, -0.140883, 0.273789, -0.563533, -0.563533, -0.444444, 0.563533, -1.74473e-16, -0.444444, -1.74473e-16, 0.563533, -0.444444, -1.33333, 2.10594e-16, -0.7698, 2.10594e-16, -1.33333, -0.7698, 1.33333, 1.33333, -0.7698, -2.10313, -2.10313, 0.444444, 2.10313, -4.17646e-16, 0.444444, -4.17646e-16, 2.10313, 0.444444}, {0.074957, 0, 0.57282, 1.27837e-16, 0.751197, 0.35094, -0.751197, -0.751197, 0.35094, -1.54162, 0, 0.81282, 2.05761e-16, 0.982137, 0.11094, -0.982137, -0.982137, 0.11094, -0.33812, -1.01436, -0.48, 0.33812, 0, -0.16, 0.67624, 1.01436, -0.48, -1.33333, 0, -1.38564, -2.4478e-16, -1.33333, -0.46188, 1.33333, 1.33333, -0.46188, -1.26188, -3.78564, 0.48, 1.26188, 0, 0.16, 2.52376, 3.78564, 0.48}, {0.751197, 8.88748e-17, 0.35094, 0, 0.074957, 0.57282, -0.751197, -0.751197, 0.35094, 0.982137, 1.93445e-16, 0.11094, 0, -1.54162, 0.81282, -0.982137, -0.982137, 0.11094, -1.01436, -0.33812, -0.48, 1.01436, 0.67624, -0.48, 0, 0.33812, -0.16, -1.33333, -1.93501e-16, -0.46188, 0, -1.33333, -1.38564, 1.33333, 1.33333, -0.46188, -3.78564, -1.26188, 0.48, 3.78564, 2.52376, 0.48, 0, 1.26188, 0.16}, {0.751197, -2.94636e-16, 0.35094, -2.94636e-16, 0.751197, 0.35094, -0.074957, -0.074957, 0.57282, 0.982137, -4.23839e-16, 0.11094, -4.23839e-16, 0.982137, 0.11094, 1.54162, 1.54162, 0.81282, -0.33812, -0.33812, -0.16, 0.33812, -0.67624, -0.48, -0.67624, 0.33812, -0.48, -1.33333, 5.4084e-16, -0.46188, 5.4084e-16, -1.33333, -0.46188, 1.33333, 1.33333, -1.38564, -1.26188, -1.26188, 0.16, 1.26188, -2.52376, 0.48, -2.52376, 1.26188, 0.48}, {0.140883, -8.85671e-19, -0.273789, -8.85671e-19, 0.140883, -0.273789, -0.140883, -0.140883, -0.273789, 0.525783, -6.16791e-17, -0.496011, -6.16791e-17, 0.525783, -0.496011, -0.525783, -0.525783, -0.496011, -2.10313, -2.10313, -0.444444, 2.10313, -4.17646e-16, -0.444444, -4.17646e-16, 2.10313, -0.444444, -1.33333, 2.10594e-16, 0.7698, 2.10594e-16, -1.33333, 0.7698, 1.33333, 1.33333, 0.7698, -0.563533, -0.563533, 0.444444, 0.563533, -1.74473e-16, 0.444444, -1.74473e-16, 0.563533, 0.444444}, {-1.54162, 0, -0.81282, 3.6932e-16, 0.982137, -0.11094, -0.982137, -0.982137, -0.11094, 0.074957, 0, -0.57282, 2.52936e-16, 0.751197, -0.35094, -0.751197, -0.751197, -0.35094, -1.26188, -3.78564, -0.48, 1.26188, 0, -0.16, 2.52376, 3.78564, -0.48, -1.33333, 0, 1.38564, -4.66825e-16, -1.33333, 0.46188, 1.33333, 1.33333, 0.46188, -0.33812, -1.01436, 0.48, 0.33812, 0, 0.16, 0.67624, 1.01436, 0.48}, {0.982137, 3.76791e-16, -0.11094, 0, -1.54162, -0.81282, -0.982137, -0.982137, -0.11094, 0.751197, 2.4388e-16, -0.35094, 0, 0.074957, -0.57282, -0.751197, -0.751197, -0.35094, -3.78564, -1.26188, -0.48, 3.78564, 2.52376, -0.48, 0, 1.26188, -0.16, -1.33333, -4.59689e-16, 0.46188, 0, -1.33333, 1.38564, 1.33333, 1.33333, 0.46188, -1.01436, -0.33812, 0.48, 1.01436, 0.67624, 0.48, 0, 0.33812, 0.16}, {0.982137, -3.5569e-16, -0.11094, -3.6932e-16, 0.982137, -0.11094, 1.54162, 1.54162, -0.81282, 0.751197, -2.42511e-16, -0.35094, -2.52936e-16, 0.751197, -0.35094, -0.074957, -0.074957, -0.57282, -1.26188, -1.26188, -0.16, 1.26188, -2.52376, -0.48, -2.52376, 1.26188, -0.48, -1.33333, 4.48321e-16, 0.46188, 4.66825e-16, -1.33333, 0.46188, 1.33333, 1.33333, 1.38564, -0.33812, -0.33812, 0.16, 0.33812, -0.67624, 0.48, -0.67624, 0.33812, 0.48}, {0.525783, -3.37021e-16, 0.496011, -3.37021e-16, 0.525783, 0.496011, -0.525783, -0.525783, 0.496011, 0.140883, -1.52869e-16, 0.273789, -1.52869e-16, 0.140883, 0.273789, -0.140883, -0.140883, 0.273789, -0.563533, -0.563533, -0.444444, 0.563533, 7.22435e-17, -0.444444, 7.22435e-17, 0.563533, -0.444444, -1.33333, 6.3792e-16, -0.7698, 6.3792e-16, -1.33333, -0.7698, 1.33333, 1.33333, -0.7698, -2.10313, -2.10313, 0.444444, 2.10313, -6.64362e-16, 0.444444, -6.64362e-16, 2.10313, 0.444444}, {0.074957, 0, 0.57282, 3.22648e-16, 0.751197, 0.35094, -0.751197, -0.751197, 0.35094, -1.54162, 0, 0.81282, 2.67345e-16, 0.982137, 0.11094, -0.982137, -0.982137, 0.11094, -0.33812, -1.01436, -0.48, 0.33812, 0, -0.16, 0.67624, 1.01436, -0.48, -1.33333, 0, -1.38564, -5.01175e-16, -1.33333, -0.46188, 1.33333, 1.33333, -0.46188, -1.26188, -3.78564, 0.48, 1.26188, 0, 0.16, 2.52376, 3.78564, 0.48}, {0.751197, 3.22648e-16, 0.35094, 0, 0.074957, 0.57282, -0.751197, -0.751197, 0.35094, 0.982137, 2.67345e-16, 0.11094, 0, -1.54162, 0.81282, -0.982137, -0.982137, 0.11094, -1.01436, -0.33812, -0.48, 1.01436, 0.67624, -0.48, 0, 0.33812, -0.16, -1.33333, -5.01175e-16, -0.46188, 0, -1.33333, -1.38564, 1.33333, 1.33333, -0.46188, -3.78564, -1.26188, 0.48, 3.78564, 2.52376, 0.48, 0, 1.26188, 0.16}, {0.751197, -4.89447e-16, 0.35094, -4.89447e-16, 0.751197, 0.35094, -0.074957, -0.074957, 0.57282, 0.982137, -4.85424e-16, 0.11094, -4.85424e-16, 0.982137, 0.11094, 1.54162, 1.54162, 0.81282, -0.33812, -0.33812, -0.16, 0.33812, -0.67624, -0.48, -0.67624, 0.33812, -0.48, -1.33333, 7.97235e-16, -0.46188, 7.97235e-16, -1.33333, -0.46188, 1.33333, 1.33333, -1.38564, -1.26188, -1.26188, 0.16, 1.26188, -2.52376, 0.48, -2.52376, 1.26188, 0.48}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_pentahedron_15) [
+ Array<double> [
+ + id : my_fem:jacobians:_pentahedron_15
+ + size : 64
+ + nb_component : 1
+ + allocated size : 64
+ + memory size : 512.00Byte
+ + values : {{-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351562}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351563}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351563}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351563}, {0.0325521}, {0.0325521}, {0.0325521}, {-0.0351563}, {0.0325521}, {0.0325521}, {0.0325521}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
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
new file mode 100644
index 000000000..71e57878d
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_pentahedron_6.verified
@@ -0,0 +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 : {{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.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 : {{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_fe_engine_precomputation_quadrangle_4.verified b/test/test_fe_engine/test_fe_engine_precomputation_quadrangle_4.verified
new file mode 100644
index 000000000..0b36b473d
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_quadrangle_4.verified
@@ -0,0 +1,109 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 2
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 2
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_point_1) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_point_1
+ + size : 4
+ + nb_component : 1
+ + allocated size : 2000
+ + memory size : 7.81KiByte
+ + values : {{0}, {1}, {2}, {3}}
+ ]
+ ]
+ (not_ghost:_segment_2) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_segment_2
+ + size : 8
+ + nb_component : 2
+ + allocated size : 2000
+ + memory size : 15.62KiByte
+ + values : {{0, 4}, {4, 1}, {1, 5}, {5, 2}, {2, 6}, {6, 3}, {3, 7}, {7, 0}}
+ ]
+ ]
+ (not_ghost:_quadrangle_4) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_quadrangle_4
+ + size : 4
+ + nb_component : 4
+ + allocated size : 2000
+ + memory size : 31.25KiByte
+ + values : {{2, 6, 8, 5}, {5, 8, 4, 1}, {6, 3, 7, 8}, {8, 7, 0, 4}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_quadrangle_4)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_quadrangle_4) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_lagrange_quadrangle_4
+ + size : 16
+ + nb_component : 4
+ + allocated size : 16
+ + memory size : 512.00Byte
+ + values : {{0.622008, 0.166667, 0.0446582, 0.166667}, {0.166667, 0.622008, 0.166667, 0.0446582}, {0.166667, 0.0446582, 0.166667, 0.622008}, {0.0446582, 0.166667, 0.622008, 0.166667}, {0.622008, 0.166667, 0.0446582, 0.166667}, {0.166667, 0.622008, 0.166667, 0.0446582}, {0.166667, 0.0446582, 0.166667, 0.622008}, {0.0446582, 0.166667, 0.622008, 0.166667}, {0.622008, 0.166667, 0.0446582, 0.166667}, {0.166667, 0.622008, 0.166667, 0.0446582}, {0.166667, 0.0446582, 0.166667, 0.622008}, {0.0446582, 0.166667, 0.622008, 0.166667}, {0.622008, 0.166667, 0.0446582, 0.166667}, {0.166667, 0.622008, 0.166667, 0.0446582}, {0.166667, 0.0446582, 0.166667, 0.622008}, {0.0446582, 0.166667, 0.622008, 0.166667}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_quadrangle_4) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_lagrange_quadrangle_4
+ + size : 16
+ + nb_component : 8
+ + allocated size : 16
+ + memory size : 1.00KiByte
+ + values : {{1.57735, 1.57735, -1.57735, 0.42265, -0.42265, -0.42265, 0.42265, -1.57735}, {1.57735, 0.42265, -1.57735, 1.57735, -0.42265, -1.57735, 0.42265, -0.42265}, {0.42265, 1.57735, -0.42265, 0.42265, -1.57735, -0.42265, 1.57735, -1.57735}, {0.42265, 0.42265, -0.42265, 1.57735, -1.57735, -1.57735, 1.57735, -0.42265}, {1.57735, 1.57735, -1.57735, 0.42265, -0.42265, -0.42265, 0.42265, -1.57735}, {1.57735, 0.42265, -1.57735, 1.57735, -0.42265, -1.57735, 0.42265, -0.42265}, {0.42265, 1.57735, -0.42265, 0.42265, -1.57735, -0.42265, 1.57735, -1.57735}, {0.42265, 0.42265, -0.42265, 1.57735, -1.57735, -1.57735, 1.57735, -0.42265}, {1.57735, 1.57735, -1.57735, 0.42265, -0.42265, -0.42265, 0.42265, -1.57735}, {1.57735, 0.42265, -1.57735, 1.57735, -0.42265, -1.57735, 0.42265, -0.42265}, {0.42265, 1.57735, -0.42265, 0.42265, -1.57735, -0.42265, 1.57735, -1.57735}, {0.42265, 0.42265, -0.42265, 1.57735, -1.57735, -1.57735, 1.57735, -0.42265}, {1.57735, 1.57735, -1.57735, 0.42265, -0.42265, -0.42265, 0.42265, -1.57735}, {1.57735, 0.42265, -1.57735, 1.57735, -0.42265, -1.57735, 0.42265, -0.42265}, {0.42265, 1.57735, -0.42265, 0.42265, -1.57735, -0.42265, 1.57735, -1.57735}, {0.42265, 0.42265, -0.42265, 1.57735, -1.57735, -1.57735, 1.57735, -0.42265}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_quadrangle_4) [
+ Array<double> [
+ + id : my_fem:jacobians:_quadrangle_4
+ + size : 16
+ + nb_component : 1
+ + allocated size : 16
+ + memory size : 128.00Byte
+ + values : {{0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_quadrangle_8.verified b/test/test_fe_engine/test_fe_engine_precomputation_quadrangle_8.verified
new file mode 100644
index 000000000..7c906859f
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_quadrangle_8.verified
@@ -0,0 +1,89 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 2
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 2
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_quadrangle_8) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_quadrangle_8
+ + size : 4
+ + nb_component : 8
+ + allocated size : 2000
+ + memory size : 62.50KiByte
+ + values : {{2, 10, 16, 7, 11, 17, 18, 9}, {7, 16, 4, 1, 18, 19, 6, 8}, {10, 3, 13, 16, 12, 14, 20, 17}, {16, 13, 0, 4, 20, 15, 5, 19}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_quadrangle_8)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_serendip_quadrangle_8) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_serendip_quadrangle_8
+ + size : 36
+ + nb_component : 8
+ + allocated size : 36
+ + memory size : 2.25KiByte
+ + values : {{0.432379, -0.1, -0.032379, -0.1, 0.354919, 0.0450807, 0.0450807, 0.354919}, {-0.1, -0.1, -0.1, -0.1, 0.887298, 0.2, 0.112702, 0.2}, {-0.1, 0.432379, -0.1, -0.032379, 0.354919, 0.354919, 0.0450807, 0.0450807}, {-0.1, -0.1, -0.1, -0.1, 0.2, 0.112702, 0.2, 0.887298}, {-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5}, {-0.1, -0.1, -0.1, -0.1, 0.2, 0.887298, 0.2, 0.112702}, {-0.1, -0.032379, -0.1, 0.432379, 0.0450807, 0.0450807, 0.354919, 0.354919}, {-0.1, -0.1, -0.1, -0.1, 0.112702, 0.2, 0.887298, 0.2}, {-0.032379, -0.1, 0.432379, -0.1, 0.0450807, 0.354919, 0.354919, 0.0450807}, {0.432379, -0.1, -0.032379, -0.1, 0.354919, 0.0450807, 0.0450807, 0.354919}, {-0.1, -0.1, -0.1, -0.1, 0.887298, 0.2, 0.112702, 0.2}, {-0.1, 0.432379, -0.1, -0.032379, 0.354919, 0.354919, 0.0450807, 0.0450807}, {-0.1, -0.1, -0.1, -0.1, 0.2, 0.112702, 0.2, 0.887298}, {-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5}, {-0.1, -0.1, -0.1, -0.1, 0.2, 0.887298, 0.2, 0.112702}, {-0.1, -0.032379, -0.1, 0.432379, 0.0450807, 0.0450807, 0.354919, 0.354919}, {-0.1, -0.1, -0.1, -0.1, 0.112702, 0.2, 0.887298, 0.2}, {-0.032379, -0.1, 0.432379, -0.1, 0.0450807, 0.354919, 0.354919, 0.0450807}, {0.432379, -0.1, -0.032379, -0.1, 0.354919, 0.0450807, 0.0450807, 0.354919}, {-0.1, -0.1, -0.1, -0.1, 0.887298, 0.2, 0.112702, 0.2}, {-0.1, 0.432379, -0.1, -0.032379, 0.354919, 0.354919, 0.0450807, 0.0450807}, {-0.1, -0.1, -0.1, -0.1, 0.2, 0.112702, 0.2, 0.887298}, {-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5}, {-0.1, -0.1, -0.1, -0.1, 0.2, 0.887298, 0.2, 0.112702}, {-0.1, -0.032379, -0.1, 0.432379, 0.0450807, 0.0450807, 0.354919, 0.354919}, {-0.1, -0.1, -0.1, -0.1, 0.112702, 0.2, 0.887298, 0.2}, {-0.032379, -0.1, 0.432379, -0.1, 0.0450807, 0.354919, 0.354919, 0.0450807}, {0.432379, -0.1, -0.032379, -0.1, 0.354919, 0.0450807, 0.0450807, 0.354919}, {-0.1, -0.1, -0.1, -0.1, 0.887298, 0.2, 0.112702, 0.2}, {-0.1, 0.432379, -0.1, -0.032379, 0.354919, 0.354919, 0.0450807, 0.0450807}, {-0.1, -0.1, -0.1, -0.1, 0.2, 0.112702, 0.2, 0.887298}, {-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5}, {-0.1, -0.1, -0.1, -0.1, 0.2, 0.887298, 0.2, 0.112702}, {-0.1, -0.032379, -0.1, 0.432379, 0.0450807, 0.0450807, 0.354919, 0.354919}, {-0.1, -0.1, -0.1, -0.1, 0.112702, 0.2, 0.887298, 0.2}, {-0.032379, -0.1, 0.432379, -0.1, 0.0450807, 0.354919, 0.354919, 0.0450807}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_serendip_quadrangle_8) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_serendip_quadrangle_8
+ + size : 36
+ + nb_component : 16
+ + allocated size : 36
+ + memory size : 4.50KiByte
+ + values : {{4.12379, 4.12379, 1.3746, 0.174597, 0.52379, 0.52379, 0.174597, 1.3746, -5.49839, 0.8, -0.8, -0.698387, -0.698387, -0.8, 0.8, -5.49839}, {1.3746, 1.54919, -1.3746, 1.54919, 0.174597, 1.54919, -0.174597, 1.54919, 5.33573e-13, 2, -0.8, -3.09839, -5.33573e-13, -2, 0.8, -3.09839}, {-1.3746, 0.174597, -4.12379, 4.12379, -0.174597, 1.3746, -0.52379, 0.52379, 5.49839, 0.8, -0.8, -5.49839, 0.698387, -0.8, 0.8, -0.698387}, {1.54919, 1.3746, 1.54919, -0.174597, 1.54919, 0.174597, 1.54919, -1.3746, -3.09839, 0.8, -2, 3.39506e-13, -3.09839, -0.8, 2, -3.39506e-13}, {0, 0, 0, 0, 0, 0, 0, 0, 2.36611e-12, 2, -2, 1.88161e-12, -2.36611e-12, -2, 2, -1.88161e-12}, {-1.54919, -0.174597, -1.54919, 1.3746, -1.54919, -1.3746, -1.54919, 0.174597, 3.09839, 0.8, -2, 4.0048e-12, 3.09839, -0.8, 2, -4.0048e-12}, {0.174597, -1.3746, 0.52379, -0.52379, 1.3746, -0.174597, 4.12379, -4.12379, -0.698387, 0.8, -0.8, 0.698387, -5.49839, -0.8, 0.8, 5.49839}, {-0.174597, -1.54919, 0.174597, -1.54919, -1.3746, -1.54919, 1.3746, -1.54919, 4.19886e-12, 2, -0.8, 3.09839, -4.19886e-12, -2, 0.8, 3.09839}, {-0.52379, -0.52379, -0.174597, -1.3746, -4.12379, -4.12379, -1.3746, -0.174597, 0.698387, 0.8, -0.8, 5.49839, 5.49839, -0.8, 0.8, 0.698387}, {4.12379, 4.12379, 1.3746, 0.174597, 0.52379, 0.52379, 0.174597, 1.3746, -5.49839, 0.8, -0.8, -0.698387, -0.698387, -0.8, 0.8, -5.49839}, {1.3746, 1.54919, -1.3746, 1.54919, 0.174597, 1.54919, -0.174597, 1.54919, 4.08307e-12, 2, -0.8, -3.09839, -4.08307e-12, -2, 0.8, -3.09839}, {-1.3746, 0.174597, -4.12379, 4.12379, -0.174597, 1.3746, -0.52379, 0.52379, 5.49839, 0.8, -0.8, -5.49839, 0.698387, -0.8, 0.8, -0.698387}, {1.54919, 1.3746, 1.54919, -0.174597, 1.54919, 0.174597, 1.54919, -1.3746, -3.09839, 0.8, -2, 5.33573e-13, -3.09839, -0.8, 2, -5.33573e-13}, {0, 0, 0, 0, 0, 0, 0, 0, 2.07689e-12, 2, -2, 2.36611e-12, -2.07689e-12, -2, 2, -2.36611e-12}, {-1.54919, -0.174597, -1.54919, 1.3746, -1.54919, -1.3746, -1.54919, 0.174597, 3.09839, 0.8, -2, 4.19864e-12, 3.09839, -0.8, 2, -4.19864e-12}, {0.174597, -1.3746, 0.52379, -0.52379, 1.3746, -0.174597, 4.12379, -4.12379, -0.698387, 0.8, -0.8, 0.698387, -5.49839, -0.8, 0.8, 5.49839}, {-0.174597, -1.54919, 0.174597, -1.54919, -1.3746, -1.54919, 1.3746, -1.54919, 4.17666e-13, 2, -0.8, 3.09839, -4.17666e-13, -2, 0.8, 3.09839}, {-0.52379, -0.52379, -0.174597, -1.3746, -4.12379, -4.12379, -1.3746, -0.174597, 0.698387, 0.8, -0.8, 5.49839, 5.49839, -0.8, 0.8, 0.698387}, {4.12379, 4.12379, 1.3746, 0.174597, 0.52379, 0.52379, 0.174597, 1.3746, -5.49839, 0.8, -0.8, -0.698387, -0.698387, -0.8, 0.8, -5.49839}, {1.3746, 1.54919, -1.3746, 1.54919, 0.174597, 1.54919, -0.174597, 1.54919, 3.39284e-13, 2, -0.8, -3.09839, -3.39284e-13, -2, 0.8, -3.09839}, {-1.3746, 0.174597, -4.12379, 4.12379, -0.174597, 1.3746, -0.52379, 0.52379, 5.49839, 0.8, -0.8, -5.49839, 0.698387, -0.8, 0.8, -0.698387}, {1.54919, 1.3746, 1.54919, -0.174597, 1.54919, 0.174597, 1.54919, -1.3746, -3.09839, 0.8, -2, 4.19864e-12, -3.09839, -0.8, 2, -4.19864e-12}, {0, 0, 0, 0, 0, 0, 0, 0, 1.88161e-12, 2, -2, 2.36589e-12, -1.88161e-12, -2, 2, -2.36589e-12}, {-1.54919, -0.174597, -1.54919, 1.3746, -1.54919, -1.3746, -1.54919, 0.174597, 3.09839, 0.8, -2, 5.3324e-13, 3.09839, -0.8, 2, -5.3324e-13}, {0.174597, -1.3746, 0.52379, -0.52379, 1.3746, -0.174597, 4.12379, -4.12379, -0.698387, 0.8, -0.8, 0.698387, -5.49839, -0.8, 0.8, 5.49839}, {-0.174597, -1.54919, 0.174597, -1.54919, -1.3746, -1.54919, 1.3746, -1.54919, 4.0048e-12, 2, -0.8, 3.09839, -4.0048e-12, -2, 0.8, 3.09839}, {-0.52379, -0.52379, -0.174597, -1.3746, -4.12379, -4.12379, -1.3746, -0.174597, 0.698387, 0.8, -0.8, 5.49839, 5.49839, -0.8, 0.8, 0.698387}, {4.12379, 4.12379, 1.3746, 0.174597, 0.52379, 0.52379, 0.174597, 1.3746, -5.49839, 0.8, -0.8, -0.698387, -0.698387, -0.8, 0.8, -5.49839}, {1.3746, 1.54919, -1.3746, 1.54919, 0.174597, 1.54919, -0.174597, 1.54919, 4.19864e-12, 2, -0.8, -3.09839, -4.19864e-12, -2, 0.8, -3.09839}, {-1.3746, 0.174597, -4.12379, 4.12379, -0.174597, 1.3746, -0.52379, 0.52379, 5.49839, 0.8, -0.8, -5.49839, 0.698387, -0.8, 0.8, -0.698387}, {1.54919, 1.3746, 1.54919, -0.174597, 1.54919, 0.174597, 1.54919, -1.3746, -3.09839, 0.8, -2, 4.08307e-12, -3.09839, -0.8, 2, -4.08307e-12}, {0, 0, 0, 0, 0, 0, 0, 0, 2.36589e-12, 2, -2, 2.07689e-12, -2.36589e-12, -2, 2, -2.07689e-12}, {-1.54919, -0.174597, -1.54919, 1.3746, -1.54919, -1.3746, -1.54919, 0.174597, 3.09839, 0.8, -2, 4.17666e-13, 3.09839, -0.8, 2, -4.17666e-13}, {0.174597, -1.3746, 0.52379, -0.52379, 1.3746, -0.174597, 4.12379, -4.12379, -0.698387, 0.8, -0.8, 0.698387, -5.49839, -0.8, 0.8, 5.49839}, {-0.174597, -1.54919, 0.174597, -1.54919, -1.3746, -1.54919, 1.3746, -1.54919, 5.3324e-13, 2, -0.8, 3.09839, -5.3324e-13, -2, 0.8, 3.09839}, {-0.52379, -0.52379, -0.174597, -1.3746, -4.12379, -4.12379, -1.3746, -0.174597, 0.698387, 0.8, -0.8, 5.49839, 5.49839, -0.8, 0.8, 0.698387}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_quadrangle_8) [
+ Array<double> [
+ + id : my_fem:jacobians:_quadrangle_8
+ + size : 36
+ + nb_component : 1
+ + allocated size : 36
+ + memory size : 288.00Byte
+ + values : {{0.0192901}, {0.0308642}, {0.0192901}, {0.0308642}, {0.0493827}, {0.0308642}, {0.0192901}, {0.0308642}, {0.0192901}, {0.0192901}, {0.0308642}, {0.0192901}, {0.0308642}, {0.0493827}, {0.0308642}, {0.0192901}, {0.0308642}, {0.0192901}, {0.0192901}, {0.0308642}, {0.0192901}, {0.0308642}, {0.0493827}, {0.0308642}, {0.0192901}, {0.0308642}, {0.0192901}, {0.0192901}, {0.0308642}, {0.0192901}, {0.0308642}, {0.0493827}, {0.0308642}, {0.0192901}, {0.0308642}, {0.0192901}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_segment_2.verified b/test/test_fe_engine/test_fe_engine_precomputation_segment_2.verified
new file mode 100644
index 000000000..c530b87cd
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_segment_2.verified
@@ -0,0 +1,99 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 1
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 1
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_point_1) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_point_1
+ + size : 2
+ + nb_component : 1
+ + allocated size : 2000
+ + memory size : 7.81KiByte
+ + values : {{0}, {1}}
+ ]
+ ]
+ (not_ghost:_segment_2) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_segment_2
+ + size : 10
+ + nb_component : 2
+ + allocated size : 2000
+ + memory size : 15.62KiByte
+ + values : {{0, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}, {10, 1}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_segment_2)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_segment_2) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_lagrange_segment_2
+ + size : 10
+ + nb_component : 2
+ + allocated size : 10
+ + memory size : 160.00Byte
+ + 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}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_segment_2) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_lagrange_segment_2
+ + size : 10
+ + nb_component : 2
+ + allocated size : 10
+ + memory size : 160.00Byte
+ + values : {{-10, 10}, {-10, 10}, {-10, 10}, {-10, 10}, {-10, 10}, {-10, 10}, {-10, 10}, {-10, 10}, {-10, 10}, {-10, 10}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_segment_2) [
+ Array<double> [
+ + id : my_fem:jacobians:_segment_2
+ + size : 10
+ + nb_component : 1
+ + allocated size : 10
+ + memory size : 80.00Byte
+ + values : {{0.1}, {0.1}, {0.1}, {0.1}, {0.1}, {0.1}, {0.1}, {0.1}, {0.1}, {0.1}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_segment_3.verified b/test/test_fe_engine/test_fe_engine_precomputation_segment_3.verified
new file mode 100644
index 000000000..4739bfa39
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_segment_3.verified
@@ -0,0 +1,99 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 1
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 1
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_point_1) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_point_1
+ + size : 2
+ + nb_component : 1
+ + allocated size : 2000
+ + memory size : 7.81KiByte
+ + values : {{0}, {1}}
+ ]
+ ]
+ (not_ghost:_segment_3) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_segment_3
+ + size : 10
+ + nb_component : 3
+ + allocated size : 2000
+ + memory size : 23.44KiByte
+ + values : {{0, 2, 11}, {2, 3, 12}, {3, 4, 13}, {4, 5, 14}, {5, 6, 15}, {6, 7, 16}, {7, 8, 17}, {8, 9, 18}, {9, 10, 19}, {10, 1, 20}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_segment_3)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_segment_3) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_lagrange_segment_3
+ + size : 20
+ + nb_component : 3
+ + allocated size : 20
+ + memory size : 480.00Byte
+ + values : {{0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}, {0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}, {0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}, {0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}, {0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}, {0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}, {0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}, {0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}, {0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}, {0.455342, -0.122008, 0.666667}, {-0.122008, 0.455342, 0.666667}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_segment_3) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_lagrange_segment_3
+ + size : 20
+ + nb_component : 3
+ + allocated size : 20
+ + memory size : 480.00Byte
+ + values : {{-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}, {-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}, {-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}, {-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}, {-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}, {-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}, {-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}, {-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}, {-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}, {-21.547, -1.54701, 23.094}, {1.54701, 21.547, -23.094}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_segment_3) [
+ Array<double> [
+ + id : my_fem:jacobians:_segment_3
+ + size : 20
+ + nb_component : 1
+ + allocated size : 20
+ + memory size : 160.00Byte
+ + values : {{0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}, {0.05}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_tetrahedron_10.verified b/test/test_fe_engine/test_fe_engine_precomputation_tetrahedron_10.verified
new file mode 100644
index 000000000..957571c2f
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_tetrahedron_10.verified
@@ -0,0 +1,119 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 3
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 3
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_point_1) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_point_1
+ + size : 8
+ + nb_component : 1
+ + allocated size : 2000
+ + memory size : 7.81KiByte
+ + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
+ ]
+ ]
+ (not_ghost:_segment_3) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_segment_3
+ + size : 48
+ + nb_component : 3
+ + allocated size : 2000
+ + memory size : 23.44KiByte
+ + values : {{6, 8, 11}, {8, 9, 12}, {9, 10, 13}, {10, 7, 14}, {7, 15, 18}, {15, 16, 19}, {16, 17, 20}, {17, 3, 21}, {3, 22, 25}, {22, 23, 26}, {23, 24, 27}, {24, 2, 28}, {2, 29, 32}, {29, 30, 33}, {30, 31, 34}, {31, 6, 35}, {0, 36, 39}, {36, 37, 40}, {37, 38, 41}, {38, 4, 42}, {4, 43, 46}, {43, 44, 47}, {44, 45, 48}, {45, 5, 49}, {5, 50, 53}, {50, 51, 54}, {51, 52, 55}, {52, 1, 56}, {1, 57, 60}, {57, 58, 61}, {58, 59, 62}, {59, 0, 63}, {2, 64, 67}, {64, 65, 68}, {65, 66, 69}, {66, 0, 70}, {6, 71, 74}, {71, 72, 75}, {72, 73, 76}, {73, 4, 77}, {7, 78, 81}, {78, 79, 82}, {79, 80, 83}, {80, 5, 84}, {3, 85, 88}, {85, 86, 89}, {86, 87, 90}, {87, 1, 91}}
+ ]
+ ]
+ (not_ghost:_triangle_6) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_triangle_6
+ + size : 240
+ + nb_component : 6
+ + allocated size : 2000
+ + memory size : 46.88KiByte
+ + values : {{93, 97, 71, 105, 106, 107}, {93, 8, 98, 108, 109, 110}, {94, 78, 99, 111, 112, 113}, {43, 95, 100, 114, 115, 116}, {94, 98, 10, 117, 118, 119}, {73, 97, 95, 120, 121, 122}, {45, 100, 96, 123, 124, 125}, {80, 96, 99, 126, 127, 128}, {71, 97, 72, 106, 129, 75}, {78, 79, 99, 82, 130, 112}, {8, 9, 98, 12, 131, 109}, {43, 100, 44, 116, 132, 47}, {72, 97, 73, 129, 120, 76}, {9, 10, 98, 13, 118, 131}, {79, 80, 99, 83, 128, 130}, {44, 100, 45, 132, 123, 48}, {93, 92, 97, 133, 134, 105}, {93, 98, 92, 110, 135, 133}, {94, 92, 98, 136, 135, 117}, {92, 95, 97, 137, 121, 134}, {94, 99, 92, 113, 138, 136}, {92, 100, 95, 139, 115, 137}, {92, 99, 96, 138, 127, 140}, {92, 96, 100, 140, 124, 139}, {93, 71, 101, 107, 141, 142}, {93, 101, 8, 142, 143, 108}, {94, 102, 78, 144, 145, 111}, {43, 103, 95, 146, 147, 114}, {94, 10, 102, 119, 148, 144}, {73, 95, 103, 122, 147, 149}, {45, 96, 104, 125, 150, 151}, {80, 104, 96, 152, 150, 126}, {4, 73, 103, 77, 149, 153}, {6, 101, 71, 154, 141, 74}, {7, 102, 10, 155, 148, 14}, {7, 78, 102, 81, 145, 155}, {6, 8, 101, 11, 143, 154}, {5, 104, 80, 156, 152, 84}, {4, 103, 43, 153, 146, 46}, {5, 45, 104, 49, 151, 156}, {15, 162, 158, 170, 171, 172}, {22, 163, 159, 173, 174, 175}, {8, 164, 160, 176, 177, 178}, {29, 165, 161, 179, 180, 181}, {10, 158, 164, 182, 183, 184}, {31, 160, 165, 185, 186, 187}, {17, 159, 162, 188, 189, 190}, {24, 161, 163, 191, 192, 193}, {22, 23, 163, 26, 194, 173}, {15, 16, 162, 19, 195, 170}, {29, 30, 165, 33, 196, 179}, {8, 9, 164, 12, 197, 176}, {16, 17, 162, 20, 190, 195}, {23, 24, 163, 27, 193, 194}, {9, 10, 164, 13, 184, 197}, {30, 31, 165, 34, 187, 196}, {158, 162, 157, 171, 198, 199}, {159, 157, 162, 200, 198, 189}, {159, 163, 157, 174, 201, 200}, {161, 157, 163, 202, 201, 192}, {158, 157, 164, 199, 203, 183}, {160, 164, 157, 177, 203, 204}, {160, 157, 165, 204, 205, 186}, {161, 165, 157, 180, 205, 202}, {15, 158, 167, 172, 206, 207}, {22, 159, 166, 175, 208, 209}, {8, 160, 169, 178, 210, 211}, {29, 161, 168, 181, 212, 213}, {10, 167, 158, 214, 206, 182}, {31, 169, 160, 215, 210, 185}, {17, 166, 159, 216, 208, 188}, {24, 168, 161, 217, 212, 191}, {2, 168, 24, 218, 217, 28}, {3, 166, 17, 219, 216, 21}, {6, 169, 31, 220, 215, 35}, {7, 167, 10, 221, 214, 14}, {7, 15, 167, 18, 207, 221}, {3, 22, 166, 25, 209, 219}, {6, 8, 169, 11, 211, 220}, {2, 29, 168, 32, 213, 218}, {50, 227, 223, 235, 236, 237}, {57, 228, 224, 238, 239, 240}, {43, 229, 225, 241, 242, 243}, {36, 230, 226, 244, 245, 246}, {45, 223, 229, 247, 248, 249}, {38, 225, 230, 250, 251, 252}, {52, 224, 227, 253, 254, 255}, {59, 226, 228, 256, 257, 258}, {57, 58, 228, 61, 259, 238}, {50, 51, 227, 54, 260, 235}, {36, 37, 230, 40, 261, 244}, {43, 44, 229, 47, 262, 241}, {51, 52, 227, 55, 255, 260}, {58, 59, 228, 62, 258, 259}, {44, 45, 229, 48, 249, 262}, {37, 38, 230, 41, 252, 261}, {223, 227, 222, 236, 263, 264}, {224, 222, 227, 265, 263, 254}, {224, 228, 222, 239, 266, 265}, {222, 228, 226, 266, 257, 267}, {223, 222, 229, 264, 268, 248}, {222, 225, 229, 269, 242, 268}, {222, 230, 225, 270, 251, 269}, {222, 226, 230, 267, 245, 270}, {50, 223, 232, 237, 271, 272}, {57, 224, 231, 240, 273, 274}, {43, 225, 234, 243, 275, 276}, {36, 226, 233, 246, 277, 278}, {45, 232, 223, 279, 271, 247}, {38, 234, 225, 280, 275, 250}, {52, 231, 224, 281, 273, 253}, {59, 233, 226, 282, 277, 256}, {0, 233, 59, 283, 282, 63}, {1, 231, 52, 284, 281, 56}, {4, 234, 38, 285, 280, 42}, {5, 232, 45, 286, 279, 49}, {5, 50, 232, 53, 272, 286}, {1, 57, 231, 60, 274, 284}, {4, 43, 234, 46, 276, 285}, {0, 36, 233, 39, 278, 283}, {85, 288, 292, 300, 301, 302}, {22, 293, 288, 303, 304, 305}, {57, 290, 294, 306, 307, 308}, {64, 295, 289, 309, 310, 311}, {24, 289, 293, 312, 313, 314}, {87, 292, 290, 315, 316, 317}, {66, 291, 295, 318, 319, 320}, {59, 294, 291, 321, 322, 323}, {85, 292, 86, 302, 324, 89}, {22, 23, 293, 26, 325, 303}, {57, 294, 58, 308, 326, 61}, {64, 65, 295, 68, 327, 309}, {86, 292, 87, 324, 315, 90}, {23, 24, 293, 27, 314, 325}, {65, 66, 295, 69, 320, 327}, {58, 294, 59, 326, 321, 62}, {288, 293, 287, 304, 328, 329}, {288, 287, 292, 329, 330, 301}, {289, 287, 293, 331, 328, 313}, {290, 292, 287, 316, 330, 332}, {289, 295, 287, 310, 333, 331}, {290, 287, 294, 332, 334, 307}, {291, 294, 287, 322, 334, 335}, {291, 287, 295, 335, 333, 319}, {22, 288, 296, 305, 336, 337}, {85, 296, 288, 338, 336, 300}, {57, 298, 290, 339, 340, 306}, {64, 289, 297, 311, 341, 342}, {87, 290, 298, 317, 340, 343}, {24, 297, 289, 344, 341, 312}, {59, 291, 299, 323, 345, 346}, {66, 299, 291, 347, 345, 318}, {1, 87, 298, 91, 343, 348}, {2, 297, 24, 349, 344, 28}, {3, 296, 85, 350, 338, 88}, {3, 22, 296, 25, 337, 350}, {1, 298, 57, 348, 339, 60}, {2, 64, 297, 67, 342, 349}, {0, 59, 299, 63, 346, 351}, {0, 299, 66, 351, 347, 70}, {64, 353, 357, 365, 366, 367}, {29, 358, 353, 368, 369, 370}, {71, 359, 354, 371, 372, 373}, {36, 355, 360, 374, 375, 376}, {31, 354, 358, 377, 378, 379}, {66, 357, 355, 380, 381, 382}, {38, 360, 356, 383, 384, 385}, {73, 356, 359, 386, 387, 388}, {64, 357, 65, 367, 389, 68}, {71, 72, 359, 75, 390, 371}, {29, 30, 358, 33, 391, 368}, {36, 360, 37, 376, 392, 40}, {65, 357, 66, 389, 380, 69}, {30, 31, 358, 34, 379, 391}, {72, 73, 359, 76, 388, 390}, {37, 360, 38, 392, 383, 41}, {353, 352, 357, 393, 394, 366}, {353, 358, 352, 369, 395, 393}, {354, 352, 358, 396, 395, 378}, {355, 357, 352, 381, 394, 397}, {354, 359, 352, 372, 398, 396}, {355, 352, 360, 397, 399, 375}, {356, 352, 359, 400, 398, 387}, {356, 360, 352, 384, 399, 400}, {64, 361, 353, 401, 402, 365}, {29, 353, 361, 370, 402, 403}, {71, 354, 362, 373, 404, 405}, {36, 363, 355, 406, 407, 374}, {31, 362, 354, 408, 404, 377}, {66, 355, 363, 382, 407, 409}, {38, 356, 364, 385, 410, 411}, {73, 364, 356, 412, 410, 386}, {0, 66, 363, 70, 409, 413}, {2, 361, 64, 414, 401, 67}, {6, 362, 31, 415, 408, 35}, {6, 71, 362, 74, 405, 415}, {2, 29, 361, 32, 403, 414}, {4, 364, 73, 416, 412, 77}, {0, 363, 36, 413, 406, 39}, {4, 38, 364, 42, 411, 416}, {15, 418, 423, 430, 431, 432}, {78, 422, 418, 433, 434, 435}, {50, 424, 420, 436, 437, 438}, {85, 419, 425, 439, 440, 441}, {17, 423, 419, 442, 443, 444}, {80, 420, 422, 445, 446, 447}, {87, 425, 421, 448, 449, 450}, {52, 421, 424, 451, 452, 453}, {15, 423, 16, 432, 454, 19}, {78, 79, 422, 82, 455, 433}, {50, 51, 424, 54, 456, 436}, {85, 425, 86, 441, 457, 89}, {79, 80, 422, 83, 447, 455}, {16, 423, 17, 454, 442, 20}, {86, 425, 87, 457, 448, 90}, {51, 52, 424, 55, 453, 456}, {417, 418, 422, 458, 434, 459}, {417, 423, 418, 460, 431, 458}, {419, 423, 417, 443, 460, 461}, {420, 417, 422, 462, 459, 446}, {419, 417, 425, 461, 463, 440}, {420, 424, 417, 437, 464, 462}, {421, 417, 424, 465, 464, 452}, {421, 425, 417, 449, 463, 465}, {15, 426, 418, 466, 467, 430}, {78, 418, 426, 435, 467, 468}, {50, 420, 428, 438, 469, 470}, {85, 427, 419, 471, 472, 439}, {80, 428, 420, 473, 469, 445}, {17, 419, 427, 444, 472, 474}, {52, 429, 421, 475, 476, 451}, {87, 421, 429, 450, 476, 477}, {5, 428, 80, 478, 473, 84}, {3, 17, 427, 21, 474, 479}, {7, 78, 426, 81, 468, 480}, {7, 426, 15, 480, 466, 18}, {5, 50, 428, 53, 470, 478}, {3, 427, 85, 479, 471, 88}, {1, 429, 52, 481, 475, 56}, {1, 87, 429, 91, 477, 481}}
+ ]
+ ]
+ (not_ghost:_tetrahedron_10) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_tetrahedron_10
+ + size : 341
+ + nb_component : 10
+ + allocated size : 2000
+ + memory size : 78.12KiByte
+ + values : {{484, 483, 485, 489, 491, 493, 492, 496, 494, 495}, {87, 290, 490, 292, 317, 498, 497, 315, 316, 499}, {222, 484, 489, 486, 500, 496, 501, 504, 502, 503}, {96, 229, 45, 100, 505, 249, 125, 124, 506, 123}, {59, 0, 233, 299, 63, 283, 282, 346, 351, 507}, {0, 363, 233, 299, 413, 508, 283, 351, 509, 507}, {486, 295, 291, 357, 510, 319, 511, 514, 512, 513}, {484, 222, 489, 485, 500, 501, 496, 492, 515, 495}, {87, 429, 421, 490, 477, 476, 450, 497, 516, 517}, {103, 356, 234, 364, 518, 520, 519, 522, 410, 521}, {356, 103, 234, 225, 518, 519, 520, 524, 523, 275}, {43, 103, 225, 234, 146, 523, 243, 276, 519, 275}, {223, 227, 485, 420, 236, 526, 525, 529, 527, 528}, {483, 92, 484, 485, 530, 531, 491, 493, 532, 492}, {87, 421, 425, 490, 450, 449, 448, 497, 517, 533}, {298, 87, 290, 490, 343, 317, 340, 534, 497, 498}, {482, 483, 488, 489, 535, 537, 536, 539, 494, 538}, {94, 10, 158, 98, 119, 182, 540, 117, 118, 541}, {355, 363, 233, 36, 407, 508, 542, 374, 406, 278}, {485, 420, 424, 417, 528, 437, 543, 544, 462, 464}, {231, 224, 52, 490, 273, 253, 281, 547, 545, 546}, {483, 482, 485, 489, 535, 548, 493, 494, 539, 495}, {167, 15, 7, 426, 207, 18, 221, 549, 466, 480}, {483, 487, 488, 489, 550, 551, 537, 494, 552, 538}, {484, 92, 97, 95, 531, 134, 553, 554, 137, 121}, {29, 165, 30, 358, 179, 196, 33, 368, 555, 391}, {228, 294, 58, 59, 556, 326, 259, 258, 321, 62}, {102, 10, 7, 167, 148, 14, 155, 557, 214, 221}, {9, 10, 98, 164, 13, 118, 131, 197, 184, 558}, {78, 102, 7, 426, 145, 155, 81, 468, 559, 480}, {483, 484, 487, 489, 491, 560, 550, 494, 496, 552}, {16, 423, 162, 17, 454, 561, 195, 20, 442, 190}, {353, 161, 358, 487, 562, 563, 369, 566, 564, 565}, {93, 101, 8, 169, 142, 143, 108, 568, 567, 211}, {78, 422, 79, 99, 433, 455, 82, 112, 569, 130}, {485, 227, 489, 424, 526, 570, 495, 543, 571, 572}, {482, 92, 483, 485, 573, 530, 535, 548, 532, 493}, {223, 222, 229, 484, 264, 268, 248, 575, 500, 574}, {422, 420, 485, 417, 446, 528, 576, 459, 462, 544}, {64, 297, 353, 289, 342, 577, 365, 311, 341, 578}, {101, 6, 8, 169, 154, 11, 143, 567, 220, 211}, {425, 488, 489, 417, 579, 538, 580, 463, 581, 582}, {163, 161, 24, 293, 192, 191, 193, 584, 583, 314}, {228, 294, 59, 226, 556, 321, 258, 257, 585, 256}, {161, 289, 24, 293, 586, 312, 191, 583, 313, 314}, {165, 483, 160, 354, 587, 588, 186, 591, 589, 590}, {103, 356, 95, 225, 518, 592, 147, 523, 524, 593}, {356, 95, 359, 73, 592, 594, 387, 386, 122, 388}, {352, 483, 359, 484, 595, 596, 398, 598, 491, 597}, {103, 43, 4, 234, 146, 46, 153, 519, 276, 285}, {230, 356, 38, 225, 599, 385, 252, 251, 524, 250}, {161, 289, 293, 487, 586, 313, 583, 564, 600, 601}, {161, 487, 293, 163, 564, 601, 583, 192, 602, 584}, {429, 87, 298, 490, 477, 343, 603, 516, 497, 534}, {364, 38, 234, 4, 411, 280, 521, 416, 42, 285}, {22, 296, 3, 166, 337, 350, 25, 209, 604, 219}, {230, 37, 360, 36, 261, 392, 605, 244, 40, 376}, {356, 230, 360, 484, 599, 605, 384, 608, 606, 607}, {22, 23, 293, 163, 26, 325, 303, 173, 194, 584}, {294, 486, 291, 226, 609, 511, 322, 585, 610, 611}, {294, 228, 486, 226, 556, 612, 609, 585, 257, 610}, {3, 17, 166, 427, 21, 216, 219, 479, 474, 613}, {364, 103, 4, 234, 522, 153, 416, 521, 519, 285}, {158, 15, 418, 162, 172, 430, 614, 171, 170, 615}, {15, 423, 418, 162, 432, 431, 430, 170, 561, 615}, {157, 483, 160, 165, 616, 588, 204, 205, 587, 186}, {482, 158, 418, 162, 617, 614, 618, 619, 171, 615}, {423, 482, 418, 162, 620, 618, 431, 561, 619, 615}, {425, 488, 292, 489, 579, 622, 621, 580, 538, 623}, {290, 489, 490, 292, 624, 625, 498, 316, 623, 499}, {222, 223, 485, 484, 264, 525, 515, 500, 575, 492}, {363, 0, 66, 299, 413, 70, 409, 509, 351, 347}, {482, 422, 485, 417, 626, 576, 548, 627, 459, 544}, {486, 290, 287, 489, 628, 332, 629, 503, 624, 630}, {296, 3, 166, 427, 350, 219, 604, 631, 479, 613}, {489, 290, 287, 292, 624, 332, 630, 623, 316, 330}, {488, 85, 427, 419, 632, 471, 633, 634, 439, 472}, {425, 488, 419, 85, 579, 634, 440, 441, 632, 439}, {15, 16, 423, 162, 19, 454, 432, 170, 195, 561}, {65, 64, 357, 295, 68, 367, 389, 327, 309, 512}, {222, 484, 486, 226, 500, 502, 504, 267, 635, 610}, {356, 484, 95, 225, 608, 554, 592, 524, 636, 593}, {352, 484, 486, 487, 598, 502, 637, 639, 560, 638}, {230, 222, 484, 225, 270, 500, 606, 251, 269, 636}, {294, 228, 58, 57, 556, 259, 326, 308, 238, 61}, {352, 483, 484, 487, 595, 491, 598, 639, 550, 560}, {23, 163, 24, 293, 194, 193, 27, 325, 584, 314}, {429, 231, 1, 52, 640, 284, 481, 475, 281, 56}, {228, 222, 486, 226, 266, 504, 612, 257, 267, 610}, {482, 422, 417, 418, 626, 459, 627, 618, 434, 458}, {489, 425, 490, 292, 580, 533, 625, 623, 621, 499}, {483, 92, 97, 484, 530, 134, 641, 491, 531, 553}, {50, 232, 5, 428, 272, 286, 53, 470, 642, 478}, {483, 165, 358, 354, 587, 555, 643, 589, 591, 378}, {157, 483, 487, 488, 616, 550, 644, 645, 537, 551}, {425, 488, 417, 419, 579, 581, 463, 440, 634, 461}, {222, 230, 484, 226, 270, 606, 500, 267, 245, 635}, {299, 363, 233, 291, 509, 508, 507, 345, 646, 647}, {103, 356, 73, 95, 518, 386, 149, 147, 592, 122}, {229, 44, 45, 100, 262, 48, 249, 506, 132, 123}, {356, 230, 38, 360, 599, 252, 385, 384, 605, 383}, {104, 223, 45, 96, 648, 247, 151, 150, 649, 125}, {22, 159, 293, 288, 175, 650, 303, 305, 651, 304}, {352, 356, 360, 484, 400, 384, 399, 598, 608, 607}, {2, 361, 168, 29, 414, 652, 218, 32, 403, 213}, {484, 483, 359, 97, 491, 596, 597, 553, 641, 653}, {483, 157, 160, 164, 616, 204, 588, 654, 203, 177}, {92, 484, 100, 95, 531, 655, 139, 137, 554, 115}, {223, 420, 96, 104, 529, 656, 649, 648, 657, 150}, {85, 425, 292, 86, 441, 621, 302, 89, 457, 324}, {355, 352, 486, 357, 397, 637, 658, 381, 394, 514}, {353, 289, 487, 357, 578, 600, 566, 366, 659, 660}, {66, 295, 357, 291, 320, 512, 380, 318, 319, 513}, {488, 487, 287, 489, 551, 662, 661, 538, 552, 630}, {486, 294, 287, 290, 609, 334, 629, 628, 307, 332}, {227, 223, 485, 222, 236, 525, 526, 263, 264, 515}, {355, 486, 226, 291, 658, 610, 663, 664, 511, 611}, {43, 103, 95, 225, 146, 147, 114, 243, 523, 593}, {356, 230, 484, 225, 599, 606, 608, 524, 251, 636}, {64, 295, 289, 357, 309, 310, 311, 367, 512, 659}, {157, 482, 162, 158, 665, 619, 198, 199, 617, 171}, {223, 229, 45, 96, 248, 249, 247, 649, 505, 125}, {222, 229, 484, 225, 268, 574, 500, 269, 242, 636}, {422, 78, 418, 99, 433, 435, 434, 569, 112, 666}, {422, 80, 79, 99, 447, 83, 455, 569, 128, 130}, {159, 22, 293, 163, 175, 303, 650, 174, 173, 584}, {101, 362, 71, 6, 667, 405, 141, 154, 415, 74}, {93, 483, 354, 160, 668, 589, 669, 670, 588, 590}, {355, 486, 291, 357, 658, 511, 664, 381, 514, 513}, {362, 101, 169, 6, 667, 567, 671, 415, 154, 220}, {94, 482, 418, 99, 672, 618, 673, 113, 674, 666}, {488, 482, 489, 417, 536, 539, 538, 581, 627, 582}, {484, 356, 95, 359, 608, 592, 554, 597, 387, 594}, {363, 355, 233, 291, 407, 542, 508, 646, 664, 647}, {485, 92, 96, 99, 532, 140, 675, 676, 138, 127}, {78, 94, 418, 99, 111, 673, 435, 112, 113, 666}, {92, 483, 97, 93, 530, 641, 134, 133, 668, 105}, {484, 95, 97, 359, 554, 121, 553, 597, 594, 653}, {72, 71, 97, 359, 75, 106, 129, 390, 371, 653}, {94, 482, 99, 92, 672, 674, 113, 136, 573, 138}, {102, 167, 7, 426, 557, 221, 155, 559, 549, 480}, {10, 164, 158, 98, 184, 183, 182, 118, 558, 541}, {482, 422, 99, 485, 626, 569, 674, 548, 576, 676}, {15, 158, 426, 167, 172, 677, 466, 207, 206, 549}, {92, 482, 99, 485, 573, 674, 138, 532, 548, 676}, {158, 15, 426, 418, 172, 466, 677, 614, 430, 467}, {38, 356, 234, 225, 385, 520, 280, 250, 524, 275}, {94, 482, 158, 418, 672, 617, 540, 673, 618, 614}, {364, 356, 234, 38, 410, 520, 521, 411, 385, 280}, {93, 160, 8, 98, 670, 178, 108, 110, 678, 109}, {355, 233, 226, 36, 542, 277, 663, 374, 278, 246}, {160, 93, 8, 169, 670, 108, 178, 210, 568, 211}, {227, 223, 50, 420, 236, 237, 235, 527, 529, 438}, {363, 0, 233, 36, 413, 283, 508, 406, 39, 278}, {486, 295, 287, 291, 510, 333, 629, 511, 319, 335}, {59, 294, 291, 226, 321, 322, 323, 256, 585, 611}, {66, 363, 299, 291, 409, 509, 347, 318, 646, 345}, {486, 352, 487, 357, 637, 639, 638, 514, 394, 660}, {295, 486, 487, 357, 510, 638, 679, 512, 514, 660}, {296, 22, 288, 166, 337, 305, 336, 604, 209, 680}, {361, 64, 2, 297, 401, 67, 414, 681, 342, 349}, {95, 97, 359, 73, 121, 653, 594, 122, 120, 388}, {423, 482, 417, 418, 620, 627, 460, 431, 618, 458}, {65, 295, 357, 66, 327, 512, 389, 69, 320, 380}, {97, 72, 359, 73, 129, 390, 653, 120, 76, 388}, {420, 223, 96, 485, 529, 649, 656, 528, 525, 675}, {159, 488, 293, 288, 682, 683, 650, 651, 684, 304}, {31, 165, 160, 354, 187, 186, 185, 377, 591, 590}, {484, 486, 487, 489, 502, 638, 560, 496, 503, 552}, {486, 295, 487, 287, 510, 679, 638, 629, 333, 662}, {59, 233, 226, 291, 282, 277, 256, 323, 647, 611}, {233, 355, 226, 291, 542, 663, 277, 647, 664, 611}, {425, 421, 489, 490, 449, 685, 580, 533, 517, 625}, {288, 488, 292, 85, 684, 622, 301, 300, 632, 302}, {421, 425, 489, 417, 449, 580, 685, 465, 463, 582}, {294, 228, 57, 290, 556, 238, 308, 307, 686, 306}, {165, 31, 358, 354, 187, 379, 555, 591, 377, 378}, {103, 356, 364, 73, 518, 410, 522, 149, 386, 412}, {352, 483, 358, 354, 595, 643, 395, 396, 589, 378}, {22, 159, 288, 166, 175, 651, 305, 209, 208, 680}, {356, 352, 359, 484, 400, 398, 387, 608, 598, 597}, {64, 361, 353, 297, 401, 402, 365, 342, 681, 577}, {355, 66, 357, 291, 382, 380, 381, 664, 318, 513}, {487, 486, 287, 489, 638, 629, 662, 552, 503, 630}, {298, 57, 490, 290, 339, 687, 534, 340, 306, 498}, {31, 362, 169, 6, 408, 671, 215, 35, 415, 220}, {488, 425, 292, 85, 579, 621, 622, 632, 441, 302}, {483, 352, 359, 354, 595, 398, 596, 589, 396, 372}, {94, 78, 418, 426, 111, 435, 673, 688, 468, 467}, {229, 43, 44, 100, 241, 47, 262, 506, 116, 132}, {31, 165, 358, 30, 187, 555, 379, 34, 196, 391}, {429, 231, 52, 490, 640, 281, 475, 516, 547, 546}, {94, 102, 78, 426, 144, 145, 111, 688, 559, 468}, {421, 429, 52, 490, 476, 475, 451, 517, 516, 546}, {364, 103, 73, 4, 522, 149, 412, 416, 153, 77}, {420, 227, 424, 50, 527, 571, 437, 438, 235, 436}, {104, 80, 5, 428, 152, 84, 156, 689, 473, 478}, {227, 51, 52, 424, 260, 55, 255, 571, 456, 453}, {487, 289, 293, 287, 600, 313, 601, 662, 331, 328}, {166, 159, 288, 488, 208, 651, 680, 690, 682, 684}, {289, 161, 353, 487, 586, 562, 578, 600, 564, 566}, {482, 485, 489, 417, 548, 495, 539, 627, 544, 582}, {50, 227, 424, 51, 235, 571, 436, 54, 260, 456}, {488, 489, 287, 292, 538, 630, 661, 622, 623, 330}, {482, 483, 157, 488, 535, 616, 665, 536, 537, 645}, {80, 420, 104, 96, 445, 657, 152, 126, 656, 150}, {232, 104, 45, 5, 691, 151, 279, 286, 156, 49}, {288, 488, 287, 292, 684, 661, 329, 301, 622, 330}, {295, 289, 487, 287, 310, 600, 679, 333, 331, 662}, {157, 161, 163, 487, 202, 192, 201, 644, 564, 602}, {483, 482, 164, 98, 535, 692, 654, 694, 693, 558}, {3, 296, 85, 427, 350, 338, 88, 479, 631, 471}, {92, 483, 93, 98, 530, 668, 133, 135, 694, 110}, {95, 484, 100, 225, 554, 655, 115, 593, 636, 695}, {231, 224, 490, 57, 273, 545, 547, 274, 240, 687}, {64, 289, 353, 357, 311, 578, 365, 367, 659, 366}, {2, 297, 24, 168, 349, 344, 28, 218, 696, 217}, {361, 297, 168, 353, 681, 696, 652, 402, 577, 697}, {353, 161, 168, 29, 562, 212, 697, 370, 181, 213}, {289, 295, 487, 357, 310, 679, 600, 659, 512, 660}, {352, 353, 487, 357, 393, 566, 639, 394, 366, 660}, {361, 353, 168, 29, 402, 697, 652, 403, 370, 213}, {484, 229, 100, 225, 574, 506, 655, 636, 242, 695}, {104, 223, 232, 45, 648, 271, 691, 151, 247, 279}, {160, 164, 8, 98, 177, 176, 178, 678, 558, 109}, {164, 9, 8, 98, 197, 12, 176, 558, 131, 109}, {165, 161, 358, 29, 180, 563, 555, 179, 181, 368}, {297, 361, 168, 2, 681, 652, 696, 349, 414, 218}, {161, 353, 358, 29, 562, 369, 563, 181, 370, 368}, {230, 37, 38, 360, 261, 41, 252, 605, 392, 383}, {43, 95, 100, 225, 114, 115, 116, 243, 593, 695}, {420, 80, 104, 428, 445, 152, 657, 469, 473, 689}, {232, 104, 5, 428, 691, 156, 286, 642, 689, 478}, {59, 299, 233, 291, 346, 507, 282, 323, 345, 647}, {355, 363, 66, 291, 407, 409, 382, 664, 646, 318}, {158, 94, 418, 426, 540, 673, 614, 677, 688, 467}, {87, 429, 298, 1, 477, 603, 343, 91, 481, 348}, {420, 227, 485, 424, 527, 526, 528, 437, 571, 543}, {482, 422, 418, 99, 626, 434, 618, 674, 569, 666}, {229, 43, 100, 225, 241, 116, 506, 242, 243, 695}, {294, 486, 287, 291, 609, 629, 334, 322, 511, 335}, {17, 166, 419, 159, 216, 698, 444, 188, 208, 699}, {419, 166, 17, 427, 698, 216, 444, 472, 613, 474}, {166, 488, 419, 159, 690, 634, 698, 208, 682, 699}, {419, 488, 166, 427, 634, 690, 698, 472, 633, 613}, {160, 98, 483, 164, 678, 694, 588, 177, 558, 654}, {483, 98, 160, 93, 694, 678, 588, 668, 110, 670}, {226, 360, 486, 355, 700, 701, 610, 663, 375, 658}, {360, 36, 226, 230, 376, 246, 700, 605, 244, 245}, {226, 36, 360, 355, 246, 376, 700, 663, 374, 375}, {93, 169, 362, 101, 568, 671, 702, 142, 567, 667}, {93, 362, 71, 101, 702, 405, 107, 142, 667, 141}, {71, 362, 93, 354, 405, 702, 107, 373, 404, 669}, {489, 424, 417, 485, 572, 464, 582, 495, 543, 544}, {417, 424, 489, 421, 464, 572, 582, 465, 452, 685}, {102, 10, 158, 94, 148, 182, 703, 144, 119, 540}, {158, 10, 102, 167, 182, 148, 703, 206, 214, 557}, {102, 158, 426, 94, 703, 677, 559, 144, 540, 688}, {426, 158, 102, 167, 677, 703, 559, 549, 206, 557}, {421, 489, 227, 424, 685, 570, 704, 452, 572, 571}, {52, 421, 227, 424, 451, 704, 255, 453, 452, 571}, {489, 227, 222, 224, 570, 263, 501, 705, 254, 265}, {489, 222, 227, 485, 501, 263, 570, 495, 515, 526}, {87, 425, 292, 490, 448, 621, 315, 497, 533, 499}, {292, 425, 87, 86, 621, 448, 315, 324, 457, 90}, {104, 420, 232, 223, 657, 706, 691, 648, 529, 271}, {104, 232, 420, 428, 691, 706, 657, 689, 642, 469}, {232, 420, 50, 223, 706, 438, 272, 271, 529, 237}, {232, 50, 420, 428, 272, 438, 706, 642, 470, 469}, {226, 484, 360, 230, 635, 607, 700, 245, 606, 605}, {226, 360, 484, 486, 700, 607, 635, 610, 701, 502}, {486, 360, 352, 355, 701, 399, 637, 658, 375, 397}, {352, 360, 486, 484, 399, 701, 637, 598, 607, 502}, {162, 488, 157, 159, 707, 645, 198, 189, 682, 200}, {157, 488, 162, 482, 645, 707, 198, 665, 536, 619}, {490, 57, 429, 231, 687, 708, 516, 547, 274, 640}, {429, 57, 490, 298, 708, 687, 516, 603, 339, 534}, {57, 1, 429, 231, 60, 481, 708, 274, 284, 640}, {429, 1, 57, 298, 481, 60, 708, 603, 348, 339}, {158, 98, 482, 94, 541, 693, 617, 540, 117, 672}, {482, 98, 158, 164, 693, 541, 617, 692, 558, 183}, {353, 297, 161, 289, 577, 709, 562, 578, 341, 586}, {353, 161, 297, 168, 562, 709, 577, 697, 212, 696}, {161, 297, 24, 289, 709, 344, 191, 586, 341, 312}, {161, 24, 297, 168, 191, 344, 709, 212, 217, 696}, {159, 293, 487, 163, 650, 601, 710, 174, 584, 602}, {487, 293, 159, 488, 601, 650, 710, 551, 683, 682}, {159, 487, 157, 163, 710, 644, 200, 174, 602, 201}, {157, 487, 159, 488, 644, 710, 200, 645, 551, 682}, {290, 228, 486, 294, 686, 612, 628, 307, 556, 609}, {290, 486, 228, 489, 628, 612, 686, 624, 503, 711}, {485, 99, 420, 422, 676, 712, 528, 576, 569, 446}, {420, 99, 485, 96, 712, 676, 528, 656, 127, 675}, {99, 80, 420, 422, 128, 445, 712, 569, 447, 446}, {420, 80, 99, 96, 445, 128, 712, 656, 126, 127}, {96, 484, 229, 100, 713, 574, 505, 124, 655, 506}, {92, 96, 484, 485, 140, 713, 531, 532, 675, 492}, {92, 484, 96, 100, 531, 713, 140, 139, 655, 124}, {161, 358, 483, 165, 563, 643, 714, 180, 555, 587}, {483, 358, 161, 487, 643, 563, 714, 550, 565, 564}, {161, 483, 157, 165, 714, 616, 202, 180, 587, 205}, {157, 483, 161, 487, 616, 714, 202, 644, 550, 564}, {362, 31, 160, 354, 408, 185, 715, 404, 377, 590}, {160, 31, 362, 169, 185, 408, 715, 210, 215, 671}, {362, 160, 93, 354, 715, 670, 702, 404, 590, 669}, {93, 160, 362, 169, 670, 715, 702, 568, 210, 671}, {482, 164, 157, 483, 692, 203, 665, 535, 654, 616}, {157, 164, 482, 158, 203, 692, 665, 199, 183, 617}, {228, 489, 222, 224, 711, 501, 266, 239, 705, 265}, {222, 489, 228, 486, 501, 711, 266, 504, 503, 612}, {288, 166, 427, 296, 680, 613, 716, 336, 604, 631}, {288, 427, 166, 488, 716, 613, 680, 684, 633, 690}, {85, 288, 427, 296, 300, 716, 471, 338, 336, 631}, {85, 427, 288, 488, 471, 716, 300, 632, 633, 684}, {484, 223, 96, 229, 575, 649, 713, 574, 248, 505}, {484, 96, 223, 485, 713, 649, 575, 492, 675, 525}, {488, 293, 287, 487, 683, 328, 661, 551, 601, 662}, {287, 293, 488, 288, 328, 683, 661, 329, 304, 684}, {419, 488, 162, 159, 634, 707, 717, 699, 682, 189}, {162, 419, 17, 423, 717, 444, 190, 561, 443, 442}, {17, 419, 162, 159, 444, 717, 190, 188, 699, 189}, {482, 98, 92, 94, 693, 135, 573, 672, 117, 136}, {92, 98, 482, 483, 135, 693, 573, 530, 694, 535}, {358, 487, 352, 353, 565, 639, 395, 369, 566, 393}, {352, 487, 358, 483, 639, 565, 395, 595, 550, 643}, {359, 483, 93, 97, 596, 668, 718, 653, 641, 105}, {359, 93, 483, 354, 718, 668, 596, 372, 669, 589}, {71, 359, 93, 97, 371, 718, 107, 106, 653, 105}, {71, 93, 359, 354, 107, 718, 371, 373, 669, 372}, {52, 490, 227, 421, 546, 719, 255, 451, 517, 704}, {227, 490, 52, 224, 719, 546, 255, 254, 545, 253}, {490, 489, 227, 421, 625, 570, 719, 517, 685, 704}, {227, 489, 490, 224, 570, 625, 719, 254, 705, 545}, {57, 490, 228, 224, 687, 720, 238, 240, 545, 239}, {228, 490, 57, 290, 720, 687, 238, 686, 498, 306}, {490, 489, 228, 224, 625, 711, 720, 545, 705, 239}, {228, 489, 490, 290, 711, 625, 720, 686, 624, 498}, {162, 419, 482, 488, 717, 721, 619, 707, 634, 536}, {482, 419, 162, 423, 721, 717, 619, 620, 443, 561}, {419, 417, 482, 488, 461, 627, 721, 634, 581, 536}, {482, 417, 419, 423, 627, 461, 721, 620, 460, 443}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_tetrahedron_10)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_tetrahedron_10) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_lagrange_tetrahedron_10
+ + size : 1364
+ + nb_component : 10
+ + allocated size : 1364
+ + memory size : 106.56KiByte
+ + values : {{0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}, {0.1, -0.1, -0.1, -0.1, 0.323607, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932}, {-0.1, 0.1, -0.1, -0.1, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607, 0.0763932}, {-0.1, -0.1, 0.1, -0.1, 0.0763932, 0.323607, 0.323607, 0.0763932, 0.0763932, 0.323607}, {-0.1, -0.1, -0.1, 0.1, 0.0763932, 0.0763932, 0.0763932, 0.323607, 0.323607, 0.323607}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_tetrahedron_10) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_lagrange_tetrahedron_10
+ + size : 1364
+ + nb_component : 30
+ + allocated size : 1364
+ + memory size : 319.69KiByte
+ + values : {{-3.9353, -4.55601, 0.673815, -1.18187e-16, -1.32529, -0.181463, -1.31177, -0.0269554, -1.36103, 1.15091e-15, -0.166427, 1.7671, -1.62143, 5.06211, 1.22778, 1.62143, 1.67146, 1.90663, 5.24706, -1.73604, 7.40408, -1.62143, -1.00576, -8.97503, -1.27652e-15, 1.84386, -1.95995, 1.62143, 0.239033, -0.501928}, {1.31177, 1.51867, -0.224605, -1.29474e-15, 3.97586, 0.54439, -1.31177, -0.0269554, -1.36103, 5.41969e-17, -0.166427, 1.7671, -6.86849, -6.31371, 1.40035, 6.86849, 1.77928, 7.35076, -3.76498e-16, -1.84386, 1.95995, -1.62143, -1.67146, -1.90663, -8.1724e-16, 2.50957, -9.02835, 1.62143, 0.239033, -0.501928}, {1.31177, 1.51867, -0.224605, 1.18187e-16, -1.32529, -0.181463, 3.9353, 0.0808662, 4.08309, -1.15091e-15, -0.166427, 1.7671, -1.62143, -0.239033, 0.501928, 1.62143, 6.97261, 2.63248, -5.24706, -7.91853, 2.85837, -1.62143, -1.67146, -1.90663, 1.27652e-15, 1.84386, -1.95995, 1.62143, 0.90474, -7.57033}, {1.31177, 1.51867, -0.224605, 0, -1.32529, -0.181463, -1.31177, -0.0269554, -1.36103, 0, 0.49928, -5.3013, -1.62143, -0.239033, 0.501928, 1.62143, 1.67146, 1.90663, -9.76951e-16, -1.84386, 1.95995, -6.86849, -7.74614, -1.00821, 0, 7.14501, -1.2341, 6.86849, 0.346855, 4.9422}, {4.62937, -1.83228, -3.04567, 1.74185, 1.32981, 2.03815, 0, 0, -2.39759, -0.198723, -1.94057, -0.655786, -7.21302, -7.71791, -11.9268, -2.15304, -1.64373, 0.444288, 1.90741, -0.754941, 11.2991, 2.94793, 9.40601, 2.17885, -1.90741, 0.754941, -1.7087, 0.245635, 2.39867, 3.77418}, {-1.54312, 0.61076, 1.01522, -5.22554, -3.98943, -6.11446, 0, 0, -2.39759, -0.198723, -1.94057, -0.655786, 5.92686, -4.84171, -7.83507, -2.15304, -1.64373, 10.0346, 1.90741, -0.754941, 1.7087, 2.15304, 1.64373, -0.444288, -1.11252, 8.51722, 0.914444, 0.245635, 2.39867, 3.77418}, {-1.54312, 0.61076, 1.01522, 1.74185, 1.32981, 2.03815, 0, 0, 7.19277, -0.198723, -1.94057, -0.655786, -0.245635, -2.39867, -3.77418, -9.12042, -6.96297, -7.70832, 8.0799, -3.19798, -2.35219, 2.15304, 1.64373, -0.444288, -1.90741, 0.754941, -1.7087, 1.04052, 10.1609, 6.39732}, {-1.54312, 0.61076, 1.01522, 1.74185, 1.32981, 2.03815, 0, 0, -2.39759, 0.596168, 5.82171, 1.96736, -0.245635, -2.39867, -3.77418, -2.15304, -1.64373, 0.444288, 1.90741, -0.754941, 1.7087, 8.32553, -0.799305, -4.50518, -8.87479, -4.5643, -9.86131, 0.245635, 2.39867, 13.3645}, {0.513102, -3.87755, 0, 0.57474, -0.851464, -1.31177, -1.67772, -0.393466, -2.54382e-16, 1.27402, -0.0475867, 1.31177, -2.79797, 2.86069, 6.86849, 1.36336, 1.53882, 1.62143, 8.99608, 0.462577, 1.33227e-15, -6.45943, -1.34847, -6.86849, -2.28519, 1.11129, -2.22045e-16, 0.499008, 0.545171, -1.62143}, {-0.171034, 1.29252, -2.22045e-16, -1.72422, 2.55439, 3.9353, -1.67772, -0.393466, 3.56134e-16, 1.27402, -0.0475867, 1.31177, 0.185129, -5.71524, 1.62143, 8.07425, 3.11268, 1.62143, 2.28519, -1.11129, -4.44089e-16, -1.36336, -1.53882, -1.62143, -7.38126, 1.30164, -5.24706, 0.499008, 0.545171, -1.62143}, {-0.171034, 1.29252, 0, 0.57474, -0.851464, -1.31177, 5.03317, 1.1804, -7.63145e-16, 1.27402, -0.0475867, 1.31177, -0.499008, -0.545171, 1.62143, -0.935598, 4.94468, 6.86849, 2.96933, -6.28136, 0, -1.36336, -1.53882, -1.62143, -2.28519, 1.11129, 2.22045e-16, -4.59706, 0.735518, -6.86849}, {-0.171034, 1.29252, -2.22045e-16, 0.57474, -0.851464, -1.31177, -1.67772, -0.393466, -5.08763e-16, -3.82205, 0.14276, -3.9353, -0.499008, -0.545171, 1.62143, 1.36336, 1.53882, 1.62143, 2.28519, -1.11129, 8.88178e-16, -0.679225, -6.70889, -1.62143, -4.58415, 4.51715, 5.24706, 7.2099, 2.11904, -1.62143}, {3.99239, 5.22128, -5.22376, -1.12887e-15, -1.155e-16, 2.34313, -0.609885, 1.54187, -1.54513, 1.94068, 0.198561, -2.53925, 1.64495, 2.15129, -14.4211, 0.75386, -1.90585, -0.986372, 4.83836, -5.92203, 5.93812, -8.51658, 1.11161, 11.1434, -2.39881, -0.245434, 0.242418, -1.64495, -2.15129, 5.04857}, {-1.3308, -1.74043, 1.74125, 4.45091e-15, -2.34416e-15, -7.02938, -0.609885, 1.54187, -1.54513, 1.94068, 0.198561, -2.53925, 6.96814, 9.11299, -12.0136, 3.1934, -8.07331, 5.19416, 2.39881, 0.245434, -0.242418, -0.75386, 1.90585, 0.986372, -10.1615, -1.03968, 10.3994, -1.64495, -2.15129, 5.04857}, {-1.3308, -1.74043, 1.74125, 0, 0, 2.34313, 1.82966, -4.6256, 4.6354, 1.94068, 0.198561, -2.53925, 1.64495, 2.15129, -5.04857, 0.75386, -1.90585, -10.3589, 7.722, 7.20714, -7.20743, -0.75386, 1.90585, 0.986372, -2.39881, -0.245434, 0.242418, -9.40768, -2.94553, 15.2056}, {-1.3308, -1.74043, 1.74125, -1.12887e-15, -1.155e-16, 2.34313, -0.609885, 1.54187, -1.54513, -5.82204, -0.595682, 7.61774, 1.64495, 2.15129, -5.04857, 0.75386, -1.90585, -0.986372, 2.39881, 0.245434, -0.242418, 4.56932, 8.86756, -5.97864, -2.39881, -0.245434, -9.13008, 0.794587, -8.31875, 11.2291}, {5.36656, -5.36656, -5.3681, 1.78885, 1.36261, 1.3621, 0, 0, -3.15147, 0, -3.15147, 0, -7.15542, -9.34589, -9.34384, -2.21115, -1.68428, 2.21178, 2.21115, -2.21115, 14.2895, 2.21115, 14.2902, -2.21178, -2.21115, 2.21115, -1.68365, 0, 3.89543, 3.89543}, {-1.78885, 1.78885, 1.78937, -5.36656, -4.08784, -4.08631, 0, 0, -3.15147, 0, -3.15147, 0, 7.15542, -11.0508, -11.0529, -2.21115, -1.68428, 14.8177, 2.21115, -2.21115, 1.68365, 2.21115, 1.68428, -2.21178, -2.21115, 14.817, -1.68365, 0, 3.89543, 3.89543}, {-1.78885, 1.78885, 1.78937, 1.78885, 1.36261, 1.3621, 0, 0, 9.45441, 0, -3.15147, 0, 1.33227e-15, -3.89543, -3.89543, -9.36656, -7.13474, -3.23663, 9.36656, -9.36656, -5.47381, 2.21115, 1.68428, -2.21178, -2.21115, 2.21115, -1.68365, 0, 16.5013, 3.89543}, {-1.78885, 1.78885, 1.78937, 1.78885, 1.36261, 1.3621, 0, 0, -3.15147, 0, 9.45441, 0, 1.33227e-15, -3.89543, -3.89543, -2.21115, -1.68428, 2.21178, 2.21115, -2.21115, 1.68365, 9.36656, -5.47113, -9.36924, -9.36656, -3.23931, -7.13206, 0, 3.89543, 16.5013}, {-4.72653, -4.72788, -4.72653, 1.57551, -1.57551, -1.57596, -1.57551, 1.57551, -1.57551, -1.57551, -1.57596, 1.57596, -10.1969, 6.30148, 6.30439, -1.73195e-14, 1.73195e-14, 3.89543, 6.30204, -10.1975, 6.30204, 6.30204, 6.30384, -10.1993, 2.13962e-12, 3.89543, -2.14073e-12, 3.89487, 0.000556765, -0.000556765}, {1.57551, 1.57596, 1.57551, -4.72653, 4.72653, 4.72788, -1.57551, 1.57551, -1.57551, -1.57551, -1.57596, 1.57596, -10.1969, -6.30439, -6.30148, 6.30204, -6.30204, 10.1975, -2.13851e-12, -3.89543, 2.13696e-12, 1.30375e-14, -1.58287e-14, -3.89543, 6.30204, 10.1993, -6.30384, 3.89487, 0.000556765, -0.000556765}, {1.57551, 1.57596, 1.57551, 1.57551, -1.57551, -1.57596, 4.72653, -4.72653, 4.72653, -1.57551, -1.57596, 1.57596, -3.89487, -0.000556765, 0.000556765, -6.30204, 6.30204, 10.1993, -6.30204, -10.1993, -6.30204, 1.5702e-14, -1.78271e-14, -3.89543, 2.13918e-12, 3.89543, -2.14007e-12, 10.1969, 6.30439, -6.30439}, {1.57551, 1.57596, 1.57551, 1.57551, -1.57551, -1.57596, -1.57551, 1.57551, -1.57551, 4.72653, 4.72788, -4.72788, -3.89487, -0.000556765, 0.000556765, -1.70974e-14, 1.70974e-14, 3.89543, -2.14229e-12, -3.89543, 2.14118e-12, -6.30204, -6.30384, -10.1975, -6.30204, 10.1975, 6.30384, 10.1969, -6.30148, 6.30148}, {3.23101, 1.27881, 3.23101, -1.12016, -2.46258, 1.22297, 0.799503, 2.33566, 0.799503, 1.39766, 0.553185, -0.945467, 7.19648, 13.4211, -5.07228, 0.396353, 0.156874, -2.49991, -2.85501, -11.7028, -2.85501, -5.98699, -2.36962, 6.28178, -0.343007, 2.36014, -0.343007, -2.71584, -3.57081, 0.180421}, {-1.077, -0.426271, -1.077, 3.36048, 7.38773, -3.6689, 0.799503, 2.33566, 0.799503, 1.39766, 0.553185, -0.945467, 7.02385, 5.2759, 4.12759, -2.80166, -9.18577, -5.69792, 0.343007, -2.36014, 0.343007, -0.396353, -0.156874, 2.49991, -5.93364, 0.147394, 3.43886, -2.71584, -3.57081, 0.180421}, {-1.077, -0.426271, -1.077, -1.12016, -2.46258, 1.22297, -2.39851, -7.00698, -2.39851, 1.39766, 0.553185, -0.945467, 2.71584, 3.57081, -0.180421, 4.87699, 10.0072, -7.39177, 4.65101, -0.65505, 4.65101, -0.396353, -0.156874, 2.49991, -0.343007, 2.36014, -0.343007, -8.30647, -5.78355, 3.96229}, {-1.077, -0.426271, -1.077, -1.12016, -2.46258, 1.22297, 0.799503, 2.33566, 0.799503, -4.19298, -1.65956, 2.8364, 2.71584, 3.57081, -0.180421, 0.396353, 0.156874, -2.49991, 0.343007, -2.36014, 0.343007, 3.91165, 1.54821, 6.80792, 4.13763, 12.2104, -5.23487, -5.91385, -12.9135, -3.01759}, {-3.9353, 2.63698, 1.65871, -1.52066e-16, 1.28613, 0.176102, 6.36808e-16, -0.456132, 1.72743, -1.31177, 0.0489967, -1.35063, -1.62143, -5.64776, -0.238656, -5.99174e-16, -1.02593, -2.3529, -1.62143, 3.47483, -8.36153, 5.24706, 0.829946, 7.75543, 1.62143, -1.65031, 1.4518, 1.62143, 0.503247, -0.465751}, {1.31177, -0.878994, -0.552902, -5.42221e-16, -3.85839, -0.528305, -3.55539e-16, -0.456132, 1.72743, -1.31177, 0.0489967, -1.35063, -6.86849, 3.01273, 2.67736, 1.63822e-15, 0.798596, -9.26263, -1.62143, 1.65031, -1.4518, -1.19301e-15, 1.02593, 2.3529, 6.86849, -1.84629, 6.85433, 1.62143, 0.503247, -0.465751}, {1.31177, -0.878994, -0.552902, 0, 1.28613, 0.176102, 0, 1.3684, -5.1823, -1.31177, 0.0489967, -1.35063, -1.62143, -0.503247, 0.465751, 0, -6.17045, -3.0573, -6.86849, 5.16628, 0.75981, -9.76951e-16, 1.02593, 2.3529, 1.62143, -1.65031, 1.4518, 6.86849, 0.30726, 4.93678}, {1.31177, -0.878994, -0.552902, -1.72043e-16, 1.28613, 0.176102, -1.68762e-15, -0.456132, 1.72743, 3.9353, -0.14699, 4.0519, -1.62143, -0.503247, 0.465751, 2.29866e-15, -1.02593, -2.3529, -1.62143, 1.65031, -1.4518, -5.24706, 4.54191, 4.56451, 1.62143, -6.79482, 0.747392, 1.62143, 2.32778, -7.37548}, {0.56235, 5.36656, -5.36656, -1.24953, 3.64699, -0.373467, -0.986118, -1.85814, -1.41539, 2.4231, 0, 0, 6.77433, -16.8847, -0.255645, 2.76341, -2.21115, 2.21115, 5.39508, 11.9405, 5.19992, -12.4558, 2.21115, -2.21115, -1.45061, -4.50793, 0.461631, -1.77621, 2.29678, 1.74951}, {-0.18745, -1.78885, 1.78885, 3.74859, -10.941, 1.1204, -0.986118, -1.85814, -1.41539, 2.4231, -1.11775e-15, -8.51416e-16, 2.52601, 4.85864, -8.90493, 6.70789, 5.2214, 7.87269, 1.45061, 4.50793, -0.461631, -2.76341, 2.21115, -2.21115, -11.143, -4.50793, 0.461631, -1.77621, 2.29678, 1.74951}, {-0.18745, -1.78885, 1.78885, -1.24953, 3.64699, -0.373467, 2.95835, 5.57441, 4.24616, 2.4231, 0, 0, 1.77621, -2.29678, -1.74951, 7.76154, -16.7991, 3.70501, 2.20041, 11.6633, -7.61705, -2.76341, 2.21115, -2.21115, -1.45061, -4.50793, 0.461631, -11.4686, 2.29678, 1.74951}, {-0.18745, -1.78885, 1.78885, -1.24953, 3.64699, -0.373467, -0.986118, -1.85814, -1.41539, -7.2693, 0, 0, 1.77621, -2.29678, -1.74951, 2.76341, -2.21115, 2.21115, 1.45061, 4.50793, -0.461631, -2.01361, 9.36656, -9.36656, 3.54752, -19.0959, 1.9555, 2.16826, 9.72932, 7.41106}, {4.72585, 4.7272, 4.7272, -1.63629, -1.63676, 1.63676, -1.57573, 1.57528, 1.57528, 4.78731, 1.63721, -1.63631, 10.5149, 10.5179, -6.62248, 3.97028, 0.0759901, -3.97031, 10.1978, -6.30058, -6.30058, -23.1195, -6.62484, 10.5155, -3.89487, -0.000556685, -0.000556685, -3.96973, -3.97086, 0.0754336}, {-1.57528, -1.57573, -1.57573, 4.90888, 4.91028, -4.91028, -1.57573, 1.57528, 1.57528, 4.78731, 1.63721, -1.63631, 10.2709, 10.2738, 6.2275, 10.2732, -6.22515, -10.2714, 3.89487, 0.000556685, 0.000556685, -3.97028, -0.0759901, 3.97031, -23.0441, -6.5494, 6.54469, -3.96973, -3.97086, 0.0754336}, {-1.57528, -1.57573, -1.57573, -1.63629, -1.63676, 1.63676, 4.7272, -4.72585, -4.72585, 4.78731, 1.63721, -1.63631, 3.96973, 3.97086, -0.0754336, 10.5155, 6.62303, -10.5174, 10.196, 6.30349, 6.30349, -3.97028, -0.0759901, 3.97031, -3.89487, -0.000556685, -0.000556685, -23.119, -10.5197, 6.62068}, {-1.57528, -1.57573, -1.57573, -1.63629, -1.63676, 1.63676, -1.57573, 1.57528, 1.57528, -14.3619, -4.91163, 4.90893, 3.96973, 3.97086, -0.0754336, 3.97028, 0.0759901, -3.97031, 3.89487, 0.000556685, 0.000556685, 2.33085, 6.22695, 10.2732, 2.6503, 6.54649, -6.5476, 2.33321, -10.272, -6.2257}, {-2.40635, 2.40855, -2.40993, -1.57388, -1.57525, -1.57621, 3.20871, 3.21151, -0.0600473, -2.43695, -0.833412, 0.832954, 7.24946, 9.24051, 7.26022, -2.02076, -2.02253, 2.02253, -17.7925, -15.8233, -0.678532, 11.7686, 5.35618, -5.35435, 4.95766, 2.97727, 0.918721, -0.953948, -2.9395, -0.955365}, {0.802117, -0.80285, 0.803308, 4.72163, 4.72576, 4.72864, 3.20871, 3.21151, -0.0600473, -2.43695, -0.833412, 0.832954, -2.25452, 6.1509, -2.25787, -14.8556, -14.8686, 2.26272, -4.95766, -2.97727, -0.918721, 2.02076, 2.02253, -2.02253, 14.7055, 6.31092, -2.41309, -0.953948, -2.9395, -0.955365}, {0.802117, -0.80285, 0.803308, -1.57388, -1.57525, -1.57621, -9.62613, -9.63454, 0.180142, -2.43695, -0.833412, 0.832954, 0.953948, 2.9395, 0.955365, 4.27475, 4.27848, 8.32739, -8.16613, 0.234124, -4.13196, 2.02076, 2.02253, -2.02253, 4.95766, 2.97727, 0.918721, 8.79385, 0.394151, -4.28718}, {0.802117, -0.80285, 0.803308, -1.57388, -1.57525, -1.57621, 3.20871, 3.21151, -0.0600473, 7.31085, 2.50024, -2.49886, 0.953948, 2.9395, 0.955365, -2.02076, -2.02253, 2.02253, -4.95766, -2.97727, -0.918721, -1.18771, 5.23393, -5.23576, 11.2532, 9.27829, 7.22358, -13.7888, -15.7856, -0.715176}, {5.36291, -5.36781, 5.37088, 0, -3.15057, 0, -1.85687, -1.41402, 1.41389, 3.64451, 2.77532, 0.376399, 2.20964, 14.2849, 2.21292, 2.29522, 5.64214, -1.74767, 11.9323, 5.19225, -5.19032, -16.8733, -16.7434, 0.242074, -4.50486, 0.463834, -0.465254, -2.20964, -1.68266, -2.21292}, {-1.78764, 1.78927, -1.79029, 0, 9.4517, 0, -1.85687, -1.41402, 1.41389, 3.64451, 2.77532, 0.376399, 9.36019, -5.47442, 9.37409, 9.72271, 11.2982, -7.40324, 4.50486, -0.463834, 0.465254, -2.29522, -5.64214, 1.74767, -19.0829, -10.6374, -1.97085, -2.20964, -1.68266, -2.21292}, {-1.78764, 1.78927, -1.79029, 0, -3.15057, 0, 5.57061, 4.24206, -4.24168, 3.64451, 2.77532, 0.376399, 2.20964, 1.68266, 2.21292, 2.29522, 18.2444, -1.74767, 11.6554, -7.62091, 7.62642, -2.29522, -5.64214, 1.74767, -4.50486, 0.463834, -0.465254, -16.7877, -12.7839, -3.71852}, {-1.78764, 1.78927, -1.79029, 0, -3.15057, 0, -1.85687, -1.41402, 1.41389, -10.9335, -8.32596, -1.1292, 2.20964, 1.68266, 2.21292, 2.29522, 5.64214, -1.74767, 4.50486, -0.463834, 0.465254, 4.85533, -12.7992, 8.90884, -4.50486, 13.0661, -0.465254, 5.21784, 3.97342, -7.8685}, {-3.12618, -1.69082, 4.8169, -0.776768, 0.776768, 1.71093, 1.29482, -1.29482, 0.513906, -1.56011, -0.0455553, -0.619199, 2.77915, -4.76387, -6.97386, -0.640348, 0.640348, -2.75005, -8.06782, 6.08311, -0.706171, 6.8808, -0.458127, 5.22684, 2.88854, -0.903828, -1.34945, 0.32792, 1.6568, 0.130149}, {1.04206, 0.563608, -1.60563, 2.3303, -2.3303, -5.13278, 1.29482, -1.29482, 0.513906, -1.56011, -0.0455553, -0.619199, -4.49616, -3.91123, 6.29239, -5.81963, 5.81963, -4.80567, -2.88854, 0.903828, 1.34945, 0.640348, -0.640348, 2.75005, 9.12899, -0.721607, 1.12734, 0.32792, 1.6568, 0.130149}, {1.04206, 0.563608, -1.60563, -0.776768, 0.776768, 1.71093, -3.88446, 3.88446, -1.54172, -1.56011, -0.0455553, -0.619199, -0.32792, -1.6568, -0.130149, 2.46672, -2.46672, -9.59376, -7.05678, -1.3506, 7.77199, 0.640348, -0.640348, 2.75005, 2.88854, -0.903828, -1.34945, 6.56837, 1.83902, 2.60694}, {1.04206, 0.563608, -1.60563, -0.776768, 0.776768, 1.71093, 1.29482, -1.29482, 0.513906, 4.68034, 0.136666, 1.8576, -0.32792, -1.6568, -0.130149, -0.640348, 0.640348, -2.75005, -2.88854, 0.903828, 1.34945, -3.52789, -2.89478, 9.17259, 5.99561, -4.0109, -8.19316, -4.85136, 6.83608, -1.92547}, {4.44089e-16, 4.18682, -1.69558, 1.89879e-16, 0.106442, -1.13019, 1.31177, 1.47434, 0.246037, -1.31177, -0.185178, 0.318964, -6.66134e-16, 1.16773, 5.21915, -1.62143, -1.95396, 1.09288, -6.86849, -5.9947, -1.98688, 6.86849, 2.69467, -2.36873, 1.62143, 0.0973232, 1.00273, 0, -1.5935, -0.69838}, {-6.66134e-16, -1.39561, 0.565192, -6.73206e-16, -0.319327, 3.39058, 1.31177, 1.47434, 0.246037, -1.31177, -0.185178, 0.318964, 2.66454e-15, 7.17592, -1.56239, -6.86849, -7.85133, 0.108727, -1.62143, -0.0973232, -1.00273, 1.62143, 1.95396, -1.09288, 6.86849, 0.838037, -0.273122, -4.44089e-16, -1.5935, -0.69838}, {-2.22045e-16, -1.39561, 0.565192, -1.05296e-15, 0.106442, -1.13019, -3.9353, -4.42303, -0.738112, -1.31177, -0.185178, 0.318964, 1.55431e-15, 1.5935, 0.69838, -1.62143, -2.37973, 5.61365, -1.62143, 5.48511, -3.2635, 1.62143, 1.95396, -1.09288, 1.62143, 0.0973232, 1.00273, 5.24706, -0.852781, -1.97424}, {-8.88178e-16, -1.39561, 0.565192, 1.31189e-15, 0.106442, -1.13019, 1.31177, 1.47434, 0.246037, 3.9353, 0.555535, -0.956892, -6.66134e-16, 1.5935, 0.69838, -1.62143, -1.95396, 1.09288, -1.62143, -0.0973232, -1.00273, 1.62143, 7.53639, -3.35364, 1.62143, -0.328446, 5.52351, -5.24706, -7.49087, -1.68253}, {3.02999, -1.83569, -4.62902, -2.0783, 1.32959, -1.74182, 0.665193, -1.94149, 0.198817, 2.4231, 0, 0, 12.1305, -7.71818, 7.21305, 1.74669, 0.756347, 1.90726, -2.23457, 9.40942, -2.94828, -11.4391, -0.756347, -1.90726, -0.4262, -1.64347, 2.15301, -3.81734, 2.39981, -0.245751}, {-1.01, 0.611898, 1.54301, 6.23489, -3.98877, 5.22547, 0.665193, -1.94149, 0.198817, 2.4231, -1.16789e-15, 1.19597e-16, 7.85732, -4.8474, -5.92628, -0.91408, 8.5223, 1.11199, 0.4262, 1.64347, -2.15301, -1.74669, -0.756347, -1.90726, -10.1186, -1.64347, 2.15301, -3.81734, 2.39981, -0.245751}, {-1.01, 0.611898, 1.54301, -2.0783, 1.32959, -1.74182, -1.99558, 5.82447, -0.59645, 2.4231, 0, 0, 3.81734, -2.39981, 0.245751, 10.0599, -4.56202, 8.87456, 4.46618, -0.804126, -8.32504, -1.74669, -0.756347, -1.90726, -0.4262, -1.64347, 2.15301, -13.5097, 2.39981, -0.245751}, {-1.01, 0.611898, 1.54301, -2.0783, 1.32959, -1.74182, 0.665193, -1.94149, 0.198817, -7.2693, 0, 0, 3.81734, -2.39981, 0.245751, 1.74669, 0.756347, 1.90726, 0.4262, 1.64347, -2.15301, 2.29329, -3.20394, -8.07929, 7.88699, -6.96183, 9.12031, -6.47811, 10.1658, -1.04102}, {-1.1204, -10.941, -3.69733, -1.78885, -1.78885, 0.204309, 1.41539, -1.85814, 0.960835, 0, 0, -2.39759, 8.90493, 4.85864, -2.59316, 0.461631, 4.50793, -1.4402, -7.87269, 5.2214, -6.55438, -0.461631, -4.50793, 11.0306, 2.21115, 2.21115, 2.71104, -1.74951, 2.29678, 1.77593}, {0.373467, 3.64699, 1.23244, 5.36656, 5.36656, -0.612928, 1.41539, -1.85814, 0.960835, 0, 0, -2.39759, 0.255645, -16.8847, -6.70571, -5.19992, 11.9405, -5.28354, -2.21115, -2.21115, -2.71104, -0.461631, -4.50793, 1.4402, 2.21115, 2.21115, 12.3014, -1.74951, 2.29678, 1.77593}, {0.373467, 3.64699, 1.23244, -1.78885, -1.78885, 0.204309, -4.24616, 5.57441, -2.88251, 0, 0, -2.39759, 1.74951, -2.29678, -1.77593, 7.61705, 11.6633, -2.25744, -3.70501, -16.7991, -7.64082, -0.461631, -4.50793, 1.4402, 2.21115, 2.21115, 2.71104, -1.74951, 2.29678, 11.3663}, {0.373467, 3.64699, 1.23244, -1.78885, -1.78885, 0.204309, 1.41539, -1.85814, 0.960835, 0, 0, 7.19277, 1.74951, -2.29678, -1.77593, 0.461631, 4.50793, -1.4402, -2.21115, -2.21115, -2.71104, -1.9555, -19.0959, -3.48958, 9.36656, 9.36656, 1.89381, -7.41106, 9.72932, -2.06741}, {3.67635, 0.128375, 3.75827, 1.3465, -0.311871, 0.167791, -0.0738998, -1.11087, 1.10252, -0.0471455, 1.46553, -0.0175582, -5.53561, 1.68587, 0.669927, -1.57302, 1.7586, -1.5702, 1.90169, 5.86948, -4.2244, 1.7616, -7.62073, 1.64043, -1.60609, -1.426, -0.185698, 0.14962, -0.438387, -1.34109}, {-1.22545, -0.0427917, -1.25276, -4.03949, 0.935613, -0.503374, -0.0738998, -1.11087, 1.10252, -0.0471455, 1.46553, -0.0175582, 4.75218, 0.609554, 6.35212, -1.27742, 6.20208, -5.98029, 1.60609, 1.426, 0.185698, 1.57302, -1.7586, 1.5702, -1.4175, -7.28813, -0.115465, 0.14962, -0.438387, -1.34109}, {-1.22545, -0.0427917, -1.25276, 1.3465, -0.311871, 0.167791, 0.221699, 3.33261, -3.30757, -0.0471455, 1.46553, -0.0175582, -0.14962, 0.438387, 1.34109, -6.959, 3.00609, -2.24136, 6.50789, 1.59717, 5.19673, 1.57302, -1.7586, 1.5702, -1.60609, -1.426, -0.185698, 0.338202, -6.30052, -1.27086}, {-1.22545, -0.0427917, -1.25276, 1.3465, -0.311871, 0.167791, -0.0738998, -1.11087, 1.10252, 0.141437, -4.3966, 0.0526746, -0.14962, 0.438387, 1.34109, -1.57302, 1.7586, -1.5702, 1.60609, 1.426, 0.185698, 6.47482, -1.58744, 6.58122, -6.99207, -0.17852, -0.856863, 0.445219, 4.00509, -5.75119}, {3.98391, -5.22497, -0.407969, -0.61239, -1.54296, -1.54296, -7.73451e-16, 7.92047e-17, 1.60567, 1.94036, -0.198701, -0.198701, 4.84797, 5.92622, 7.91093, 0.756955, 1.9072, -0.0775154, 1.64146, -2.15281, -8.57548, -8.51839, -1.1124, 0.87232, -1.64146, 2.15281, 2.15281, -2.39842, 0.245608, -1.73911}, {-1.32797, 1.74166, 0.13599, 1.83717, 4.62887, 4.62887, 0, 0, 1.60567, 1.94036, -0.198701, -0.198701, 7.71029, -7.21224, 1.19515, 0.756955, 1.9072, -6.50019, 1.64146, -2.15281, -2.15281, -0.756955, -1.9072, 0.0775154, -9.4029, 2.94761, 2.94761, -2.39842, 0.245608, -1.73911}, {-1.32797, 1.74166, 0.13599, -0.61239, -1.54296, -1.54296, 0, 0, -4.817, 1.94036, -0.198701, -0.198701, 2.39842, -0.245608, 1.73911, 3.20651, 8.07903, 6.09431, 6.95334, -9.11944, -2.69677, -0.756955, -1.9072, 0.0775154, -1.64146, 2.15281, 2.15281, -10.1599, 1.04041, -0.944303}, {-1.32797, 1.74166, 0.13599, -0.61239, -1.54296, -1.54296, -7.73451e-16, 7.92047e-17, 1.60567, -5.82108, 0.596103, 0.596103, 2.39842, -0.245608, 1.73911, 0.756955, 1.9072, -0.0775154, 1.64146, -2.15281, -2.15281, 4.55492, -8.87383, -0.466443, 0.808098, 8.32463, 8.32463, -2.39842, 0.245608, -8.16178}, {4.24495, 4.24616, 5.57441, 2.77721, -0.373467, 3.64699, -3.15057, 0, 0, 1.78834, 1.78885, -1.78885, -12.7926, 3.70501, -16.7991, 0.461499, 0.461631, -4.50793, 18.2456, 1.74951, 2.29678, -7.61487, -7.61705, 11.6633, -5.64333, -1.74951, -2.29678, 1.6838, -2.21115, 2.21115}, {-1.41498, -1.41539, -1.85814, -8.33162, 1.1204, -10.941, -3.15057, 0, 0, 1.78834, 1.78885, -1.78885, 3.97613, 7.87269, 5.2214, 13.0638, 0.461631, -4.50793, 5.64333, 1.74951, 2.29678, -0.461499, -0.461631, 4.50793, -12.7967, -8.90493, 4.85864, 1.6838, -2.21115, 2.21115}, {-1.41498, -1.41539, -1.85814, 2.77721, -0.373467, 3.64699, 9.4517, 0, 0, 1.78834, 1.78885, -1.78885, -1.6838, 2.21115, -2.21115, -10.6473, 1.9555, -19.0959, 11.3033, 7.41106, 9.72932, -0.461499, -0.461631, 4.50793, -5.64333, -1.74951, -2.29678, -5.46957, -9.36656, 9.36656}, {-1.41498, -1.41539, -1.85814, 2.77721, -0.373467, 3.64699, -3.15057, 0, 0, -5.36503, -5.36656, 5.36656, -1.6838, 2.21115, -2.21115, 0.461499, 0.461631, -4.50793, 5.64333, 1.74951, 2.29678, 5.19843, 5.19992, 11.9405, -16.7522, -0.255645, -16.8847, 14.2861, -2.21115, 2.21115}, {-5.69487, -1.77636e-15, 1.77636e-15, -0.76309, -0.00636856, -2.01559, -0.460311, 1.45577, 1.44144, -0.67489, -1.4494, 0.574147, 1.64917, 0.0333462, 10.5538, 1.51221, -1.79156, 0.709685, 0.063805, -7.62252, -7.54749, 1.18735, 7.58918, -3.00627, 1.77744, 1.79943, 1.78172, 1.40319, -0.00787198, -2.49141}, {1.89829, 1.33227e-15, 6.66134e-16, 2.28927, 0.0191057, 6.04677, -0.460311, 1.45577, 1.44144, -0.67489, -1.4494, 0.574147, -8.99635, 0.00787198, 2.49141, 3.35345, -7.61465, -5.05609, -1.77744, -1.79943, -1.78172, -1.51221, 1.79156, -0.709685, 4.477, 7.59705, -0.514866, 1.40319, -0.00787198, -2.49141}, {1.89829, 0, -4.44089e-16, -0.76309, -0.00636856, -2.01559, 1.38093, -4.36732, -4.32433, -0.67489, -1.4494, 0.574147, -1.40319, 0.00787198, 2.49141, 4.56457, -1.76609, 8.77205, -9.3706, -1.79943, -1.78172, -1.51221, 1.79156, -0.709685, 1.77744, 1.79943, 1.78172, 4.10275, 5.78974, -4.78799}, {1.89829, 8.88178e-16, -5.55112e-16, -0.76309, -0.00636856, -2.01559, -0.460311, 1.45577, 1.44144, 2.02467, 4.34821, -1.72244, -1.40319, 0.00787198, 2.49141, 1.51221, -1.79156, 0.709685, -1.77744, -1.79943, -1.78172, -9.10537, 1.79156, -0.709685, 4.8298, 1.82491, 9.84408, 3.24443, -5.83096, -8.25718}, {-1.1204, -4.37783, -10.941, 1.41539, 0.69601, -1.85814, -1.78885, 0.0170635, -1.78885, 0, -2.17235, 0, -7.87269, -5.44812, 5.2214, 0.461631, -0.881407, 4.50793, 8.90493, -1.89311, 4.85864, -0.461631, 9.57081, -4.50793, -1.74951, 1.82486, 2.29678, 2.21115, 2.66408, 2.21115}, {0.373467, 1.45928, 3.64699, -4.24616, -2.08803, 5.57441, -1.78885, 0.0170635, -1.78885, 0, -2.17235, 0, -3.70501, -8.50119, -16.7991, 7.61705, -0.949661, 11.6633, 1.74951, -1.82486, -2.29678, -0.461631, 0.881407, -4.50793, -1.74951, 10.5143, 2.29678, 2.21115, 2.66408, 2.21115}, {0.373467, 1.45928, 3.64699, 1.41539, 0.69601, -1.85814, 5.36656, -0.0511904, 5.36656, 0, -2.17235, 0, -2.21115, -2.66408, -2.21115, -5.19992, -3.66545, 11.9405, 0.255645, -7.66197, -16.8847, -0.461631, 0.881407, -4.50793, -1.74951, 1.82486, 2.29678, 2.21115, 11.3535, 2.21115}, {0.373467, 1.45928, 3.64699, 1.41539, 0.69601, -1.85814, -1.78885, 0.0170635, -1.78885, 0, 6.51705, 0, -2.21115, -2.66408, -2.21115, 0.461631, -0.881407, 4.50793, 1.74951, -1.82486, -2.29678, -1.9555, -4.9557, -19.0959, -7.41106, -0.959181, 9.72932, 9.36656, 2.59583, 9.36656}, {-4.15743, -0.83732, 1.25624, -1.32462, -1.53355, 0.226806, 0.107516, 1.61619, -1.60405, -0.168703, -0.361739, 1.79599, 5.22286, 7.6848, -0.669975, 1.50443, -0.10214, 1.70236, -2.27592, -8.80746, 8.91649, -0.829614, 1.5491, -8.88631, 1.84585, 2.34271, -2.50031, 0.0756322, -1.55058, -0.237251}, {1.38581, 0.279107, -0.418747, 3.97387, 4.60066, -0.680419, 0.107516, 1.61619, -1.60405, -0.168703, -0.361739, 1.79599, -5.61888, 0.434156, 1.91224, 1.07436, -6.56689, 8.11854, -1.84585, -2.34271, 2.50031, -1.50443, 0.10214, -1.70236, 2.52067, 3.78967, -9.68425, 0.0756322, -1.55058, -0.237251}, {1.38581, 0.279107, -0.418747, -1.32462, -1.53355, 0.226806, -0.322547, -4.84856, 4.81214, -0.168703, -0.361739, 1.79599, -0.0756322, 1.55058, 0.237251, 6.80292, 6.03208, 0.795135, -7.3891, -3.45914, 4.1753, -1.50443, 0.10214, -1.70236, 1.84585, 2.34271, -2.50031, 0.750446, -0.103625, -7.4212}, {1.38581, 0.279107, -0.418747, -1.32462, -1.53355, 0.226806, 0.107516, 1.61619, -1.60405, 0.50611, 1.08522, -5.38796, -0.0756322, 1.55058, 0.237251, 1.50443, -0.10214, 1.70236, -1.84585, -2.34271, 2.50031, -7.04767, -1.01429, -0.0273746, 7.14434, 8.47693, -3.40753, -0.354431, -8.01533, 6.17893}, {-9.45441, 3.55271e-15, 3.55271e-15, -1.78885, -1.78885, 1.78885, -1.36261, -1.36216, -1.78885, 0, 3.15102, 0, 5.47113, 9.36656, -9.36656, 3.89543, 3.89487, -1.33227e-15, 3.23931, 7.13238, 9.36656, -3.89543, -16.4989, 1.33227e-15, 2.21115, -1.68373, -2.21115, 1.68428, -2.21115, 2.21115}, {3.15147, -2.66454e-15, -1.54979e-16, 5.36656, 5.36656, -5.36656, -1.36261, -1.36216, -1.78885, -1.06591e-15, 3.15102, -1.39933e-15, -14.2902, 2.21115, -2.21115, 9.34589, 9.34353, 7.15542, -2.21115, 1.68373, 2.21115, -3.89543, -3.89487, 1.77636e-15, 2.21115, -14.2878, -2.21115, 1.68428, -2.21115, 2.21115}, {3.15147, -3.55271e-15, 5.55112e-15, -1.78885, -1.78885, 1.78885, 4.08784, 4.08649, 5.36656, 0, 3.15102, 0, -1.68428, 2.21115, -2.21115, 11.0508, 11.0503, -7.15542, -14.817, 1.68373, 2.21115, -3.89543, -3.89487, -7.10543e-15, 2.21115, -1.68373, -2.21115, 1.68428, -14.8152, 2.21115}, {3.15147, -4.44089e-16, 0, -1.78885, -1.78885, 1.78885, -1.36261, -1.36216, -1.78885, 0, -9.45305, 0, -1.68428, 2.21115, -2.21115, 3.89543, 3.89487, 0, -2.21115, 1.68373, 2.21115, -16.5013, -3.89487, 0, 9.36656, 5.47169, -9.36656, 7.13474, 3.23751, 9.36656}, {-1.45879e-15, 1.07667, 3.62612, 1.31177, 0.0458057, 1.34099, -1.31177, -1.15409, -0.162924, -4.86263e-16, 1.46718, 0.0306378, -6.86849, 0.20377, -5.52749, 0, 1.36992, -1.45618, 6.86849, 6.48653, 2.34713, 1.94505e-15, -7.23863, 1.33362, -1.62143, -1.87015, -1.69543, 1.62143, -0.386993, 0.163515}, {1.99923e-16, -0.358889, -1.20871, -3.9353, -0.137417, -4.02298, -1.31177, -1.15409, -0.162924, 4.66211e-16, 1.46718, 0.0306378, -1.62143, 1.82255, 4.67132, 5.24706, 5.9863, -0.804479, 1.62143, 1.87015, 1.69543, -8.88178e-16, -1.36992, 1.45618, -1.62143, -7.73886, -1.81798, 1.62143, -0.386993, 0.163515}, {2.32071e-16, -0.358889, -1.20871, 1.31177, 0.0458057, 1.34099, 3.9353, 3.46228, 0.488772, -1.0026e-17, 1.46718, 0.0306378, -1.62143, 0.386993, -0.163515, -5.24706, 1.1867, -6.82015, 1.62143, 3.30571, 6.53026, -4.44089e-16, -1.36992, 1.45618, -1.62143, -1.87015, -1.69543, 1.62143, -6.25571, 0.0409633}, {0, -0.358889, -1.20871, 1.31177, 0.0458057, 1.34099, -1.31177, -1.15409, -0.162924, 0, -4.40153, -0.0919135, -1.62143, 0.386993, -0.163515, 0, 1.36992, -1.45618, 1.62143, 1.87015, 1.69543, 0, 0.0656375, 6.29101, -6.86849, -2.05337, -7.05941, 6.86849, 4.22939, 0.815211}, {-7.42462e-16, 4.44089e-15, -3.26126, -1.4431, -0.571101, -0.587405, 1.45561, -1.44292, 0.31363, -0.0125109, 2.01402, -0.813311, 7.55617, 2.99032, 1.73198, -0.0154644, 2.48947, 0.338405, -7.62167, 7.55524, -2.9859, 0.0655081, -10.5456, 2.91484, 1.79923, -1.78355, 1.73138, -1.78377, -0.70592, 0.61764}, {-7.09502e-16, 0, 1.08709, 4.3293, 1.7133, 1.76222, 1.45561, -1.44292, 0.31363, -0.0125109, 2.01402, -0.813311, 1.78377, 0.70592, -4.96598, -5.83791, 8.26116, -0.916114, -1.79923, 1.78355, -1.73138, 0.0154644, -2.48947, -0.338405, 1.84928, -9.83965, 4.98462, -1.78377, -0.70592, 0.61764}, {-2.32453e-16, 0, 1.08709, -1.4431, -0.571101, -0.587405, -4.36683, 4.32877, -0.940889, -0.0125109, 2.01402, -0.813311, 1.78377, 0.70592, -0.61764, 5.75693, 4.77387, 2.68803, -1.79923, 1.78355, -6.07972, 0.0154644, -2.48947, -0.338405, 1.79923, -1.78355, 1.73138, -1.73373, -8.76202, 3.87088}, {-2.68882e-16, -4.44089e-16, 1.08709, -1.4431, -0.571101, -0.587405, 1.45561, -1.44292, 0.31363, 0.0375328, -6.04207, 2.43993, 1.78377, 0.70592, -0.61764, -0.0154644, 2.48947, 0.338405, -1.79923, 1.78355, -1.73138, 0.0154644, -2.48947, -4.68675, 7.57163, 0.500853, 4.081, -7.60621, 5.06577, -0.63688}, {2.18323e-11, -2.07603e-11, -5.36656, -2.34313, 0, 0, 2.34313, -2.34313, -1.78885, 0, 2.34313, 0, 12.2688, -8.5536e-12, -2.21115, -8.99547e-12, 2.89626, 2.21115, -12.2688, 12.2688, 7.15542, 8.99547e-12, -12.2688, -2.21115, 2.89626, -2.89626, 0, -2.89626, 8.5536e-12, 2.21115}, {-7.2791e-12, 6.92024e-12, 1.78885, 7.02938, 0, 0, 2.34313, -2.34313, -1.78885, 1.36297e-15, 2.34313, -1.04056e-15, 2.89626, -3.62341e-11, -9.36656, -9.3725, 12.2688, 9.36656, -2.89626, 2.89626, -2.61847e-15, 8.99636e-12, -2.89626, -2.21115, 2.89626, -12.2688, 5.44843e-15, -2.89626, 8.5536e-12, 2.21115}, {-7.2764e-12, 6.92024e-12, 1.78885, -2.34313, 0, 0, -7.02938, 7.02938, 5.36656, 0, 2.34313, 0, 2.89626, -8.5536e-12, -2.21115, 9.3725, 2.89626, 2.21115, -2.89626, 2.89626, -7.15542, 8.99414e-12, -2.89626, -2.21115, 2.89626, -2.89626, 0, -2.89626, -9.3725, 2.21115}, {-7.27995e-12, 6.92069e-12, 1.78885, -2.34313, 0, 0, 2.34313, -2.34313, -1.78885, 0, -7.02938, 0, 2.89626, -8.55493e-12, -2.21115, -8.99769e-12, 2.89626, 2.21115, -2.89626, 2.89626, -1.33227e-15, 3.81171e-11, -2.89626, -9.36656, 12.2688, -2.89626, 0, -12.2688, 9.3725, 9.36656}, {0, -7.95209e-19, 7.02938, 0, -2.34313, 0, -1.78885, 2.34313, 2.34566, 1.78885, 1.02102e-11, -0.00253498, 0, 12.2688, 2.89626, 2.21115, 1.26206e-11, -2.8994, 9.36656, -12.2688, -9.38578, -9.36656, -5.34614e-11, 2.90954, -2.21115, 2.89626, 0.00313341, 0, -2.89626, -2.89626}, {0, 2.33279e-16, -2.34313, 0, 7.02938, 0, -1.78885, 2.34313, 2.34566, 1.78885, 1.02076e-11, -0.00253498, 0, 2.89626, 12.2688, 9.36656, -9.3725, -12.282, 2.21115, -2.89626, -0.00313341, -2.21115, -1.26175e-11, 2.8994, -9.36656, 2.89626, 0.0132733, 0, -2.89626, -2.89626}, {0, 4.58607e-18, -2.34313, 0, -2.34313, 0, 5.36656, -7.02938, -7.03698, 1.78885, 1.02092e-11, -0.00253498, 0, 2.89626, 2.89626, 2.21115, 9.3725, -2.8994, 2.21115, -2.89626, 9.36937, -2.21115, -1.26197e-11, 2.8994, -2.21115, 2.89626, 0.00313341, -7.15542, -2.89626, -2.88612}, {0, 4.03857e-16, -2.34313, 0, -2.34313, 0, -1.78885, 2.34313, 2.34566, -5.36656, -3.0633e-11, 0.00760494, 0, 2.89626, 2.89626, 2.21115, 1.26219e-11, -2.8994, 2.21115, -2.89626, -0.00313341, -2.21115, -1.26244e-11, 12.2719, -2.21115, 12.2688, 0.00313341, 7.15542, -12.2688, -12.2789}, {7.99361e-15, -9.45441, -8.88178e-15, 1.78885, -1.78885, -1.78885, -1.78885, -1.36261, -1.36261, 0, 0, 3.15147, -9.36656, 5.47113, 9.36656, -3.55271e-15, 3.89543, 3.89543, 9.36656, 3.23931, 7.13474, 3.55271e-15, -3.89543, -16.5013, -2.21115, 2.21115, -1.68428, 2.21115, 1.68428, -2.21115}, {1.39953e-15, 3.15147, -1.33227e-15, -5.36656, 5.36656, 5.36656, -1.78885, -1.36261, -1.36261, -1.39953e-15, -1.06606e-15, 3.15147, -2.21115, -14.2902, 2.21115, 7.15542, 9.34589, 9.34589, 2.21115, -2.21115, 1.68428, -1.04232e-30, -3.89543, -3.89543, -2.21115, 2.21115, -14.2902, 2.21115, 1.68428, -2.21115}, {-5.55112e-15, 3.15147, 8.88178e-16, 1.78885, -1.78885, -1.78885, 5.36656, 4.08784, 4.08784, 0, 0, 3.15147, -2.21115, -1.68428, 2.21115, -7.15542, 11.0508, 11.0508, 2.21115, -14.817, 1.68428, 6.66134e-15, -3.89543, -3.89543, -2.21115, 2.21115, -1.68428, 2.21115, 1.68428, -14.817}, {0, 3.15147, 2.66454e-15, 1.78885, -1.78885, -1.78885, -1.78885, -1.36261, -1.36261, 0, 0, -9.45441, -2.21115, -1.68428, 2.21115, 0, 3.89543, 3.89543, 2.21115, -2.21115, 1.68428, 0, -16.5013, -3.89543, -9.36656, 9.36656, 5.47113, 9.36656, 7.13474, 3.23931}, {-5.36656, 7.03835, 7.02938, -1.78885, -6.94e-12, -7.11689e-12, 0, 2.34612, -2.72942e-15, 0, 0, 2.34313, 7.15542, 2.89996, 2.89626, 2.21115, -2.89996, 8.80033e-12, -2.21115, -9.38447, 2.89626, -2.21115, 2.89996, -9.3725, 2.21115, 8.57831e-12, -2.89626, 0, -2.89996, -2.89626}, {1.78885, -2.34612, -2.34313, 5.36656, 2.08309e-11, 2.13491e-11, 0, 2.34612, -1.36471e-15, 0, 1.36471e-15, 2.34313, -7.15542, 12.2844, 12.2688, 2.21115, -12.2844, 8.80346e-12, -2.21115, -8.57938e-12, 2.89626, -2.21115, 2.89996, -8.79626e-12, 2.21115, 8.57567e-12, -12.2688, 0, -2.89996, -2.89626}, {1.78885, -2.34612, -2.34313, -1.78885, -6.94417e-12, -7.11741e-12, 0, -7.03835, 0, 0, 0, 2.34313, -1.33227e-15, 2.89996, 2.89626, 9.36656, -2.89996, 3.72672e-11, -9.36656, 9.38447, 12.2688, -2.21115, 2.89996, -8.79586e-12, 2.21115, 8.58346e-12, -2.89626, 0, -2.89996, -12.2688}, {1.78885, -2.34612, -2.34313, -1.78885, -6.94104e-12, -7.11793e-12, 0, 2.34612, -2.72942e-15, 0, 0, -7.02938, -1.33227e-15, 2.89996, 2.89626, 2.21115, -2.89996, 8.80162e-12, -2.21115, -8.57785e-12, 2.89626, -9.36656, 12.2844, 9.3725, 9.36656, 3.63438e-11, -2.89626, 0, -12.2844, -2.89626}, {5.36656, -5.36656, 5.36656, 3.15147, 0, -4.93048e-15, -1.36261, -1.78885, -1.36216, 0, 0, 3.15102, -14.2902, -2.21115, 2.21115, -2.21115, 2.21115, 1.68373, 9.34589, 7.15542, 9.34353, 2.21115, -2.21115, -14.2878, -3.89543, 0, -3.89487, 1.68428, 2.21115, -2.21115}, {-1.78885, 1.78885, -1.78885, -9.45441, 4.1986e-15, 1.05928e-14, -1.36261, -1.78885, -1.36216, -1.06591e-15, -1.39933e-15, 3.15102, 5.47113, -9.36656, 9.36656, 3.23931, 9.36656, 7.13238, 3.89543, -4.79186e-15, 3.89487, 2.21115, -2.21115, -1.68373, -3.89543, 9.05692e-15, -16.4989, 1.68428, 2.21115, -2.21115}, {-1.78885, 1.78885, -1.78885, 3.15147, 0, 0, 4.08784, 5.36656, 4.08649, 0, 0, 3.15102, -1.68428, -2.21115, 2.21115, -14.817, 2.21115, 1.68373, 11.0508, -7.15542, 11.0503, 2.21115, -2.21115, -1.68373, -3.89543, 0, -3.89487, 1.68428, 2.21115, -14.8152}, {-1.78885, 1.78885, -1.78885, 3.15147, 0, -4.93048e-15, -1.36261, -1.78885, -1.36216, 0, 0, -9.45305, -1.68428, -2.21115, 2.21115, -2.21115, 2.21115, 1.68373, 3.89543, -1.33227e-15, 3.89487, 9.36656, -9.36656, 5.47169, -16.5013, 0, -3.89487, 7.13474, 9.36656, 3.23751}, {3.37408, 4.04519, 4.04519, 1.73606, 1.52739, 0.215622, 1.28983, 0.0265046, 1.33827, -1.90119, -0.205494, -0.205494, -7.69991, -6.33079, 0.5377, -3.7402, -1.92072, -1.92072, -5.36342, 1.52793, -5.34056, 11.345, 2.74269, 2.74269, 0.204116, -1.63395, -0.0125188, 0.755686, 0.221243, -1.40019}, {-1.12469, -1.3484, -1.3484, -5.20817, -4.58216, -0.646866, 1.28983, 0.0265046, 1.33827, -1.90119, -0.205494, -0.205494, 3.74309, 5.17235, 6.79378, -8.89951, -2.02673, -7.27379, -0.204116, 1.63395, 0.0125188, 3.7402, 1.92072, 1.92072, 7.80888, -0.811974, 0.809457, 0.755686, 0.221243, -1.40019}, {-1.12469, -1.3484, -1.3484, 1.73606, 1.52739, 0.215622, -3.86948, -0.0795138, -4.01481, -1.90119, -0.205494, -0.205494, -0.755686, -0.221243, 1.40019, -10.6844, -8.03027, -2.7832, 4.29466, 7.02754, 5.40611, 3.7402, 1.92072, 1.92072, 0.204116, -1.63395, -0.0125188, 8.36045, 1.04322, -0.578212}, {-1.12469, -1.3484, -1.3484, 1.73606, 1.52739, 0.215622, 1.28983, 0.0265046, 1.33827, 5.70357, 0.616482, 0.616482, -0.755686, -0.221243, 1.40019, -3.7402, -1.92072, -1.92072, -0.204116, 1.63395, 0.0125188, 8.23897, 7.31431, 7.31431, -6.74011, -7.7435, -0.875007, -4.40362, 0.115225, -6.75327}, {7.02938, 7.0206, 5.36656, 6.04912e-27, 2.34147, -1.03982e-15, 2.34313, 0, 0, -1.04066e-11, -0.00126659, 1.78885, 2.89626, -9.36743, 2.21115, -2.89626, -2.89421, 1.28529e-15, -9.3725, 2.89265, 2.21115, 2.89626, 2.89928, -7.15542, 1.28633e-11, -2.89265, -2.21115, -2.89626, 0.00156559, -2.21115}, {-2.34313, -2.3402, -1.78885, -4.08602e-15, -7.0244, 3.11946e-15, 2.34313, -7.36763e-19, 1.04056e-15, -1.0404e-11, -0.00126659, 1.78885, 12.2688, 9.35923, 9.36656, -12.2688, -2.89421, -4.16314e-15, -1.28566e-11, 2.89265, 2.21115, 2.89626, 2.89421, 1.33318e-15, 5.44744e-11, -2.88758, -9.36656, -2.89626, 0.00156559, -2.21115}, {-2.34313, -2.3402, -1.78885, 0, 2.34147, 0, -7.02938, 0, 0, -1.04066e-11, -0.00126659, 1.78885, 2.89626, -0.00156559, 2.21115, -2.89626, -12.2601, 0, 9.3725, 12.2534, 9.36656, 2.89626, 2.89421, 1.33227e-15, 1.28633e-11, -2.89265, -2.21115, -2.89626, 0.00663197, -9.36656}, {-2.34313, -2.3402, -1.78885, 6.05094e-27, 2.34147, -1.03982e-15, 2.34313, 0, 0, 3.12292e-11, 0.00379978, -5.36656, 2.89626, -0.00156559, 2.21115, -2.89626, -2.89421, 1.28529e-15, -1.28654e-11, 2.89265, 2.21115, 12.2688, 12.255, 7.15542, 1.28671e-11, -12.2585, -2.21115, -12.2688, 0.00156559, -2.21115}, {-3.69587, -1.12113, -5.61393, -0.115297, -1.49037, 0.58988, -0.136463, 0.136463, -2.07323, -0.980196, 0.980196, -0.387956, -0.919078, 7.34175, -5.40172, 0.311194, 1.67352, 1.83353, -0.80825, -1.17646, 8.54253, 3.60959, -5.59431, -0.281701, 1.3541, 0.630611, -0.249592, 1.38027, -1.38027, 3.0422}, {1.23196, 0.373711, 1.87131, 0.345892, 4.47111, -1.76964, -0.136463, 0.136463, -2.07323, -0.980196, 0.980196, -0.387956, -6.30809, -0.114578, -10.5274, 0.857047, 1.12767, 10.1265, -1.3541, -0.630611, 0.249592, -0.311194, -1.67352, -1.83353, 5.27489, -3.29017, 1.30223, 1.38027, -1.38027, 3.0422}, {1.23196, 0.373711, 1.87131, -0.115297, -1.49037, 0.58988, 0.40939, -0.40939, 6.2197, -0.980196, 0.980196, -0.387956, -1.38027, 1.38027, -3.0422, 0.772383, 7.635, -0.525997, -6.28193, -2.12546, -7.23564, -0.311194, -1.67352, -1.83353, 1.3541, 0.630611, -0.249592, 5.30105, -5.30105, 4.59402}, {1.23196, 0.373711, 1.87131, -0.115297, -1.49037, 0.58988, -0.136463, 0.136463, -2.07323, 2.94059, -2.94059, 1.16387, -1.38027, 1.38027, -3.0422, 0.311194, 1.67352, 1.83353, -1.3541, -0.630611, 0.249592, -5.23902, -3.16837, -9.31876, 1.81529, 6.59209, -2.60911, 1.92612, -1.92612, 11.3351}, {5.57441, -4.24616, -4.24616, 3.64699, 0.373467, -2.778, -1.78885, -1.78885, -1.78885, 0, 0, 3.15147, -16.7991, -3.70501, 12.7963, -2.29678, 1.74951, 5.64494, 11.6633, 7.61705, 7.61705, 2.29678, -1.74951, -18.2508, -4.50793, -0.461631, -0.461631, 2.21115, 2.21115, -1.68428}, {-1.85814, 1.41539, 1.41539, -10.941, -1.1204, 8.334, -1.78885, -1.78885, -1.78885, -1.39953e-15, -1.39953e-15, 3.15147, 5.2214, -7.87269, -3.97726, 4.85864, 8.90493, 12.8004, 4.50793, 0.461631, 0.461631, 2.29678, -1.74951, -5.64494, -4.50793, -0.461631, -13.0675, 2.21115, 2.21115, -1.68428}, {-1.85814, 1.41539, 1.41539, 3.64699, 0.373467, -2.778, 5.36656, 5.36656, 5.36656, 0, 0, 3.15147, -2.21115, -2.21115, 1.68428, -16.8847, 0.255645, 16.7569, 11.9405, -5.19992, -5.19992, 2.29678, -1.74951, -5.64494, -4.50793, -0.461631, -0.461631, 2.21115, 2.21115, -14.2902}, {-1.85814, 1.41539, 1.41539, 3.64699, 0.373467, -2.778, -1.78885, -1.78885, -1.78885, 0, 0, -9.45441, -2.21115, -2.21115, 1.68428, -2.29678, 1.74951, 5.64494, 4.50793, 0.461631, 0.461631, 9.72932, -7.41106, -11.3065, -19.0959, -1.9555, 10.6504, 9.36656, 9.36656, 5.47113}, {0.00760494, 5.36656, -0.00379978, -1.36201e-15, 0, 2.34147, -2.34059, 1.78885, -2.34273, 2.34313, 0, 0, 0.00313341, 2.21115, -12.2616, 2.89313, -2.21115, 0.00156559, 12.2586, -7.15542, 12.2651, -12.2656, 2.21115, -0.00156559, -2.89626, 0, -2.89421, -0.00313341, -2.21115, 2.89578}, {-0.00253498, -1.78885, 0.00126659, 8.16761e-15, -3.11946e-15, -7.0244, -2.34059, 1.78885, -2.34273, 2.34313, 1.04056e-15, -1.36274e-15, 0.0132733, 9.36656, -2.90084, 12.2555, -9.36656, 9.3725, 2.89626, 3.90375e-15, 2.89421, -2.89313, 2.21115, -0.00156559, -12.2688, -6.73371e-15, -2.89421, -0.00313341, -2.21115, 2.89578}, {-0.00253498, -1.78885, 0.00126659, 0, 0, 2.34147, 7.02177, -5.36656, 7.0282, 2.34313, 0, 0, 0.00313341, 2.21115, -2.89578, 2.89313, -2.21115, -9.3643, 2.9064, 7.15542, 2.88915, -2.89313, 2.21115, -0.00156559, -2.89626, 0, -2.89421, -9.37564, -2.21115, 2.89578}, {-0.00253498, -1.78885, 0.00126659, -1.36201e-15, 0, 2.34147, -2.34059, 1.78885, -2.34273, -7.02938, 0, 0, 0.00313341, 2.21115, -2.89578, 2.89313, -2.21115, 0.00156559, 2.89626, 1.33227e-15, 2.89421, -2.88299, 9.36656, -0.00663197, -2.89626, 0, -12.2601, 9.35923, -9.36656, 12.2667}, {-2.0499, 2.05263, 6.32666, 0.872781, 1.47234, -0.0861955, 0.376973, -0.375702, 1.61414, -1.93305, -0.412429, 0.580942, -5.41454, -6.86355, 3.05805, -1.54478, -1.35552, -1.88864, -2.81846, 2.81293, -5.84502, 9.277, 3.00524, -0.435124, 1.31057, -1.31012, -0.61154, 1.92342, 0.974184, -2.71327}, {0.683301, -0.68421, -2.10889, -2.61834, -4.41703, 0.258586, 0.376973, -0.375702, 1.61414, -1.93305, -0.412429, 0.580942, -4.65662, 1.76266, 11.1488, -3.05267, 0.147289, -8.34521, -1.31057, 1.31012, 0.61154, 1.54478, 1.35552, 1.88864, 9.04279, 0.339593, -2.93531, 1.92342, 0.974184, -2.71327}, {0.683301, -0.68421, -2.10889, 0.872781, 1.47234, -0.0861955, -1.13092, 1.12711, -4.84242, -1.93305, -0.412429, 0.580942, -1.92342, -0.974184, 2.71327, -5.0359, -7.24489, -1.54386, -4.04377, 4.04697, 9.04709, 1.54478, 1.35552, 1.88864, 1.31057, -1.31012, -0.61154, 9.65564, 2.6239, -5.03704}, {0.683301, -0.68421, -2.10889, 0.872781, 1.47234, -0.0861955, 0.376973, -0.375702, 1.61414, 5.79916, 1.23729, -1.74283, -1.92342, -0.974184, 2.71327, -1.54478, -1.35552, -1.88864, -1.31057, 1.31012, 0.61154, -1.18842, 4.09236, 10.3242, -2.18055, -7.19949, -0.266758, 0.41553, 2.47699, -9.16983}, {3.84226, 4.31846, 0.720662, 0.104325, 0.223697, -1.11063, 1.27099, 0.0329107, 0.803582, -0.0945646, 1.18288, 0.547265, 1.03685, 0.608011, 6.11224, -1.69999, -0.317185, 0.379527, -5.07191, 1.60698, -3.91068, 2.07825, -4.41433, -2.56859, -0.0120645, -1.73863, 0.696352, -1.45415, -1.5028, -1.66974}, {-1.28075, -1.43949, -0.240221, -0.312975, -0.671092, 3.33188, 1.27099, 0.0329107, 0.803582, -0.0945646, 1.18288, 0.547265, 6.57716, 7.26075, 2.63062, -6.78396, -0.448828, -2.8348, 0.0120645, 1.73863, -0.696352, 1.69999, 0.317185, -0.379527, 0.366194, -6.47014, -1.49271, -1.45415, -1.5028, -1.66974}, {-1.28075, -1.43949, -0.240221, 0.104325, 0.223697, -1.11063, -3.81298, -0.0987322, -2.41075, -0.0945646, 1.18288, 0.547265, 1.45415, 1.5028, 1.66974, -2.11729, -1.21197, 4.82203, 5.13508, 7.49658, 0.26453, 1.69999, 0.317185, -0.379527, -0.0120645, -1.73863, 0.696352, -1.07589, -6.23432, -3.8588}, {-1.28075, -1.43949, -0.240221, 0.104325, 0.223697, -1.11063, 1.27099, 0.0329107, 0.803582, 0.283694, -3.54864, -1.64179, 1.45415, 1.5028, 1.66974, -1.69999, -0.317185, 0.379527, 0.0120645, 1.73863, -0.696352, 6.823, 6.07514, 0.581356, -0.429365, -2.63341, 5.13886, -6.53812, -1.63444, -4.88406}, {6.08004, 1.41594, 0.0377686, 0.57469, 1.08447, 1.45022, 1.45199, 0.720135, -1.43763, 0, -1.33263, 0, -0.504, -5.09498, -7.57787, -2.50511, -2.23062, -0.0155615, -5.09761, -3.18728, 7.54308, 2.50511, 7.56114, 0.0155615, -0.710355, 0.306735, -1.79257, -1.79476, 0.757084, 1.77701}, {-2.02668, -0.471981, -0.0125895, -1.72407, -3.25342, -4.35065, 1.45199, 0.720135, -1.43763, 0, -1.33263, 0, 9.90148, 1.13084, -1.72665, -8.31307, -5.11116, 5.73495, 0.710355, -0.306735, 1.79257, 2.50511, 2.23062, 0.0155615, -0.710355, 5.63725, -1.79257, -1.79476, 0.757084, 1.77701}, {-2.02668, -0.471981, -0.0125895, 0.57469, 1.08447, 1.45022, -4.35597, -2.1604, 4.31288, 0, -1.33263, 0, 1.79476, -0.757084, -1.77701, -4.80387, -6.56852, -5.81643, 8.81707, 1.58119, 1.84292, 2.50511, 2.23062, 0.0155615, -0.710355, 0.306735, -1.79257, -1.79476, 6.0876, 1.77701}, {-2.02668, -0.471981, -0.0125895, 0.57469, 1.08447, 1.45022, 1.45199, 0.720135, -1.43763, 0, 3.99789, 0, 1.79476, -0.757084, -1.77701, -2.50511, -2.23062, -0.0155615, 0.710355, -0.306735, 1.79257, 10.6118, 4.11854, 0.0659197, -3.00911, -4.03116, -7.59343, -7.60272, -2.12346, 7.52752}, {-1.37732, 4.35589, 4.31302, -1.40475, 2.02293, -0.00626368, 1.89829, 5.38146e-16, -1.36093e-15, -0.952649, -0.570969, 1.44394, 6.78788, -8.79749, 1.80986, -0.610051, -2.50048, 0.00774234, -10.5071, 1.79473, 1.77706, 4.42065, 4.78436, -5.78349, 2.9139, -1.79473, -1.77706, -1.16888, 0.705756, -1.7848}, {0.459107, -1.45196, -1.43767, 4.21425, -6.0688, 0.018791, 1.89829, 2.69073e-16, -6.80465e-16, -0.952649, -0.570969, 1.44394, -0.66755, 5.1021, 7.53549, -8.20322, -2.50048, 0.00774234, -2.9139, 1.79473, 1.77706, 0.610051, 2.50048, -0.00774234, 6.7245, 0.489149, -7.5528, -1.16888, 0.705756, -1.7848}, {0.459107, -1.45196, -1.43767, -1.40475, 2.02293, -0.00626368, -5.69487, 0, 0, -0.952649, -0.570969, 1.44394, 1.16888, -0.705756, 1.7848, 5.00895, -10.5922, 0.0327971, -4.75033, 7.60258, 7.52775, 0.610051, 2.50048, -0.00774234, 2.9139, -1.79473, -1.77706, 2.64172, 2.98963, -7.56055}, {0.459107, -1.45196, -1.43767, -1.40475, 2.02293, -0.00626368, 1.89829, 5.38146e-16, -1.36093e-15, 2.85795, 1.71291, -4.33181, 1.16888, -0.705756, 1.7848, -0.610051, -2.50048, 0.00774234, -2.9139, 1.79473, 1.77706, -1.22638, 8.30834, 5.74295, 8.5329, -9.88646, -1.75201, -8.76204, 0.705756, -1.7848}, {-5.36656, -5.36656, -5.36656, -0.373467, -3.64699, -0.373467, 0, 0, -1.60567, -1.41539, 1.85814, 0.190281, -0.255645, 16.8847, -0.255645, 0.461631, 4.50793, 2.44635, -2.21115, -2.21115, 6.19624, 5.19992, -11.9405, -3.20747, 2.21115, 2.21115, 0.226431, 1.74951, -2.29678, 1.74951}, {1.78885, 1.78885, 1.78885, 1.1204, 10.941, 1.1204, 0, 0, -1.60567, -1.41539, 1.85814, 0.190281, -8.90493, -4.85864, -8.90493, 0.461631, 4.50793, 8.86902, -2.21115, -2.21115, -0.226431, -0.461631, -4.50793, -2.44635, 7.87269, -5.2214, -0.534693, 1.74951, -2.29678, 1.74951}, {1.78885, 1.78885, 1.78885, -0.373467, -3.64699, -0.373467, 0, 0, 4.817, -1.41539, 1.85814, 0.190281, -1.74951, 2.29678, -1.74951, 1.9555, 19.0959, 3.94022, -9.36656, -9.36656, -7.38185, -0.461631, -4.50793, -2.44635, 2.21115, 2.21115, 0.226431, 7.41106, -9.72932, 0.988391}, {1.78885, 1.78885, 1.78885, -0.373467, -3.64699, -0.373467, 0, 0, -1.60567, 4.24616, -5.57441, -0.570843, -1.74951, 2.29678, -1.74951, 0.461631, 4.50793, 2.44635, -2.21115, -2.21115, -0.226431, -7.61705, -11.6633, -9.60176, 3.70501, 16.7991, 1.7203, 1.74951, -2.29678, 8.17219}, {-5.32907e-15, -9.45441, 2.4869e-14, 1.78885, -1.36261, -1.36261, -1.78885, -1.78885, -1.78885, 0, 0, 3.15147, -9.36656, 3.23931, 7.13474, 1.77636e-15, 3.89543, 3.89543, 9.36656, 5.47113, 9.36656, -1.77636e-15, -3.89543, -16.5013, -2.21115, 1.68428, -2.21115, 2.21115, 2.21115, -1.68428}, {-2.81931e-15, 3.15147, -5.32907e-15, -5.36656, 4.08784, 4.08784, -1.78885, -1.78885, -1.78885, -1.39953e-15, -1.39953e-15, 3.15147, -2.21115, -14.817, 1.68428, 7.15542, 11.0508, 11.0508, 2.21115, -1.68428, 2.21115, 5.32907e-15, -3.89543, -3.89543, -2.21115, 1.68428, -14.817, 2.21115, 2.21115, -1.68428}, {2.88658e-15, 3.15147, 8.88178e-16, 1.78885, -1.36261, -1.36261, 5.36656, 5.36656, 5.36656, 0, 0, 3.15147, -2.21115, -2.21115, 1.68428, -7.15542, 9.34589, 9.34589, 2.21115, -14.2902, 2.21115, -3.55271e-15, -3.89543, -3.89543, -2.21115, 1.68428, -2.21115, 2.21115, 2.21115, -14.2902}, {-5.55112e-15, 3.15147, -5.32907e-15, 1.78885, -1.36261, -1.36261, -1.78885, -1.78885, -1.78885, 0, 0, -9.45441, -2.21115, -2.21115, 1.68428, -7.10543e-15, 3.89543, 3.89543, 2.21115, -1.68428, 2.21115, 3.01981e-14, -16.5013, -3.89543, -9.36656, 7.13474, 3.23931, 9.36656, 9.36656, 5.47113}, {3.05492, -2.11527, -4.36034, 0.668117, -1.63909, -0.00517894, 0.911433, 1.21439, 0.00383706, -0.561241, -0.2804, -1.4521, -2.23961, 7.71083, -1.76944, -1.95243, 0.524948, 0.00165865, -3.51362, -7.23019, -1.81665, 4.1974, 0.59665, 5.80676, -0.132105, 2.37262, 1.8013, -0.43286, -1.15448, 1.79016}, {-1.01831, 0.705091, 1.45345, -2.00435, 4.91726, 0.0155368, 0.911433, 1.21439, 0.00383706, -0.561241, -0.2804, -1.4521, 4.50609, -1.66588, -7.60394, -5.59816, -4.33263, -0.0136896, 0.132105, -2.37262, -1.8013, 1.95243, -0.524948, -0.00165865, 2.11286, 3.49421, 7.60972, -0.43286, -1.15448, 1.79016}, {-1.01831, 0.705091, 1.45345, 0.668117, -1.63909, -0.00517894, -2.7343, -3.64318, -0.0115112, -0.561241, -0.2804, -1.4521, 0.43286, 1.15448, -1.79016, -4.6249, 7.08129, 0.0223744, 4.20534, -5.19298, -7.61508, 1.95243, -0.524948, -0.00165865, -0.132105, 2.37262, 1.8013, 1.81211, -0.0328828, 7.59857}, {-1.01831, 0.705091, 1.45345, 0.668117, -1.63909, -0.00517894, 0.911433, 1.21439, 0.00383706, 1.68372, 0.841199, 4.35631, 0.43286, 1.15448, -1.79016, -1.95243, 0.524948, 0.00165865, 0.132105, -2.37262, -1.8013, 6.02566, -3.34531, -5.81544, -2.80457, 8.92896, 1.82202, -4.07859, -6.01206, 1.77481}, {5.82171, 7.62554, -0.596168, 1.32981, 1.74185, -1.74185, 0.61076, -1.54312, 1.54312, 0, 2.34313, 0, -4.5643, -5.97853, 8.87479, -2.39867, -0.245635, 0.245635, -0.799305, 11.2218, -8.32553, 2.39867, -9.12687, -0.245635, -1.64373, -5.0493, 2.15304, -0.754941, -0.988857, -1.90741}, {-1.94057, -2.54185, 0.198723, -3.98943, -5.22554, 5.22554, 0.61076, -1.54312, 1.54312, 3.55272e-16, 2.34313, 8.97618e-16, 8.51722, 11.1562, 1.11252, -4.84171, 5.92686, -5.92686, 1.64373, 5.0493, -2.15304, 2.39867, 0.245635, -0.245635, -1.64373, -14.4218, 2.15304, -0.754941, -0.988857, -1.90741}, {-1.94057, -2.54185, 0.198723, 1.32981, 1.74185, -1.74185, -1.83228, 4.62937, -4.62937, 0, 2.34313, 0, 0.754941, 0.988857, 1.90741, -7.71791, -7.21302, 7.21302, 9.40601, 15.2167, -2.94793, 2.39867, 0.245635, -0.245635, -1.64373, -5.0493, 2.15304, -0.754941, -10.3614, -1.90741}, {-1.94057, -2.54185, 0.198723, 1.32981, 1.74185, -1.74185, 0.61076, -1.54312, 1.54312, 0, -7.02938, 0, 0.754941, 0.988857, 1.90741, -2.39867, -0.245635, 0.245635, 1.64373, 5.0493, -2.15304, 10.1609, 10.413, -1.04052, -6.96297, -12.0167, 9.12042, -3.19798, 5.18364, -8.0799}, {5.81909, -7.62212, -0.600985, 0, -2.34313, 0, 0.610485, 1.54348, 1.54262, 1.32921, -1.74106, -1.74295, 2.3976, 9.12828, -0.24762, -0.754601, 0.988412, -1.90678, -0.798945, -11.2223, -8.32487, -4.56224, 5.97584, 8.87857, -1.643, 5.04833, 2.1544, -2.3976, 0.244222, 0.24762}, {-1.9397, 2.54071, 0.200328, 0, 7.02938, 0, 0.610485, 1.54348, 1.54262, 1.32921, -1.74106, -1.74295, 10.1564, -10.407, -1.04893, -3.19654, -5.18552, -8.07725, 1.643, -5.04833, -2.1544, 0.754601, -0.988412, 1.90678, -6.95984, 12.0126, 9.12619, -2.3976, 0.244222, 0.24762}, {-1.9397, 2.54071, 0.200328, 0, -2.34313, 0, -1.83146, -4.63045, -4.62785, 1.32921, -1.74106, -1.74295, 2.3976, -0.244222, -0.24762, -0.754601, 10.3609, -1.90678, 9.40178, -15.2112, -2.95571, 0.754601, -0.988412, 1.90678, -1.643, 5.04833, 2.1544, -7.71444, 7.20847, 7.21941}, {-1.9397, 2.54071, 0.200328, 0, -2.34313, 0, 0.610485, 1.54348, 1.54262, -3.98763, 5.22319, 5.22884, 2.3976, -0.244222, -0.24762, -0.754601, 0.988412, -1.90678, 1.643, -5.04833, -2.1544, 8.51339, -11.1512, 1.10547, -1.643, 14.4208, 2.1544, -4.83954, -5.92971, -5.92285}, {0, 1.11022e-16, 4.817, 1.32981, 1.74185, -0.136178, 0.61076, -1.54312, 1.54312, -1.94057, -0.198723, 0.198723, -6.96297, -9.12042, 2.69775, -2.39867, -0.245635, -1.73908, -3.19798, 8.0799, -6.09519, 10.1609, 1.04052, 0.94419, 0.754941, -1.90741, -0.0773091, 1.64373, 2.15304, -2.15304}, {2.22045e-16, 1.38778e-16, -1.60567, -3.98943, -5.22554, 0.408534, 0.61076, -1.54312, 1.54312, -1.94057, -0.198723, 0.198723, -1.64373, -2.15304, 8.57571, -4.84171, 5.92686, -7.91157, -0.754941, 1.90741, 0.0773091, 2.39867, 0.245635, 1.73908, 8.51722, -1.11252, -0.872199, 1.64373, 2.15304, -2.15304}, {2.22045e-16, 3.33067e-16, -1.60567, 1.32981, 1.74185, -0.136178, -1.83228, 4.62937, -4.62937, -1.94057, -0.198723, 0.198723, -1.64373, -2.15304, 2.15304, -7.71791, -7.21302, -1.19437, -0.754941, 1.90741, 6.49998, 2.39867, 0.245635, 1.73908, 0.754941, -1.90741, -0.0773091, 9.40601, 2.94793, -2.94793}, {0, -8.32667e-17, -1.60567, 1.32981, 1.74185, -0.136178, 0.61076, -1.54312, 1.54312, 5.82171, 0.596168, -0.596168, -1.64373, -2.15304, 2.15304, -2.39867, -0.245635, -1.73908, -0.754941, 1.90741, 0.0773091, 2.39867, 0.245635, 8.16175, -4.5643, -8.87479, 0.467403, -0.799305, 8.32553, -8.32553}, {-1.28888, 1.28888, -5.54754, -0.937563, 0.937563, 0.371082, -0.607159, -0.998509, -1.77891, 1.1151, 0.490571, -0.441349, 4.3781, -4.3781, -4.22872, 1.90938, 0.0753332, 1.74017, 2.64808, 5.7593, 7.02879, -6.36977, -2.03762, 0.0252242, -0.219445, -1.76527, 0.0868549, -0.627846, 0.627846, 2.74439}, {0.429625, -0.429625, 1.84918, 2.81269, -2.81269, -1.11325, -0.607159, -0.998509, -1.77891, 1.1151, 0.490571, -0.441349, -1.09065, 1.09065, -10.1411, 4.33802, 4.06937, 8.85582, 0.219445, 1.76527, -0.0868549, -1.90938, -0.0753332, -1.74017, -4.67983, -3.72755, 1.85225, -0.627846, 0.627846, 2.74439}, {0.429625, -0.429625, 1.84918, -0.937563, 0.937563, 0.371082, 1.82148, 2.99553, 5.33673, 1.1151, 0.490571, -0.441349, 0.627846, -0.627846, -2.74439, 5.65963, -3.67492, 0.255844, -1.49906, 3.48377, -7.48357, -1.90938, -0.0753332, -1.74017, -0.219445, -1.76527, 0.0868549, -5.08823, -1.33444, 4.50979}, {0.429625, -0.429625, 1.84918, -0.937563, 0.937563, 0.371082, -0.607159, -0.998509, -1.77891, -3.34529, -1.47171, 1.32405, 0.627846, -0.627846, -2.74439, 1.90938, 0.0753332, 1.74017, 0.219445, 1.76527, -0.0868549, -3.62788, 1.64317, -9.13689, 3.53081, -5.51552, -1.39747, 1.80079, 4.62188, 9.86004}, {-4.9045, -4.90878, 4.90879, 0.803078, -0.801888, 0.80329, -1.63483, -1.63626, 0.030594, -0.803078, 0.801888, 0.802378, -6.22574, 2.17621, -2.18355, 1.0281, 3.01372, -1.03074, 6.53933, 6.54504, 1.86234, 2.18421, -6.22127, -2.17877, 7.4829e-14, -7.4607e-14, -1.98471, 3.01342, 1.03134, -1.02961}, {1.63483, 1.63626, -1.63626, -2.40924, 2.40566, -2.40987, -1.63483, -1.63626, 0.030594, -0.803078, 0.801888, 0.802378, -9.55275, -7.57638, 7.57466, 7.56743, 9.55876, -1.15311, -7.60503e-14, 7.18314e-14, 1.98471, -1.0281, -3.01372, 1.03074, 3.21231, -3.20755, -5.19423, 3.01342, 1.03134, -1.02961}, {1.63483, 1.63626, -1.63626, 0.803078, -0.801888, 0.80329, 4.9045, 4.90878, -0.0917819, -0.803078, 0.801888, 0.802378, -3.01342, -1.03134, 1.02961, -2.18421, 6.22127, -4.2439, -6.53933, -6.54504, 8.52976, -1.0281, -3.01372, 1.03074, 7.40519e-14, -7.36078e-14, -1.98471, 6.22574, -2.17621, -4.23912}, {1.63483, 1.63626, -1.63626, 0.803078, -0.801888, 0.80329, -1.63483, -1.63626, 0.030594, 2.40924, -2.40566, -2.40713, -3.01342, -1.03134, 1.02961, 1.0281, 3.01372, -1.03074, -7.77156e-14, 7.50511e-14, 1.98471, -7.56743, -9.55876, 7.57579, -3.21231, 3.20755, -5.19788, 9.55275, 7.57638, -1.15199}, {0.412021, -3.98943, -5.22554, -1.60567, 0, 0, 0.200419, -1.94057, -0.198723, 1.54259, 0.61076, -1.54312, 8.57715, -1.64373, -2.15304, 1.73698, 2.39867, 0.245635, -0.879643, 8.51722, -1.11252, -7.90734, -4.84171, 5.92686, 0.0779689, -0.754941, 1.90741, -2.15448, 1.64373, 2.15304}, {-0.13734, 1.32981, 1.74185, 4.817, 0, 0, 0.200419, -1.94057, -0.198723, 1.54259, 0.61076, -1.54312, 2.70384, -6.96297, -9.12042, 0.93531, 10.1609, 1.04052, -0.0779689, 0.754941, -1.90741, -1.73698, -2.39867, -0.245635, -6.09239, -3.19798, 8.0799, -2.15448, 1.64373, 2.15304}, {-0.13734, 1.32981, 1.74185, -1.60567, 0, 0, -0.601256, 5.82171, 0.596168, 1.54259, 0.61076, -1.54312, 2.15448, -1.64373, -2.15304, 8.15966, 2.39867, 0.245635, 0.471392, -4.5643, -8.87479, -1.73698, -2.39867, -0.245635, 0.0779689, -0.754941, 1.90741, -8.32484, -0.799305, 8.32553}, {-0.13734, 1.32981, 1.74185, -1.60567, 0, 0, 0.200419, -1.94057, -0.198723, -4.62777, -1.83228, 4.62937, 2.15448, -1.64373, -2.15304, 1.73698, 2.39867, 0.245635, -0.0779689, 0.754941, -1.90741, -1.18762, -7.71791, -7.21302, 6.50064, -0.754941, 1.90741, -2.95615, 9.40601, 2.94793}, {-2.2024, 0.148267, -4.33994, -0.546238, -1.40698, 1.37377e-12, 0.372712, 0.180326, -1.44665, -0.560609, 1.27608, -1.24596e-12, 1.9527, 7.42813, -1.78815, 0.21449, 1.51623, 1.78815, -2.85899, -0.883108, 5.78659, 2.02795, -6.62053, -1.78815, 1.36814, 0.161805, -1.57986e-13, 0.232253, -1.80021, 1.78815}, {0.734135, -0.0494224, 1.44665, 1.63871, 4.22094, -4.12359e-12, 0.372712, 0.180326, -1.44665, -0.560609, 1.27608, -1.24665e-12, -3.16879, 1.9979, -7.57474, -1.27636, 0.794924, 7.57474, -1.36814, -0.161805, 1.56996e-13, -0.21449, -1.51623, -1.78815, 3.61057, -4.9425, 4.82851e-12, 0.232253, -1.80021, 1.78815}, {0.734135, -0.0494224, 1.44665, -0.546238, -1.40698, 1.37478e-12, -1.11814, -0.540977, 4.33994, -0.560609, 1.27608, -1.24687e-12, -0.232253, 1.80021, -1.78815, 2.39944, 7.14414, 1.78815, -4.30468, 0.0358845, -5.78659, -0.21449, -1.51623, -1.78815, 1.36814, 0.161805, -1.58103e-13, 2.47469, -6.90451, 1.78815}, {0.734135, -0.0494224, 1.44665, -0.546238, -1.40698, 1.3739e-12, 0.372712, 0.180326, -1.44665, 1.68183, -3.82823, 3.73822e-12, -0.232253, 1.80021, -1.78815, 0.21449, 1.51623, 1.78815, -1.36814, -0.161805, 1.56924e-13, -3.15103, -1.31854, -7.57474, 3.55309, 5.78972, -5.65359e-12, -1.25859, -2.52151, 7.57474}, {0, 9.4517, 0, -1.78885, 1.78834, -1.78937, 1.78885, 1.36222, -1.3621, 0, 0, 3.15147, 9.36656, -5.46957, 9.36924, 0, -3.89432, 3.89543, -9.36656, -3.23838, 7.13206, 0, 3.89432, -16.5013, 2.21115, -2.21051, -1.68365, -2.21115, -1.6838, -2.21178}, {5.98868e-16, -3.15057, 0, 5.36656, -5.36503, 5.3681, 1.78885, 1.36222, -1.3621, 1.39953e-15, 1.06575e-15, 3.15147, 2.21115, 14.2861, 2.21178, -7.15542, -9.34321, 9.34384, -2.21115, 2.21051, 1.68365, -2.66454e-15, 3.89432, -3.89543, 2.21115, -2.21051, -14.2895, -2.21115, -1.6838, -2.21178}, {-4.44089e-16, -3.15057, 4.44089e-16, -1.78885, 1.78834, -1.78937, -5.36656, -4.08667, 4.08631, 0, 0, 3.15147, 2.21115, 1.6838, 2.21178, 7.15542, -11.0477, 11.0529, -2.21115, 14.8128, 1.68365, 8.88178e-16, 3.89432, -3.89543, 2.21115, -2.21051, -1.68365, -2.21115, -1.6838, -14.8177}, {0, -3.15057, -4.44089e-16, -1.78885, 1.78834, -1.78937, 1.78885, 1.36222, -1.3621, 0, 0, -9.45441, 2.21115, 1.6838, 2.21178, 0, -3.89432, 3.89543, -2.21115, 2.21051, 1.68365, 0, 16.4966, -3.89543, 9.36656, -9.36389, 5.47381, -9.36656, -7.1327, 3.23663}, {-0.595682, -0.596202, -5.82204, 0, -1.60567, 0, 1.54187, 1.54321, -0.609885, -1.74043, -0.136279, -1.3308, -0.245434, 8.16174, -2.39881, -1.90585, 0.0771985, 0.75386, -8.31875, -8.32602, 0.794587, 8.86756, 0.467918, 4.56932, 2.15129, 2.15317, 1.64495, 0.245434, -1.73907, 2.39881}, {0.198561, 0.198734, 1.94068, 0, 4.817, 0, 1.54187, 1.54321, -0.609885, -1.74043, -0.136279, -1.3308, -1.03968, 0.94413, -10.1615, -8.07331, -6.09565, 3.1934, -2.15129, -2.15317, -1.64495, 1.90585, -0.0771985, -0.75386, 9.11299, 2.69828, 6.96814, 0.245434, -1.73907, 2.39881}, {0.198561, 0.198734, 1.94068, 0, -1.60567, 0, -4.6256, -4.62964, 1.82966, -1.74043, -0.136279, -1.3308, -0.245434, 1.73907, -2.39881, -1.90585, 6.49987, 0.75386, -2.94553, -2.9481, -9.40768, 1.90585, -0.0771985, -0.75386, 2.15129, 2.15317, 1.64495, 7.20714, -1.19395, 7.722}, {0.198561, 0.198734, 1.94068, 0, -1.60567, 0, 1.54187, 1.54321, -0.609885, 5.22128, 0.408838, 3.99239, -0.245434, 1.73907, -2.39881, -1.90585, 0.0771985, 0.75386, -2.15129, -2.15317, -1.64495, 1.11161, -0.872135, -8.51658, 2.15129, 8.57584, 1.64495, -5.92203, -7.91192, 4.83836}, {-1.34911, 3.4086, 1.4084, 1.74422, 0.694821, 0.910847, -1.68823, -0.836265, 0.836265, -0.505685, 1.27764, -1.27764, -9.68869, -2.23371, -4.18896, -0.0691986, 0.174835, -2.15955, 8.28384, 5.78316, -3.79845, 2.09194, -5.28541, 7.27013, -1.53091, -2.4381, 0.453387, 2.71183, -0.545574, 0.545574}, {0.449702, -1.1362, -0.469468, -5.23265, -2.08446, -2.73254, -1.68823, -0.836265, 0.836265, -0.505685, 1.27764, -1.27764, -4.51064, 5.09037, 1.3323, 6.68373, 3.5199, -5.50461, 1.53091, 2.4381, -0.453387, 0.0691986, -0.174835, 2.15955, 0.49183, -7.54868, 5.56396, 2.71183, -0.545574, 0.545574}, {0.449702, -1.1362, -0.469468, 1.74422, 0.694821, 0.910847, 5.0647, 2.5088, -2.5088, -0.505685, 1.27764, -1.27764, -2.71183, 0.545574, -0.545574, -7.04606, -2.60445, -5.80294, -0.267898, 6.9829, 1.42448, 0.0691986, -0.174835, 2.15955, -1.53091, -2.4381, 0.453387, 4.73457, -5.65615, 5.65615}, {0.449702, -1.1362, -0.469468, 1.74422, 0.694821, 0.910847, -1.68823, -0.836265, 0.836265, 1.51705, -3.83293, 3.83293, -2.71183, 0.545574, -0.545574, -0.0691986, 0.174835, -2.15955, 1.53091, 2.4381, -0.453387, -1.72961, 4.36997, 4.03742, -8.50777, -5.21739, -3.19, 9.46476, 2.79949, -2.79949}, {-6.58175, 1.32414, -1.32414, -0.505685, 1.27764, -1.27764, 0.857073, 0.177676, 2.16545, -2.54531, -1.01394, -1.32918, -0.0640323, -6.14426, 6.14426, -0.43434, -1.79887, -1.09739, -7.19952, -0.384749, -11.884, 10.6156, 5.85464, 6.41412, 3.77123, -0.325955, 3.22222, 2.08677, 1.03368, -1.03368}, {2.19392, -0.441379, 0.441379, 1.51705, -3.83293, 3.83293, 0.857073, 0.177676, 2.16545, -2.54531, -1.01394, -1.32918, -10.8624, 0.731834, -0.731834, -3.86263, -2.50958, -9.75919, -3.77123, 0.325955, -3.22222, 0.43434, 1.79887, 1.09739, 13.9525, 3.72981, 8.53895, 2.08677, 1.03368, -1.03368}, {2.19392, -0.441379, 0.441379, -0.505685, 1.27764, -1.27764, -2.57122, -0.533028, -6.49635, -2.54531, -1.01394, -1.32918, -2.08677, -1.03368, 1.03368, 1.5884, -6.90945, 4.01319, -12.5469, 2.09147, -4.98773, 0.43434, 1.79887, 1.09739, 3.77123, -0.325955, 3.22222, 12.268, 5.08945, 4.28305}, {2.19392, -0.441379, 0.441379, -0.505685, 1.27764, -1.27764, 0.857073, 0.177676, 2.16545, 7.63592, 3.04182, 3.98755, -2.08677, -1.03368, 1.03368, -0.43434, -1.79887, -1.09739, -3.77123, 0.325955, -3.22222, -8.34133, 3.56439, -0.668128, 5.79397, -5.43653, 8.33279, -1.34152, 0.322977, -9.69548}, {5.63148, -7.39306, 3.82293, -0.845027, -3.02792, 0.845027, 1.29407, 2.43841, 1.8574, 1.42811, -1.87484, -1.42811, 6.74491, 12.8083, -2.84948, -0.55505, 0.728676, -3.34038, -4.45555, -15.8138, -8.15032, -5.15741, 6.7707, 9.05284, -0.720736, 6.06015, 0.720736, -3.36481, -0.696607, -0.530622}, {-1.87716, 2.46435, -1.27431, 2.53508, 9.08376, -2.53508, 1.29407, 2.43841, 1.8574, 1.42811, -1.87484, -1.42811, 10.8734, -9.16081, 5.62786, -5.73134, -9.02497, -10.77, 0.720736, -6.06015, -0.720736, 0.55505, -0.728676, 3.34038, -6.43319, 13.5595, 6.43319, -3.36481, -0.696607, -0.530622}, {-1.87716, 2.46435, -1.27431, -0.845027, -3.02792, 0.845027, -3.88221, -7.31523, -5.57219, 1.42811, -1.87484, -1.42811, 3.36481, 0.696607, 0.530622, 2.82506, 12.8404, -6.72049, 8.22937, -15.9176, 4.3765, 0.55505, -0.728676, 3.34038, -0.720736, 6.06015, 0.720736, -9.07726, 6.80277, 5.18184}, {-1.87716, 2.46435, -1.27431, -0.845027, -3.02792, 0.845027, 1.29407, 2.43841, 1.8574, -4.28434, 5.62453, 4.28434, 3.36481, 0.696607, 0.530622, -0.55505, 0.728676, -3.34038, 0.720736, -6.06015, -0.720736, 8.06369, -10.5861, 8.43762, 2.65937, 18.1718, -2.65937, -8.54109, -10.4502, -7.96021}, {1.77636e-15, 9.45441, 0, 1.78834, 1.78885, 1.78885, -3.15057, 0, 0, 1.36222, 1.36261, -1.78885, -9.36389, -5.47113, -9.36656, 1.6838, -2.21115, -2.21115, 16.4966, 3.89543, 0, -7.1327, -3.23931, 9.36656, -3.89432, -3.89543, 0, 2.21051, -1.68428, 2.21115}, {2.22045e-16, -3.15147, 0, -5.36503, -5.36656, -5.36656, -3.15057, 0, 0, 1.36222, 1.36261, -1.78885, -2.21051, 14.2902, -2.21115, 14.2861, -2.21115, -2.21115, 3.89432, 3.89543, 0, -1.6838, 2.21115, 2.21115, -9.34321, -9.34589, 7.15542, 2.21051, -1.68428, 2.21115}, {2.22045e-16, -3.15147, 0, 1.78834, 1.78885, 1.78885, 9.4517, 0, 0, 1.36222, 1.36261, -1.78885, -2.21051, 1.68428, -2.21115, -5.46957, -9.36656, -9.36656, 3.89432, 16.5013, 0, -1.6838, 2.21115, 2.21115, -3.89432, -3.89543, 0, -3.23838, -7.13474, 9.36656}, {-4.44089e-16, -3.15147, 0, 1.78834, 1.78885, 1.78885, -3.15057, 0, 0, -4.08667, -4.08784, 5.36656, -2.21051, 1.68428, -2.21115, 1.6838, -2.21115, -2.21115, 3.89432, 3.89543, 0, -1.6838, 14.817, 2.21115, -11.0477, -11.0508, -7.15542, 14.8128, -1.68428, 2.21115}, {-5.36656, 5.36656, -5.36656, 0, 3.15147, 0, -1.78885, -1.36261, 1.36261, 0, 0, -3.15147, -2.21115, -14.2902, -2.21115, 2.21115, -2.21115, -1.68428, 7.15542, 9.34589, -9.34589, -2.21115, 2.21115, 14.2902, 0, -3.89543, 3.89543, 2.21115, 1.68428, 2.21115}, {1.78885, -1.78885, 1.78885, 4.1986e-15, -9.45441, -1.0595e-14, -1.78885, -1.36261, 1.36261, 0, 0, -3.15147, -9.36656, 5.47113, -9.36656, 9.36656, 3.23931, -7.13474, -3.06219e-15, 3.89543, -3.89543, -2.21115, 2.21115, 1.68428, 1.72992e-15, -3.89543, 16.5013, 2.21115, 1.68428, 2.21115}, {1.78885, -1.78885, 1.78885, 0, 3.15147, 9.86237e-15, 5.36656, 4.08784, -4.08784, 0, 0, -3.15147, -2.21115, -1.68428, -2.21115, 2.21115, -14.817, -1.68428, -7.15542, 11.0508, -11.0508, -2.21115, 2.21115, 1.68428, 0, -3.89543, 3.89543, 2.21115, 1.68428, 14.817}, {1.78885, -1.78885, 1.78885, 0, 3.15147, 0, -1.78885, -1.36261, 1.36261, 0, 0, 9.45441, -2.21115, -1.68428, -2.21115, 2.21115, -2.21115, -1.68428, -1.33227e-15, 3.89543, -3.89543, -9.36656, 9.36656, -5.47113, 0, -16.5013, 3.89543, 9.36656, 7.13474, -3.23931}, {7.01844, 7.44471e-16, 0, 2.33948, 2.34313, -1.78885, 0, -2.34313, 0, -7.30269e-12, -6.91866e-12, 1.78885, -9.35791, -12.2688, 9.36656, -2.89175, -8.55227e-12, 2.21115, 2.89175, 12.2688, 0, 2.89175, 3.62269e-11, -9.36656, -2.89175, -2.89626, 0, 9.02662e-12, 2.89626, -2.21115}, {-2.33948, 1.32789e-16, 0, -7.01844, -7.02938, 5.36656, 0, -2.34313, 0, -7.30373e-12, -6.92126e-12, 1.78885, 9.35791, -2.89626, 2.21115, -2.89175, 9.3725, 2.21115, 2.89175, 2.89626, 0, 2.89175, 8.55538e-12, -2.21115, -2.89175, -2.89626, -7.15542, 9.02791e-12, 2.89626, -2.21115}, {-2.33948, -6.16057e-16, 0, 2.33948, 2.34313, -1.78885, 0, 7.02938, 0, -7.30321e-12, -6.91918e-12, 1.78885, -9.02552e-12, -2.89626, 2.21115, -12.2497, -9.3725, 9.36656, 12.2497, 2.89626, 0, 2.89175, 8.55316e-12, -2.21115, -2.89175, -2.89626, 0, 3.82401e-11, 2.89626, -9.36656}, {-2.33948, -3.87489e-16, 0, 2.33948, 2.34313, -1.78885, 0, -2.34313, 0, 2.19143e-11, 2.07622e-11, -5.36656, -9.02745e-12, -2.89626, 2.21115, -2.89175, -8.55449e-12, 2.21115, 2.89175, 2.89626, 0, 12.2497, 8.55648e-12, -2.21115, -12.2497, -12.2688, 7.15542, 9.02919e-12, 12.2688, -2.21115}, {-1.00651, -1.00808, 6.45666, -0.481765, 1.86061, -0.736419, 0.984821, -1.35677, 2.55622, -0.83856, -0.839867, 0.332415, 2.10785, -10.1576, 6.51623, -0.62181, -0.62278, -2.2494, -5.57129, 6.68879, -10.7243, 3.97605, 3.98225, 0.919744, 1.63201, -1.26171, 0.499377, -0.180789, 2.71519, -3.57055}, {0.335504, 0.336027, -2.15222, 1.4453, -5.58183, 2.20926, 0.984821, -1.35677, 2.55622, -0.83856, -0.839867, 0.332415, -1.16123, -4.0593, 12.1794, -4.56109, 4.8043, -12.4743, -1.63201, 1.26171, -0.499377, 0.62181, 0.62278, 2.2494, 4.98625, 2.09776, -0.830282, -0.180789, 2.71519, -3.57055}, {0.335504, 0.336027, -2.15222, -0.481765, 1.86061, -0.736419, -2.95446, 4.07031, -7.66867, -0.83856, -0.839867, 0.332415, 0.180789, -2.71519, 3.57055, 1.30525, -8.06522, 0.696272, -2.97403, -0.0824032, 8.1095, 0.62181, 0.62278, 2.2494, 1.63201, -1.26171, 0.499377, 3.17345, 6.07466, -4.90021}, {0.335504, 0.336027, -2.15222, -0.481765, 1.86061, -0.736419, 0.984821, -1.35677, 2.55622, 2.51568, 2.5196, -0.997244, 0.180789, -2.71519, 3.57055, -0.62181, -0.62278, -2.2494, -1.63201, 1.26171, -0.499377, -0.720207, -0.72133, 10.8583, 3.55907, -8.70414, 3.44505, -4.12007, 8.14227, -13.7954}, {5.36656, -5.48122e-11, 5.58789e-11, 1.78885, -2.34313, 2.34313, 0, 2.34313, 0, 0, 0, -2.34313, -7.15542, 12.2688, -12.2688, -2.21115, 2.25837e-11, -2.89626, 2.21115, -12.2688, 2.30234e-11, 2.21115, -2.25837e-11, 12.2688, -2.21115, 2.89626, -2.30234e-11, 0, -2.89626, 2.89626}, {-1.78885, 1.21125e-11, -1.24687e-11, -5.36656, 7.02938, -7.02938, 0, 2.34313, -1.36297e-15, 0, 0, -2.34313, 7.15542, 2.89626, -2.89626, -2.21115, -9.3725, -2.89626, 2.21115, -2.89626, 1.54134e-11, 2.21115, -1.49716e-11, 2.89626, -2.21115, 2.89626, 9.3725, 0, -2.89626, 2.89626}, {-1.78885, 1.21099e-11, -1.24665e-11, 1.78885, -2.34313, 2.34313, 0, -7.02938, 0, 0, 0, -2.34313, 1.33227e-15, 2.89626, -2.89626, -9.36656, 9.3725, -12.2688, 9.36656, -2.89626, 6.5274e-11, 2.21115, -1.4968e-11, 2.89626, -2.21115, 2.89626, -1.5409e-11, 0, -2.89626, 12.2688}, {-1.78885, 1.21099e-11, -1.24687e-11, 1.78885, -2.34313, 2.34313, 0, 2.34313, 0, 0, 0, 7.02938, 1.33227e-15, 2.89626, -2.89626, -2.21115, 1.49689e-11, -2.89626, 2.21115, -2.89626, 1.54121e-11, 9.36656, -6.34088e-11, 2.89626, -9.36656, 12.2688, -9.3725, 0, -12.2688, 2.89626}, {5.09908, -2.42192, -2.42638, -0.488904, -1.23525, -1.23482, 1.75382, -0.670557, 0.933579, 0.434779, 1.0985, -0.507552, 4.66087, 5.46995, 5.46587, -1.56352, 2.3557, 0.372353, -7.08218, 2.51319, -5.888, -0.175592, -6.74968, 1.65786, 0.0669023, 0.169033, 2.15369, -2.70526, -0.528962, -0.526598}, {-1.69969, 0.807307, 0.808792, 1.46671, 3.70574, 3.70446, 1.75382, -0.670557, 0.933579, 0.434779, 1.0985, -0.507552, 9.50403, -2.70027, -2.70857, -8.5788, 5.03793, -3.36196, -0.0669023, -0.169033, -2.15369, 1.56352, -2.3557, -0.372353, -1.67221, -4.22495, 4.1839, -2.70526, -0.528962, -0.526598}, {-1.69969, 0.807307, 0.808792, -0.488904, -1.23525, -1.23482, -5.26146, 2.01167, -2.80074, 0.434779, 1.0985, -0.507552, 2.70526, 0.528962, 0.526598, 0.392092, 7.29669, 5.31163, 6.73188, -3.39826, -5.38886, 1.56352, -2.3557, -0.372353, 0.0669023, 0.169033, 2.15369, -4.44437, -4.92294, 1.50361}, {-1.69969, 0.807307, 0.808792, -0.488904, -1.23525, -1.23482, 1.75382, -0.670557, 0.933579, -1.30434, -3.29549, 1.52266, 2.70526, 0.528962, 0.526598, -1.56352, 2.3557, 0.372353, -0.0669023, -0.169033, -2.15369, 8.3623, -5.58493, -3.60752, 2.02252, 5.11002, 7.09296, -9.72053, 2.15326, -4.26091}, {-2.57735, 0.513092, -6.51263, -2.5578, 0.977952, -1.36155, -0.488614, -1.23536, -1.23466, 2.1873, 0.428435, 0.425336, 12.3309, -4.90922, 4.44581, 3.76558, 0.31817, 3.2091, 1.49649, 6.67982, 3.78144, -12.5148, -2.03191, -4.91044, 0.457966, -1.73839, 1.15722, -2.09969, 0.99741, 1.00039}, {0.859116, -0.171031, 2.17088, 7.67341, -2.93386, 4.08465, -0.488614, -1.23536, -1.23466, 2.1873, 0.428435, 0.425336, -1.33677, -0.313288, -9.6839, 5.72003, 5.2596, 8.14775, -0.457966, 1.73839, -1.15722, -3.76558, -0.31817, -3.2091, -8.29124, -3.45213, -0.54412, -2.09969, 0.99741, 1.00039}, {0.859116, -0.171031, 2.17088, -2.5578, 0.977952, -1.36155, 1.46584, 3.70607, 3.70399, 2.1873, 0.428435, 0.425336, 2.09969, -0.99741, -1.00039, 13.9968, -3.59364, 8.65529, -3.89443, 2.42251, -9.84073, -3.76558, -0.31817, -3.2091, 0.457966, -1.73839, 1.15722, -10.8489, -0.716331, -0.700957}, {0.859116, -0.171031, 2.17088, -2.5578, 0.977952, -1.36155, -0.488614, -1.23536, -1.23466, -6.5619, -1.28531, -1.27601, 2.09969, -0.99741, -1.00039, 3.76558, 0.31817, 3.2091, -0.457966, 1.73839, -1.15722, -7.20204, 0.365952, -11.8926, 10.6892, -5.6502, 6.60342, -0.145237, 5.93884, 5.93904}, {4.08784, 4.08784, -5.36656, -1.78885, -1.78885, -1.78885, 3.15147, -4.93118e-15, 0, 0, 3.15147, 0, 11.0508, 11.0508, 7.15542, -1.68428, 2.21115, 2.21115, -14.817, 1.68428, -2.21115, 1.68428, -14.817, -2.21115, 2.21115, -1.68428, 2.21115, -3.89543, -3.89543, 0}, {-1.36261, -1.36261, 1.78885, 5.36656, 5.36656, 5.36656, 3.15147, -2.46559e-15, 0, 2.46559e-15, 3.15147, 0, 9.34589, 9.34589, -7.15542, -14.2902, 2.21115, 2.21115, -2.21115, 1.68428, -2.21115, 1.68428, -2.21115, -2.21115, 2.21115, -14.2902, 2.21115, -3.89543, -3.89543, 0}, {-1.36261, -1.36261, 1.78885, -1.78885, -1.78885, -1.78885, -9.45441, 0, 0, 0, 3.15147, 0, 3.89543, 3.89543, -1.33227e-15, 5.47113, 9.36656, 9.36656, 3.23931, 7.13474, -9.36656, 1.68428, -2.21115, -2.21115, 2.21115, -1.68428, 2.21115, -3.89543, -16.5013, 0}, {-1.36261, -1.36261, 1.78885, -1.78885, -1.78885, -1.78885, 3.15147, -4.93118e-15, 0, 0, -9.45441, 0, 3.89543, 3.89543, -1.33227e-15, -1.68428, 2.21115, 2.21115, -2.21115, 1.68428, -2.21115, 7.13474, 3.23931, -9.36656, 9.36656, 5.47113, 9.36656, -16.5013, -3.89543, 0}, {-4.7272, 4.72585, -4.72855, -1.57528, -1.57573, -1.57573, 1.57528, 1.57573, -1.57573, -1.57573, 1.57528, 1.57528, 6.30058, 10.1978, 6.30238, 2.11986e-12, -2.11609e-12, 3.89543, -10.196, -6.30349, 6.30238, 6.30294, -6.30114, -10.1966, 3.89487, 0.000556685, 0.000556685, 0.000556685, -3.89487, 0.000556844}, {1.57573, -1.57528, 1.57618, 4.72585, 4.7272, 4.7272, 1.57528, 1.57573, -1.57573, -1.57573, 1.57528, 1.57528, -6.30349, 10.196, -6.3053, -6.30114, -6.30294, 10.1984, -3.89487, -0.000556685, -0.000556685, -2.11726e-12, 2.11504e-12, -3.89543, 10.1978, -6.30058, -6.30058, 0.000556685, -3.89487, 0.000556844}, {1.57573, -1.57528, 1.57618, -1.57528, -1.57573, -1.57573, -4.72585, -4.7272, 4.7272, -1.57573, 1.57528, 1.57528, -0.000556685, 3.89487, -0.000556844, 6.30114, 6.30294, 10.1984, -10.1978, 6.30058, -6.3053, -2.11637e-12, 2.11548e-12, -3.89543, 3.89487, 0.000556685, 0.000556685, 6.30349, -10.196, -6.30058}, {1.57573, -1.57528, 1.57618, -1.57528, -1.57573, -1.57573, 1.57528, 1.57573, -1.57573, 4.7272, -4.72585, -4.72585, -0.000556685, 3.89487, -0.000556844, 2.1152e-12, -2.11431e-12, 3.89543, -3.89487, -0.000556685, -0.000556685, -6.30294, 6.30114, -10.2002, 10.196, 6.30349, 6.30349, -6.30058, -10.1978, 6.30349}, {-5.22554, -0.410098, 3.98943, -1.54312, -1.54218, -0.61076, 1.18768e-16, 1.60497, -1.1598e-15, -0.198723, -0.199483, 1.94057, 5.92686, 7.906, 4.84171, 1.90741, -0.0776051, 0.754941, -2.15304, -8.57268, 1.64373, -1.11252, 0.875539, -8.51722, 2.15304, 2.15282, -1.64373, 0.245635, -1.73727, -2.39867}, {1.74185, 0.136699, -1.32981, 4.62937, 4.62655, 1.83228, 3.95893e-17, 1.60497, -3.86599e-16, -0.198723, -0.199483, 1.94057, -7.21302, 1.19047, 7.71791, 1.90741, -6.49747, 0.754941, -2.15304, -2.15282, 1.64373, -1.90741, 0.0776051, -0.754941, 2.94793, 2.95075, -9.40601, 0.245635, -1.73727, -2.39867}, {1.74185, 0.136699, -1.32981, -1.54312, -1.54218, -0.61076, 0, -4.8149, 0, -0.198723, -0.199483, 1.94057, -0.245635, 1.73727, 2.39867, 8.0799, 6.09113, 3.19798, -9.12042, -2.69962, 6.96297, -1.90741, 0.0776051, -0.754941, 2.15304, 2.15282, -1.64373, 1.04052, -0.939339, -10.1609}, {1.74185, 0.136699, -1.32981, -1.54312, -1.54218, -0.61076, 1.18768e-16, 1.60497, -1.1598e-15, 0.596168, 0.59845, -5.82171, -0.245635, 1.73727, 2.39867, 1.90741, -0.0776051, 0.754941, -2.15304, -2.15282, 1.64373, -8.87479, -0.469193, 4.5643, 8.32553, 8.32155, 0.799305, 0.245635, -8.15714, -2.39867}, {4.63127, 4.6267, 1.83083, -2.54134, -0.199443, 1.94018, 1.74197, 1.74168, -1.3299, 2.34313, 0, 0, 15.2148, 2.9506, -9.40456, 0.988073, -1.9063, -0.754342, -7.21287, -7.21323, 7.7178, -10.3606, 1.9063, 0.754342, 0.245001, 0.246525, -2.39819, -5.04945, -2.15283, 1.64385}, {-1.54376, -1.54223, -0.610276, 7.62401, 0.598329, -5.82053, 1.74197, 1.74168, -1.3299, 2.34313, 1.01311e-15, -7.73589e-16, 11.2245, 8.32176, 0.797254, -5.9798, -8.87301, 4.56526, -0.245001, -0.246525, 2.39819, -0.988073, 1.9063, 0.754342, -9.1275, 0.246525, -2.39819, -5.04945, -2.15283, 1.64385}, {-1.54376, -1.54223, -0.610276, -2.54134, -0.199443, 1.94018, -5.2259, -5.22503, 3.9897, 2.34313, 0, 0, 5.04945, 2.15283, -1.64385, 11.1534, -1.10853, -8.51505, 5.93003, 5.92241, 4.83929, -0.988073, 1.9063, 0.754342, 0.245001, 0.246525, -2.39819, -14.422, -2.15283, 1.64385}, {-1.54376, -1.54223, -0.610276, -2.54134, -0.199443, 1.94018, 1.74197, 1.74168, -1.3299, -7.02938, 0, 0, 5.04945, 2.15283, -1.64385, 0.988073, -1.9063, -0.754342, -0.245001, -0.246525, 2.39819, 5.18696, 8.07523, 3.19544, 10.4103, 1.0443, -10.1589, -12.0173, -9.11953, 6.96345}, {4.33994, 1.90929, -1.71772, 0, 1.35003, 0, 1.36079e-12, -0.731398, -2.01922, 1.44665, 0.0177991, 1.44665, 1.78815, -6.28218, -0.707741, -1.68203e-12, -0.764672, 2.4959, 1.78815, 4.61632, 9.86504, -5.78659, 0.693475, -8.28248, -1.78815, -1.69073, -1.78815, -1.78815, 0.882056, 0.707741}, {-1.44665, -0.636431, 0.572575, 4.36359e-15, -4.05009, 2.33336e-15, 1.36121e-12, -0.731398, -2.01922, 1.44665, 0.0177991, 1.44665, 7.57474, 1.66367, -2.99804, -7.12561e-12, 2.16092, 10.5728, 1.78815, 1.69073, 1.78815, 1.68183e-12, 0.764672, -2.4959, -7.57474, -1.76193, -7.57474, -1.78815, 0.882056, 0.707741}, {-1.44665, -0.636431, 0.572575, 0, 1.35003, 0, -4.08128e-12, 2.19419, 6.05767, 1.44665, 0.0177991, 1.44665, 1.78815, -0.882056, -0.707741, -1.68158e-12, -6.16479, 2.4959, 7.57474, 4.23646, -0.502145, 1.68266e-12, 0.764672, -2.4959, -1.78815, -1.69073, -1.78815, -7.57474, 0.81086, -5.07885}, {-1.44665, -0.636431, 0.572575, 0, 1.35003, 0, 1.35934e-12, -0.731398, -2.01922, -4.33994, -0.0533972, -4.33994, 1.78815, -0.882056, -0.707741, -1.68023e-12, -0.764672, 2.4959, 1.78815, 1.69073, 1.78815, 5.78659, 3.3104, -4.7862, -1.78815, -7.09085, -1.78815, -1.78815, 3.80765, 8.78463}, {-3.79117, -3.78885, -1.50052, 0.577052, -1.02738, -1.79083, -1.45233, 0.153525, -0.574823, -0.388446, -0.389091, 1.86548, -4.58353, 3.81836, 8.75865, 1.0819, 1.08015, 2.92411, 6.04244, -2.36496, 2.39156, 0.471884, 0.476215, -10.386, -0.233129, 1.75086, -0.0922713, 2.27532, 0.291177, -1.59534}, {1.26372, 1.26295, 0.500174, -1.73116, 3.08215, 5.37248, -1.45233, 0.153525, -0.574823, -0.388446, -0.389091, 1.86548, -7.33021, -5.34298, -0.40536, 6.89121, 0.466052, 5.2234, 0.233129, -1.75086, 0.0922713, -1.0819, -1.08015, -2.92411, 1.32066, 3.30723, -7.55418, 2.27532, 0.291177, -1.59534}, {1.26372, 1.26295, 0.500174, 0.577052, -1.02738, -1.79083, 4.35698, -0.460574, 1.72447, -0.388446, -0.389091, 1.86548, -2.27532, -0.291177, 1.59534, -1.22631, 5.18969, 10.0874, -4.82176, -6.80267, -1.90843, -1.0819, -1.08015, -2.92411, -0.233129, 1.75086, -0.0922713, 3.82911, 1.84754, -9.05724}, {1.26372, 1.26295, 0.500174, 0.577052, -1.02738, -1.79083, -1.45233, 0.153525, -0.574823, 1.16534, 1.16727, -5.59643, -2.27532, -0.291177, 1.59534, 1.0819, 1.08015, 2.92411, 0.233129, -1.75086, 0.0922713, -6.13679, -6.13196, -4.9248, -2.54134, 5.8604, 7.07104, 8.08463, -0.322922, 0.703957}, {2.52504, -4.49559, -7.83624, 1.26389, 1.26265, 0.49964, -0.875592, -0.873298, -2.36467, 0.453379, -1.88788, -0.747051, -5.57746, -8.46358, -5.84486, -0.479968, -0.48126, 2.3053, 5.62503, 2.72036, 9.15287, -1.33355, 8.03278, 0.682901, -2.12267, 0.772832, 0.305817, 0.521884, 3.413, 3.8463}, {-0.841681, 1.49853, 2.61208, -3.79168, -3.78794, -1.49892, -0.875592, -0.873298, -2.36467, 0.453379, -1.88788, -0.747051, 2.84484, -9.40713, -14.2946, 3.0224, 3.01193, 11.764, 2.12267, -0.772832, -0.305817, 0.479968, 0.48126, -2.3053, -3.93618, 8.32435, 3.29402, 0.521884, 3.413, 3.8463}, {-0.841681, 1.49853, 2.61208, 1.26389, 1.26265, 0.49964, 2.62678, 2.61989, 7.09401, 0.453379, -1.88788, -0.747051, -0.521884, -3.413, -3.8463, -5.53554, -5.53184, 0.306743, 5.48939, -6.76696, -10.7541, 0.479968, 0.48126, -2.3053, -2.12267, 0.772832, 0.305817, -1.29163, 10.9645, 6.8345}, {-0.841681, 1.49853, 2.61208, 1.26389, 1.26265, 0.49964, -0.875592, -0.873298, -2.36467, -1.36014, 5.66364, 2.24115, -0.521884, -3.413, -3.8463, -0.479968, -0.48126, 2.3053, 2.12267, -0.772832, -0.305817, 3.84669, -5.51287, -12.7536, -7.17824, -4.27775, -1.69274, 4.02425, 6.90619, 13.305}, {5.37846, -0.954422, 1.65136, 0.482922, -1.73161, -0.484335, 0.65353, 0.326507, 1.69088, 0.656368, 1.08696, -0.656093, -0.312565, 8.67359, 3.21641, -1.40473, 1.7368, -1.49137, -1.20588, -2.10286, -8.17318, -1.22074, -6.08465, 4.11575, -1.40824, 0.796829, 1.40965, -1.61912, -1.74715, -1.27907}, {-1.79282, 0.318141, -0.550454, -1.44877, 5.19483, 1.45301, 0.65353, 0.326507, 1.69088, 0.656368, 1.08696, -0.656093, 8.7904, 0.474582, 3.48088, -4.01885, 0.430774, -8.2549, 1.40824, -0.796829, -1.40965, 1.40473, -1.7368, 1.49137, -4.03371, -3.55102, 4.03402, -1.61912, -1.74715, -1.27907}, {-1.79282, 0.318141, -0.550454, 0.482922, -1.73161, -0.484335, -1.96059, -0.979522, -5.07265, 0.656368, 1.08696, -0.656093, 1.61912, 1.74715, 1.27907, -3.33642, 8.66325, 0.445966, 8.57952, -2.06939, 0.792169, 1.40473, -1.7368, 1.49137, -1.40824, 0.796829, 1.40965, -4.24459, -6.095, 1.3453}, {-1.79282, 0.318141, -0.550454, 0.482922, -1.73161, -0.484335, 0.65353, 0.326507, 1.69088, -1.9691, -3.26089, 1.96828, 1.61912, 1.74715, 1.27907, -1.40473, 1.7368, -1.49137, 1.40824, -0.796829, -1.40965, 8.57601, -3.00937, 3.69319, -3.33993, 7.72327, 3.34699, -4.23324, -3.05317, -8.0426}, {-8.19974, -2.81226, -4.15773, 1.49846, -0.593081, -0.985836, -2.7214, 1.07711, -0.607179, -1.5103, -1.42145, 0.207104, -11.2245, 1.9467, 3.44883, 1.51164, -0.598298, 1.96907, 10.8709, -6.79856, 1.46615, 4.52957, 6.28411, -2.79749, 0.0146435, 2.4901, 0.962565, 5.23067, 0.425625, 0.494519}, {2.73325, 0.937419, 1.38591, -4.49537, 1.77924, 2.95751, -2.7214, 1.07711, -0.607179, -1.5103, -1.42145, 0.207104, -16.1637, -4.1753, -6.03816, 12.3972, -4.90676, 4.39779, -0.0146435, -2.4901, -0.962565, -1.51164, 0.598298, -1.96907, 6.05586, 8.17591, 0.134147, 5.23067, 0.425625, 0.494519}, {2.73325, 0.937419, 1.38591, 1.49846, -0.593081, -0.985836, 8.16419, -3.23134, 1.82154, -1.5103, -1.42145, 0.207104, -5.23067, -0.425625, -0.494519, -4.48219, 1.77402, 5.91242, -10.9476, -6.23977, -6.50621, -1.51164, 0.598298, -1.96907, 0.0146435, 2.4901, 0.962565, 11.2719, 6.11143, -0.333899}, {2.73325, 0.937419, 1.38591, 1.49846, -0.593081, -0.985836, -2.7214, 1.07711, -0.607179, 4.53091, 4.26436, -0.621313, -5.23067, -0.425625, -0.494519, 1.51164, -0.598298, 1.96907, -0.0146435, -2.4901, -0.962565, -12.4446, -3.15138, -7.51272, -5.97918, 4.86242, 4.90591, 16.1163, -3.88283, 2.92323}, {-8.88178e-16, -2.39835, -6.05767, -3.06161e-16, 0.53318, -2.01922, -1.31177, -0.650588, 1.29879, 1.31177, -0.68204, -1.29879, 1.33227e-15, -3.77994, 8.07689, 1.62143, 0.145125, 0.890503, 6.86849, 2.41835, -9.29645, -6.86849, 2.58304, 4.30465, -1.62143, 0.184002, 4.10129, 0, 1.64722, 0}, {0, 0.799449, 2.01922, 0, -1.59954, 6.05767, -1.31177, -0.650588, 1.29879, 1.31177, -0.68204, -1.29879, 0, -4.84502, -8.07689, 6.86849, 2.74748, -4.30465, 1.62143, -0.184002, -4.10129, -1.62143, -0.145125, -0.890503, -6.86849, 2.91216, 9.29645, 0, 1.64722, 0}, {6.66134e-16, 0.799449, 2.01922, -6.73554e-16, 0.53318, -2.01922, 3.9353, 1.95177, -3.89637, 1.31177, -0.68204, -1.29879, 0, -1.64722, -1.55431e-15, 1.62143, -1.98759, 8.96739, 1.62143, -3.3818, -12.1782, -1.62143, -0.145125, -0.890503, -1.62143, 0.184002, 4.10129, -5.24706, 4.37538, 5.19516}, {2.22045e-16, 0.799449, 2.01922, -4.28625e-16, 0.53318, -2.01922, -1.31177, -0.650588, 1.29879, -3.9353, 2.04612, 3.89637, 4.44089e-16, -1.64722, -1.77636e-15, 1.62143, 0.145125, 0.890503, 1.62143, -0.184002, -4.10129, -1.62143, -3.34292, -8.96739, -1.62143, -1.94872, 12.1782, 5.24706, 4.24957, -5.19516}, {-1.77636e-15, 0, 9.45441, 1.36261, 1.78885, 1.36261, 1.78885, -1.78885, 1.78885, -3.15147, 0, 0, -7.13474, -9.36656, -3.23931, -3.89543, 0, -3.89543, -9.36656, 9.36656, -5.47113, 16.5013, 0, 3.89543, 2.21115, -2.21115, -1.68428, 1.68428, 2.21115, -2.21115}, {-4.44089e-16, 0, -3.15147, -4.08784, -5.36656, -4.08784, 1.78885, -1.78885, 1.78885, -3.15147, 0, 0, -1.68428, -2.21115, 14.817, -11.0508, 7.15542, -11.0508, -2.21115, 2.21115, 1.68428, 3.89543, 0, 3.89543, 14.817, -2.21115, -1.68428, 1.68428, 2.21115, -2.21115}, {0, 0, -3.15147, 1.36261, 1.78885, 1.36261, -5.36656, 5.36656, -5.36656, -3.15147, 0, 0, -1.68428, -2.21115, 2.21115, -9.34589, -7.15542, -9.34589, -2.21115, 2.21115, 14.2902, 3.89543, 0, 3.89543, 2.21115, -2.21115, -1.68428, 14.2902, 2.21115, -2.21115}, {4.44089e-16, 0, -3.15147, 1.36261, 1.78885, 1.36261, 1.78885, -1.78885, 1.78885, 9.45441, 0, 0, -1.68428, -2.21115, 2.21115, -3.89543, 0, -3.89543, -2.21115, 2.21115, 1.68428, 3.89543, 0, 16.5013, -3.23931, -9.36656, -7.13474, -5.47113, 9.36656, -9.36656}, {-2.46108, 3.54412, -0.0109738, -0.670026, 0.174063, -1.44271, 0.904569, 1.43103, -0.00443094, -1.0549, -0.423716, 1.44348, 2.49428, 0.548851, 7.54959, -0.28991, -1.984, 1.78876, -5.7504, -6.03269, 0.0186792, 4.50952, 3.67886, -7.56268, 2.13213, 0.308587, -0.000955489, 0.185824, -1.2451, -1.77876}, {0.820361, -1.18137, 0.00365793, 2.01008, -0.52219, 4.32812, 0.904569, 1.43103, -0.00443094, -1.0549, -0.423716, 1.44348, -3.46727, 5.9706, 1.76413, -3.90819, -7.7081, 1.80648, -2.13213, -0.308587, 0.000955489, 0.28991, 1.984, -1.78876, 6.35174, 2.00345, -5.77487, 0.185824, -1.2451, -1.77876}, {0.820361, -1.18137, 0.00365793, -0.670026, 0.174063, -1.44271, -2.71371, -4.29308, 0.0132928, -1.0549, -0.423716, 1.44348, -0.185824, 1.2451, 1.77876, 2.39019, -2.68025, 7.55959, -5.41357, 4.41691, -0.0136762, 0.28991, 1.984, -1.78876, 2.13213, 0.308587, -0.000955489, 4.40544, 0.449758, -7.55268}, {0.820361, -1.18137, 0.00365793, -0.670026, 0.174063, -1.44271, 0.904569, 1.43103, -0.00443094, 3.16471, 1.27115, -4.33044, -0.185824, 1.2451, 1.77876, -0.28991, -1.984, 1.78876, -2.13213, -0.308587, 0.000955489, -2.99153, 6.7095, -1.80339, 4.81224, -0.387667, 5.76987, -3.43245, -6.96921, -1.76104}, {-4.81192, -4.81192, 0.736124, -0.501255, 1.51797, 0.85277, 0.0700522, -1.94917, 0.533356, -1.17277, -1.17277, -1.14075, 0.641985, -9.9308, -4.16186, 0.532996, 0.532996, -1.71335, -2.34942, 8.22336, -2.48939, 4.15809, 4.15809, 6.27635, 2.06921, -0.426686, 0.355964, 1.36304, 3.85893, 0.750782}, {1.60397, 1.60397, -0.245375, 1.50376, -4.5539, -2.55831, 0.0700522, -1.94917, 0.533356, -1.17277, -1.17277, -1.14075, -7.77893, -10.2748, 0.230717, 0.252787, 8.32967, -3.84677, -2.06921, 0.426686, -0.355964, -0.532996, -0.532996, 1.71335, 6.76029, 4.2644, 4.91897, 1.36304, 3.85893, 0.750782}, {1.60397, 1.60397, -0.245375, -0.501255, 1.51797, 0.85277, -0.210157, 5.84751, -1.60007, -1.17277, -1.17277, -1.14075, -1.36304, -3.85893, -0.750782, 2.53802, -5.53887, -5.12443, -8.4851, -5.98921, 0.625534, -0.532996, -0.532996, 1.71335, 2.06921, -0.426686, 0.355964, 6.05412, 8.55001, 5.31379}, {1.60397, 1.60397, -0.245375, -0.501255, 1.51797, 0.85277, 0.0700522, -1.94917, 0.533356, 3.51831, 3.51831, 3.42225, -1.36304, -3.85893, -0.750782, 0.532996, 0.532996, -1.71335, -2.06921, 0.426686, -0.355964, -6.94889, -6.94889, 2.69484, 4.07423, -6.49855, -3.05512, 1.08283, 11.6556, -1.38264}, {-4.7272, -4.7272, -4.7272, -1.57573, -1.57573, 1.57573, 1.57573, -1.57573, -1.57573, -1.57573, 1.57573, -1.57573, 6.30294, 6.30294, -10.1984, -1.80989e-12, 3.89543, -1.81655e-12, -10.1984, 6.30294, 6.30294, 6.30294, -10.1984, 6.30294, 3.89543, -1.7979e-12, -1.80411e-12, 4.21885e-15, -3.55271e-15, 3.89543}, {1.57573, 1.57573, 1.57573, 4.7272, 4.7272, -4.7272, 1.57573, -1.57573, -1.57573, -1.57573, 1.57573, -1.57573, -6.30294, -6.30294, -10.1984, -6.30294, 10.1984, 6.30294, -3.89543, 1.79723e-12, 1.80655e-12, 1.80694e-12, -3.89543, 1.81759e-12, 10.1984, -6.30294, 6.30294, 3.33067e-15, -3.10862e-15, 3.89543}, {1.57573, 1.57573, 1.57573, -1.57573, -1.57573, 1.57573, -4.7272, 4.7272, 4.7272, -1.57573, 1.57573, -1.57573, -4.21885e-15, 1.77636e-15, -3.89543, 6.30294, 10.1984, -6.30294, -10.1984, -6.30294, -6.30294, 1.81515e-12, -3.89543, 1.81515e-12, 3.89543, -1.80722e-12, -1.80145e-12, 6.30294, -6.30294, 10.1984}, {1.57573, 1.57573, 1.57573, -1.57573, -1.57573, 1.57573, 1.57573, -1.57573, -1.57573, 4.7272, -4.7272, 4.7272, -3.10862e-15, 1.11022e-15, -3.89543, -1.80456e-12, 3.89543, -1.81655e-12, -3.89543, 1.80789e-12, 1.79878e-12, -6.30294, -10.1984, -6.30294, 10.1984, 6.30294, -6.30294, -6.30294, 6.30294, 10.1984}, {0, 2.66454e-15, 3.96048, -1.97345e-12, 2.01922, 0.776088, 1.44665, -0.572575, 0.322765, -1.44665, -1.44665, 0.221307, 1.03333e-11, -10.5728, -2.43184, -1.78815, -1.78815, -1.35826, -7.57474, 2.99804, -0.0582134, 7.57474, 7.57474, 0.47303, 1.78815, -0.707741, -1.23285, -2.4396e-12, 2.4959, -0.672511}, {0, -4.44089e-16, -1.32016, 5.91834e-12, -6.05767, -2.32827, 1.44665, -0.572575, 0.322765, -1.44665, -1.44665, 0.221307, 2.43894e-12, -2.4959, 5.95315, -7.57474, 0.502145, -2.64932, -1.78815, 0.707741, 1.23285, 1.78815, 1.78815, 1.35826, 7.57474, 5.07885, -2.11808, -2.43872e-12, 2.4959, -0.672511}, {0, 0, -1.32016, -1.97211e-12, 2.01922, 0.776088, -4.33994, 1.71772, -0.968296, -1.44665, -1.44665, 0.221307, 2.43783e-12, -2.4959, 0.672511, -1.78815, -9.86504, -4.46261, -1.78815, 0.707741, 6.51349, 1.78815, 1.78815, 1.35826, 1.78815, -0.707741, -1.23285, 5.78659, 8.28248, -1.55774}, {2.22045e-16, 0, -1.32016, -1.97238e-12, 2.01922, 0.776088, 1.44665, -0.572575, 0.322765, 4.33994, 4.33994, -0.663921, 2.43761e-12, -2.4959, 0.672511, -1.78815, -1.78815, -1.35826, -1.78815, 0.707741, 1.23285, 1.78815, 1.78815, 6.6389, 1.78815, -8.78463, -4.3372, -5.78659, 4.7862, -1.96357}, {-5.69487, 6.21725e-15, -5.32907e-15, -0.575562, 1.78885, 1.78885, 0.744968, -3.64699, -0.373467, -2.0677, 1.85814, -1.41539, 0.667265, -9.36656, -9.36656, -0.209397, 2.29678, -1.74951, -6.24712, 19.0959, 1.9555, 8.48018, -9.72932, 7.41106, 3.26725, -4.50793, -0.461631, 1.63498, 2.21115, 2.21115}, {1.89829, -2.44249e-15, 8.88178e-16, 1.72669, -5.36656, -5.36656, 0.744968, -3.64699, -0.373467, -2.0677, 1.85814, -1.41539, -9.22815, -2.21115, -2.21115, -3.18927, 16.8847, -0.255645, -3.26725, 4.50793, 0.461631, 0.209397, -2.29678, 1.74951, 11.538, -11.9405, 5.19992, 1.63498, 2.21115, 2.21115}, {1.89829, 4.44089e-16, 2.22045e-16, -0.575562, 1.78885, 1.78885, -2.2349, 10.941, 1.1204, -2.0677, 1.85814, -1.41539, -1.63498, -2.21115, -2.21115, 2.09285, -4.85864, -8.90493, -10.8604, 4.50793, 0.461631, 0.209397, -2.29678, 1.74951, 3.26725, -4.50793, -0.461631, 9.90577, -5.2214, 7.87269}, {1.89829, -8.88178e-16, 8.88178e-16, -0.575562, 1.78885, 1.78885, 0.744968, -3.64699, -0.373467, 6.20309, -5.57441, 4.24616, -1.63498, -2.21115, -2.21115, -0.209397, 2.29678, -1.74951, -3.26725, 4.50793, 0.461631, -7.38377, -2.29678, 1.74951, 5.5695, -11.6633, -7.61705, -1.34489, 16.7991, 3.70501}, {1.1885, -5.81832, -0.595821, 1.89829, 5.76114e-16, -1.45437e-15, -1.41683, -1.32819, -1.74168, -0.0852942, -0.611252, 1.54307, -9.44989, -2.39728, -0.245492, -0.59512, 1.64173, 2.15284, 7.9083, 4.5572, 8.87406, 0.936297, 0.803277, -8.32513, -2.24099, 0.755549, -1.90734, 1.85673, 2.39728, 0.245492}, {-0.396168, 1.93944, 0.198607, -5.69487, 1.01358e-15, 4.64389e-15, -1.41683, -1.32819, -1.74168, -0.0852942, -0.611252, 1.54307, -0.272056, -10.155, -1.03992, 5.0722, 6.95448, 9.11956, 2.24099, -0.755549, 1.90734, 0.59512, -1.64173, -2.15284, -1.89981, 3.20056, -8.07964, 1.85673, 2.39728, 0.245492}, {-0.396168, 1.93944, 0.198607, 1.89829, 0, 0, 4.25049, 3.98456, 5.22504, -0.0852942, -0.611252, 1.54307, -1.85673, -2.39728, -0.245492, -8.18828, 1.64173, 2.15284, 3.82566, -8.51331, 1.11292, 0.59512, -1.64173, -2.15284, -2.24099, 0.755549, -1.90734, 2.1979, 4.84229, -5.9268}, {-0.396168, 1.93944, 0.198607, 1.89829, 5.76114e-16, -1.45437e-15, -1.41683, -1.32819, -1.74168, 0.255883, 1.83376, -4.62922, -1.85673, -2.39728, -0.245492, -0.59512, 1.64173, 2.15284, 2.24099, -0.755549, 1.90734, 2.17979, -9.39949, -2.94726, -9.83415, 0.755549, -1.90734, 7.52404, 7.71003, 7.21221}, {-5.53957e-11, -0.00379978, 5.36656, -2.34313, -2.34273, 1.78885, -1.36201e-15, 2.34147, 0, 2.34313, 0, 0, 12.2688, 12.2651, -7.15542, 2.89626, 0.00156559, -2.21115, -2.28173e-11, -12.2616, 2.21115, -12.2688, -0.00156559, 2.21115, 2.28226e-11, 2.89578, -2.21115, -2.89626, -2.89421, 0}, {1.2307e-11, 0.00126659, -1.78885, 7.02938, 7.0282, -5.36656, 0, 2.34147, 0, 2.34313, 1.36201e-15, 0, 2.89626, 2.88915, 7.15542, 2.89626, -9.3643, -2.21115, -1.52123e-11, -2.89578, 2.21115, -2.89626, -0.00156559, 2.21115, -9.3725, 2.89578, -2.21115, -2.89626, -2.89421, 0}, {1.23048e-11, 0.00126659, -1.78885, -2.34313, -2.34273, 1.78885, 0, -7.0244, 0, 2.34313, 0, 0, 2.89626, 2.89421, 1.33227e-15, 12.2688, 9.3725, -9.36656, -6.44302e-11, -2.90084, 9.36656, -2.89626, -0.00156559, 2.21115, 1.52101e-11, 2.89578, -2.21115, -12.2688, -2.89421, 0}, {1.23097e-11, 0.00126659, -1.78885, -2.34313, -2.34273, 1.78885, -1.36201e-15, 2.34147, 0, -7.02938, 0, 0, 2.89626, 2.89421, 1.33227e-15, 2.89626, 0.00156559, -2.21115, -1.52136e-11, -2.89578, 2.21115, -2.89626, -0.00663197, 9.36656, 9.3725, 12.2667, -9.36656, -2.89626, -12.2601, 0}, {-7.02938, -5.36656, -7.02938, -1.21121e-11, -1.78885, -1.21116e-11, 0, 0, -2.34313, -2.34313, 0, 0, -2.89626, 7.15542, -2.89626, 1.49714e-11, 2.21115, 2.89626, -2.89626, -2.21115, 9.3725, 9.3725, -2.21115, -2.89626, 2.89626, 2.21115, 1.49707e-11, 2.89626, 0, 2.89626}, {2.34313, 1.78885, 2.34313, 5.48025e-11, 5.36656, 5.48009e-11, 0, 0, -2.34313, -2.34313, 0, 0, -12.2688, -7.15542, -12.2688, 2.25799e-11, 2.21115, 12.2688, -2.89626, -2.21115, -2.2581e-11, -2.25816e-11, -2.21115, -2.89626, 12.2688, 2.21115, 2.25792e-11, 2.89626, 0, 2.89626}, {2.34313, 1.78885, 2.34313, -1.21079e-11, -1.78885, -1.21095e-11, 0, 0, 7.02938, -2.34313, 0, 0, -2.89626, -1.33227e-15, -2.89626, 6.33979e-11, 9.36656, 2.89626, -12.2688, -9.36656, -9.3725, -1.4968e-11, -2.21115, -2.89626, 2.89626, 2.21115, 1.49681e-11, 12.2688, 0, 2.89626}, {2.34313, 1.78885, 2.34313, -1.211e-11, -1.78885, -1.21079e-11, 0, 0, -2.34313, 7.02938, 0, 0, -2.89626, -1.33227e-15, -2.89626, 1.49688e-11, 2.21115, 2.89626, -2.89626, -2.21115, -1.4968e-11, -9.3725, -9.36656, -12.2688, 2.89626, 9.36656, 6.33979e-11, 2.89626, 0, 12.2688}, {6.00487, -2.5896, 0, 1.30033, -0.681296, -1.31177, -1.30033, -0.651333, 1.31177, 2.00162, 0.469428, 0, -4.33448, 2.50034, 6.86849, 0, 1.64722, 0, 9.28277, 2.34345, -6.86849, -8.00649, -3.52493, 0, -4.08144, 0.261882, 1.62143, -0.866843, 0.224847, -1.62143}, {-2.00162, 0.8632, 3.03492e-16, -3.901, 2.04389, 3.9353, -1.30033, -0.651333, 1.31177, 2.00162, 0.469428, -3.03492e-16, 8.87333, -3.67765, 1.62143, 5.20133, 4.25255, -5.24706, 4.08144, -0.261882, -1.62143, 1.49073e-15, -1.64722, -2.26029e-31, -12.0879, -1.61583, 1.62143, -0.866843, 0.224847, -1.62143}, {-2.00162, 0.8632, -1.61346e-16, 1.30033, -0.681296, -1.31177, 3.901, 1.954, -3.9353, 2.00162, 0.469428, -6.06985e-17, 0.866843, -0.224847, 1.62143, -5.20133, 4.3724, 5.24706, 12.0879, -3.71468, -1.62143, 1.26868e-15, -1.64722, 2.22045e-16, -4.08144, 0.261882, 1.62143, -8.87333, -1.65287, -1.62143}, {-2.00162, 0.8632, 0, 1.30033, -0.681296, -1.31177, -1.30033, -0.651333, 1.31177, -6.00487, -1.40829, 0, 0.866843, -0.224847, 1.62143, 0, 1.64722, 0, 4.08144, -0.261882, -1.62143, 8.00649, -5.10002, 0, -9.28277, 2.98706, 6.86849, 4.33448, 2.83018, -6.86849}, {-3.67855, 1.13524, -1.13945, -0.728854, -0.729491, 0.729491, -0.347691, -0.347995, -1.25767, -0.149637, 1.4559, 0.148365, 2.30068, 4.28741, -4.28915, 1.33068, 1.33185, 0.652868, 0.304891, 2.28987, 6.11578, -0.732135, -7.15545, -1.24633, 1.08587, -0.897892, -1.08509, 0.614731, -1.36945, 1.37118}, {1.22618, -0.378415, 0.379817, 2.18656, 2.18847, -2.18847, -0.347691, -0.347995, -1.25767, -0.149637, 1.4559, 0.148365, -5.51946, 2.8831, -2.89045, 2.72145, 2.72383, 5.68356, -1.08587, 0.897892, 1.08509, -1.33068, -1.33185, -0.652868, 1.68442, -6.72149, -1.67855, 0.614731, -1.36945, 1.37118}, {1.22618, -0.378415, 0.379817, -0.728854, -0.729491, 0.729491, 1.04307, 1.04399, 3.77302, -0.149637, 1.4559, 0.148365, -0.614731, 1.36945, -1.37118, 4.2461, 4.24981, -2.2651, -5.9906, 2.41155, -0.434178, -1.33068, -1.33185, -0.652868, 1.08587, -0.897892, -1.08509, 1.21328, -7.19305, 0.777722}, {1.22618, -0.378415, 0.379817, -0.728854, -0.729491, 0.729491, -0.347691, -0.347995, -1.25767, 0.448911, -4.3677, -0.445094, -0.614731, 1.36945, -1.37118, 1.33068, 1.33185, 0.652868, -1.08587, 0.897892, 1.08509, -6.23541, 0.181812, -2.17214, 4.00129, 2.02007, -4.00305, 2.0055, 0.0225343, 6.40187}, {-3.16808, 4.44089e-16, 0, -0.781545, -5.04356e-16, -1.31177, 0.234793, 1.31177, 1.31177, -0.509273, -1.31177, 0, 2.78691, 2.88658e-15, 6.86849, 0.675824, -1.62143, 0, -2.53471, -6.86849, -6.86849, 1.36127, 6.86849, 0, 1.59554, 1.62143, 1.62143, 0.339276, -8.88178e-16, -1.62143}, {1.05603, 2.22045e-16, -1.91911e-16, 2.34464, 3.02613e-15, 3.9353, 0.234793, 1.31177, 1.31177, -0.509273, -1.31177, -2.52178e-16, -4.56338, 0, 1.62143, -0.263347, -6.86849, -5.24706, -1.59554, -1.62143, -1.62143, -0.675824, 1.62143, 4.44089e-16, 3.63263, 6.86849, 1.62143, 0.339276, -8.88178e-16, -1.62143}, {1.05603, -2.22045e-16, 6.58225e-17, -0.781545, -7.56534e-16, -1.31177, -0.704378, -3.9353, -3.9353, -0.509273, -1.31177, 3.78267e-16, -0.339276, 1.11022e-15, 1.62143, 3.80201, -1.62143, 5.24706, -5.81964, -1.62143, -1.62143, -0.675824, 1.62143, -6.66134e-16, 1.59554, 1.62143, 1.62143, 2.37637, 5.24706, -1.62143}, {1.05603, -2.22045e-16, 0, -0.781545, 2.52178e-16, -1.31177, 0.234793, 1.31177, 1.31177, 1.52782, 3.9353, 0, -0.339276, 0, 1.62143, 0.675824, -1.62143, 0, -1.59554, -1.62143, -1.62143, -4.89993, 1.62143, 0, 4.72172, 1.62143, 6.86849, -0.599895, -5.24706, -6.86849}, {-4.31352, 0.137385, -4.35145, -1.43784, 0.845244, 0.568738, 0, -1.33263, 0, 1.50711e-12, 0.53318, -2.01922, 5.75136, -4.36915, -4.77085, 1.77727, 0.602441, -0.702999, -1.77727, 7.03434, -1.7929, -1.77727, -2.73516, 8.77989, 1.77727, -1.70383, 1.7929, -1.86289e-12, 0.988174, 2.4959}, {1.43784, -0.0457949, 1.45048, 4.31352, -2.53573, -1.70622, 0, -1.33263, 0, 1.50495e-12, 0.53318, -2.01922, -5.75136, -0.804994, -8.29783, 1.77727, 5.93296, -0.702999, -1.77727, 1.70383, -1.7929, -1.77727, -0.602441, 0.702999, 1.77727, -3.83654, 9.86978, -1.86021e-12, 0.988174, 2.4959}, {1.43784, -0.0457949, 1.45048, -1.43784, 0.845244, 0.568738, 0, 3.99789, 0, 1.50711e-12, 0.53318, -2.01922, 1.86182e-12, -0.988174, -2.4959, 7.52863, -2.77854, -2.97795, -7.52863, 1.887, -7.59483, -1.77727, -0.602441, 0.702999, 1.77727, -1.70383, 1.7929, -7.89132e-12, -1.14454, 10.5728}, {1.43784, -0.0457949, 1.45048, -1.43784, 0.845244, 0.568738, 0, -1.33263, 0, -4.51484e-12, -1.59954, 6.05767, 1.85914e-12, -0.988174, -2.4959, 1.77727, 0.602441, -0.702999, -1.77727, 1.70383, -1.7929, -7.52863, -0.419261, -5.09894, 7.52863, -5.0848, -0.482057, -1.86021e-12, 6.31869, 2.4959}, {0, 7.02938, 3.90313e-17, 0, 0, -2.34313, 1.78885, 2.34313, 2.34059, -1.78885, -1.21084e-11, 0.00253498, 0, 2.89626, 12.2688, -2.21115, -2.89626, 0.00313341, -9.36656, -9.3725, -12.2555, 9.36656, 2.89626, -0.0132733, 2.21115, 1.49669e-11, 2.89313, 0, -2.89626, -2.89626}, {0, -2.34313, -2.39826e-16, 0, 0, 7.02938, 1.78885, 2.34313, 2.34059, -1.78885, -1.211e-11, 0.00253498, 0, 12.2688, 2.89626, -9.36656, -12.2688, -9.35923, -2.21115, -1.4967e-11, -2.89313, 2.21115, 2.89626, -0.00313341, 9.36656, 6.34088e-11, 2.88299, 0, -2.89626, -2.89626}, {0, -2.34313, -6.10623e-16, 0, 0, -2.34313, -5.36656, -7.02938, -7.02177, -1.78885, -1.21105e-11, 0.00253498, 0, 2.89626, 2.89626, -2.21115, -2.89626, 9.37564, -2.21115, 9.3725, -2.89313, 2.21115, 2.89626, -0.00313341, 2.21115, 1.49694e-11, 2.89313, 7.15542, -2.89626, -2.9064}, {0, -2.34313, 7.67181e-16, 0, 0, -2.34313, 1.78885, 2.34313, 2.34059, 5.36656, 5.47978e-11, -0.00760494, 0, 2.89626, 2.89626, -2.21115, -2.89626, 0.00313341, -2.21115, -2.25762e-11, -2.89313, 2.21115, 12.2688, -0.00313341, 2.21115, 2.25779e-11, 12.2656, -7.15542, -12.2688, -12.2586}, {-3.23058, -0.349184, -0.349184, -0.223923, -1.25104, -1.25104, -0.552433, 1.28003, -0.0317341, -0.300503, -0.14539, 1.16638, -0.158596, 6.40664, 6.40664, 0.959628, -0.0358398, 1.58559, 1.56151, -6.8462, 0.0222906, 0.242385, 0.617398, -6.25109, 0.648226, 1.72608, 0.104646, 1.05429, -1.40249, -1.40249}, {1.07686, 0.116395, 0.116395, 0.671768, 3.75311, 3.75311, -0.552433, 1.28003, -0.0317341, -0.300503, -0.14539, 1.16638, -5.36172, 0.936916, 0.936916, 3.16936, -5.15596, 1.71253, -0.648226, -1.72608, -0.104646, -0.959628, 0.0358398, -1.58559, 1.85024, 2.30764, -4.56086, 1.05429, -1.40249, -1.40249}, {1.07686, 0.116395, 0.116395, -0.223923, -1.25104, -1.25104, 1.6573, -3.84009, 0.0952024, -0.300503, -0.14539, 1.16638, -1.05429, 1.40249, 1.40249, 1.85532, 4.96831, 6.58973, -4.95566, -2.19166, -0.570224, -0.959628, 0.0358398, -1.58559, 0.648226, 1.72608, 0.104646, 2.2563, -0.820936, -6.068}, {1.07686, 0.116395, 0.116395, -0.223923, -1.25104, -1.25104, -0.552433, 1.28003, -0.0317341, 0.90151, 0.436169, -3.49913, -1.05429, 1.40249, 1.40249, 0.959628, -0.0358398, 1.58559, -0.648226, -1.72608, -0.104646, -5.26706, -0.429738, -2.05117, 1.54392, 6.73022, 5.10879, 3.26402, -6.52262, -1.27556}, {5.36656, 7.02938, -7.02938, 0, 0, -2.34313, 1.78885, -1.02105e-11, 1.05689e-11, 0, 2.34313, 0, 2.21115, 2.89626, 9.3725, -2.21115, 1.26208e-11, 2.89626, -7.15542, 2.89626, -2.89626, 2.21115, -9.3725, -2.89626, 0, -2.89626, 2.89626, -2.21115, -2.89626, -1.30639e-11}, {-1.78885, -2.34313, 2.34313, 0, 0, 7.02938, 1.78885, -1.02084e-11, 1.05669e-11, 1.04056e-15, 2.34313, 6.14662e-27, 9.36656, 12.2688, -9.3725, -9.36656, 5.34518e-11, 2.89626, 2.61847e-15, 2.89626, -2.89626, 2.21115, -1.26165e-11, -2.89626, -5.44843e-15, -12.2688, 2.89626, -2.21115, -2.89626, -1.30613e-11}, {-1.78885, -2.34313, 2.34313, 0, 0, -2.34313, -5.36656, 3.06329e-11, -3.17084e-11, 0, 2.34313, 0, 2.21115, 2.89626, 1.30628e-11, -2.21115, 1.26215e-11, 12.2688, 7.15542, 12.2688, -12.2688, 2.21115, -1.26197e-11, -2.89626, 0, -2.89626, 2.89626, -2.21115, -12.2688, -1.30646e-11}, {-1.78885, -2.34313, 2.34313, 0, 0, -2.34313, 1.78885, -1.02084e-11, 1.05658e-11, 0, -7.02938, 0, 2.21115, 2.89626, 1.30583e-11, -2.21115, 1.26183e-11, 2.89626, 1.33227e-15, 2.89626, -2.89626, 9.36656, 9.3725, -12.2688, 0, -2.89626, 12.2688, -9.36656, -2.89626, -5.53233e-11}, {1.77636e-15, 9.45441, -8.88178e-16, 3.15147, -2.79907e-15, 2.79907e-15, -1.36261, 1.36261, 1.78885, -1.78885, 1.78885, -1.78885, -16.5013, 3.89543, -1.42109e-14, -2.21115, -1.68428, -2.21115, 7.13474, -3.23931, -9.36656, 9.36656, -5.47113, 9.36656, -1.68428, -2.21115, 2.21115, 3.89543, -3.89543, 3.10862e-15}, {-6.66134e-16, -3.15147, 6.66134e-16, -9.45441, 1.00042e-15, -8.3972e-15, -1.36261, 1.36261, 1.78885, -1.78885, 1.78885, -1.78885, -3.89543, 16.5013, -7.10543e-15, 3.23931, -7.13474, -9.36656, 1.68428, 2.21115, -2.21115, 2.21115, 1.68428, 2.21115, 5.47113, -9.36656, 9.36656, 3.89543, -3.89543, 3.9968e-15}, {4.44089e-16, -3.15147, 0, 3.15147, 0, 0, 4.08784, -4.08784, -5.36656, -1.78885, 1.78885, -1.78885, -3.89543, 3.89543, 0, -14.817, -1.68428, -2.21115, 1.68428, 14.817, -2.21115, 2.21115, 1.68428, 2.21115, -1.68428, -2.21115, 2.21115, 11.0508, -11.0508, 7.15542}, {2.22045e-16, -3.15147, 0, 3.15147, -2.79907e-15, 2.79907e-15, -1.36261, 1.36261, 1.78885, 5.36656, -5.36656, 5.36656, -3.89543, 3.89543, -3.55271e-15, -2.21115, -1.68428, -2.21115, 1.68428, 2.21115, -2.21115, 2.21115, 14.2902, 2.21115, -14.2902, -2.21115, 2.21115, 9.34589, -9.34589, -7.15542}, {4.32877, -2.26802, -4.36683, -0.571101, 0.113693, -1.4431, 0, -1.33263, 0, 2.01402, 0.462931, -0.0125109, 4.77387, -1.52978, 5.75693, 0.70592, 1.50669, 1.78377, 1.78355, 6.04326, -1.79923, -8.76202, -3.35841, -1.73373, -1.78355, -0.712746, 1.79923, -2.48947, 1.07501, 0.0154644}, {-1.44292, 0.756005, 1.45561, 1.7133, -0.34108, 4.3293, 0, -1.33263, 0, 2.01402, 0.462931, -0.0125109, 8.26116, -4.09903, -5.83791, 0.70592, 6.8372, 1.78377, 1.78355, 0.712746, -1.79923, -0.70592, -1.50669, -1.78377, -9.83965, -2.56447, 1.84928, -2.48947, 1.07501, 0.0154644}, {-1.44292, 0.756005, 1.45561, -0.571101, 0.113693, -1.4431, 0, 3.99789, 0, 2.01402, 0.462931, -0.0125109, 2.48947, -1.07501, -0.0154644, 2.99032, 1.05191, 7.55617, 7.55524, -2.31127, -7.62167, -0.70592, -1.50669, -1.78377, -1.78355, -0.712746, 1.79923, -10.5456, -0.776716, 0.0655081}, {-1.44292, 0.756005, 1.45561, -0.571101, 0.113693, -1.4431, 0, -1.33263, 0, -6.04207, -1.38879, 0.0375328, 2.48947, -1.07501, -0.0154644, 0.70592, 1.50669, 1.78377, 1.78355, 0.712746, -1.79923, 5.06577, -4.53071, -7.60621, 0.500853, -1.16752, 7.57163, -2.48947, 6.40552, 0.0154644}, {-4.70136, -6.21725e-15, -3.21271e-15, 0.134389, 1.44665, -1.44665, -0.426776, 0.569981, 1.4404, -1.27473, -2.01663, 0.00624416, -2.64074, -7.57474, 7.57474, 0.36141, -2.49269, 0.00771821, 0.297559, -2.98446, -7.54205, 4.73753, 10.5592, -0.0326948, 1.40954, 0.704535, 1.78044, 2.10318, 1.78815, -1.78815}, {1.56712, -4.44089e-16, 4.96131e-16, -0.403167, -4.33994, 4.33994, -0.426776, 0.569981, 1.4404, -1.27473, -2.01663, 0.00624416, -8.37167, -1.78815, 1.78815, 2.06851, -4.77261, -5.75389, -1.40954, -0.704535, -1.78044, -0.36141, 2.49269, -0.00771821, 6.50848, 8.77105, 1.75546, 2.10318, 1.78815, -1.78815}, {1.56712, -2.22045e-15, -7.71952e-17, 0.134389, 1.44665, -1.44665, 1.28033, -1.70994, -4.32121, -1.27473, -2.01663, 0.00624416, -2.10318, -1.78815, 1.78815, -0.176146, -8.27928, 5.79431, -7.67803, -0.704535, -1.78044, -0.36141, 2.49269, -0.00771821, 1.40954, 0.704535, 1.78044, 7.20212, 9.85467, -1.81313}, {1.56712, 1.33227e-15, 1.89085e-16, 0.134389, 1.44665, -1.44665, -0.426776, 0.569981, 1.4404, 3.8242, 6.04988, -0.0187325, -2.10318, -1.78815, 1.78815, 0.36141, -2.49269, 0.00771821, -1.40954, -0.704535, -1.78044, -6.6299, 2.49269, -0.00771821, 0.871989, -5.08205, 7.56702, 3.81029, -0.491769, -7.54977}, {-3.47256, 2.13004, 3.47613, -1.55533, -0.53343, -0.78864, -0.511744, 1.83496, 0.513241, 0.909554, -0.591516, 1.43411, 6.71303, 3.6707, 5.56162, 2.55504, -1.60878, 0.340411, 1.24875, -8.73034, -1.25512, -6.19326, 3.97484, -6.07685, 0.798222, 1.39051, -0.797844, -0.49172, -1.53698, -2.40706}, {1.15752, -0.710012, -1.15871, 4.66599, 1.60029, 2.36592, -0.511744, 1.83496, 0.513241, 0.909554, -0.591516, 1.43411, -4.13836, 4.37703, 7.0419, 4.60202, -8.94861, -1.71255, -0.798222, -1.39051, 0.797844, -2.55504, 1.60878, -0.340411, -2.83999, 3.75657, -6.53428, -0.49172, -1.53698, -2.40706}, {1.15752, -0.710012, -1.15871, -1.55533, -0.53343, -0.78864, 1.53523, -5.50487, -1.53972, 0.909554, -0.591516, 1.43411, 0.49172, 1.53698, 2.40706, 8.77636, 0.524942, 3.49497, -5.4283, 1.44954, 5.43269, -2.55504, 1.60878, -0.340411, 0.798222, 1.39051, -0.797844, -4.12993, 0.829086, -8.14349}, {1.15752, -0.710012, -1.15871, -1.55533, -0.53343, -0.78864, -0.511744, 1.83496, 0.513241, -2.72866, 1.77455, -4.30233, 0.49172, 1.53698, 2.40706, 2.55504, -1.60878, 0.340411, -0.798222, -1.39051, 0.797844, -7.18512, 4.44882, 4.29443, 7.01954, 3.52423, 2.35672, 1.55526, -8.87681, -4.46002}, {-0.0259854, 4.18315, -1.68926, -1.44604, -0.0976914, -0.778579, 1.44538, 0.20404, -0.351453, -0.00800116, 1.28804, 0.566947, 7.56086, 2.23507, 3.38068, 0.000816584, -0.131455, 1.3968, -7.57881, 0.655184, 1.14422, 0.031188, -5.02069, -3.66458, 1.79729, -1.47135, 0.261592, -1.7767, -1.84431, -0.266365}, {0.00866179, -1.39438, 0.563086, 4.33812, 0.293074, 2.33574, 1.44538, 0.20404, -0.351453, -0.00800116, 1.28804, 0.566947, 1.74205, 7.42184, -1.98598, -5.7807, -0.947617, 2.80261, -1.79729, 1.47135, -0.261592, -0.000816584, 0.131455, -1.3968, 1.8293, -6.62349, -2.0062, -1.7767, -1.84431, -0.266365}, {0.00866179, -1.39438, 0.563086, -1.44604, -0.0976914, -0.778579, -4.33614, -0.612121, 1.05436, -0.00800116, 1.28804, 0.566947, 1.7767, 1.84431, 0.266365, 5.78498, 0.259311, 4.51111, -1.83194, 7.04888, -2.51393, -0.000816584, 0.131455, -1.3968, 1.79729, -1.47135, 0.261592, -1.74469, -6.99645, -2.53415}, {0.00866179, -1.39438, 0.563086, -1.44604, -0.0976914, -0.778579, 1.44538, 0.20404, -0.351453, 0.0240035, -3.86411, -1.70084, 1.7767, 1.84431, 0.266365, 0.000816584, -0.131455, 1.3968, -1.79729, 1.47135, -0.261592, -0.0354637, 5.70899, -3.64914, 7.58145, -1.08058, 3.37591, -7.55822, -2.66047, 1.13945}, {5.36656, -5.36656, -5.36656, 3.15147, 2.46559e-15, 0, -1.36261, 1.36261, -1.78885, 0, -3.15147, 0, -14.2902, -2.21115, -2.21115, -2.21115, -1.68428, 2.21115, 9.34589, -9.34589, 7.15542, 2.21115, 14.2902, -2.21115, -3.89543, 3.89543, 0, 1.68428, 2.21115, 2.21115}, {-1.78885, 1.78885, 1.78885, -9.45441, -1.0595e-14, 4.1986e-15, -1.36261, 1.36261, -1.78885, 0, -3.15147, 0, 5.47113, -9.36656, -9.36656, 3.23931, -7.13474, 9.36656, 3.89543, -3.89543, -3.06219e-15, 2.21115, 1.68428, -2.21115, -3.89543, 16.5013, 1.72992e-15, 1.68428, 2.21115, 2.21115}, {-1.78885, 1.78885, 1.78885, 3.15147, 0, 0, 4.08784, -4.08784, 5.36656, 0, -3.15147, 0, -1.68428, -2.21115, -2.21115, -14.817, -1.68428, 2.21115, 11.0508, -11.0508, -7.15542, 2.21115, 1.68428, -2.21115, -3.89543, 3.89543, 0, 1.68428, 14.817, 2.21115}, {-1.78885, 1.78885, 1.78885, 3.15147, 2.46559e-15, 0, -1.36261, 1.36261, -1.78885, 0, 9.45441, 0, -1.68428, -2.21115, -2.21115, -2.21115, -1.68428, 2.21115, 3.89543, -3.89543, -1.33227e-15, 9.36656, -5.47113, -9.36656, -16.5013, 3.89543, 0, 7.13474, -3.23931, 9.36656}, {2.81269, -2.81269, -1.11325, -0.456393, -1.88673, -0.746758, 0.886018, 1.45711, 2.59594, 0.507938, -0.507938, -2.22026, 3.5486, 8.72017, 3.45139, -0.531046, 0.531046, -2.28571, -3.48036, -8.78841, -14.0512, -1.50071, 1.50071, 11.1668, -0.0637129, 2.95998, 3.66744, -1.72302, -1.17324, -0.464361}, {-0.937563, 0.937563, 0.371082, 1.36918, 5.6602, 2.24027, 0.886018, 1.45711, 2.59594, 0.507938, -0.507938, -2.22026, 5.47328, -2.57701, -1.01997, -4.07512, -5.29738, -12.6695, 0.0637129, -2.95998, -3.66744, 0.531046, -0.531046, 2.28571, -2.09546, 4.99173, 12.5485, -1.72302, -1.17324, -0.464361}, {-0.937563, 0.937563, 0.371082, -0.456393, -1.88673, -0.746758, -2.65805, -4.37132, -7.78781, 0.507938, -0.507938, -2.22026, 1.72302, 1.17324, 0.464361, 1.29453, 8.07798, 0.701322, 3.81396, -6.71023, -5.15177, 0.531046, -0.531046, 2.28571, -0.0637129, 2.95998, 3.66744, -3.75477, 0.858512, 8.41668}, {-0.937563, 0.937563, 0.371082, -0.456393, -1.88673, -0.746758, 0.886018, 1.45711, 2.59594, -1.52381, 1.52381, 6.66078, 1.72302, 1.17324, 0.464361, -0.531046, 0.531046, -2.28571, 0.0637129, -2.95998, -3.66744, 4.2813, -4.2813, 0.801382, 1.76186, 10.5069, 6.65447, -5.2671, -7.00167, -10.8481}, {-4.44089e-16, 4.08096, 0.0852192, -1.48733e-16, 0.921902, -1.18196, 1.31177, 0.0265815, 1.34059, -1.31177, 0.411835, -0.130224, 6.66134e-16, -3.1457, 6.22395, -1.62143, -1.17239, -0.196078, -6.86849, 1.54226, -6.98432, 6.86849, -0.474951, 0.716974, 1.62143, -1.64859, 1.62195, 0, -0.541913, -1.4961}, {-1.11022e-15, -1.36032, -0.0284064, 0, -2.76571, 3.54589, 1.31177, 0.0265815, 1.34059, -1.31177, 0.411835, -0.130224, 5.32907e-15, 5.98319, 1.60972, -6.86849, -1.27872, -5.55845, -1.62143, 1.64859, -1.62195, 1.62143, 1.17239, 0.196078, 6.86849, -3.29593, 2.14285, -1.33227e-15, -0.541913, -1.4961}, {-6.66134e-16, -1.36032, -0.0284064, 0, 0.921902, -1.18196, -3.9353, -0.0797444, -4.02178, -1.31177, 0.411835, -0.130224, 8.88178e-16, 0.541913, 1.4961, -1.62143, -4.86, 4.53177, -1.62143, 7.08987, -1.50833, 1.62143, 1.17239, 0.196078, 1.62143, -1.64859, 1.62195, 5.24706, -2.18925, -0.975202}, {-1.55431e-15, -1.36032, -0.0284064, 1.18986e-15, 0.921902, -1.18196, 1.31177, 0.0265815, 1.34059, 3.9353, -1.23551, 0.390672, 4.44089e-16, 0.541913, 1.4961, -1.62143, -1.17239, -0.196078, -1.62143, 1.64859, -1.62195, 1.62143, 6.61367, 0.309704, 1.62143, -5.3362, 6.3498, -5.24706, -0.648239, -6.85847}, {1.39697, -4.32433, -4.36732, 1.89829, 1.89972e-15, 6.00246e-18, 0.0801166, 0.574147, -1.4494, -1.51275, -2.01559, -0.00636856, -9.364, -1.78172, -1.79943, -2.44545, -0.709685, 1.79156, 0.156089, -4.78799, 5.78974, 8.49644, 8.77205, -1.76609, -0.476556, 2.49141, 0.00787198, 1.77083, 1.78172, 1.79943}, {-0.465658, 1.44144, 1.45577, -5.69487, -3.6613e-15, 2.04012e-15, 0.0801166, 0.574147, -1.4494, -1.51275, -2.01559, -0.00636856, 0.0918014, -7.54749, -7.62252, -2.76591, -3.00627, 7.58918, 0.476556, -2.49141, -0.00787198, 2.44545, 0.709685, -1.79156, 5.57444, 10.5538, 0.0333462, 1.77083, 1.78172, 1.79943}, {-0.465658, 1.44144, 1.45577, 1.89829, 0, 0, -0.24035, -1.72244, 4.34821, -1.51275, -2.01559, -0.00636856, -1.77083, -1.78172, -1.79943, -10.0386, -0.709685, 1.79156, 2.33919, -8.25718, -5.83096, 2.44545, 0.709685, -1.79156, -0.476556, 2.49141, 0.00787198, 7.82183, 9.84408, 1.82491}, {-0.465658, 1.44144, 1.45577, 1.89829, 1.89972e-15, 6.00246e-18, 0.0801166, 0.574147, -1.4494, 4.53825, 6.04677, 0.0191057, -1.77083, -1.78172, -1.79943, -2.44545, -0.709685, 1.79156, 0.476556, -2.49141, -0.00787198, 4.30808, -5.05609, -7.61465, -8.06972, 2.49141, 0.00787198, 1.45037, -0.514866, 7.59705}, {4.31352, -3.43679, 1.70622, 1.43784, 0.720211, -1.45048, 0, -1.33263, 0, -1.50657e-12, -0.53318, 2.01922, -5.75136, -5.18711, 8.29783, -1.77727, 0.75699, 1.7929, 1.77727, 5.5617, 0.702999, 1.77727, 1.37573, -9.86978, -1.77727, -0.231184, -0.702999, 1.86222e-12, 2.30627, -2.4959}, {-1.43784, 1.1456, -0.568738, -4.31352, -2.16063, 4.35145, 0, -1.33263, 0, -1.50873e-12, -0.53318, 2.01922, 5.75136, -6.88865, 4.77085, -1.77727, 6.08751, 1.7929, 1.77727, 0.231184, 0.702999, 1.77727, -0.75699, -1.7929, -1.77727, 1.90153, -8.77989, 1.86489e-12, 2.30627, -2.4959}, {-1.43784, 1.1456, -0.568738, 1.43784, 0.720211, -1.45048, 0, 3.99789, 0, -1.50801e-12, -0.53318, 2.01922, -1.86293e-12, -2.30627, 2.4959, -7.52863, -2.12386, 7.59483, 7.52863, -4.3512, 2.97795, 1.77727, -0.75699, -1.7929, -1.77727, -0.231184, -0.702999, 7.89603e-12, 4.43898, -10.5728}, {-1.43784, 1.1456, -0.568738, 1.43784, 0.720211, -1.45048, 0, -1.33263, 0, 4.52565e-12, 1.59954, -6.05767, -1.8636e-12, -2.30627, 2.4959, -1.77727, 0.75699, 1.7929, 1.77727, 0.231184, 0.702999, 7.52863, -5.33938, 0.482057, -7.52863, -3.11203, 5.09894, 1.86467e-12, 7.63678, -2.4959}, {-4.90958, -4.91099, -14.364, 1.57551, -1.57551, -1.57596, -1.57551, 1.57551, -1.57551, -1.63653, -1.637, -1.63653, -10.2723, 6.22604, 2.33354, -1.70974e-14, 1.70974e-14, 3.89543, 6.22661, -10.2729, 2.33118, 6.54611, 6.54798, 2.65068, 0.0754226, 3.97087, 3.97085, 3.9703, 0.076001, 3.9703}, {1.63653, 1.637, 4.788, -4.72653, 4.72653, 4.72788, -1.57551, 1.57551, -1.57551, -1.63653, -1.637, -1.63653, -10.5164, -6.62398, -23.1223, 6.30204, -6.30204, 10.1975, -0.0754226, -3.97087, -3.97085, 1.277e-14, -1.58741e-14, -3.89543, 6.62153, 10.5189, 10.517, 3.9703, 0.076001, 3.9703}, {1.63653, 1.637, 4.788, 1.57551, -1.57551, -1.57596, 4.72653, -4.72653, 4.72653, -1.63653, -1.637, -1.63653, -3.9703, -0.076001, -3.9703, -6.30204, 6.30204, 10.1993, -6.62153, -10.5189, -23.1228, 1.56566e-14, -1.80946e-14, -3.89543, 0.0754226, 3.97087, 3.97085, 10.5164, 6.62398, 10.5164}, {1.63653, 1.637, 4.788, 1.57551, -1.57551, -1.57596, -1.57551, 1.57551, -1.57551, 4.90958, 4.91099, 4.90958, -3.9703, -0.076001, -3.9703, -1.68754e-14, 1.68754e-14, 3.89543, -0.0754226, -3.97087, -3.97085, -6.54611, -6.54798, -23.0474, -6.22661, 10.2729, 10.2747, 10.2723, -6.22604, 10.2723}, {1.1292, -10.9335, -1.11964, 5.63596e-16, 7.40172e-16, 1.60567, 1.79029, -1.78764, -1.78873, -1.41389, -1.85687, -0.190152, 0.465254, -4.50486, -8.8687, -2.21292, 2.20964, 0.226277, -8.90884, 4.85533, 8.90459, 7.8685, 5.21784, 0.53433, 1.74767, 2.29522, -1.74967, -0.465254, 4.50486, 2.44603}, {-0.376399, 3.64451, 0.373213, -3.83169e-15, -8.27924e-17, -4.817, 1.79029, -1.78764, -1.78873, -1.41389, -1.85687, -0.190152, 1.97085, -19.0829, -3.93889, -9.37409, 9.36019, 7.3812, -1.74767, -2.29522, 1.74967, 2.21292, -2.20964, -0.226277, 7.40324, 9.72271, -0.989068, -0.465254, 4.50486, 2.44603}, {-0.376399, 3.64451, 0.373213, 0, 0, 1.60567, -5.37088, 5.36291, 5.36619, -1.41389, -1.85687, -0.190152, 0.465254, -4.50486, -2.44603, -2.21292, 2.20964, -6.1964, -0.242074, -16.8733, 0.256821, 2.21292, -2.20964, -0.226277, 1.74767, 2.29522, -1.74967, 5.19032, 11.9323, 3.20664}, {-0.376399, 3.64451, 0.373213, 5.63596e-16, 7.40172e-16, 1.60567, 1.79029, -1.78764, -1.78873, 4.24168, 5.57061, 0.570455, 0.465254, -4.50486, -2.44603, -2.21292, 2.20964, 0.226277, -1.74767, -2.29522, 1.74967, 3.71852, -16.7877, -1.71913, 1.74767, 2.29522, -8.17235, -7.62642, 11.6554, 9.60095}, {3.55271e-15, -8.88178e-16, -7.02938, 1.78885, 2.33948, -2.34059, -1.78885, 6.92556e-12, -0.00253498, 0, -2.33948, 0, -9.36656, -12.2497, 9.35923, -1.77636e-15, -2.89175, 2.89626, 9.36656, -3.6263e-11, -2.88299, 1.77636e-15, 12.2497, -2.89626, -2.21115, 8.56071e-12, 2.89313, 2.21115, 2.89175, 0.00313341}, {2.22045e-15, 4.44089e-15, 2.34313, -5.36656, -7.01844, 7.02177, -1.78885, 6.92607e-12, -0.00253498, 0, -2.33948, 0, -2.21115, -2.89175, -9.37564, 7.15542, -2.89175, 2.9064, 2.21115, -8.56648e-12, -2.89313, -2.66454e-15, 2.89175, -2.89626, -2.21115, 9.35791, 2.89313, 2.21115, 2.89175, 0.00313341}, {1.9984e-15, 3.9968e-15, 2.34313, 1.78885, 2.33948, -2.34059, 5.36656, -2.0786e-11, 0.00760494, 0, -2.33948, 0, -2.21115, -2.89175, -0.00313341, -7.15542, -12.2497, 12.2586, 2.21115, -8.58513e-12, -12.2656, -2.22045e-15, 2.89175, -2.89626, -2.21115, 8.56959e-12, 2.89313, 2.21115, 12.2497, 0.00313341}, {0, -2.66454e-15, 2.34313, 1.78885, 2.33948, -2.34059, -1.78885, 6.92919e-12, -0.00253498, 0, 7.01844, 0, -2.21115, -2.89175, -0.00313341, 0, -2.89175, 2.89626, 2.21115, -8.56115e-12, -2.89313, 0, 2.89175, -12.2688, -9.36656, -9.35791, 12.2555, 9.36656, 2.89175, 0.0132733}, {5.21741, 5.22554, 3.98943, -2.33948, 0, 0, 1.54072, 1.54312, -0.61076, 2.53789, 0.198723, 1.94057, 14.3994, 2.15304, 1.64373, 0.987318, -1.90741, 0.754941, -5.91764, -5.92686, 4.84171, -11.1389, 1.11252, -8.51722, -0.245252, -0.245635, -2.39867, -5.04144, -2.15304, -1.64373}, {-1.73914, -1.74185, -1.32981, 7.01844, 0, 0, 1.54072, 1.54312, -0.61076, 2.53789, 0.198723, 1.94057, 11.998, 9.12042, 6.96297, -5.17557, -8.0799, 3.19798, 0.245252, 0.245635, 2.39867, -0.987318, 1.90741, -0.754941, -10.3968, -1.04052, -10.1609, -5.04144, -2.15304, -1.64373}, {-1.73914, -1.74185, -1.32981, -2.33948, 0, 0, -4.62217, -4.62937, 1.83228, 2.53789, 0.198723, 1.94057, 5.04144, 2.15304, 1.64373, 10.3452, -1.90741, 0.754941, 7.20179, 7.21302, 7.71791, -0.987318, 1.90741, -0.754941, -0.245252, -0.245635, -2.39867, -15.193, -2.94793, -9.40601}, {-1.73914, -1.74185, -1.32981, -2.33948, 0, 0, 1.54072, 1.54312, -0.61076, -7.61368, -0.596168, -5.82171, 5.04144, 2.15304, 1.64373, 0.987318, -1.90741, 0.754941, 0.245252, 0.245635, 2.39867, 5.96922, 8.87479, 4.5643, 9.11266, -0.245635, -2.39867, -11.2043, -8.32553, 0.799305}, {10.9417, 1.1195, -1.12048, -7.40292e-16, 5.63738e-16, 1.60567, 1.79007, 1.78742, -1.78898, 1.85717, -1.41425, -0.190182, 4.50824, 0.46126, -8.86905, -2.21265, -2.20937, 0.226585, -4.86469, -8.89778, 8.90555, -5.21604, 7.86637, 0.534145, -2.29559, 1.74811, -1.74964, -4.50824, -0.46126, 2.44638}, {-3.64724, -0.373167, 0.373493, 8.02431e-17, -3.82867e-15, -4.817, 1.79007, 1.78742, -1.78898, 1.85717, -1.41425, -0.190182, 19.0972, 1.95393, -3.94035, -9.37293, -9.35904, 7.3825, 2.29559, -1.74811, 1.74964, 2.21265, 2.20937, -0.226585, -9.72428, 7.40511, -0.988907, -4.50824, -0.46126, 2.44638}, {-3.64724, -0.373167, 0.373493, 0, 0, 1.60567, -5.37021, -5.36225, 5.36694, 1.85717, -1.41425, -0.190182, 4.50824, 0.46126, -2.44638, -2.21265, -2.20937, -6.19609, 16.8846, -0.25544, 0.255663, 2.21265, 2.20937, -0.226585, -2.29559, 1.74811, -1.74964, -11.9369, 5.19574, 3.20711}, {-3.64724, -0.373167, 0.373493, -7.40292e-16, 5.63738e-16, 1.60567, 1.79007, 1.78742, -1.78898, -5.57152, 4.24275, 0.570547, 4.50824, 0.46126, -2.44638, -2.21265, -2.20937, 0.226585, 2.29559, -1.74811, 1.74964, 16.8016, 3.70204, -1.72056, -2.29559, 1.74811, -8.17231, -11.6685, -7.61093, 9.60229}, {1.83228, 4.62937, -4.62937, 0, 0, -1.60567, 1.94057, -0.198723, 0.198723, -1.32981, 1.74185, -0.136178, 0.754941, 1.90741, 6.49998, -2.39867, 0.245635, 1.73908, -9.40601, 2.94793, -2.94793, 7.71791, -7.21302, -1.19437, 1.64373, -2.15304, 2.15304, -0.754941, -1.90741, -0.0773091}, {-0.61076, -1.54312, 1.54312, 0, 0, 4.817, 1.94057, -0.198723, 0.198723, -1.32981, 1.74185, -0.136178, 3.19798, 8.0799, -6.09519, -10.1609, 1.04052, 0.94419, -1.64373, 2.15304, -2.15304, 2.39867, -0.245635, -1.73908, 6.96297, -9.12042, 2.69775, -0.754941, -1.90741, -0.0773091}, {-0.61076, -1.54312, 1.54312, 0, 0, -1.60567, -5.82171, 0.596168, -0.596168, -1.32981, 1.74185, -0.136178, 0.754941, 1.90741, 0.0773091, -2.39867, 0.245635, 8.16175, 0.799305, 8.32553, -8.32553, 2.39867, -0.245635, -1.73908, 1.64373, -2.15304, 2.15304, 4.5643, -8.87479, 0.467403}, {-0.61076, -1.54312, 1.54312, 0, 0, -1.60567, 1.94057, -0.198723, 0.198723, 3.98943, -5.22554, 0.408534, 0.754941, 1.90741, 0.0773091, -2.39867, 0.245635, 1.73908, -1.64373, 2.15304, -2.15304, 4.84171, 5.92686, -7.91157, 1.64373, -2.15304, 8.57571, -8.51722, -1.11252, -0.872199}, {-1.12374, 4.33994, -1.71772, 0.422512, 1.58958e-12, -2.01922, 0.258935, 1.44665, 1.44665, -1.05603, 0, 0, -2.6753, 1.78815, 9.86504, -0.842315, -1.78815, 0.707741, -1.81881, -5.78659, -8.28248, 5.06642, 1.78815, -0.707741, 0.783066, -1.96483e-12, 2.4959, 0.985258, -1.78815, -1.78815}, {0.374579, -1.44665, 0.572575, -1.26754, -4.76548e-12, 6.05767, 0.258935, 1.44665, 1.44665, -1.05603, 0, 0, -2.48357, 7.57474, -0.502145, -1.87805, -7.57474, -5.07885, -0.783066, 1.96456e-12, -2.4959, 0.842315, 1.78815, -0.707741, 5.00717, -1.96348e-12, 2.4959, 0.985258, -1.78815, -1.78815}, {0.374579, -1.44665, 0.572575, 0.422512, 1.58668e-12, -2.01922, -0.776805, -4.33994, -4.33994, -1.05603, 0, 0, -0.985258, 1.78815, 1.78815, -2.53236, -1.78815, 8.78463, -2.28138, 5.78659, -4.7862, 0.842315, 1.78815, -0.707741, 0.783066, -1.96124e-12, 2.4959, 5.20936, -1.78815, -1.78815}, {0.374579, -1.44665, 0.572575, 0.422512, 1.58958e-12, -2.01922, 0.258935, 1.44665, 1.44665, 3.16808, 0, 0, -0.985258, 1.78815, 1.78815, -0.842315, -1.78815, 0.707741, -0.783066, 1.96591e-12, -2.4959, -0.656, 7.57474, -2.99804, -0.906981, -8.32315e-12, 10.5728, -0.0504823, -7.57474, -7.57474}, {-4.08784, 4.08784, -5.36656, -3.53165e-15, 3.15147, -1.39953e-15, -3.15147, 0, 0, 1.78885, -1.78885, -1.78885, -1.68428, -14.817, -2.21115, 3.89543, -3.89543, 1.72992e-15, 14.817, 1.68428, -2.21115, -11.0508, 11.0508, 7.15542, -2.21115, -1.68428, 2.21115, 1.68428, 2.21115, 2.21115}, {1.36261, -1.36261, 1.78885, 1.15954e-14, -9.45441, -4.1986e-15, -3.15147, 0, 0, 1.78885, -1.78885, -1.78885, -7.13474, 3.23931, -9.36656, 16.5013, -3.89543, -1.72992e-15, 2.21115, 1.68428, -2.21115, -3.89543, 3.89543, 3.9765e-16, -9.36656, 5.47113, 9.36656, 1.68428, 2.21115, 2.21115}, {1.36261, -1.36261, 1.78885, 0, 3.15147, 0, 9.45441, 0, 0, 1.78885, -1.78885, -1.78885, -1.68428, -2.21115, -2.21115, 3.89543, -16.5013, 0, -3.23931, 7.13474, -9.36656, -3.89543, 3.89543, -1.33227e-15, -2.21115, -1.68428, 2.21115, -5.47113, 9.36656, 9.36656}, {1.36261, -1.36261, 1.78885, 1.39953e-15, 3.15147, -1.39953e-15, -3.15147, 0, 0, -5.36656, 5.36656, 5.36656, -1.68428, -2.21115, -2.21115, 3.89543, -3.89543, 1.72992e-15, 2.21115, 1.68428, -2.21115, -9.34589, 9.34589, -7.15542, -2.21115, -14.2902, 2.21115, 14.2902, 2.21115, 2.21115}, {1.11747, -3.79023, -1.1121, -0.361676, -1.4194, 0.363688, 1.52298, 0.102889, 0.820003, -0.788811, 0.0531033, -1.55439, 2.35418, 5.87043, -2.3625, -1.43545, 1.6273, -1.46312, -7.51399, -2.1004, -4.7518, 4.59069, -1.83971, 7.68068, 1.42208, 1.68884, 1.47179, -0.907478, -0.192817, 0.907751}, {-0.372489, 1.26341, 0.370699, 1.08503, 4.25821, -1.09106, 1.52298, 0.102889, 0.820003, -0.788811, 0.0531033, -1.55439, 2.39743, -4.86083, -2.39055, -7.52735, 1.21575, -4.74314, -1.42208, -1.68884, -1.47179, 1.43545, -1.6273, 1.46312, 4.57732, 1.47643, 7.68935, -0.907478, -0.192817, 0.907751}, {-0.372489, 1.26341, 0.370699, -0.361676, -1.4194, 0.363688, -4.56893, -0.308667, -2.46001, -0.788811, 0.0531033, -1.55439, 0.907478, 0.192817, -0.907751, 0.0112586, 7.30492, -2.91787, 0.0678761, -6.74249, -2.95458, 1.43545, -1.6273, 1.46312, 1.42208, 1.68884, 1.47179, 2.24777, -0.40523, 7.12531}, {-0.372489, 1.26341, 0.370699, -0.361676, -1.4194, 0.363688, 1.52298, 0.102889, 0.820003, 2.36643, -0.15931, 4.66317, 0.907478, 0.192817, -0.907751, -1.43545, 1.6273, -1.46312, -1.42208, -1.68884, -1.47179, 2.9254, -6.68095, -0.0196727, 2.86879, 7.36645, 0.0170383, -6.99938, -0.604373, -2.37226}, {0, -4.05009, 3.55271e-15, -0.572575, -0.625677, 1.44665, 2.01922, -0.706554, 1.38572e-12, -1.44665, -0.0177991, -1.44665, 2.99804, 1.60736, -7.57474, -1.78815, 1.64673, -1.78815, -10.5728, 2.03083, -7.25442e-12, 7.57474, -1.57553, 7.57474, 2.4959, 0.79538, 1.71152e-12, -0.707741, 0.895349, 1.78815}, {0, 1.35003, 2.22045e-16, 1.71772, 1.87703, -4.33994, 2.01922, -0.706554, 1.3879e-12, -1.44665, -0.0177991, -1.44665, 0.707741, -6.29547, -1.78815, -9.86504, 4.47294, -1.78815, -2.4959, -0.79538, -1.71618e-12, 1.78815, -1.64673, 1.78815, 8.28248, 0.866577, 5.78659, -0.707741, 0.895349, 1.78815}, {1.9984e-15, 1.35003, -2.22045e-16, -0.572575, -0.625677, 1.44665, -6.05767, 2.11966, -4.15715e-12, -1.44665, -0.0177991, -1.44665, 0.707741, -0.895349, -1.78815, 0.502145, 4.14944, -7.57474, -2.4959, -6.1955, -1.71241e-12, 1.78815, -1.64673, 1.78815, 2.4959, 0.79538, 1.71285e-12, 5.07885, 0.966546, 7.57474}, {-6.66134e-16, 1.35003, -4.44089e-16, -0.572575, -0.625677, 1.44665, 2.01922, -0.706554, 1.38517e-12, 4.33994, 0.0533972, 4.33994, 0.707741, -0.895349, -1.78815, -1.78815, 1.64673, -1.78815, -2.4959, -0.79538, -1.71152e-12, 1.78815, -7.04685, 1.78815, 4.7862, 3.29809, -5.78659, -8.78463, 3.72156, 1.78815}, {1.70622, 4.31352, 1.19704, -8.51907e-16, -7.76069e-16, 1.08709, -1.45048, 1.43784, -0.312525, 2.01922, -1.66018e-12, -0.375548, 0.702999, 1.77727, -5.19885, 1.7929, -1.77727, -0.95741, 8.29783, -5.75136, 2.12961, -9.86978, 1.77727, 2.4596, -2.4959, 2.05306e-12, -0.879509, -0.702999, -1.77727, 0.850505}, {-0.568738, -1.43784, -0.399013, 3.73006e-15, 1.1641e-15, -3.26126, -1.45048, 1.43784, -0.312525, 2.01922, -1.65851e-12, -0.375548, 2.97795, 7.52863, 0.745546, 7.59483, -7.52863, 0.292691, 2.4959, -2.04944e-12, 0.879509, -1.7929, 1.77727, 0.95741, -10.5728, 8.68457e-12, 0.622683, -0.702999, -1.77727, 0.850505}, {-0.568738, -1.43784, -0.399013, 0, 0, 1.08709, 4.35145, -4.31352, 0.937576, 2.01922, -1.65685e-12, -0.375548, 0.702999, 1.77727, -0.850505, 1.7929, -1.77727, -5.30575, 4.77085, 5.75136, 2.47556, -1.7929, 1.77727, 0.95741, -2.4959, 2.04797e-12, -0.879509, -8.77989, -1.77727, 2.3527}, {-0.568738, -1.43784, -0.399013, 0, 0, 1.08709, -1.45048, 1.43784, -0.312525, -6.05767, 4.97324e-12, 1.12664, 0.702999, 1.77727, -0.850505, 1.7929, -1.77727, -0.95741, 2.4959, -2.04802e-12, 0.879509, 0.482057, 7.52863, 2.55346, -2.4959, 2.04909e-12, -5.22785, 5.09894, -7.52863, 2.10061}, {-2.41029, -2.40672, -2.40819, -0.80343, -0.802238, 0.80294, 1.63555, -1.63555, 0.0313083, -1.63555, 1.63555, -1.63698, 3.21372, 3.20895, -5.19647, -1.02855, 3.01327, -1.03119, -9.55693, 7.57221, -1.15616, 7.57074, -9.55546, 7.57909, 3.01474, -1.03003, 1.03093, 7.99361e-15, 6.21725e-15, 1.98471}, {0.80343, 0.802238, 0.802728, 2.41029, 2.40672, -2.40882, 1.63555, -1.63555, 0.0313083, -1.63555, 1.63555, -1.63698, -3.21372, -3.20895, -5.19563, -7.57074, 9.55546, -1.15642, -3.01474, 1.03003, -1.03093, 1.02855, -3.01327, 1.03119, 9.55693, -7.57221, 7.57883, 7.10543e-15, 7.54952e-15, 1.98471}, {0.80343, 0.802238, 0.802728, -0.80343, -0.802238, 0.80294, -4.90664, 4.90664, -0.0939249, -1.63555, 1.63555, -1.63698, -6.21725e-15, -7.99361e-15, -1.98471, 2.18516, 6.22222, -4.24295, -6.22846, -2.17893, -4.24184, 1.02855, -3.01327, 1.03119, 3.01474, -1.03003, 1.03093, 6.54219, -6.54219, 8.53262}, {0.80343, 0.802238, 0.802728, -0.80343, -0.802238, 0.80294, 1.63555, -1.63555, 0.0313083, 4.90664, -4.90664, 4.91093, -7.10543e-15, -6.66134e-15, -1.98471, -1.02855, 3.01327, -1.03119, -3.01474, 1.03003, -1.03093, -2.18516, -6.22222, -2.17973, 6.22846, 2.17893, -2.18083, -6.54219, 6.54219, 1.85948}, {-5.4813e-11, 5.36656, 0.00342441, 0, 0, -2.34462, 2.34313, 0, 0, -2.34313, 1.78885, 2.34576, -2.25842e-11, 2.21115, 12.278, -2.89626, 0, 2.89811, -12.2688, 2.21115, 0.00141093, 12.2688, -7.15542, -12.2812, 2.89626, -2.21115, -0.00141093, 2.25842e-11, -2.21115, -2.89952}, {1.21108e-11, -1.78885, -0.00114147, 0, 0, 7.03386, 2.34313, 1.04056e-15, 1.3645e-15, -2.34313, 1.78885, 2.34576, -6.34124e-11, 9.36656, 2.90409, -12.2688, -5.44843e-15, 2.89811, -2.89626, 2.21115, 0.00141093, 2.89626, 2.61847e-15, -2.89811, 12.2688, -9.36656, -9.38446, 1.49698e-11, -2.21115, -2.89952}, {1.21108e-11, -1.78885, -0.00114147, 0, 0, -2.34462, -7.02938, 0, 0, -2.34313, 1.78885, 2.34576, -1.49689e-11, 2.21115, 2.89952, -2.89626, 0, 12.2766, -2.89626, 9.36656, 0.00597681, 2.89626, 1.33227e-15, -2.89811, 2.89626, -2.21115, -0.00141093, 9.3725, -9.36656, -12.2826}, {1.21116e-11, -1.78885, -0.00114147, 0, 0, -2.34462, 2.34313, 0, 0, 7.02938, -5.36656, -7.03729, -1.49707e-11, 2.21115, 2.89952, -2.89626, 0, 2.89811, -2.89626, 2.21115, 0.00141093, 2.89626, 7.15542, -2.89354, 2.89626, -2.21115, 9.37707, -9.3725, -2.21115, -2.89952}, {-2.3518, -6.05767, -5.91971e-12, -0.0281756, -0.572575, -1.44665, -1.05603, 0, 0, 0.300269, -1.44665, 1.44665, -0.821464, 0.502145, 7.57474, 1.34015, 0.707741, 1.78815, 4.56043, -2.4959, -2.43916e-12, -2.54122, 5.07885, -7.57474, -0.336326, 2.4959, 2.43916e-12, 0.934166, 1.78815, -1.78815}, {0.783932, 2.01922, 1.97176e-12, 0.0845268, 1.71772, 4.33994, -1.05603, 0, 0, 0.300269, -1.44665, 1.44665, -4.06989, -9.86504, 1.78815, 5.56425, 0.707741, 1.78815, 0.336326, -2.4959, -2.43716e-12, -1.34015, -0.707741, -1.78815, -1.5374, 8.28248, -5.78659, 0.934166, 1.78815, -1.78815}, {0.783932, 2.01922, 1.97087e-12, -0.0281756, -0.572575, -1.44665, 3.16808, 0, 0, 0.300269, -1.44665, 1.44665, -0.934166, -1.78815, 1.78815, 1.45285, 2.99804, 7.57474, -2.7994, -10.5728, -1.03197e-11, -1.34015, -0.707741, -1.78815, -0.336326, 2.4959, 2.43583e-12, -0.266911, 7.57474, -7.57474}, {0.783932, 2.01922, 1.97353e-12, -0.0281756, -0.572575, -1.44665, -1.05603, 0, 0, -0.900808, 4.33994, -4.33994, -0.934166, -1.78815, 1.78815, 1.34015, 0.707741, 1.78815, 0.336326, -2.4959, -2.43938e-12, -4.47587, -8.78463, -1.78815, -0.223624, 4.7862, 5.78659, 5.15827, 1.78815, -1.78815}, {-2.45207, 5.12164, 2.36493, 0.0510009, -0.6557, 1.65667, -1.08957, 0.431245, -1.08957, 0.22121, 1.93167, 0.22121, -1.27735, 5.54352, -7.70003, 1.28374, 0.277442, -0.700975, 4.69474, -0.147797, 6.67946, -2.16858, -8.00412, -0.183865, -0.336471, -1.57718, -2.32119, 1.07335, -2.92072, 1.07335}, {0.817357, -1.70721, -0.788311, -0.153003, 1.9671, -4.97001, -1.08957, 0.431245, -1.08957, 0.22121, 1.93167, 0.22121, -4.34278, 9.74957, 2.07989, 5.64201, -1.44754, 3.6573, 0.336471, 1.57718, 2.32119, -1.28374, -0.277442, 0.700975, -1.22131, -9.30386, -3.20603, 1.07335, -2.92072, 1.07335}, {0.817357, -1.70721, -0.788311, 0.0510009, -0.6557, 1.65667, 3.2687, -1.29374, 3.2687, 0.22121, 1.93167, 0.22121, -1.07335, 2.92072, -1.07335, 1.07974, 2.90024, -7.32765, -2.93296, 8.40603, 5.47443, -1.28374, -0.277442, 0.700975, -0.336471, -1.57718, -2.32119, 0.18851, -10.6474, 0.18851}, {0.817357, -1.70721, -0.788311, 0.0510009, -0.6557, 1.65667, -1.08957, 0.431245, -1.08957, -0.66363, -5.795, -0.66363, -1.07335, 2.92072, -1.07335, 1.28374, 0.277442, -0.700975, 0.336471, 1.57718, 2.32119, -4.55317, 6.55141, 3.85422, -0.540475, 1.04562, -8.94786, 5.43162, -4.6457, 5.43162}, {-4.62937, -1.83228, -4.62937, 0.198723, -1.94057, 2.54185, 0, 0, -2.34313, -1.74185, 1.32981, -1.74185, -2.94793, 9.40601, -15.2167, -0.245635, 2.39867, -0.245635, -1.90741, -0.754941, 10.3614, 7.21302, -7.71791, 7.21302, 1.90741, 0.754941, -0.988857, 2.15304, -1.64373, 5.0493}, {1.54312, 0.61076, 1.54312, -0.596168, 5.82171, -7.62554, 0, 0, -2.34313, -1.74185, 1.32981, -1.74185, -8.32553, -0.799305, -11.2218, -0.245635, 2.39867, 9.12687, -1.90741, -0.754941, 0.988857, 0.245635, -2.39867, 0.245635, 8.87479, -4.5643, 5.97853, 2.15304, -1.64373, 5.0493}, {1.54312, 0.61076, 1.54312, 0.198723, -1.94057, 2.54185, 0, 0, 7.02938, -1.74185, 1.32981, -1.74185, -2.15304, 1.64373, -5.0493, -1.04052, 10.1609, -10.413, -8.0799, -3.19798, -5.18364, 0.245635, -2.39867, 0.245635, 1.90741, 0.754941, -0.988857, 9.12042, -6.96297, 12.0167}, {1.54312, 0.61076, 1.54312, 0.198723, -1.94057, 2.54185, 0, 0, -2.34313, 5.22554, -3.98943, 5.22554, -2.15304, 1.64373, -5.0493, -0.245635, 2.39867, -0.245635, -1.90741, -0.754941, 0.988857, -5.92686, -4.84171, -5.92686, 1.11252, 8.51722, -11.1562, 2.15304, -1.64373, 14.4218}, {3.9353, 3.03575, -0.94776, 1.31177, -0.633999, -0.948528, 0, 0.442478, 1.49023, 0, 1.20344, -0.85762, -5.24706, 4.57046, 4.57606, -1.62143, 0.236733, -0.669578, 1.62143, -1.06605, -8.19343, 1.62143, -5.05048, 4.10006, -1.62143, -0.703864, 2.23252, 0, -2.03446, -0.781946}, {-1.31177, -1.01192, 0.31592, -3.9353, 1.902, 2.84558, 2.88186e-16, 0.442478, 1.49023, 7.83799e-16, 1.20344, -0.85762, 5.24706, 6.08213, -0.481733, -1.62143, -1.53318, -6.63049, 1.62143, 0.703864, -2.23252, 1.62143, -0.236733, 0.669578, -1.62143, -5.51761, 5.663, -1.32505e-15, -2.03446, -0.781946}, {-1.31177, -1.01192, 0.31592, 1.31177, -0.633999, -0.948528, 0, -1.32743, -4.47068, 0, 1.20344, -0.85762, 9.76951e-16, 2.03446, 0.781946, -6.86849, 2.77273, 3.12453, 6.86849, 4.75153, -3.4962, 1.62143, -0.236733, 0.669578, -1.62143, -0.703864, 2.23252, 0, -6.84821, 2.64853}, {-1.31177, -1.01192, 0.31592, 1.31177, -0.633999, -0.948528, 0, 0.442478, 1.49023, 0, -3.61031, 2.57286, 9.76951e-16, 2.03446, 0.781946, -1.62143, 0.236733, -0.669578, 1.62143, 0.703864, -2.23252, 6.86849, 3.81093, -0.594102, -6.86849, 1.83213, 6.02663, 0, -3.80438, -6.74286}, {0, 1.48946e-15, 5.41667, 1.44665, 1.44665, 1.40715, 0.572575, -1.44665, 1.02216, -2.01922, -1.97067e-12, -0.623753, -7.57474, -7.57474, -5.13614, -2.4959, -2.4365e-12, -3.00279, -2.99804, 7.57474, -3.1203, 10.5728, 1.03192e-11, 5.4978, 0.707741, -1.78815, -0.968332, 1.78815, 1.78815, -0.492457}, {4.44089e-16, -2.12735e-16, -1.80556, -4.33994, -4.33994, -4.22145, 0.572575, -1.44665, 1.02216, -2.01922, -1.97177e-12, -0.623753, -1.78815, -1.78815, 7.71468, -4.7862, 5.78659, -7.09142, -0.707741, 1.78815, 0.968332, 2.4959, 2.43738e-12, 3.00279, 8.78463, -1.78815, 1.52668, 1.78815, 1.78815, -0.492457}, {-4.44089e-16, -1.6373e-17, -1.80556, 1.44665, 1.44665, 1.40715, -1.71772, 4.33994, -3.06648, -2.01922, -1.97241e-12, -0.623753, -1.78815, -1.78815, 0.492457, -8.28248, -5.78659, -8.63139, -0.707741, 1.78815, 8.19056, 2.4959, 2.43805e-12, 3.00279, 0.707741, -1.78815, -0.968332, 9.86504, 1.78815, 2.00255}, {-4.44089e-16, -2.38418e-16, -1.80556, 1.44665, 1.44665, 1.40715, 0.572575, -1.44665, 1.02216, 6.05767, 5.91722e-12, 1.87126, -1.78815, -1.78815, 0.492457, -2.4959, -2.43805e-12, -3.00279, -0.707741, 1.78815, 0.968332, 2.4959, 2.43812e-12, 10.225, -5.07885, -7.57474, -6.59693, -0.502145, 7.57474, -4.58109}, {4.36745, -2.27082, -4.32425, 1.62155e-12, 0.53318, -2.01922, 0, -1.33263, 0, 1.45582, 0.0425099, 0.577805, 1.79949, -3.72739, 8.79109, -2.00435e-12, 0.988174, 2.4959, 1.79949, 6.04211, -1.78169, -5.82327, -1.15821, -4.80711, -1.79949, -0.711591, 1.78169, -1.79949, 1.59467, -0.714206}, {-1.45582, 0.756939, 1.44142, -4.85918e-12, -1.59954, 6.05767, 0, -1.33263, 0, 1.45582, 0.0425099, 0.577805, 7.62276, -4.62243, -5.05146, -2.00209e-12, 6.31869, 2.4959, 1.79949, 0.711591, -1.78169, 2.00318e-12, -0.988174, -2.4959, -7.62276, -0.881631, -0.529529, -1.79949, 1.59467, -0.714206}, {-1.45582, 0.756939, 1.44142, 1.62009e-12, 0.53318, -2.01922, 0, 3.99789, 0, 1.45582, 0.0425099, 0.577805, 1.79949, -1.59467, 0.714206, -8.4829e-12, -1.14454, 10.5728, 7.62276, -2.31617, -7.54736, 2.00363e-12, -0.988174, -2.4959, -1.79949, -0.711591, 1.78169, -7.62276, 1.42464, -3.02542}, {-1.45582, 0.756939, 1.44142, 1.6179e-12, 0.53318, -2.01922, 0, -1.33263, 0, -4.36745, -0.12753, -1.73341, 1.79949, -1.59467, 0.714206, -1.99984e-12, 0.988174, 2.4959, 1.79949, 0.711591, -1.78169, 5.82327, -4.01593, -8.26156, -1.79949, -2.84431, 9.85858, -1.79949, 6.92519, -0.714206}, {-3.26389, 1.55026, 1.55311, -0.994319, -0.995188, -0.994319, -0.203724, 1.40177, -0.203724, 0.110078, 0.110174, 1.71575, 3.86152, 5.84961, 5.84624, 1.48086, -0.502558, 1.48086, -0.278087, -6.701, 1.70663, -1.92117, 0.0618612, -8.34385, 1.09298, 1.09394, -0.891733, 0.115752, -1.86886, -1.86896}, {1.08796, -0.516753, -0.517703, 2.98296, 2.98556, 2.98296, -0.203724, 1.40177, -0.203724, 0.110078, 0.110174, 1.71575, -4.46761, 3.93587, 3.93978, 2.29576, -6.10962, 2.29576, -1.09298, -1.09394, 0.891733, -1.48086, 0.502558, -1.48086, 0.65267, 0.65324, -7.75472, 0.115752, -1.86886, -1.86896}, {1.08796, -0.516753, -0.517703, -0.994319, -0.995188, -0.994319, 0.611171, -4.2053, 0.611171, 0.110078, 0.110174, 1.71575, -0.115752, 1.86886, 1.86896, 5.45814, 3.47819, 5.45814, -5.44484, 0.973073, 2.96255, -1.48086, 0.502558, -1.48086, 1.09298, 1.09394, -0.891733, -0.32456, -2.30956, -8.73195}, {1.08796, -0.516753, -0.517703, -0.994319, -0.995188, -0.994319, -0.203724, 1.40177, -0.203724, -0.330234, -0.330523, -5.14724, -0.115752, 1.86886, 1.86896, 1.48086, -0.502558, 1.48086, -1.09298, -1.09394, 0.891733, -5.83272, 2.56957, 0.589952, 5.07026, 5.07469, 3.08554, 0.930647, -7.47593, -1.05407}, {5.37021, -5.36225, 5.37163, 3.64724, -0.373167, 0.376681, -1.85717, -1.41425, -0.191806, 0, 0, 1.60567, -16.8846, -0.25544, 0.240906, -2.21265, 2.20937, -0.228519, 11.9369, 5.19574, 3.21754, 2.21265, -2.20937, -6.19415, -4.50824, 0.46126, -2.45032, 2.29559, 1.74811, -1.74763}, {-1.79007, 1.78742, -1.79054, -10.9417, 1.1195, -1.13004, -1.85717, -1.41425, -0.191806, -7.40292e-16, -5.63738e-16, 1.60567, 4.86469, -8.89778, 8.9098, 5.21604, 7.86637, 0.538704, 4.50824, -0.46126, 2.45032, 2.21265, -2.20937, 0.228519, -4.50824, 0.46126, -8.87299, 2.29559, 1.74811, -1.74763}, {-1.79007, 1.78742, -1.79054, 3.64724, -0.373167, 0.376681, 5.57152, 4.24275, 0.575417, 0, 0, 1.60567, -2.29559, -1.74811, 1.74763, -16.8016, 3.70204, -1.73524, 11.6685, -7.61093, 9.61249, 2.21265, -2.20937, 0.228519, -4.50824, 0.46126, -2.45032, 2.29559, 1.74811, -8.1703}, {-1.79007, 1.78742, -1.79054, 3.64724, -0.373167, 0.376681, -1.85717, -1.41425, -0.191806, 0, 0, -4.817, -2.29559, -1.74811, 1.74763, -2.21265, 2.20937, -0.228519, 4.50824, -0.46126, 2.45032, 9.37293, -9.35904, 7.39069, -19.0972, 1.95393, -3.95704, 9.72428, 7.40511, -0.980408}, {-3.03198, 1.78237, 1.1993, 0.5032, 0.50364, 1.82018, -0.838801, -0.839534, 0.331788, -0.67506, 0.930018, -1.7522, -3.88404, -1.90272, -9.03645, 0.414826, 0.415188, -2.65998, 3.14277, 5.13024, -1.24312, 2.28541, -4.13526, 9.66879, 0.212431, -1.7721, -0.084027, 1.87124, -0.111844, 1.75573}, {1.01066, -0.594124, -0.399767, -1.5096, -1.51092, -5.46054, -0.838801, -0.839534, 0.331788, -0.67506, 0.930018, -1.7522, -5.91388, 2.48834, -0.156659, 3.77003, 3.77333, -3.98713, -0.212431, 1.7721, 0.084027, -0.414826, -0.415188, 2.65998, 2.91267, -5.49217, 6.92478, 1.87124, -0.111844, 1.75573}, {1.01066, -0.594124, -0.399767, 0.5032, 0.50364, 1.82018, 2.5164, 2.5186, -0.995364, -0.67506, 0.930018, -1.7522, -1.87124, 0.111844, -1.75573, -1.59797, -1.59937, -9.9407, -4.25508, 4.14859, 1.6831, -0.414826, -0.415188, 2.65998, 0.212431, -1.7721, -0.084027, 4.57148, -3.83192, 8.76454}, {1.01066, -0.594124, -0.399767, 0.5032, 0.50364, 1.82018, -0.838801, -0.839534, 0.331788, 2.02518, -2.79005, 5.25661, -1.87124, 0.111844, -1.75573, 0.414826, 0.415188, -2.65998, -0.212431, 1.7721, 0.084027, -4.45747, 1.96131, 4.25905, -1.80037, -3.78666, -7.36475, 5.22644, 3.24629, 0.428576}, {-4.62937, 1.83228, -4.62937, 0.198723, 1.94057, 2.54185, -1.74185, -1.32981, -1.74185, 0, 0, -2.34313, -2.94793, -9.40601, -15.2167, 1.90741, -0.754941, -0.988857, 7.21302, 7.71791, 7.21302, -1.90741, 0.754941, 10.3614, -0.245635, -2.39867, -0.245635, 2.15304, 1.64373, 5.0493}, {1.54312, -0.61076, 1.54312, -0.596168, -5.82171, -7.62554, -1.74185, -1.32981, -1.74185, 0, 0, -2.34313, -8.32553, 0.799305, -11.2218, 8.87479, 4.5643, 5.97853, 0.245635, 2.39867, 0.245635, -1.90741, 0.754941, 0.988857, -0.245635, -2.39867, 9.12687, 2.15304, 1.64373, 5.0493}, {1.54312, -0.61076, 1.54312, 0.198723, 1.94057, 2.54185, 5.22554, 3.98943, 5.22554, 0, 0, -2.34313, -2.15304, -1.64373, -5.0493, 1.11252, -8.51722, -11.1562, -5.92686, 4.84171, -5.92686, -1.90741, 0.754941, 0.988857, -0.245635, -2.39867, -0.245635, 2.15304, 1.64373, 14.4218}, {1.54312, -0.61076, 1.54312, 0.198723, 1.94057, 2.54185, -1.74185, -1.32981, -1.74185, 0, 0, 7.02938, -2.15304, -1.64373, -5.0493, 1.90741, -0.754941, -0.988857, 0.245635, 2.39867, 0.245635, -8.0799, 3.19798, -5.18364, -1.04052, -10.1609, -10.413, 9.12042, 6.96297, 12.0167}, {-4.33994, 0.458772, -1.71772, -6.12948e-28, 1.39654, 7.00055e-16, -1.44665, -0.27723, 1.44665, 1.76797e-12, -0.966385, -2.01922, -1.78815, -7.12335, -0.707741, 1.78815, -1.38354, -1.78815, 5.78659, 1.64062, -8.28248, -1.78815, 5.24908, 9.86504, -2.18533e-12, -0.531699, 2.4959, 1.78815, 1.53719, 0.707741}, {1.44665, -0.152924, 0.572575, 1.50464e-15, -4.18962, -3.6048e-15, -1.44665, -0.27723, 1.44665, 1.77158e-12, -0.966385, -2.01922, -7.57474, -0.925496, -2.99804, 7.57474, -0.274623, -7.57474, 2.1881e-12, 0.531699, -2.4959, -1.78815, 1.38354, 1.78815, -9.27551e-12, 3.33384, 10.5728, 1.78815, 1.53719, 0.707741}, {1.44665, -0.152924, 0.572575, 0, 1.39654, 0, 4.33994, 0.831689, -4.33994, 1.77087e-12, -0.966385, -2.01922, -1.78815, -1.53719, -0.707741, 1.78815, -6.9697, -1.78815, -5.78659, 1.1434, -4.7862, -1.78815, 1.38354, 1.78815, -2.18892e-12, -0.531699, 2.4959, 1.78815, 5.40273, 8.78463}, {1.44665, -0.152924, 0.572575, -6.13451e-28, 1.39654, 7.00055e-16, -1.44665, -0.27723, 1.44665, -5.30827e-12, 2.89915, 6.05767, -1.78815, -1.53719, -0.707741, 1.78815, -1.38354, -1.78815, 2.18605e-12, 0.531699, -2.4959, -7.57474, 1.99524, -0.502145, -2.18713e-12, -6.11785, 2.4959, 7.57474, 2.64611, -5.07885}, {3.99411, 0.408657, -5.22602, 1.94285, 0.198782, -0.198956, -0.611477, 1.5417, -1.54305, 0, -1.60427, 0, -8.52722, -0.872462, -1.11149, -1.64567, -2.15136, 2.15324, 4.8474, -7.90408, 5.92628, 1.64567, 8.56842, -2.15324, -2.40149, 1.73727, 0.245923, 0.755828, 0.0773324, 1.90731}, {-1.33137, -0.136219, 1.74201, -5.82855, -0.596347, 0.596868, -0.611477, 1.5417, -1.54305, 0, -1.60427, 0, 4.56966, 0.467544, -8.87534, 0.800244, -8.31817, 8.32544, 2.40149, -1.73727, -0.245923, 1.64567, 2.15136, -2.15324, -2.40149, 8.15434, 0.245923, 0.755828, 0.0773324, 1.90731}, {-1.33137, -0.136219, 1.74201, 1.94285, 0.198782, -0.198956, 1.83443, -4.62511, 4.62915, 0, -1.60427, 0, -0.755828, -0.0773324, -1.90731, -9.41706, -2.94649, 2.94906, 7.72698, -1.1924, -7.21395, 1.64567, 2.15136, -2.15324, -2.40149, 1.73727, 0.245923, 0.755828, 6.4944, 1.90731}, {-1.33137, -0.136219, 1.74201, 1.94285, 0.198782, -0.198956, -0.611477, 1.5417, -1.54305, 0, 4.8128, 0, -0.755828, -0.0773324, -1.90731, -1.64567, -2.15136, 2.15324, 2.40149, -1.73727, -0.245923, 6.97115, 2.69623, -9.12126, -10.1729, 0.942144, 1.04175, 3.20174, -6.08948, 8.07952}, {1.7133, -2.45292, -4.3293, -1.44292, 0.0459567, -1.45561, 0, -1.33263, 0, 2.01402, 0.469033, 0.0125109, 8.26116, -1.25129, 5.83791, 1.78355, 1.59041, 1.79923, 0.70592, 5.96708, -1.78377, -9.83965, -3.46655, -1.84928, -0.70592, -0.636563, 1.78377, -2.48947, 1.06746, -0.0154644}, {-0.571101, 0.817639, 1.4431, 4.32877, -0.13787, 4.36683, 0, -1.33263, 0, 2.01402, 0.469033, 0.0125109, 4.77387, -4.33802, -5.75693, 1.78355, 6.92093, 1.79923, 0.70592, 0.636563, -1.78377, -1.78355, -1.59041, -1.79923, -8.76202, -2.5127, 1.73373, -2.48947, 1.06746, -0.0154644}, {-0.571101, 0.817639, 1.4431, -1.44292, 0.0459567, -1.45561, 0, 3.99789, 0, 2.01402, 0.469033, 0.0125109, 2.48947, -1.06746, 0.0154644, 7.55524, 1.40659, 7.62167, 2.99032, -2.63399, -7.55617, -1.78355, -1.59041, -1.79923, -0.70592, -0.636563, 1.78377, -10.5456, -0.808671, -0.0655081}, {-0.571101, 0.817639, 1.4431, -1.44292, 0.0459567, -1.45561, 0, -1.33263, 0, -6.04207, -1.4071, -0.0375328, 2.48947, -1.06746, 0.0154644, 1.78355, 1.59041, 1.79923, 0.70592, 0.636563, -1.78377, 0.500853, -4.86097, -7.57163, 5.06577, -0.82039, 7.60621, -2.48947, 6.39798, -0.0154644}, {7.61576, -5.82053, 0.598329, -1.54462, -0.610276, -1.54223, 1.74008, -1.3299, 1.74168, 2.34313, 0, 0, 11.2256, 0.797254, 8.32176, -0.241602, 2.39819, -0.246525, -5.97333, 4.56526, -8.87301, -9.1309, -2.39819, 0.246525, -0.987004, 0.754342, 1.9063, -5.04712, 1.64385, -2.15283}, {-2.53859, 1.94018, -0.199443, 4.63387, 1.83083, 4.6267, 1.74008, -1.3299, 1.74168, 2.34313, -7.73589e-16, 1.01311e-15, 15.2015, -9.40456, 2.9506, -7.20193, 7.7178, -7.21323, 0.987004, -0.754342, -1.9063, 0.241602, -2.39819, 0.246525, -10.3595, 0.754342, 1.9063, -5.04712, 1.64385, -2.15283}, {-2.53859, 1.94018, -0.199443, -1.54462, -0.610276, -1.54223, -5.22025, 3.9897, -5.22503, 2.34313, 0, 0, 5.04712, -1.64385, 2.15283, 5.93689, 4.83929, 5.92241, 11.1413, -8.51505, -1.10853, 0.241602, -2.39819, 0.246525, -0.987004, 0.754342, 1.9063, -14.4196, 1.64385, -2.15283}, {-2.53859, 1.94018, -0.199443, -1.54462, -0.610276, -1.54223, 1.74008, -1.3299, 1.74168, -7.02938, 0, 0, 5.04712, -1.64385, 2.15283, -0.241602, 2.39819, -0.246525, 0.987004, -0.754342, -1.9063, 10.3959, -10.1589, 1.0443, 5.19149, 3.19544, 8.07523, -12.0075, 6.96345, -9.11953}, {3.55271e-15, 3.55271e-15, -7.0244, 0.00253498, 1.78885, -0.00126659, -2.34566, -1.78885, -2.3402, 2.34313, 0, 0, -0.0132733, -9.36656, -2.88758, 2.89626, -1.33227e-15, 2.89421, 12.282, 9.36656, 9.35923, -12.2688, 1.33227e-15, -2.89421, -2.8994, -2.21115, 0.00156559, 0.00313341, 2.21115, 2.89265}, {-1.77636e-15, -6.96663e-17, 2.34147, -0.00760494, -5.36656, 0.00379978, -2.34566, -1.78885, -2.3402, 2.34313, -1.04056e-15, -1.36127e-15, -0.00313341, -2.21115, -12.2585, 12.2789, 7.15542, 12.255, 2.8994, 2.21115, -0.00156559, -2.89626, 1.33227e-15, -2.89421, -12.2719, -2.21115, 0.00156559, 0.00313341, 2.21115, 2.89265}, {-1.33227e-15, -1.9984e-15, 2.34147, 0.00253498, 1.78885, -0.00126659, 7.03698, 5.36656, 7.0206, 2.34313, 0, 0, -0.00313341, -2.21115, -2.89265, 2.88612, -7.15542, 2.89928, 2.8994, 2.21115, -9.36743, -2.89626, 2.66454e-15, -2.89421, -2.8994, -2.21115, 0.00156559, -9.36937, 2.21115, 2.89265}, {4.44089e-16, 0, 2.34147, 0.00253498, 1.78885, -0.00126659, -2.34566, -1.78885, -2.3402, -7.02938, 0, 0, -0.00313341, -2.21115, -2.89265, 2.89626, 0, 2.89421, 2.8994, 2.21115, -0.00156559, -2.89626, 0, -12.2601, -2.90954, -9.36656, 0.00663197, 9.38578, 9.36656, 12.2534}, {3.98943, -5.22554, 5.22554, -0.61076, -1.54312, 1.54312, 0, 2.34313, 0, 1.94057, -2.54185, 0.198723, 4.84171, 5.92686, -5.92686, 0.754941, -0.988857, -1.90741, 1.64373, -14.4218, 2.15304, -8.51722, 11.1562, 1.11252, -1.64373, 5.0493, -2.15304, -2.39867, 0.245635, -0.245635}, {-1.32981, 1.74185, -1.74185, 1.83228, 4.62937, -4.62937, 1.12881e-15, 2.34313, 1.15595e-16, 1.94057, -2.54185, 0.198723, 7.71791, -7.21302, 7.21302, 0.754941, -10.3614, -1.90741, 1.64373, -5.0493, 2.15304, -0.754941, 0.988857, 1.90741, -9.40601, 15.2167, -2.94793, -2.39867, 0.245635, -0.245635}, {-1.32981, 1.74185, -1.74185, -0.61076, -1.54312, 1.54312, 0, -7.02938, 0, 1.94057, -2.54185, 0.198723, 2.39867, -0.245635, 0.245635, 3.19798, 5.18364, -8.0799, 6.96297, -12.0167, 9.12042, -0.754941, 0.988857, 1.90741, -1.64373, 5.0493, -2.15304, -10.1609, 10.413, -1.04052}, {-1.32981, 1.74185, -1.74185, -0.61076, -1.54312, 1.54312, 0, 2.34313, 0, -5.82171, 7.62554, -0.596168, 2.39867, -0.245635, 0.245635, 0.754941, -0.988857, -1.90741, 1.64373, -5.0493, 2.15304, 4.5643, -5.97853, 8.87479, 0.799305, 11.2218, -8.32553, -2.39867, -9.12687, -0.245635}, {9.45441, 0, 8.88178e-16, -2.13212e-15, 2.79907e-15, 3.15147, 1.78885, 1.78885, -1.78885, 1.36261, -1.78885, -1.36261, 3.89543, -1.46549e-14, -16.5013, -2.21115, -2.21115, -1.68428, -5.47113, -9.36656, 9.36656, -3.23931, 9.36656, 7.13474, -1.68428, 2.21115, -2.21115, -3.89543, 3.55271e-15, 3.89543}, {-3.15147, -2.22045e-16, 2.22045e-16, -1.00042e-15, -8.3972e-15, -9.45441, 1.78885, 1.78885, -1.78885, 1.36261, -1.78885, -1.36261, 16.5013, -3.55271e-15, -3.89543, -9.36656, -9.36656, 5.47113, 1.68428, -2.21115, 2.21115, 2.21115, 2.21115, 1.68428, -7.13474, 9.36656, 3.23931, -3.89543, 3.10862e-15, 3.89543}, {-3.15147, 0, -4.44089e-16, 0, 0, 3.15147, -5.36656, -5.36656, 5.36656, 1.36261, -1.78885, -1.36261, 3.89543, 0, -3.89543, -2.21115, -2.21115, -14.2902, 14.2902, -2.21115, 2.21115, 2.21115, 2.21115, 1.68428, -1.68428, 2.21115, -2.21115, -9.34589, 7.15542, 9.34589}, {-3.15147, 0, -2.22045e-16, -2.13212e-15, 2.79907e-15, 3.15147, 1.78885, 1.78885, -1.78885, -4.08784, 5.36656, 4.08784, 3.89543, -3.55271e-15, -3.89543, -2.21115, -2.21115, -1.68428, 1.68428, -2.21115, 2.21115, 14.817, 2.21115, 1.68428, -1.68428, 2.21115, -14.817, -11.0508, -7.15542, 11.0508}, {0.908154, -0.908154, 3.90885, -0.830764, 0.830764, 0.830764, 1.29079, 0.314875, 0.314875, -0.157311, -1.44836, 0.157311, 4.72412, -4.72412, -2.7394, -0.568628, -1.41609, -1.41609, -6.3845, -2.02289, -0.0381727, 1.19787, 7.20951, 0.786843, 1.22133, 0.763387, -1.22133, -1.40106, 1.40106, -0.583654}, {-0.302718, 0.302718, -1.30295, 2.49229, -2.49229, -2.49229, 1.29079, 0.314875, 0.314875, -0.157311, -1.44836, 0.157311, 2.61193, -2.61193, 5.79545, -5.7318, -2.67559, -2.67559, -1.22133, -0.763387, 1.22133, 0.568628, 1.41609, 1.41609, 1.85057, 6.55681, -1.85057, -1.40106, 1.40106, -0.583654}, {-0.302718, 0.302718, -1.30295, -0.830764, 0.830764, 0.830764, -3.87238, -0.944625, -0.944625, -0.157311, -1.44836, 0.157311, 1.40106, -1.40106, 0.583654, 2.75443, -4.73914, -4.73914, -0.0104551, -1.97426, 6.43313, 0.568628, 1.41609, 1.41609, 1.22133, 0.763387, -1.22133, -0.771816, 7.19449, -1.2129}, {-0.302718, 0.302718, -1.30295, -0.830764, 0.830764, 0.830764, 1.29079, 0.314875, 0.314875, 0.471934, 4.34507, -0.471934, 1.40106, -1.40106, 0.583654, -0.568628, -1.41609, -1.41609, -1.22133, -0.763387, 1.22133, 1.7795, 0.205215, 6.62789, 4.54438, -2.55967, -4.54438, -6.56423, 0.14156, -1.84315}, {-2.30283, -5.06257, 2.51418, -1.077, -0.426271, -1.077, 0.0318939, 0.648138, 1.63756, 0.277498, -1.90939, 0.277498, 4.69044, 0.146092, 6.67515, 1.29182, -0.274242, -0.692891, -1.11582, -5.47959, -7.53849, -2.40182, 7.9118, -0.417103, 0.988241, 2.88704, 0.988241, -0.38243, 1.55899, -2.36714}, {0.767609, 1.68752, -0.838059, 3.23101, 1.27881, 3.23101, 0.0318939, 0.648138, 1.63756, 0.277498, -1.90939, 0.277498, -2.68801, -8.30908, 5.71938, 1.16425, -2.86679, -7.24314, -0.988241, -2.88704, -0.988241, -1.29182, 0.274242, 0.692891, -0.121753, 10.5246, -0.121753, -0.38243, 1.55899, -2.36714}, {0.767609, 1.68752, -0.838059, -1.077, -0.426271, -1.077, -0.0956818, -1.94441, -4.91269, 0.277498, -1.90939, 0.277498, 0.38243, -1.55899, 2.36714, 5.59983, 1.43084, 3.61512, -4.05868, -9.63713, 2.36399, -1.29182, 0.274242, 0.692891, 0.988241, 2.88704, 0.988241, -1.49242, 9.19655, -3.47714}, {0.767609, 1.68752, -0.838059, -1.077, -0.426271, -1.077, 0.0318939, 0.648138, 1.63756, -0.832495, 5.72817, -0.832495, 0.38243, -1.55899, 2.36714, 1.29182, -0.274242, -0.692891, -0.988241, -2.88704, -0.988241, -4.36226, -6.47585, 4.04513, 5.29625, 4.59212, 5.29625, -0.510006, -1.03356, -8.91739}, {-4.7272, -4.7272, -4.7272, -1.57573, 1.57573, -1.57573, -1.57573, -1.57573, 1.57573, 1.57573, -1.57573, -1.57573, 6.30294, -10.1984, 6.30294, 3.89543, 1.32738e-12, -1.32694e-12, 6.30294, 6.30294, -10.1984, -10.1984, 6.30294, 6.30294, 3.07976e-13, 3.13749e-13, 3.89543, 1.65312e-12, 3.89543, 1.65046e-12}, {1.57573, 1.57573, 1.57573, 4.7272, -4.7272, 4.7272, -1.57573, -1.57573, 1.57573, 1.57573, -1.57573, -1.57573, -6.30294, -10.1984, -6.30294, 10.1984, 6.30294, -6.30294, -3.062e-13, -3.03313e-13, -3.89543, -3.89543, -1.32856e-12, 1.32554e-12, -6.30294, 6.30294, 10.1984, 1.64868e-12, 3.89543, 1.64846e-12}, {1.57573, 1.57573, 1.57573, -1.57573, 1.57573, -1.57573, 4.7272, 4.7272, -4.7272, 1.57573, -1.57573, -1.57573, -1.63936e-12, -3.89543, -1.66356e-12, 10.1984, -6.30294, 6.30294, -6.30294, -6.30294, -10.1984, -3.89543, -1.32833e-12, 1.32599e-12, 3.10862e-13, 3.1064e-13, 3.89543, -6.30294, 10.1984, 6.30294}, {1.57573, 1.57573, 1.57573, -1.57573, 1.57573, -1.57573, -1.57573, -1.57573, 1.57573, -4.7272, 4.7272, 4.7272, -1.65867e-12, -3.89543, -1.64624e-12, 3.89543, 1.32672e-12, -1.32694e-12, -2.95097e-13, -3.04201e-13, -3.89543, -10.1984, -6.30294, -6.30294, 6.30294, -6.30294, 10.1984, 6.30294, 10.1984, -6.30294}, {-1.56775, 5.44381, 3.24545, 1.20899, 0.479095, 1.20825, -1.50445, -0.59618, 0.101437, -0.227124, 1.93169, -0.227868, -6.97629, -0.265605, -4.98928, 0.365209, 0.144724, -1.61886, 7.23144, 5.36461, 0.80607, 0.543287, -7.87147, 2.53034, -1.21365, -2.97989, -1.21182, 2.14034, -1.65078, 0.156278}, {0.522584, -1.8146, -1.08182, -3.62696, -1.43729, -3.62475, -1.50445, -0.59618, 0.101437, -0.227124, 1.93169, -0.227868, -4.23068, 8.90919, 4.171, 6.383, 2.52944, -2.02461, 1.21365, 2.97989, 1.21182, -0.365209, -0.144724, 1.61886, -0.305154, -10.7066, -0.300344, 2.14034, -1.65078, 0.156278}, {0.522584, -1.8146, -1.08182, 1.20899, 0.479095, 1.20825, 4.51334, 1.78854, -0.304311, -0.227124, 1.93169, -0.227868, -2.14034, 1.65078, -0.156278, -4.47074, -1.77166, -6.45186, -0.876686, 10.2383, 5.53909, -0.365209, -0.144724, 1.61886, -1.21365, -2.97989, -1.21182, 3.04884, -9.37752, 1.06775}, {0.522584, -1.8146, -1.08182, 1.20899, 0.479095, 1.20825, -1.50445, -0.59618, 0.101437, 0.681372, -5.79506, 0.683605, -2.14034, 1.65078, -0.156278, 0.365209, 0.144724, -1.61886, 1.21365, 2.97989, 1.21182, -2.45554, 7.11368, 5.94614, -6.0496, -4.89627, -6.04482, 8.15813, 0.733943, -0.24947}, {0.31567, 3.31084, -3.29586, 0.708828, -0.490803, -1.01172, 0.848249, 1.25814, 0.0940198, -1.45185, 0.336273, -0.18092, -3.58141, 3.93402, 3.93947, -1.92465, -0.948485, 1.13434, -4.31143, -5.22358, -1.85026, 7.73207, -0.396608, -0.41066, 0.91843, 0.191009, 1.47418, 0.746096, -1.97081, 0.107415}, {-0.105223, -1.10361, 1.09862, -2.12648, 1.47241, 3.03516, 0.848249, 1.25814, 0.0940198, -1.45185, 0.336273, -0.18092, -0.325203, 6.38527, -4.5019, -5.31765, -5.98106, 0.758261, -0.91843, -0.191009, -1.47418, 1.92465, 0.948485, -1.13434, 6.72585, -1.15408, 2.19787, 0.746096, -1.97081, 0.107415}, {-0.105223, -1.10361, 1.09862, 0.708828, -0.490803, -1.01172, -2.54475, -3.77443, -0.282059, -1.45185, 0.336273, -0.18092, -0.746096, 1.97081, -0.107415, -4.75996, 1.01473, 5.18122, -0.497537, 4.22345, -5.86867, 1.92465, 0.948485, -1.13434, 0.91843, 0.191009, 1.47418, 6.55351, -3.3159, 0.831095}, {-0.105223, -1.10361, 1.09862, 0.708828, -0.490803, -1.01172, 0.848249, 1.25814, 0.0940198, 4.35556, -1.00882, 0.54276, -0.746096, 1.97081, -0.107415, -1.92465, -0.948485, 1.13434, -0.91843, -0.191009, -1.47418, 2.34555, 5.36294, -5.52882, -1.91688, 2.15422, 5.52107, -2.6469, -7.00338, -0.268664}, {2.3172, 0.917451, -2.318, 1.00416, 1.78176, 0.599951, -0.431249, 0.464989, -1.17482, 0.199489, -1.94094, -0.197793, -4.30311, -8.95143, -4.09645, -0.708156, -2.77714, 0.710583, 3.21279, -2.0567, 5.1964, -0.0898, 10.5409, 0.0805874, -1.48779, 0.196748, -0.497096, 0.286472, 1.82437, 1.69665}, {-0.772399, -0.305817, 0.772666, -3.01248, -5.34529, -1.79985, -0.431249, 0.464989, -1.17482, 0.199489, -1.94094, -0.197793, 2.80312, -0.601104, -4.78731, 1.01684, -4.6371, 5.40988, 1.48779, -0.196748, 0.497096, 0.708156, 2.77714, -0.710583, -2.28575, 7.96049, 0.294074, 0.286472, 1.82437, 1.69665}, {-0.772399, -0.305817, 0.772666, 1.00416, 1.78176, 0.599951, 1.29375, -1.39497, 3.52447, 0.199489, -1.94094, -0.197793, -0.286472, -1.82437, -1.69665, -4.72479, -9.9042, -1.68922, 4.57739, 1.02652, -2.59357, 0.708156, 2.77714, -0.710583, -1.48779, 0.196748, -0.497096, -0.511484, 9.58812, 2.48782}, {-0.772399, -0.305817, 0.772666, 1.00416, 1.78176, 0.599951, -0.431249, 0.464989, -1.17482, -0.598467, 5.82281, 0.593378, -0.286472, -1.82437, -1.69665, -0.708156, -2.77714, 0.710583, 1.48779, -0.196748, 0.497096, 3.79775, 4.00041, -3.80125, -5.50443, -6.93031, -2.8969, 2.01147, -0.0355852, 6.39595}, {-9.63611, -0.184458, -9.63611, -0.833808, -0.834046, -2.43948, -1.57551, 1.57551, -1.57551, -0.802719, -0.802949, 0.802949, 0.39558, 4.29112, 8.80297, 2.97808, -0.916498, 4.96279, 4.27918, -8.32547, 4.27918, 0.232798, 4.12829, -8.17459, 2.02286, 2.02344, 2.02286, 2.93965, -0.954937, 0.954937}, {3.21204, 0.0614861, 3.21204, 2.50142, 2.50214, 7.31843, -1.57551, 1.57551, -1.57551, -0.802719, -0.802949, 0.802949, -15.7878, 0.708993, -13.8031, 9.28012, -7.21853, 11.2648, -2.02286, -2.02344, -2.02286, -2.97808, 0.916498, -4.96279, 5.23374, 5.23523, -1.18894, 2.93965, -0.954937, 0.954937}, {3.21204, 0.0614861, 3.21204, -0.833808, -0.834046, -2.43948, 4.72653, -4.72653, 4.72653, -0.802719, -0.802949, 0.802949, -2.93965, 0.954937, -0.954937, 6.31331, 2.41969, 14.7207, -14.871, -2.26938, -14.871, -2.97808, 0.916498, -4.96279, 2.02286, 2.02344, 2.02286, 6.15053, 2.25686, -2.25686}, {3.21204, 0.0614861, 3.21204, -0.833808, -0.834046, -2.43948, -1.57551, 1.57551, -1.57551, 2.40816, 2.40885, -2.40885, -2.93965, 0.954937, -0.954937, 2.97808, -0.916498, 4.96279, -2.02286, -2.02344, -2.02286, -15.8262, 0.670554, -17.8109, 5.35809, 5.35962, 11.7808, 9.24169, -7.25697, 7.25697}, {-2.66454e-15, -4.44089e-15, -3.26126, 1.4431, -0.571101, 0.0717263, 0.0125109, 2.01402, -0.807596, -1.45561, -1.44292, -0.351216, -7.55617, 2.99032, -1.71928, -1.79923, -1.78355, 0.909586, -0.0655081, -10.5456, 2.88492, 7.62167, 7.55524, 0.495278, 0.0154644, 2.48947, 0.345468, 1.78377, -0.70592, 1.43237}, {0, -8.88178e-16, 1.08709, -4.3293, 1.7133, -0.215179, 0.0125109, 2.01402, -0.807596, -1.45561, -1.44292, -0.351216, -1.78377, 0.70592, -5.78072, -1.84928, -9.83965, 4.13997, -0.0154644, -2.48947, -0.345468, 1.79923, 1.78355, -0.909586, 5.83791, 8.26116, 1.75033, 1.78377, -0.70592, 1.43237}, {-2.22045e-16, -4.44089e-16, 1.08709, 1.4431, -0.571101, 0.0717263, -0.0375328, -6.04207, 2.42279, -1.45561, -1.44292, -0.351216, -1.78377, 0.70592, -1.43237, -7.57163, 0.500853, 0.622681, -0.0154644, -2.48947, -4.69381, 1.79923, 1.78355, -0.909586, 0.0154644, 2.48947, 0.345468, 7.60621, 5.06577, 2.83723}, {-4.44089e-16, 4.44089e-16, 1.08709, 1.4431, -0.571101, 0.0717263, 0.0125109, 2.01402, -0.807596, 4.36683, 4.32877, 1.05365, -1.78377, 0.70592, -1.43237, -1.79923, -1.78355, 0.909586, -0.0154644, -2.48947, -0.345468, 1.79923, 1.78355, -5.25793, -5.75693, 4.77387, 0.0585632, 1.73373, -8.76202, 4.66276}, {4.62915, 1.83443, 4.62633, 1.74201, -1.33137, 0.13686, 1.18908e-16, -1.16116e-15, 1.60497, -0.198956, 1.94285, -0.199718, -7.21395, 7.72698, 1.18954, -2.15324, 1.64567, -2.15302, 1.90731, 0.755828, -6.49756, 2.94906, -9.41706, 2.95189, -1.90731, -0.755828, 0.0776963, 0.245923, -2.40149, -1.73698}, {-1.54305, -0.611477, -1.54211, -5.22602, 3.99411, -0.41058, 3.96359e-17, -3.87053e-16, 1.60497, -0.198956, 1.94285, -0.199718, 5.92628, 4.8474, 7.90542, -2.15324, 1.64567, -8.57288, 1.90731, 0.755828, -0.0776963, 2.15324, -1.64567, 2.15302, -1.11149, -8.52722, 0.876567, 0.245923, -2.40149, -1.73698}, {-1.54305, -0.611477, -1.54211, 1.74201, -1.33137, 0.13686, 0, 0, -4.8149, -0.198956, 1.94285, -0.199718, -0.245923, 2.40149, 1.73698, -9.12126, 6.97115, -2.70046, 8.07952, 3.20174, 6.09074, 2.15324, -1.64567, 2.15302, -1.90731, -0.755828, 0.0776963, 1.04175, -10.1729, -0.938112}, {-1.54305, -0.611477, -1.54211, 1.74201, -1.33137, 0.13686, 1.18908e-16, -1.16116e-15, 1.60497, 0.596868, -5.82855, 0.599153, -0.245923, 2.40149, 1.73698, -2.15324, 1.64567, -2.15302, 1.90731, 0.755828, -0.0776963, 8.32544, 0.800244, 8.32145, -8.87534, 4.56966, -0.469744, 0.245923, -2.40149, -8.15685}, {4.35065, -1.72407, 1.44786, 0, 0, 1.17684, 1.43763, 1.45199, 0.197849, 0.0125895, -2.02668, -0.892072, 1.79257, -0.710355, -5.56548, -1.77701, -1.79476, -1.69921, -5.73495, -8.31307, -0.439401, 1.72665, 9.90148, 5.2675, -0.0155615, 2.50511, -0.351997, -1.79257, 0.710355, 0.858106}, {-1.45022, 0.57469, -0.482621, 1.29313e-15, -4.05633e-15, -3.53053, 1.43763, 1.45199, 0.197849, 0.0125895, -2.02668, -0.892072, 7.59343, -3.00911, 1.07238, -7.52752, -7.60272, -2.49061, 0.0155615, -2.50511, 0.351997, 1.77701, 1.79476, 1.69921, -0.0659197, 10.6118, 3.21629, -1.79257, 0.710355, 0.858106}, {-1.45022, 0.57469, -0.482621, -1.47124e-17, 2.36842e-15, 1.17684, -4.31288, -4.35597, -0.593548, 0.0125895, -2.02668, -0.892072, 1.79257, -0.710355, -0.858106, -1.77701, -1.79476, -6.40659, 5.81643, -4.80387, 2.28248, 1.77701, 1.79476, 1.69921, -0.0155615, 2.50511, -0.351997, -1.84292, 8.81707, 4.42639}, {-1.45022, 0.57469, -0.482621, 0, 0, 1.17684, 1.43763, 1.45199, 0.197849, -0.0377686, 6.08004, 2.67622, 1.79257, -0.710355, -0.858106, -1.77701, -1.79476, -1.69921, 0.0155615, -2.50511, 0.351997, 7.57787, -0.504, 3.6297, -0.0155615, 2.50511, -5.05937, -7.54308, -5.09761, 0.0667081}, {2.31688, 0.916898, -2.31818, 0.572147, 2.2454, -0.575329, -1.46447, -2.59853, -0.874972, 1.66462, 0.658766, 0.677573, -2.04119, -11.3793, 2.05732, 1.10297, 0.436497, 1.79267, 8.62268, 13.9839, 3.62627, -7.76145, -3.07156, -4.50296, -2.76479, -3.58975, -0.126381, -0.247396, 2.39768, 0.243998}, {-0.772295, -0.305633, 0.772728, -1.71644, -6.7362, 1.72599, -1.46447, -2.59853, -0.874972, 1.66462, 0.658766, 0.677573, 3.33658, -1.17515, -3.33491, 6.96086, 10.8306, 5.29256, 2.76479, 3.58975, 0.126381, -1.10297, -0.436497, -1.79267, -9.42327, -6.22481, -2.83667, -0.247396, 2.39768, 0.243998}, {-0.772295, -0.305633, 0.772728, 0.572147, 2.2454, -0.575329, 4.39341, 7.7956, 2.62492, 1.66462, 0.658766, 0.677573, 0.247396, -2.39768, -0.243998, -1.18562, -8.5451, 4.09399, 5.85397, 4.81228, -2.96453, -1.10297, -0.436497, -1.79267, -2.76479, -3.58975, -0.126381, -6.90587, -0.237381, -2.46629}, {-0.772295, -0.305633, 0.772728, 0.572147, 2.2454, -0.575329, -1.46447, -2.59853, -0.874972, -4.99386, -1.9763, -2.03272, 0.247396, -2.39768, -0.243998, 1.10297, 0.436497, 1.79267, 2.76479, 3.58975, 0.126381, 1.98621, 0.786034, -4.88358, -5.05338, -12.5713, 2.17494, 5.61049, 12.7918, 3.74389}, {-7.02177, -5.36656, 7.02938, 0.00253498, -1.78885, 1.21116e-11, -2.34313, 0, 0, 0, 0, 2.34313, -2.9064, 7.15542, 2.89626, 2.89313, 2.21115, -1.49707e-11, 9.37564, -2.21115, 2.89626, -2.89313, -2.21115, -9.3725, -0.00313341, 2.21115, -2.89626, 2.89626, 0, -2.89626}, {2.34059, 1.78885, -2.34313, -0.00760494, 5.36656, -5.48009e-11, -2.34313, 0, 0, -1.36297e-15, 0, 2.34313, -12.2586, -7.15542, 12.2688, 12.2656, 2.21115, -2.25792e-11, 0.00313341, -2.21115, 2.89626, -2.89313, -2.21115, 2.2581e-11, -0.00313341, 2.21115, -12.2688, 2.89626, 0, -2.89626}, {2.34059, 1.78885, -2.34313, 0.00253498, -1.78885, 1.211e-11, 7.02938, 0, 0, 0, 0, 2.34313, -2.89626, -1.33227e-15, 2.89626, 2.88299, 9.36656, -6.34088e-11, -9.35923, -9.36656, 12.2688, -2.89313, -2.21115, 1.49705e-11, -0.00313341, 2.21115, -2.89626, 2.89626, 0, -12.2688}, {2.34059, 1.78885, -2.34313, 0.00253498, -1.78885, 1.21095e-11, -2.34313, 0, 0, 0, 0, -7.02938, -2.89626, -1.33227e-15, 2.89626, 2.89313, 2.21115, -1.49681e-11, 0.00313341, -2.21115, 2.89626, -12.2555, -9.36656, 9.3725, -0.0132733, 9.36656, -2.89626, 12.2688, 0, -2.89626}, {0.0377686, 6.08004, 3.1372, -4.64343e-16, -1.84009e-16, 1.28977, -1.43763, 1.45199, -0.146251, 1.45022, 0.57469, -0.0977806, 0.0155615, 2.50511, -5.4607, 1.77701, -1.79476, -1.41346, 7.54308, -5.09761, 2.05838, -7.57787, -0.504, 1.80458, -1.79257, -0.710355, -1.47337, -0.0155615, -2.50511, 0.301639}, {-0.0125895, -2.02668, -1.04573, 2.77397e-15, -8.42705e-16, -3.8693, -1.43763, 1.45199, -0.146251, 1.45022, 0.57469, -0.0977806, 0.0659197, 10.6118, 3.8813, 7.52752, -7.60272, -0.82846, 1.79257, 0.710355, 1.47337, -1.77701, 1.79476, 1.41346, -7.59343, -3.00911, -1.08225, -0.0155615, -2.50511, 0.301639}, {-0.0125895, -2.02668, -1.04573, 0, 0, 1.28977, 4.31288, -4.35597, 0.438752, 1.45022, 0.57469, -0.0977806, 0.0155615, 2.50511, -0.301639, 1.77701, -1.79476, -6.57252, 1.84292, 8.81707, 5.65631, -1.77701, 1.79476, 1.41346, -1.79257, -0.710355, -1.47337, -5.81643, -4.80387, 0.692761}, {-0.0125895, -2.02668, -1.04573, -4.64343e-16, -1.84009e-16, 1.28977, -1.43763, 1.45199, -0.146251, -4.35065, -1.72407, 0.293342, 0.0155615, 2.50511, -0.301639, 1.77701, -1.79476, -1.41346, 1.79257, 0.710355, 1.47337, -1.72665, 9.90148, 5.5964, -1.79257, -0.710355, -6.63244, 5.73495, -8.31307, 0.886641}, {-4.7272, -4.7272, 4.7272, 1.57573, -1.57573, 1.57573, -1.57596, -1.57551, -1.57551, -1.57551, 1.57551, 1.57551, -10.1984, 6.30294, -6.30294, 0.000278382, 3.89515, -0.000278382, 6.30412, 6.30176, 10.1972, 6.30176, -10.1972, -6.30176, -0.000278382, 0.000278382, -3.89515, 3.89543, -1.33227e-15, -1.77636e-15}, {1.57573, 1.57573, -1.57573, -4.7272, 4.7272, -4.7272, -1.57596, -1.57551, -1.57551, -1.57551, 1.57551, 1.57551, -10.1984, -6.30294, 6.30294, 6.30412, 10.1972, 6.30176, 0.000278382, -0.000278382, 3.89515, -0.000278382, -3.89515, 0.000278382, 6.30176, -6.30176, -10.1972, 3.89543, -9.32587e-15, 3.10862e-15}, {1.57573, 1.57573, -1.57573, 1.57573, -1.57573, 1.57573, 4.72788, 4.72653, 4.72653, -1.57551, 1.57551, 1.57551, -3.89543, 3.55271e-15, -9.76996e-15, -6.30266, 10.1981, -6.30322, -6.30266, -6.30322, 10.1981, -0.000278382, -3.89515, 0.000278382, -0.000278382, 0.000278382, -3.89515, 10.1975, -6.30204, -6.30204}, {1.57573, 1.57573, -1.57573, 1.57573, -1.57573, 1.57573, -1.57596, -1.57551, -1.57551, 4.72653, -4.72653, -4.72653, -3.89543, 7.99361e-15, -1.9984e-15, 0.000278382, 3.89515, -0.000278382, 0.000278382, -0.000278382, 3.89515, -6.30322, -10.1981, 6.30322, -6.30322, 6.30322, -10.1981, 10.1993, 6.30204, 6.30204}, {1.83228, 4.63528, 4.62937, 1.94057, -2.54509, -0.198723, -1.32981, 1.74407, 1.74185, 0, 2.34612, 0, -9.40601, 15.2361, 2.94793, -0.754941, 0.990119, -1.90741, 7.71791, -7.22223, -7.21302, 0.754941, -10.3746, 1.90741, -2.39867, 0.245948, 0.245635, 1.64373, -5.05575, -2.15304}, {-0.61076, -1.54509, -1.54312, -5.82171, 7.63528, 0.596168, -1.32981, 1.74407, 1.74185, -7.74523e-16, 2.34612, 1.01451e-15, 0.799305, 11.2361, 8.32553, 4.5643, -5.98616, -8.87479, 2.39867, -0.245948, -0.245635, 0.754941, -0.990119, 1.90741, -2.39867, -9.13852, 0.245635, 1.64373, -5.05575, -2.15304}, {-0.61076, -1.54509, -1.54312, 1.94057, -2.54509, -0.198723, 3.98943, -5.23221, -5.22554, 0, 2.34612, 0, -1.64373, 5.05575, 2.15304, -8.51722, 11.1705, -1.11252, 4.84171, 5.93443, 5.92686, 0.754941, -0.990119, 1.90741, -2.39867, 0.245948, 0.245635, 1.64373, -14.4402, -2.15304}, {-0.61076, -1.54509, -1.54312, 1.94057, -2.54509, -0.198723, -1.32981, 1.74407, 1.74185, 0, -7.03835, 0, -1.64373, 5.05575, 2.15304, -0.754941, 0.990119, -1.90741, 2.39867, -0.245948, -0.245635, 3.19798, 5.19026, 8.0799, -10.1609, 10.4263, 1.04052, 6.96297, -12.032, -9.12042}, {-1.42344, 3.96091, -1.43084, -1.98584, -0.354449, 0.357788, 0.9893, 0.397365, -1.35371, 0.52206, 1.27739, 0.518977, 9.81149, 3.4879, -2.46294, 1.23179, -0.0530468, 1.23103, -5.76653, -0.448647, 6.49858, -3.32003, -5.0565, -3.30694, 1.80933, -1.14081, -1.08374, -1.86814, -2.07011, 1.03179}, {0.474478, -1.3203, 0.476947, 5.95751, 1.06335, -1.07336, 0.9893, 0.397365, -1.35371, 0.52206, 1.27739, 0.518977, -0.029771, 7.35132, -2.93958, -2.72541, -1.64251, 6.64587, -1.80933, 1.14081, 1.08374, -1.23179, 0.0530468, -1.23103, -0.278909, -6.25036, -3.15965, -1.86814, -2.07011, 1.03179}, {0.474478, -1.3203, 0.476947, -1.98584, -0.354449, 0.357788, -2.9679, -1.1921, 4.06113, 0.52206, 1.27739, 0.518977, 1.86814, 2.07011, -1.03179, 9.17514, 1.36475, -0.200121, -3.70724, 6.42202, -0.824048, -1.23179, 0.0530468, -1.23103, 1.80933, -1.14081, -1.08374, -3.95638, -7.17965, -1.04412}, {0.474478, -1.3203, 0.476947, -1.98584, -0.354449, 0.357788, 0.9893, 0.397365, -1.35371, -1.56618, -3.83216, -1.55693, 1.86814, 2.07011, -1.03179, 1.23179, -0.0530468, 1.23103, -1.80933, 1.14081, 1.08374, -3.1297, 5.33426, -3.13882, 9.75268, 0.276984, -2.51489, -5.82534, -3.65957, 6.44663}, {5.36656, 5.36656, -5.36656, 1.41539, 1.41492, 1.85814, -8.76436e-16, 3.15102, 8.55858e-15, 0.373467, -2.77708, -3.64699, -5.19992, -5.19747, -11.9405, -1.74951, -5.64381, -2.29678, 2.21115, -14.2878, -2.21115, 0.255645, 16.7521, 16.8847, -2.21115, 1.68373, 2.21115, -0.461631, -0.462209, 4.50793}, {-1.78885, -1.78885, 1.78885, -4.24616, -4.24476, -5.57441, 5.8429e-16, 3.15102, -5.70572e-15, 0.373467, -2.77708, -3.64699, 7.61705, 7.61763, -11.6633, -1.74951, -18.2479, -2.29678, 2.21115, -1.68373, -2.21115, 1.74951, 5.64381, 2.29678, -3.70501, 12.7921, 16.7991, -0.461631, -0.462209, 4.50793}, {-1.78885, -1.78885, 1.78885, 1.41539, 1.41492, 1.85814, 0, -9.45305, 0, 0.373467, -2.77708, -3.64699, 0.461631, 0.462209, -4.50793, -7.41106, -11.3035, -9.72932, 9.36656, 5.47169, -9.36656, 1.74951, 5.64381, 2.29678, -2.21115, 1.68373, 2.21115, -1.9555, 10.6461, 19.0959}, {-1.78885, -1.78885, 1.78885, 1.41539, 1.41492, 1.85814, -2.92145e-16, 3.15102, 2.85286e-15, -1.1204, 8.33125, 10.941, 0.461631, 0.462209, -4.50793, -1.74951, -5.64381, -2.29678, 2.21115, -1.68373, -2.21115, 8.90493, 12.7992, -4.85864, -7.87269, -3.97595, -5.2214, -0.461631, -13.0663, 4.50793}, {-4.34476, -0.77549, 0.782793, -0.00873736, -1.40655, 0.564008, -1.44688, -0.0374651, -0.914786, 0.00736434, 1.18552, 0.611709, -1.74439, 7.04528, -2.63065, 1.79924, 1.7849, 0.433585, 5.78582, -0.123349, 5.11241, -1.8287, -6.52698, -2.88042, 0.00169715, 0.27321, -1.45327, 1.77934, -1.41907, 0.374623}, {1.44825, 0.258497, -0.260931, 0.0262121, 4.21965, -1.69202, -1.44688, -0.0374651, -0.914786, 0.00736434, 1.18552, 0.611709, -7.57235, 0.385087, 0.669101, 7.58676, 1.93476, 4.09273, -0.00169715, -0.27321, 1.45327, -1.79924, -1.7849, -0.433585, -0.0277602, -4.46887, -3.9001, 1.77934, -1.41907, 0.374623}, {1.44825, 0.258497, -0.260931, -0.00873736, -1.40655, 0.564008, 4.34064, 0.112395, 2.74436, 0.00736434, 1.18552, 0.611709, -1.77934, 1.41907, -0.374623, 1.83419, 7.4111, -1.82245, -5.79471, -1.3072, 2.49699, -1.79924, -1.7849, -0.433585, 0.00169715, 0.27321, -1.45327, 1.74988, -6.16115, -2.07221}, {1.44825, 0.258497, -0.260931, -0.00873736, -1.40655, 0.564008, -1.44688, -0.0374651, -0.914786, -0.022093, -3.55656, -1.83513, -1.77934, 1.41907, -0.374623, 1.79924, 1.7849, 0.433585, -0.00169715, -0.27321, 1.45327, -7.59225, -2.81889, 0.610139, 0.0366466, 5.89941, -3.7093, 7.56686, -1.26921, 4.03377}, {-4.817, -8.88178e-16, -5.32907e-15, -1.78885, -1.78885, 1.78885, 0.373353, 0.374783, -3.64588, -0.190167, 1.41407, 1.85702, 7.38185, 9.36656, -9.36656, 1.74966, 1.74789, 2.29541, -3.93962, -1.96239, 19.0901, -0.988987, -7.40418, -9.72349, 2.4462, 0.463257, -4.50655, -0.226431, -2.21115, 2.21115}, {1.60567, 4.44089e-16, -4.88498e-15, 5.36656, 5.36656, -5.36656, 0.373353, 0.374783, -3.64588, -0.190167, 1.41407, 1.85702, -6.19624, 2.21115, -2.21115, 0.256242, 0.248757, 16.8789, -2.4462, -0.463257, 4.50655, -1.74966, -1.74789, -2.29541, 3.20687, -5.19303, -11.9346, -0.226431, -2.21115, 2.21115}, {1.60567, -2.22045e-16, 2.88658e-15, -1.78885, -1.78885, 1.78885, -1.12006, -1.12435, 10.9376, -0.190167, 1.41407, 1.85702, 0.226431, 2.21115, -2.21115, 8.90507, 8.90331, -4.86001, -8.86888, -0.463257, 4.50655, -1.74966, -1.74789, -2.29541, 2.4462, 0.463257, -4.50655, 0.534237, -7.86743, -5.21694}, {1.60567, 0, 2.22045e-16, -1.78885, -1.78885, 1.78885, 0.373353, 0.374783, -3.64588, 0.570501, -4.24221, -5.57107, 0.226431, 2.21115, -2.21115, 1.74966, 1.74789, 2.29541, -2.4462, -0.463257, 4.50655, -8.17233, -1.74789, -2.29541, 9.60162, 7.61867, -11.662, -1.71984, -3.71028, 16.7947}, {-5.36225, -5.36694, -5.37021, 0, -1.60567, 0, -0.373167, -0.373493, -3.64724, -1.41425, 0.190182, 1.85717, -2.20937, 6.19609, -2.21265, 0.46126, 2.44638, 4.50824, -0.25544, -0.255663, 16.8846, 5.19574, -3.20711, -11.9369, 1.74811, 1.74964, -2.29559, 2.20937, 0.226585, 2.21265}, {1.78742, 1.78898, 1.79007, 0, 4.817, 0, -0.373167, -0.373493, -3.64724, -1.41425, 0.190182, 1.85717, -9.35904, -7.3825, -9.37293, 1.95393, 3.94035, 19.0972, -1.74811, -1.74964, 2.29559, -0.46126, -2.44638, -4.50824, 7.40511, 0.988907, -9.72428, 2.20937, 0.226585, 2.21265}, {1.78742, 1.78898, 1.79007, 0, -1.60567, 0, 1.1195, 1.12048, 10.9417, -1.41425, 0.190182, 1.85717, -2.20937, -0.226585, -2.21265, 0.46126, 8.86905, 4.50824, -8.89778, -8.90555, -4.86469, -0.46126, -2.44638, -4.50824, 1.74811, 1.74964, -2.29559, 7.86637, -0.534145, -5.21604}, {1.78742, 1.78898, 1.79007, 0, -1.60567, 0, -0.373167, -0.373493, -3.64724, 4.24275, -0.570547, -5.57152, -2.20937, -0.226585, -2.21265, 0.46126, 2.44638, 4.50824, -1.74811, -1.74964, 2.29559, -7.61093, -9.60229, -11.6685, 1.74811, 8.17231, -2.29559, 3.70204, 1.72056, 16.8016}, {-0.829936, -0.831314, 3.98569, 1.1323, 1.13131, 1.13131, 0.168871, -1.43624, 0.169424, -1.57782, 0.027827, 0.027827, -6.27076, -6.26615, -4.28143, -1.60834, 0.376916, -1.6078, -1.22617, 7.17775, 0.755077, 7.9196, -0.488224, 1.49649, 0.550688, -1.43277, -1.43277, 1.74155, 1.7409, -0.243816}, {0.276645, 0.277105, -1.32856, -3.3969, -3.39394, -3.39394, 0.168871, -1.43624, 0.169424, -1.57782, 0.027827, 0.027827, -2.84813, -2.84932, 5.55807, -2.28382, 6.12189, -2.2855, -0.550688, 1.43277, 1.43277, 1.60834, -0.376916, 1.6078, 6.86195, -1.54408, -1.54408, 1.74155, 1.7409, -0.243816}, {0.276645, 0.277105, -1.32856, 1.1323, 1.13131, 1.13131, -0.506612, 4.30873, -0.508273, -1.57782, 0.027827, 0.027827, -1.74155, -1.7409, 0.243816, -6.13754, -4.14833, -6.13305, -1.65727, 0.324356, 6.74703, 1.60834, -0.376916, 1.6078, 0.550688, -1.43277, -1.43277, 8.05282, 1.62959, -0.355124}, {0.276645, 0.277105, -1.32856, 1.1323, 1.13131, 1.13131, 0.168871, -1.43624, 0.169424, 4.73345, -0.0834809, -0.0834809, -1.74155, -1.7409, 0.243816, -1.60834, 0.376916, -1.6078, -0.550688, 1.43277, 1.43277, 0.501756, -1.48534, 6.92205, -3.97852, -5.95802, -5.95802, 1.06607, 7.48587, -0.921513}, {-8.33162, 1.1204, 10.941, -1.41498, -1.41539, 1.85814, -3.15057, 0, 0, 1.78834, 1.78885, 1.78885, 3.97613, 7.87269, -5.2214, 5.64333, 1.74951, -2.29678, 13.0638, 0.461631, 4.50793, -12.7967, -8.90493, -4.85864, -0.461499, -0.461631, -4.50793, 1.6838, -2.21115, -2.21115}, {2.77721, -0.373467, -3.64699, 4.24495, 4.24616, -5.57441, -3.15057, 0, 0, 1.78834, 1.78885, 1.78885, -12.7926, 3.70501, 16.7991, 18.2456, 1.74951, -2.29678, 0.461499, 0.461631, 4.50793, -5.64333, -1.74951, 2.29678, -7.61487, -7.61705, -11.6633, 1.6838, -2.21115, -2.21115}, {2.77721, -0.373467, -3.64699, -1.41498, -1.41539, 1.85814, 9.4517, 0, 0, 1.78834, 1.78885, 1.78885, -1.6838, 2.21115, 2.21115, 11.3033, 7.41106, -9.72932, -10.6473, 1.9555, 19.0959, -5.64333, -1.74951, 2.29678, -0.461499, -0.461631, -4.50793, -5.46957, -9.36656, -9.36656}, {2.77721, -0.373467, -3.64699, -1.41498, -1.41539, 1.85814, -3.15057, 0, 0, -5.36503, -5.36656, -5.36656, -1.6838, 2.21115, 2.21115, 5.64333, 1.74951, -2.29678, 0.461499, 0.461631, 4.50793, -16.7522, -0.255645, 16.8847, 5.19843, 5.19992, -11.9405, 14.2861, -2.21115, -2.21115}, {-3.98391, -5.22497, -0.407969, 7.73451e-16, 7.92047e-17, 1.60567, 0.61239, -1.54296, -1.54296, -1.94036, -0.198701, -0.198701, -1.64146, -2.15281, -8.57548, -0.756955, 1.9072, -0.0775154, -4.84797, 5.92622, 7.91093, 8.51839, -1.1124, 0.87232, 2.39842, 0.245608, -1.73911, 1.64146, 2.15281, 2.15281}, {1.32797, 1.74166, 0.13599, -3.05267e-15, 1.60751e-15, -4.817, 0.61239, -1.54296, -1.54296, -1.94036, -0.198701, -0.198701, -6.95334, -9.11944, -2.69677, -3.20651, 8.07903, 6.09431, -2.39842, -0.245608, 1.73911, 0.756955, -1.9072, 0.0775154, 10.1599, 1.04041, -0.944303, 1.64146, 2.15281, 2.15281}, {1.32797, 1.74166, 0.13599, 0, 0, 1.60567, -1.83717, 4.62887, 4.62887, -1.94036, -0.198701, -0.198701, -1.64146, -2.15281, -2.15281, -0.756955, 1.9072, -6.50019, -7.71029, -7.21224, 1.19515, 0.756955, -1.9072, 0.0775154, 2.39842, 0.245608, -1.73911, 9.4029, 2.94761, 2.94761}, {1.32797, 1.74166, 0.13599, 7.73451e-16, 7.92047e-17, 1.60567, 0.61239, -1.54296, -1.54296, 5.82108, 0.596103, 0.596103, -1.64146, -2.15281, -2.15281, -0.756955, 1.9072, -0.0775154, -2.39842, -0.245608, 1.73911, -4.55492, -8.87383, -0.466443, 2.39842, 0.245608, -8.16178, -0.808098, 8.32463, 8.32463}, {0, 4.817, -8.88178e-16, -0.373167, -0.373493, 3.64724, -1.41425, 0.190182, -1.85717, 1.78742, 1.78898, -1.79007, 1.95393, 3.94035, -19.0972, 2.20937, 0.226585, -2.21265, 7.40511, 0.988907, 9.72428, -9.35904, -7.3825, 9.37293, -1.74811, -1.74964, -2.29559, -0.46126, -2.44638, 4.50824}, {0, -1.60567, -4.44089e-16, 1.1195, 1.12048, -10.9417, -1.41425, 0.190182, -1.85717, 1.78742, 1.78898, -1.79007, 0.46126, 8.86905, -4.50824, 7.86637, -0.534145, 5.21604, 1.74811, 1.74964, 2.29559, -2.20937, -0.226585, 2.21265, -8.89778, -8.90555, 4.86469, -0.46126, -2.44638, 4.50824}, {0, -1.60567, -4.44089e-16, -0.373167, -0.373493, 3.64724, 4.24275, -0.570547, 5.57152, 1.78742, 1.78898, -1.79007, 0.46126, 2.44638, -4.50824, 3.70204, 1.72056, -16.8016, 1.74811, 8.17231, 2.29559, -2.20937, -0.226585, 2.21265, -1.74811, -1.74964, -2.29559, -7.61093, -9.60229, 11.6685}, {-2.22045e-16, -1.60567, -4.44089e-16, -0.373167, -0.373493, 3.64724, -1.41425, 0.190182, -1.85717, -5.36225, -5.36694, 5.37021, 0.46126, 2.44638, -4.50824, 2.20937, 0.226585, -2.21265, 1.74811, 1.74964, 2.29559, -2.20937, 6.19609, 2.21265, -0.25544, -0.255663, -16.8846, 5.19574, -3.20711, 11.9369}, {5.57441, 0.570843, -4.24616, 0, 1.60567, 0, -1.78885, -1.78885, -1.78885, 3.64699, 0.373467, 0.373467, 2.29678, -8.17219, -1.74951, 2.21115, 0.226431, 2.21115, 11.6633, 9.60176, 7.61705, -16.7991, -1.7203, -3.70501, -4.50793, -2.44635, -0.461631, -2.29678, 1.74951, 1.74951}, {-1.85814, -0.190281, 1.41539, 6.50039e-15, -4.817, 2.58579e-15, -1.78885, -1.78885, -1.78885, 3.64699, 0.373467, 0.373467, 9.72932, -0.988391, -7.41106, 9.36656, 7.38185, 9.36656, 4.50793, 2.44635, 0.461631, -2.21115, -0.226431, -2.21115, -19.0959, -3.94022, -1.9555, -2.29678, 1.74951, 1.74951}, {-1.85814, -0.190281, 1.41539, -5.81494e-15, 1.60567, -5.95475e-16, 5.36656, 5.36656, 5.36656, 3.64699, 0.373467, 0.373467, 2.29678, -1.74951, -1.74951, 2.21115, -6.19624, 2.21115, 11.9405, 3.20747, -5.19992, -2.21115, -0.226431, -2.21115, -4.50793, -2.44635, -0.461631, -16.8847, 0.255645, 0.255645}, {-1.85814, -0.190281, 1.41539, 0, 1.60567, 0, -1.78885, -1.78885, -1.78885, -10.941, -1.1204, -1.1204, 2.29678, -1.74951, -1.74951, 2.21115, 0.226431, 2.21115, 4.50793, 2.44635, 0.461631, 5.2214, 0.534693, -7.87269, -4.50793, -8.86902, -0.461631, 4.85864, 8.90493, 8.90493}, {0.596103, -0.596103, -5.82108, 1.74166, -0.13599, -1.32797, -1.54296, 1.54296, -0.61239, 0, -1.60567, 0, -8.87383, 0.466443, 4.55492, -0.245608, -1.73911, 2.39842, 8.32463, -8.32463, 0.808098, 0.245608, 8.16178, -2.39842, -2.15281, 2.15281, 1.64146, 1.9072, 0.0775154, 0.756955}, {-0.198701, 0.198701, 1.94036, -5.22497, 0.407969, 3.98391, -1.54296, 1.54296, -0.61239, 0, -1.60567, 0, -1.1124, -0.87232, -8.51839, 5.92622, -7.91093, 4.84797, 2.15281, -2.15281, -1.64146, 0.245608, 1.73911, -2.39842, -2.15281, 8.57548, 1.64146, 1.9072, 0.0775154, 0.756955}, {-0.198701, 0.198701, 1.94036, 1.74166, -0.13599, -1.32797, 4.62887, -4.62887, 1.83717, 0, -1.60567, 0, -1.9072, -0.0775154, -0.756955, -7.21224, -1.19515, 7.71029, 2.94761, -2.94761, -9.4029, 0.245608, 1.73911, -2.39842, -2.15281, 2.15281, 1.64146, 1.9072, 6.50019, 0.756955}, {-0.198701, 0.198701, 1.94036, 1.74166, -0.13599, -1.32797, -1.54296, 1.54296, -0.61239, 0, 4.817, 0, -1.9072, -0.0775154, -0.756955, -0.245608, -1.73911, 2.39842, 2.15281, -2.15281, -1.64146, 1.04041, 0.944303, -10.1599, -9.11944, 2.69677, 6.95334, 8.07903, -6.09431, 3.20651}, {0, 9.45441, 0, 1.36222, 1.36261, 1.78885, -3.15057, 0, 0, 1.78834, 1.78885, -1.78885, -7.1327, -3.23931, -9.36656, 2.21051, -1.68428, -2.21115, 16.4966, 3.89543, 0, -9.36389, -5.47113, 9.36656, -3.89432, -3.89543, 0, 1.6838, -2.21115, 2.21115}, {0, -3.15147, 0, -4.08667, -4.08784, -5.36656, -3.15057, 0, 0, 1.78834, 1.78885, -1.78885, -1.6838, 14.817, -2.21115, 14.8128, -1.68428, -2.21115, 3.89432, 3.89543, 0, -2.21051, 1.68428, 2.21115, -11.0477, -11.0508, 7.15542, 1.6838, -2.21115, 2.21115}, {0, -3.15147, 0, 1.36222, 1.36261, 1.78885, 9.4517, 0, 0, 1.78834, 1.78885, -1.78885, -1.6838, 2.21115, -2.21115, -3.23838, -7.13474, -9.36656, 3.89432, 16.5013, 0, -2.21051, 1.68428, 2.21115, -3.89432, -3.89543, 0, -5.46957, -9.36656, 9.36656}, {4.44089e-16, -3.15147, 0, 1.36222, 1.36261, 1.78885, -3.15057, 0, 0, -5.36503, -5.36656, 5.36656, -1.6838, 2.21115, -2.21115, 2.21051, -1.68428, -2.21115, 3.89432, 3.89543, 0, -2.21051, 14.2902, 2.21115, -9.34321, -9.34589, -7.15542, 14.2861, -2.21115, 2.21115}, {2.5318e-16, -8.88178e-16, 5.41667, 1.44665, -1.44665, -0.51339, -1.44665, -0.572575, 0.978606, 1.97332e-12, 2.01922, 1.34034, -7.57474, 7.57474, 4.91993, 2.43894e-12, 2.4959, -0.575039, 7.57474, 2.99804, -2.89226, -1.03322e-11, -10.5728, -4.78632, -1.78815, -0.707741, -1.02217, 1.78815, -1.78815, -2.86637}, {-3.49928e-17, -4.44089e-16, -1.80556, -4.33994, 4.33994, 1.54017, -1.44665, -0.572575, 0.978606, 1.97112e-12, 2.01922, 1.34034, -1.78815, 1.78815, 10.0886, 5.78659, 4.7862, -4.48946, 1.78815, 0.707741, 1.02217, -2.43627e-12, -2.4959, 0.575039, -1.78815, -8.78463, -6.38352, 1.78815, -1.78815, -2.86637}, {-7.40514e-17, 0, -1.80556, 1.44665, -1.44665, -0.51339, 4.33994, 1.71772, -2.93582, 1.97094e-12, 2.01922, 1.34034, -1.78815, 1.78815, 2.86637, -5.78659, 8.28248, 1.47852, 1.78815, 0.707741, 8.24439, -2.43627e-12, -2.4959, 0.575039, -1.78815, -0.707741, -1.02217, 1.78815, -9.86504, -8.22773}, {-2.32423e-16, 0, -1.80556, 1.44665, -1.44665, -0.51339, -1.44665, -0.572575, 0.978606, -5.91996e-12, -6.05767, -4.02102, -1.78815, 1.78815, 2.86637, 2.43894e-12, 2.4959, -0.575039, 1.78815, 0.707741, 1.02217, -2.4389e-12, -2.4959, 7.79726, -7.57474, 5.07885, 1.03139, 7.57474, 0.502145, -6.7808}, {-1.83228, -4.62937, -4.62777, -1.94057, 0.198723, 0.200419, 1.32981, -1.74185, -0.13734, 0, 0, -1.60567, 9.40601, -2.94793, -2.95615, 0.754941, 1.90741, -0.0779689, -7.71791, 7.21302, -1.18762, -0.754941, -1.90741, 6.50064, 2.39867, -0.245635, 1.73698, -1.64373, 2.15304, 2.15448}, {0.61076, 1.54312, 1.54259, 5.82171, -0.596168, -0.601256, 1.32981, -1.74185, -0.13734, 0, 0, -1.60567, -0.799305, -8.32553, -8.32484, -4.5643, 8.87479, 0.471392, -2.39867, 0.245635, -1.73698, -0.754941, -1.90741, 0.0779689, 2.39867, -0.245635, 8.15966, -1.64373, 2.15304, 2.15448}, {0.61076, 1.54312, 1.54259, -1.94057, 0.198723, 0.200419, -3.98943, 5.22554, 0.412021, 0, 0, -1.60567, 1.64373, -2.15304, -2.15448, 8.51722, 1.11252, -0.879643, -4.84171, -5.92686, -7.90734, -0.754941, -1.90741, 0.0779689, 2.39867, -0.245635, 1.73698, -1.64373, 2.15304, 8.57715}, {0.61076, 1.54312, 1.54259, -1.94057, 0.198723, 0.200419, 1.32981, -1.74185, -0.13734, 0, 0, 4.817, 1.64373, -2.15304, -2.15448, 0.754941, 1.90741, -0.0779689, -2.39867, 0.245635, -1.73698, -3.19798, -8.0799, -6.09239, 10.1609, -1.04052, 0.93531, -6.96297, 9.12042, 2.70384}, {-5.36656, 5.36656, -5.36656, 0, 0, -3.15147, -0.373467, 3.64699, 2.778, -1.41539, -1.85814, -1.41539, -2.21115, 2.21115, 14.2902, 0.461631, -4.50793, 0.461631, -0.255645, -16.8847, -16.7569, 5.19992, 11.9405, 5.19992, 1.74951, 2.29678, 5.64494, 2.21115, -2.21115, -1.68428}, {1.78885, -1.78885, 1.78885, 0, 0, 9.45441, -0.373467, 3.64699, 2.778, -1.41539, -1.85814, -1.41539, -9.36656, 9.36656, -5.47113, 1.9555, -19.0959, -10.6504, -1.74951, -2.29678, -5.64494, -0.461631, 4.50793, -0.461631, 7.41106, 9.72932, 11.3065, 2.21115, -2.21115, -1.68428}, {1.78885, -1.78885, 1.78885, 0, 0, -3.15147, 1.1204, -10.941, -8.334, -1.41539, -1.85814, -1.41539, -2.21115, 2.21115, 1.68428, 0.461631, -4.50793, 13.0675, -8.90493, 4.85864, -12.8004, -0.461631, 4.50793, -0.461631, 1.74951, 2.29678, 5.64494, 7.87269, 5.2214, 3.97726}, {1.78885, -1.78885, 1.78885, 0, 0, -3.15147, -0.373467, 3.64699, 2.778, 4.24616, 5.57441, 4.24616, -2.21115, 2.21115, 1.68428, 0.461631, -4.50793, 0.461631, -1.74951, -2.29678, -5.64494, -7.61705, 11.6633, -7.61705, 1.74951, 2.29678, 18.2508, 3.70501, -16.7991, -12.7963}, {1.64026, -3.9353, -3.84492e-12, 0.194118, -2.3555e-16, -1.44665, -0.509273, -1.31177, -1.28166e-12, 0.861908, 2.3555e-16, 1.44665, -0.34059, -1.62143, 7.57474, 0.389553, 1.62143, 1.78815, 3.34241, 5.24706, 5.12657e-12, -3.83718, -1.62143, -7.57474, -1.30532, 0, 0, -0.435881, 1.62143, -1.78815}, {-0.546753, 1.31177, 1.28098e-12, -0.582353, -4.00737e-16, 4.33994, -0.509273, -1.31177, -1.28097e-12, 0.861908, -4.76051e-17, 1.44665, 2.62289, -6.86849, 1.78815, 2.42664, 6.86849, 1.78815, 1.30532, -8.70681e-16, 0, -0.389553, -1.62143, -1.78815, -4.75295, 8.41511e-17, -5.78659, -0.435881, 1.62143, -1.78815}, {-0.546753, 1.31177, 1.28164e-12, 0.194118, -6.32145e-17, -1.44665, 1.52782, 3.9353, 3.84498e-12, 0.861908, -2.8068e-16, 1.44665, 0.435881, -1.62143, 1.78815, -0.386918, 1.62143, 7.57474, 3.49233, -5.24706, -5.12657e-12, -0.389553, -1.62143, -1.78815, -1.30532, 4.25078e-16, 0, -3.88351, 1.62143, -7.57474}, {-0.546753, 1.31177, 1.28098e-12, 0.194118, 0, -1.44665, -0.509273, -1.31177, -1.28097e-12, -2.58572, 0, -4.33994, 0.435881, -1.62143, 1.78815, 0.389553, 1.62143, 1.78815, 1.30532, -9.76951e-16, 0, 1.79746, -6.86849, -1.78815, -2.08179, 0, 5.78659, 1.60121, 6.86849, -1.78815}, {0.831641, 5.95736e-16, -6.19774, -0.482067, 1.31177, -0.482067, -0.449021, -1.31177, -0.449021, 1.2083, 1.98579e-16, -1.13482, 2.86679, -6.86849, -0.0294728, 1.15089, 0, 1.15089, 2.69376, 6.86849, -0.202503, -5.98409, -7.94315e-16, 3.38841, -0.897675, -1.62143, 1.99859, -0.938522, 1.62143, 1.95774}, {-0.277214, 0, 2.06591, 1.4462, -3.9353, 1.4462, -0.449021, -1.31177, -0.449021, 1.2083, 0, -1.13482, 2.04738, -1.62143, -10.2214, 2.94697, 5.24706, 2.94697, 0.897675, 1.62143, -1.99859, -1.15089, 0, -1.15089, -5.73088, -1.62143, 6.53788, -0.938522, 1.62143, 1.95774}, {-0.277214, 1.98579e-16, 2.06591, -0.482067, 1.31177, -0.482067, 1.34706, 3.9353, 1.34706, 1.2083, -1.98579e-16, -1.13482, 0.938522, -1.62143, -1.95774, 3.07916, -5.24706, 3.07916, 2.00653, 1.62143, -10.2622, -1.15089, -1.47894e-31, -1.15089, -0.897675, -1.62143, 1.99859, -5.77173, 1.62143, 6.49704}, {-0.277214, 0, 2.06591, -0.482067, 1.31177, -0.482067, -0.449021, -1.31177, -0.449021, -3.6249, 0, 3.40447, 0.938522, -1.62143, -1.95774, 1.15089, 0, 1.15089, 0.897675, 1.62143, -1.99859, -0.0420334, 0, -9.41454, 1.03059, -6.86849, 3.92685, 0.857562, 6.86849, 3.75382}, {10.941, -1.1204, -8.334, 1.78885, -1.78885, 1.78885, 1.85814, 1.41539, -1.41539, 0, 0, -3.15147, -4.85864, 8.90493, -12.8004, -4.50793, 0.461631, -0.461631, -5.2214, -7.87269, 3.97726, 4.50793, -0.461631, 13.0675, -2.21115, 2.21115, 1.68428, -2.29678, -1.74951, 5.64494}, {-3.64699, 0.373467, 2.778, -5.36656, 5.36656, -5.36656, 1.85814, 1.41539, -1.41539, 0, 0, -3.15147, 16.8847, 0.255645, -16.7569, -11.9405, -5.19992, 5.19992, 2.21115, -2.21115, -1.68428, 4.50793, -0.461631, 0.461631, -2.21115, 2.21115, 14.2902, -2.29678, -1.74951, 5.64494}, {-3.64699, 0.373467, 2.778, 1.78885, -1.78885, 1.78885, -5.57441, -4.24616, 4.24616, 0, 0, -3.15147, 2.29678, 1.74951, -5.64494, -11.6633, 7.61705, -7.61705, 16.7991, -3.70501, -12.7963, 4.50793, -0.461631, 0.461631, -2.21115, 2.21115, 1.68428, -2.29678, -1.74951, 18.2508}, {-3.64699, 0.373467, 2.778, 1.78885, -1.78885, 1.78885, 1.85814, 1.41539, -1.41539, 0, 0, 9.45441, 2.29678, 1.74951, -5.64494, -4.50793, 0.461631, -0.461631, 2.21115, -2.21115, -1.68428, 19.0959, -1.9555, -10.6504, -9.36656, 9.36656, -5.47113, -9.72932, -7.41106, 11.3065}, {0, 0, 9.45441, 1.78885, 1.78885, 1.78885, 1.36261, -1.78885, 1.36261, -3.15147, 0, 0, -9.36656, -9.36656, -5.47113, -3.89543, 0, -3.89543, -7.13474, 9.36656, -3.23931, 16.5013, 0, 3.89543, 1.68428, -2.21115, -2.21115, 2.21115, 2.21115, -1.68428}, {0, 0, -3.15147, -5.36656, -5.36656, -5.36656, 1.36261, -1.78885, 1.36261, -3.15147, 0, 0, -2.21115, -2.21115, 14.2902, -9.34589, 7.15542, -9.34589, -1.68428, 2.21115, 2.21115, 3.89543, 0, 3.89543, 14.2902, -2.21115, -2.21115, 2.21115, 2.21115, -1.68428}, {4.44089e-16, 0, -3.15147, 1.78885, 1.78885, 1.78885, -4.08784, 5.36656, -4.08784, -3.15147, 0, 0, -2.21115, -2.21115, 1.68428, -11.0508, -7.15542, -11.0508, -1.68428, 2.21115, 14.817, 3.89543, 0, 3.89543, 1.68428, -2.21115, -2.21115, 14.817, 2.21115, -1.68428}, {0, 0, -3.15147, 1.78885, 1.78885, 1.78885, 1.36261, -1.78885, 1.36261, 9.45441, 0, 0, -2.21115, -2.21115, 1.68428, -3.89543, 0, -3.89543, -1.68428, 2.21115, 2.21115, 3.89543, 0, 16.5013, -5.47113, -9.36656, -9.36656, -3.23931, 9.36656, -7.13474}, {5.22884, -3.98763, -5.22319, 0.200328, -1.9397, -2.54071, 8.97324e-16, 3.55112e-16, 2.34313, 1.54262, 0.610485, -1.54348, 1.10547, 8.51339, 11.1512, -0.24762, 2.3976, 0.244222, 2.1544, -1.643, -14.4208, -5.92285, -4.83954, 5.92971, -2.1544, 1.643, 5.04833, -1.90678, -0.754601, -0.988412}, {-1.74295, 1.32921, 1.74106, -0.600985, 5.81909, 7.62212, -1.79465e-15, -7.10225e-16, 2.34313, 1.54262, 0.610485, -1.54348, 8.87857, -4.56224, -5.97584, -0.24762, 2.3976, -9.12828, 2.1544, -1.643, -5.04833, 0.24762, -2.3976, -0.244222, -8.32487, -0.798945, 11.2223, -1.90678, -0.754601, -0.988412}, {-1.74295, 1.32921, 1.74106, 0.200328, -1.9397, -2.54071, 0, 0, -7.02938, 1.54262, 0.610485, -1.54348, 1.90678, 0.754601, 0.988412, -1.04893, 10.1564, 10.407, 9.12619, -6.95984, -12.0126, 0.24762, -2.3976, -0.244222, -2.1544, 1.643, 5.04833, -8.07725, -3.19654, 5.18552}, {-1.74295, 1.32921, 1.74106, 0.200328, -1.9397, -2.54071, -8.97324e-16, -3.55112e-16, 2.34313, -4.62785, -1.83146, 4.63045, 1.90678, 0.754601, 0.988412, -0.24762, 2.3976, 0.244222, 2.1544, -1.643, -5.04833, 7.21941, -7.71444, -7.20847, -2.95571, 9.40178, 15.2112, -1.90678, -0.754601, -10.3609}, {0.403167, 4.33994, -4.33994, 1.56712, 1.12319e-15, -3.41061e-16, -0.345916, 1.4404, 0.569981, -1.08682, 0.00624416, -2.01663, -8.03944, 1.78815, -1.78815, -1.50949, -1.78044, -0.704535, 1.97736, -5.75389, -4.77261, 5.85676, 1.75546, 8.77105, -0.59369, -0.00771821, 2.49269, 1.77095, -1.78815, 1.78815}, {-0.134389, -1.44665, 1.44665, -4.70136, -1.67385e-15, -3.01891e-15, -0.345916, 1.4404, 0.569981, -1.08682, 0.00624416, -2.01663, -1.2334, 7.57474, -7.57474, -0.125826, -7.54205, -2.98446, 0.59369, 0.00771821, -2.49269, 1.50949, 1.78044, 0.704535, 3.75357, -0.0326948, 10.5592, 1.77095, -1.78815, 1.78815}, {-0.134389, -1.44665, 1.44665, 1.56712, 0, 0, 1.03775, -4.32121, -1.70994, -1.08682, 0.00624416, -2.01663, -1.77095, 1.78815, -1.78815, -7.77798, -1.78044, -0.704535, 1.13125, 5.79431, -8.27928, 1.50949, 1.78044, 0.704535, -0.59369, -0.00771821, 2.49269, 6.11822, -1.81313, 9.85467}, {-0.134389, -1.44665, 1.44665, 1.56712, 2.42925e-18, -7.84555e-16, -0.345916, 1.4404, 0.569981, 3.26045, -0.0187325, 6.04988, -1.77095, 1.78815, -1.78815, -1.50949, -1.78044, -0.704535, 0.59369, 0.00771821, -2.49269, 2.04705, 7.56702, -5.08205, -6.86218, -0.00771821, 2.49269, 3.15462, -7.54977, -0.491769}, {-7.02938, 5.36656, -7.02938, -2.34313, 0, 0, 0, 0, -2.34313, 1.02097e-11, 1.78885, 1.02102e-11, 9.3725, 2.21115, -2.89626, 2.89626, 0, 2.89626, -2.89626, 2.21115, 9.3725, -2.89626, -7.15542, -2.89626, 2.89626, -2.21115, -1.26205e-11, -1.26199e-11, -2.21115, 2.89626}, {2.34313, -1.78885, 2.34313, 7.02938, 0, 0, 0, 0, -2.34313, 1.02086e-11, 1.78885, 1.02076e-11, -9.3725, 9.36656, -12.2688, 2.89626, 0, 12.2688, -2.89626, 2.21115, 1.26155e-11, -2.89626, 1.33227e-15, -2.89626, 2.89626, -9.36656, -5.34477e-11, -1.26186e-11, -2.21115, 2.89626}, {2.34313, -1.78885, 2.34313, -2.34313, 0, 0, 0, 0, 7.02938, 1.0206e-11, 1.78885, 1.02081e-11, 1.26136e-11, 2.21115, -2.89626, 12.2688, 0, 2.89626, -12.2688, 9.36656, -9.3725, -2.89626, 1.33227e-15, -2.89626, 2.89626, -2.21115, -1.26179e-11, -5.34395e-11, -9.36656, 2.89626}, {2.34313, -1.78885, 2.34313, -2.34313, 0, 0, 0, 0, -2.34313, -3.06361e-11, -5.36656, -3.06329e-11, 1.2621e-11, 2.21115, -2.89626, 2.89626, 0, 2.89626, -2.89626, 2.21115, 1.26197e-11, -12.2688, 7.15542, -12.2688, 12.2688, -2.21115, -1.26215e-11, -1.26228e-11, -2.21115, 12.2688}, {7.02938, 1.77636e-15, 4.56849e-16, 2.34566, -1.78885, -2.34313, -1.47457e-18, 1.04056e-15, 2.34313, -0.00253498, 1.78885, -1.02092e-11, -9.38578, 9.36656, 12.2688, -2.8994, 2.21115, -1.26197e-11, 2.89626, -4.88498e-15, -12.2688, 2.90954, -9.36656, 5.34563e-11, -2.89626, 8.88178e-16, 2.89626, 0.00313341, -2.21115, -2.89626}, {-2.34313, -2.22045e-16, -2.19983e-16, -7.03698, 5.36656, 7.02938, 2.94914e-18, -2.08111e-15, 2.34313, -0.00253498, 1.78885, -1.02107e-11, 9.36937, 2.21115, 2.89626, -2.8994, 2.21115, -9.3725, 2.89626, 3.10862e-15, -2.89626, 2.8994, -2.21115, 1.26215e-11, -2.88612, -7.15542, 2.89626, 0.00313341, -2.21115, -2.89626}, {-2.34313, 0, 7.30909e-16, 2.34566, -1.78885, -2.34313, 0, 0, -7.02938, -0.00253498, 1.78885, -1.02081e-11, -0.00313341, 2.21115, 2.89626, -12.282, 9.36656, 9.3725, 12.2688, 0, -2.89626, 2.8994, -2.21115, 1.26179e-11, -2.89626, 0, 2.89626, 0.0132733, -9.36656, -2.89626}, {-2.34313, 0, 4.83989e-16, 2.34566, -1.78885, -2.34313, 1.47457e-18, -1.04056e-15, 2.34313, 0.00760494, -5.36656, 3.06329e-11, -0.00313341, 2.21115, 2.89626, -2.8994, 2.21115, -1.2621e-11, 2.89626, 1.33227e-15, -2.89626, 12.2719, -2.21115, 1.26191e-11, -12.2789, 7.15542, 12.2688, 0.00313341, -2.21115, -12.2688}, {5.3029, -0.485897, 0.486322, 0.215713, 1.38996, 0.214498, 0.501223, -0.501223, -1.10401, 1.0507, -1.0507, 1.05162, 1.05543, -7.4781, -0.922752, -0.886182, -1.09853, 1.09949, -0.439523, 2.42424, 5.98103, -3.31661, 5.30132, -5.30596, -1.56537, -0.419345, -1.565, -1.91828, 1.91828, 0.0647586}, {-1.76763, 0.161966, -0.162107, -0.647139, -4.16987, -0.643495, 0.501223, -0.501223, -1.10401, 1.0507, -1.0507, 1.05162, 8.98882, -2.56614, 0.583671, -2.89107, 0.90636, 5.51552, 1.56537, 0.419345, 1.565, 0.886182, 1.09853, -1.09949, -5.76816, 3.78345, -5.77147, -1.91828, 1.91828, 0.0647586}, {-1.76763, 0.161966, -0.162107, 0.215713, 1.38996, 0.214498, -1.50367, 1.50367, 3.31202, 1.0507, -1.0507, 1.05162, 1.91828, -1.91828, -0.0647586, -1.74903, -6.65835, 0.2415, 8.63591, -0.228518, 2.21343, 0.886182, 1.09853, -1.09949, -1.56537, -0.419345, -1.565, -6.12107, 6.12107, -4.14171}, {-1.76763, 0.161966, -0.162107, 0.215713, 1.38996, 0.214498, 0.501223, -0.501223, -1.10401, -3.15209, 3.15209, -3.15485, 1.91828, -1.91828, -0.0647586, -0.886182, -1.09853, 1.09949, 1.56537, 0.419345, 1.565, 7.95672, 0.45067, -0.451064, -2.42822, -5.97917, -2.423, -3.92317, 3.92317, 4.48079}, {1.71308, 4.3282, 0.488804, 0.642112, 1.62234, -1.62234, 2.1437, 0.314496, -0.314496, -2.21478, -0.4941, 2.09977, -2.65632, -6.71135, 8.69607, -3.44345, -2.39406, 2.39406, -10.5187, 0.136594, 1.84812, 12.3026, 4.37046, -10.7931, 1.94393, -1.39458, -0.590137, 0.0878675, 0.222003, -2.20672}, {-0.571026, -1.44273, -0.162935, -1.92634, -4.86701, 4.86701, 2.1437, 0.314496, -0.314496, -2.21478, -0.4941, 2.09977, 2.19624, 5.54893, 2.85846, -12.0182, -3.65204, 3.65204, -1.94393, 1.39458, 0.590137, 3.44345, 2.39406, -2.39406, 10.8031, 0.581823, -8.98921, 0.0878675, 0.222003, -2.20672}, {-0.571026, -1.44273, -0.162935, 0.642112, 1.62234, -1.62234, -6.43109, -0.943488, 0.943488, -2.21478, -0.4941, 2.09977, -0.0878675, -0.222003, 2.20672, -6.0119, -8.88341, 8.88341, 0.340174, 7.16551, 1.24188, 3.44345, 2.39406, -2.39406, 1.94393, -1.39458, -0.590137, 8.947, 2.1984, -10.6058}, {-0.571026, -1.44273, -0.162935, 0.642112, 1.62234, -1.62234, 2.1437, 0.314496, -0.314496, 6.64435, 1.4823, -6.2993, -0.0878675, -0.222003, 2.20672, -3.44345, -2.39406, 2.39406, -1.94393, 1.39458, 0.590137, 5.72755, 8.16499, -1.74232, -0.624519, -7.88393, 5.89921, -8.48692, -1.03598, -0.948734}, {-4.62937, 4.62937, 1.83228, 0.198723, -0.198723, 1.94057, -1.74185, 0.136178, -1.32981, 0, 1.60567, 0, -2.94793, 2.94793, -9.40601, 1.90741, 0.0773091, -0.754941, 7.21302, 1.19437, 7.71791, -1.90741, -6.49998, 0.754941, -0.245635, -1.73908, -2.39867, 2.15304, -2.15304, 1.64373}, {1.54312, -1.54312, -0.61076, -0.596168, 0.596168, -5.82171, -1.74185, 0.136178, -1.32981, -6.94322e-16, 1.60567, -5.30079e-16, -8.32553, 8.32553, 0.799305, 8.87479, -0.467403, 4.5643, 0.245635, 1.73908, 2.39867, -1.90741, -0.0773091, 0.754941, -0.245635, -8.16175, -2.39867, 2.15304, -2.15304, 1.64373}, {1.54312, -1.54312, -0.61076, 0.198723, -0.198723, 1.94057, 5.22554, -0.408534, 3.98943, 0, 1.60567, 0, -2.15304, 2.15304, -1.64373, 1.11252, 0.872199, -8.51722, -5.92686, 7.91157, 4.84171, -1.90741, -0.0773091, 0.754941, -0.245635, -1.73908, -2.39867, 2.15304, -8.57571, 1.64373}, {1.54312, -1.54312, -0.61076, 0.198723, -0.198723, 1.94057, -1.74185, 0.136178, -1.32981, 0, -4.817, 0, -2.15304, 2.15304, -1.64373, 1.90741, 0.0773091, -0.754941, 0.245635, 1.73908, 2.39867, -8.0799, 6.09519, 3.19798, -1.04052, -0.94419, -10.1609, 9.12042, -2.69775, 6.96297}, {-1.38621, 0, 3.9353, 1.09414, 1.31177, 1.31177, 0.173581, -1.31177, 0, -1.72979, 0, 0, -6.30013, -6.86849, -5.24706, -1.56699, 0, -1.62143, -1.48003, 6.86849, 1.62143, 8.48614, 0, 1.62143, 0.785706, -1.62143, -1.62143, 1.92358, 1.62143, 0}, {0.462069, 6.22914e-16, -1.31177, -3.28242, -3.9353, -3.9353, 0.173581, -1.31177, 5.65267e-17, -1.72979, -8.44959e-16, -5.63306e-16, -3.77185, -1.62143, 5.24706, -2.26131, 5.24706, -1.62143, -0.785706, 1.62143, 1.62143, 1.56699, 2.22045e-16, 1.62143, 7.70486, -1.62143, -1.62143, 1.92358, 1.62143, 6.26414e-16}, {0.462069, -1.0074e-15, -1.31177, 1.09414, 1.31177, 1.31177, -0.520744, 3.9353, 0, -1.72979, 5.63306e-16, 0, -1.92358, -1.62143, 9.76951e-16, -5.94354, -5.24706, -6.86849, -2.63398, 1.62143, 6.86849, 1.56699, 4.44089e-16, 1.62143, 0.785706, -1.62143, -1.62143, 8.84273, 1.62143, 0}, {0.462069, 0, -1.31177, 1.09414, 1.31177, 1.31177, 0.173581, -1.31177, 0, 5.18937, 0, 0, -1.92358, -1.62143, 9.76951e-16, -1.56699, 0, -1.62143, -0.785706, 1.62143, 1.62143, -0.281287, 0, 6.86849, -3.59085, -6.86849, -6.86849, 1.22925, 6.86849, 0}, {-3.84581e-12, -3.9353, 2.80446, 1.44665, -7.27633e-17, 0.44688, -1.28195e-12, -1.31177, -0.870737, -1.44665, -2.21227e-16, 1.35868, -7.57474, -1.62143, -1.18439, -1.78815, 1.62143, 0.523916, 5.12768e-12, 5.24706, 5.71474, 7.57474, -1.62143, -5.95862, 0, 3.63391e-16, -2.23179, 1.78815, 1.62143, -0.603126}, {1.28142e-12, 1.31177, -0.934819, -4.33994, -5.97507e-16, -1.34064, -1.28135e-12, -1.31177, -0.870737, -1.44665, -3.46164e-16, 1.35868, -1.78815, -6.86849, 4.3424, -1.78815, 6.86849, 4.00686, 0, -1.15865e-15, 2.23179, 1.78815, -1.62143, -0.523916, 5.78659, 1.56635e-15, -7.66649, 1.78815, 1.62143, -0.603126}, {1.28164e-12, 1.31177, -0.934819, 1.44665, -5.43864e-16, 0.44688, 3.84263e-12, 3.9353, 2.61221, -1.44665, 2.49874e-16, 1.35868, -1.78815, -1.62143, 0.603126, -7.57474, 1.62143, -1.2636, -5.12657e-12, -5.24706, 5.97107, 1.78815, -1.62143, -0.523916, 6.66134e-16, 3.63391e-16, -2.23179, 7.57474, 1.62143, -6.03783}, {1.28142e-12, 1.31177, -0.934819, 1.44665, 0, 0.44688, -1.28147e-12, -1.31177, -0.870737, 4.33994, 0, -4.07603, -1.78815, -1.62143, 0.603126, -1.78815, 1.62143, 0.523916, 0, -9.76951e-16, 2.23179, 1.78815, -6.86849, 3.21536, -5.78659, 0, -4.01931, 1.78815, 6.86849, 2.87982}, {5.36291, -5.36619, -5.37088, 3.64451, -0.373213, -0.376399, -1.85687, 0.190152, -1.41389, 0, -1.60567, 0, -16.8733, -0.256821, -0.242074, -2.20964, 0.226277, 2.21292, 11.9323, -3.20664, 5.19032, 2.20964, 6.1964, -2.21292, -4.50486, 2.44603, 0.465254, 2.29522, 1.74967, 1.74767}, {-1.78764, 1.78873, 1.79029, -10.9335, 1.11964, 1.1292, -1.85687, 0.190152, -1.41389, 0, -1.60567, 0, 4.85533, -8.90459, -8.90884, 5.21784, -0.53433, 7.8685, 4.50486, -2.44603, -0.465254, 2.20964, -0.226277, -2.21292, -4.50486, 8.8687, 0.465254, 2.29522, 1.74967, 1.74767}, {-1.78764, 1.78873, 1.79029, 3.64451, -0.373213, -0.376399, 5.57061, -0.570455, 4.24168, 0, -1.60567, 0, -2.29522, -1.74967, -1.74767, -16.7877, 1.71913, 3.71852, 11.6554, -9.60095, -7.62642, 2.20964, -0.226277, -2.21292, -4.50486, 2.44603, 0.465254, 2.29522, 8.17235, 1.74767}, {-1.78764, 1.78873, 1.79029, 3.64451, -0.373213, -0.376399, -1.85687, 0.190152, -1.41389, 0, 4.817, 0, -2.29522, -1.74967, -1.74767, -2.20964, 0.226277, 2.21292, 4.50486, -2.44603, -0.465254, 9.36019, -7.3812, -9.37409, -19.0829, 3.93889, 1.97085, 9.72271, 0.989068, 7.40324}, {-4.90664, -4.91093, -4.90664, 0.802238, -0.802728, -0.80343, -1.63555, -0.0313083, -1.63555, -0.802238, -0.80294, 0.80343, -6.22222, 2.17973, 2.18516, 1.03003, 1.03093, 3.01474, 6.54219, -1.85948, 6.54219, 2.17893, 2.18083, -6.22846, -3.77476e-14, 1.98471, 3.78586e-14, 3.01327, 1.03119, 1.02855}, {1.63555, 1.63698, 1.63555, -2.40672, 2.40819, 2.41029, -1.63555, -0.0313083, -1.63555, -0.802238, -0.80294, 0.80343, -9.55546, -7.57909, -7.57074, 7.57221, 1.15616, 9.55693, 3.60822e-14, -1.98471, -3.85247e-14, -1.03003, -1.03093, -3.01474, 3.20895, 5.19647, -3.21372, 3.01327, 1.03119, 1.02855}, {1.63555, 1.63698, 1.63555, 0.802238, -0.802728, -0.80343, 4.90664, 0.0939249, 4.90664, -0.802238, -0.80294, 0.80343, -3.01327, -1.03119, -1.02855, -2.17893, 4.24184, 6.22846, -6.54219, -8.53262, -6.54219, -1.03003, -1.03093, -3.01474, -3.77476e-14, 1.98471, 3.78586e-14, 6.22222, 4.24295, -2.18516}, {1.63555, 1.63698, 1.63555, 0.802238, -0.802728, -0.80343, -1.63555, -0.0313083, -1.63555, 2.40672, 2.40882, -2.41029, -3.01327, -1.03119, -1.02855, 1.03003, 1.03093, 3.01474, 3.68594e-14, -1.98471, -3.94129e-14, -7.57221, -7.57883, -9.55693, -3.20895, 5.19563, 3.21372, 9.55546, 1.15642, 7.57074}, {0.433524, 4.35281, -4.30748, -1.58383, 1.03002, -2.49725, 0.961132, -0.582294, -1.46836, 0.767201, 1.00321, 2.52978, 8.47164, -3.5998, 11.301, 0.769691, -0.553419, 4.90175, -4.85393, 4.84239, 5.91364, -3.83849, -3.45943, -15.0209, 1.0094, -2.51321, -0.0402101, -2.13634, -0.520284, -1.31199}, {-0.144508, -1.45094, 1.43583, 4.75148, -3.09006, 7.49174, 0.961132, -0.582294, -1.46836, 0.767201, 1.00321, 2.52978, 2.71437, 6.32404, -4.43132, -3.07484, 1.77576, 10.7752, -1.0094, 2.51321, 0.0402101, -0.769691, 0.553419, -4.90175, -2.0594, -6.52607, -10.1593, -2.13634, -0.520284, -1.31199}, {-0.144508, -1.45094, 1.43583, -1.58383, 1.03002, -2.49725, -2.8834, 1.74688, 4.40507, 0.767201, 1.00321, 2.52978, 2.13634, 0.520284, 1.31199, 7.10499, -4.6735, 14.8907, -0.431372, 8.31697, -5.70309, -0.769691, 0.553419, -4.90175, 1.0094, -2.51321, -0.0402101, -5.20514, -4.53314, -11.4311}, {-0.144508, -1.45094, 1.43583, -1.58383, 1.03002, -2.49725, 0.961132, -0.582294, -1.46836, -2.3016, -3.00964, -7.58933, 2.13634, 0.520284, 1.31199, 0.769691, -0.553419, 4.90175, -1.0094, 2.51321, 0.0402101, -0.191659, 6.35717, -10.6451, 7.3447, -6.63329, 9.94877, -5.98087, 1.80889, 4.56144}, {-5.22554, 3.98943, -3.78662, 0, 0, -1.80556, -0.198723, 1.94057, 0.386742, -1.54312, -0.61076, 0.156608, -2.15304, 1.64373, 7.89384, 0.245635, -2.39867, 1.75375, -1.11252, -8.51722, -3.58518, 5.92686, 4.84171, -2.38018, 1.90741, 0.754941, 2.03821, 2.15304, -1.64373, -0.671617}, {1.74185, -1.32981, 1.26221, 0, 0, 5.41667, -0.198723, 1.94057, 0.386742, -1.54312, -0.61076, 0.156608, -9.12042, 6.96297, -4.37721, 1.04052, -10.1609, 0.206785, -1.90741, -0.754941, -2.03821, -0.245635, 2.39867, -1.75375, 8.0799, 3.19798, 1.41178, 2.15304, -1.64373, -0.671617}, {1.74185, -1.32981, 1.26221, 0, 0, -1.80556, 0.596168, -5.82171, -1.16022, -1.54312, -0.61076, 0.156608, -2.15304, 1.64373, 0.671617, 0.245635, -2.39867, 8.97597, -8.87479, 4.5643, -7.08704, -0.245635, 2.39867, -1.75375, 1.90741, 0.754941, 2.03821, 8.32553, 0.799305, -1.29805}, {1.74185, -1.32981, 1.26221, 0, 0, -1.80556, -0.198723, 1.94057, 0.386742, 4.62937, 1.83228, -0.469823, -2.15304, 1.64373, 0.671617, 0.245635, -2.39867, 1.75375, -1.90741, -0.754941, -2.03821, -7.21302, 7.71791, -6.80258, 1.90741, 0.754941, 9.26043, 2.94793, -9.40601, -2.21858}, {2.47366, -6.0686, -0.0191747, -0.141226, -1.44665, 1.44665, 1.40644, 1.00594e-16, 2.53667e-16, -0.440661, -0.57622, -1.45304, 1.75867, 5.07434, -7.58264, -1.56389, 1.78815, -1.78815, -6.34501, -2.5004, -0.0079004, 3.32653, 0.516725, 7.60031, 0.719252, 2.5004, 0.0079004, -1.19377, 0.712247, 1.79605}, {-0.824552, 2.02287, 0.00639156, 0.423679, 4.33994, -4.33994, 1.40644, -1.00594e-16, -2.53667e-16, -0.440661, -0.57622, -1.45304, 4.49197, -8.80371, -1.82162, -7.18964, 1.78815, -1.78815, -0.719252, -2.5004, -0.0079004, 1.56389, -1.78815, 1.78815, 2.48189, 4.80528, 5.82005, -1.19377, 0.712247, 1.79605}, {-0.824552, 2.02287, 0.00639156, -0.141226, -1.44665, 1.44665, -4.21932, 0, 0, -0.440661, -0.57622, -1.45304, 1.19377, -0.712247, -1.79605, -0.998983, 7.57474, -7.57474, 2.57896, -10.5919, -0.0334666, 1.56389, -1.78815, 1.78815, 0.719252, 2.5004, 0.0079004, 0.568875, 3.01713, 7.60821}, {-0.824552, 2.02287, 0.00639156, -0.141226, -1.44665, 1.44665, 1.40644, 1.00594e-16, 2.53667e-16, 1.32198, 1.72866, 4.35912, 1.19377, -0.712247, -1.79605, -1.56389, 1.78815, -1.78815, -0.719252, -2.5004, -0.0079004, 4.8621, -9.87962, 1.76259, 1.28416, 8.28699, -5.77869, -6.81952, 0.712247, 1.79605}, {-5.82171, -0.596168, -7.61729, 0, 0, -2.34313, -0.61076, 1.54312, 1.54399, -1.32981, -1.74185, -1.73996, -2.39867, -0.245635, 9.13027, 0.754941, -1.90741, 0.987787, 0.799305, -8.32553, -11.2229, 4.5643, 8.87479, 5.97206, 1.64373, 2.15304, 5.04697, 2.39867, 0.245635, 0.242235}, {1.94057, 0.198723, 2.5391, 0, 0, 7.02938, -0.61076, 1.54312, 1.54399, -1.32981, -1.74185, -1.73996, -10.1609, -1.04052, -10.3986, 3.19798, -8.0799, -5.18817, -1.64373, -2.15304, -5.04697, -0.754941, 1.90741, -0.987787, 6.96297, 9.12042, 12.0068, 2.39867, 0.245635, 0.242235}, {1.94057, 0.198723, 2.5391, 0, 0, -2.34313, 1.83228, -4.62937, -4.63197, -1.32981, -1.74185, -1.73996, -2.39867, -0.245635, -0.242235, 0.754941, -1.90741, 10.3603, -9.40601, -2.94793, -15.2034, -0.754941, 1.90741, -0.987787, 1.64373, 2.15304, 5.04697, 7.71791, 7.21302, 7.20208}, {1.94057, 0.198723, 2.5391, 0, 0, -2.34313, -0.61076, 1.54312, 1.54399, 3.98943, 5.22554, 5.21989, -2.39867, -0.245635, -0.242235, 0.754941, -1.90741, 0.987787, -1.64373, -2.15304, -5.04697, -8.51722, 1.11252, -11.1442, 1.64373, 2.15304, 14.4195, 4.84171, -5.92686, -5.93372}, {7.02938, -2.66454e-15, 0, 1.54312, -1.54312, -0.61076, 2.54185, -0.198723, 1.94057, -1.74185, 1.74185, -1.32981, -5.18364, 8.0799, 3.19798, -5.0493, 2.15304, -1.64373, -10.413, 1.04052, -10.1609, 12.0167, -9.12042, 6.96297, 0.245635, -0.245635, 2.39867, -0.988857, -1.90741, -0.754941}, {-2.34313, -2.22045e-16, 0, -4.62937, 4.62937, 1.83228, 2.54185, -0.198723, 1.94057, -1.74185, 1.74185, -1.32981, 10.3614, 1.90741, 0.754941, -15.2167, 2.94793, -9.40601, -0.245635, 0.245635, -2.39867, 5.0493, -2.15304, 1.64373, 7.21302, -7.21302, 7.71791, -0.988857, -1.90741, -0.754941}, {-2.34313, 0, -2.22045e-16, 1.54312, -1.54312, -0.61076, -7.62554, 0.596168, -5.82171, -1.74185, 1.74185, -1.32981, 0.988857, 1.90741, 0.754941, -11.2218, 8.32553, 0.799305, 9.12687, 0.245635, -2.39867, 5.0493, -2.15304, 1.64373, 0.245635, -0.245635, 2.39867, 5.97853, -8.87479, 4.5643}, {-2.34313, 2.22045e-16, 2.22045e-16, 1.54312, -1.54312, -0.61076, 2.54185, -0.198723, 1.94057, 5.22554, -5.22554, 3.98943, 0.988857, 1.90741, 0.754941, -5.0493, 2.15304, -1.64373, -0.245635, 0.245635, -2.39867, 14.4218, -2.15304, 1.64373, -5.92686, 5.92686, 4.84171, -11.1562, -1.11252, -8.51722}, {9.45441, 8.88178e-16, 0, -1.41486, -1.85814, 1.41539, 2.77696, 3.64699, 0.373467, 1.78937, -1.78885, -1.78885, 11.3037, 9.72932, -7.41106, -1.68365, -2.21115, -2.21115, -10.6449, -19.0959, -1.9555, -5.47381, 9.36656, 9.36656, -0.46292, 4.50793, 0.461631, -5.64429, -2.29678, 1.74951}, {-3.15147, 2.22045e-16, 0, 4.24457, 5.57441, -4.24616, 2.77696, 3.64699, 0.373467, 1.78937, -1.78885, -1.78885, 18.2502, 2.29678, -1.74951, -12.7915, -16.7991, -3.70501, 0.46292, -4.50793, -0.461631, 1.68365, 2.21115, 2.21115, -7.62038, 11.6633, 7.61705, -5.64429, -2.29678, 1.74951}, {-3.15147, -2.22045e-16, -2.22045e-16, -1.41486, -1.85814, 1.41539, -8.33088, -10.941, -1.1204, 1.78937, -1.78885, -1.78885, 5.64429, 2.29678, -1.74951, 3.97577, 5.2214, -7.87269, 13.0688, -4.50793, -0.461631, 1.68365, 2.21115, 2.21115, -0.46292, 4.50793, 0.461631, -12.8018, 4.85864, 8.90493}, {-3.15147, 2.22045e-16, 2.22045e-16, -1.41486, -1.85814, 1.41539, 2.77696, 3.64699, 0.373467, -5.3681, 5.36656, 5.36656, 5.64429, 2.29678, -1.74951, -1.68365, -2.21115, -2.21115, 0.46292, -4.50793, -0.461631, 14.2895, 2.21115, 2.21115, 5.1965, 11.9405, -5.19992, -16.7521, -16.8847, 0.255645}, {-1.04981, -4.33994, -1.71772, -1.16436, 0, 0, 0.183612, -1.44665, 1.44665, 0.630806, -1.58958e-12, -2.01922, 5.6641, -1.78815, -0.707741, 1.21227, 1.78815, -1.78815, -1.39395, 5.78659, -8.28248, -3.73549, -1.78815, 9.86504, 0.659504, 1.96483e-12, 2.4959, -1.00668, 1.78815, 0.707741}, {0.349938, 1.44665, 0.572575, 3.49307, 0, 0, 0.183612, -1.44665, 1.44665, 0.630806, -1.58849e-12, -2.01922, -0.393077, -7.57474, -2.99804, 0.47782, 7.57474, -7.57474, -0.659504, -1.96456e-12, -2.4959, -1.21227, -1.78815, 1.78815, -1.86372, 8.31745e-12, 10.5728, -1.00668, 1.78815, 0.707741}, {0.349938, 1.44665, 0.572575, -1.16436, 0, 0, -0.550835, 4.33994, -4.33994, 0.630806, -1.58668e-12, -2.01922, 1.00668, -1.78815, -0.707741, 5.86969, 1.78815, -1.78815, -2.05926, -5.78659, -4.7862, -1.21227, -1.78815, 1.78815, 0.659504, 1.96124e-12, 2.4959, -3.5299, 1.78815, 8.78463}, {0.349938, 1.44665, 0.572575, -1.16436, 0, 0, 0.183612, -1.44665, 1.44665, -1.89242, 4.75569e-12, 6.05767, 1.00668, -1.78815, -0.707741, 1.21227, 1.78815, -1.78815, -0.659504, -1.96053e-12, -2.4959, -2.61202, -7.57474, -0.502145, 5.31693, 1.95945e-12, 2.4959, -1.74112, 7.57474, -5.07885}, {-5.36656, 5.36656, -5.36656, 1.85814, -0.190281, -1.41539, 1.45374e-15, 1.60567, 1.48869e-16, -3.64699, 0.373467, -0.373467, -11.9405, 3.20747, 5.19992, -2.29678, -1.74951, 1.74951, -2.21115, -6.19624, -2.21115, 16.8847, 0.255645, -0.255645, 2.21115, -0.226431, 2.21115, 4.50793, -2.44635, 0.461631}, {1.78885, -1.78885, 1.78885, -5.57441, 0.570843, 4.24616, 0, 1.60567, 0, -3.64699, 0.373467, -0.373467, -11.6633, 9.60176, -7.61705, -2.29678, -8.17219, 1.74951, -2.21115, 0.226431, -2.21115, 2.29678, 1.74951, -1.74951, 16.7991, -1.7203, 3.70501, 4.50793, -2.44635, 0.461631}, {1.78885, -1.78885, 1.78885, 1.85814, -0.190281, -1.41539, 0, -4.817, 0, -3.64699, 0.373467, -0.373467, -4.50793, 2.44635, -0.461631, -9.72932, -0.988391, 7.41106, -9.36656, 7.38185, -9.36656, 2.29678, 1.74951, -1.74951, 2.21115, -0.226431, 2.21115, 19.0959, -3.94022, 1.9555}, {1.78885, -1.78885, 1.78885, 1.85814, -0.190281, -1.41539, 1.45374e-15, 1.60567, 1.48869e-16, 10.941, -1.1204, 1.1204, -4.50793, 2.44635, -0.461631, -2.29678, -1.74951, 1.74951, -2.21115, 0.226431, -2.21115, -4.85864, 8.90493, -8.90493, -5.2214, 0.534693, 7.87269, 4.50793, -8.86902, 0.461631}, {-2.3518, -6.05767, 5.91704e-12, 0.531029, -0.572575, 1.44665, -0.258935, -1.44665, -1.44665, -1.05603, 0, 0, -3.7495, 0.502145, -7.57474, -0.336326, 2.4959, -2.43805e-12, 0.386809, 5.07885, 7.57474, 4.56043, -2.4959, 2.43805e-12, 0.648932, 0.707741, -1.78815, 1.62538, 1.78815, 1.78815}, {0.783932, 2.01922, -1.9722e-12, -1.59309, 1.71772, -4.33994, -0.258935, -1.44665, -1.44665, -1.05603, 0, 0, -4.76111, -9.86504, -1.78815, 0.699414, 8.28248, 5.78659, -0.648932, -0.707741, 1.78815, 0.336326, -2.4959, 2.43761e-12, 4.87303, 0.707741, -1.78815, 1.62538, 1.78815, 1.78815}, {0.783932, 2.01922, -1.97309e-12, 0.531029, -0.572575, 1.44665, 0.776805, 4.33994, 4.33994, -1.05603, 0, 0, -1.62538, -1.78815, -1.78815, -2.46044, 4.7862, -5.78659, -3.78466, -8.78463, 1.78815, 0.336326, -2.4959, 2.43894e-12, 0.648932, 0.707741, -1.78815, 5.84948, 1.78815, 1.78815}, {0.783932, 2.01922, -1.97176e-12, 0.531029, -0.572575, 1.44665, -0.258935, -1.44665, -1.44665, 3.16808, 0, 0, -1.62538, -1.78815, -1.78815, -0.336326, 2.4959, -2.43716e-12, -0.648932, -0.707741, 1.78815, -2.7994, -10.5728, 1.03233e-11, -1.47518, 2.99804, -7.57474, 2.66112, 7.57474, 7.57474}, {-5.36656, -5.36656, -5.36656, 2.778, -3.64699, -0.373467, -1.41539, 1.85814, -1.41539, -3.15147, 0, 0, -16.7569, 16.8847, -0.255645, -1.68428, 2.21115, 2.21115, 5.19992, -11.9405, 5.19992, 14.2902, -2.21115, -2.21115, 0.461631, 4.50793, 0.461631, 5.64494, -2.29678, 1.74951}, {1.78885, 1.78885, 1.78885, -8.334, 10.941, 1.1204, -1.41539, 1.85814, -1.41539, -3.15147, 0, 0, -12.8004, -4.85864, -8.90493, 3.97726, -5.2214, 7.87269, -0.461631, -4.50793, -0.461631, 1.68428, -2.21115, -2.21115, 13.0675, 4.50793, 0.461631, 5.64494, -2.29678, 1.74951}, {1.78885, 1.78885, 1.78885, 2.778, -3.64699, -0.373467, 4.24616, -5.57441, 4.24616, -3.15147, 0, 0, -5.64494, 2.29678, -1.74951, -12.7963, 16.7991, 3.70501, -7.61705, -11.6633, -7.61705, 1.68428, -2.21115, -2.21115, 0.461631, 4.50793, 0.461631, 18.2508, -2.29678, 1.74951}, {1.78885, 1.78885, 1.78885, 2.778, -3.64699, -0.373467, -1.41539, 1.85814, -1.41539, 9.45441, 0, 0, -5.64494, 2.29678, -1.74951, -1.68428, 2.21115, 2.21115, -0.461631, -4.50793, -0.461631, -5.47113, -9.36656, -9.36656, -10.6504, 19.0959, 1.9555, 11.3065, -9.72932, 7.41106}, {0.408534, -3.98943, 5.22554, 1.54312, 0.61076, 1.54312, 0.198723, -1.94057, 0.198723, -1.60567, 0, 0, -7.91157, -4.84171, -5.92686, -2.15304, 1.64373, -2.15304, -0.872199, 8.51722, 1.11252, 8.57571, -1.64373, 2.15304, 0.0773091, -0.754941, -1.90741, 1.73908, 2.39867, -0.245635}, {-0.136178, 1.32981, -1.74185, -4.62937, -1.83228, -4.62937, 0.198723, -1.94057, 0.198723, -1.60567, 0, 0, -1.19437, -7.71791, 7.21302, -2.94793, 9.40601, -2.94793, -0.0773091, 0.754941, 1.90741, 2.15304, -1.64373, 2.15304, 6.49998, -0.754941, -1.90741, 1.73908, 2.39867, -0.245635}, {-0.136178, 1.32981, -1.74185, 1.54312, 0.61076, 1.54312, -0.596168, 5.82171, -0.596168, -1.60567, 0, 0, -1.73908, -2.39867, 0.245635, -8.32553, -0.799305, -8.32553, 0.467403, -4.5643, 8.87479, 2.15304, -1.64373, 2.15304, 0.0773091, -0.754941, -1.90741, 8.16175, 2.39867, -0.245635}, {-0.136178, 1.32981, -1.74185, 1.54312, 0.61076, 1.54312, 0.198723, -1.94057, 0.198723, 4.817, 0, 0, -1.73908, -2.39867, 0.245635, -2.15304, 1.64373, -2.15304, -0.0773091, 0.754941, 1.90741, 2.69775, -6.96297, 9.12042, -6.09519, -3.19798, -8.0799, 0.94419, 10.1609, -1.04052}, {-1.29949, 3.9353, 2.21079, 1.70046, 1.31177, -0.409533, -0.573592, 0, 1.62837, -1.56004, 0, -0.481907, -9.43917, -5.24706, 3.05524, -1.39289, -1.62143, -1.50656, 2.46795, 1.62143, -7.61536, 7.63304, 1.62143, 3.43419, -0.173579, -1.62143, 1.10188, 2.63731, 0, -1.4171}, {0.433164, -1.31177, -0.736929, -5.10139, -3.9353, 1.2286, -0.573592, -1.8679e-16, 1.62837, -1.56004, -5.08026e-16, -0.481907, -4.36997, 5.24706, 4.36482, 0.901477, -1.62143, -8.02004, 0.173579, 1.62143, -1.10188, 1.39289, 1.62143, 1.50656, 6.06657, -1.62143, 3.02951, 2.63731, 8.58841e-16, -1.4171}, {0.433164, -1.31177, -0.736929, 1.70046, 1.31177, -0.409533, 1.72078, 0, -4.88511, -1.56004, 0, -0.481907, -2.63731, 9.76951e-16, 1.4171, -8.19475, -6.86849, 0.131566, -1.55908, 6.86849, 1.84584, 1.39289, 1.62143, 1.50656, -0.173579, -1.62143, 1.10188, 8.87746, 0, 0.510523}, {0.433164, -1.31177, -0.736929, 1.70046, 1.31177, -0.409533, -0.573592, 0, 1.62837, 4.68011, 0, 1.44572, -2.63731, 9.76951e-16, 1.4171, -1.39289, -1.62143, -1.50656, 0.173579, 1.62143, -1.10188, -0.339765, 6.86849, 4.45428, -6.97544, -6.86849, 2.74001, 4.93168, 0, -7.93058}, {10.941, 1.1204, -5.07489, 1.78885, 1.78885, -0.204309, 0, 0, -2.39759, 1.85814, -1.41539, 0.910268, -4.85864, -8.90493, -1.02119, -2.21115, -2.21115, 3.21612, 4.50793, 0.461631, 10.463, -5.2214, 7.87269, -6.8572, -4.50793, -0.461631, -0.872613, -2.29678, 1.74951, 1.83843}, {-3.64699, -0.373467, 1.69163, -5.36656, -5.36656, 0.612928, 0, 0, -2.39759, 1.85814, -1.41539, 0.910268, 16.8847, -0.255645, -8.60495, -2.21115, -2.21115, 12.8065, 4.50793, 0.461631, 0.872613, 2.21115, 2.21115, -3.21612, -11.9405, 5.19992, -4.51368, -2.29678, 1.74951, 1.83843}, {-3.64699, -0.373467, 1.69163, 1.78885, 1.78885, -0.204309, 0, 0, 7.19277, 1.85814, -1.41539, 0.910268, 2.29678, -1.74951, -1.83843, -9.36656, -9.36656, 4.03336, 19.0959, 1.9555, -5.89391, 2.21115, 2.21115, -3.21612, -4.50793, -0.461631, -0.872613, -9.72932, 7.41106, -1.80264}, {-3.64699, -0.373467, 1.69163, 1.78885, 1.78885, -0.204309, 0, 0, -2.39759, -5.57441, 4.24616, -2.7308, 2.29678, -1.74951, -1.83843, -2.21115, -2.21115, 3.21612, 4.50793, 0.461631, 0.872613, 16.7991, 3.70501, -9.98265, -11.6633, -7.61705, -0.0553752, -2.29678, 1.74951, 11.4288}, {-5.36656, 5.36656, -5.36656, 0, 3.15147, 0, -3.15147, 0, 0, 1.36261, -1.36261, -1.78885, -2.21115, -14.2902, -2.21115, 3.89543, -3.89543, 0, 14.2902, 2.21115, -2.21115, -9.34589, 9.34589, 7.15542, -1.68428, -2.21115, 2.21115, 2.21115, 1.68428, 2.21115}, {1.78885, -1.78885, 1.78885, 1.0595e-14, -9.45441, -4.1986e-15, -3.15147, 0, 0, 1.36261, -1.36261, -1.78885, -9.36656, 5.47113, -9.36656, 16.5013, -3.89543, -1.72992e-15, 1.68428, 2.21115, -2.21115, -3.89543, 3.89543, 3.9765e-16, -7.13474, 3.23931, 9.36656, 2.21115, 1.68428, 2.21115}, {1.78885, -1.78885, 1.78885, -4.26423e-15, 3.15147, 5.59813e-15, 9.45441, 0, 0, 1.36261, -1.36261, -1.78885, -2.21115, -1.68428, -2.21115, 3.89543, -16.5013, -2.93122e-14, -5.47113, 9.36656, -9.36656, -3.89543, 3.89543, 5.5874e-15, -1.68428, -2.21115, 2.21115, -3.23931, 7.13474, 9.36656}, {1.78885, -1.78885, 1.78885, 0, 3.15147, 0, -3.15147, 0, 0, -4.08784, 4.08784, 5.36656, -2.21115, -1.68428, -2.21115, 3.89543, -3.89543, 0, 1.68428, 2.21115, -2.21115, -11.0508, 11.0508, -7.15542, -1.68428, -14.817, 2.21115, 14.817, 1.68428, 2.21115}, {-3.13871, 2.39624, 3.14224, -1.3586, 1.03722, -0.984492, 1.05172, 0.985921, 1.29286, -0.739357, -1.22439, 0.739047, 5.8205, -4.44365, 6.44954, 0.379324, -2.50074, -0.381162, -6.8001, -4.17504, -5.47482, 2.5781, 7.39832, -2.57503, 2.59322, 0.231359, 0.303387, -0.386102, 0.294769, -2.51157}, {1.04624, -0.798747, -1.04741, 4.0758, -3.11166, 2.95348, 1.05172, 0.985921, 1.29286, -0.739357, -1.22439, 0.739047, -3.79884, 2.90022, 6.70123, -3.82756, -6.44442, -5.5526, -2.59322, -0.231359, -0.303387, -0.379324, 2.50074, 0.381162, 5.55064, 5.12894, -2.6528, -0.386102, 0.294769, -2.51157}, {1.04624, -0.798747, -1.04741, -1.3586, 1.03722, -0.984492, -3.15516, -2.95776, -3.87858, -0.739357, -1.22439, 0.739047, 0.386102, -0.294769, 2.51157, 5.81372, -6.64962, 3.55681, -6.77816, 2.96363, 3.88627, -0.379324, 2.50074, 0.381162, 2.59322, 0.231359, 0.303387, 2.57132, 5.19235, -5.46776}, {1.04624, -0.798747, -1.04741, -1.3586, 1.03722, -0.984492, 1.05172, 0.985921, 1.29286, 2.21807, 3.67318, -2.21714, 0.386102, -0.294769, 2.51157, 0.379324, -2.50074, -0.381162, -2.59322, -0.231359, -0.303387, -4.56427, 5.69573, 4.57082, 8.02762, -3.91752, 4.24135, -4.59298, -3.64891, -7.68301}, {3.49307, -8.88178e-16, 1.61767e-15, 0.460877, 0.572575, 1.44665, -0.183612, 1.44665, -1.44665, 0.88709, -2.01922, 1.97348e-12, -0.973962, -2.99804, -7.57474, -0.342719, -2.4959, 2.43849e-12, 2.40063, -7.57474, 7.57474, -3.20564, 10.5728, -1.03324e-11, -1.66618, 1.78815, -1.78815, -0.869547, 0.707741, 1.78815}, {-1.16436, 0, 1.22701e-16, -1.38263, -1.71772, -4.33994, -0.183612, 1.44665, -1.44665, 0.88709, -2.01922, 1.9723e-12, 5.52697, -0.707741, -1.78815, 0.391727, -8.28248, 5.78659, 1.66618, -1.78815, 1.78815, 0.342719, 2.4959, -2.43783e-12, -5.21454, 9.86504, -1.78815, -0.869547, 0.707741, 1.78815}, {-1.16436, 0, -2.95382e-17, 0.460877, 0.572575, 1.44665, 0.550835, -4.33994, 4.33994, 0.88709, -2.01922, 1.97112e-12, 0.869547, -0.707741, -1.78815, -2.18623, -4.7862, -5.78659, 6.3236, -1.78815, 1.78815, 0.342719, 2.4959, -2.43627e-12, -1.66618, 1.78815, -1.78815, -4.41791, 8.78463, 1.78815}, {-1.16436, 0, -4.73627e-16, 0.460877, 0.572575, 1.44665, -0.183612, 1.44665, -1.44665, -2.66127, 6.05767, -5.91336e-12, 0.869547, -0.707741, -1.78815, -0.342719, -2.4959, 2.43605e-12, 1.66618, -1.78815, 1.78815, 5.00014, 2.4959, -2.43438e-12, -3.50969, -0.502145, -7.57474, -0.135101, -5.07885, 7.57474}, {-4.817, -1.77636e-15, 1.77636e-15, -1.78885, 1.78885, -1.78885, -0.190167, 1.85702, 1.41407, 0.373353, -3.64588, 0.374783, 7.38185, -9.36656, 9.36656, 2.4462, -4.50655, 0.463257, -0.988987, -9.72349, -7.40418, -3.93962, 19.0901, -1.96239, 1.74966, 2.29541, 1.74789, -0.226431, 2.21115, -2.21115}, {1.60567, -1.33227e-15, 1.11022e-15, 5.36656, -5.36656, 5.36656, -0.190167, 1.85702, 1.41407, 0.373353, -3.64588, 0.374783, -6.19624, -2.21115, 2.21115, 3.20687, -11.9346, -5.19303, -1.74966, -2.29541, -1.74789, -2.4462, 4.50655, -0.463257, 0.256242, 16.8789, 0.248757, -0.226431, 2.21115, -2.21115}, {1.60567, -5.32907e-15, -7.21645e-16, -1.78885, 1.78885, -1.78885, 0.570501, -5.57107, -4.24221, 0.373353, -3.64588, 0.374783, 0.226431, -2.21115, 2.21115, 9.60162, -11.662, 7.61867, -8.17233, -2.29541, -1.74789, -2.4462, 4.50655, -0.463257, 1.74966, 2.29541, 1.74789, -1.71984, 16.7947, -3.71028}, {1.60567, 6.21725e-15, -6.10623e-16, -1.78885, 1.78885, -1.78885, -0.190167, 1.85702, 1.41407, -1.12006, 10.9376, -1.12435, 0.226431, -2.21115, 2.21115, 2.4462, -4.50655, 0.463257, -1.74966, -2.29541, -1.74789, -8.86888, 4.50655, -0.463257, 8.90507, -4.86001, 8.90331, 0.534237, -5.21694, -7.86743}, {4.44089e-15, -3.55271e-15, -7.02938, 1.78885, -6.92503e-12, 0.00253498, -1.78885, 2.33948, -2.34566, 0, -2.33948, 0, -9.36656, 3.62586e-11, -2.90954, -2.22045e-15, -2.89175, 2.89626, 9.36656, -12.2497, 9.38578, 2.22045e-15, 12.2497, -2.89626, -2.21115, 2.89175, -0.00313341, 2.21115, -8.55849e-12, 2.8994}, {1.9984e-15, 1.33227e-15, 2.34313, -5.36656, 2.07829e-11, -0.00760494, -1.78885, 2.33948, -2.34566, 0, -2.33948, 0, -2.21115, 8.55671e-12, -12.2719, 7.15542, -12.2497, 12.2789, 2.21115, -2.89175, 0.00313341, -2.66454e-15, 2.89175, -2.89626, -2.21115, 12.2497, -0.00313341, 2.21115, -8.5616e-12, 2.8994}, {2.22045e-15, 8.88178e-16, 2.34313, 1.78885, -6.92659e-12, 0.00253498, 5.36656, -7.01844, 7.03698, 0, -2.33948, 0, -2.21115, 8.55982e-12, -2.8994, -7.15542, -2.89175, 2.88612, 2.21115, -2.89175, -9.36937, -2.66454e-15, 2.89175, -2.89626, -2.21115, 2.89175, -0.00313341, 2.21115, 9.35791, 2.8994}, {0, -2.66454e-15, 2.34313, 1.78885, -6.92816e-12, 0.00253498, -1.78885, 2.33948, -2.34566, 0, 7.01844, 0, -2.21115, 8.56781e-12, -2.8994, 0, -2.89175, 2.89626, 2.21115, -2.89175, 0.00313341, 0, 2.89175, -12.2688, -9.36656, 2.89175, -0.0132733, 9.36656, -9.35791, 12.282}, {-2.18376e-11, 2.07612e-11, 5.36656, -2.34313, 0, 0, 0, 2.34313, 0, 2.34313, -2.34313, 1.78885, 12.2688, 8.55405e-12, 2.21115, 2.89626, -2.89626, 0, -8.99769e-12, -12.2688, 2.21115, -12.2688, 12.2688, -7.15542, 8.99769e-12, 2.89626, -2.21115, -2.89626, -8.55405e-12, -2.21115}, {7.27862e-12, -6.92246e-12, -1.78885, 7.02938, 0, 0, 1.36297e-15, 2.34313, 1.04056e-15, 2.34313, -2.34313, 1.78885, 2.89626, 3.62483e-11, 9.36656, 2.89626, -12.2688, -5.44843e-15, -8.99814e-12, -2.89626, 2.21115, -2.89626, 2.89626, 2.61847e-15, -9.3725, 12.2688, -9.36656, -2.89626, -8.55671e-12, -2.21115}, {7.27818e-12, -6.91713e-12, -1.78885, -2.34313, 0, 0, 0, -7.02938, 0, 2.34313, -2.34313, 1.78885, 2.89626, 8.55005e-12, 2.21115, 12.2688, -2.89626, 0, -3.811e-11, -2.89626, 9.36656, -2.89626, 2.89626, 1.33227e-15, 8.9968e-12, 2.89626, -2.21115, -12.2688, 9.3725, -9.36656}, {7.27907e-12, -6.92379e-12, -1.78885, -2.34313, 0, 0, 0, 2.34313, 0, -7.02938, 7.02938, -5.36656, 2.89626, 8.55804e-12, 2.21115, 2.89626, -2.89626, 0, -8.99769e-12, -2.89626, 2.21115, -2.89626, 2.89626, 7.15542, 9.3725, 2.89626, -2.21115, -2.89626, -9.3725, -2.21115}, {6.33782, 3.11659, -8.32035, 1.25748, 1.89399, 2.48645, -0.601124, 0.601124, -3.34812, 1.45625, -1.45625, -1.91178, -3.97294, -8.63294, -16.4474, -0.811303, -3.08413, 1.06509, 5.75885, -1.86342, 14.1028, -5.01369, 8.90912, 6.58202, -3.35435, -0.541075, -0.71033, -1.05699, 1.05699, 6.50159}, {-2.11261, -1.03886, 2.77345, -3.77244, -5.68196, -7.45934, -0.601124, 0.601124, -3.34812, 1.45625, -1.45625, -1.91178, 9.50741, 3.09846, -17.5954, 1.59319, -5.48862, 14.4576, 3.35435, 0.541075, 0.71033, 0.811303, 3.08413, -1.06509, -9.17934, 5.28392, 6.93678, -1.05699, 1.05699, 6.50159}, {-2.11261, -1.03886, 2.77345, 1.25748, 1.89399, 2.48645, 1.80337, -1.80337, 10.0444, 1.45625, -1.45625, -1.91178, 1.05699, -1.05699, -6.50159, -5.84123, -10.6601, -8.8807, 11.8048, 4.69653, -10.3835, 0.811303, 3.08413, -1.06509, -3.35435, -0.541075, -0.71033, -6.88198, 6.88198, 14.1487}, {-2.11261, -1.03886, 2.77345, 1.25748, 1.89399, 2.48645, -0.601124, 0.601124, -3.34812, -4.36874, 4.36874, 5.73533, 1.05699, -1.05699, -6.50159, -0.811303, -3.08413, 1.06509, 3.35435, 0.541075, 0.71033, 9.26172, 7.23958, -12.1589, -8.38428, -8.11702, -10.6561, 1.34751, -1.34751, 19.8941}, {-4.24616, -5.57441, -4.24476, 0.373467, -3.64699, -2.77708, -1.78885, 1.78885, -1.78885, 0, 0, 3.15102, -3.70501, 16.7991, 12.7921, 1.74951, 2.29678, 5.64381, 7.61705, -11.6633, 7.61763, -1.74951, -2.29678, -18.2479, -0.461631, 4.50793, -0.462209, 2.21115, -2.21115, -1.68373}, {1.41539, 1.85814, 1.41492, -1.1204, 10.941, 8.33125, -1.78885, 1.78885, -1.78885, -1.39933e-15, 1.39933e-15, 3.15102, -7.87269, -5.2214, -3.97595, 8.90493, -4.85864, 12.7992, 0.461631, -4.50793, 0.462209, -1.74951, -2.29678, -5.64381, -0.461631, 4.50793, -13.0663, 2.21115, -2.21115, -1.68373}, {1.41539, 1.85814, 1.41492, 0.373467, -3.64699, -2.77708, 5.36656, -5.36656, 5.36656, 0, 0, 3.15102, -2.21115, 2.21115, 1.68373, 0.255645, 16.8847, 16.7521, -5.19992, -11.9405, -5.19747, -1.74951, -2.29678, -5.64381, -0.461631, 4.50793, -0.462209, 2.21115, -2.21115, -14.2878}, {1.41539, 1.85814, 1.41492, 0.373467, -3.64699, -2.77708, -1.78885, 1.78885, -1.78885, 0, 0, -9.45305, -2.21115, 2.21115, 1.68373, 1.74951, 2.29678, 5.64381, 0.461631, -4.50793, 0.462209, -7.41106, -9.72932, -11.3035, -1.9555, 19.0959, 10.6461, 9.36656, -9.36656, 5.47169}, {2.81917, 4.24616, 5.57441, -1.67083, -0.373467, 3.64699, 0.18745, 1.78885, -1.78885, 2.4231, 0, 0, 9.91012, 3.70501, -16.7991, 1.83355, -1.74951, -2.29678, 0.18006, -7.61705, 11.6633, -11.526, 1.74951, 2.29678, -0.929861, 0.461631, -4.50793, -3.22682, -2.21115, 2.21115}, {-0.939723, -1.41539, -1.85814, 5.01248, 1.1204, -10.941, 0.18745, 1.78885, -1.78885, 2.4231, 1.07607e-15, -1.07607e-15, 6.98571, 7.87269, 5.2214, 1.08375, -8.90493, 4.85864, 0.929861, -0.461631, 4.50793, -1.83355, 1.74951, 2.29678, -10.6223, 0.461631, -4.50793, -3.22682, -2.21115, 2.21115}, {-0.939723, -1.41539, -1.85814, -1.67083, -0.373467, 3.64699, -0.56235, -5.36656, 5.36656, 2.4231, 0, 0, 3.22682, 2.21115, -2.21115, 8.51686, -0.255645, -16.8847, 4.68875, 5.19992, 11.9405, -1.83355, 1.74951, 2.29678, -0.929861, 0.461631, -4.50793, -12.9192, -2.21115, 2.21115}, {-0.939723, -1.41539, -1.85814, -1.67083, -0.373467, 3.64699, 0.18745, 1.78885, -1.78885, -7.2693, 0, 0, 3.22682, 2.21115, -2.21115, 1.83355, -1.74951, -2.29678, 0.929861, -0.461631, 4.50793, 1.92534, 7.41106, 9.72932, 5.75345, 1.9555, -19.0959, -3.97662, -9.36656, 9.36656}, {-5.32907e-15, 4.44089e-15, -9.45441, -3.15147, 0, 0, 1.78937, -1.78885, -1.78885, 1.3621, 1.78885, -1.36261, 16.5013, 1.77636e-15, -3.89543, 1.68365, 2.21115, 2.21115, -9.36924, 9.36656, 5.47113, -7.13206, -9.36656, 3.23931, 2.21178, -2.21115, 1.68428, -3.89543, -1.77636e-15, 3.89543}, {-4.44089e-16, -1.55431e-15, 3.15147, 9.45441, 0, 0, 1.78937, -1.78885, -1.78885, 1.3621, 1.78885, -1.36261, 3.89543, 8.88178e-15, -16.5013, -5.47381, 9.36656, 9.36656, -2.21178, 2.21115, -1.68428, -1.68365, -2.21115, -2.21115, -3.23663, -9.36656, 7.13474, -3.89543, -1.77636e-15, 3.89543}, {8.88178e-16, 1.33227e-15, 3.15147, -3.15147, 0, 0, -5.3681, 5.36656, 5.36656, 1.3621, 1.78885, -1.36261, 3.89543, -1.77636e-15, -3.89543, 14.2895, 2.21115, 2.21115, -2.21178, 2.21115, -14.2902, -1.68365, -2.21115, -2.21115, 2.21178, -2.21115, 1.68428, -9.34384, -7.15542, 9.34589}, {0, 0, 3.15147, -3.15147, 0, 0, 1.78937, -1.78885, -1.78885, -4.08631, -5.36656, 4.08784, 3.89543, 0, -3.89543, 1.68365, 2.21115, 2.21115, -2.21178, 2.21115, -1.68428, -1.68365, -2.21115, -14.817, 14.8177, -2.21115, 1.68428, -11.0529, 7.15542, 11.0508}, {-5.22583, 5.22504, 3.98456, 2.34612, -8.98735e-16, 3.56012e-16, -2.54361, 0.198607, 1.93944, -1.54445, 1.54307, -0.611252, -14.4376, 2.15284, 1.64173, 0.244118, -0.245492, -2.39728, 11.1654, 1.11292, -8.51331, 5.93368, -5.9268, 4.84229, -0.990917, -1.90734, 0.755549, 5.05312, -2.15284, -1.64173}, {1.74194, -1.74168, -1.32819, -7.03835, 2.34918e-15, -4.45681e-15, -2.54361, 0.198607, 1.93944, -1.54445, 1.54307, -0.611252, -12.0209, 9.11956, 6.95448, 10.4186, -1.03992, -10.155, 0.990917, 1.90734, -0.755549, -0.244118, 0.245492, 2.39728, 5.18688, -8.07964, 3.20056, 5.05312, -2.15284, -1.64173}, {1.74194, -1.74168, -1.32819, 2.34612, 0, 0, 7.63084, -0.595821, -5.81832, -1.54445, 1.54307, -0.611252, -5.05312, 2.15284, 1.64173, -9.14035, -0.245492, -2.39728, -5.97686, 8.87406, 4.5572, -0.244118, 0.245492, 2.39728, -0.990917, -1.90734, 0.755549, 11.2309, -8.32513, 0.803277}, {1.74194, -1.74168, -1.32819, 2.34612, -8.98735e-16, 3.56012e-16, -2.54361, 0.198607, 1.93944, 4.63335, -4.62922, 1.83376, -5.05312, 2.15284, 1.64173, 0.244118, -0.245492, -2.39728, 0.990917, 1.90734, -0.755549, -7.21189, 7.21221, 7.71003, -10.3754, -1.90734, 0.755549, 15.2276, -2.94726, -9.39949}, {-9.45441, -8.88178e-15, -7.10543e-15, -1.78937, -1.78885, -1.78885, -1.3621, 1.78885, -1.36261, 0, 0, 3.15147, 5.47381, 9.36656, 9.36656, 3.89543, 3.10862e-15, 3.89543, 3.23663, -9.36656, 7.13474, -3.89543, -3.10862e-15, -16.5013, 2.21178, 2.21115, -1.68428, 1.68365, -2.21115, -2.21115}, {3.15147, -1.17749e-15, -1.77636e-15, 5.3681, 5.36656, 5.36656, -1.3621, 1.78885, -1.36261, -1.06566e-15, 1.39953e-15, 3.15147, -14.2895, 2.21115, 2.21115, 9.34384, -7.15542, 9.34589, -2.21178, -2.21115, 1.68428, -3.89543, 1.04232e-30, -3.89543, 2.21178, 2.21115, -14.2902, 1.68365, -2.21115, -2.21115}, {3.15147, -2.66454e-15, -2.66454e-15, -1.78937, -1.78885, -1.78885, 4.08631, -5.36656, 4.08784, 0, 0, 3.15147, -1.68365, 2.21115, 2.21115, 11.0529, 7.15542, 11.0508, -14.8177, -2.21115, 1.68428, -3.89543, 3.55271e-15, -3.89543, 2.21178, 2.21115, -1.68428, 1.68365, -2.21115, -14.817}, {3.15147, 0, -2.66454e-15, -1.78937, -1.78885, -1.78885, -1.3621, 1.78885, -1.36261, 0, 0, -9.45441, -1.68365, 2.21115, 2.21115, 3.89543, 0, 3.89543, -2.21178, -2.21115, 1.68428, -16.5013, 0, -3.89543, 9.36924, 9.36656, 5.47113, 7.13206, -9.36656, 3.23931}, {-7.03835, 0, -3.55271e-15, -2.34612, 2.34348, -1.78885, -1.03923e-11, 0.00114147, 1.78885, 0, -2.34462, 0, 9.38447, -12.2706, 9.36656, 2.89996, -2.89811, 1.33227e-15, -2.89996, -0.00597681, -9.36656, -2.89996, 12.2766, -1.33227e-15, 2.89996, 0.00141093, 2.21115, 1.28456e-11, 2.8967, -2.21115}, {2.34612, -1.77636e-15, 1.9984e-15, 7.03835, -7.03044, 5.36656, -1.03933e-11, 0.00114147, 1.78885, 0, -2.34462, 0, -9.38447, -2.8967, 2.21115, 2.89996, -2.90268, -7.15542, -2.89996, -0.00141093, -2.21115, -2.89996, 2.89811, -2.22045e-15, 2.89996, 9.37989, 2.21115, 1.28469e-11, 2.8967, -2.21115}, {2.34612, -1.77636e-15, 0, -2.34612, 2.34348, -1.78885, 3.11847e-11, -0.00342441, -5.36656, 0, -2.34462, 0, -1.28505e-11, -2.8967, 2.21115, 12.2844, -12.272, 7.15542, -12.2844, -0.00141093, -2.21115, -2.89996, 2.89811, 0, 2.89996, 0.00141093, 2.21115, 1.28488e-11, 12.2752, -2.21115}, {2.34612, 2.66454e-15, 0, -2.34612, 2.34348, -1.78885, -1.03918e-11, 0.00114147, 1.78885, 0, 7.03386, 0, -1.28467e-11, -2.8967, 2.21115, 2.89996, -2.89811, 0, -2.89996, -0.00141093, -2.21115, -12.2844, 2.89811, 0, 12.2844, -9.37251, 9.36656, 5.4412e-11, 2.89213, -9.36656}, {6.66134e-16, -8.88178e-16, 5.41667, 2.01922, -1.97094e-12, 0.623753, -1.44665, -1.44665, 0.584061, -0.572575, 1.44665, 0.597742, -10.5728, 1.03195e-11, -1.03422, -0.707741, 1.78815, -1.49294, 7.57474, 7.57474, -0.826394, 2.99804, -7.57474, -0.898027, -1.78815, -1.78815, -1.50985, 2.4959, -2.43583e-12, -1.46079}, {2.22045e-16, 0, -1.80556, -6.05767, 5.91859e-12, -1.87126, -1.44665, -1.44665, 0.584061, -0.572575, 1.44665, 0.597742, -2.4959, 2.43894e-12, 8.68301, 5.07885, 7.57474, -3.82918, 1.78815, 1.78815, 1.50985, 0.707741, -1.78815, 1.49294, 0.502145, -7.57474, -3.90082, 2.4959, -2.43849e-12, -1.46079}, {0, -2.22045e-16, -1.80556, 2.01922, -1.97204e-12, 0.623753, 4.33994, 4.33994, -1.75218, -0.572575, 1.44665, 0.597742, -2.4959, 2.43761e-12, 1.46079, -8.78463, 1.78815, -3.98795, 1.78815, 1.78815, 8.73207, 0.707741, -1.78815, 1.49294, -1.78815, -1.78815, -1.50985, 4.7862, -5.78659, -3.85176}, {2.22045e-16, 0, -1.80556, 2.01922, -1.97268e-12, 0.623753, -1.44665, -1.44665, 0.584061, 1.71772, -4.33994, -1.79323, -2.4959, 2.43805e-12, 1.46079, -0.707741, 1.78815, -1.49294, 1.78815, 1.78815, 1.50985, 0.707741, -1.78815, 8.71516, -9.86504, -1.78815, -4.00486, 8.28248, 5.78659, -3.79703}, {8.56414, 1.25642, -1.25642, 2.63957, -0.971716, -0.633952, 1.54777, 0.0578944, 1.54777, -1.33263, 1.33263, -1.33263, -10.2923, 5.60564, 2.80174, -5.17584, 1.12955, -1.12955, -4.57563, 0.214536, -8.62192, 10.5064, -6.46006, 6.46006, -1.61547, -0.446113, 2.43083, -0.265934, -1.71878, -0.265934}, {-2.85471, -0.418807, 0.418807, -7.91871, 2.91515, 1.90186, 1.54777, 0.0578944, 1.54777, -1.33263, 1.33263, -1.33263, 11.6848, 3.39401, -1.4093, -11.3669, 0.897968, -7.32064, 1.61547, 0.446113, -2.43083, 5.17584, -1.12955, 1.12955, 3.71505, -5.77663, 7.76134, -0.265934, -1.71878, -0.265934}, {-2.85471, -0.418807, 0.418807, 2.63957, -0.971716, -0.633952, -4.64332, -0.173683, -4.64332, -1.33263, 1.33263, -1.33263, 0.265934, 1.71878, 0.265934, -15.7341, 5.01641, 1.40626, 13.0343, 2.12134, -4.10606, 5.17584, -1.12955, 1.12955, -1.61547, -0.446113, 2.43083, 5.06458, -7.0493, 5.06458}, {-2.85471, -0.418807, 0.418807, 2.63957, -0.971716, -0.633952, 1.54777, 0.0578944, 1.54777, 3.99789, -3.99789, 3.99789, 0.265934, 1.71878, 0.265934, -5.17584, 1.12955, -1.12955, 1.61547, 0.446113, -2.43083, 16.5947, 0.545684, -0.545684, -12.1737, 3.44075, 4.96664, -6.45703, -1.95036, -6.45703}, {-0.339403, 0.339403, -5.15641, -0.164984, -1.44068, -0.164984, 1.07377, 0.531894, -0.531894, -1.02192, 1.02192, -1.02192, 0.724024, 7.68336, -1.26069, -1.12333, 1.12333, 0.861388, -5.7622, -2.64519, 0.660475, 5.21103, -5.21103, 3.22631, 1.4671, 0.517615, 1.4671, -0.0640894, -1.92063, 1.92063}, {0.113134, -0.113134, 1.7188, 0.494951, 4.32205, 0.494951, 1.07377, 0.531894, -0.531894, -1.02192, 1.02192, -1.02192, -0.388448, 2.37316, -8.79583, -5.41842, -1.00425, 2.98896, -1.4671, -0.517615, -1.4671, 1.12333, -1.12333, -0.861388, 5.5548, -3.57008, 5.5548, -0.0640894, -1.92063, 1.92063}, {0.113134, -0.113134, 1.7188, -0.164984, -1.44068, -0.164984, -3.22132, -1.59568, 1.59568, -1.02192, 1.02192, -1.02192, 0.0640894, 1.92063, -1.92063, -0.463392, 6.88606, 1.52132, -1.91964, -0.0650781, -8.34231, 1.12333, -1.12333, -0.861388, 1.4671, 0.517615, 1.4671, 4.02361, -6.00832, 6.00832}, {0.113134, -0.113134, 1.7188, -0.164984, -1.44068, -0.164984, 1.07377, 0.531894, -0.531894, 3.06577, -3.06577, 3.06577, 0.0640894, 1.92063, -1.92063, -1.12333, 1.12333, 0.861388, -1.4671, -0.517615, -1.4671, 0.67079, -0.67079, -7.7366, 2.12703, 6.28035, 2.12703, -4.35919, -4.0482, 4.0482}, {-1.94182, 3.40923, 1.10711, 0.155006, 1.62575, -1.6184, 0.710689, -0.184627, 1.53026, -1.51297, -0.304717, 0.45717, -1.6117, -7.10787, 8.93018, -1.07006, -1.78133, 0.108939, -4.52129, 2.3714, -7.5564, 7.12193, 3.0002, -1.93762, 1.67853, -1.63289, 1.43535, 0.991672, 0.604862, -2.4566}, {0.647273, -1.13641, -0.369036, -0.465018, -4.87726, 4.85519, 0.710689, -0.184627, 1.53026, -1.51297, -0.304717, 0.45717, -3.58076, 3.94077, 3.93275, -3.91281, -1.04282, -6.01211, -1.67853, 1.63289, -1.43535, 1.07006, 1.78133, -0.108939, 7.73041, -0.414023, -0.393324, 0.991672, 0.604862, -2.4566}, {0.647273, -1.13641, -0.369036, 0.155006, 1.62575, -1.6184, -2.13207, 0.553881, -4.59079, -1.51297, -0.304717, 0.45717, -0.991672, -0.604862, 2.4566, -1.69008, -8.28434, 6.58252, -4.26763, 6.17852, 0.0407896, 1.07006, 1.78133, -0.108939, 1.67853, -1.63289, 1.43535, 7.04355, 1.82373, -4.28528}, {0.647273, -1.13641, -0.369036, 0.155006, 1.62575, -1.6184, 0.710689, -0.184627, 1.53026, 4.53891, 0.91415, -1.37151, -0.991672, -0.604862, 2.4566, -1.07006, -1.78133, 0.108939, -1.67853, 1.63289, -1.43535, -1.51903, 6.32696, 1.36721, 1.05851, -8.1359, 7.90894, -1.85108, 1.34337, -8.57765}, {-5.5377e-11, 0.00342441, 5.36656, 2.34612, -1.36625e-15, -1.04189e-15, 0, -2.34462, 0, -2.34612, 2.34576, 1.78885, -12.2844, 0.00141093, 2.21115, -2.89996, 2.89811, 1.28784e-15, -2.28164e-11, 12.278, 2.21115, 12.2844, -12.2812, -7.15542, 2.28164e-11, -2.89952, -2.21115, 2.89996, -0.00141093, -2.21115}, {1.22973e-11, -0.00114147, -1.78885, -7.03835, 8.19548e-15, 3.12566e-15, 0, -2.34462, 0, -2.34612, 2.34576, 1.78885, -2.89996, 0.00597681, 9.36656, -2.89996, 12.2766, 1.28784e-15, -1.51998e-11, 2.89952, 2.21115, 2.89996, -2.89811, 4.44263e-17, 9.38447, -12.2826, -9.36656, 2.89996, -0.00141093, -2.21115}, {1.22946e-11, -0.00114147, -1.78885, 2.34612, 0, 0, 0, 7.03386, 0, -2.34612, 2.34576, 1.78885, -2.89996, 0.00141093, 2.21115, -12.2844, 2.89811, 0, -6.43752e-11, 2.90409, 9.36656, 2.89996, -2.89811, 1.33227e-15, 1.51972e-11, -2.89952, -2.21115, 12.2844, -9.38446, -9.36656}, {1.22959e-11, -0.00114147, -1.78885, 2.34612, -1.36625e-15, -1.04189e-15, 0, -2.34462, 0, 7.03835, -7.03729, -5.36656, -2.89996, 0.00141093, 2.21115, -2.89996, 2.89811, 1.28784e-15, -1.51994e-11, 2.89952, 2.21115, 2.89996, -2.89354, 7.15542, -9.38447, -2.89952, -2.21115, 2.89996, 9.37707, -2.21115}, {-4.82192e-12, 4.93775, 1.89782, -1.17532e-12, 1.20344, -0.85762, 1.44665, -0.256711, 0.444168, -1.44665, 0.69919, 1.04606, 4.16733e-12, -4.26682, 5.2725, -1.78815, -1.17022, 0.511055, -7.57474, 3.37862, -1.54375, 7.57474, -1.62654, -4.69529, 1.78815, -2.35178, -0.232925, 5.34017e-13, -0.546933, -1.84202}, {1.6076e-12, -1.64592, -0.632608, 3.52661e-12, -3.61031, 2.57286, 1.44665, -0.256711, 0.444168, -1.44665, 0.69919, 1.04606, -6.96421e-12, 7.13059, 4.37245, -7.57474, -0.143371, -1.26562, -1.78815, 2.35178, 0.232925, 1.78815, 1.17022, -0.511055, 7.57474, -5.14853, -4.41716, 5.33795e-13, -0.546933, -1.84202}, {1.60716e-12, -1.64592, -0.632608, -1.17499e-12, 1.20344, -0.85762, -4.33994, 0.770134, -1.3325, -1.44665, 0.69919, 1.04606, -5.33795e-13, 0.546933, 1.84202, -1.78815, -5.98397, 3.94153, -1.78815, 8.93544, 2.76336, 1.78815, 1.17022, -0.511055, 1.78815, -2.35178, -0.232925, 5.78659, -3.34369, -6.02626}, {1.60671e-12, -1.64592, -0.632608, -1.1751e-12, 1.20344, -0.85762, 1.44665, -0.256711, 0.444168, 4.33994, -2.09757, -3.13818, -5.33573e-13, 0.546933, 1.84202, -1.78815, -1.17022, 0.511055, -1.78815, 2.35178, 0.232925, 1.78815, 7.75388, 2.01938, 1.78815, -7.16552, 3.19755, -5.78659, 0.479913, -3.61869}, {3.67809, 0.0745323, 3.75892, 1.30596, 0.948366, 0.152693, 0.0437324, -1.35943, 0.016287, -0.123659, 0.435911, 1.08399, -5.32262, -4.935, 0.74925, -1.66831, 0.508107, -0.20887, 1.28647, 7.14879, 1.46348, 2.16294, -2.25175, -4.1271, -1.4614, -1.71106, -1.52863, 0.0987948, 1.14154, -1.36002}, {-1.22603, -0.0248441, -1.25297, -3.91787, -2.8451, -0.458078, 0.0437324, -1.35943, 0.016287, -0.123659, 0.435911, 1.08399, 4.80532, -1.04216, 6.37191, -1.84323, 5.94584, -0.274019, 1.4614, 1.71106, 1.52863, 1.66831, -0.508107, 0.20887, -0.966762, -3.4547, -5.8646, 0.0987948, 1.14154, -1.36002}, {-1.22603, -0.0248441, -1.25297, 1.30596, 0.948366, 0.152693, -0.131197, 4.0783, -0.0488611, -0.123659, 0.435911, 1.08399, -0.0987948, -1.14154, 1.36002, -6.89213, -3.28536, -0.819641, 6.36551, 1.81044, 6.54052, 1.66831, -0.508107, 0.20887, -1.4614, -1.71106, -1.52863, 0.593431, -0.602108, -5.69599}, {-1.22603, -0.0248441, -1.25297, 1.30596, 0.948366, 0.152693, 0.0437324, -1.35943, 0.016287, 0.370977, -1.30773, -3.25198, -0.0987948, -1.14154, 1.36002, -1.66831, 0.508107, -0.20887, 1.4614, 1.71106, 1.52863, 6.57242, -0.40873, 5.22076, -6.68522, -5.50453, -2.1394, -0.0761347, 6.57927, -1.42517}, {5.37088, 5.36291, 5.36619, -1.12719e-15, 1.48034e-15, 1.60567, 0.376399, 3.64451, 0.373213, 1.41389, -1.85687, -0.190152, 2.21292, 2.20964, -6.1964, -0.465254, -4.50486, -2.44603, 0.242074, -16.8733, 0.256821, -5.19032, 11.9323, 3.20664, -1.74767, 2.29522, -1.74967, -2.21292, -2.20964, -0.226277}, {-1.79029, -1.78764, -1.78873, 1.24068e-15, -6.57876e-15, -4.817, 0.376399, 3.64451, 0.373213, 1.41389, -1.85687, -0.190152, 9.37409, 9.36019, 7.3812, -1.97085, -19.0829, -3.93889, 1.74767, -2.29522, 1.74967, 0.465254, 4.50486, 2.44603, -7.40324, 9.72271, -0.989068, -2.21292, -2.20964, -0.226277}, {-1.79029, -1.78764, -1.78873, 0, 0, 1.60567, -1.1292, -10.9335, -1.11964, 1.41389, -1.85687, -0.190152, 2.21292, 2.20964, 0.226277, -0.465254, -4.50486, -8.8687, 8.90884, 4.85533, 8.90459, 0.465254, 4.50486, 2.44603, -1.74767, 2.29522, -1.74967, -7.8685, 5.21784, 0.53433}, {-1.79029, -1.78764, -1.78873, -1.12719e-15, 1.48034e-15, 1.60567, 0.376399, 3.64451, 0.373213, -4.24168, 5.57061, 0.570455, 2.21292, 2.20964, 0.226277, -0.465254, -4.50486, -2.44603, 1.74767, -2.29522, 1.74967, 7.62642, 11.6554, 9.60095, -1.74767, 2.29522, -8.17235, -3.71852, -16.7877, -1.71913}, {0, -1.24345e-14, -9.45441, 0, -3.15057, 0, 1.78885, 1.78834, -1.78885, -1.78885, 1.36222, -1.36261, 0, 16.4966, -3.89543, -2.21115, 1.6838, 2.21115, -9.36656, -9.36389, 5.47113, 9.36656, -7.1327, 3.23931, 2.21115, 2.21051, 1.68428, 0, -3.89432, 3.89543}, {0, -2.44249e-15, 3.15147, 0, 9.4517, 0, 1.78885, 1.78834, -1.78885, -1.78885, 1.36222, -1.36261, 0, 3.89432, -16.5013, -9.36656, -5.46957, 9.36656, -2.21115, -2.21051, -1.68428, 2.21115, -1.6838, -2.21115, 9.36656, -3.23838, 7.13474, 0, -3.89432, 3.89543}, {2.66454e-15, 7.54952e-15, 3.15147, 0, -3.15057, 0, -5.36656, -5.36503, 5.36656, -1.78885, 1.36222, -1.36261, -3.10862e-15, 3.89432, -3.89543, -2.21115, 14.2861, 2.21115, -2.21115, -2.21051, -14.2902, 2.21115, -1.6838, -2.21115, 2.21115, 2.21051, 1.68428, 7.15542, -9.34321, 9.34589}, {-1.55431e-15, 6.66134e-16, 3.15147, 0, -3.15057, 0, 1.78885, 1.78834, -1.78885, 5.36656, -4.08667, 4.08784, 1.77636e-15, 3.89432, -3.89543, -2.21115, 1.6838, 2.21115, -2.21115, -2.21051, -1.68428, 2.21115, -1.6838, -14.817, 2.21115, 14.8128, 1.68428, -7.15542, -11.0477, 11.0508}, {-5.9055e-12, 6.05767, -4.31695, 0, 0, -1.80556, 1.44665, 0.572575, -0.146817, -1.44665, 1.44665, 0.51339, -2.43294e-12, 2.4959, 7.67533, -1.78815, -0.707741, 2.41326, -7.57474, -0.502145, -1.00994, 7.57474, -5.07885, -4.46683, 1.78815, -1.78815, 1.5972, 2.43294e-12, -2.4959, -0.45311}, {1.97087e-12, -2.01922, 1.43898, 0, 0, 5.41667, 1.44665, 0.572575, -0.146817, -1.44665, 1.44665, 0.51339, -1.03206e-11, 10.5728, -5.30282, -7.57474, -2.99804, 3.00053, -1.78815, 1.78815, -1.5972, 1.78815, 0.707741, -2.41326, 7.57474, -7.57474, -0.456356, 2.43605e-12, -2.4959, -0.45311}, {1.97176e-12, -2.01922, 1.43898, 0, 0, -1.80556, -4.33994, -1.71772, 0.44045, -1.44665, 1.44665, 0.51339, -2.43716e-12, 2.4959, 0.45311, -1.78815, -0.707741, 9.63549, -1.78815, 9.86504, -7.35313, 1.78815, 0.707741, -2.41326, 1.78815, -1.78815, 1.5972, 5.78659, -8.28248, -2.50667}, {1.9722e-12, -2.01922, 1.43898, 0, 0, -1.80556, 1.44665, 0.572575, -0.146817, 4.33994, -4.33994, -1.54017, -2.43761e-12, 2.4959, 0.45311, -1.78815, -0.707741, 2.41326, -1.78815, 1.78815, -1.5972, 1.78815, 8.78463, -8.16919, 1.78815, -1.78815, 8.81943, -5.78659, -4.7862, 0.134156}, {-4.33994, -4.33994, 1.75218, -1.97392e-12, -2.01922, 1.43898, 0, 0, -1.80556, -1.44665, 0.572575, 0.950635, -1.78815, 8.78463, -6.81267, 2.4399e-12, 2.4959, 0.45311, -1.78815, -1.78815, 10.176, 5.78659, -4.7862, -4.25565, 1.78815, 1.78815, -2.95373, 1.78815, -0.707741, 1.05674}, {1.44665, 1.44665, -0.584061, 5.91959e-12, 6.05767, -4.31695, 0, 0, -1.80556, -1.44665, 0.572575, 0.950635, -7.57474, -5.07885, 1.2795, 2.43901e-12, 2.4959, 7.67533, -1.78815, -1.78815, 2.95373, -2.44008e-12, -2.4959, -0.45311, 7.57474, -0.502145, -6.75627, 1.78815, -0.707741, 1.05674}, {1.44665, 1.44665, -0.584061, -1.97247e-12, -2.01922, 1.43898, 0, 0, 5.41667, -1.44665, 0.572575, 0.950635, -1.78815, 0.707741, -1.05674, 1.0328e-11, 10.5728, -5.30282, -7.57474, -7.57474, 5.28997, -2.43919e-12, -2.4959, -0.45311, 1.78815, 1.78815, -2.95373, 7.57474, -2.99804, -2.7458}, {1.44665, 1.44665, -0.584061, -1.97247e-12, -2.01922, 1.43898, 0, 0, -1.80556, 4.33994, -1.71772, -2.8519, -1.78815, 0.707741, -1.05674, 2.43811e-12, 2.4959, 0.45311, -1.78815, -1.78815, 2.95373, -5.78659, -8.28248, 1.88313, 1.78815, 9.86504, -8.70966, 1.78815, -0.707741, 8.27896}, {1.71772, 0.356094, 4.33994, 2.01922, -0.477594, 1.7444e-12, -1.44665, -0.786183, 1.44665, 0, 1.38248, 0, -9.86504, 2.64743, 1.78815, -0.707741, 1.56212, -1.78815, 8.28248, 4.26323, -5.78659, 0.707741, -7.09202, 1.78815, -2.4959, -1.11849, -2.1562e-12, 1.78815, -0.737058, -1.78815}, {-0.572575, -0.118698, -1.44665, -6.05767, 1.43278, -5.22944e-12, -1.44665, -0.786183, 1.44665, -4.96495e-16, 1.38248, 4.96495e-16, 0.502145, 1.21185, 7.57474, 5.07885, 4.70685, -7.57474, 2.4959, 1.11849, 2.15634e-12, 0.707741, -1.56212, 1.78815, -2.4959, -6.6484, -2.15725e-12, 1.78815, -0.737058, -1.78815}, {-0.572575, -0.118698, -1.44665, 2.01922, -0.477594, 1.7444e-12, 4.33994, 2.35855, -4.33994, 0, 1.38248, 0, -1.78815, 0.737058, 1.78815, -8.78463, 3.47249, -1.78815, 4.7862, 1.59329, 5.78659, 0.707741, -1.56212, 1.78815, -2.4959, -1.11849, -2.1562e-12, 1.78815, -6.26696, -1.78815}, {-0.572575, -0.118698, -1.44665, 2.01922, -0.477594, 1.74332e-12, -1.44665, -0.786183, 1.44665, 0, -4.14743, 0, -1.78815, 0.737058, 1.78815, -0.707741, 1.56212, -1.78815, 2.4959, 1.11849, 2.15594e-12, 2.99804, -1.08732, 7.57474, -10.5728, 0.791882, -9.12813e-12, 7.57474, 2.40768, -7.57474}, {-3.82778, -1.72626, -1.72406, -1.39459, 0.310766, 0.31037, -0.00684175, -1.71025, 0.635056, 0.125505, 0.824062, -1.52011, 5.72503, -2.33845, -2.33547, 1.73226, 1.72986, -1.16861, -1.54131, 8.24373, -4.03555, -2.23428, -5.02611, 7.24907, 1.56867, -1.40273, 1.49533, -0.146676, 1.09539, 1.09399}, {1.27593, 0.575422, 0.574688, 4.18377, -0.932299, -0.93111, -0.00684175, -1.71025, 0.635056, 0.125505, 0.824062, -1.52011, -4.95703, -3.39708, -3.39274, 1.75963, 8.57086, -3.70884, -1.56867, 1.40273, -1.49533, -1.73226, -1.72986, 1.16861, 1.06665, -4.69898, 7.57578, -0.146676, 1.09539, 1.09399}, {1.27593, 0.575422, 0.574688, -1.39459, 0.310766, 0.31037, 0.0205252, 5.13075, -1.90517, 0.125505, 0.824062, -1.52011, 0.146676, -1.09539, -1.09399, 7.31062, 0.486792, -2.41009, -6.67238, -0.898961, -3.79408, -1.73226, -1.72986, 1.16861, 1.56867, -1.40273, 1.49533, -0.648696, -2.20086, 7.17445}, {1.27593, 0.575422, 0.574688, -1.39459, 0.310766, 0.31037, -0.00684175, -1.71025, 0.635056, -0.376515, -2.47219, 4.56034, 0.146676, -1.09539, -1.09399, 1.73226, 1.72986, -1.16861, -1.56867, 1.40273, -1.49533, -6.83597, -4.03154, -1.13014, 7.14703, -2.64579, 0.253846, -0.119309, 7.93639, -1.44623}, {4.08784, 5.36656, -4.08784, 3.15147, 0, 0, -1.78885, 1.78885, 1.78885, 0, 0, -3.15147, -14.817, 2.21115, -1.68428, -1.68428, -2.21115, -2.21115, 11.0508, -7.15542, -11.0508, 1.68428, 2.21115, 14.817, -3.89543, 0, 3.89543, 2.21115, -2.21115, 1.68428}, {-1.36261, -1.78885, 1.36261, -9.45441, -4.1986e-15, -1.15954e-14, -1.78885, 1.78885, 1.78885, 0, 0, -3.15147, 3.23931, 9.36656, -7.13474, 5.47113, -9.36656, -9.36656, 3.89543, 3.06219e-15, -3.89543, 1.68428, 2.21115, 2.21115, -3.89543, -1.72992e-15, 16.5013, 2.21115, -2.21115, 1.68428}, {-1.36261, -1.78885, 1.36261, 3.15147, 0, 9.86237e-15, 5.36656, -5.36656, -5.36656, 0, 0, -3.15147, -2.21115, 2.21115, -1.68428, -14.2902, -2.21115, -2.21115, 9.34589, 7.15542, -9.34589, 1.68428, 2.21115, 2.21115, -3.89543, 0, 3.89543, 2.21115, -2.21115, 14.2902}, {-1.36261, -1.78885, 1.36261, 3.15147, 0, 0, -1.78885, 1.78885, 1.78885, 0, 0, 9.45441, -2.21115, 2.21115, -1.68428, -1.68428, -2.21115, -2.21115, 3.89543, 1.33227e-15, -3.89543, 7.13474, 9.36656, -3.23931, -16.5013, 0, 3.89543, 9.36656, -9.36656, -5.47113}, {1.73341, -4.36745, 1.08767, 0, 0, 1.17684, 2.01922, 1.68176e-12, -0.615915, -1.44142, -1.45582, -0.198371, 0.714206, -1.79949, -5.71389, -2.4959, -2.07877e-12, -0.693346, -9.85858, -1.79949, 3.67312, 8.26156, 5.82327, 1.48683, 1.78169, 1.79949, -1.20946, -0.714206, 1.79949, 1.00651}, {-0.577805, 1.45582, -0.362558, -2.02028e-15, -3.82793e-15, -3.53053, 2.01922, 1.68145e-12, -0.615915, -1.44142, -1.45582, -0.198371, 3.02542, -7.62276, 0.443719, -10.5728, -8.80578e-12, 1.77031, -1.78169, -1.79949, 1.20946, 2.4959, 2.07888e-12, 0.693346, 7.54736, 7.62276, -0.415974, -0.714206, 1.79949, 1.00651}, {-0.577805, 1.45582, -0.362558, 1.68447e-15, 1.7013e-15, 1.17684, -6.05767, -5.04369e-12, 1.84774, -1.44142, -1.45582, -0.198371, 0.714206, -1.79949, -1.00651, -2.4959, -2.08702e-12, -5.40072, 0.529529, -7.62276, 2.65969, 2.4959, 2.07913e-12, 0.693346, 1.78169, 1.79949, -1.20946, 5.05146, 7.62276, 1.8}, {-0.577805, 1.45582, -0.362558, 0, 0, 1.17684, 2.01922, 1.68103e-12, -0.615915, 4.32425, 4.36745, 0.595113, 0.714206, -1.79949, -1.00651, -2.4959, -2.07786e-12, -0.693346, -1.78169, -1.79949, 1.20946, 4.80711, -5.82327, 2.14358, 1.78169, 1.79949, -5.91683, -8.79109, 1.79949, 3.47017}, {-4.91714, 2.88338, 1.92681, -0.336451, -0.850591, 0.85104, -1.79955, 0.555362, -0.55742, 0.496952, 1.25636, 0.348649, -0.264293, 5.64177, -3.66222, 2.64024, 0.364922, -0.362934, 7.39658, -1.7199, 3.71258, -4.62805, -5.39034, -1.03166, -0.198389, -0.501553, -1.4829, 1.6101, -2.23941, 0.258056}, {1.63905, -0.961127, -0.642269, 1.00935, 2.55177, -2.55312, -1.79955, 0.555362, -0.55742, 0.496952, 1.25636, 0.348649, -8.16629, 6.08391, 2.31102, 9.83843, -1.85653, 1.86675, 0.198389, 0.501553, 1.4829, -2.64024, -0.364922, 0.362934, -2.1862, -5.52697, -2.87749, 1.6101, -2.23941, 0.258056}, {1.63905, -0.961127, -0.642269, -0.336451, -0.850591, 0.85104, 5.39864, -1.66609, 1.67226, 0.496952, 1.25636, 0.348649, -1.6101, 2.23941, -0.258056, 3.98605, 3.76729, -3.76709, -6.3578, 4.34606, 4.05197, -2.64024, -0.364922, 0.362934, -0.198389, -0.501553, -1.4829, -0.377708, -7.26483, -1.13654}, {1.63905, -0.961127, -0.642269, -0.336451, -0.850591, 0.85104, -1.79955, 0.555362, -0.55742, -1.49085, -3.76907, -1.04595, -1.6101, 2.23941, -0.258056, 2.64024, 0.364922, -0.362934, 0.198389, 0.501553, 1.4829, -9.19643, 3.47958, 2.93201, 1.14742, 2.90081, -4.88706, 8.80829, -4.46086, 2.48774}, {10.941, -4.49288, 1.1204, 1.85814, 0.691786, -1.41539, 0, -2.17235, 0, 1.78885, -0.0170635, 1.78885, -5.2214, -5.47341, 7.87269, -2.29678, 1.83008, 1.74951, 4.50793, 9.5234, 0.461631, -4.85864, -1.76182, -8.90493, -4.50793, -0.834003, -0.461631, -2.21115, 2.70626, -2.21115}, {-3.64699, 1.49763, -0.373467, -5.57441, -2.07536, 4.24616, 0, -2.17235, 0, 1.78885, -0.0170635, 1.78885, 16.7991, -8.69677, 3.70501, -2.29678, 10.5195, 1.74951, 4.50793, 0.834003, 0.461631, 2.29678, -1.83008, -1.74951, -11.6633, -0.76575, -7.61705, -2.21115, 2.70626, -2.21115}, {-3.64699, 1.49763, -0.373467, 1.85814, 0.691786, -1.41539, 0, 6.51705, 0, 1.78885, -0.0170635, 1.78885, 2.21115, -2.70626, 2.21115, -9.72932, -0.937068, 7.41106, 19.0959, -5.15651, 1.9555, 2.29678, -1.83008, -1.74951, -4.50793, -0.834003, -0.461631, -9.36656, 2.77452, -9.36656}, {-3.64699, 1.49763, -0.373467, 1.85814, 0.691786, -1.41539, 0, -2.17235, 0, -5.36656, 0.0511904, -5.36656, 2.21115, -2.70626, 2.21115, -2.29678, 1.83008, 1.74951, 4.50793, 0.834003, 0.461631, 16.8847, -7.82059, -0.255645, -11.9405, -3.60115, 5.19992, -2.21115, 11.3957, -2.21115}, {-4.62937, 1.83228, -4.62937, -1.60567, 0, 0, -0.136178, -1.32981, -1.74185, 0.198723, 1.94057, 0.198723, 6.49998, 0.754941, -1.90741, 2.15304, 1.64373, 2.15304, -1.19437, 7.71791, 7.21302, -2.94793, -9.40601, -2.94793, 1.73908, -2.39867, -0.245635, -0.0773091, -0.754941, 1.90741}, {1.54312, -0.61076, 1.54312, 4.817, 0, 0, -0.136178, -1.32981, -1.74185, 0.198723, 1.94057, 0.198723, -6.09519, 3.19798, -8.0799, 2.69775, 6.96297, 9.12042, -1.73908, 2.39867, 0.245635, -2.15304, -1.64373, -2.15304, 0.94419, -10.1609, -1.04052, -0.0773091, -0.754941, 1.90741}, {1.54312, -0.61076, 1.54312, -1.60567, 0, 0, 0.408534, 3.98943, 5.22554, 0.198723, 1.94057, 0.198723, 0.0773091, 0.754941, -1.90741, 8.57571, 1.64373, 2.15304, -7.91157, 4.84171, -5.92686, -2.15304, -1.64373, -2.15304, 1.73908, -2.39867, -0.245635, -0.872199, -8.51722, 1.11252}, {1.54312, -0.61076, 1.54312, -1.60567, 0, 0, -0.136178, -1.32981, -1.74185, -0.596168, -5.82171, -0.596168, 0.0773091, 0.754941, -1.90741, 2.15304, 1.64373, 2.15304, -1.73908, 2.39867, 0.245635, -8.32553, 0.799305, -8.32553, 8.16175, -2.39867, -0.245635, 0.467403, 4.5643, 8.87479}, {-5.36656, 4.08784, -4.08784, 2.79907e-15, 3.15147, 4.59771e-15, -1.78885, -1.78885, 1.78885, 0, 0, -3.15147, -2.21115, -14.817, -1.68428, 2.21115, -1.68428, -2.21115, 7.15542, 11.0508, -11.0508, -2.21115, 1.68428, 14.817, -3.45984e-15, -3.89543, 3.89543, 2.21115, 2.21115, 1.68428}, {1.78885, -1.36261, 1.36261, 4.1986e-15, -9.45441, -1.15954e-14, -1.78885, -1.78885, 1.78885, 0, 0, -3.15147, -9.36656, 3.23931, -7.13474, 9.36656, 5.47113, -9.36656, -3.06219e-15, 3.89543, -3.89543, -2.21115, 1.68428, 2.21115, 1.72992e-15, -3.89543, 16.5013, 2.21115, 2.21115, 1.68428}, {1.78885, -1.36261, 1.36261, 0, 3.15147, 0, 5.36656, 5.36656, -5.36656, 0, 0, -3.15147, -2.21115, -2.21115, -1.68428, 2.21115, -14.2902, -2.21115, -7.15542, 9.34589, -9.34589, -2.21115, 1.68428, 2.21115, 0, -3.89543, 3.89543, 2.21115, 2.21115, 14.2902}, {1.78885, -1.36261, 1.36261, 0, 3.15147, -2.46559e-15, -1.78885, -1.78885, 1.78885, 0, 0, 9.45441, -2.21115, -2.21115, -1.68428, 2.21115, -1.68428, -2.21115, -1.33227e-15, 3.89543, -3.89543, -9.36656, 7.13474, -3.23931, 0, -16.5013, 3.89543, 9.36656, 9.36656, -5.47113}, {-14.3647, 4.91028, -4.91028, -1.57573, 1.57573, 1.57573, -1.57573, -1.57573, -1.57573, -1.63676, 1.63676, -1.63676, 2.33207, -6.2275, -10.2738, 3.89543, -3.19522e-13, -3.193e-13, 2.33207, 10.2738, 6.2275, 2.65162, -6.54704, 6.54704, 3.97086, -3.97086, 0.0754334, 3.97086, -0.0754334, 3.97086}, {4.78823, -1.63676, 1.63676, 4.7272, -4.7272, -4.7272, -1.57573, -1.57573, -1.57573, -1.63676, 1.63676, -1.63676, -23.1238, 6.62248, -10.5179, 10.1984, 6.30294, 6.30294, -3.97086, 3.97086, -0.0754334, -3.89543, 3.19631e-13, 3.16971e-13, 10.5179, -10.5179, 6.62248, 3.97086, -0.0754334, 3.97086}, {4.78823, -1.63676, 1.63676, -1.57573, 1.57573, 1.57573, 4.7272, 4.7272, 4.7272, -1.63676, 1.63676, -1.63676, -3.97086, 0.0754334, -3.97086, 10.1984, -6.30294, -6.30294, -23.1238, 10.5179, -6.62248, -3.89543, 3.22073e-13, 3.19413e-13, 3.97086, -3.97086, 0.0754334, 10.5179, -6.62248, 10.5179}, {4.78823, -1.63676, 1.63676, -1.57573, 1.57573, 1.57573, -1.57573, -1.57573, -1.57573, 4.91028, -4.91028, 4.91028, -3.97086, 0.0754334, -3.97086, 3.89543, -3.19078e-13, -3.193e-13, -3.97086, 3.97086, -0.0754334, -23.0483, 6.54704, -6.54704, 10.2738, -10.2738, -6.2275, 10.2738, 6.2275, 10.2738}, {0, -4.817, 8.88178e-16, -1.41539, -0.190281, -1.85814, -0.373467, 0.373467, 3.64699, 1.78885, -1.78885, -1.78885, 7.41106, -0.988391, 9.72932, 2.21115, -0.226431, -2.21115, 1.9555, -3.94022, -19.0959, -9.36656, 7.38185, 9.36656, -0.461631, 2.44635, 4.50793, -1.74951, 1.74951, -2.29678}, {1.55431e-15, 1.60567, 2.66454e-15, 4.24616, 0.570843, 5.57441, -0.373467, 0.373467, 3.64699, 1.78885, -1.78885, -1.78885, 1.74951, -8.17219, 2.29678, 3.70501, -1.7203, -16.7991, 0.461631, -2.44635, -4.50793, -2.21115, 0.226431, 2.21115, -7.61705, 9.60176, 11.6633, -1.74951, 1.74951, -2.29678}, {1.55431e-15, 1.60567, -1.33227e-15, -1.41539, -0.190281, -1.85814, 1.1204, -1.1204, -10.941, 1.78885, -1.78885, -1.78885, 1.74951, -1.74951, 2.29678, 7.87269, 0.534693, 5.2214, 0.461631, -8.86902, -4.50793, -2.21115, 0.226431, 2.21115, -0.461631, 2.44635, 4.50793, -8.90493, 8.90493, 4.85864}, {-2.44249e-15, 1.60567, 1.77636e-15, -1.41539, -0.190281, -1.85814, -0.373467, 0.373467, 3.64699, -5.36656, 5.36656, 5.36656, 1.74951, -1.74951, 2.29678, 2.21115, -0.226431, -2.21115, 0.461631, -2.44635, -4.50793, -2.21115, -6.19624, 2.21115, 5.19992, 3.20747, 11.9405, -0.255645, 0.255645, -16.8847}, {-2.60507, 7.08874, -2.60507, -1.19276, 2.49131, 1.15037, -1.08957, 0.431245, -1.08957, 1.41397, -0.55964, -0.929159, 5.172, -10.1239, -7.09676, 2.82111, -3.61247, -0.0751544, 4.6317, 0.662693, 4.6317, -8.47697, 5.85103, 3.79179, -0.273431, -2.38767, -0.273431, -0.400978, 0.158705, 2.49528}, {0.868358, -2.36291, 0.868358, 3.57827, -7.47392, -3.45111, -1.08957, 0.431245, -1.08957, 1.41397, -0.55964, -0.929159, -3.07245, 9.29295, -5.96872, 7.17938, -5.33745, 4.28312, 0.273431, 2.38767, 0.273431, -2.82111, 3.61247, 0.0751544, -5.9293, -0.149113, 3.44321, -0.400978, 0.158705, 2.49528}, {0.868358, -2.36291, 0.868358, -1.19276, 2.49131, 1.15037, 3.2687, -1.29374, 3.2687, 1.41397, -0.55964, -0.929159, 0.400978, -0.158705, -2.49528, 7.59213, -13.5777, -4.67663, -3.2, 11.8393, -3.2, -2.82111, 3.61247, 0.0751544, -0.273431, -2.38767, -0.273431, -6.05684, 2.39726, 6.21192}, {0.868358, -2.36291, 0.868358, -1.19276, 2.49131, 1.15037, -1.08957, 0.431245, -1.08957, -4.2419, 1.67892, 2.78748, 0.400978, -0.158705, -2.49528, 2.82111, -3.61247, -0.0751544, 0.273431, 2.38767, 0.273431, -6.29454, 13.0641, -3.39828, 4.49759, -12.3529, -4.87491, 3.95729, -1.56628, 6.85356}, {0.133606, -1.71772, 4.33994, 0.841626, -2.01922, -1.97283e-12, -1.05603, 0, 0, 0.258935, 1.44665, 1.44665, -4.35176, 9.86504, 1.78815, 0.265013, 2.4959, 2.43856e-12, 5.58447, -0.707741, 1.78815, -1.30075, -8.28248, -5.78659, -1.36037, 0.707741, -1.78815, 0.985258, -1.78815, -1.78815}, {-0.0445353, 0.572575, -1.44665, -2.52488, 6.05767, 5.91959e-12, -1.05603, 0, 0, 0.258935, 1.44665, 1.44665, -0.807116, -0.502145, 7.57474, 4.48912, 2.4959, 2.43901e-12, 1.36037, -0.707741, 1.78815, -0.265013, -2.4959, -2.43793e-12, -2.39611, -5.07885, -7.57474, 0.985258, -1.78815, -1.78815}, {-0.0445353, 0.572575, -1.44665, 0.841626, -2.01922, -1.97102e-12, 3.16808, 0, 0, 0.258935, 1.44665, 1.44665, -0.985258, 1.78815, 1.78815, -3.10149, 10.5728, 1.03204e-11, 1.53851, -2.99804, 7.57474, -0.265013, -2.4959, -2.43524e-12, -1.36037, 0.707741, -1.78815, -0.0504837, -7.57474, -7.57474}, {-0.0445353, 0.572575, -1.44665, 0.841626, -2.01922, -1.97356e-12, -1.05603, 0, 0, -0.776806, -4.33994, -4.33994, -0.985258, 1.78815, 1.78815, 0.265013, 2.4959, 2.43945e-12, 1.36037, -0.707741, 1.78815, -0.0868717, -4.7862, 5.78659, -4.72687, 8.78463, -1.78815, 5.20936, -1.78815, -1.78815}, {-8.334, -1.1204, -10.941, -1.41539, 1.41539, -1.85814, -3.15147, 0, 0, 1.78885, -1.78885, -1.78885, 3.97726, -7.87269, 5.2214, 5.64494, -1.74951, 2.29678, 13.0675, -0.461631, -4.50793, -12.8004, 8.90493, 4.85864, -0.461631, 0.461631, 4.50793, 1.68428, 2.21115, 2.21115}, {2.778, 0.373467, 3.64699, 4.24616, -4.24616, 5.57441, -3.15147, 0, 0, 1.78885, -1.78885, -1.78885, -12.7963, -3.70501, -16.7991, 18.2508, -1.74951, 2.29678, 0.461631, -0.461631, -4.50793, -5.64494, 1.74951, -2.29678, -7.61705, 7.61705, 11.6633, 1.68428, 2.21115, 2.21115}, {2.778, 0.373467, 3.64699, -1.41539, 1.41539, -1.85814, 9.45441, 0, 0, 1.78885, -1.78885, -1.78885, -1.68428, -2.21115, -2.21115, 11.3065, -7.41106, 9.72932, -10.6504, -1.9555, -19.0959, -5.64494, 1.74951, -2.29678, -0.461631, 0.461631, 4.50793, -5.47113, 9.36656, 9.36656}, {2.778, 0.373467, 3.64699, -1.41539, 1.41539, -1.85814, -3.15147, 0, 0, -5.36656, 5.36656, 5.36656, -1.68428, -2.21115, -2.21115, 5.64494, -1.74951, 2.29678, 0.461631, -0.461631, -4.50793, -16.7569, 0.255645, -16.8847, 5.19992, -5.19992, 11.9405, 14.2902, 2.21115, 2.21115}, {1.01058, 2.55106, -2.5536, -2.38953, 1.40121, 0.936349, 0.591368, -0.846655, -1.49431, 2.13502, 0.295801, -0.293237, 12.9281, -6.28572, -5.95493, 2.22265, -0.685462, 0.68968, -2.68006, 5.48424, 6.77218, -10.7627, -0.497743, 0.483267, 0.314591, -2.09762, -0.794931, -3.37, 0.680893, 2.20953}, {-0.336859, -0.850352, 0.8512, 7.1686, -4.20362, -2.80905, 0.591368, -0.846655, -1.49431, 2.13502, 0.295801, -0.293237, 4.71744, 2.72051, -5.61433, -0.142821, 2.70116, 6.66693, -0.314591, 2.09762, 0.794931, -2.22265, 0.685462, -0.68968, -8.2255, -3.28082, 0.378017, -3.37, 0.680893, 2.20953}, {-0.336859, -0.850352, 0.8512, -2.38953, 1.40121, 0.936349, -1.77411, 2.53997, 4.48294, 2.13502, 0.295801, -0.293237, 3.37, -0.680893, -2.20953, 11.7808, -6.29028, -3.05572, 1.03285, 5.49902, -2.60987, -2.22265, 0.685462, -0.68968, 0.314591, -2.09762, -0.794931, -11.9101, -0.502312, 3.38248}, {-0.336859, -0.850352, 0.8512, -2.38953, 1.40121, 0.936349, 0.591368, -0.846655, -1.49431, -6.40507, -0.887404, 0.879711, 3.37, -0.680893, -2.20953, 2.22265, -0.685462, 0.68968, -0.314591, 2.09762, 0.794931, -0.875216, 4.08687, -4.09448, 9.87272, -7.70244, -4.54033, -5.73548, 4.06751, 8.18678}, {1.77636e-15, 9.4517, 0, 1.85814, -1.41498, 1.41539, -3.64699, 2.77721, 0.373467, 1.78885, 1.78834, -1.78885, -9.72932, 11.3033, -7.41106, 2.21115, -1.6838, -2.21115, 19.0959, -10.6473, -1.9555, -9.36656, -5.46957, 9.36656, -4.50793, -0.461499, 0.461631, 2.29678, -5.64333, 1.74951}, {-2.22045e-16, -3.15057, 2.22045e-16, -5.57441, 4.24495, -4.24616, -3.64699, 2.77721, 0.373467, 1.78885, 1.78834, -1.78885, -2.29678, 18.2456, -1.74951, 16.7991, -12.7926, -3.70501, 4.50793, 0.461499, -0.461631, -2.21115, 1.6838, 2.21115, -11.6633, -7.61487, 7.61705, 2.29678, -5.64333, 1.74951}, {-2.22045e-16, -3.15057, 0, 1.85814, -1.41498, 1.41539, 10.941, -8.33162, -1.1204, 1.78885, 1.78834, -1.78885, -2.29678, 5.64333, -1.74951, -5.2214, 3.97613, -7.87269, 4.50793, 13.0638, -0.461631, -2.21115, 1.6838, 2.21115, -4.50793, -0.461499, 0.461631, -4.85864, -12.7967, 8.90493}, {4.44089e-16, -3.15057, 2.22045e-16, 1.85814, -1.41498, 1.41539, -3.64699, 2.77721, 0.373467, -5.36656, -5.36503, 5.36656, -2.29678, 5.64333, -1.74951, 2.21115, -1.6838, -2.21115, 4.50793, 0.461499, -0.461631, -2.21115, 14.2861, 2.21115, -11.9405, 5.19843, -5.19992, 16.8847, -16.7522, 0.255645}, {-3.98943, -5.23221, -5.22554, -1.94057, -2.54509, -0.198723, 0.61076, -1.54509, -1.54312, 0, 2.34612, 0, 8.51722, 11.1705, -1.11252, 1.64373, 5.05575, 2.15304, -4.84171, 5.93443, 5.92686, -1.64373, -14.4402, -2.15304, 2.39867, 0.245948, 0.245635, -0.754941, -0.990119, 1.90741}, {1.32981, 1.74407, 1.74185, 5.82171, 7.63528, 0.596168, 0.61076, -1.54509, -1.54312, 3.55726e-16, 2.34612, -8.98764e-16, -4.5643, -5.98616, -8.87479, -0.799305, 11.2361, 8.32553, -2.39867, -0.245948, -0.245635, -1.64373, -5.05575, -2.15304, 2.39867, -9.13852, 0.245635, -0.754941, -0.990119, 1.90741}, {1.32981, 1.74407, 1.74185, -1.94057, -2.54509, -0.198723, -1.83228, 4.63528, 4.62937, 0, 2.34612, 0, 0.754941, 0.990119, -1.90741, 9.40601, 15.2361, 2.94793, -7.71791, -7.22223, -7.21302, -1.64373, -5.05575, -2.15304, 2.39867, 0.245948, 0.245635, -0.754941, -10.3746, 1.90741}, {1.32981, 1.74407, 1.74185, -1.94057, -2.54509, -0.198723, 0.61076, -1.54509, -1.54312, 0, -7.03835, 0, 0.754941, 0.990119, -1.90741, 1.64373, 5.05575, 2.15304, -2.39867, -0.245948, -0.245635, -6.96297, -12.032, -9.12042, 10.1609, 10.4263, 1.04052, -3.19798, 5.19026, 8.0799}, {0, 8.88178e-15, -7.02938, -1.78885, -2.34612, -2.34313, 1.78885, 6.94365e-12, 7.11949e-12, 0, 2.34612, 0, 9.36656, 12.2844, 9.3725, 0, 2.89996, 2.89626, -9.36656, -3.63536e-11, -2.89626, 0, -12.2844, -2.89626, 2.21115, 8.57892e-12, 2.89626, -2.21115, -2.89996, -8.80017e-12}, {9.56516e-16, -1.33227e-15, 2.34313, 5.36656, 7.03835, 7.02938, 1.78885, 6.94156e-12, 7.11845e-12, 1.04189e-15, 2.34612, 4.14601e-27, 2.21115, 2.89996, -9.3725, -7.15542, 2.89996, 2.89626, -2.21115, -8.57892e-12, -2.89626, -2.22045e-15, -2.89996, -2.89626, 2.21115, -9.38447, 2.89626, -2.21115, -2.89996, -8.79889e-12}, {0, -4.44089e-16, 2.34313, -1.78885, -2.34612, -2.34313, -5.36656, -2.08325e-11, -2.13616e-11, 0, 2.34612, 0, 2.21115, 2.89996, 8.79971e-12, 7.15542, 12.2844, 12.2688, -2.21115, -8.58158e-12, -12.2688, 0, -2.89996, -2.89626, 2.21115, 8.58336e-12, 2.89626, -2.21115, -12.2844, -8.80146e-12}, {0, -1.33227e-15, 2.34313, -1.78885, -2.34612, -2.34313, 1.78885, 6.9426e-12, 7.11741e-12, 0, -7.03835, 0, 2.21115, 2.89996, 8.79586e-12, 0, 2.89996, 2.89626, -2.21115, -8.5798e-12, -2.89626, 0, -2.89996, -12.2688, 9.36656, 9.38447, 12.2688, -9.36656, -2.89996, -3.72672e-11}, {-0.596168, 7.62554, 5.82171, -1.74185, 1.74185, 1.32981, 0, 2.34313, 0, 1.54312, -1.54312, 0.61076, 8.87479, -5.97853, -4.5643, 2.15304, -5.0493, -1.64373, -0.245635, -9.12687, 2.39867, -8.32553, 11.2218, -0.799305, 0.245635, -0.245635, -2.39867, -1.90741, -0.988857, -0.754941}, {0.198723, -2.54185, -1.94057, 5.22554, -5.22554, -3.98943, 8.97618e-16, 2.34313, 3.55272e-16, 1.54312, -1.54312, 0.61076, 1.11252, 11.1562, 8.51722, 2.15304, -14.4218, -1.64373, -0.245635, 0.245635, 2.39867, -2.15304, 5.0493, 1.64373, -5.92686, 5.92686, -4.84171, -1.90741, -0.988857, -0.754941}, {0.198723, -2.54185, -1.94057, -1.74185, 1.74185, 1.32981, 0, -7.02938, 0, 1.54312, -1.54312, 0.61076, 1.90741, 0.988857, 0.754941, 9.12042, -12.0167, -6.96297, -1.04052, 10.413, 10.1609, -2.15304, 5.0493, 1.64373, 0.245635, -0.245635, -2.39867, -8.0799, 5.18364, -3.19798}, {0.198723, -2.54185, -1.94057, -1.74185, 1.74185, 1.32981, 0, 2.34313, 0, -4.62937, 4.62937, -1.83228, 1.90741, 0.988857, 0.754941, 2.15304, -5.0493, -1.64373, -0.245635, 0.245635, 2.39867, -2.94793, 15.2167, 9.40601, 7.21302, -7.21302, -7.71791, -1.90741, -10.3614, -0.754941}, {4.7272, -4.7272, -4.7272, 1.57573, 1.57573, -1.57573, -1.57573, -1.57573, -1.57573, 1.57573, -1.57573, 1.57573, -6.30294, -10.1984, 6.30294, 1.805e-12, 1.805e-12, 3.89543, 10.1984, 6.30294, 6.30294, -6.30294, 6.30294, -10.1984, -3.89543, 3.18634e-13, 3.18412e-13, -2.13962e-12, 3.89543, 2.14562e-12}, {-1.57573, 1.57573, 1.57573, -4.7272, -4.7272, 4.7272, -1.57573, -1.57573, -1.57573, 1.57573, -1.57573, 1.57573, 6.30294, -10.1984, -6.30294, 6.30294, 6.30294, 10.1984, 3.89543, -3.19744e-13, -3.20854e-13, -1.80294e-12, -1.80595e-12, -3.89543, -10.1984, 6.30294, -6.30294, -2.14428e-12, 3.89543, 2.13496e-12}, {-1.57573, 1.57573, 1.57573, 1.57573, 1.57573, -1.57573, 4.7272, 4.7272, 4.7272, 1.57573, -1.57573, 1.57573, 2.14517e-12, -3.89543, -2.13607e-12, -6.30294, -6.30294, 10.1984, 10.1984, -6.30294, -6.30294, -1.80294e-12, -1.80506e-12, -3.89543, -3.89543, 3.20854e-13, 3.20854e-13, -6.30294, 10.1984, -6.30294}, {-1.57573, 1.57573, 1.57573, 1.57573, 1.57573, -1.57573, -1.57573, -1.57573, -1.57573, -4.7272, 4.7272, -4.7272, 2.14184e-12, -3.89543, -2.13896e-12, 1.80522e-12, 1.80478e-12, 3.89543, 3.89543, -3.20188e-13, -3.2041e-13, 6.30294, -6.30294, -10.1984, -10.1984, -6.30294, 6.30294, 6.30294, 10.1984, 6.30294}, {4.817, -8.88178e-16, 1.11022e-15, -0.136178, 1.74185, 1.32981, 0.198723, -0.198723, -1.94057, 1.54312, -1.54312, 0.61076, 2.69775, -9.12042, -6.96297, -0.0773091, -1.90741, 0.754941, 0.94419, 1.04052, 10.1609, -6.09519, 8.0799, -3.19798, -1.73908, -0.245635, -2.39867, -2.15304, 2.15304, 1.64373}, {-1.60567, -2.22045e-16, 1.11022e-16, 0.408534, -5.22554, -3.98943, 0.198723, -0.198723, -1.94057, 1.54312, -1.54312, 0.61076, 8.57571, -2.15304, -1.64373, -0.872199, -1.11252, 8.51722, 1.73908, 0.245635, 2.39867, 0.0773091, 1.90741, -0.754941, -7.91157, 5.92686, -4.84171, -2.15304, 2.15304, 1.64373}, {-1.60567, -4.44089e-16, -2.22045e-16, -0.136178, 1.74185, 1.32981, -0.596168, 0.596168, 5.82171, 1.54312, -1.54312, 0.61076, 2.15304, -2.15304, -1.64373, 0.467403, -8.87479, -4.5643, 8.16175, 0.245635, 2.39867, 0.0773091, 1.90741, -0.754941, -1.73908, -0.245635, -2.39867, -8.32553, 8.32553, -0.799305}, {-1.60567, 0, 1.11022e-16, -0.136178, 1.74185, 1.32981, 0.198723, -0.198723, -1.94057, -4.62937, 4.62937, -1.83228, 2.15304, -2.15304, -1.64373, -0.0773091, -1.90741, 0.754941, 1.73908, 0.245635, 2.39867, 6.49998, 1.90741, -0.754941, -1.19437, -7.21302, -7.71791, -2.94793, 2.94793, 9.40601}, {7.01844, -8.88178e-16, 0, 2.33948, 2.34313, 1.78885, 7.30165e-12, 6.91814e-12, -1.78885, 0, -2.34313, 0, -9.35791, -12.2688, -9.36656, -2.89175, -2.89626, 0, 2.89175, -3.62235e-11, 9.36656, 2.89175, 12.2688, 0, -2.89175, 8.55094e-12, -2.21115, -9.02534e-12, 2.89626, 2.21115}, {-2.33948, 0, 0, -7.01844, -7.02938, -5.36656, 7.30269e-12, 6.9197e-12, -1.78885, 0, -2.34313, 0, 9.35791, -2.89626, -2.21115, -2.89175, -2.89626, 7.15542, 2.89175, -8.55316e-12, 2.21115, 2.89175, 2.89626, 0, -2.89175, 9.3725, -2.21115, -9.02662e-12, 2.89626, 2.21115}, {-2.33948, 0, 0, 2.33948, 2.34313, 1.78885, -2.19003e-11, -2.07544e-11, 5.36656, 0, -2.34313, 0, 9.02515e-12, -2.89626, -2.21115, -12.2497, -12.2688, -7.15542, 12.2497, -8.54961e-12, 2.21115, 2.89175, 2.89626, 0, -2.89175, 8.55049e-12, -2.21115, -9.02341e-12, 12.2688, 2.21115}, {-2.33948, 0, 0, 2.33948, 2.34313, 1.78885, 7.30373e-12, 6.92126e-12, -1.78885, 0, 7.02938, 0, 9.02965e-12, -2.89626, -2.21115, -2.89175, -2.89626, 0, 2.89175, -8.55493e-12, 2.21115, 12.2497, 2.89626, 0, -12.2497, -9.3725, -9.36656, -3.82428e-11, 2.89626, 9.36656}, {-1.82966, -4.6256, 4.62804, 1.3308, -1.74043, 0.137442, -1.94068, 0.198561, -0.20043, 0, 0, 1.60567, -7.722, 7.20714, 1.1872, 0.75386, 1.90585, 0.0778573, 9.40768, -2.94553, 2.95632, -0.75386, -1.90585, -6.50053, -1.64495, 2.15129, -2.1546, 2.39881, -0.245434, -1.73697}, {0.609885, 1.54187, -1.54268, -3.99239, 5.22128, -0.412327, -1.94068, 0.198561, -0.20043, -7.7358e-16, 7.91487e-17, 1.60567, -4.83836, -5.92203, 7.90769, 8.51658, 1.11161, 0.879578, 1.64495, -2.15129, 2.1546, -0.75386, -1.90585, -0.0778573, -1.64495, 2.15129, -8.57728, 2.39881, -0.245434, -1.73697}, {0.609885, 1.54187, -1.54268, 1.3308, -1.74043, 0.137442, 5.82204, -0.595682, 0.601291, 0, 0, 1.60567, -2.39881, 0.245434, 1.73697, -4.56932, 8.86756, -0.471912, -0.794587, -8.31875, 8.32532, -0.75386, -1.90585, -0.0778573, -1.64495, 2.15129, -2.1546, 2.39881, -0.245434, -8.15964}, {0.609885, 1.54187, -1.54268, 1.3308, -1.74043, 0.137442, -1.94068, 0.198561, -0.20043, 0, 0, -4.817, -2.39881, 0.245434, 1.73697, 0.75386, 1.90585, 0.0778573, 1.64495, -2.15129, 2.1546, -3.1934, -8.07331, 6.09286, -6.96814, 9.11299, -2.70437, 10.1615, -1.03968, -0.935249}, {-4.24457, 5.57441, -4.24616, -1.78937, -1.78885, -1.78885, 3.15147, 0, 0, -2.77696, 3.64699, 0.373467, 7.62038, 11.6633, 7.61705, -1.68365, 2.21115, 2.21115, -18.2502, 2.29678, -1.74951, 12.7915, -16.7991, -3.70501, 5.64429, -2.29678, 1.74951, -0.46292, -4.50793, -0.461631}, {1.41486, -1.85814, 1.41539, 5.3681, 5.36656, 5.36656, 3.15147, 2.85327e-15, 2.92187e-16, -2.77696, 3.64699, 0.373467, -5.1965, 11.9405, -5.19992, -14.2895, 2.21115, 2.21115, -5.64429, 2.29678, -1.74951, 1.68365, -2.21115, -2.21115, 16.7521, -16.8847, 0.255645, -0.46292, -4.50793, -0.461631}, {1.41486, -1.85814, 1.41539, -1.78937, -1.78885, -1.78885, -9.45441, 0, 0, -2.77696, 3.64699, 0.373467, 0.46292, 4.50793, 0.461631, 5.47381, 9.36656, 9.36656, -11.3037, 9.72932, -7.41106, 1.68365, -2.21115, -2.21115, 5.64429, -2.29678, 1.74951, 10.6449, -19.0959, -1.9555}, {1.41486, -1.85814, 1.41539, -1.78937, -1.78885, -1.78885, 3.15147, 0, 0, 8.33088, -10.941, -1.1204, 0.46292, 4.50793, 0.461631, -1.68365, 2.21115, 2.21115, -5.64429, 2.29678, -1.74951, -3.97577, 5.2214, -7.87269, 12.8018, 4.85864, 8.90493, -13.0688, -4.50793, -0.461631}, {-4.72788, -4.72653, -4.72653, 1.57551, -1.57551, -1.57551, -1.57551, 1.57551, -1.57596, -1.57596, -1.57551, 1.57596, -10.1975, 6.30204, 6.30204, -4.94049e-13, -4.8761e-13, 3.89543, 6.30148, -10.1969, 6.30439, 6.30384, 6.30204, -10.1993, 0.000556765, 3.89487, -0.000556765, 3.89543, -1.81499e-12, -1.81166e-12}, {1.57596, 1.57551, 1.57551, -4.72653, 4.72653, 4.72653, -1.57551, 1.57551, -1.57596, -1.57596, -1.57551, 1.57596, -10.1993, -6.30204, -6.30204, 6.30204, -6.30204, 10.1993, -0.000556765, -3.89487, 0.000556765, 4.80219e-13, 4.8355e-13, -3.89543, 6.30439, 10.1969, -6.30439, 3.89543, -1.81166e-12, -1.81499e-12}, {1.57596, 1.57551, 1.57551, 1.57551, -1.57551, -1.57551, 4.72653, -4.72653, 4.72788, -1.57596, -1.57551, 1.57596, -3.89543, 1.81788e-12, 1.81499e-12, -6.30204, 6.30204, 10.1975, -6.30439, -10.1969, -6.30148, 4.80885e-13, 4.68229e-13, -3.89543, 0.000556765, 3.89487, -0.000556765, 10.1993, 6.30204, -6.30384}, {1.57596, 1.57551, 1.57551, 1.57551, -1.57551, -1.57551, -1.57551, 1.57551, -1.57596, 4.72788, 4.72653, -4.72788, -3.89543, 1.81499e-12, 1.81499e-12, -4.96714e-13, -4.84501e-13, 3.89543, -0.000556765, -3.89487, 0.000556765, -6.30384, -6.30204, -10.1975, -6.30148, 10.1969, 6.30148, 10.1975, -6.30204, 6.30384}, {5.36656, -5.36656, -5.3681, 3.64699, -0.373467, 2.77696, 0, 0, -3.15147, -1.85814, -1.41539, -1.41486, -16.8847, -0.255645, -16.7521, -4.50793, 0.461631, 0.46292, 2.21115, -2.21115, 14.2895, 11.9405, 5.19992, 5.1965, -2.21115, 2.21115, -1.68365, 2.29678, 1.74951, 5.64429}, {-1.78885, 1.78885, 1.78937, -10.941, 1.1204, -8.33088, 0, 0, -3.15147, -1.85814, -1.41539, -1.41486, 4.85864, -8.90493, -12.8018, -4.50793, 0.461631, 13.0688, 2.21115, -2.21115, 1.68365, 4.50793, -0.461631, -0.46292, 5.2214, 7.87269, 3.97577, 2.29678, 1.74951, 5.64429}, {-1.78885, 1.78885, 1.78937, 3.64699, -0.373467, 2.77696, 0, 0, 9.45441, -1.85814, -1.41539, -1.41486, -2.29678, -1.74951, -5.64429, -19.0959, 1.9555, -10.6449, 9.36656, -9.36656, -5.47381, 4.50793, -0.461631, -0.46292, -2.21115, 2.21115, -1.68365, 9.72932, 7.41106, 11.3037}, {-1.78885, 1.78885, 1.78937, 3.64699, -0.373467, 2.77696, 0, 0, -3.15147, 5.57441, 4.24616, 4.24457, -2.29678, -1.74951, -5.64429, -4.50793, 0.461631, 0.46292, 2.21115, -2.21115, 1.68365, 11.6633, -7.61705, -7.62038, -16.7991, 3.70501, -12.7915, 2.29678, 1.74951, 18.2502}, {-0.570843, 5.57441, 4.24616, -0.373467, 3.64699, -0.373467, 1.78885, -1.78885, 1.78885, -1.60567, 0, 0, 1.7203, -16.7991, 3.70501, -1.74951, -2.29678, -1.74951, -9.60176, 11.6633, -7.61705, 8.17219, 2.29678, 1.74951, 2.44635, -4.50793, 0.461631, -0.226431, 2.21115, -2.21115}, {0.190281, -1.85814, -1.41539, 1.1204, -10.941, 1.1204, 1.78885, -1.78885, 1.78885, -1.60567, 0, 0, -0.534693, 5.2214, 7.87269, -8.90493, 4.85864, -8.90493, -2.44635, 4.50793, -0.461631, 1.74951, 2.29678, 1.74951, 8.86902, -4.50793, 0.461631, -0.226431, 2.21115, -2.21115}, {0.190281, -1.85814, -1.41539, -0.373467, 3.64699, -0.373467, -5.36656, 5.36656, -5.36656, -1.60567, 0, 0, 0.226431, -2.21115, 2.21115, -0.255645, -16.8847, -0.255645, -3.20747, 11.9405, 5.19992, 1.74951, 2.29678, 1.74951, 2.44635, -4.50793, 0.461631, 6.19624, 2.21115, -2.21115}, {0.190281, -1.85814, -1.41539, -0.373467, 3.64699, -0.373467, 1.78885, -1.78885, 1.78885, 4.817, 0, 0, 0.226431, -2.21115, 2.21115, -1.74951, -2.29678, -1.74951, -2.44635, 4.50793, -0.461631, 0.988391, 9.72932, 7.41106, 3.94022, -19.0959, 1.9555, -7.38185, 9.36656, -9.36656}, {-2.4085, 2.4085, -2.4085, 0.802834, 0.802834, -0.802834, 0.0313083, 1.63555, 1.63555, -1.63698, -1.63555, -1.63555, -5.19605, -3.21134, 3.21134, -1.03106, -3.014, -1.02929, -1.15629, -7.57148, -9.55619, 7.57896, 9.55619, 7.57148, 1.03106, 1.02929, 3.014, 1.98471, -5.77316e-15, 8.88178e-15}, {0.802834, -0.802834, 0.802834, -2.4085, -2.4085, 2.4085, 0.0313083, 1.63555, 1.63555, -1.63698, -1.63555, -1.63555, -5.19605, 3.21134, -3.21134, -1.15629, -9.55619, -7.57148, -1.03106, -1.02929, -3.014, 1.03106, 3.014, 1.02929, 7.57896, 7.57148, 9.55619, 1.98471, -6.66134e-15, 7.99361e-15}, {0.802834, -0.802834, 0.802834, 0.802834, 0.802834, -0.802834, -0.0939249, -4.90664, -4.90664, -1.63698, -1.63555, -1.63555, -1.98471, 6.66134e-15, -7.54952e-15, -4.24239, -6.22534, 2.18205, -4.24239, 2.18205, -6.22534, 1.03106, 3.014, 1.02929, 1.03106, 1.02929, 3.014, 8.53262, 6.54219, 6.54219}, {0.802834, -0.802834, 0.802834, 0.802834, 0.802834, -0.802834, 0.0313083, 1.63555, 1.63555, 4.91093, 4.90664, 4.90664, -1.98471, 7.10543e-15, -6.21725e-15, -1.03106, -3.014, -1.02929, -1.03106, -1.02929, -3.014, -2.18028, 6.22534, -2.18205, -2.18028, -2.18205, 6.22534, 1.85948, -6.54219, -6.54219}, {5.36656, 5.36656, -5.36656, 0, 0, -3.15147, 3.15147, 0, 0, -1.36261, 1.78885, 1.36261, 2.21115, 2.21115, 14.2902, -3.89543, 0, 3.89543, -14.2902, 2.21115, -2.21115, 9.34589, -7.15542, -9.34589, 1.68428, -2.21115, 2.21115, -2.21115, -2.21115, -1.68428}, {-1.78885, -1.78885, 1.78885, 0, 0, 9.45441, 3.15147, 1.39953e-15, 1.06606e-15, -1.36261, 1.78885, 1.36261, 9.36656, 9.36656, -5.47113, -16.5013, -7.32805e-15, 3.89543, -1.68428, 2.21115, -2.21115, 3.89543, 3.06219e-15, -3.89543, 7.13474, -9.36656, -3.23931, -2.21115, -2.21115, -1.68428}, {-1.78885, -1.78885, 1.78885, 0, 0, -3.15147, -9.45441, 0, 0, -1.36261, 1.78885, 1.36261, 2.21115, 2.21115, 1.68428, -3.89543, 0, 16.5013, 5.47113, 9.36656, -9.36656, 3.89543, 1.33227e-15, -3.89543, 1.68428, -2.21115, 2.21115, 3.23931, -9.36656, -7.13474}, {-1.78885, -1.78885, 1.78885, 0, 0, -3.15147, 3.15147, 0, 0, 4.08784, -5.36656, -4.08784, 2.21115, 2.21115, 1.68428, -3.89543, 0, 3.89543, -1.68428, 2.21115, -2.21115, 11.0508, 7.15542, -11.0508, 1.68428, -2.21115, 14.817, -14.817, -2.21115, -1.68428}, {1.55756, -1.55231, 6.66925, 0.74491, 1.59978, -0.633715, 1.29557, -1.29442, 0.512752, -1.52129, -0.822804, 2.34405, -3.25865, -9.01615, 6.06606, -2.52217, -0.377453, 0.149519, -6.14194, 6.13806, 0.0630791, 8.60734, 3.66867, -9.52571, 0.95966, -0.960396, -2.11409, 0.279008, 2.61703, -3.5312}, {-0.519188, 0.517438, -2.22308, -2.23473, -4.79934, 1.90115, 1.29557, -1.29442, 0.512752, -1.52129, -0.822804, 2.34405, 1.79774, -4.68678, 12.4235, -7.70445, 4.80021, -1.90149, -0.95966, 0.960396, 2.11409, 2.52217, 0.377453, -0.149519, 7.04482, 2.33082, -11.4903, 0.279008, 2.61703, -3.5312}, {-0.519188, 0.517438, -2.22308, 0.74491, 1.59978, -0.633715, -3.88671, 3.88325, -1.53826, -1.52129, -0.822804, 2.34405, -0.279008, -2.61703, 3.5312, -5.50181, -6.77658, 2.68438, 1.11709, -1.10936, 11.0064, 2.52217, 0.377453, -0.149519, 0.95966, -0.960396, -2.11409, 6.36417, 5.90824, -12.9074}, {-0.519188, 0.517438, -2.22308, 0.74491, 1.59978, -0.633715, 1.29557, -1.29442, 0.512752, 4.56387, 2.46841, -7.03214, -0.279008, -2.61703, 3.5312, -2.52217, -0.377453, 0.149519, -0.95966, 0.960396, 2.11409, 4.59892, -1.6923, 8.74282, -2.01998, -7.35952, 0.420775, -4.90327, 7.79469, -5.58221}, {-3.62807, -1.43344, -3.62246, -0.761007, 2.64249, 1.57539, -0.983272, -2.40589, -0.977465, 0.534922, -0.714416, -1.80541, 2.48984, -14.4269, -9.74136, 2.15605, -0.292457, -0.73907, 3.65363, 12.0068, 3.62554, -4.29574, 3.15012, 7.96069, 0.279456, -2.38324, 0.28432, 0.554191, 3.85691, 3.43982}, {1.20936, 0.477813, 1.20749, 2.28302, -7.92748, -4.72616, -0.983272, -2.40589, -0.977465, 0.534922, -0.714416, -1.80541, -5.39162, -5.76816, -8.26976, 6.08913, 9.33111, 3.17079, -0.279456, 2.38324, -0.28432, -2.15605, 0.292457, 0.73907, -1.86023, 0.474427, 7.50594, 0.554191, 3.85691, 3.43982}, {1.20936, 0.477813, 1.20749, -0.761007, 2.64249, 1.57539, 2.94982, 7.21767, 2.9324, 0.534922, -0.714416, -1.80541, -0.554191, -3.85691, -3.43982, 5.20007, -10.8624, -7.04061, -5.11688, 0.471983, -5.11426, -2.15605, 0.292457, 0.73907, 0.279456, -2.38324, 0.28432, -1.5855, 6.71457, 10.6614}, {1.20936, 0.477813, 1.20749, -0.761007, 2.64249, 1.57539, -0.983272, -2.40589, -0.977465, -1.60477, 2.14325, 5.41622, -0.554191, -3.85691, -3.43982, 2.15605, -0.292457, -0.73907, -0.279456, 2.38324, -0.28432, -6.99347, -1.6188, -4.09087, 3.32348, -12.9532, -6.01722, 4.48728, 13.4805, 7.34968}, {5.81909, -7.61025, 0.600985, 0.610485, 1.54108, -1.54262, 0, -2.33948, 0, 1.32921, -1.73835, 1.74295, -0.798945, -11.2048, 8.32487, -0.754601, 0.986874, 1.90678, 2.3976, 9.11407, 0.24762, -4.56224, 5.96654, -8.87857, -2.3976, 0.243842, -0.24762, -1.643, 5.04048, -2.1544}, {-1.9397, 2.53675, -0.200328, -1.83146, -4.62324, 4.62785, 0, -2.33948, 0, 1.32921, -1.73835, 1.74295, 9.40178, -15.1875, 2.95571, -0.754601, 10.3448, 1.90678, 2.3976, -0.243842, 0.24762, 0.754601, -0.986874, -1.90678, -7.71444, 7.19725, -7.21941, -1.643, 5.04048, -2.1544}, {-1.9397, 2.53675, -0.200328, 0.610485, 1.54108, -1.54262, 0, 7.01844, 0, 1.32921, -1.73835, 1.74295, 1.643, -5.04048, 2.1544, -3.19654, -5.17745, 8.07725, 10.1564, -10.3908, 1.04893, 0.754601, -0.986874, -1.90678, -2.3976, 0.243842, -0.24762, -6.95984, 11.9939, -9.12619}, {-1.9397, 2.53675, -0.200328, 0.610485, 1.54108, -1.54262, 0, -2.33948, 0, -3.98763, 5.21506, -5.22884, 1.643, -5.04048, 2.1544, -0.754601, 0.986874, 1.90678, 2.3976, -0.243842, 0.24762, 8.51339, -11.1339, -1.10547, -4.83954, -5.92048, 5.92285, -1.643, 14.3984, -2.1544}, {4.33994, -4.33994, -1.54017, 0, 0, -1.80556, -0.572575, -1.44665, 0.668413, 2.01922, 1.97175e-12, 0.623753, 1.78815, -1.78815, 8.81943, 0.707741, 1.78815, 1.40559, 4.7862, 5.78659, -4.13444, -8.78463, -1.78815, -3.9006, -2.4959, -2.43721e-12, 1.46079, -1.78815, 1.78815, -1.5972}, {-1.44665, 1.44665, 0.51339, 0, 0, 5.41667, -0.572575, -1.44665, 0.668413, 2.01922, 1.97066e-12, 0.623753, 7.57474, -7.57474, -0.456355, 2.99804, 7.57474, -1.26807, 2.4959, 2.43479e-12, -1.46079, -0.707741, -1.78815, -1.40559, -10.5728, -1.03185e-11, -1.03422, -1.78815, 1.78815, -1.5972}, {-1.44665, 1.44665, 0.51339, 0, 0, -1.80556, 1.71772, 4.33994, -2.00524, 2.01922, 1.97175e-12, 0.623753, 1.78815, -1.78815, 1.5972, 0.707741, 1.78815, 8.62781, 8.28248, -5.78659, -3.51435, -0.707741, -1.78815, -1.40559, -2.4959, -2.43721e-12, 1.46079, -9.86504, 1.78815, -4.09222}, {-1.44665, 1.44665, 0.51339, 0, 0, -1.80556, -0.572575, -1.44665, 0.668413, -6.05767, -5.91959e-12, -1.87126, 1.78815, -1.78815, 1.5972, 0.707741, 1.78815, 1.40559, 2.4959, 2.43793e-12, -1.46079, 5.07885, -7.57474, -3.45914, -2.4959, -2.43901e-12, 8.68301, 0.502145, 7.57474, -4.27086}, {5.36656, 5.36656, 5.36656, 0.373467, 0.373467, 3.64699, -1.12838e-15, 1.60567, 1.48135e-15, 1.41539, -0.190281, -1.85814, 0.255645, 0.255645, -16.8847, -0.461631, -2.44635, -4.50793, 2.21115, -6.19624, 2.21115, -5.19992, 3.20747, 11.9405, -2.21115, -0.226431, -2.21115, -1.74951, -1.74951, 2.29678}, {-1.78885, -1.78885, -1.78885, -1.1204, -1.1204, -10.941, -5.64191e-16, 1.60567, 7.40676e-16, 1.41539, -0.190281, -1.85814, 8.90493, 8.90493, 4.85864, -0.461631, -8.86902, -4.50793, 2.21115, 0.226431, 2.21115, 0.461631, 2.44635, 4.50793, -7.87269, 0.534693, 5.2214, -1.74951, -1.74951, 2.29678}, {-1.78885, -1.78885, -1.78885, 0.373467, 0.373467, 3.64699, 0, -4.817, 0, 1.41539, -0.190281, -1.85814, 1.74951, 1.74951, -2.29678, -1.9555, -3.94022, -19.0959, 9.36656, 7.38185, 9.36656, 0.461631, 2.44635, 4.50793, -2.21115, -0.226431, -2.21115, -7.41106, -0.988391, 9.72932}, {-1.78885, -1.78885, -1.78885, 0.373467, 0.373467, 3.64699, -1.12838e-15, 1.60567, 1.48135e-15, -4.24616, 0.570843, 5.57441, 1.74951, 1.74951, -2.29678, -0.461631, -2.44635, -4.50793, 2.21115, 0.226431, 2.21115, 7.61705, 9.60176, 11.6633, -3.70501, -1.7203, -16.7991, -1.74951, -8.17219, 2.29678}, {-4.24616, -4.24616, 5.57441, 3.15147, -5.84374e-16, -5.70654e-15, -1.78885, -1.78885, -1.78885, -2.778, 0.373467, 3.64699, -18.2508, -1.74951, 2.29678, -1.68428, 2.21115, 2.21115, 7.61705, 7.61705, 11.6633, 12.7963, -3.70501, -16.7991, -0.461631, -0.461631, -4.50793, 5.64494, 1.74951, -2.29678}, {1.41539, 1.41539, -1.85814, -9.45441, 5.07516e-15, 1.27584e-14, -1.78885, -1.78885, -1.78885, -2.778, 0.373467, 3.64699, -11.3065, -7.41106, 9.72932, 5.47113, 9.36656, 9.36656, 0.461631, 0.461631, 4.50793, 1.68428, -2.21115, -2.21115, 10.6504, -1.9555, -19.0959, 5.64494, 1.74951, -2.29678}, {1.41539, 1.41539, -1.85814, 3.15147, 0, 0, 5.36656, 5.36656, 5.36656, -2.778, 0.373467, 3.64699, -5.64494, -1.74951, 2.29678, -14.2902, 2.21115, 2.21115, -5.19992, -5.19992, 11.9405, 1.68428, -2.21115, -2.21115, -0.461631, -0.461631, -4.50793, 16.7569, 0.255645, -16.8847}, {1.41539, 1.41539, -1.85814, 3.15147, -5.84374e-16, -5.70654e-15, -1.78885, -1.78885, -1.78885, 8.334, -1.1204, -10.941, -5.64494, -1.74951, 2.29678, -1.68428, 2.21115, 2.21115, 0.461631, 0.461631, 4.50793, -3.97726, -7.87269, 5.2214, -13.0675, -0.461631, -4.50793, 12.8004, 8.90493, 4.85864}, {0.972456, 0.972456, -8.84811, 1.4362, 1.4362, 1.4362, -1.66806, -0.0623937, -1.66806, 0.556017, -1.04965, -2.71751, -7.11935, -7.11935, -11.1656, 0.286601, -1.69811, 0.286601, 9.13476, 0.727372, 5.08846, -2.51067, 5.89672, 10.5834, -2.46251, -0.477797, 1.58378, 1.37456, 1.37456, 5.42086}, {-0.324152, -0.324152, 2.94937, -4.30859, -4.30859, -4.30859, -1.66806, -0.0623937, -1.66806, 0.556017, -1.04965, -2.71751, -0.0779551, -0.0779551, -17.2183, 6.95885, -1.44854, 6.95885, 2.46251, 0.477797, -1.58378, -0.286601, 1.69811, -0.286601, -4.68658, 3.72081, 12.4538, 1.37456, 1.37456, 5.42086}, {-0.324152, -0.324152, 2.94937, 1.4362, 1.4362, 1.4362, 5.00419, 0.187181, 5.00419, 0.556017, -1.04965, -2.71751, -1.37456, -1.37456, -5.42086, -5.45818, -7.4429, -5.45818, 3.75912, 1.7744, -13.3813, -0.286601, 1.69811, -0.286601, -2.46251, -0.477797, 1.58378, -0.849506, 5.57317, 16.2909}, {-0.324152, -0.324152, 2.94937, 1.4362, 1.4362, 1.4362, -1.66806, -0.0623937, -1.66806, -1.66805, 3.14895, 8.15252, -1.37456, -1.37456, -5.42086, 0.286601, -1.69811, 0.286601, 2.46251, 0.477797, -1.58378, 1.01001, 2.99472, -12.0841, -8.2073, -6.22258, -4.161, 8.04681, 1.62414, 12.0931}, {3.33613, 3.33613, 13.1567, 1.4362, 1.4362, 1.4362, 0.767151, -2.38432, -2.38432, -1.0913, 2.06017, 5.33369, -6.14546, -6.14546, -2.09916, -2.72349, 1.17194, 1.17194, -2.64229, 13.859, 17.9053, 7.0887, -9.4126, -22.5067, -0.426311, -4.32174, -8.36804, 0.400674, 0.400674, -3.64562}, {-1.11204, -1.11204, -4.38557, -4.30859, -4.30859, -4.30859, 0.767151, -2.38432, -2.38432, -1.0913, 2.06017, 5.33369, 4.0475, 4.0475, 21.1879, -5.79209, 10.7092, 10.7092, 0.426311, 4.32174, 8.36804, 2.72349, -1.17194, -1.17194, 3.9389, -12.5624, -29.7028, 0.400674, 0.400674, -3.64562}, {-1.11204, -1.11204, -4.38557, 1.4362, 1.4362, 1.4362, -2.30145, 7.15295, 7.15295, -1.0913, 2.06017, 5.33369, -0.400674, -0.400674, 3.64562, -8.46827, -4.57284, -4.57284, 4.87449, 8.76992, 25.9103, 2.72349, -1.17194, -1.17194, -0.426311, -4.32174, -8.36804, 4.76589, -7.83999, -24.9804}, {-1.11204, -1.11204, -4.38557, 1.4362, 1.4362, 1.4362, 0.767151, -2.38432, -2.38432, 3.27391, -6.1805, -16.0011, -0.400674, -0.400674, 3.64562, -2.72349, 1.17194, 1.17194, 0.426311, 4.32174, 8.36804, 7.17167, 3.27624, 16.3703, -6.1711, -10.0665, -14.1128, -2.66793, 9.93794, 5.89165}, {-6.6428, 1.48026, 1.47837, 0.647646, 0.70771, -1.63632, -0.372676, 0.942791, 0.941589, -2.48924, -1.15708, 1.18752, -6.1281, -3.09572, 9.177, -0.339882, -2.04013, 0.858732, -0.785628, -4.32662, -4.3211, 10.2968, 6.66845, -5.60881, 2.27633, 0.555453, 0.554744, 3.53752, 0.264876, -2.63172}, {2.21427, -0.493421, -0.492791, -1.94294, -2.12313, 4.90895, -0.372676, 0.942791, 0.941589, -2.48924, -1.15708, 1.18752, -12.3946, 1.70881, 4.60289, 1.15082, -5.8113, -2.90762, -2.27633, -0.555453, -0.554744, 0.339882, 2.04013, -0.858732, 12.2333, 5.18378, -4.19534, 3.53752, 0.264876, -2.63172}, {2.21427, -0.493421, -0.492791, 0.647646, 0.70771, -1.63632, 1.11803, -2.82837, -2.82477, -2.48924, -1.15708, 1.18752, -3.53752, -0.264876, 2.63172, -2.93046, -4.87097, 7.404, -11.1334, 1.41823, 1.41642, 0.339882, 2.04013, -0.858732, 2.27633, 0.555453, 0.554744, 13.4945, 4.8932, -7.38181}, {2.21427, -0.493421, -0.492791, 0.647646, 0.70771, -1.63632, -0.372676, 0.942791, 0.941589, 7.46771, 3.47124, -3.56256, -3.53752, -0.264876, 2.63172, -0.339882, -2.04013, 0.858732, -2.27633, -0.555453, -0.554744, -8.51718, 4.01381, 1.11243, -0.314251, -2.27539, 7.10002, 5.02822, -3.50629, -6.39808}, {1.12186, -2.82659, -2.82659, -1.84098, -0.449088, -0.449088, 0.510215, -1.28552, 0.320147, 1.70472, 0.792411, -0.813257, 10.1017, 1.18683, 1.18683, 1.64492, 2.14409, 0.15938, -2.20929, 5.56645, -2.84093, -8.4638, -5.31374, 3.09365, 0.16843, -0.424371, 1.56034, -2.73781, 0.609518, 0.609518}, {-0.373952, 0.942198, 0.942198, 5.52295, 1.34726, 1.34726, 0.510215, -1.28552, 0.320147, 1.70472, 0.792411, -0.813257, 4.23362, -4.37831, -4.37831, -0.395942, 7.28618, -1.12121, -0.16843, 0.424371, -1.56034, -1.64492, -2.14409, -0.15938, -6.65045, -3.59401, 4.81337, -2.73781, 0.609518, 0.609518}, {-0.373952, 0.942198, 0.942198, -1.84098, -0.449088, -0.449088, -1.53064, 3.85656, -0.960441, 1.70472, 0.792411, -0.813257, 2.73781, -0.609518, -0.609518, 9.00885, 3.94045, 1.95573, 1.32738, -3.34442, -5.32914, -1.64492, -2.14409, -0.15938, 0.16843, -0.424371, 1.56034, -9.55669, -2.56013, 3.86255}, {-0.373952, 0.942198, 0.942198, -1.84098, -0.449088, -0.449088, 0.510215, -1.28552, 0.320147, -5.11416, -2.37723, 2.43977, 2.73781, -0.609518, -0.609518, 1.64492, 2.14409, 0.15938, -0.16843, 0.424371, -1.56034, -0.149109, -5.91289, -3.92817, 7.53236, 1.37198, 3.3567, -4.77867, 5.7516, -0.67107}, {0.461366, -4.35523, -1.72378, -0.132927, -0.133043, -2.07188, -0.954792, -0.955627, -0.378232, 1.24151, -0.363075, 1.87552, 0.886107, -1.09783, 10.1383, 1.34449, 1.34567, 3.0285, 5.18945, 3.20927, 1.27021, -6.31053, 0.10663, -10.5306, -1.37028, 0.613236, 0.242715, -0.3544, 1.63001, -1.85075}, {-0.153789, 1.45174, 0.574593, 0.39878, 0.399129, 6.21564, -0.954792, -0.955627, -0.378232, 1.24151, -0.363075, 1.87552, 0.969555, -7.43698, -0.447622, 5.16366, 5.16818, 4.54143, 1.37028, -0.613236, -0.242715, -1.34449, -1.34567, -3.0285, -6.33631, 2.06554, -7.25936, -0.3544, 1.63001, -1.85075}, {-0.153789, 1.45174, 0.574593, -0.132927, -0.133043, -2.07188, 2.86438, 2.86688, 1.1347, 1.24151, -0.363075, 1.87552, 0.3544, -1.63001, 1.85075, 1.8762, 1.87784, 11.316, 1.98544, -6.42021, -2.54109, -1.34449, -1.34567, -3.0285, -1.37028, 0.613236, 0.242715, -5.32043, 3.08231, -9.35282}, {-0.153789, 1.45174, 0.574593, -0.132927, -0.133043, -2.07188, -0.954792, -0.955627, -0.378232, -3.72452, 1.08923, -5.62656, 0.3544, -1.63001, 1.85075, 1.34449, 1.34567, 3.0285, 1.37028, -0.613236, -0.242715, -0.72934, -7.15265, -5.32687, -0.838575, 1.14541, 8.53023, 3.46477, 5.45251, -0.337821}, {-5.55112e-16, 7.02938, 0, 1.54187, 1.54427, 0.609885, -1.74043, -1.74314, 1.3308, 0.198561, 2.542, -1.94068, -8.07331, -5.18964, -3.1934, 0.245434, 0.245817, -2.39881, 9.11299, 12.0235, -6.96814, -1.03968, -10.4138, 10.1615, -2.15129, -5.0509, 1.64495, 1.90585, -0.987441, 0.75386}, {2.77556e-17, -2.34313, 2.22045e-16, -4.6256, -4.63281, -1.82966, -1.74043, -1.74314, 1.3308, 0.198561, 2.542, -1.94068, -1.90585, 10.3599, -0.75386, 7.20714, 7.21837, -7.722, 2.15129, 5.0509, -1.64495, -0.245434, -0.245817, 2.39881, -2.94553, -15.2189, 9.40768, 1.90585, -0.987441, 0.75386}, {5.55112e-17, -2.34313, 0, 1.54187, 1.54427, 0.609885, 5.22128, 5.22942, -3.99239, 0.198561, 2.542, -1.94068, -1.90585, 0.987441, -0.75386, -5.92203, -5.93126, -4.83836, 2.15129, 14.4234, -1.64495, -0.245434, -0.245817, 2.39881, -2.15129, -5.0509, 1.64495, 1.11161, -11.1554, 8.51658}, {2.498e-16, -2.34313, -2.22045e-16, 1.54187, 1.54427, 0.609885, -1.74043, -1.74314, 1.3308, -0.595682, -7.62599, 5.82204, -1.90585, 0.987441, -0.75386, 0.245434, 0.245817, -2.39881, 2.15129, 5.0509, -1.64495, -0.245434, 9.12668, 2.39881, -8.31875, -11.228, -0.794587, 8.86756, 5.98512, -4.56932}, {4.8128, -8.88178e-16, 4.44089e-16, 1.54178, 1.54312, 0.61076, 0.198549, 0.198723, -1.94057, -0.136059, -1.74185, 1.32981, -6.08986, -8.0799, -3.19798, -2.15116, -2.15304, 1.64373, 0.943366, -1.04052, 10.1609, 2.6954, 9.12042, -6.96297, -1.73756, 0.245635, -2.39867, -0.0772416, 1.90741, 0.754941}, {-1.60427, 0, 0, -4.62533, -4.62937, -1.83228, 0.198549, 0.198723, -1.94057, -0.136059, -1.74185, 1.32981, 6.49431, -1.90741, -0.754941, -2.94536, -2.94793, 9.40601, 1.73756, -0.245635, 2.39867, 2.15116, 2.15304, -1.64373, -1.19332, 7.21302, -7.71791, -0.0772416, 1.90741, 0.754941}, {-1.60427, 0, 2.22045e-16, 1.54178, 1.54312, 0.61076, -0.595647, -0.596168, 5.82171, -0.136059, -1.74185, 1.32981, 0.0772416, -1.90741, -0.754941, -8.31826, -8.32553, -0.799305, 8.15463, -0.245635, 2.39867, 2.15116, 2.15304, -1.64373, -1.73756, 0.245635, -2.39867, 0.466995, 8.87479, -4.5643}, {-1.60427, 0, 0, 1.54178, 1.54312, 0.61076, 0.198549, 0.198723, -1.94057, 0.408178, 5.22554, -3.98943, 0.0772416, -1.90741, -0.754941, -2.15116, -2.15304, 1.64373, 1.73756, -0.245635, 2.39867, 8.56822, 2.15304, -1.64373, -7.90467, -5.92686, -4.84171, -0.871438, 1.11252, 8.51722}, {4.91028, -4.91028, -4.91028, -1.57573, -1.57573, 1.57573, 1.57573, 1.57573, 1.57573, 1.63676, -1.63676, -4.78823, 10.2738, 6.2275, -10.2738, -3.0731e-13, -3.13971e-13, -3.89543, -6.2275, -10.2738, -10.2738, -6.54704, 6.54704, 23.0483, -0.0754334, 3.97086, 3.97086, -3.97086, 0.0754334, 3.97086}, {-1.63676, 1.63676, 1.63676, 4.7272, 4.7272, -4.7272, 1.57573, 1.57573, 1.57573, 1.63676, -1.63676, -4.78823, 10.5179, -6.62248, -10.5179, -6.30294, -6.30294, -10.1984, 0.0754334, -3.97086, -3.97086, 3.02978e-13, 3.03648e-13, 3.89543, -6.62248, 10.5179, 23.1238, -3.97086, 0.0754334, 3.97086}, {-1.63676, 1.63676, 1.63676, -1.57573, -1.57573, 1.57573, -4.7272, -4.7272, -4.7272, 1.63676, -1.63676, -4.78823, 3.97086, -0.0754334, -3.97086, 6.30294, 6.30294, -10.1984, 6.62248, -10.5179, -10.5179, 3.08973e-13, 3.06757e-13, 3.89543, -0.0754334, 3.97086, 3.97086, -10.5179, 6.62248, 23.1238}, {-1.63676, 1.63676, 1.63676, -1.57573, -1.57573, 1.57573, 1.57573, 1.57573, 1.57573, -4.91028, 4.91028, 14.3647, 3.97086, -0.0754334, -3.97086, -3.01759e-13, -3.07976e-13, -3.89543, 0.0754334, -3.97086, -3.97086, 6.54704, -6.54704, -2.65162, 6.2275, 10.2738, -2.33207, -10.2738, -6.2275, -2.33207}, {4.24616, -5.57441, -4.24616, 5.84374e-16, 5.70654e-15, 3.15147, 1.78885, 1.78885, -1.78885, -0.373467, -3.64699, -2.778, 1.74951, -2.29678, -18.2508, -2.21115, -2.21115, -1.68428, -7.61705, -11.6633, 7.61705, 3.70501, 16.7991, 12.7963, 0.461631, 4.50793, -0.461631, -1.74951, 2.29678, 5.64494}, {-1.41539, 1.85814, 1.41539, -5.07516e-15, -1.27584e-14, -9.45441, 1.78885, 1.78885, -1.78885, -0.373467, -3.64699, -2.778, 7.41106, -9.72932, -11.3065, -9.36656, -9.36656, 5.47113, -0.461631, -4.50793, 0.461631, 2.21115, 2.21115, 1.68428, 1.9555, 19.0959, 10.6504, -1.74951, 2.29678, 5.64494}, {-1.41539, 1.85814, 1.41539, 0, 0, 3.15147, -5.36656, -5.36656, 5.36656, -0.373467, -3.64699, -2.778, 1.74951, -2.29678, -5.64494, -2.21115, -2.21115, -14.2902, 5.19992, -11.9405, -5.19992, 2.21115, 2.21115, 1.68428, 0.461631, 4.50793, -0.461631, -0.255645, 16.8847, 16.7569}, {-1.41539, 1.85814, 1.41539, 5.84374e-16, 5.70654e-15, 3.15147, 1.78885, 1.78885, -1.78885, 1.1204, 10.941, 8.334, 1.74951, -2.29678, -5.64494, -2.21115, -2.21115, -1.68428, -0.461631, -4.50793, 0.461631, 7.87269, -5.2214, -3.97726, 0.461631, 4.50793, -13.0675, -8.90493, -4.85864, 12.8004}, {-5.36656, -5.36656, 5.36656, -0.373467, -3.64699, 0.373467, -1.60567, 0, 0, 0.190281, 1.85814, 1.41539, -0.255645, 16.8847, 0.255645, 2.44635, 4.50793, -0.461631, 6.19624, -2.21115, 2.21115, -3.20747, -11.9405, -5.19992, 0.226431, 2.21115, -2.21115, 1.74951, -2.29678, -1.74951}, {1.78885, 1.78885, -1.78885, 1.1204, 10.941, -1.1204, -1.60567, 0, 0, 0.190281, 1.85814, 1.41539, -8.90493, -4.85864, 8.90493, 8.86902, 4.50793, -0.461631, -0.226431, -2.21115, 2.21115, -2.44635, -4.50793, 0.461631, -0.534693, -5.2214, -7.87269, 1.74951, -2.29678, -1.74951}, {1.78885, 1.78885, -1.78885, -0.373467, -3.64699, 0.373467, 4.817, 0, 0, 0.190281, 1.85814, 1.41539, -1.74951, 2.29678, 1.74951, 3.94022, 19.0959, -1.9555, -7.38185, -9.36656, 9.36656, -2.44635, -4.50793, 0.461631, 0.226431, 2.21115, -2.21115, 0.988391, -9.72932, -7.41106}, {1.78885, 1.78885, -1.78885, -0.373467, -3.64699, 0.373467, -1.60567, 0, 0, -0.570843, -5.57441, -4.24616, -1.74951, 2.29678, 1.74951, 2.44635, 4.50793, -0.461631, -0.226431, -2.21115, 2.21115, -9.60176, -11.6633, 7.61705, 1.7203, 16.7991, -3.70501, 8.17219, -2.29678, -1.74951}, {-1.80799, -0.0150891, -4.77555, -0.827431, 1.45271, 0.471751, -0.860099, -1.45095, 0.0849431, 1.08487, -0.00678866, -2.14855, 3.58755, -7.6127, -4.43776, 2.0859, -0.00217419, -0.688112, 3.7586, 7.59105, -2.4124, -6.42536, 0.0293288, 9.28229, -0.318207, -1.78726, 2.07263, -0.277826, 1.80186, 2.55075}, {0.602665, 0.0050297, 1.59185, 2.48229, -4.35813, -1.41525, -0.860099, -1.45095, 0.0849431, 1.08487, -0.00678866, -2.14855, -2.13283, -1.82198, -8.91816, 5.5263, 5.80162, -1.02788, 0.318207, 1.78726, -2.07263, -2.0859, 0.00217419, 0.688112, -4.65767, -1.7601, 10.6668, -0.277826, 1.80186, 2.55075}, {0.602665, 0.0050297, 1.59185, -0.827431, 1.45271, 0.471751, 2.5803, 4.35285, -0.254829, 1.08487, -0.00678866, -2.14855, 0.277826, -1.80186, -2.55075, 5.39562, -5.81301, -2.57512, -2.09245, 1.76714, -8.44004, -2.0859, 0.00217419, 0.688112, -0.318207, -1.78726, 2.07263, -4.61729, 1.82902, 11.1449}, {0.602665, 0.0050297, 1.59185, -0.827431, 1.45271, 0.471751, -0.860099, -1.45095, 0.0849431, -3.2546, 0.020366, 6.44564, 0.277826, -1.80186, -2.55075, 2.0859, -0.00217419, -0.688112, 0.318207, 1.78726, -2.07263, -4.49656, -0.0179446, -5.67929, 2.99152, -7.59809, 0.185628, 3.16257, 7.60566, 2.21098}, {1.57878, 4.35912, 1.72866, 0.141226, 1.44665, -1.44665, 1.40644, -1.11582e-18, -3.53145e-16, -1.02141, 0.00639156, 2.02287, -0.0889792, -5.77869, 8.28699, -1.91302, -1.78815, 1.78815, -6.71372, 1.79605, 0.712247, 5.99864, 1.76259, -9.87962, 1.08796, -1.79605, -0.712247, -0.475926, -0.0079004, -2.5004}, {-0.526258, -1.45304, -0.57622, -0.423679, -4.33994, 4.33994, 1.40644, 1.11582e-18, 3.53145e-16, -1.02141, 0.00639156, 2.02287, 2.58096, 5.82005, 4.80528, -7.53877, -1.78815, 1.78815, -1.08796, 1.79605, 0.712247, 1.91302, 1.78815, -1.78815, 5.17359, -1.82162, -8.80371, -0.475926, -0.0079004, -2.5004}, {-0.526258, -1.45304, -0.57622, 0.141226, 1.44665, -1.44665, -4.21932, 0, 0, -1.02141, 0.00639156, 2.02287, 0.475926, 0.0079004, 2.5004, -2.47792, -7.57474, 7.57474, 1.01707, 7.60821, 3.01713, 1.91302, 1.78815, -1.78815, 1.08796, -1.79605, -0.712247, 3.6097, -0.0334666, -10.5919}, {-0.526258, -1.45304, -0.57622, 0.141226, 1.44665, -1.44665, 1.40644, -1.11582e-18, -3.53145e-16, 3.06422, -0.0191747, -6.0686, 0.475926, 0.0079004, 2.5004, -1.91302, -1.78815, 1.78815, -1.08796, 1.79605, 0.712247, 4.01805, 7.60031, 0.516725, 0.523057, -7.58264, 5.07434, -6.10168, -0.0079004, -2.5004}, {10.941, -1.1204, -1.1204, 1.78885, -1.78885, -1.78885, -7.40676e-16, -5.64191e-16, 1.60567, 1.85814, 1.41539, -0.190281, -4.85864, 8.90493, 8.90493, -2.21115, 2.21115, 0.226431, 4.50793, -0.461631, -8.86902, -5.2214, -7.87269, 0.534693, -4.50793, 0.461631, 2.44635, -2.29678, -1.74951, -1.74951}, {-3.64699, 0.373467, 0.373467, -5.36656, 5.36656, 5.36656, 0, 0, 1.60567, 1.85814, 1.41539, -0.190281, 16.8847, 0.255645, 0.255645, -2.21115, 2.21115, -6.19624, 4.50793, -0.461631, -2.44635, 2.21115, -2.21115, -0.226431, -11.9405, -5.19992, 3.20747, -2.29678, -1.74951, -1.74951}, {-3.64699, 0.373467, 0.373467, 1.78885, -1.78885, -1.78885, 0, 0, -4.817, 1.85814, 1.41539, -0.190281, 2.29678, 1.74951, 1.74951, -9.36656, 9.36656, 7.38185, 19.0959, -1.9555, -3.94022, 2.21115, -2.21115, -0.226431, -4.50793, 0.461631, 2.44635, -9.72932, -7.41106, -0.988391}, {-3.64699, 0.373467, 0.373467, 1.78885, -1.78885, -1.78885, -7.40676e-16, -5.64191e-16, 1.60567, -5.57441, -4.24616, 0.570843, 2.29678, 1.74951, 1.74951, -2.21115, 2.21115, 0.226431, 4.50793, -0.461631, -2.44635, 16.7991, -3.70501, -1.7203, -11.6633, 7.61705, 9.60176, -2.29678, -1.74951, -8.17219}, {-5.57441, -4.24616, -4.24616, 1.78885, -1.78885, -1.78885, 0, 3.15147, 0, -3.64699, -2.778, 0.373467, -11.6633, 7.61705, 7.61705, -2.21115, -1.68428, 2.21115, -2.29678, -18.2508, -1.74951, 16.7991, 12.7963, -3.70501, 2.29678, 5.64494, 1.74951, 4.50793, -0.461631, -0.461631}, {1.85814, 1.41539, 1.41539, -5.36656, 5.36656, 5.36656, -2.85327e-15, 3.15147, 2.92187e-16, -3.64699, -2.778, 0.373467, -11.9405, -5.19992, -5.19992, -2.21115, -14.2902, 2.21115, -2.29678, -5.64494, -1.74951, 2.21115, 1.68428, -2.21115, 16.8847, 16.7569, 0.255645, 4.50793, -0.461631, -0.461631}, {1.85814, 1.41539, 1.41539, 1.78885, -1.78885, -1.78885, 0, -9.45441, 0, -3.64699, -2.778, 0.373467, -4.50793, 0.461631, 0.461631, -9.36656, 5.47113, 9.36656, -9.72932, -11.3065, -7.41106, 2.21115, 1.68428, -2.21115, 2.29678, 5.64494, 1.74951, 19.0959, 10.6504, -1.9555}, {1.85814, 1.41539, 1.41539, 1.78885, -1.78885, -1.78885, 0, 3.15147, 0, 10.941, 8.334, -1.1204, -4.50793, 0.461631, 0.461631, -2.21115, -1.68428, 2.21115, -2.29678, -5.64494, -1.74951, -5.2214, -3.97726, -7.87269, -4.85864, 12.8004, 8.90493, 4.50793, -13.0675, -0.461631}, {0.184458, 9.63611, 9.63611, 0.802834, -0.802834, 0.802834, -1.57551, 1.57551, 1.57551, 0.834161, 2.43936, 0.833693, -4.12769, 8.17399, -0.233398, 0.955079, -0.955079, -2.93979, 8.32547, -4.27918, -4.27918, -4.29172, -8.80237, -0.394979, -2.02344, -2.02286, -2.02286, 0.916356, -4.96265, -2.97794}, {-0.0614861, -3.21204, -3.21204, -2.4085, 2.4085, -2.4085, -1.57551, 1.57551, 1.57551, 0.834161, 2.43936, 0.833693, -0.670412, 17.8108, 15.8261, 7.25711, -7.25711, -9.24183, 2.02344, 2.02286, 2.02286, -0.955079, 0.955079, 2.93979, -5.36008, -11.7803, -5.35763, 0.916356, -4.96265, -2.97794}, {-0.0614861, -3.21204, -3.21204, 0.802834, -0.802834, 0.802834, 4.72653, -4.72653, -4.72653, 0.834161, 2.43936, 0.833693, -0.916356, 4.96265, 2.97794, -2.25626, 2.25626, -6.15113, 2.26938, 14.871, 14.871, -0.955079, 0.955079, 2.93979, -2.02344, -2.02286, -2.02286, -2.42029, -14.7201, -6.31271}, {-0.0614861, -3.21204, -3.21204, 0.802834, -0.802834, 0.802834, -1.57551, 1.57551, 1.57551, -2.50248, -7.31808, -2.50108, -0.916356, 4.96265, 2.97794, 0.955079, -0.955079, -2.93979, 2.02344, 2.02286, 2.02286, -0.709135, 13.8032, 15.7879, -5.23477, 1.18848, -5.23419, 7.21839, -11.2647, -9.27997}, {4.72653, -4.72653, -4.72653, 1.637, 1.63653, 1.63653, 1.57573, 1.57573, -1.57573, -1.63722, -4.78777, -1.6363, -6.62398, -10.5164, -10.5164, -3.97115, -3.97057, -0.0751443, -6.30322, -10.1981, 6.30322, 10.52, 23.1217, 6.62035, 0.000278382, 3.89515, -0.000278382, 0.076001, 3.9703, 3.9703}, {-1.57551, 1.57551, 1.57551, -4.91099, -4.90958, -4.90958, 1.57573, 1.57573, -1.57573, -1.63722, -4.78777, -1.6363, 6.22604, -10.2723, -10.2723, -10.2741, -10.2735, 6.22779, -0.000278382, -3.89515, 0.000278382, 3.97115, 3.97057, 0.0751443, 6.54916, 23.0462, 6.54493, 0.076001, 3.9703, 3.9703}, {-1.57551, 1.57551, 1.57551, 1.637, 1.63653, 1.63653, -4.7272, -4.7272, 4.7272, -1.63722, -4.78777, -1.6363, -0.076001, -3.9703, -3.9703, -10.5191, -10.5167, -6.62125, 6.30176, -10.1972, -6.30176, 3.97115, 3.97057, 0.0751443, 0.000278382, 3.89515, -0.000278382, 6.62488, 23.1214, 10.5155}, {-1.57551, 1.57551, 1.57551, 1.637, 1.63653, 1.63653, 1.57573, 1.57573, -1.57573, 4.91166, 14.3633, 4.90891, -0.076001, -3.9703, -3.9703, -3.97115, -3.97057, -0.0751443, -0.000278382, -3.89515, 0.000278382, 10.2732, -2.33146, -6.22689, -6.5477, -2.65096, -6.54639, -6.22694, -2.33264, 10.2732}, {2.2538, -2.2568, -6.95596, 1.0326, -1.0322, -0.409331, 0.623613, 1.72184, 0.682817, -0.904944, -1.44191, -2.59214, -4.47814, 4.47482, -0.722725, -2.04719, -0.852443, -0.338046, -2.33666, -9.94553, -6.44129, 5.66697, 6.62007, 10.7066, -0.157789, 3.05817, 3.71002, 0.347745, -0.346017, 2.36005}, {-0.751267, 0.752267, 2.31865, -3.09779, 3.0966, 1.22799, 0.623613, 1.72184, 0.682817, -0.904944, -1.44191, -2.59214, 2.65732, -2.66305, -11.6347, -4.54164, -7.73981, -3.06931, 0.157789, -3.05817, -3.71002, 2.04719, 0.852443, 0.338046, 3.46199, 8.8258, 14.0786, 0.347745, -0.346017, 2.36005}, {-0.751267, 0.752267, 2.31865, 1.0326, -1.0322, -0.409331, -1.87084, -5.16552, -2.04845, -0.904944, -1.44191, -2.59214, -0.347745, 0.346017, -2.36005, -6.17758, 3.27636, 1.29928, 3.16286, -6.06723, -12.9846, 2.04719, 0.852443, 0.338046, -0.157789, 3.05817, 3.71002, 3.96752, 5.42161, 12.7286}, {-0.751267, 0.752267, 2.31865, 1.0326, -1.0322, -0.409331, 0.623613, 1.72184, 0.682817, 2.71483, 4.32572, 7.77641, -0.347745, 0.346017, -2.36005, -2.04719, -0.852443, -0.338046, 0.157789, -3.05817, -3.71002, 5.05226, -2.15663, -8.93656, -4.28818, 7.18697, 5.34735, -2.14671, -7.23338, -0.371216}, {4.6308, -4.62902, -1.83569, 1.74378, -1.74182, 1.32959, 2.34612, -1.15797e-16, 1.13078e-15, -2.5463, 0.198817, -1.94149, -7.22258, 7.21305, -7.71818, -5.0554, 2.15301, -1.64347, -10.3764, -1.90726, -0.756347, 15.2406, -2.94828, 9.40942, 0.991964, 1.90726, 0.756347, 0.24744, -0.245751, 2.39981}, {-1.5436, 1.54301, 0.611898, -5.23135, 5.22547, -3.98877, 2.34612, 0, 0, -2.5463, 0.198817, -1.94149, 5.92697, -5.92628, -4.8474, -14.4399, 2.15301, -1.64347, -0.991964, -1.90726, -0.756347, 5.0554, -2.15301, 1.64347, 11.1772, 1.11199, 8.5223, 0.24744, -0.245751, 2.39981}, {-1.5436, 1.54301, 0.611898, 1.74378, -1.74182, 1.32959, -7.03835, 0, 0, -2.5463, 0.198817, -1.94149, -0.24744, 0.245751, -2.39981, -12.0305, 9.12031, -6.96183, 5.18244, -8.07929, -3.20394, 5.0554, -2.15301, 1.64347, 0.991964, 1.90726, 0.756347, 10.4326, -1.04102, 10.1658}, {-1.5436, 1.54301, 0.611898, 1.74378, -1.74182, 1.32959, 2.34612, -1.15797e-16, 1.13078e-15, 7.6389, -0.59645, 5.82447, -0.24744, 0.245751, -2.39981, -5.0554, 2.15301, -1.64347, -0.991964, -1.90726, -0.756347, 11.2298, -8.32504, -0.804126, -5.98318, 8.87456, -4.56202, -9.13703, -0.245751, 2.39981}, {6.00044e-16, 3.62803, 0, -1.45582, 0.0794645, -1.44142, 1.45582, 0.249439, -0.577805, -1.62191e-12, 0.88044, 2.01922, 7.62276, 1.07875, 7.54736, -2.00484e-12, -0.406547, 2.4959, -7.62276, 0.188753, 3.02542, 8.49248e-12, -3.11521, -10.5728, 1.79949, -1.18651, -0.714206, -1.79949, -1.39661, -1.78169}, {-2.31939e-18, -1.20934, -4.44089e-16, 4.36745, -0.238394, 4.32425, 1.45582, 0.249439, -0.577805, -1.61981e-12, 0.88044, 2.01922, 1.79949, 6.23398, 1.78169, -5.82327, -1.4043, 4.80711, -1.79949, 1.18651, 0.714206, 2.00218e-12, 0.406547, -2.4959, 1.79949, -4.70827, -8.79109, -1.79949, -1.39661, -1.78169}, {-1.25659e-16, -1.20934, 0, -1.45582, 0.0794645, -1.44142, -4.36745, -0.748316, 1.73341, -1.61969e-12, 0.88044, 2.01922, 1.79949, 1.39661, 1.78169, 5.82327, -0.724405, 8.26156, -1.79949, 6.02388, 0.714206, 2.00218e-12, 0.406547, -2.4959, 1.79949, -1.18651, -0.714206, -1.79949, -4.91837, -9.85858}, {2.23143e-17, -1.20934, 4.44089e-16, -1.45582, 0.0794645, -1.44142, 1.45582, 0.249439, -0.577805, 4.86018e-12, -2.64132, -6.05767, 1.79949, 1.39661, 1.78169, -2.0024e-12, -0.406547, 2.4959, -1.79949, 1.18651, 0.714206, 2.00186e-12, 5.24392, -2.4959, 7.62276, -1.50437, 5.05146, -7.62276, -2.39436, 0.529529}, {4.15977e-12, 1.3684, -5.1823, 1.45582, 0.310608, -0.437518, -1.45582, 0.975521, 0.61362, 1.5284e-12, -0.829997, -1.90353, -7.62276, -1.06255, 0.155649, 1.74971e-13, -1.58974, -0.217674, 7.62276, -4.54408, -5.34818, -6.28859e-12, 4.90973, 7.83181, -1.79949, 0.642, 2.8937, 1.79949, -0.179878, 1.59442}, {-1.38545e-12, -0.456132, 1.72743, -4.36745, -0.931824, 1.31255, -1.45582, 0.975521, 0.61362, 1.52689e-12, -0.829997, -1.90353, -1.79949, 2.00441, -8.50415, 5.82327, -5.49183, -2.67215, 1.79949, -0.642, -2.8937, -1.74749e-13, 1.58974, 0.217674, -1.79949, 3.96199, 10.5078, 1.79949, -0.179878, 1.59442}, {-1.38636e-12, -0.456132, 1.72743, 1.45582, 0.310608, -0.437518, 4.36745, -2.92656, -1.84086, 1.52736e-12, -0.829997, -1.90353, -1.79949, 0.179878, -1.59442, -5.82327, -2.83217, 1.5324, 1.79949, 1.18253, -9.80343, -1.74305e-13, 1.58974, 0.217674, -1.79949, 0.642, 2.8937, 1.79949, 3.14011, 9.20856}, {-1.38463e-12, -0.456132, 1.72743, 1.45582, 0.310608, -0.437518, -1.45582, 0.975521, 0.61362, -4.57754e-12, 2.48999, 5.7106, -1.79949, 0.179878, -1.59442, 1.74527e-13, -1.58974, -0.217674, 1.79949, -0.642, -2.8937, 5.36353e-12, 3.41427, -6.69206, -7.62276, -0.600431, 4.64377, 7.62276, -4.08196, -0.860057}, {3.89774, -2.39084, -3.90175, -1.08034, -0.824783, -1.26412, 1.27484, -0.81558, 1.06845, 1.10475, 0.843417, -1.10491, 7.26269, 3.33354, 5.01139, -0.240416, 2.0276, 0.241863, -5.06919, 3.28535, -7.20207, -4.17857, -5.40127, 4.17779, -0.0301684, -0.023032, 2.92828, -2.94133, -0.0344082, 0.0450763}, {-1.29925, 0.796947, 1.30058, 3.24102, 2.47435, 3.79235, 1.27484, -0.81558, 1.06845, 1.10475, 0.843417, -1.10491, 8.13832, -3.15338, -5.24742, -5.33978, 5.28992, -4.03192, 0.0301684, 0.023032, -2.92828, 0.240416, -2.0276, -0.241863, -4.44916, -3.3967, 7.34794, -2.94133, -0.0344082, 0.0450763}, {-1.29925, 0.796947, 1.30058, -1.08034, -0.824783, -1.26412, -3.82452, 2.44674, -3.20534, 1.10475, 0.843417, -1.10491, 2.94133, 0.0344082, -0.0450763, 4.08094, 5.32673, 5.29833, 5.22716, -3.16475, -8.13062, 0.240416, -2.0276, -0.241863, -0.0301684, -0.023032, 2.92828, -7.36032, -3.40808, 4.46473}, {-1.29925, 0.796947, 1.30058, -1.08034, -0.824783, -1.26412, 1.27484, -0.81558, 1.06845, -3.31424, -2.53025, 3.31474, 2.94133, 0.0344082, -0.0450763, -0.240416, 2.0276, 0.241863, 0.0301684, 0.023032, -2.92828, 5.43741, -5.21539, -5.4442, 4.29119, 3.2761, 7.98475, -8.04069, 3.22791, -4.22871}, {-7.02938, 0, -7.99361e-15, 0, 0, -2.34462, -1.02086e-11, 1.78885, 0.00114147, -2.34313, -1.78885, 2.34348, -2.89626, 0, 12.2766, 1.26186e-11, -2.21115, 2.8967, -2.89626, -9.36656, -0.00597681, 9.3725, 9.36656, -12.2706, 2.89626, 2.21115, 0.00141093, 2.89626, 0, -2.89811}, {2.34313, 0, 1.77636e-15, 0, 0, 7.03386, -1.02097e-11, 1.78885, 0.00114147, -2.34313, -1.78885, 2.34348, -12.2688, 0, 2.89811, 5.34586e-11, -9.36656, 2.89213, -2.89626, -2.21115, -0.00141093, -1.26216e-11, 2.21115, -2.8967, 12.2688, 9.36656, -9.37251, 2.89626, 0, -2.89811}, {2.34313, 0, 2.66454e-15, 0, 0, -2.34462, 3.06329e-11, -5.36656, -0.00342441, -2.34313, -1.78885, 2.34348, -2.89626, 0, 2.89811, 1.26215e-11, -2.21115, 12.2752, -12.2688, -2.21115, -0.00141093, -1.26232e-11, 2.21115, -2.8967, 2.89626, 2.21115, 0.00141093, 12.2688, 7.15542, -12.272}, {2.34313, 8.88178e-16, -1.33227e-15, 0, 0, -2.34462, -1.02112e-11, 1.78885, 0.00114147, 7.02938, 5.36656, -7.03044, -2.89626, -8.88178e-16, 2.89811, 1.26218e-11, -2.21115, 2.8967, -2.89626, -2.21115, -0.00141093, -9.3725, 2.21115, -2.8967, 2.89626, 2.21115, 9.37989, 2.89626, -7.15542, -2.90268}, {-4.72653, 4.72653, 4.72653, -0.802949, -0.802719, 0.802949, -3.21204, 3.21204, -0.0614861, 2.43948, -0.833808, 0.834046, 2.25686, 6.15053, -2.25686, 4.96279, -2.97808, -0.916498, 14.871, -14.871, 2.26938, -14.7207, 6.31331, -2.41969, -2.02286, 2.02286, -2.02344, 0.954937, -2.93965, -0.954937}, {1.57551, -1.57551, -1.57551, 2.40885, 2.40816, -2.40885, -3.21204, 3.21204, -0.0614861, 2.43948, -0.833808, 0.834046, -7.25697, 9.24169, 7.25697, 17.8109, -15.8262, -0.670554, 2.02286, -2.02286, 2.02344, -4.96279, 2.97808, 0.916498, -11.7808, 5.35809, -5.35962, 0.954937, -2.93965, -0.954937}, {1.57551, -1.57551, -1.57551, -0.802949, -0.802719, 0.802949, 9.63611, -9.63611, 0.184458, 2.43948, -0.833808, 0.834046, -0.954937, 2.93965, 0.954937, 8.17459, 0.232798, -4.12829, -4.27918, 4.27918, 8.32547, -4.96279, 2.97808, 0.916498, -2.02286, 2.02286, -2.02344, -8.80297, 0.39558, -4.29112}, {1.57551, -1.57551, -1.57551, -0.802949, -0.802719, 0.802949, -3.21204, 3.21204, -0.0614861, -7.31843, 2.50142, -2.50214, -0.954937, 2.93965, 0.954937, 4.96279, -2.97808, -0.916498, 2.02286, -2.02286, 2.02344, -11.2648, 9.28012, 7.21853, 1.18894, 5.23374, -5.23523, 13.8031, -15.7878, -0.708993}, {-4.72653, 4.72653, 4.72653, 1.57596, 1.57551, 1.57551, 1.63653, -1.63653, 1.637, -4.788, 1.63653, -1.637, -10.1993, -6.30204, -6.30204, -3.97085, 0.0754226, -3.97087, -10.5164, 10.5164, -6.62398, 23.1228, -6.62153, 10.5189, 3.9703, -3.9703, 0.076001, 3.89543, -1.81455e-12, -1.8181e-12}, {1.57551, -1.57551, -1.57551, -4.72788, -4.72653, -4.72653, 1.63653, -1.63653, 1.637, -4.788, 1.63653, -1.637, -10.1975, 6.30204, 6.30204, -10.517, 6.62153, -10.5189, -3.9703, 3.9703, -0.076001, 3.97085, -0.0754226, 3.97087, 23.1223, -10.5164, 6.62398, 3.89543, -1.81632e-12, -1.81632e-12}, {1.57551, -1.57551, -1.57551, 1.57596, 1.57551, 1.57551, -4.90958, 4.90958, -4.91099, -4.788, 1.63653, -1.637, -3.89543, 1.81943e-12, 1.81899e-12, -10.2747, -6.22661, -10.2729, -10.2723, 10.2723, 6.22604, 3.97085, -0.0754226, 3.97087, 3.9703, -3.9703, 0.076001, 23.0474, -6.54611, 6.54798}, {1.57551, -1.57551, -1.57551, 1.57596, 1.57551, 1.57551, 1.63653, -1.63653, 1.637, 14.364, -4.90958, 4.91099, -3.89543, 1.81721e-12, 1.81766e-12, -3.97085, 0.0754226, -3.97087, -3.9703, 3.9703, -0.076001, -2.33118, 6.22661, 10.2729, -2.33354, -10.2723, -6.22604, -2.65068, 6.54611, -6.54798}, {-1.1204, 1.1204, 10.941, 0, -1.60567, 0, -1.78885, 1.78885, 1.78885, 1.41539, 0.190281, 1.85814, -0.461631, 8.86902, 4.50793, 2.21115, -0.226431, -2.21115, 8.90493, -8.90493, -4.85864, -7.87269, -0.534693, -5.2214, -1.74951, 1.74951, -2.29678, 0.461631, -2.44635, -4.50793}, {0.373467, -0.373467, -3.64699, 0, 4.817, 0, -1.78885, 1.78885, 1.78885, 1.41539, 0.190281, 1.85814, -1.9555, 3.94022, 19.0959, 9.36656, -7.38185, -9.36656, 1.74951, -1.74951, 2.29678, -2.21115, 0.226431, 2.21115, -7.41106, 0.988391, -9.72932, 0.461631, -2.44635, -4.50793}, {0.373467, -0.373467, -3.64699, 0, -1.60567, 0, 5.36656, -5.36656, -5.36656, 1.41539, 0.190281, 1.85814, -0.461631, 2.44635, 4.50793, 2.21115, 6.19624, -2.21115, 0.255645, -0.255645, 16.8847, -2.21115, 0.226431, 2.21115, -1.74951, 1.74951, -2.29678, -5.19992, -3.20747, -11.9405}, {0.373467, -0.373467, -3.64699, 0, -1.60567, 0, -1.78885, 1.78885, 1.78885, -4.24616, -0.570843, -5.57441, -0.461631, 2.44635, 4.50793, 2.21115, -0.226431, -2.21115, 1.74951, -1.74951, 2.29678, -3.70501, 1.7203, 16.7991, -1.74951, 8.17219, -2.29678, 7.61705, -9.60176, -11.6633}, {-9.45441, 3.55271e-15, -5.32907e-15, -1.78885, 1.78885, 1.78885, 1.41539, -1.41539, 1.85814, -2.778, -0.373467, -3.64699, 5.47113, -9.36656, -9.36656, 0.461631, -0.461631, -4.50793, -11.3065, 7.41106, -9.72932, 10.6504, 1.9555, 19.0959, 5.64494, -1.74951, 2.29678, 1.68428, 2.21115, 2.21115}, {3.15147, 1.66533e-16, 3.10862e-15, 5.36656, -5.36656, -5.36656, 1.41539, -1.41539, 1.85814, -2.778, -0.373467, -3.64699, -14.2902, -2.21115, -2.21115, -5.19992, 5.19992, -11.9405, -5.64494, 1.74951, -2.29678, -0.461631, 0.461631, 4.50793, 16.7569, -0.255645, 16.8847, 1.68428, 2.21115, 2.21115}, {3.15147, 5.38458e-15, 1.77636e-15, -1.78885, 1.78885, 1.78885, -4.24616, 4.24616, -5.57441, -2.778, -0.373467, -3.64699, -1.68428, -2.21115, -2.21115, 7.61705, -7.61705, -11.6633, -18.2508, 1.74951, -2.29678, -0.461631, 0.461631, 4.50793, 5.64494, -1.74951, 2.29678, 12.7963, 3.70501, 16.7991}, {3.15147, -5.55112e-17, 4.44089e-16, -1.78885, 1.78885, 1.78885, 1.41539, -1.41539, 1.85814, 8.334, 1.1204, 10.941, -1.68428, -2.21115, -2.21115, 0.461631, -0.461631, -4.50793, -5.64494, 1.74951, -2.29678, -13.0675, 0.461631, 4.50793, 12.8004, -8.90493, -4.85864, -3.97726, 7.87269, -5.2214}, {0.889469, 0.890856, -5.70584, -0.741046, -0.742202, -0.293121, 1.30296, -1.03813, 0.515387, -0.265426, 2.07729, -2.12421, 4.24665, 4.25327, -0.816132, -0.694566, 2.20061, -0.274736, -6.45592, 5.80278, -5.04953, 1.75627, -10.5098, 8.77158, 1.24407, -1.65026, 2.98799, -1.28247, -1.28446, 1.98862}, {-0.29649, -0.296952, 1.90195, 2.22314, 2.2266, 0.879363, 1.30296, -1.03813, 0.515387, -0.265426, 2.07729, -2.12421, 2.46842, 2.47227, -9.5964, -5.90641, 6.35314, -2.33628, -1.24407, 1.65026, -2.98799, 0.694566, -2.20061, 0.274736, 2.30577, -9.9594, 11.4848, -1.28247, -1.28446, 1.98862}, {-0.29649, -0.296952, 1.90195, -0.741046, -0.742202, -0.293121, -3.90889, 3.1144, -1.54616, -0.265426, 2.07729, -2.12421, 1.28247, 1.28446, -1.98862, 2.26962, 5.16942, 0.897749, -0.0581089, 2.83806, -10.5958, 0.694566, -2.20061, 0.274736, 1.24407, -1.65026, 2.98799, -0.220762, -9.59361, 10.4855}, {-0.29649, -0.296952, 1.90195, -0.741046, -0.742202, -0.293121, 1.30296, -1.03813, 0.515387, 0.796277, -6.23186, 6.37263, 1.28247, 1.28446, -1.98862, -0.694566, 2.20061, -0.274736, -1.24407, 1.65026, -2.98799, 1.88052, -1.01281, -7.33305, 4.20825, 1.31855, 4.16047, -6.49431, 2.86807, -0.0729313}, {1.60243, -4.68893, 0, 1.23856, -0.534131, 0, -0.868329, 0.25394, -1.31177, 0.163908, -1.28279, 1.31177, -5.82496, 0.864798, 0, -0.457635, 0.346335, 1.62143, 5.20686, -3.26159, 6.86849, -0.197999, 4.78481, -6.86849, -1.73355, 2.24583, -1.62143, 0.870711, 1.27173, 0}, {-0.534143, 1.56298, 2.22045e-16, -3.71569, 1.60239, 6.76061e-16, -0.868329, 0.25394, -1.31177, 0.163908, -1.28279, 1.31177, 1.26586, -7.52364, -8.88178e-16, 3.01568, -0.669425, 6.86849, 1.73355, -2.24583, 1.62143, 0.457635, -0.346335, -1.62143, -2.38918, 7.37698, -6.86849, 0.870711, 1.27173, 0}, {-0.534143, 1.56298, -2.22045e-16, 1.23856, -0.534131, 7.51179e-17, 2.60499, -0.76182, 3.9353, 0.163908, -1.28279, 1.31177, -0.870711, -1.27173, 2.22045e-16, -5.41189, 2.48286, 1.62143, 3.87012, -8.49775, 1.62143, 0.457635, -0.346335, -1.62143, -1.73355, 2.24583, -1.62143, 0.215077, 6.40287, -5.24706}, {-0.534143, 1.56298, -2.22045e-16, 1.23856, -0.534131, 7.51179e-17, -0.868329, 0.25394, -1.31177, -0.491725, 3.84836, -3.9353, -0.870711, -1.27173, 2.22045e-16, -0.457635, 0.346335, 1.62143, 1.73355, -2.24583, 1.62143, 2.59421, -6.59825, -1.62143, -6.6878, 4.38236, -1.62143, 4.34403, 0.255965, 5.24706}, {3.16808, 6.1315e-16, 0, -0.300269, 1.44665, -1.44665, 0.153249, -1.44665, -0.572575, 1.20305, -1.58845e-12, 2.01922, 2.87755, -7.57474, 7.57474, 0.181727, -1.96354e-12, 2.4959, 0.502898, 7.57474, 2.99804, -4.99391, 8.31734e-12, -10.5728, -1.11589, -1.78815, -0.707741, -1.67647, 1.78815, -1.78815}, {-1.05603, -2.30419e-16, 4.44089e-16, 0.900808, -4.33994, 4.33994, 0.153249, -1.44665, -0.572575, 1.20305, -1.58717e-12, 2.01922, 5.90057, -1.78815, 1.78815, -0.431268, 5.78659, 4.7862, 1.11589, 1.78815, 0.707741, -0.181727, 1.96176e-12, -2.4959, -5.92808, -1.78815, -8.78463, -1.67647, 1.78815, -1.78815}, {-1.05603, -8.03432e-17, 0, -0.300269, 1.44665, -1.44665, -0.459746, 4.33994, 1.71772, 1.20305, -1.58909e-12, 2.01922, 1.67647, -1.78815, 1.78815, 1.3828, -5.78659, 8.28248, 5.34, 1.78815, 0.707741, -0.181727, 1.96443e-12, -2.4959, -1.11589, -1.78815, -0.707741, -6.48866, 1.78815, -9.86504}, {-1.05603, -2.38416e-16, 0, -0.300269, 1.44665, -1.44665, 0.153249, -1.44665, -0.572575, -3.60914, 4.76214e-12, -6.05767, 1.67647, -1.78815, 1.78815, 0.181727, -1.96221e-12, 2.4959, 1.11589, 1.78815, 0.707741, 4.04237, 1.96294e-12, -2.4959, 0.0851836, -7.57474, 5.07885, -2.28947, 7.57474, 0.502145}, {-1.48316, 4.33994, 8.88178e-16, 0.561638, 1.44665, 2.78108e-16, -0.27448, -1.03218e-12, 1.31177, -0.781545, 1.03218e-12, -1.31177, -3.55187, -5.78659, -1.11022e-15, -0.354947, -1.78815, -1.62143, 0.8261, 1.78815, -6.86849, 3.48113, 1.78815, 6.86849, 0.27182, -1.78815, 1.62143, 1.30532, 0, 0}, {0.494387, -1.44665, 2.22045e-16, -1.68492, -4.33994, 4.17162e-16, -0.27448, -1.03077e-12, 1.31177, -0.781545, 1.03077e-12, -1.31177, -3.28287, 5.78659, -8.88178e-16, 0.742973, -1.78815, -6.86849, -0.27182, 1.78815, -1.62143, 0.354947, 1.78815, 1.62143, 3.398, -1.78815, 6.86849, 1.30532, 0, 0}, {0.494387, -1.44665, -2.22045e-16, 0.561638, 1.44665, 9.73378e-16, 0.82344, 3.09372e-12, -3.9353, -0.781545, 1.03124e-12, -1.31177, -1.30532, 1.07741e-15, -8.88178e-16, -2.6015, -7.57474, -1.62143, -2.24937, 7.57474, -1.62143, 0.354947, 1.78815, 1.62143, 0.27182, -1.78815, 1.62143, 4.4315, -4.12496e-12, 5.24706}, {0.494387, -1.44665, -4.44089e-16, 0.561638, 1.44665, 2.78108e-16, -0.27448, -1.03265e-12, 1.31177, 2.34464, -3.09796e-12, 3.9353, -1.30532, 1.07741e-15, 2.22045e-16, -0.354947, -1.78815, -1.62143, -0.27182, 1.78815, -1.62143, -1.6226, 7.57474, 1.62143, -1.97473, -7.57474, 1.62143, 2.40324, 4.13061e-12, -5.24706}, {4.33994, 0.162335, 4.33994, 6.07958e-28, 1.38248, -6.93006e-16, 1.44665, 0.246581, -0.572575, -1.77142e-12, -1.57494, 2.01922, 1.78815, -7.17185, 1.78815, -1.78815, -2.01362, 0.707741, -5.78659, -1.22423, 4.7862, 1.78815, 8.3134, -8.78463, 2.18959e-12, 0.237905, -2.4959, -1.78815, 1.64195, -1.78815}, {-1.44665, -0.0541117, -1.44665, -1.48949e-15, -4.14743, 2.66855e-15, 1.44665, 0.246581, -0.572575, -1.7709e-12, -1.57494, 2.01922, 7.57474, -1.4255, 7.57474, -7.57474, -2.99995, 2.99804, -2.18726e-12, -0.237905, 2.4959, 1.78815, 2.01362, -0.707741, 9.27191e-12, 6.53768, -10.5728, -1.78815, 1.64195, -1.78815}, {-1.44665, -0.0541117, -1.44665, 0, 1.38248, 0, -4.33994, -0.739742, 1.71772, -1.76852e-12, -1.57494, 2.01922, 1.78815, -1.64195, 1.78815, -1.78815, -7.54353, 0.707741, 5.78659, -0.021458, 8.28248, 1.78815, 2.01362, -0.707741, 2.18601e-12, 0.237905, -2.4959, -1.78815, 7.94173, -9.86504}, {-1.44665, -0.0541117, -1.44665, 6.07523e-28, 1.38248, -6.93006e-16, 1.44665, 0.246581, -0.572575, 5.31045e-12, 4.72483, -6.05767, 1.78815, -1.64195, 1.78815, -1.78815, -2.01362, 0.707741, -2.18695e-12, -0.237905, 2.4959, 7.57474, 2.23007, 5.07885, 2.18802e-12, -5.292, -2.4959, -7.57474, 0.655625, 0.502145}, {-4.33994, 1.02197, -0.540949, -9.62166e-13, 0.52571, 1.09845, -1.44665, -1.05053, -0.169142, 9.71954e-13, 0.86548, -1.10962, -1.78815, -2.33158, -5.97445, 1.78815, 0.648718, -1.14869, 5.78659, 5.92175, 0.662758, -1.78815, -4.11064, 5.58719, -1.2098e-14, -1.71961, 0.0138116, 1.78815, 0.22874, 1.58064}, {1.44665, -0.340656, 0.180316, 2.89002e-12, -1.57713, -3.29535, -1.44665, -1.05053, -0.169142, 9.72639e-13, 0.86548, -1.10962, -7.57474, 1.13389, -2.30191, 7.57474, 4.85086, -0.472119, 1.04155e-14, 1.71961, -0.0138116, -1.78815, -0.648718, 1.14869, -3.90205e-12, -5.18153, 4.45231, 1.78815, 0.22874, 1.58064}, {1.44665, -0.340656, 0.180316, -9.63744e-13, 0.52571, 1.09845, 4.33994, 3.1516, 0.507427, 9.73548e-13, 0.86548, -1.10962, -1.78815, -0.22874, -1.58064, 1.78815, -1.45412, -5.54249, -5.78659, 3.08223, -0.735077, -1.78815, -0.648718, 1.14869, -1.21179e-14, -1.71961, 0.0138116, 1.78815, -3.23318, 6.01914}, {1.44665, -0.340656, 0.180316, -9.64139e-13, 0.52571, 1.09845, -1.44665, -1.05053, -0.169142, -2.92184e-12, -2.59644, 3.32887, -1.78815, -0.22874, -1.58064, 1.78815, 0.648718, -1.14869, 1.10454e-14, 1.71961, -0.0138116, -7.57474, 0.713906, 0.427423, 3.84443e-12, -3.82245, -4.37999, 7.57474, 4.43088, 2.25721}, {-4.74899, 4.74899, 3.61742, 0.497745, -0.497745, 2.77232, -2.29648, -0.854984, 1.74929, 0.215741, 2.93573, -3.3158, -4.56292, 4.56292, -13.0256, 2.22336, 1.67207, -5.58902, 10.0679, 6.43345, -7.66893, -3.08633, -13.415, 18.8522, -0.881918, -3.01351, 0.671778, 2.57194, -2.57194, 1.93632}, {1.583, -1.583, -1.20581, -1.49324, 1.49324, -8.31697, -2.29648, -0.854984, 1.74929, 0.215741, 2.93573, -3.3158, -8.90393, 8.90393, 2.88691, 11.4093, 5.092, -12.5862, 0.881918, 3.01351, -0.671778, -2.22336, -1.67207, 5.58902, -1.74488, -14.7564, 13.935, 2.57194, -2.57194, 1.93632}, {1.583, -1.583, -1.20581, 0.497745, -0.497745, 2.77232, 6.88945, 2.56495, -5.24786, 0.215741, 2.93573, -3.3158, -2.57194, 2.57194, -1.93632, 0.232383, 3.66305, -16.6783, -5.45007, 9.3455, 4.15145, -2.22336, -1.67207, 5.58902, -0.881918, -3.01351, 0.671778, 1.70898, -14.3148, 15.1995}, {1.583, -1.583, -1.20581, 0.497745, -0.497745, 2.77232, -2.29648, -0.854984, 1.74929, -0.647223, -8.80718, 9.94741, -2.57194, 2.57194, -1.93632, 2.22336, 1.67207, -5.58902, 0.881918, 3.01351, -0.671778, -8.55536, 4.65993, 10.4123, -2.8729, -1.02253, -10.4175, 11.7579, 0.847997, -5.06083}, {6.34574, -4.8337, 3.10867, 0.725317, 2.59898, -0.725317, 1.60925, -1.2258, -1.60925, -0.219319, -2.98441, 3.37079, -1.18322, -15.6, 5.07865, -2.88568, -1.69734, 2.88568, -5.81154, 4.42679, 9.70697, 3.76295, 13.635, -16.3688, -0.625449, 0.47642, -3.26998, -1.71805, 5.20411, -2.17738}, {-2.11525, 1.61123, -1.03622, -2.17595, -7.79693, 2.17595, 1.60925, -1.2258, -1.60925, -0.219319, -2.98441, 3.37079, 10.179, -11.649, 6.32227, -9.32267, 3.20588, 9.32267, 0.625449, -0.47642, 3.26998, 2.88568, 1.69734, -2.88568, 0.251825, 12.4141, -16.7531, -1.71805, 5.20411, -2.17738}, {-2.11525, 1.61123, -1.03622, 0.725317, 2.59898, -0.725317, -4.82774, 3.67741, 4.82774, -0.219319, -2.98441, 3.37079, 1.71805, -5.20411, 2.17738, -5.78695, -12.0932, 5.78695, 9.08643, -6.92136, 7.41487, 2.88568, 1.69734, -2.88568, -0.625449, 0.47642, -3.26998, -0.840773, 17.1417, -15.6605}, {-2.11525, 1.61123, -1.03622, 0.725317, 2.59898, -0.725317, 1.60925, -1.2258, -1.60925, 0.657956, 8.95322, -10.1124, 1.71805, -5.20411, 2.17738, -2.88568, -1.69734, 2.88568, 0.625449, -0.47642, 3.26998, 11.3467, -4.7476, 1.25921, -3.52672, -9.91949, -0.36871, -8.15504, 10.1073, 4.25961}, {-5.36656, 5.36656, -5.36656, -1.78885, 1.78885, 1.36261, 0, -3.15147, 0, 0, 3.15147, -3.15147, 7.15542, -7.15542, -9.34589, 2.21115, 1.68428, -1.68428, -2.21115, 18.7124, -2.21115, -2.21115, -14.2902, 14.2902, 2.21115, -6.10657, 2.21115, 0, 3.63043e-12, 3.89543}, {1.78885, -1.78885, 1.78885, 5.36656, -5.36656, -4.08784, 0, -3.15147, 0, 0, 3.15147, -3.15147, -7.15542, 7.15542, -11.0508, 2.21115, 14.2902, -1.68428, -2.21115, 6.10657, -2.21115, -2.21115, -1.68428, 1.68428, 2.21115, -18.7124, 14.817, 0, 3.63132e-12, 3.89543}, {1.78885, -1.78885, 1.78885, -1.78885, 1.78885, 1.36261, 0, 9.45441, 0, 0, 3.15147, -3.15147, -1.33227e-15, -3.63265e-12, -3.89543, 9.36656, -5.47113, -7.13474, -9.36656, 13.262, -9.36656, -2.21115, -1.68428, 1.68428, 2.21115, -6.10657, 2.21115, 0, -12.6059, 16.5013}, {1.78885, -1.78885, 1.78885, -1.78885, 1.78885, 1.36261, 0, -3.15147, 0, 0, -9.45441, 9.45441, -1.33227e-15, -3.62732e-12, -3.89543, 2.21115, 1.68428, -1.68428, -2.21115, 6.10657, -2.21115, -9.36656, 5.47113, -5.47113, 9.36656, -13.262, -3.23931, 0, 12.6059, 3.89543}, {-9.24597e-16, 0, 9.45441, -1.78885, 1.36261, 1.78885, 1.78885, 1.78885, -1.78885, -3.08199e-16, -3.15147, 3.15147, 9.36656, -7.13474, -5.47113, 0, -3.89543, -3.62732e-12, -9.36656, -9.36656, 13.262, 1.2328e-15, 16.5013, -12.6059, 2.21115, 2.21115, -6.10657, -2.21115, 1.68428, -1.68428}, {6.16398e-16, 4.44089e-16, -3.15147, 5.36656, -4.08784, -5.36656, 1.78885, 1.78885, -1.78885, -6.16398e-16, -3.15147, 3.15147, 2.21115, -1.68428, 14.2902, -7.15542, -11.0508, 7.15542, -2.21115, -2.21115, 6.10657, -4.59069e-31, 3.89543, 3.62745e-12, 2.21115, 14.817, -18.7124, -2.21115, 1.68428, -1.68428}, {-6.16398e-16, 8.88178e-16, -3.15147, -1.78885, 1.36261, 1.78885, -5.36656, -5.36656, 5.36656, 6.16398e-16, -3.15147, 3.15147, 2.21115, -1.68428, 1.68428, 7.15542, -9.34589, -7.15542, -2.21115, -2.21115, 18.7124, 4.59069e-31, 3.89543, 3.62789e-12, 2.21115, 2.21115, -6.10657, -2.21115, 14.2902, -14.2902}, {-6.16398e-16, 8.88178e-16, -3.15147, -1.78885, 1.36261, 1.78885, 1.78885, 1.78885, -1.78885, -1.84919e-15, 9.45441, -9.45441, 2.21115, -1.68428, 1.68428, 0, -3.89543, -3.6251e-12, -2.21115, -2.21115, 6.10657, 2.46559e-15, 3.89543, 12.6059, 9.36656, -3.23931, -13.262, -9.36656, -5.47113, 5.47113}, {1.6947, 4.26991, -0.547096, 2.00519, -0.0353642, -0.0353642, 0.45376, 1.14328, 1.14328, -1.89405, 0.315388, -1.29028, -9.80104, 1.94447, -0.0402465, -3.03942, -1.36946, -1.36946, -1.67766, -4.22699, -6.2117, 10.6156, 0.107907, 6.53058, -0.137376, -0.346128, 1.63859, 1.78029, -1.80301, 0.181703}, {-0.5649, -1.4233, 0.182365, -6.01556, 0.106093, 0.106093, 0.45376, 1.14328, 1.14328, -1.89405, 0.315388, -1.29028, 0.479306, 7.49622, -0.911165, -4.85446, -5.94257, -5.94257, 0.137376, 0.346128, -1.63859, 3.03942, 1.36946, 1.36946, 7.43881, -1.60768, 6.79971, 1.78029, -1.80301, 0.181703}, {-0.5649, -1.4233, 0.182365, 2.00519, -0.0353642, -0.0353642, -1.36128, -3.42984, -3.42984, -1.89405, 0.315388, -1.29028, -1.78029, 1.80301, -0.181703, -11.0602, -1.228, -1.228, 2.39697, 6.03934, -2.36805, 3.03942, 1.36946, 1.36946, -0.137376, -0.346128, 1.63859, 9.35648, -3.06456, 5.34282}, {-0.5649, -1.4233, 0.182365, 2.00519, -0.0353642, -0.0353642, 0.45376, 1.14328, 1.14328, 5.68214, -0.946164, 3.87084, -1.78029, 1.80301, -0.181703, -3.03942, -1.36946, -1.36946, 0.137376, 0.346128, -1.63859, 5.29902, 7.06267, 0.639997, -8.15812, -0.204671, 1.78004, -0.0347482, -6.37613, -4.39141}, {-1.35612, -3.4307, -3.42632, -0.759405, 0.424983, -1.91868, -2.45728, -1.10819, -1.10678, 2.76464, -0.460356, 1.88336, 3.41754, -3.63876, 8.63464, 3.97604, 0.844494, 3.73968, 12.3077, 4.38905, 4.38345, -15.0346, 0.996929, -11.2731, -2.47861, 0.0437235, 0.0436678, -0.379924, 1.93883, -0.959903}, {0.45204, 1.14357, 1.14211, 2.27821, -1.27495, 5.75605, -2.45728, -1.10819, -1.10678, 2.76464, -0.460356, 1.88336, -1.42823, -6.51309, -3.60853, 13.8052, 5.27726, 8.1668, 2.47861, -0.0437235, -0.0436678, -3.97604, -0.844494, -3.73968, -13.5372, 1.88515, -7.48976, -0.379924, 1.93883, -0.959903}, {0.45204, 1.14357, 1.14211, -0.759405, 0.424983, -1.91868, 7.37184, 3.32458, 3.32034, 2.76464, -0.460356, 1.88336, 0.379924, -1.93883, 0.959903, 7.01366, -0.855437, 11.4144, 0.670454, -4.61799, -4.6121, -3.97604, -0.844494, -3.73968, -2.47861, 0.0437235, 0.0436678, -11.4385, 3.78026, -8.49333}, {0.45204, 1.14357, 1.14211, -0.759405, 0.424983, -1.91868, -2.45728, -1.10819, -1.10678, -8.29393, 1.38107, -5.65007, 0.379924, -1.93883, 0.959903, 3.97604, 0.844494, 3.73968, 2.47861, -0.0437235, -0.0436678, -5.7842, -5.41876, -8.30811, 0.559007, -1.65621, 7.71841, 9.44919, 6.3716, 3.46721}, {-2.4085, -2.4085, 2.4085, 1.63676, -1.63676, 1.63676, -0.802834, -0.802834, -0.802834, -1.63676, 1.63676, -0.0310931, -9.56255, 7.57784, -7.57784, -1.03079, 3.01551, -1.03079, 3.21134, 3.21134, 5.19605, 7.57784, -9.56255, 1.15516, 3.73035e-14, 3.68594e-14, -1.98471, 3.01551, -1.03079, 1.03079}, {0.802834, 0.802834, -0.802834, -4.91028, 4.91028, -4.91028, -0.802834, -0.802834, -0.802834, -1.63676, 1.63676, -0.0310931, -6.22684, -2.18055, 2.18055, 2.18055, 6.22684, 2.18055, -3.77476e-14, -3.68594e-14, 1.98471, 1.03079, -3.01551, 1.03079, 6.54704, -6.54704, -1.86034, 3.01551, -1.03079, 1.03079}, {0.802834, 0.802834, -0.802834, 1.63676, -1.63676, 1.63676, 2.4085, 2.4085, 2.4085, -1.63676, 1.63676, -0.0310931, -3.01551, 1.03079, -1.03079, -7.57784, 9.56255, -7.57784, -3.21134, -3.21134, 5.19605, 1.03079, -3.01551, 1.03079, 3.73035e-14, 3.68594e-14, -1.98471, 9.56255, -7.57784, 1.15516}, {0.802834, 0.802834, -0.802834, 1.63676, -1.63676, 1.63676, -0.802834, -0.802834, -0.802834, 4.91028, -4.91028, 0.0932794, -3.01551, 1.03079, -1.03079, -1.03079, 3.01551, -1.03079, -3.77476e-14, -3.73035e-14, 1.98471, -2.18055, -6.22684, 4.24213, -6.54704, 6.54704, -8.53176, 6.22684, 2.18055, 4.24213}, {-2.4085, -2.4085, 2.4085, -2.4396, 0.833927, -0.833927, -1.57573, 1.57573, 1.57573, 3.2125, -3.2125, 0.0610269, 11.7815, -5.35886, 5.35886, 4.96322, -2.97851, -0.916924, 7.25829, -9.24301, -7.25829, -17.8132, 15.8285, 0.672816, -0.955357, 2.94007, 0.955357, -2.02315, 2.02315, -2.02315}, {0.802834, 0.802834, -0.802834, 7.31879, -2.50178, 2.50178, -1.57573, 1.57573, 1.57573, 3.2125, -3.2125, 0.0610269, -1.18819, -5.23448, 5.23448, 11.2662, -9.28144, -7.21986, 0.955357, -2.94007, -0.955357, -4.96322, 2.97851, 0.916924, -13.8053, 15.7901, 0.71125, -2.02315, 2.02315, -2.02315}, {0.802834, 0.802834, -0.802834, -2.4396, 0.833927, -0.833927, 4.7272, -4.7272, -4.7272, 3.2125, -3.2125, 0.0610269, 2.02315, -2.02315, 2.02315, 14.7216, -6.31421, 2.41878, -2.25598, -6.15141, 2.25598, -4.96322, 2.97851, 0.916924, -0.955357, 2.94007, 0.955357, -14.8731, 14.8731, -2.26726}, {0.802834, 0.802834, -0.802834, -2.4396, 0.833927, -0.833927, -1.57573, 1.57573, 1.57573, -9.63749, 9.63749, -0.183081, 2.02315, -2.02315, 2.02315, 4.96322, -2.97851, -0.916924, 0.955357, -2.94007, -0.955357, -8.17456, -0.232831, 4.12826, 8.80302, -0.395637, 4.29107, 4.27979, -4.27979, -8.32609}, {1.77636e-15, 0, 4.817, 3.64699, 0.373467, -0.373467, -1.78885, -1.78885, 1.78885, -1.85814, 1.41539, 0.190281, -19.0959, -1.9555, 3.94022, -2.29678, 1.74951, -1.74951, 9.36656, 9.36656, -7.38185, 9.72932, -7.41106, 0.988391, -2.21115, -2.21115, 0.226431, 4.50793, 0.461631, -2.44635}, {2.22045e-16, 0, -1.60567, -10.941, -1.1204, 1.1204, -1.78885, -1.78885, 1.78885, -1.85814, 1.41539, 0.190281, -4.50793, -0.461631, 8.86902, 4.85864, 8.90493, -8.90493, 2.21115, 2.21115, -0.226431, 2.29678, -1.74951, 1.74951, 5.2214, -7.87269, -0.534693, 4.50793, 0.461631, -2.44635}, {-2.22045e-16, 0, -1.60567, 3.64699, 0.373467, -0.373467, 5.36656, 5.36656, -5.36656, -1.85814, 1.41539, 0.190281, -4.50793, -0.461631, 2.44635, -16.8847, 0.255645, -0.255645, 2.21115, 2.21115, 6.19624, 2.29678, -1.74951, 1.74951, -2.21115, -2.21115, 0.226431, 11.9405, -5.19992, -3.20747}, {0, 0, -1.60567, 3.64699, 0.373467, -0.373467, -1.78885, -1.78885, 1.78885, 5.57441, -4.24616, -0.570843, -4.50793, -0.461631, 2.44635, -2.29678, 1.74951, -1.74951, 2.21115, 2.21115, -0.226431, 2.29678, -1.74951, 8.17219, -16.7991, -3.70501, 1.7203, 11.6633, 7.61705, -9.60176}, {5.57441, -4.24616, 4.24616, -1.78885, -1.78885, 1.78885, 2.85327e-15, 3.15147, -2.92187e-16, 3.64699, -2.778, -0.373467, 11.6633, 7.61705, -7.61705, 2.21115, -1.68428, -2.21115, 2.29678, -18.2508, 1.74951, -16.7991, 12.7963, 3.70501, -2.29678, 5.64494, -1.74951, -4.50793, -0.461631, 0.461631}, {-1.85814, 1.41539, -1.41539, 5.36656, 5.36656, -5.36656, -5.70654e-15, 3.15147, 5.84374e-16, 3.64699, -2.778, -0.373467, 11.9405, -5.19992, 5.19992, 2.21115, -14.2902, -2.21115, 2.29678, -5.64494, 1.74951, -2.21115, 1.68428, 2.21115, -16.8847, 16.7569, -0.255645, -4.50793, -0.461631, 0.461631}, {-1.85814, 1.41539, -1.41539, -1.78885, -1.78885, 1.78885, 0, -9.45441, 0, 3.64699, -2.778, -0.373467, 4.50793, 0.461631, -0.461631, 9.36656, 5.47113, -9.36656, 9.72932, -11.3065, 7.41106, -2.21115, 1.68428, 2.21115, -2.29678, 5.64494, -1.74951, -19.0959, 10.6504, 1.9555}, {-1.85814, 1.41539, -1.41539, -1.78885, -1.78885, 1.78885, -2.85327e-15, 3.15147, 2.92187e-16, -10.941, 8.334, 1.1204, 4.50793, 0.461631, -0.461631, 2.21115, -1.68428, -2.21115, 2.29678, -5.64494, 1.74951, 5.2214, -3.97726, 7.87269, 4.85864, 12.8004, -8.90493, -4.50793, -13.0675, 0.461631}, {5.61089, -1.12882, 1.12882, -0.730647, 0.497098, 1.84603, 0.431092, 1.08918, -1.08918, 2.16985, -1.96255, -0.380575, 6.13753, -3.06794, -9.20083, 0.370271, -1.96075, -0.935513, 0.0545869, -6.16812, 6.16812, -9.04968, 9.81095, 2.45781, -1.77895, 1.8114, -1.8114, -3.21494, 1.07954, 1.81672}, {-1.8703, 0.376272, -0.376272, 2.19194, -1.49129, -5.53808, 0.431092, 1.08918, -1.08918, 2.16985, -1.96255, -0.380575, 10.6961, -2.58463, -0.311631, -1.3541, -6.31747, 3.42121, 1.77895, -1.8114, 1.8114, -0.370271, 1.96075, 0.935513, -10.4584, 9.6616, -0.289101, -3.21494, 1.07954, 1.81672}, {-1.8703, 0.376272, -0.376272, -0.730647, 0.497098, 1.84603, -1.29328, -3.26754, 3.26754, 2.16985, -1.96255, -0.380575, 3.21494, -1.07954, -1.81672, 3.29286, -3.94914, -8.31962, 9.26014, -3.31649, 3.31649, -0.370271, 1.96075, 0.935513, -1.77895, 1.8114, -1.8114, -11.8943, 8.92975, 3.33902}, {-1.8703, 0.376272, -0.376272, -0.730647, 0.497098, 1.84603, 0.431092, 1.08918, -1.08918, -6.50955, 5.88765, 1.14172, 3.21494, -1.07954, -1.81672, 0.370271, -1.96075, -0.935513, 1.77895, -1.8114, 1.8114, 7.11091, 0.455662, 2.4406, 1.14364, -0.176994, -9.19551, -4.93931, -3.27718, 6.17344}, {-3.9353, -0.877932, 3.73093, -7.99856e-17, -0.163745, 1.71788, -6.42512e-16, -1.31534, -0.704307, -1.31177, 1.18644, 0.230073, -1.62143, 0.495654, -7.45769, 8.93056e-16, 1.82825, -1.25284, -1.62143, 6.52549, 5.22503, 5.24706, -6.57403, 0.33255, 1.62143, -1.26412, -2.4078, 1.62143, 0.159328, 0.586185}, {1.31177, 0.292644, -1.24364, 7.39513e-16, 0.491236, -5.15363, -7.99343e-16, -1.31534, -0.704307, -1.31177, 1.18644, 0.230073, -6.86849, -1.3299, 4.38839, 4.49011e-15, 7.08962, 1.56438, -1.62143, 1.26412, 2.4078, -2.26969e-15, -1.82825, 1.25284, 6.86849, -6.0099, -3.32809, 1.62143, 0.159328, 0.586185}, {1.31177, 0.292644, -1.24364, -1.06647e-16, -0.163745, 1.71788, 2.57005e-15, 3.94603, 2.11292, -1.31177, 1.18644, 0.230073, -1.62143, -0.159328, -0.586185, 1.61733e-15, 2.48323, -8.12435, -6.86849, 0.0935482, 7.38238, -2.16769e-15, -1.82825, 1.25284, 1.62143, -1.26412, -2.4078, 6.86849, -4.58645, -0.334108}, {1.31177, 0.292644, -1.24364, -6.5475e-18, -0.163745, 1.71788, 1.12819e-15, -1.31534, -0.704307, 3.9353, -3.55933, -0.690219, -1.62143, -0.159328, -0.586185, -1.38643e-15, 1.82825, -1.25284, -1.62143, 1.26412, 2.4078, -5.24706, -2.99883, 6.22742, 1.62143, -0.609143, -9.27931, 1.62143, 5.4207, 3.40341}, {6.05767, -1.43278, 5.23404e-12, -4.96495e-16, 1.38248, -4.96495e-16, 0.572575, -0.389553, -1.44665, 1.44665, -1.47052, 1.44665, 2.4959, -7.82907, 2.15916e-12, -0.707741, -1.22732, 1.78815, -0.502145, 1.44939, 7.57474, -5.07885, 7.10939, -7.57474, -1.78815, 0.108825, -1.78815, -2.4959, 2.29917, -2.15716e-12}, {-2.01922, 0.477594, -1.74527e-12, 8.99956e-16, -4.14743, 2.97897e-15, 0.572575, -0.389553, -1.44665, 1.44665, -1.47052, 1.44665, 10.5728, -4.20955, 9.13936e-12, -2.99804, 0.330893, 7.57474, 1.78815, -0.108825, 1.78815, 0.707741, 1.22732, -1.78815, -7.57474, 5.99089, -7.57474, -2.4959, 2.29917, -2.15827e-12}, {-2.01922, 0.477594, -1.74238e-12, 0, 1.38248, 0, -1.71772, 1.16866, 4.33994, 1.44665, -1.47052, 1.44665, 2.4959, -2.29917, 2.15405e-12, -0.707741, -6.75722, 1.78815, 9.86504, -2.0192, 1.78815, 0.707741, 1.22732, -1.78815, -1.78815, 0.108825, -1.78815, -8.28248, 8.18124, -5.78659}, {-2.01922, 0.477594, -1.74483e-12, -4.96495e-16, 1.38248, -4.96495e-16, 0.572575, -0.389553, -1.44665, -4.33994, 4.41155, -4.33994, 2.4959, -2.29917, 2.15739e-12, -0.707741, -1.22732, 1.78815, 1.78815, -0.108825, 1.78815, 8.78463, -0.683057, -1.78815, -1.78815, -5.42108, -1.78815, -4.7862, 3.85739, 5.78659}, {4.44089e-16, -0.577407, 6.05767, 1.31177, 0.0490665, 1.31177, -5.0818e-16, -1.57494, 2.01922, -1.31177, 1.33341, -1.31177, -6.86849, -0.49482, -4.3726, -1.62143, 1.88609, -4.11733, 2.66454e-15, 8.00861, -8.07689, 6.86849, -7.21973, 9.36439, -6.66134e-16, -1.70883, -8.88178e-16, 1.62143, 0.298554, -0.874465}, {-6.66134e-16, 0.192469, -2.01922, -3.9353, -0.147199, -3.9353, -5.0818e-16, -1.57494, 2.01922, -1.31177, 1.33341, -1.31177, -1.62143, -1.06843, 8.95135, -1.62143, 8.18587, -12.1942, 1.33227e-15, 1.70883, 3.77476e-15, 1.62143, -1.88609, 4.11733, 5.24706, -7.04247, 5.24706, 1.62143, 0.298554, -0.874465}, {-6.66134e-16, 0.192469, -2.01922, 1.31177, 0.0490665, 1.31177, 5.33589e-15, 4.72483, -6.05767, -1.31177, 1.33341, -1.31177, -1.62143, -0.298554, 0.874465, -6.86849, 1.68982, -9.36439, 5.32907e-15, 0.938958, 8.07689, 1.62143, -1.88609, 4.11733, -3.10862e-15, -1.70883, -3.10862e-15, 6.86849, -5.03508, 4.3726}, {8.88178e-16, 0.192469, -2.01922, 1.31177, 0.0490665, 1.31177, -1.27045e-15, -1.57494, 2.01922, 3.9353, -4.00023, 3.9353, -1.62143, -0.298554, 0.874465, -1.62143, 1.88609, -4.11733, 4.44089e-16, 1.70883, 1.77636e-15, 1.62143, -2.65597, 12.1942, -5.24706, -1.9051, -5.24706, 1.62143, 6.59833, -8.95135}, {5.62183, 1.10117, 1.0932, -0.543248, 1.37255, -0.969804, 0.418614, -1.05765, -1.05825, 1.99858, 0.0521603, 2.39245, 5.16081, -6.73306, 5.52839, 0.154056, -0.389233, 2.50681, 0.12443, 5.99166, 5.99148, -8.14837, 0.180592, -12.0766, -1.79889, -1.76104, -1.75849, -2.98781, 1.24286, -1.64917}, {-1.87394, -0.367057, -0.364401, 1.62974, -4.11765, 2.90941, 0.418614, -1.05765, -1.05825, 1.99858, 0.0521603, 2.39245, 10.4836, 0.225367, 3.10677, -1.5204, 3.84139, 6.7398, 1.79889, 1.76104, 1.75849, -0.154056, 0.389233, -2.50681, -9.79319, -1.96968, -11.3283, -2.98781, 1.24286, -1.64917}, {-1.87394, -0.367057, -0.364401, -0.543248, 1.37255, -0.969804, -1.25584, 3.17296, 3.17474, 1.99858, 0.0521603, 2.39245, 2.98781, -1.24286, 1.64917, 2.32705, -5.87944, 6.38603, 9.29466, 3.22927, 3.2161, -0.154056, 0.389233, -2.50681, -1.79889, -1.76104, -1.75849, -10.9821, 1.03422, -11.219}, {-1.87394, -0.367057, -0.364401, -0.543248, 1.37255, -0.969804, 0.418614, -1.05765, -1.05825, -5.99573, -0.156481, -7.17736, 2.98781, -1.24286, 1.64917, 0.154056, -0.389233, 2.50681, 1.79889, 1.76104, 1.75849, 7.34172, 1.85746, -1.04921, 0.374107, -7.25124, 2.12073, -4.66227, 5.47348, 2.58382}, {1.30457, 0.988495, -4.07489, 1.69843, -1.02425, 0.473793, -0.0497917, 1.38543, -0.379098, -1.21378, -0.0316781, -1.45299, -8.35558, 5.77034, -4.15976, -2.03783, -0.446439, -0.117049, 0.798227, -6.84692, 0.306038, 6.89295, 0.573151, 5.92901, -0.59906, 1.3052, 1.21036, 1.56186, -1.67333, 2.26459}, {-0.434858, -0.329498, 1.3583, -5.09529, 3.07276, -1.42138, -0.0497917, 1.38543, -0.379098, -1.21378, -0.0316781, -1.45299, 0.17757, 2.99132, -7.69777, -1.83866, -5.98816, 1.39934, 0.59906, -1.3052, -1.21036, 2.03783, 0.446439, 0.117049, 4.25606, 1.43192, 7.02232, 1.56186, -1.67333, 2.26459}, {-0.434858, -0.329498, 1.3583, 1.69843, -1.02425, 0.473793, 0.149375, -4.15629, 1.1373, -1.21378, -0.0316781, -1.45299, -1.56186, 1.67333, -2.26459, -8.83155, 3.65057, -2.01222, 2.33849, 0.0127912, -6.64354, 2.03783, 0.446439, 0.117049, -0.59906, 1.3052, 1.21036, 6.41699, -1.54662, 8.07655}, {-0.434858, -0.329498, 1.3583, 1.69843, -1.02425, 0.473793, -0.0497917, 1.38543, -0.379098, 3.64134, 0.0950343, 4.35897, -1.56186, 1.67333, -2.26459, -2.03783, -0.446439, -0.117049, 0.59906, -1.3052, -1.21036, 3.77726, 1.76443, -5.31614, -7.39278, 5.40222, -0.684818, 1.76103, -7.21505, 3.78098}, {-3.43097, 1.35687, -3.43142, 0.931473, 0.558277, -1.41184, -0.847096, 2.35716, -0.851503, -1.22803, -2.46315, 1.11954, -6.29089, -2.36411, 5.97866, -0.104296, -3.60368, 2.79764, 3.02181, -11.7832, 3.0447, 5.01642, 13.4563, -7.27579, 0.366568, 2.35455, 0.361307, 2.565, 0.131007, -0.331307}, {1.14366, -0.45229, 1.14381, -2.79442, -1.67483, 4.23552, -0.847096, 2.35716, -0.851503, -1.22803, -2.46315, 1.11954, -7.13962, 1.67815, -4.24392, 3.28409, -13.0323, 6.20366, -0.366568, -2.35455, -0.361307, 0.104296, 3.60368, -2.79764, 5.2787, 12.2071, -4.11684, 2.565, 0.131007, -0.331307}, {1.14366, -0.45229, 1.14381, 0.931473, 0.558277, -1.41184, 2.54129, -7.07148, 2.55451, -1.22803, -2.46315, 1.11954, -2.565, -0.131007, 0.331307, -3.83019, -5.83679, 8.445, -4.94119, -0.545391, -4.93653, 0.104296, 3.60368, -2.79764, 0.366568, 2.35455, 0.361307, 7.47713, 9.9836, -4.80945}, {1.14366, -0.45229, 1.14381, 0.931473, 0.558277, -1.41184, -0.847096, 2.35716, -0.851503, 3.6841, 7.38945, -3.35861, -2.565, -0.131007, 0.331307, -0.104296, -3.60368, 2.79764, -0.366568, -2.35455, -0.361307, -4.47033, 5.41284, -7.37287, -3.35932, 0.121443, 6.00866, 5.95338, -9.29764, 3.0747}, {5.0671, -2.00529, 0.25185, -0.295203, -1.90215, -0.29354, 1.14353, -0.452546, 1.14392, 0.840709, 1.68627, -0.766433, 3.63346, 9.13356, 1.64076, -1.04859, 2.91057, -1.05113, -3.89983, 1.54334, -5.88589, -2.31425, -9.65564, 4.11686, -0.674283, 0.266845, 1.3102, -2.45265, -1.52496, -0.466604}, {-1.68903, 0.668429, -0.0839499, 0.885608, 5.70645, 0.880621, 1.14353, -0.452546, 1.14392, 0.840709, 1.68627, -0.766433, 9.20879, -1.14875, 0.802403, -5.6227, 4.72075, -5.62682, 0.674283, -0.266845, -1.3102, 1.04859, -2.91057, 1.05113, -4.03712, -6.47823, 4.37593, -2.45265, -1.52496, -0.466604}, {-1.68903, 0.668429, -0.0839499, -0.295203, -1.90215, -0.29354, -3.43058, 1.35764, -3.43177, 0.840709, 1.68627, -0.766433, 2.45265, 1.52496, 0.466604, 0.132224, 10.5192, 0.123031, 7.43042, -2.94056, -0.974399, 1.04859, -2.91057, 1.05113, -0.674283, 0.266845, 1.3102, -5.81549, -8.27004, 2.59913}, {-1.68903, 0.668429, -0.0839499, -0.295203, -1.90215, -0.29354, 1.14353, -0.452546, 1.14392, -2.52213, -5.0588, 2.2993, 2.45265, 1.52496, 0.466604, -1.04859, 2.91057, -1.05113, 0.674283, -0.266845, -1.3102, 7.80472, -5.58428, 1.38693, 0.506528, 7.87545, 2.48436, -7.02676, 0.285222, -5.04229}, {-7.02938, -7.10543e-15, -5.55112e-16, -1.54298, 0.610212, -1.54318, 1.7461, 1.33161, 1.74203, -2.54625, -1.94182, -0.198851, 5.18286, -3.19511, 8.08019, -0.25107, -2.40023, -0.245794, -12.0389, -6.97241, -9.12139, 10.4361, 10.1675, 1.0412, 5.05456, 1.64596, 2.15327, 0.989039, 0.754264, -1.90748}, {2.34313, 2.22045e-15, 1.36002e-15, 4.62893, -1.83064, 4.62954, 1.7461, 1.33161, 1.74203, -2.54625, -1.94182, -0.198851, -10.3615, -0.754264, 1.90748, -7.23545, -7.72668, -7.21392, -5.05456, -1.64596, -2.15327, 0.25107, 2.40023, 0.245794, 15.2395, 9.41326, 2.94867, 0.989039, 0.754264, -1.90748}, {2.34313, 2.22045e-16, 2.77556e-17, -1.54298, 0.610212, -1.54318, -5.23829, -3.99484, -5.22609, -2.54625, -1.94182, -0.198851, -0.989039, -0.754264, 1.90748, 5.92083, -4.84108, 5.92693, -14.4271, -1.64596, -2.15327, 0.25107, 2.40023, 0.245794, 5.05456, 1.64596, 2.15327, 11.174, 8.52156, -1.11207}, {2.34313, 8.88178e-16, -1.38778e-16, -1.54298, 0.610212, -1.54318, 1.7461, 1.33161, 1.74203, 7.63874, 5.82547, 0.596554, -0.989039, -0.754264, 1.90748, -0.25107, -2.40023, -0.245794, -5.05456, -1.64596, -2.15327, -9.12143, 2.40023, 0.245794, 11.2265, -0.794885, 8.32599, -5.99534, -4.57219, -8.8756}, {4.44089e-15, 3.55271e-15, -4.817, -1.54262, 0.610485, -1.54315, -0.200328, -1.9397, -0.198633, 1.74295, 1.32921, 0.136117, 8.07725, -3.19654, 6.09533, 2.1544, 1.643, 2.15296, 1.04893, 10.1564, -0.944658, -9.12619, -6.95984, -2.69743, -0.24762, -2.3976, 1.73919, -1.90678, 0.754601, 0.0772744}, {-4.44089e-16, -1.77636e-15, 1.60567, 4.62785, -1.83146, 4.62946, -0.200328, -1.9397, -0.198633, 1.74295, 1.32921, 0.136117, 1.90678, -0.754601, -6.49995, 2.95571, 9.40178, 2.9475, 0.24762, 2.3976, -1.73919, -2.1544, -1.643, -2.15296, -7.21941, -7.71444, 1.19472, -1.90678, 0.754601, 0.0772744}, {0, 2.22045e-16, 1.60567, -1.54262, 0.610485, -1.54315, 0.600985, 5.81909, 0.5959, 1.74295, 1.32921, 0.136117, 1.90678, -0.754601, -0.0772744, 8.32487, -0.798945, 8.32557, 0.24762, 2.3976, -8.16186, -2.1544, -1.643, -2.15296, -0.24762, -2.3976, 1.73919, -8.87857, -4.56224, -0.467193}, {-8.88178e-16, -4.44089e-16, 1.60567, -1.54262, 0.610485, -1.54315, -0.200328, -1.9397, -0.198633, -5.22884, -3.98763, -0.408351, 1.90678, -0.754601, -0.0772744, 2.1544, 1.643, 2.15296, 0.24762, 2.3976, -1.73919, -2.1544, -1.643, -8.57564, 5.92285, -4.83954, 7.9118, -1.10547, 8.51339, 0.871807}, {5.74294, 0.795668, -0.78877, 0.30138, -0.761926, 0.76354, -0.6496, 1.64227, 0.697377, 2.26253, -0.61512, -1.72384, 0.788176, 4.31733, -4.32294, 0.430423, -1.08816, -1.80579, 5.76757, -8.2712, -3.9765, -9.48055, 3.54864, 8.70115, -3.16917, 1.70212, 1.187, -1.9937, -1.26962, 1.26878}, {-1.91431, -0.265223, 0.262923, -0.904139, 2.28578, -2.29062, -0.6496, 1.64227, 0.697377, 2.26253, -0.61512, -1.72384, 9.65095, 2.33052, -2.32047, 3.02882, -7.65724, -4.5953, 3.16917, -1.70212, -1.187, -0.430423, 1.08816, 1.80579, -12.2193, 4.1626, 8.08236, -1.9937, -1.26962, 1.26878}, {-1.91431, -0.265223, 0.262923, 0.30138, -0.761926, 0.76354, 1.9488, -4.9268, -2.09213, 2.26253, -0.61512, -1.72384, 1.9937, 1.26962, -1.26878, -0.775096, 1.95954, -4.85995, 10.8264, -0.641232, -2.23869, -0.430423, 1.08816, 1.80579, -3.16917, 1.70212, 1.187, -11.0438, 1.19086, 8.16414}, {-1.91431, -0.265223, 0.262923, 0.30138, -0.761926, 0.76354, -0.6496, 1.64227, 0.697377, -6.7876, 1.84536, 5.17152, 1.9937, 1.26962, -1.26878, 0.430423, -1.08816, -1.80579, 3.16917, -1.70212, -1.187, 7.22683, 2.14905, 0.7541, -4.37469, 4.74982, -1.86717, 0.604703, -7.8387, -1.52073}, {-1.33227e-15, 6.00487, 0.829413, 1.98058e-16, 2.00162, -0.810615, 1.31177, 1.30033, 0.316508, -1.31177, -1.30033, 0.770578, -1.55431e-15, -8.00649, 4.58617, -1.62143, -4.08144, 0.61075, -6.86849, -4.33448, -1.31552, 6.86849, 9.28277, -3.69306, 1.62143, -0.866843, 0.0494889, 6.66134e-16, 6.66134e-16, -1.34371}, {0, -2.00162, -0.276471, 0, -6.00487, 2.43185, 1.31177, 1.30033, 0.316508, -1.31177, -1.30033, 0.770578, 0, 8.00649, 2.4496, -6.86849, -9.28277, -0.655284, -1.62143, 0.866843, -0.0494889, 1.62143, 4.08144, -0.61075, 6.86849, 4.33448, -3.03282, 0, 0, -1.34371}, {-1.77636e-15, -2.00162, -0.276471, 3.96116e-16, 2.00162, -0.810615, -3.9353, -3.901, -0.949525, -1.31177, -1.30033, 0.770578, 1.55431e-15, 3.10862e-15, 1.34371, -1.62143, -12.0879, 3.85321, -1.62143, 8.87333, 1.0564, 1.62143, 4.08144, -0.61075, 1.62143, -0.866843, 0.0494889, 5.24706, 5.20133, -4.42602}, {-2.22045e-16, -2.00162, -0.276471, 1.98058e-16, 2.00162, -0.810615, 1.31177, 1.30033, 0.316508, 3.9353, 3.901, -2.31173, 0, 1.77636e-15, 1.34371, -1.62143, -4.08144, 0.61075, -1.62143, 0.866843, -0.0494889, 1.62143, 12.0879, 0.495134, 1.62143, -8.87333, 3.29195, -5.24706, -5.20133, -2.60975}, {-1.70622, 4.31352, 1.8317, -8.44721e-17, -1.1641e-15, 1.08709, -2.01922, 1.66059e-12, 0.375548, 1.45048, 1.43784, -0.852066, -0.702999, 1.77727, -4.93735, 2.4959, -2.05116e-12, -1.80792, 9.86978, 1.77727, -1.21169, -8.29783, -5.75136, 5.21618, -1.7929, -1.77727, -0.290501, 0.702999, -1.77727, 0.589009}, {0.568738, -1.43784, -0.610568, 1.88822e-15, 3.49231e-15, -3.26126, -2.01922, 1.65915e-12, 0.375548, 1.45048, 1.43784, -0.852066, -2.97795, 7.52863, 1.85326, 10.5728, -8.68596e-12, -3.31011, 1.7929, 1.77727, 0.290501, -2.4959, 2.05045e-12, 1.80792, -7.59483, -7.52863, 3.11776, 0.702999, -1.77727, 0.589009}, {0.568738, -1.43784, -0.610568, 0, 0, 1.08709, 6.05767, -4.97756e-12, -1.12664, 1.45048, 1.43784, -0.852066, -0.702999, 1.77727, -0.589009, 2.4959, -2.05087e-12, -6.15626, -0.482057, 7.52863, 2.73277, -2.4959, 2.05194e-12, 1.80792, -1.7929, -1.77727, -0.290501, -5.09894, -7.52863, 3.99727}, {0.568738, -1.43784, -0.610568, 0, 0, 1.08709, -2.01922, 1.65667e-12, 0.375548, -4.35145, -4.31352, 2.5562, -0.702999, 1.77727, -0.589009, 2.4959, -2.04775e-12, -1.80792, 1.7929, 1.77727, 0.290501, -4.77085, 5.75136, 4.25019, -1.7929, -1.77727, -4.63885, 8.77989, -1.77727, -0.913184}, {1.27077, -1.27077, -5.5547, 1.35703, 0.9861, 0.537103, -0.781872, 0.781872, -0.309461, -0.151563, -2.19156, -2.07921, -6.58189, -5.68687, -5.10097, -0.710928, -2.18533, -0.281381, 4.61752, -4.61752, -0.668306, 1.31718, 10.9516, 8.59822, -1.49003, 1.49003, 1.90615, 1.15379, 1.74247, 2.95256}, {-0.42359, 0.42359, 1.85157, -4.07108, -2.9583, -1.61131, -0.781872, 0.781872, -0.309461, -0.151563, -2.19156, -2.07921, 0.540572, -3.43683, -10.3588, 2.41656, -5.31282, 0.956461, 1.49003, -1.49003, -1.90615, 0.710928, 2.18533, 0.281381, -0.883782, 10.2563, 10.223, 1.15379, 1.74247, 2.95256}, {-0.42359, 0.42359, 1.85157, 1.35703, 0.9861, 0.537103, 2.34562, -2.34562, 0.928382, -0.151563, -2.19156, -2.07921, -1.15379, -1.74247, -2.95256, -6.13903, -6.12973, -2.42979, 3.18439, -3.18439, -9.31242, 0.710928, 2.18533, 0.281381, -1.49003, 1.49003, 1.90615, 1.76004, 10.5087, 11.2694}, {-0.42359, 0.42359, 1.85157, 1.35703, 0.9861, 0.537103, -0.781872, 0.781872, -0.309461, 0.454689, 6.57469, 6.23763, -1.15379, -1.74247, -2.95256, -0.710928, -2.18533, -0.281381, 1.49003, -1.49003, -1.90615, 2.40529, 0.490973, -7.12489, -6.91814, -2.45437, -0.242264, 4.28128, -1.38502, 4.1904}, {2.56157, 0.777047, 3.89096, 1.32901, 0.581011, 0.152782, -0.565397, -1.62691, -0.0938093, 0.0902443, 1.30491, 1.23801, -5.90336, -2.72205, 0.803187, -0.943878, 1.2928, -0.0728941, 4.01589, 8.83876, 2.09436, 0.5829, -6.51244, -4.87916, -1.7543, -2.33113, -1.71912, 0.587321, 0.398009, -1.41431}, {-0.853857, -0.259016, -1.29699, -3.98703, -1.74303, -0.458346, -0.565397, -1.62691, -0.0938093, 0.0902443, 1.30491, 1.23801, 2.82811, 0.638054, 6.60226, 1.31771, 7.80043, 0.302343, 1.7543, 2.33113, 1.71912, 0.943878, -1.2928, 0.0728941, -2.11527, -7.55078, -6.67117, 0.587321, 0.398009, -1.41431}, {-0.853857, -0.259016, -1.29699, 1.32901, 0.581011, 0.152782, 1.69619, 4.88072, 0.281428, 0.0902443, 1.30491, 1.23801, -0.587321, -0.398009, 1.41431, -6.25992, -1.03125, -0.684022, 5.16973, 3.36719, 6.90706, 0.943878, -1.2928, 0.0728941, -1.7543, -2.33113, -1.71912, 0.226344, -4.82164, -6.36637}, {-0.853857, -0.259016, -1.29699, 1.32901, 0.581011, 0.152782, -0.565397, -1.62691, -0.0938093, -0.270733, -3.91473, -3.71404, -0.587321, -0.398009, 1.41431, -0.943878, 1.2928, -0.0728941, 1.7543, 2.33113, 1.71912, 4.35931, -0.256736, 5.26084, -7.07034, -4.65518, -2.33025, 2.84891, 6.90564, -1.03908}, {4.07852e-12, -2.19419, -6.05767, 0, 1.35003, 0, -1.44665, -1.05122, -0.572575, 1.44665, -1.0302, -1.44665, 1.68043e-12, -7.97291, -2.4959, 1.78815, -0.369344, 0.707741, 7.57474, 4.60023, 0.502145, -7.57474, 4.49015, 5.07885, -1.78815, -0.395328, 1.78815, -1.68043e-12, 2.57279, 2.4959}, {-1.36113e-12, 0.731398, 2.01922, 2.90906e-15, -4.05009, -4.93928e-15, -1.44665, -1.05122, -0.572575, 1.44665, -1.0302, -1.44665, 7.12852e-12, -5.49838, -10.5728, 7.57474, 3.83556, 2.99804, 1.78815, 0.395328, -1.78815, -1.78815, 0.369344, -0.707741, -7.57474, 3.72548, 7.57474, -1.68354e-12, 2.57279, 2.4959}, {-1.35891e-12, 0.731398, 2.01922, 0, 1.35003, 0, 4.33994, 3.15367, 1.71772, 1.44665, -1.0302, -1.44665, 1.67955e-12, -2.57279, -2.4959, 1.78815, -5.76946, 0.707741, 1.78815, -2.53026, -9.86504, -1.78815, 0.369344, -0.707741, -1.78815, -0.395328, 1.78815, -5.78659, 6.6936, 8.28248}, {-1.36025e-12, 0.731398, 2.01922, 0, 1.35003, 0, -1.44665, -1.05122, -0.572575, -4.33994, 3.09061, 4.33994, 1.68154e-12, -2.57279, -2.4959, 1.78815, -0.369344, 0.707741, 1.78815, 0.395328, -1.78815, -1.78815, -2.55625, -8.78463, -1.78815, -5.79545, 1.78815, 5.78659, 6.77769, 4.7862}, {5.43308, 2.37521, 0.624583, 1.07522, 0.584331, -1.07522, 1.83687, -0.576694, 0.182353, -1.10106, 0.784101, 1.10106, -3.39138, -2.08096, 5.88727, -3.59954, -0.00943971, 1.10365, -7.37942, 3.99825, -0.697471, 8.00379, -3.12696, -5.50789, 0.0319413, -1.69148, -0.0319413, -0.909507, -0.256369, -1.58639}, {-1.81103, -0.791738, -0.208194, -3.22566, -1.75299, 3.22566, 1.83687, -0.576694, 0.182353, -1.10106, 0.784101, 1.10106, 8.15362, 3.42332, 2.41917, -10.947, 2.29734, 0.374233, -0.0319413, 1.69148, 0.0319413, 3.59954, 0.00943971, -1.10365, 4.43619, -4.82788, -4.43619, -0.909507, -0.256369, -1.58639}, {-1.81103, -0.791738, -0.208194, 1.07522, 0.584331, -1.07522, -5.51061, 1.73008, -0.547059, -1.10106, 0.784101, 1.10106, 0.909507, 0.256369, 1.58639, -7.90043, -2.34676, 5.40453, 7.21217, 4.85843, 0.864718, 3.59954, 0.00943971, -1.10365, 0.0319413, -1.69148, -0.0319413, 3.49474, -3.39277, -5.99064}, {-1.81103, -0.791738, -0.208194, 1.07522, 0.584331, -1.07522, 1.83687, -0.576694, 0.182353, 3.30319, -2.3523, -3.30319, 0.909507, 0.256369, 1.58639, -3.59954, -0.00943971, 1.10365, -0.0319413, 1.69148, 0.0319413, 10.8437, 3.17639, -0.270869, -4.26894, -4.0288, 4.26894, -8.25698, 2.05041, -2.3158}, {1.1204, -1.1204, 10.941, 1.78885, -1.78885, 1.78885, -1.60567, 0, 0, 0.190281, 1.41539, 1.85814, -8.90493, 8.90493, -4.85864, -0.226431, 2.21115, -2.21115, 8.86902, -0.461631, 4.50793, -0.534693, -7.87269, -5.2214, -2.44635, 0.461631, -4.50793, 1.74951, -1.74951, -2.29678}, {-0.373467, 0.373467, -3.64699, -5.36656, 5.36656, -5.36656, -1.60567, 0, 0, 0.190281, 1.41539, 1.85814, -0.255645, 0.255645, 16.8847, 6.19624, 2.21115, -2.21115, 2.44635, -0.461631, 4.50793, 0.226431, -2.21115, 2.21115, -3.20747, -5.19992, -11.9405, 1.74951, -1.74951, -2.29678}, {-0.373467, 0.373467, -3.64699, 1.78885, -1.78885, 1.78885, 4.817, 0, 0, 0.190281, 1.41539, 1.85814, -1.74951, 1.74951, 2.29678, -7.38185, 9.36656, -9.36656, 3.94022, -1.9555, 19.0959, 0.226431, -2.21115, 2.21115, -2.44635, 0.461631, -4.50793, 0.988391, -7.41106, -9.72932}, {-0.373467, 0.373467, -3.64699, 1.78885, -1.78885, 1.78885, -1.60567, 0, 0, -0.570843, -4.24616, -5.57441, -1.74951, 1.74951, 2.29678, -0.226431, 2.21115, -2.21115, 2.44635, -0.461631, 4.50793, 1.7203, -3.70501, 16.7991, -9.60176, 7.61705, -11.6633, 8.17219, -1.74951, -2.29678}, {4.24616, -4.24616, -5.57441, 1.78885, -1.78885, 1.78885, 0, 3.15147, 0, -0.373467, -2.778, -3.64699, -7.61705, 7.61705, -11.6633, -2.21115, -1.68428, -2.21115, 1.74951, -18.2508, -2.29678, 3.70501, 12.7963, 16.7991, -1.74951, 5.64494, 2.29678, 0.461631, -0.461631, 4.50793}, {-1.41539, 1.41539, 1.85814, -5.36656, 5.36656, -5.36656, -2.92187e-16, 3.15147, -2.85327e-15, -0.373467, -2.778, -3.64699, 5.19992, -5.19992, -11.9405, -2.21115, -14.2902, -2.21115, 1.74951, -5.64494, -2.29678, 2.21115, 1.68428, 2.21115, -0.255645, 16.7569, 16.8847, 0.461631, -0.461631, 4.50793}, {-1.41539, 1.41539, 1.85814, 1.78885, -1.78885, 1.78885, 0, -9.45441, 0, -0.373467, -2.778, -3.64699, -0.461631, 0.461631, -4.50793, -9.36656, 5.47113, -9.36656, 7.41106, -11.3065, -9.72932, 2.21115, 1.68428, 2.21115, -1.74951, 5.64494, 2.29678, 1.9555, 10.6504, 19.0959}, {-1.41539, 1.41539, 1.85814, 1.78885, -1.78885, 1.78885, 0, 3.15147, 0, 1.1204, 8.334, 10.941, -0.461631, 0.461631, -4.50793, -2.21115, -1.68428, -2.21115, 1.74951, -5.64494, -2.29678, 7.87269, -3.97726, -5.2214, -8.90493, 12.8004, -4.85864, 0.461631, -13.0675, 4.50793}, {-4.91028, 4.91028, 4.91028, -0.802834, -0.802834, 0.802834, -0.802834, 0.802834, -0.802834, -0.0310931, 1.63676, 1.63676, 2.18055, 6.22684, -2.18055, 1.98471, -5.77316e-15, 5.88418e-15, 2.18055, -2.18055, 6.22684, -1.86034, -6.54704, -6.54704, 1.03079, -1.03079, -3.01551, 1.03079, -3.01551, -1.03079}, {1.63676, -1.63676, -1.63676, 2.4085, 2.4085, -2.4085, -0.802834, 0.802834, -0.802834, -0.0310931, 1.63676, 1.63676, -7.57784, 9.56255, 7.57784, 5.19605, -3.21134, 3.21134, -1.03079, 1.03079, 3.01551, -1.98471, 7.32522e-15, -4.99825e-15, 1.15516, -7.57784, -9.56255, 1.03079, -3.01551, -1.03079}, {1.63676, -1.63676, -1.63676, -0.802834, -0.802834, 0.802834, 2.4085, -2.4085, 2.4085, -0.0310931, 1.63676, 1.63676, -1.03079, 3.01551, 1.03079, 5.19605, 3.21134, -3.21134, -7.57784, 7.57784, 9.56255, -1.98471, 6.77011e-15, -4.2211e-15, 1.03079, -1.03079, -3.01551, 1.15516, -9.56255, -7.57784}, {1.63676, -1.63676, -1.63676, -0.802834, -0.802834, 0.802834, -0.802834, 0.802834, -0.802834, 0.0932794, -4.91028, -4.91028, -1.03079, 3.01551, 1.03079, 1.98471, -5.77316e-15, 5.77316e-15, -1.03079, 1.03079, 3.01551, -8.53176, 6.54704, 6.54704, 4.24213, 2.18055, -6.22684, 4.24213, -6.22684, 2.18055}, {2.4085, -2.4085, 2.4085, -0.833927, 0.833927, 2.4396, 1.57573, 1.57573, 1.57573, 0.0610269, -3.2125, -3.2125, 5.35886, -5.35886, -11.7815, -0.916924, -2.97851, -4.96322, -7.25829, -9.24301, -7.25829, 0.672816, 15.8285, 17.8132, 0.955357, 2.94007, 0.955357, -2.02315, 2.02315, 2.02315}, {-0.802834, 0.802834, -0.802834, 2.50178, -2.50178, -7.31879, 1.57573, 1.57573, 1.57573, 0.0610269, -3.2125, -3.2125, 5.23448, -5.23448, 1.18819, -7.21986, -9.28144, -11.2662, -0.955357, -2.94007, -0.955357, 0.916924, 2.97851, 4.96322, 0.71125, 15.7901, 13.8053, -2.02315, 2.02315, 2.02315}, {-0.802834, 0.802834, -0.802834, -0.833927, 0.833927, 2.4396, -4.7272, -4.7272, -4.7272, 0.0610269, -3.2125, -3.2125, 2.02315, -2.02315, -2.02315, 2.41878, -6.31421, -14.7216, 2.25598, -6.15141, 2.25598, 0.916924, 2.97851, 4.96322, 0.955357, 2.94007, 0.955357, -2.26726, 14.8731, 14.8731}, {-0.802834, 0.802834, -0.802834, -0.833927, 0.833927, 2.4396, 1.57573, 1.57573, 1.57573, -0.183081, 9.63749, 9.63749, 2.02315, -2.02315, -2.02315, -0.916924, -2.97851, -4.96322, -0.955357, -2.94007, -0.955357, 4.12826, -0.232831, 8.17456, 4.29107, -0.395637, -8.80302, -8.32609, -4.27979, -4.27979}, {4.10689, -1.43706, 2.82495e-12, 0.16503, -0.581747, -1.44665, -0.119439, -0.784236, 1.44665, 1.32337, 0.886963, 9.09971e-13, 0.828026, 2.45397, 7.57474, -0.0563528, 1.68845, -3.88578e-14, 2.31753, 3.51421, -7.57474, -5.23714, -5.2363, -3.60102e-12, -1.83977, -0.377268, 1.78815, -1.48814, -0.126978, -1.78815}, {-1.36896, 0.47902, -9.39573e-13, -0.495089, 1.74524, 4.33994, -0.119439, -0.784236, 1.44665, 1.32337, 0.886963, 9.08486e-13, 6.964, -1.7891, 1.78815, 0.421405, 4.82539, -5.78659, 1.83977, 0.377268, -1.78815, 0.0563528, -1.68845, 3.81917e-14, -7.13326, -3.92512, 1.78815, -1.48814, -0.126978, -1.78815}, {-1.36896, 0.47902, -9.39612e-13, 0.16503, -0.581747, -1.44665, 0.358318, 2.35271, -4.33994, 1.32337, 0.886963, 9.09414e-13, 1.48814, 0.126978, 1.78815, -0.716472, 4.01544, 5.78659, 7.31562, -1.53881, -1.78815, 0.0563528, -1.68845, 3.73035e-14, -1.83977, -0.377268, 1.78815, -6.78164, -3.67483, -1.78815}, {-1.36896, 0.47902, -9.40166e-13, 0.16503, -0.581747, -1.44665, -0.119439, -0.784236, 1.44665, -3.97012, -2.66089, -2.72657e-12, 1.48814, 0.126978, 1.78815, -0.0563528, 1.68845, -3.88578e-14, 1.83977, 0.377268, -1.78815, 5.53221, -3.60453, 3.79974e-12, -2.49989, 1.94972, 7.57474, -1.01039, 3.00996, -7.57474}, {-1.71772, 0.961283, -4.33994, 1.44665, 0.27723, -1.44665, 3.50028e-16, 1.39654, 2.40289e-28, -2.01922, -1.35334, -1.38617e-12, -8.28248, -1.05552, 5.78659, -1.78815, -2.06889, 1.78815, -0.707741, -6.9163, -1.78815, 9.86504, 7.48225, -1.78815, 0.707741, 1.33015, 1.78815, 2.4959, -0.0533958, 1.7134e-12}, {0.572575, -0.320428, 1.44665, -4.33994, -0.831689, 4.33994, -3.50028e-16, 1.39654, -2.40289e-28, -2.01922, -1.35334, -1.38617e-12, -4.7862, 1.33511, -5.78659, -1.78815, -7.65505, 1.78815, -0.707741, -1.33015, -1.78815, 1.78815, 2.06889, -1.78815, 8.78463, 6.74351, 1.78815, 2.4959, -0.0533958, 1.7134e-12}, {0.572575, -0.320428, 1.44665, 1.44665, 0.27723, -1.44665, 0, -4.18962, 0, -2.01922, -1.35334, -1.38689e-12, -2.4959, 0.0533958, -1.71537e-12, -7.57474, -3.17781, 7.57474, -2.99804, -0.0484352, -7.57474, 1.78815, 2.06889, -1.78815, 0.707741, 1.33015, 1.78815, 10.5728, 5.35997, 7.26187e-12}, {0.572575, -0.320428, 1.44665, 1.44665, 0.27723, -1.44665, 3.50028e-16, 1.39654, 2.40604e-28, 6.05767, 4.06002, 4.16395e-12, -2.4959, 0.0533958, -1.71672e-12, -1.78815, -2.06889, 1.78815, -0.707741, -1.33015, -1.78815, -0.502145, 3.3506, -7.57474, -5.07885, 0.221228, 7.57474, 2.4959, -5.63955, 1.71564e-12}, {-4.35597, 0.237767, -4.31288, 0, -1.20934, 0, 0.57469, 0.297534, -1.45022, -2.02668, 0.991065, 0.0125895, -1.79476, 6.43017, -1.77701, -0.710355, 1.12706, 1.79257, -4.80387, -1.45994, 5.81643, 8.81707, -5.09132, -1.84292, 2.50511, 0.269807, -0.0155615, 1.79476, -1.5928, 1.77701}, {1.45199, -0.0792556, 1.43763, 0, 3.62803, 0, 0.57469, 0.297534, -1.45022, -2.02668, 0.991065, 0.0125895, -7.60272, 1.90982, -7.52752, -3.00911, -0.0630793, 7.59343, -2.50511, -0.269807, 0.0155615, 0.710355, -1.12706, -1.79257, 10.6118, -3.69445, -0.0659197, 1.79476, -1.5928, 1.77701}, {1.45199, -0.0792556, 1.43763, 0, -1.20934, 0, -1.72407, -0.892603, 4.35065, -2.02668, 0.991065, 0.0125895, -1.79476, 1.5928, -1.77701, -0.710355, 5.96443, 1.79257, -8.31307, 0.047215, -5.73495, 0.710355, -1.12706, -1.79257, 2.50511, 0.269807, -0.0155615, 9.90148, -5.55705, 1.72665}, {1.45199, -0.0792556, 1.43763, 0, -1.20934, 0, 0.57469, 0.297534, -1.45022, 6.08004, -2.97319, -0.0377686, -1.79476, 1.5928, -1.77701, -0.710355, 1.12706, 1.79257, -2.50511, -0.269807, 0.0155615, -5.09761, -0.810036, -7.54308, 2.50511, 5.10718, -0.0155615, -0.504, -2.78293, 7.57787}, {-1.3922, -1.05489, 4.34859, -1.6823, -0.386683, 0.0104503, -0.635567, 0.941579, 1.4506, 1.8538, -0.906526, -0.0115156, 8.23503, 1.59006, 1.737, 2.86504, -0.685889, -1.80595, 2.75426, -5.36481, -5.8037, -10.2803, 4.31199, 1.85201, -0.211987, 1.59849, 0.00131684, -1.50582, -0.0433277, -1.7788}, {0.464066, 0.35163, -1.44953, 5.0469, 1.16005, -0.0313509, -0.635567, 0.941579, 1.4506, 1.8538, -0.906526, -0.0115156, -0.350444, -1.36319, 7.57692, 5.40731, -4.4522, -7.60833, 0.211987, -1.59849, -0.00131684, -2.86504, 0.685889, 1.80595, -7.6272, 5.2246, 0.0473794, -1.50582, -0.0433277, -1.7788}, {0.464066, 0.35163, -1.44953, -1.6823, -0.386683, 0.0104503, 1.9067, -2.82474, -4.35179, 1.8538, -0.906526, -0.0115156, 1.50582, 0.0433277, 1.7788, 9.59425, 0.860843, -1.84775, -1.64428, -3.00501, 5.7968, -2.86504, 0.685889, 1.80595, -0.211987, 1.59849, 0.00131684, -8.92103, 3.58278, -1.73274}, {0.464066, 0.35163, -1.44953, -1.6823, -0.386683, 0.0104503, -0.635567, 0.941579, 1.4506, -5.56141, 2.71958, 0.0345469, 1.50582, 0.0433277, 1.7788, 2.86504, -0.685889, -1.80595, 0.211987, -1.59849, -0.00131684, -4.72131, -0.720632, 7.60407, 6.51722, 3.14523, -0.0404844, 1.03645, -3.80964, -7.58118}, {-4.91028, -4.91028, 4.91028, 1.57573, -1.57573, -1.57573, -1.57573, 1.57573, -1.57573, -1.63676, -1.63676, 4.78823, -10.2738, 6.2275, 10.2738, 2.88658e-15, -3.33067e-15, 3.89543, 6.2275, -10.2738, 10.2738, 6.54704, 6.54704, -23.0483, 0.0754334, 3.97086, -3.97086, 3.97086, 0.0754334, -3.97086}, {1.63676, 1.63676, -1.63676, -4.7272, 4.7272, 4.7272, -1.57573, 1.57573, -1.57573, -1.63676, -1.63676, 4.78823, -10.5179, -6.62248, 10.5179, 6.30294, -6.30294, 10.1984, -0.0754334, -3.97086, 3.97086, -3.88353e-15, 1.66759e-15, -3.89543, 6.62248, 10.5179, -23.1238, 3.97086, 0.0754334, -3.97086}, {1.63676, 1.63676, -1.63676, 1.57573, -1.57573, -1.57573, 4.7272, -4.7272, 4.7272, -1.63676, -1.63676, 4.78823, -3.97086, -0.0754334, 3.97086, -6.30294, 6.30294, 10.1984, -6.62248, -10.5179, 10.5179, -3.43944e-15, 1.00145e-15, -3.89543, 0.0754334, 3.97086, -3.97086, 10.5179, 6.62248, -23.1238}, {1.63676, 1.63676, -1.63676, 1.57573, -1.57573, -1.57573, -1.57573, 1.57573, -1.57573, 4.91028, 4.91028, -14.3647, -3.97086, -0.0754334, 3.97086, 2.88658e-15, -3.10862e-15, 3.89543, -0.0754334, -3.97086, 3.97086, -6.54704, -6.54704, 2.65162, -6.2275, 10.2738, 2.33207, 10.2738, -6.2275, 2.33207}, {-1.37636, -1.37636, -5.42796, -2.30348, 0.847989, 0.553233, 1.22922, -1.92224, -0.562043, 0.615468, 0.615468, -1.80051, 11.4941, -5.00722, -5.1332, 1.32785, 1.32785, 0.0108901, -7.00339, 9.49791, 0.706454, -3.78972, -3.78972, 7.19114, 2.0865, -1.80893, 1.54172, -2.28016, 1.61526, 2.92027}, {0.458787, 0.458787, 1.80932, 6.91044, -2.54397, -1.6597, 1.22922, -1.92224, -0.562043, 0.615468, 0.615468, -1.80051, 0.445015, -3.45041, -10.1575, -3.58904, 9.01683, 2.25906, -2.0865, 1.80893, -1.54172, -1.32785, -1.32785, -0.0108901, -0.375375, -4.2708, 8.74375, -2.28016, 1.61526, 2.92027}, {0.458787, 0.458787, 1.80932, -2.30348, 0.847989, 0.553233, -3.68767, 5.76673, 1.68613, 0.615468, 0.615468, -1.80051, 2.28016, -1.61526, -2.92027, 10.5418, -2.0641, -2.20204, -3.92165, -0.0262169, -8.77899, -1.32785, -1.32785, -0.0108901, 2.0865, -1.80893, 1.54172, -4.74204, -0.846607, 10.1223}, {0.458787, 0.458787, 1.80932, -2.30348, 0.847989, 0.553233, 1.22922, -1.92224, -0.562043, -1.8464, -1.8464, 5.40152, 2.28016, -1.61526, -2.92027, 1.32785, 1.32785, 0.0108901, -2.0865, 1.80893, -1.54172, -3.163, -3.163, -7.24816, 11.3004, -5.20089, -0.671213, -7.19706, 9.30424, 5.16845}, {5.36656, -5.36656, -5.36656, 1.41539, 1.85814, -1.41539, 0, 0, -3.15147, 0.373467, -3.64699, 2.778, -5.19992, -11.9405, 5.19992, -1.74951, -2.29678, 5.64494, 2.21115, -2.21115, 14.2902, 0.255645, 16.8847, -16.7569, -2.21115, 2.21115, -1.68428, -0.461631, 4.50793, 0.461631}, {-1.78885, 1.78885, 1.78885, -4.24616, -5.57441, 4.24616, 0, 0, -3.15147, 0.373467, -3.64699, 2.778, 7.61705, -11.6633, -7.61705, -1.74951, -2.29678, 18.2508, 2.21115, -2.21115, 1.68428, 1.74951, 2.29678, -5.64494, -3.70501, 16.7991, -12.7963, -0.461631, 4.50793, 0.461631}, {-1.78885, 1.78885, 1.78885, 1.41539, 1.85814, -1.41539, 0, 0, 9.45441, 0.373467, -3.64699, 2.778, 0.461631, -4.50793, -0.461631, -7.41106, -9.72932, 11.3065, 9.36656, -9.36656, -5.47113, 1.74951, 2.29678, -5.64494, -2.21115, 2.21115, -1.68428, -1.9555, 19.0959, -10.6504}, {-1.78885, 1.78885, 1.78885, 1.41539, 1.85814, -1.41539, 0, 0, -3.15147, -1.1204, 10.941, -8.334, 0.461631, -4.50793, -0.461631, -1.74951, -2.29678, 5.64494, 2.21115, -2.21115, 1.68428, 8.90493, -4.85864, -12.8004, -7.87269, -5.2214, 3.97726, -0.461631, 4.50793, 13.0675}, {5.73547, -8.96906, -2.62245, 0.335815, -3.2793, -0.653542, 1.76841, -1.58918, 1.21052, -0.192397, 1.8788, -1.43113, 0.604796, 13.4752, 2.34148, -2.60096, 6.01778, -0.688458, -6.89635, 4.62559, -7.41885, 3.37055, -13.533, 6.41296, -0.177274, 1.73112, 2.57679, -1.94806, -0.357987, 0.272688}, {-1.91182, 2.98969, 0.874151, -1.00744, 9.83791, 1.96063, 1.76841, -1.58918, 1.21052, -0.192397, 1.8788, -1.43113, 9.59535, -11.6008, -3.76929, -9.67459, 12.3745, -5.53052, 0.177274, -1.73112, -2.57679, 2.60096, -6.01778, 0.688458, 0.592313, -5.78406, 8.30129, -1.94806, -0.357987, 0.272688}, {-1.91182, 2.98969, 0.874151, 0.335815, -3.2793, -0.653542, -5.30522, 4.76754, -3.63155, -0.192397, 1.8788, -1.43113, 1.94806, 0.357987, -0.272688, -3.94422, 19.135, 1.92571, 7.82457, -13.6899, -6.07339, 2.60096, -6.01778, 0.688458, -0.177274, 1.73112, 2.57679, -1.17847, -7.87317, 5.99719}, {-1.91182, 2.98969, 0.874151, 0.335815, -3.2793, -0.653542, 1.76841, -1.58918, 1.21052, 0.57719, -5.63639, 4.29338, 1.94806, 0.357987, -0.272688, -2.60096, 6.01778, -0.688458, 0.177274, -1.73112, -2.57679, 10.2483, -17.9765, -2.80815, -1.52053, 14.8483, 5.19096, -9.02168, 5.99873, -4.56938}, {-0.906892, 2.28653, -2.28852, -1.55284, 0.422175, 1.18312, -0.363916, -0.686733, -0.918335, 1.61446, 1.02673, -1.02763, 7.75714, -1.26844, -7.13784, 2.36925, 0.327011, -0.327296, 1.53183, 4.53788, 3.86554, -8.8271, -4.43394, 4.43781, -0.0761652, -1.79095, -0.192201, -1.54576, -0.420263, 2.40534}, {0.302297, -0.762175, 0.762841, 4.65853, -1.26653, -3.54937, -0.363916, -0.686733, -0.918335, 1.61446, 1.02673, -1.02763, 0.336571, 3.46896, -5.45671, 3.82491, 3.07394, 3.34604, 0.0761652, 1.79095, 0.192201, -2.36925, -0.327011, 0.327296, -6.53402, -5.89788, 3.91832, -1.54576, -0.420263, 2.40534}, {0.302297, -0.762175, 0.762841, -1.55284, 0.422175, 1.18312, 1.09175, 2.0602, 2.75501, 1.61446, 1.02673, -1.02763, 1.54576, 0.420263, -2.40534, 8.58063, -1.36169, -5.05979, -1.13302, 4.83965, -2.85916, -2.36925, -0.327011, 0.327296, -0.0761652, -1.79095, -0.192201, -8.00362, -4.52719, 6.51586}, {0.302297, -0.762175, 0.762841, -1.55284, 0.422175, 1.18312, -0.363916, -0.686733, -0.918335, -4.84339, -3.0802, 3.08289, 1.54576, 0.420263, -2.40534, 2.36925, 0.327011, -0.327296, 0.0761652, 1.79095, 0.192201, -3.57844, 2.72169, -2.72407, 6.13521, -3.47965, -4.9247, -0.0900956, 2.32667, 6.07869}, {-3.9353, 0.360586, -0.360901, -3.37422e-16, -0.455297, -1.14997, -5.13598e-17, 1.40972, 0.194715, -1.31177, -0.834228, 0.834958, -1.62143, 2.53253, 5.87264, 4.80561e-16, -1.17973, 1.18076, -1.62143, -7.23282, -1.16824, 5.24706, 4.51665, -4.52059, 1.62143, 1.59394, 0.389381, 1.62143, -0.711347, -1.27275}, {1.31177, -0.120195, 0.1203, -1.12347e-15, 1.36589, 3.44992, -6.34091e-17, 1.40972, 0.194715, -1.31177, -0.834228, 0.834958, -6.86849, 1.19213, 0.791545, -1.30879e-16, -6.81861, 0.401902, -1.62143, -1.59394, -0.389381, -5.92435e-16, 1.17973, -1.18076, 6.86849, 4.93085, -2.95045, 1.62143, -0.711347, -1.27275}, {1.31177, -0.120195, 0.1203, 0, -0.455297, -1.14997, 0, -4.22916, -0.584146, -1.31177, -0.834228, 0.834958, -1.62143, 0.711347, 1.27275, 0, 0.641455, 5.78066, -6.86849, -1.11316, -0.870582, -9.76951e-16, 1.17973, -1.18076, 1.62143, 1.59394, 0.389381, 6.86849, 2.62557, -4.61258}, {1.31177, -0.120195, 0.1203, 7.86045e-16, -0.455297, -1.14997, -2.41587e-16, 1.40972, 0.194715, 3.9353, 2.50269, -2.50487, -1.62143, 0.711347, 1.27275, -6.72987e-16, -1.17973, 1.18076, -1.62143, -1.59394, -0.389381, -5.24706, 1.66051, -1.66196, 1.62143, 3.41513, 4.98927, 1.62143, -6.35023, -2.05161}, {3.9353, -3.84584e-12, 1.21564, -7.06651e-16, -1.44665, 1.03094, 7.06651e-16, 1.44665, 0.774615, 1.31177, -1.28195e-12, -1.40034, 1.62143, 7.57474, -4.89721, 0, 0, -2.23179, 1.62143, -7.57474, -3.55506, -5.24706, 5.12778e-12, 7.83316, -1.62143, 1.78815, 0.456604, -1.62143, -1.78815, 0.773441}, {-1.31177, 1.28101e-12, -0.405214, -4.4917e-15, 4.33994, -3.09282, -1.35024e-15, 1.44665, 0.774615, 1.31177, -1.28123e-12, -1.40034, 6.86849, 1.78815, 0.847415, 5.21926e-15, -5.78659, -5.33025, 1.62143, -1.78815, -0.456604, 1.15865e-15, 2.22045e-16, 2.23179, -6.86849, 1.78815, 6.05797, -1.62143, -1.78815, 0.773441}, {-1.31177, 1.28004e-12, -0.405214, 0, -1.44665, 1.03094, 0, -4.33994, -2.32384, 1.31177, -1.28004e-12, -1.40034, 1.62143, 1.78815, -0.773441, 0, 5.78659, -6.35555, 6.86849, -1.78815, 1.16425, 9.76951e-16, -9.53326e-28, 2.23179, -1.62143, 1.78815, 0.456604, -6.86849, -1.78815, 6.37481}, {-1.31177, 1.27933e-12, -0.405214, -1.17775e-15, -1.44665, 1.03094, 1.17775e-15, 1.44665, 0.774615, -3.9353, 3.83799e-12, 4.20103, 1.62143, 1.78815, -0.773441, 0, 0, -2.23179, 1.62143, -1.78815, -0.456604, 5.24706, -5.11732e-12, 3.85265, -1.62143, 7.57474, -3.66716, -1.62143, -7.57474, -2.32502}, {-1.71772, -4.33994, -0.49013, 1.44665, -1.44665, -0.51339, 0, 0, -1.80556, -2.01922, 1.97138e-12, 2.15557, -8.28248, 5.78659, 2.4862, -1.78815, 1.78815, 2.86637, -0.707741, -1.78815, 9.25207, 9.86504, -1.78815, -11.4887, 0.707741, 1.78815, -2.02984, 2.4959, -2.43676e-12, -0.432641}, {0.572575, 1.44665, 0.163377, -4.33994, 4.33994, 1.54017, 0, 0, -1.80556, -2.01922, 1.97138e-12, 2.15557, -4.7862, -5.78659, -0.220866, -1.78815, 1.78815, 10.0886, -0.707741, -1.78815, 2.02984, 1.78815, -1.78815, -2.86637, 8.78463, 1.78815, -10.6521, 2.4959, -2.43676e-12, -0.432641}, {0.572575, 1.44665, 0.163377, 1.44665, -1.44665, -0.51339, 0, 0, 5.41667, -2.01922, 1.97211e-12, 2.15557, -2.4959, 2.43658e-12, 0.432641, -7.57474, 7.57474, 4.91994, -2.99804, -7.57474, 1.37634, 1.78815, -1.78815, -2.86637, 0.707741, 1.78815, -2.02984, 10.5728, -1.03261e-11, -9.05492}, {0.572575, 1.44665, 0.163377, 1.44665, -1.44665, -0.51339, 0, 0, -1.80556, 6.05767, -5.90871e-12, -6.46671, -2.4959, 2.43345e-12, 0.432641, -1.78815, 1.78815, 2.86637, -0.707741, -1.78815, 2.02984, -0.502145, -7.57474, -3.51988, -5.07885, 7.57474, 0.0237159, 2.4959, -2.43452e-12, 6.78958}, {5.80677, 0.989763, -2.29829, 1.66654, 1.66654, -0.659606, 0.232016, 0.232016, -2.11105, 0.0370362, -1.56863, 2.00456, -6.33358, -8.31829, 2.5068, -2.34674, -2.34674, 3.42472, 1.17767, -0.807048, 10.1067, 2.1986, 8.62127, -11.443, -2.10573, -0.121017, -1.66246, -0.332567, 1.65215, 0.131628}, {-1.93559, -0.329921, 0.766095, -4.99961, -4.99961, 1.97882, 0.232016, 0.232016, -2.11105, 0.0370362, -1.56863, 2.00456, 8.07492, -0.332464, -3.19601, -3.2748, -3.2748, 11.8689, 2.10573, 0.121017, 1.66246, 2.34674, 2.34674, -3.42472, -2.25388, 6.15351, -9.68071, -0.332567, 1.65215, 0.131628}, {-1.93559, -0.329921, 0.766095, 1.66654, 1.66654, -0.659606, -0.696049, -0.696049, 6.33316, 0.0370362, -1.56863, 2.00456, 0.332567, -1.65215, -0.131628, -9.01289, -9.01289, 6.06315, 9.84809, 1.4407, -1.40192, 2.34674, 2.34674, -3.42472, -2.10573, -0.121017, -1.66246, -0.480712, 7.92668, -7.88662}, {-1.93559, -0.329921, 0.766095, 1.66654, 1.66654, -0.659606, 0.232016, 0.232016, -2.11105, -0.111109, 4.7059, -6.01369, 0.332567, -1.65215, -0.131628, -2.34674, -2.34674, 3.42472, 2.10573, 0.121017, 1.66246, 10.0891, 3.66642, -6.4891, -8.77188, -6.78716, 0.975965, -1.26063, 0.724083, 8.57584}, {-7.02938, 6.77236e-15, 4.44089e-15, 1.74421, 1.74203, 1.33161, -1.54384, -1.54318, 0.610212, -2.54349, -0.198851, -1.94182, -12.0291, -9.12139, -6.97241, -0.247668, -0.245794, -2.40023, 5.18739, 8.08019, -3.19511, 10.4216, 1.0412, 10.1675, 0.98797, -1.90748, 0.754264, 5.05222, 2.15327, 1.64596}, {2.34313, 9.71445e-16, 6.66134e-16, -5.23263, -5.22609, -3.99484, -1.54384, -1.54318, 0.610212, -2.54349, -0.198851, -1.94182, -14.4247, -2.15327, -1.64596, 5.92769, 5.92693, -4.84108, -0.98797, 1.90748, -0.754264, 0.247668, 0.245794, 2.40023, 11.1619, -1.11207, 8.52156, 5.05222, 2.15327, 1.64596}, {2.34313, 1.88738e-15, 1.33227e-15, 1.74421, 1.74203, 1.33161, 4.63152, 4.62954, -1.83064, -2.54349, -0.198851, -1.94182, -5.05222, -2.15327, -1.64596, -7.2245, -7.21392, -7.72668, -10.3605, 1.90748, -0.754264, 0.247668, 0.245794, 2.40023, 0.98797, -1.90748, 0.754264, 15.2262, 2.94867, 9.41326}, {2.34313, 3.05311e-16, 1.33227e-15, 1.74421, 1.74203, 1.33161, -1.54384, -1.54318, 0.610212, 7.63048, 0.596554, 5.82547, -5.05222, -2.15327, -1.64596, -0.247668, -0.245794, -2.40023, -0.98797, 1.90748, -0.754264, -9.12483, 0.245794, 2.40023, -5.98886, -8.8756, -4.57219, 11.2276, 8.32599, -0.794885}, {4.62937, 4.62937, -1.83228, -1.38864e-15, 1.60567, -1.06016e-15, -0.198723, -0.198723, -1.94057, 1.74185, 0.136178, 1.32981, 1.90741, -6.49998, -0.754941, 0.245635, -1.73908, 2.39867, 2.94793, 2.94793, 9.40601, -7.21302, 1.19437, -7.71791, -2.15304, -2.15304, -1.64373, -1.90741, 0.0773091, 0.754941}, {-1.54312, -1.54312, 0.61076, 2.32061e-15, -4.817, 3.91084e-15, -0.198723, -0.198723, -1.94057, 1.74185, 0.136178, 1.32981, 8.0799, 6.09519, -3.19798, 1.04052, -0.94419, 10.1609, 2.15304, 2.15304, 1.64373, -0.245635, 1.73908, -2.39867, -9.12042, -2.69775, -6.96297, -1.90741, 0.0773091, 0.754941}, {-1.54312, -1.54312, 0.61076, 0, 1.60567, 0, 0.596168, 0.596168, 5.82171, 1.74185, 0.136178, 1.32981, 1.90741, -0.0773091, -0.754941, 0.245635, -8.16175, 2.39867, 8.32553, 8.32553, -0.799305, -0.245635, 1.73908, -2.39867, -2.15304, -2.15304, -1.64373, -8.87479, -0.467403, -4.5643}, {-1.54312, -1.54312, 0.61076, -1.38864e-15, 1.60567, -1.06016e-15, -0.198723, -0.198723, -1.94057, -5.22554, -0.408534, -3.98943, 1.90741, -0.0773091, -0.754941, 0.245635, -1.73908, 2.39867, 2.15304, 2.15304, 1.64373, 5.92686, 7.91157, -4.84171, -2.15304, -8.57571, -1.64373, -1.11252, 0.872199, 8.51722}, {6.21725e-15, 1.65922e-15, -3.8693, 1.44142, -1.45582, 0.146636, 0.577805, 1.45582, -0.186531, -2.01922, -1.68136e-12, -1.24987, -7.54736, 7.62276, -2.36203, -2.4959, -2.07878e-12, 0.0493134, -3.02542, -7.62276, -0.617546, 10.5728, 8.80422e-12, 4.95017, 0.714206, 1.79949, 1.36367, 1.78169, -1.79949, 1.77549}, {8.88178e-16, 6.06249e-16, 1.28977, -4.32425, 4.36745, -0.439908, 0.577805, 1.45582, -0.186531, -2.01922, -1.68215e-12, -1.24987, -1.78169, 1.79949, -6.93455, -4.80711, -5.82327, 0.795439, -0.714206, -1.79949, -1.36367, 2.4959, 2.07856e-12, -0.0493134, 8.79109, 1.79949, 6.36315, 1.78169, -1.79949, 1.77549}, {-4.44089e-16, 9.1037e-16, 1.28977, 1.44142, -1.45582, 0.146636, -1.73341, -4.36745, 0.559594, -2.01922, -1.68268e-12, -1.24987, -1.78169, 1.79949, -1.77549, -8.26156, 5.82327, -0.537231, -0.714206, -1.79949, -6.52273, 2.4959, 2.07878e-12, -0.0493134, 0.714206, 1.79949, 1.36367, 9.85858, -1.79949, 6.77497}, {0, 2.53762e-16, 1.28977, 1.44142, -1.45582, 0.146636, 0.577805, 1.45582, -0.186531, 6.05767, 5.0354e-12, 3.74961, -1.78169, 1.79949, -1.77549, -2.4959, -2.07478e-12, 0.0493134, -0.714206, -1.79949, -1.36367, 2.4959, 2.07377e-12, -5.20838, -5.05146, 7.62276, 0.777128, -0.529529, -7.62276, 2.52162}, {-0.0174717, -4.36745, 1.62174, 0.116385, -1.45582, -0.673541, -1.39583, -1.16268e-12, 0.425765, 1.27362, 1.06088e-12, 0.788355, -0.616596, 5.82327, 4.1949, 1.58148, 1.79949, 0.306268, 7.30147, -1.79949, -1.56114, -6.67598, -1.79949, -3.45969, -1.71815, 1.79949, -0.141919, 0.151058, 1.25826e-13, -1.50074}, {0.0058239, 1.45582, -0.54058, -0.349154, 4.36745, 2.02062, -1.39583, -1.16217e-12, 0.425765, 1.27362, 1.06042e-12, 0.788355, -0.174354, -5.82327, 3.66305, 7.16481, 1.79949, -1.39679, 1.71815, -1.79949, 0.141919, -1.58148, -1.79949, -0.306268, -6.81264, 1.79949, -3.29534, 0.151058, 1.25771e-13, -1.50074}, {0.0058239, 1.45582, -0.54058, 0.116385, -1.45582, -0.673541, 4.1875, 3.48803e-12, -1.27729, 1.27362, 1.06088e-12, 0.788355, -0.151058, -1.2691e-13, 1.50074, 1.11595, 7.62276, 3.00043, 1.69485, -7.62276, 2.30424, -1.58148, -1.79949, -0.306268, -1.71815, 1.79949, -0.141919, -4.94344, -4.1177e-12, -4.65416}, {0.0058239, 1.45582, -0.54058, 0.116385, -1.45582, -0.673541, -1.39583, -1.1623e-12, 0.425765, -3.82087, -3.18161e-12, -2.36507, -0.151058, -1.26869e-13, 1.50074, 1.58148, 1.79949, 0.306268, 1.71815, -1.79949, 0.141919, -1.60478, -7.62276, 1.85605, -2.18368, 7.62276, 2.55224, 5.73439, 4.77498e-12, -3.20379}, {0.776806, 4.33994, 4.33994, -1.05603, 0, 0, 0.111915, 1.44665, -0.572575, 1.20305, 1.58595e-12, 2.01922, 5.84948, 1.78815, 1.78815, 1.16698, -1.78815, 0.707741, -0.265932, -5.78659, 4.7862, -5.97917, 1.78815, -8.78463, -0.181727, -1.96035e-12, -2.4959, -1.62538, -1.78815, -1.78815}, {-0.258935, -1.44665, -1.44665, 3.16808, 0, 0, 0.111915, 1.44665, -0.572575, 1.20305, 1.58777e-12, 2.01922, 2.66112, 7.57474, 7.57474, 0.719326, -7.57474, 2.99804, 0.181727, 1.96367e-12, 2.4959, -1.16698, 1.78815, -0.707741, -4.99391, -8.31366e-12, -10.5728, -1.62538, -1.78815, -1.78815}, {-0.258935, -1.44665, -1.44665, -1.05603, 0, 0, -0.335745, -4.33994, 1.71772, 1.20305, 1.58813e-12, 2.01922, 1.62538, 1.78815, 1.78815, 5.39109, -1.78815, 0.707741, 1.21747, 5.78659, 8.28248, -1.16698, 1.78815, -0.707741, -0.181727, -1.96304e-12, -2.4959, -6.43757, -1.78815, -9.86504}, {-0.258935, -1.44665, -1.44665, -1.05603, 0, 0, 0.111915, 1.44665, -0.572575, -3.60914, -4.76221e-12, -6.05767, 1.62538, 1.78815, 1.78815, 1.16698, -1.78815, 0.707741, 0.181727, 1.96322e-12, 2.4959, -0.131244, 7.57474, 5.07885, 4.04237, -1.96214e-12, -2.4959, -2.07304, -7.57474, 0.502145}, {-1.50826, -4.33994, -0.250246, -0.36325, 9.15361e-13, 1.16277, 0.624341, -1.44665, 0.0358648, -0.763842, -1.00926e-12, -1.28205, 1.28057, -1.78815, -6.19146, -0.322725, 1.78815, -1.4816, -3.89052, 5.78659, -0.290898, 3.37809, -1.78815, 6.6098, 1.39316, 1.16067e-13, 0.147438, 0.172433, 1.78815, 1.54037}, {0.502752, 1.44665, 0.0834153, 1.08975, -2.74295e-12, -3.48831, 0.624341, -1.44665, 0.0358648, -0.763842, -1.00811e-12, -1.28205, -2.18344, -7.57474, -1.87403, -2.82009, 7.57474, -1.62505, -1.39316, -1.17012e-13, -0.147438, 0.322725, -1.78815, 1.4816, 4.44853, 4.14838e-12, 5.27564, 0.172433, 1.78815, 1.54037}, {0.502752, 1.44665, 0.0834153, -0.36325, 9.13691e-13, 1.16277, -1.87302, 4.33994, -0.107594, -0.763842, -1.00742e-12, -1.28205, -0.172433, -1.78815, -1.54037, 1.13028, 1.78815, -6.13268, -3.40417, -5.78659, -0.4811, 0.322725, -1.78815, 1.4816, 1.39316, 1.15855e-13, 0.147438, 3.2278, 1.78815, 6.66858}, {0.502752, 1.44665, 0.0834153, -0.36325, 9.14526e-13, 1.16277, 0.624341, -1.44665, 0.0358648, 2.29153, 3.02502e-12, 3.84615, -0.172433, -1.78815, -1.54037, -0.322725, 1.78815, -1.4816, -1.39316, -1.17039e-13, -0.147438, -1.68828, -7.57474, 1.14793, 2.84616, -3.54214e-12, -4.50365, -2.32493, 7.57474, 1.39691}, {-5.2764, 2.09092, -1.75594, -0.883363, 0.350058, 0.882867, 0.674903, -2.28914, -0.671659, -1.55034, 2.63606, -0.796523, 2.45135, -0.971419, -5.34624, 0.257671, 2.39684, -0.261068, -5.70783, 12.8476, 2.79336, 5.94368, -12.9411, 3.44716, 3.00822, -3.69104, -0.106727, 1.0821, -0.428812, 1.81477}, {1.7588, -0.696974, 0.585315, 2.65009, -1.05017, -2.6486, 0.674903, -2.28914, -0.671659, -1.55034, 2.63606, -0.796523, -8.11729, 3.21671, -4.15603, -2.44194, 11.5534, 2.42557, -3.00822, 3.69104, 0.106727, -0.257671, -2.39684, 0.261068, 9.20957, -14.2353, 3.07936, 1.0821, -0.428812, 1.81477}, {1.7588, -0.696974, 0.585315, -0.883363, 0.350058, 0.882867, -2.02471, 6.86742, 2.01498, -1.55034, 2.63606, -0.796523, -1.0821, 0.428812, -1.81477, 3.79112, 0.996607, -3.79254, -10.0434, 6.47894, -2.23453, -0.257671, -2.39684, 0.261068, 3.00822, -3.69104, -0.106727, 7.28345, -10.973, 5.00086}, {1.7588, -0.696974, 0.585315, -0.883363, 0.350058, 0.882867, 0.674903, -2.28914, -0.671659, 4.65101, -7.90817, 2.38957, -1.0821, 0.428812, -1.81477, 0.257671, 2.39684, -0.261068, -3.00822, 3.69104, 0.106727, -7.29286, 0.391057, -2.08019, 6.54167, -5.09127, -3.6382, -1.61751, 8.72775, 4.50141}, {-0.630826, -5.80799, 0.630826, -0.387946, -0.481968, -1.21772, -0.883035, 0.3495, 0.883035, 1.06071, -1.80353, 0.544962, 1.7714, 0.130593, 6.63599, 1.57102, 0.163739, 0.413696, 4.36372, -4.22303, -4.36372, -5.81384, 7.05038, -2.59355, -0.831577, 2.82503, 0.831577, -0.219612, 1.79728, -1.7651}, {0.210275, 1.936, -0.210275, 1.16384, 1.4459, 3.65317, -0.883035, 0.3495, 0.883035, 1.06071, -1.80353, 0.544962, -0.621489, -9.54126, 2.6062, 5.10316, -1.23426, -3.11845, 0.831577, -2.82503, -0.831577, -1.57102, -0.163739, -0.413696, -5.0744, 10.0391, -1.34827, -0.219612, 1.79728, -1.7651}, {0.210275, 1.936, -0.210275, -0.387946, -0.481968, -1.21772, 2.64911, -1.0485, -2.64911, 1.06071, -1.80353, 0.544962, 0.219612, -1.79728, 1.7651, 3.1228, 2.09161, 5.28459, -0.00952469, -10.569, 0.00952469, -1.57102, -0.163739, -0.413696, -0.831577, 2.82503, 0.831577, -4.46243, 9.01139, -3.94495}, {0.210275, 1.936, -0.210275, -0.387946, -0.481968, -1.21772, -0.883035, 0.3495, 0.883035, -3.18212, 5.41059, -1.63489, 0.219612, -1.79728, 1.7651, 1.57102, 0.163739, 0.413696, 0.831577, -2.82503, -0.831577, -2.41212, -7.90772, 0.427406, 0.720206, 4.7529, 5.70247, 3.31253, 0.399276, -5.29724}, {-4.62915, 1.83443, 4.62655, 1.67942e-15, -1.84151e-15, 2.34313, -1.74201, -1.33137, 1.74389, 0.198956, 1.94285, -2.54483, -1.90731, 0.755828, -10.3625, 2.15324, 1.64567, -5.05183, 7.21395, 7.72698, -7.2249, -2.94906, -9.41706, 15.2312, -0.245923, -2.40149, 0.249326, 1.90731, -0.755828, 0.990019}, {1.54305, -0.611477, -1.54218, 3.38711e-15, 5.71373e-15, -7.02938, -1.74201, -1.33137, 1.74389, 0.198956, 1.94285, -2.54483, -8.07952, 3.20174, 5.17872, 9.12126, 6.97115, -12.0274, 0.245923, 2.40149, -0.249326, -2.15324, -1.64567, 5.05183, -1.04175, -10.1729, 10.4287, 1.90731, -0.755828, 0.990019}, {1.54305, -0.611477, -1.54218, 0, 0, 2.34313, 5.22602, 3.99411, -5.23168, 0.198956, 1.94285, -2.54483, -1.90731, 0.755828, -0.990019, 2.15324, 1.64567, -14.4243, -5.92628, 4.8474, 5.91941, -2.15324, -1.64567, 5.05183, -0.245923, -2.40149, 0.249326, 1.11149, -8.52722, 11.1694}, {1.54305, -0.611477, -1.54218, 1.15731e-16, 1.13013e-15, 2.34313, -1.74201, -1.33137, 1.74389, -0.596868, -5.82855, 7.6345, -1.90731, 0.755828, -0.990019, 2.15324, 1.64567, -5.05183, 0.245923, 2.40149, -0.249326, -8.32544, 0.800244, 11.2206, -0.245923, -2.40149, -9.12318, 8.87534, 4.56966, -5.98555}, {-4.62937, 1.83228, 4.62937, -1.60567, 0, 0, 0.198723, 1.94057, -0.198723, -0.136178, -1.32981, 1.74185, 6.49998, 0.754941, 1.90741, 1.73908, -2.39867, 0.245635, -2.94793, -9.40601, 2.94793, -1.19437, 7.71791, -7.21302, 2.15304, 1.64373, -2.15304, -0.0773091, -0.754941, -1.90741}, {1.54312, -0.61076, -1.54312, 4.817, 0, 0, 0.198723, 1.94057, -0.198723, -0.136178, -1.32981, 1.74185, -6.09519, 3.19798, 8.0799, 0.94419, -10.1609, 1.04052, -2.15304, -1.64373, 2.15304, -1.73908, 2.39867, -0.245635, 2.69775, 6.96297, -9.12042, -0.0773091, -0.754941, -1.90741}, {1.54312, -0.61076, -1.54312, -1.60567, 0, 0, -0.596168, -5.82171, 0.596168, -0.136178, -1.32981, 1.74185, 0.0773091, 0.754941, 1.90741, 8.16175, -2.39867, 0.245635, -8.32553, 0.799305, 8.32553, -1.73908, 2.39867, -0.245635, 2.15304, 1.64373, -2.15304, 0.467403, 4.5643, -8.87479}, {1.54312, -0.61076, -1.54312, -1.60567, 0, 0, 0.198723, 1.94057, -0.198723, 0.408534, 3.98943, -5.22554, 0.0773091, 0.754941, 1.90741, 1.73908, -2.39867, 0.245635, -2.15304, -1.64373, 2.15304, -7.91157, 4.84171, 5.92686, 8.57571, 1.64373, -2.15304, -0.872199, -8.51722, -1.11252}, {3.22749, -4.51945, -2.90569, 1.79579, -0.140217, 1.36925, 0.607375, 0.135762, -1.32575, -1.32734, -1.50203, -1.01206, -8.0731, -1.12793, -8.36668, -2.97048, 0.00550629, -0.0537701, -1.85046, -2.57298, 5.74449, 8.27985, 6.00261, 4.10202, -0.57904, 2.02993, -0.441503, 0.889927, 1.6888, 2.88969}, {-1.07583, 1.50648, 0.968563, -5.38738, 0.42065, -4.10774, 0.607375, 0.135762, -1.32575, -1.32734, -1.50203, -1.01206, 3.41339, -7.71473, -6.76394, -5.39998, -0.537542, 5.24921, 0.57904, -2.02993, 0.441503, 2.97048, -0.00550629, 0.0537701, 4.73032, 8.03804, 3.60675, 0.889927, 1.6888, 2.88969}, {-1.07583, 1.50648, 0.968563, 1.79579, -0.140217, 1.36925, -1.82213, -0.407286, 3.97724, -1.32734, -1.50203, -1.01206, -0.889927, -1.6888, -2.88969, -10.1537, 0.566373, -5.53076, 4.88236, -8.05586, -3.43275, 2.97048, -0.00550629, 0.0537701, -0.57904, 2.02993, -0.441503, 6.19929, 7.69691, 6.93795}, {-1.07583, 1.50648, 0.968563, 1.79579, -0.140217, 1.36925, 0.607375, 0.135762, -1.32575, 3.98202, 4.50609, 3.03619, -0.889927, -1.6888, -2.88969, -2.97048, 0.00550629, -0.0537701, 0.57904, -2.02993, 0.441503, 7.2738, -6.03144, -3.82048, -7.76222, 2.59079, -5.91849, -1.53958, 1.14575, 8.19268}, {0.596103, 2.3292, 5.82108, 0, -2.17235, 0, -1.54296, 0.977878, 0.61239, 1.74166, 1.97087, 1.32797, 0.245608, 12.3343, 2.39842, 1.9072, 1.47645, -0.756955, 8.32463, -4.16055, -0.808098, -8.87383, -9.35994, -4.55492, -2.15281, 0.249041, -1.64146, -0.245608, -3.64486, -2.39842}, {-0.198701, -0.7764, -1.94036, 0, 6.51705, 0, -1.54296, 0.977878, 0.61239, 1.74166, 1.97087, 1.32797, 1.04041, 6.75045, 10.1599, 8.07903, -2.43506, -3.20651, 2.15281, -0.249041, 1.64146, -1.9072, -1.47645, 0.756955, -9.11944, -7.63445, -6.95334, -0.245608, -3.64486, -2.39842}, {-0.198701, -0.7764, -1.94036, 0, -2.17235, 0, 4.62887, -2.93363, -1.83717, 1.74166, 1.97087, 1.32797, 0.245608, 3.64486, 2.39842, 1.9072, 10.1659, -0.756955, 2.94761, 2.85656, 9.4029, -1.9072, -1.47645, 0.756955, -2.15281, 0.249041, -1.64146, -7.21224, -11.5283, -7.71029}, {-0.198701, -0.7764, -1.94036, 0, -2.17235, 0, -1.54296, 0.977878, 0.61239, -5.22497, -5.91262, -3.98391, 0.245608, 3.64486, 2.39842, 1.9072, 1.47645, -0.756955, 2.15281, -0.249041, 1.64146, -1.1124, 1.62915, 8.51839, -2.15281, 8.93844, -1.64146, 5.92622, -7.55637, -4.84797}, {-2.37946, -3.79135, -6.81576, 0.894391, -1.25242, -0.805215, 0.086206, 0.865556, -0.85654, -1.77375, -0.876923, -0.610165, -5.66348, 4.99561, 1.40791, -1.21208, 0.478185, 2.05404, -1.43177, -6.09423, 1.67666, 8.30708, 3.02951, 0.386615, 1.08695, 2.63201, 1.74951, 2.08592, 0.0140506, 1.81295}, {0.793153, 1.26378, 2.27192, -2.68317, 3.75725, 2.41565, 0.086206, 0.865556, -0.85654, -1.77375, -0.876923, -0.610165, -5.25853, -5.06918, -10.9006, -1.55691, -2.98404, 5.4802, -1.08695, -2.63201, -1.74951, 1.21208, -0.478185, -2.05404, 8.18195, 6.1397, 4.19016, 2.08592, 0.0140506, 1.81295}, {0.793153, 1.26378, 2.27192, 0.894391, -1.25242, -0.805215, -0.258618, -2.59667, 2.56962, -1.77375, -0.876923, -0.610165, -2.08592, -0.0140506, -1.81295, -4.78965, 5.48785, 5.2749, -4.25956, -7.68714, -10.8372, 1.21208, -0.478185, -2.05404, 1.08695, 2.63201, 1.74951, 9.18092, 3.52174, 4.25361}, {0.793153, 1.26378, 2.27192, 0.894391, -1.25242, -0.805215, 0.086206, 0.865556, -0.85654, 5.32125, 2.63077, 1.83049, -2.08592, -0.0140506, -1.81295, -1.21208, 0.478185, 2.05404, -1.08695, -2.63201, -1.74951, -1.96053, -5.53332, -11.1417, -2.49062, 7.64167, 4.97037, 1.74109, -3.44817, 5.23911}, {4.58783, -0.200634, 4.23679, 1.50209, -0.951977, -0.596169, -2.69821, -0.462309, 1.0709, 2.7254, 1.34741, 0.937529, -5.97475, 4.90195, 4.86723, 1.47849, 1.74815, -0.586802, 16.0183, 2.33802, -3.86166, -12.3801, -7.13778, -3.16331, -5.22546, -0.48878, -0.421944, -0.0336074, -1.09404, -2.48256}, {-1.52928, 0.0668781, -1.41226, -4.50626, 2.85593, 1.78851, -2.69821, -0.462309, 1.0709, 2.7254, 1.34741, 0.937529, 6.15072, 0.82653, 8.1316, 12.2713, 3.59739, -4.87041, 5.22546, 0.48878, 0.421944, -1.47849, -1.74815, 0.586802, -16.1271, -5.87841, -4.17206, -0.0336074, -1.09404, -2.48256}, {-1.52928, 0.0668781, -1.41226, 1.50209, -0.951977, -0.596169, 8.09463, 1.38693, -3.21271, 2.7254, 1.34741, 0.937529, 0.0336074, 1.09404, 2.48256, -4.52987, 5.55606, 1.79787, 11.3426, 0.221267, 6.07099, -1.47849, -1.74815, 0.586802, -5.22546, -0.48878, -0.421944, -10.9352, -6.48367, -6.23267}, {-1.52928, 0.0668781, -1.41226, 1.50209, -0.951977, -0.596169, -2.69821, -0.462309, 1.0709, -8.1762, -4.04222, -2.81259, 0.0336074, 1.09404, 2.48256, 1.47849, 1.74815, -0.586802, 5.22546, 0.48878, 0.421944, 4.63862, -2.01567, 6.23585, -11.2338, 3.31913, 1.96273, 10.7592, 0.755194, -6.76616}, {1.83443, -2.90588, -4.62915, 0, -2.17235, 0, 1.94285, -0.797826, 0.198956, -1.33137, 2.00155, -1.74201, 0.755828, 10.1773, -1.90731, -2.40149, 3.67134, -0.245923, -9.41706, 2.98018, -2.94906, 7.72698, -11.6775, 7.21395, 1.64567, 0.211121, 2.15324, -0.755828, -1.48788, 1.90731}, {-0.611477, 0.968627, 1.54305, 0, 6.51705, 0, 1.94285, -0.797826, 0.198956, -1.33137, 2.00155, -1.74201, 3.20174, -2.38662, -8.07952, -10.1729, 6.86264, -1.04175, -1.64567, -0.211121, -2.15324, 2.40149, -3.67134, 0.245923, 6.97115, -7.79508, 9.12126, -0.755828, -1.48788, 1.90731}, {-0.611477, 0.968627, 1.54305, 0, -2.17235, 0, -5.82855, 2.39348, -0.596868, -1.33137, 2.00155, -1.74201, 0.755828, 1.48788, -1.90731, -2.40149, 12.3607, -0.245923, 0.800244, -4.08563, -8.32544, 2.40149, -3.67134, 0.245923, 1.64567, 0.211121, 2.15324, 4.56966, -9.49408, 8.87534}, {-0.611477, 0.968627, 1.54305, 0, -2.17235, 0, 1.94285, -0.797826, 0.198956, 3.99411, -6.00465, 5.22602, 0.755828, 1.48788, -1.90731, -2.40149, 3.67134, -0.245923, -1.64567, -0.211121, -2.15324, 4.8474, -7.54585, -5.92628, 1.64567, 8.90052, 2.15324, -8.52722, 1.70342, 1.11149}, {-3.96631, -0.406167, 1.83974, -1.35283, -0.138536, -1.77009, -0.9692, 1.50642, 1.075, 0.999931, -1.50327, 1.30834, 5.44932, 0.558033, 10.0263, 2.87019, -1.6908, 0.859181, 3.44059, -8.05506, -4.87073, -6.86992, 7.70388, -6.09254, 0.436211, 2.02938, 0.570751, -0.0379859, -0.00388992, -2.94596}, {1.3221, 0.135389, -0.613248, 4.0585, 0.415608, 5.31026, -0.9692, 1.50642, 1.075, 0.999931, -1.50327, 1.30834, -5.25042, -0.537666, 5.39896, 6.74699, -7.71647, -3.4408, -0.436211, -2.02938, -0.570751, -2.87019, 1.6908, -0.859181, -3.56351, 8.04247, -4.66261, -0.0379859, -0.00388992, -2.94596}, {1.3221, 0.135389, -0.613248, -1.35283, -0.138536, -1.77009, 2.9076, -4.51925, -3.22499, 0.999931, -1.50327, 1.30834, 0.0379859, 0.00388992, 2.94596, 8.28152, -1.13665, 7.93953, -5.72462, -2.57094, 1.88224, -2.87019, 1.6908, -0.859181, 0.436211, 2.02938, 0.570751, -4.03771, 6.00919, -8.17932}, {1.3221, 0.135389, -0.613248, -1.35283, -0.138536, -1.77009, -0.9692, 1.50642, 1.075, -2.99979, 4.50981, -3.92502, 0.0379859, 0.00388992, 2.94596, 2.87019, -1.6908, 0.859181, -0.436211, -2.02938, -0.570751, -8.1586, 1.14924, 1.59381, 5.84754, 2.58353, 7.6511, 3.83881, -6.02956, -7.24594}, {3.10069, 1.60532, -7.82452, 0.575383, -0.91145, -1.45197, 1.48006, -0.0647255, 1.36681, -1.02187, 1.51128, -2.52301, -1.73519, 5.43384, 4.37871, -2.54066, 1.20662, 0.105263, -6.47211, 1.00034, -10.3806, 6.62816, -7.25175, 9.9868, 0.551894, -0.741434, 4.91335, -0.566342, -1.78804, 1.42915}, {-1.03356, -0.535107, 2.60817, -1.72615, 2.73435, 4.3559, 1.48006, -0.0647255, 1.36681, -1.02187, 1.51128, -2.52301, 4.7006, 3.92847, -11.8619, -8.46088, 1.46552, -5.36196, -0.551894, 0.741434, -4.91335, 2.54066, -1.20662, -0.105263, 4.63939, -6.78657, 15.0054, -0.566342, -1.78804, 1.42915}, {-1.03356, -0.535107, 2.60817, 0.575383, -0.91145, -1.45197, -4.44017, 0.194177, -4.10042, -1.02187, 1.51128, -2.52301, 0.566342, 1.78804, -1.42915, -4.84219, 4.85242, 5.91313, 3.58236, 2.88186, -15.346, 2.54066, -1.20662, -0.105263, 0.551894, -0.741434, 4.91335, 3.52116, -7.83317, 11.5212}, {-1.03356, -0.535107, 2.60817, 0.575383, -0.91145, -1.45197, 1.48006, -0.0647255, 1.36681, 3.06562, -4.53385, 7.56904, 0.566342, 1.78804, -1.42915, -2.54066, 1.20662, 0.105263, -0.551894, 0.741434, -4.91335, 6.67491, 0.933809, -10.538, -1.74964, 2.90437, 10.7212, -6.48656, -1.52914, -4.03807}, {-2.63316, -2.47826, 0.36108, 0.802811, -1.2478, -0.890444, -2.35614, 1.42089, -0.657266, 0.675604, -0.999172, 1.66807, -5.2885, 5.51247, 4.8112, 1.92002, -0.213947, 1.91307, 11.252, -8.46096, 3.59026, -4.62243, 4.21063, -8.58536, -1.82742, 2.77741, -0.961199, 2.07725, -0.52127, -1.24942}, {0.877721, 0.826085, -0.12036, -2.40843, 3.7434, 2.67133, -2.35614, 1.42089, -0.657266, 0.675604, -0.999172, 1.66807, -5.58814, -2.78307, 1.73086, 11.3446, -5.8975, 4.54214, 1.82742, -2.77741, 0.961199, -1.92002, 0.213947, -1.91307, -4.52984, 6.7741, -7.63348, 2.07725, -0.52127, -1.24942}, {0.877721, 0.826085, -0.12036, 0.802811, -1.2478, -0.890444, 7.06841, -4.26266, 1.9718, 0.675604, -0.999172, 1.66807, -2.07725, 0.52127, 1.24942, -1.29123, 4.77726, 5.47485, -1.68346, -6.08175, 1.44264, -1.92002, 0.213947, -1.91307, -1.82742, 2.77741, -0.961199, -0.625163, 3.47542, -7.9217}, {0.877721, 0.826085, -0.12036, 0.802811, -1.2478, -0.890444, -2.35614, 1.42089, -0.657266, -2.02681, 2.99752, -5.00421, -2.07725, 0.52127, 1.24942, 1.92002, -0.213947, 1.91307, 1.82742, -2.77741, 0.961199, -5.4309, -3.09039, -1.43164, -5.03867, 7.76862, 2.60058, 11.5018, -6.20482, 1.37964}, {-0.815557, 4.36562, -0.135176, -1.95424, 0.460185, -0.243585, -0.0205487, 0.870319, -1.11219, 1.70294, 0.124702, 1.31071, 9.89652, -0.610825, 1.21973, 2.44098, -1.64459, 1.67583, -0.228434, -2.75832, 5.76778, -9.25274, 1.14578, -6.91867, 0.310628, -0.722961, -1.31904, -2.07955, -1.22991, -0.245392}, {0.271852, -1.45521, 0.0450587, 5.86273, -1.38055, 0.730756, -0.0205487, 0.870319, -1.11219, 1.70294, 0.124702, 1.31071, 0.99214, 7.05074, 0.0651576, 2.52317, -5.12587, 6.12457, -0.310628, 0.722961, 1.31904, -2.44098, 1.64459, -1.67583, -6.50113, -1.22177, -6.56189, -2.07955, -1.22991, -0.245392}, {0.271852, -1.45521, 0.0450587, -1.95424, 0.460185, -0.243585, 0.0616461, -2.61096, 3.33656, 1.70294, 0.124702, 1.31071, 2.07955, 1.22991, 0.245392, 10.258, -3.48533, 2.65017, -1.39804, 6.54379, 1.13881, -2.44098, 1.64459, -1.67583, 0.310628, -0.722961, -1.31904, -8.89131, -1.72872, -5.48824}, {0.271852, -1.45521, 0.0450587, -1.95424, 0.460185, -0.243585, -0.0205487, 0.870319, -1.11219, -5.10882, -0.374107, -3.93214, 2.07955, 1.22991, 0.245392, 2.44098, -1.64459, 1.67583, -0.310628, 0.722961, 1.31904, -3.52839, 7.46542, -1.85606, 8.1276, -2.5637, -0.344701, -1.99736, -4.71119, 4.20335}, {-2.82343, -2.82223, 1.11598, 0.652804, 0.651093, 1.763, 0.935946, -1.40658, 0.556196, -2.52989, -0.185258, -1.9472, -4.58144, -4.57199, -8.77136, -1.9638, 0.933829, -2.86668, -6.064, 6.20211, -2.45247, 12.0834, -0.192795, 10.6555, 2.32021, -0.575803, 0.227687, 1.97023, 1.96762, 1.71938}, {0.941145, 0.940742, -0.371993, -1.95841, -1.95328, -5.28899, 0.935946, -1.40658, 0.556196, -2.52989, -0.185258, -1.9472, -5.73481, -5.73058, -0.231403, -5.70759, 6.56014, -5.09146, -2.32021, 0.575803, -0.227687, 1.9638, -0.933829, 2.86668, 12.4398, 0.165231, 8.01649, 1.97023, 1.96762, 1.71938}, {0.941145, 0.940742, -0.371993, 0.652804, 0.651093, 1.763, -2.80784, 4.21973, -1.66859, -2.52989, -0.185258, -1.9472, -1.97023, -1.96762, -1.71938, -4.57502, -1.67054, -9.91867, -6.08479, -3.18716, 1.26029, 1.9638, -0.933829, 2.86668, 2.32021, -0.575803, 0.227687, 12.0898, 2.70865, 9.50817}, {0.941145, 0.940742, -0.371993, 0.652804, 0.651093, 1.763, 0.935946, -1.40658, 0.556196, 7.58968, 0.555775, 5.8416, -1.97023, -1.96762, -1.71938, -1.9638, 0.933829, -2.86668, -2.32021, 0.575803, -0.227687, -1.80078, -4.6968, 4.35465, -0.291002, -3.18018, -6.8243, -1.77356, 7.59392, -0.505409}, {4.38876, 6.50951, 0.486449, -0.364196, 1.94951, -0.0603643, 0.336809, -1.04259, -1.05295, 1.49031, 1.26291, 1.27547, 3.71522, -7.52572, 0.5165, 0.0338521, -1.12102, 1.37614, 0.0447138, 8.14114, 5.71377, -5.99508, -3.93064, -6.47801, -1.39195, -3.97078, -1.50195, -2.25844, -0.272335, -0.275043}, {-1.46292, -2.16984, -0.16215, 1.09259, -5.84854, 0.181093, 0.336809, -1.04259, -1.05295, 1.49031, 1.26291, 1.27547, 8.11012, 8.95169, 0.923642, -1.31338, 3.04934, 5.58796, 1.39195, 3.97078, 1.50195, -0.0338521, 1.12102, -1.37614, -7.35318, -9.02244, -6.60383, -2.25844, -0.272335, -0.275043}, {-1.46292, -2.16984, -0.16215, -0.364196, 1.94951, -0.0603643, -1.01043, 3.12777, 3.15886, 1.49031, 1.26291, 1.27547, 2.25844, 0.272335, 0.275043, 1.49064, -8.91908, 1.6176, 7.24363, 12.6501, 2.15055, -0.0338521, 1.12102, -1.37614, -1.39195, -3.97078, -1.50195, -8.21966, -5.32399, -5.37692}, {-1.46292, -2.16984, -0.16215, -0.364196, 1.94951, -0.0603643, 0.336809, -1.04259, -1.05295, -4.47092, -3.78874, -3.82641, 2.25844, 0.272335, 0.275043, 0.0338521, -1.12102, 1.37614, 1.39195, 3.97078, 1.50195, 5.81783, 9.80037, -0.727539, 0.0648337, -11.7688, -1.26049, -3.60567, 3.89803, 3.93678}, {-4.70136, -4.44089e-15, -7.10543e-15, -0.960805, 1.44394, -0.570969, 1.09021, -0.00626368, 2.02293, -1.69653, -1.43767, -1.45196, 3.09377, -7.56055, 2.98963, -0.159958, -1.77706, -1.79473, -7.6455, 0.0327971, -10.5922, 6.94608, 7.52775, 7.60258, 3.28465, -0.00774234, 2.50048, 0.749448, 1.7848, -0.705756}, {1.56712, -8.88178e-16, -4.44089e-16, 2.88242, -4.33181, 1.71291, 1.09021, -0.00626368, 2.02293, -1.69653, -1.43767, -1.45196, -7.01793, -1.7848, 0.705756, -4.52081, -1.75201, -9.88646, -3.28465, 0.00774234, -2.50048, 0.159958, 1.77706, 1.79473, 10.0708, 5.74295, 8.30834, 0.749448, 1.7848, -0.705756}, {1.56712, -1.55431e-15, -1.55431e-15, -0.960805, 1.44394, -0.570969, -3.27064, 0.018791, -6.0688, -1.69653, -1.43767, -1.45196, -0.749448, -1.7848, 0.705756, 3.68326, -7.5528, 0.489149, -9.55313, 0.00774234, -2.50048, 0.159958, 1.77706, 1.79473, 3.28465, -0.00774234, 2.50048, 7.53557, 7.53549, 5.1021}, {1.56712, 1.55431e-15, 6.66134e-16, -0.960805, 1.44394, -0.570969, 1.09021, -0.00626368, 2.02293, 5.08959, 4.31302, 4.35589, -0.749448, -1.7848, 0.705756, -0.159958, -1.77706, -1.79473, -3.28465, 0.00774234, -2.50048, -6.10853, 1.77706, 1.79473, 7.12787, -5.78349, 4.78436, -3.61141, 1.80986, -8.79749}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_tetrahedron_10) [
+ Array<double> [
+ + id : my_fem:jacobians:_tetrahedron_10
+ + size : 1364
+ + nb_component : 1
+ + allocated size : 1364
+ + memory size : 10.66KiByte
+ + values : {{0.00119768}, {0.00119768}, {0.00119768}, {0.00119768}, {0.000498855}, {0.000498855}, {0.000498855}, {0.000498855}, {0.00127072}, {0.00127072}, {0.00127072}, {0.00127072}, {0.000510867}, {0.000510867}, {0.000510867}, {0.000510867}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.00023817}, {0.00023817}, {0.00023817}, {0.00023817}, {0.000731371}, {0.000731371}, {0.000731371}, {0.000731371}, {0.00123415}, {0.00123415}, {0.00123415}, {0.00123415}, {0.000262647}, {0.000262647}, {0.000262647}, {0.000262647}, {0.000229322}, {0.000229322}, {0.000229322}, {0.000229322}, {0.000450497}, {0.000450497}, {0.000450497}, {0.000450497}, {0.000202139}, {0.000202139}, {0.000202139}, {0.000202139}, {0.000887737}, {0.000887737}, {0.000887737}, {0.000887737}, {0.00187262}, {0.00187262}, {0.00187262}, {0.00187262}, {0.000493369}, {0.000493369}, {0.000493369}, {0.000493369}, {0.000265441}, {0.000265441}, {0.000265441}, {0.000265441}, {0.00172558}, {0.00172558}, {0.00172558}, {0.00172558}, {0.000744972}, {0.000744972}, {0.000744972}, {0.000744972}, {0.000202002}, {0.000202002}, {0.000202002}, {0.000202002}, {0.000671175}, {0.000671175}, {0.000671175}, {0.000671175}, {0.000292964}, {0.000292964}, {0.000292964}, {0.000292964}, {0.00118606}, {0.00118606}, {0.00118606}, {0.00118606}, {0.000209795}, {0.000209795}, {0.000209795}, {0.000209795}, {0.00161203}, {0.00161203}, {0.00161203}, {0.00161203}, {0.00117664}, {0.00117664}, {0.00117664}, {0.00117664}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000378978}, {0.000378978}, {0.000378978}, {0.000378978}, {0.000209795}, {0.000209795}, {0.000209795}, {0.000209795}, {0.00121805}, {0.00121805}, {0.00121805}, {0.00121805}, {0.00037973}, {0.00037973}, {0.00037973}, {0.00037973}, {0.00117268}, {0.00117268}, {0.00117268}, {0.00117268}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.00037973}, {0.00037973}, {0.00037973}, {0.00037973}, {0.00083749}, {0.00083749}, {0.00083749}, {0.00083749}, {0.00191797}, {0.00191797}, {0.00191797}, {0.00191797}, {0.000953843}, {0.000953843}, {0.000953843}, {0.000953843}, {0.000672936}, {0.000672936}, {0.000672936}, {0.000672936}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.00111398}, {0.00111398}, {0.00111398}, {0.00111398}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051068}, {0.00051068}, {0.00051068}, {0.00051068}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.00122601}, {0.00122601}, {0.00122601}, {0.00122601}, {0.000884197}, {0.000884197}, {0.000884197}, {0.000884197}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.00173384}, {0.00173384}, {0.00173384}, {0.00173384}, {0.000209825}, {0.000209825}, {0.000209825}, {0.000209825}, {0.0007455}, {0.0007455}, {0.0007455}, {0.0007455}, {0.000899671}, {0.000899671}, {0.000899671}, {0.000899671}, {0.000616516}, {0.000616516}, {0.000616516}, {0.000616516}, {0.000200144}, {0.000200144}, {0.000200144}, {0.000200144}, {0.000209825}, {0.000209825}, {0.000209825}, {0.000209825}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000380053}, {0.000380053}, {0.000380053}, {0.000380053}, {0.000939334}, {0.000939334}, {0.000939334}, {0.000939334}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000930551}, {0.000930551}, {0.000930551}, {0.000930551}, {0.000638055}, {0.000638055}, {0.000638055}, {0.000638055}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000238204}, {0.000238204}, {0.000238204}, {0.000238204}, {0.000745217}, {0.000745217}, {0.000745217}, {0.000745217}, {0.000510776}, {0.000510776}, {0.000510776}, {0.000510776}, {0.000945026}, {0.000945026}, {0.000945026}, {0.000945026}, {0.000909981}, {0.000909981}, {0.000909981}, {0.000909981}, {0.000623877}, {0.000623877}, {0.000623877}, {0.000623877}, {0.000956672}, {0.000956672}, {0.000956672}, {0.000956672}, {0.000513725}, {0.000513725}, {0.000513725}, {0.000513725}, {0.00105581}, {0.00105581}, {0.00105581}, {0.00105581}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.00115231}, {0.00115231}, {0.00115231}, {0.00115231}, {0.000871617}, {0.000871617}, {0.000871617}, {0.000871617}, {0.000238136}, {0.000238136}, {0.000238136}, {0.000238136}, {0.000966407}, {0.000966407}, {0.000966407}, {0.000966407}, {0.000335259}, {0.000335259}, {0.000335259}, {0.000335259}, {0.000630433}, {0.000630433}, {0.000630433}, {0.000630433}, {0.00037973}, {0.00037973}, {0.00037973}, {0.00037973}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.00106509}, {0.00106509}, {0.00106509}, {0.00106509}, {0.00198327}, {0.00198327}, {0.00198327}, {0.00198327}, {0.00205091}, {0.00205091}, {0.00205091}, {0.00205091}, {0.000963229}, {0.000963229}, {0.000963229}, {0.000963229}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.00215047}, {0.00215047}, {0.00215047}, {0.00215047}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000959836}, {0.000959836}, {0.000959836}, {0.000959836}, {0.000817692}, {0.000817692}, {0.000817692}, {0.000817692}, {0.000902791}, {0.000902791}, {0.000902791}, {0.000902791}, {0.00169951}, {0.00169951}, {0.00169951}, {0.00169951}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000840144}, {0.000840144}, {0.000840144}, {0.000840144}, {0.00173867}, {0.00173867}, {0.00173867}, {0.00173867}, {0.000671175}, {0.000671175}, {0.000671175}, {0.000671175}, {0.000963229}, {0.000963229}, {0.000963229}, {0.000963229}, {0.00022929}, {0.00022929}, {0.00022929}, {0.00022929}, {0.000396628}, {0.000396628}, {0.000396628}, {0.000396628}, {0.000380053}, {0.000380053}, {0.000380053}, {0.000380053}, {0.000511246}, {0.000511246}, {0.000511246}, {0.000511246}, {0.000396677}, {0.000396677}, {0.000396677}, {0.000396677}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.00120813}, {0.00120813}, {0.00120813}, {0.00120813}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.00161366}, {0.00161366}, {0.00161366}, {0.00161366}, {0.000945026}, {0.000945026}, {0.000945026}, {0.000945026}, {0.0011808}, {0.0011808}, {0.0011808}, {0.0011808}, {0.000883811}, {0.000883811}, {0.000883811}, {0.000883811}, {0.000379219}, {0.000379219}, {0.000379219}, {0.000379219}, {0.00120813}, {0.00120813}, {0.00120813}, {0.00120813}, {0.00105497}, {0.00105497}, {0.00105497}, {0.00105497}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00130751}, {0.00130751}, {0.00130751}, {0.00130751}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000951335}, {0.000951335}, {0.000951335}, {0.000951335}, {0.00145377}, {0.00145377}, {0.00145377}, {0.00145377}, {0.000396677}, {0.000396677}, {0.000396677}, {0.000396677}, {0.00137036}, {0.00137036}, {0.00137036}, {0.00137036}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.000913554}, {0.000913554}, {0.000913554}, {0.000913554}, {0.000744668}, {0.000744668}, {0.000744668}, {0.000744668}, {0.000959836}, {0.000959836}, {0.000959836}, {0.000959836}, {0.000510776}, {0.000510776}, {0.000510776}, {0.000510776}, {0.00037973}, {0.00037973}, {0.00037973}, {0.00037973}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.00173998}, {0.00173998}, {0.00173998}, {0.00173998}, {0.00106728}, {0.00106728}, {0.00106728}, {0.00106728}, {0.000238136}, {0.000238136}, {0.000238136}, {0.000238136}, {0.000950017}, {0.000950017}, {0.000950017}, {0.000950017}, {0.00160036}, {0.00160036}, {0.00160036}, {0.00160036}, {0.00148765}, {0.00148765}, {0.00148765}, {0.00148765}, {0.00045003}, {0.00045003}, {0.00045003}, {0.00045003}, {0.00117664}, {0.00117664}, {0.00117664}, {0.00117664}, {0.000744343}, {0.000744343}, {0.000744343}, {0.000744343}, {0.00108011}, {0.00108011}, {0.00108011}, {0.00108011}, {0.00102006}, {0.00102006}, {0.00102006}, {0.00102006}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000985542}, {0.000985542}, {0.000985542}, {0.000985542}, {0.00023817}, {0.00023817}, {0.00023817}, {0.00023817}, {0.000509799}, {0.000509799}, {0.000509799}, {0.000509799}, {0.00122872}, {0.00122872}, {0.00122872}, {0.00122872}, {0.000201973}, {0.000201973}, {0.000201973}, {0.000201973}, {0.00168481}, {0.00168481}, {0.00168481}, {0.00168481}, {0.000396652}, {0.000396652}, {0.000396652}, {0.000396652}, {0.000396677}, {0.000396677}, {0.000396677}, {0.000396677}, {0.00127773}, {0.00127773}, {0.00127773}, {0.00127773}, {0.000202002}, {0.000202002}, {0.000202002}, {0.000202002}, {0.000744972}, {0.000744972}, {0.000744972}, {0.000744972}, {0.000396677}, {0.000396677}, {0.000396677}, {0.000396677}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000744972}, {0.000744972}, {0.000744972}, {0.000744972}, {0.000209825}, {0.000209825}, {0.000209825}, {0.000209825}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.00185969}, {0.00185969}, {0.00185969}, {0.00185969}, {0.00130224}, {0.00130224}, {0.00130224}, {0.00130224}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.00051068}, {0.00051068}, {0.00051068}, {0.00051068}, {0.000817692}, {0.000817692}, {0.000817692}, {0.000817692}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.00137577}, {0.00137577}, {0.00137577}, {0.00137577}, {0.000708521}, {0.000708521}, {0.000708521}, {0.000708521}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.00125207}, {0.00125207}, {0.00125207}, {0.00125207}, {0.00108769}, {0.00108769}, {0.00108769}, {0.00108769}, {0.000396628}, {0.000396628}, {0.000396628}, {0.000396628}, {0.000883811}, {0.000883811}, {0.000883811}, {0.000883811}, {0.000518452}, {0.000518452}, {0.000518452}, {0.000518452}, {0.000662427}, {0.000662427}, {0.000662427}, {0.000662427}, {0.000902637}, {0.000902637}, {0.000902637}, {0.000902637}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.00109572}, {0.00109572}, {0.00109572}, {0.00109572}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.00120813}, {0.00120813}, {0.00120813}, {0.00120813}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.00100863}, {0.00100863}, {0.00100863}, {0.00100863}, {0.000265441}, {0.000265441}, {0.000265441}, {0.000265441}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000849291}, {0.000849291}, {0.000849291}, {0.000849291}, {0.00109572}, {0.00109572}, {0.00109572}, {0.00109572}, {0.000396652}, {0.000396652}, {0.000396652}, {0.000396652}, {0.000380053}, {0.000380053}, {0.000380053}, {0.000380053}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000379461}, {0.000196277}, {0.000196277}, {0.000196277}, {0.000196277}, {0.000201973}, {0.000201973}, {0.000201973}, {0.000201973}, {0.000262647}, {0.000262647}, {0.000262647}, {0.000262647}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000510096}, {0.000510096}, {0.000510096}, {0.000510096}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000378736}, {0.000378736}, {0.000378736}, {0.000378736}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000532051}, {0.000532051}, {0.000532051}, {0.000532051}, {0.0014145}, {0.0014145}, {0.0014145}, {0.0014145}, {0.00108638}, {0.00108638}, {0.00108638}, {0.00108638}, {0.000378736}, {0.000378736}, {0.000378736}, {0.000378736}, {0.0011856}, {0.0011856}, {0.0011856}, {0.0011856}, {0.00186025}, {0.00186025}, {0.00186025}, {0.00186025}, {0.000396628}, {0.000396628}, {0.000396628}, {0.000396628}, {0.000209825}, {0.000209825}, {0.000209825}, {0.000209825}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000922847}, {0.000922847}, {0.000922847}, {0.000922847}, {0.00132655}, {0.00132655}, {0.00132655}, {0.00132655}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.00107727}, {0.00107727}, {0.00107727}, {0.00107727}, {0.00135137}, {0.00135137}, {0.00135137}, {0.00135137}, {0.000292964}, {0.000292964}, {0.000292964}, {0.000292964}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000229257}, {0.000229257}, {0.000229257}, {0.000229257}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000722936}, {0.000722936}, {0.000722936}, {0.000722936}, {0.00120813}, {0.00120813}, {0.00120813}, {0.00120813}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000926941}, {0.000926941}, {0.000926941}, {0.000926941}, {0.000202002}, {0.000202002}, {0.000202002}, {0.000202002}, {0.000509799}, {0.000509799}, {0.000509799}, {0.000509799}, {0.000378978}, {0.000378978}, {0.000378978}, {0.000378978}, {0.00051045}, {0.00051045}, {0.00051045}, {0.00051045}, {0.000238136}, {0.000238136}, {0.000238136}, {0.000238136}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000380053}, {0.000380053}, {0.000380053}, {0.000380053}, {0.0007455}, {0.0007455}, {0.0007455}, {0.0007455}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.00023817}, {0.00023817}, {0.00023817}, {0.00023817}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000883811}, {0.000883811}, {0.000883811}, {0.000883811}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000608086}, {0.000608086}, {0.000608086}, {0.000608086}, {0.000652377}, {0.000652377}, {0.000652377}, {0.000652377}, {0.000511476}, {0.000511476}, {0.000511476}, {0.000511476}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000493684}, {0.000493684}, {0.000493684}, {0.000493684}, {0.000251531}, {0.000251531}, {0.000251531}, {0.000251531}, {0.000835485}, {0.000835485}, {0.000835485}, {0.000835485}, {0.00121998}, {0.00121998}, {0.00121998}, {0.00121998}, {0.00120388}, {0.00120388}, {0.00120388}, {0.00120388}, {0.000510867}, {0.000510867}, {0.000510867}, {0.000510867}, {0.000745543}, {0.000745543}, {0.000745543}, {0.000745543}, {0.000229257}, {0.000229257}, {0.000229257}, {0.000229257}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000849837}, {0.000849837}, {0.000849837}, {0.000849837}, {0.000902637}, {0.000902637}, {0.000902637}, {0.000902637}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.00045003}, {0.00045003}, {0.00045003}, {0.00045003}, {0.00022929}, {0.00022929}, {0.00022929}, {0.00022929}, {0.000761723}, {0.000761723}, {0.000761723}, {0.000761723}, {0.000509558}, {0.000509558}, {0.000509558}, {0.000509558}, {0.00104832}, {0.00104832}, {0.00104832}, {0.00104832}, {0.00111203}, {0.00111203}, {0.00111203}, {0.00111203}, {0.00080431}, {0.00080431}, {0.00080431}, {0.00080431}, {0.000379219}, {0.000379219}, {0.000379219}, {0.000379219}, {0.00045003}, {0.00045003}, {0.00045003}, {0.00045003}, {0.00022929}, {0.00022929}, {0.00022929}, {0.00022929}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.00106294}, {0.00106294}, {0.00106294}, {0.00106294}, {0.00172128}, {0.00172128}, {0.00172128}, {0.00172128}, {0.00120813}, {0.00120813}, {0.00120813}, {0.00120813}, {0.00185969}, {0.00185969}, {0.00185969}, {0.00185969}, {0.000922847}, {0.000922847}, {0.000922847}, {0.000922847}, {0.00167934}, {0.00167934}, {0.00167934}, {0.00167934}, {0.000237043}, {0.000237043}, {0.000237043}, {0.000237043}, {0.000233177}, {0.000233177}, {0.000233177}, {0.000233177}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.000209765}, {0.00100541}, {0.00100541}, {0.00100541}, {0.00100541}, {0.0006888}, {0.0006888}, {0.0006888}, {0.0006888}, {0.000883155}, {0.000883155}, {0.000883155}, {0.000883155}, {0.000449966}, {0.000449966}, {0.000449966}, {0.000449966}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000723193}, {0.000723193}, {0.000723193}, {0.000723193}, {0.00119627}, {0.00119627}, {0.00119627}, {0.00119627}, {0.000922847}, {0.000922847}, {0.000922847}, {0.000922847}, {0.00101774}, {0.00101774}, {0.00101774}, {0.00101774}, {0.00074475}, {0.00074475}, {0.00074475}, {0.00074475}, {0.00122628}, {0.00122628}, {0.00122628}, {0.00122628}, {0.000688235}, {0.000688235}, {0.000688235}, {0.000688235}, {0.00100531}, {0.00100531}, {0.00100531}, {0.00100531}, {0.00051012}, {0.00051012}, {0.00051012}, {0.00051012}, {0.000745227}, {0.000745227}, {0.000745227}, {0.000745227}, {0.00103381}, {0.00103381}, {0.00103381}, {0.00103381}, {0.00130566}, {0.00130566}, {0.00130566}, {0.00130566}, {0.0011808}, {0.0011808}, {0.0011808}, {0.0011808}, {0.00100744}, {0.00100744}, {0.00100744}, {0.00100744}, {0.00169196}, {0.00169196}, {0.00169196}, {0.00169196}, {0.000945026}, {0.000945026}, {0.000945026}, {0.000945026}, {0.00124164}, {0.00124164}, {0.00124164}, {0.00124164}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000396358}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000883155}, {0.000883155}, {0.000883155}, {0.000883155}, {0.000449966}, {0.000449966}, {0.000449966}, {0.000449966}, {0.00139391}, {0.00139391}, {0.00139391}, {0.00139391}, {0.000913554}, {0.000913554}, {0.000913554}, {0.000913554}, {0.00105108}, {0.00105108}, {0.00105108}, {0.00105108}, {0.0011491}, {0.0011491}, {0.0011491}, {0.0011491}, {0.000229257}, {0.000229257}, {0.000229257}, {0.000229257}, {0.000609681}, {0.000609681}, {0.000609681}, {0.000609681}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000201944}, {0.000391999}, {0.000391999}, {0.000391999}, {0.000391999}, {0.00150629}, {0.00150629}, {0.00150629}, {0.00150629}, {0.00185388}, {0.00185388}, {0.00185388}, {0.00185388}, {0.00108769}, {0.00108769}, {0.00108769}, {0.00108769}, {0.000706604}, {0.000706604}, {0.000706604}, {0.000706604}, {0.00068973}, {0.00068973}, {0.00068973}, {0.00068973}, {0.00051012}, {0.00051012}, {0.00051012}, {0.00051012}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000982951}, {0.000982951}, {0.000982951}, {0.000982951}, {0.00155838}, {0.00155838}, {0.00155838}, {0.00155838}, {0.00120813}, {0.00120813}, {0.00120813}, {0.00120813}, {0.00190279}, {0.00190279}, {0.00190279}, {0.00190279}, {0.000890603}, {0.000890603}, {0.000890603}, {0.000890603}, {0.00130171}, {0.00130171}, {0.00130171}, {0.00130171}, {0.000509851}, {0.000509851}, {0.000509851}, {0.000509851}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000744892}, {0.000722514}, {0.000722514}, {0.000722514}, {0.000722514}, {0.000550638}, {0.000550638}, {0.000550638}, {0.000550638}, {0.000869085}, {0.000869085}, {0.000869085}, {0.000869085}, {0.00056562}, {0.00056562}, {0.00056562}, {0.00056562}, {0.000549932}, {0.000549932}, {0.000549932}, {0.000549932}, {0.000732214}, {0.000732214}, {0.000732214}, {0.000732214}, {0.00058443}, {0.00058443}, {0.00058443}, {0.00058443}, {0.000883971}, {0.000883971}, {0.000883971}, {0.000883971}, {0.00124314}, {0.00124314}, {0.00124314}, {0.00124314}, {0.000836794}, {0.000836794}, {0.000836794}, {0.000836794}, {0.00092794}, {0.00092794}, {0.00092794}, {0.00092794}, {0.000815143}, {0.000815143}, {0.000815143}, {0.000815143}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_tetrahedron_4.verified b/test/test_fe_engine/test_fe_engine_precomputation_tetrahedron_4.verified
new file mode 100644
index 000000000..1db1a92c1
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_tetrahedron_4.verified
@@ -0,0 +1,119 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 3
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 3
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_point_1) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_point_1
+ + size : 8
+ + nb_component : 1
+ + allocated size : 2000
+ + memory size : 7.81KiByte
+ + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
+ ]
+ ]
+ (not_ghost:_segment_2) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_segment_2
+ + size : 48
+ + nb_component : 2
+ + allocated size : 2000
+ + memory size : 15.62KiByte
+ + values : {{6, 8}, {8, 9}, {9, 10}, {10, 7}, {7, 11}, {11, 12}, {12, 13}, {13, 3}, {3, 14}, {14, 15}, {15, 16}, {16, 2}, {2, 17}, {17, 18}, {18, 19}, {19, 6}, {0, 20}, {20, 21}, {21, 22}, {22, 4}, {4, 23}, {23, 24}, {24, 25}, {25, 5}, {5, 26}, {26, 27}, {27, 28}, {28, 1}, {1, 29}, {29, 30}, {30, 31}, {31, 0}, {2, 32}, {32, 33}, {33, 34}, {34, 0}, {6, 35}, {35, 36}, {36, 37}, {37, 4}, {7, 38}, {38, 39}, {39, 40}, {40, 5}, {3, 41}, {41, 42}, {42, 43}, {43, 1}}
+ ]
+ ]
+ (not_ghost:_triangle_3) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_triangle_3
+ + size : 240
+ + nb_component : 3
+ + allocated size : 2000
+ + memory size : 23.44KiByte
+ + values : {{45, 49, 35}, {45, 8, 50}, {46, 38, 51}, {23, 47, 52}, {46, 50, 10}, {37, 49, 47}, {25, 52, 48}, {40, 48, 51}, {35, 49, 36}, {38, 39, 51}, {8, 9, 50}, {23, 52, 24}, {36, 49, 37}, {9, 10, 50}, {39, 40, 51}, {24, 52, 25}, {45, 44, 49}, {45, 50, 44}, {46, 44, 50}, {44, 47, 49}, {46, 51, 44}, {44, 52, 47}, {44, 51, 48}, {44, 48, 52}, {45, 35, 53}, {45, 53, 8}, {46, 54, 38}, {23, 55, 47}, {46, 10, 54}, {37, 47, 55}, {25, 48, 56}, {40, 56, 48}, {4, 37, 55}, {6, 53, 35}, {7, 54, 10}, {7, 38, 54}, {6, 8, 53}, {5, 56, 40}, {4, 55, 23}, {5, 25, 56}, {11, 62, 58}, {14, 63, 59}, {8, 64, 60}, {17, 65, 61}, {10, 58, 64}, {19, 60, 65}, {13, 59, 62}, {16, 61, 63}, {14, 15, 63}, {11, 12, 62}, {17, 18, 65}, {8, 9, 64}, {12, 13, 62}, {15, 16, 63}, {9, 10, 64}, {18, 19, 65}, {58, 62, 57}, {59, 57, 62}, {59, 63, 57}, {61, 57, 63}, {58, 57, 64}, {60, 64, 57}, {60, 57, 65}, {61, 65, 57}, {11, 58, 67}, {14, 59, 66}, {8, 60, 69}, {17, 61, 68}, {10, 67, 58}, {19, 69, 60}, {13, 66, 59}, {16, 68, 61}, {2, 68, 16}, {3, 66, 13}, {6, 69, 19}, {7, 67, 10}, {7, 11, 67}, {3, 14, 66}, {6, 8, 69}, {2, 17, 68}, {26, 75, 71}, {29, 76, 72}, {23, 77, 73}, {20, 78, 74}, {25, 71, 77}, {22, 73, 78}, {28, 72, 75}, {31, 74, 76}, {29, 30, 76}, {26, 27, 75}, {20, 21, 78}, {23, 24, 77}, {27, 28, 75}, {30, 31, 76}, {24, 25, 77}, {21, 22, 78}, {71, 75, 70}, {72, 70, 75}, {72, 76, 70}, {70, 76, 74}, {71, 70, 77}, {70, 73, 77}, {70, 78, 73}, {70, 74, 78}, {26, 71, 80}, {29, 72, 79}, {23, 73, 82}, {20, 74, 81}, {25, 80, 71}, {22, 82, 73}, {28, 79, 72}, {31, 81, 74}, {0, 81, 31}, {1, 79, 28}, {4, 82, 22}, {5, 80, 25}, {5, 26, 80}, {1, 29, 79}, {4, 23, 82}, {0, 20, 81}, {41, 84, 88}, {14, 89, 84}, {29, 86, 90}, {32, 91, 85}, {16, 85, 89}, {43, 88, 86}, {34, 87, 91}, {31, 90, 87}, {41, 88, 42}, {14, 15, 89}, {29, 90, 30}, {32, 33, 91}, {42, 88, 43}, {15, 16, 89}, {33, 34, 91}, {30, 90, 31}, {84, 89, 83}, {84, 83, 88}, {85, 83, 89}, {86, 88, 83}, {85, 91, 83}, {86, 83, 90}, {87, 90, 83}, {87, 83, 91}, {14, 84, 92}, {41, 92, 84}, {29, 94, 86}, {32, 85, 93}, {43, 86, 94}, {16, 93, 85}, {31, 87, 95}, {34, 95, 87}, {1, 43, 94}, {2, 93, 16}, {3, 92, 41}, {3, 14, 92}, {1, 94, 29}, {2, 32, 93}, {0, 31, 95}, {0, 95, 34}, {32, 97, 101}, {17, 102, 97}, {35, 103, 98}, {20, 99, 104}, {19, 98, 102}, {34, 101, 99}, {22, 104, 100}, {37, 100, 103}, {32, 101, 33}, {35, 36, 103}, {17, 18, 102}, {20, 104, 21}, {33, 101, 34}, {18, 19, 102}, {36, 37, 103}, {21, 104, 22}, {97, 96, 101}, {97, 102, 96}, {98, 96, 102}, {99, 101, 96}, {98, 103, 96}, {99, 96, 104}, {100, 96, 103}, {100, 104, 96}, {32, 105, 97}, {17, 97, 105}, {35, 98, 106}, {20, 107, 99}, {19, 106, 98}, {34, 99, 107}, {22, 100, 108}, {37, 108, 100}, {0, 34, 107}, {2, 105, 32}, {6, 106, 19}, {6, 35, 106}, {2, 17, 105}, {4, 108, 37}, {0, 107, 20}, {4, 22, 108}, {11, 110, 115}, {38, 114, 110}, {26, 116, 112}, {41, 111, 117}, {13, 115, 111}, {40, 112, 114}, {43, 117, 113}, {28, 113, 116}, {11, 115, 12}, {38, 39, 114}, {26, 27, 116}, {41, 117, 42}, {39, 40, 114}, {12, 115, 13}, {42, 117, 43}, {27, 28, 116}, {109, 110, 114}, {109, 115, 110}, {111, 115, 109}, {112, 109, 114}, {111, 109, 117}, {112, 116, 109}, {113, 109, 116}, {113, 117, 109}, {11, 118, 110}, {38, 110, 118}, {26, 112, 120}, {41, 119, 111}, {40, 120, 112}, {13, 111, 119}, {28, 121, 113}, {43, 113, 121}, {5, 120, 40}, {3, 13, 119}, {7, 38, 118}, {7, 118, 11}, {5, 26, 120}, {3, 119, 41}, {1, 121, 28}, {1, 43, 121}}
+ ]
+ ]
+ (not_ghost:_tetrahedron_4) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_tetrahedron_4
+ + size : 341
+ + nb_component : 4
+ + allocated size : 2000
+ + memory size : 31.25KiByte
+ + values : {{124, 123, 125, 129}, {43, 86, 130, 88}, {70, 124, 129, 126}, {48, 77, 25, 52}, {31, 0, 81, 95}, {0, 107, 81, 95}, {126, 91, 87, 101}, {124, 70, 129, 125}, {43, 121, 113, 130}, {55, 100, 82, 108}, {100, 55, 82, 73}, {23, 55, 73, 82}, {71, 75, 125, 112}, {123, 44, 124, 125}, {43, 113, 117, 130}, {94, 43, 86, 130}, {122, 123, 128, 129}, {46, 10, 58, 50}, {99, 107, 81, 20}, {125, 112, 116, 109}, {79, 72, 28, 130}, {123, 122, 125, 129}, {67, 11, 7, 118}, {123, 127, 128, 129}, {124, 44, 49, 47}, {17, 65, 18, 102}, {76, 90, 30, 31}, {54, 10, 7, 67}, {9, 10, 50, 64}, {38, 54, 7, 118}, {123, 124, 127, 129}, {12, 115, 62, 13}, {97, 61, 102, 127}, {45, 53, 8, 69}, {38, 114, 39, 51}, {125, 75, 129, 116}, {122, 44, 123, 125}, {71, 70, 77, 124}, {114, 112, 125, 109}, {32, 93, 97, 85}, {53, 6, 8, 69}, {117, 128, 129, 109}, {63, 61, 16, 89}, {76, 90, 31, 74}, {61, 85, 16, 89}, {65, 123, 60, 98}, {55, 100, 47, 73}, {100, 47, 103, 37}, {96, 123, 103, 124}, {55, 23, 4, 82}, {78, 100, 22, 73}, {61, 85, 89, 127}, {61, 127, 89, 63}, {121, 43, 94, 130}, {108, 22, 82, 4}, {14, 92, 3, 66}, {78, 21, 104, 20}, {100, 78, 104, 124}, {14, 15, 89, 63}, {90, 126, 87, 74}, {90, 76, 126, 74}, {3, 13, 66, 119}, {108, 55, 4, 82}, {58, 11, 110, 62}, {11, 115, 110, 62}, {57, 123, 60, 65}, {122, 58, 110, 62}, {115, 122, 110, 62}, {117, 128, 88, 129}, {86, 129, 130, 88}, {70, 71, 125, 124}, {107, 0, 34, 95}, {122, 114, 125, 109}, {126, 86, 83, 129}, {92, 3, 66, 119}, {129, 86, 83, 88}, {128, 41, 119, 111}, {117, 128, 111, 41}, {11, 12, 115, 62}, {33, 32, 101, 91}, {70, 124, 126, 74}, {100, 124, 47, 73}, {96, 124, 126, 127}, {78, 70, 124, 73}, {90, 76, 30, 29}, {96, 123, 124, 127}, {15, 63, 16, 89}, {121, 79, 1, 28}, {76, 70, 126, 74}, {122, 114, 109, 110}, {129, 117, 130, 88}, {123, 44, 49, 124}, {26, 80, 5, 120}, {123, 65, 102, 98}, {57, 123, 127, 128}, {117, 128, 109, 111}, {70, 78, 124, 74}, {95, 107, 81, 87}, {55, 100, 37, 47}, {77, 24, 25, 52}, {100, 78, 22, 104}, {56, 71, 25, 48}, {14, 59, 89, 84}, {96, 100, 104, 124}, {2, 105, 68, 17}, {124, 123, 103, 49}, {123, 57, 60, 64}, {44, 124, 52, 47}, {71, 112, 48, 56}, {41, 117, 88, 42}, {99, 96, 126, 101}, {97, 85, 127, 101}, {34, 91, 101, 87}, {128, 127, 83, 129}, {126, 90, 83, 86}, {75, 71, 125, 70}, {99, 126, 74, 87}, {23, 55, 47, 73}, {100, 78, 124, 73}, {32, 91, 85, 101}, {57, 122, 62, 58}, {71, 77, 25, 48}, {70, 77, 124, 73}, {114, 38, 110, 51}, {114, 40, 39, 51}, {59, 14, 89, 63}, {53, 106, 35, 6}, {45, 123, 98, 60}, {99, 126, 87, 101}, {106, 53, 69, 6}, {46, 122, 110, 51}, {128, 122, 129, 109}, {124, 100, 47, 103}, {107, 99, 81, 87}, {125, 44, 48, 51}, {38, 46, 110, 51}, {44, 123, 49, 45}, {124, 47, 49, 103}, {36, 35, 49, 103}, {46, 122, 51, 44}, {54, 67, 7, 118}, {10, 64, 58, 50}, {122, 114, 51, 125}, {11, 58, 118, 67}, {44, 122, 51, 125}, {58, 11, 118, 110}, {22, 100, 82, 73}, {46, 122, 58, 110}, {108, 100, 82, 22}, {45, 60, 8, 50}, {99, 81, 74, 20}, {60, 45, 8, 69}, {75, 71, 26, 112}, {107, 0, 81, 20}, {126, 91, 83, 87}, {31, 90, 87, 74}, {34, 107, 95, 87}, {126, 96, 127, 101}, {91, 126, 127, 101}, {92, 14, 84, 66}, {105, 32, 2, 93}, {47, 49, 103, 37}, {115, 122, 109, 110}, {33, 91, 101, 34}, {49, 36, 103, 37}, {112, 71, 48, 125}, {59, 128, 89, 84}, {19, 65, 60, 98}, {124, 126, 127, 129}, {126, 91, 127, 83}, {31, 81, 74, 87}, {81, 99, 74, 87}, {117, 113, 129, 130}, {84, 128, 88, 41}, {113, 117, 129, 109}, {90, 76, 29, 86}, {65, 19, 102, 98}, {55, 100, 108, 37}, {96, 123, 102, 98}, {14, 59, 84, 66}, {100, 96, 103, 124}, {32, 105, 97, 93}, {99, 34, 101, 87}, {127, 126, 83, 129}, {94, 29, 130, 86}, {19, 106, 69, 6}, {128, 117, 88, 41}, {123, 96, 103, 98}, {46, 38, 110, 118}, {77, 23, 24, 52}, {19, 65, 102, 18}, {121, 79, 28, 130}, {46, 54, 38, 118}, {113, 121, 28, 130}, {108, 55, 37, 4}, {112, 75, 116, 26}, {56, 40, 5, 120}, {75, 27, 28, 116}, {127, 85, 89, 83}, {66, 59, 84, 128}, {85, 61, 97, 127}, {122, 125, 129, 109}, {26, 75, 116, 27}, {128, 129, 83, 88}, {122, 123, 57, 128}, {40, 112, 56, 48}, {80, 56, 25, 5}, {84, 128, 83, 88}, {91, 85, 127, 83}, {57, 61, 63, 127}, {123, 122, 64, 50}, {3, 92, 41, 119}, {44, 123, 45, 50}, {47, 124, 52, 73}, {79, 72, 130, 29}, {32, 85, 97, 101}, {2, 93, 16, 68}, {105, 93, 68, 97}, {97, 61, 68, 17}, {85, 91, 127, 101}, {96, 97, 127, 101}, {105, 97, 68, 17}, {124, 77, 52, 73}, {56, 71, 80, 25}, {60, 64, 8, 50}, {64, 9, 8, 50}, {65, 61, 102, 17}, {93, 105, 68, 2}, {61, 97, 102, 17}, {78, 21, 22, 104}, {23, 47, 52, 73}, {112, 40, 56, 120}, {80, 56, 5, 120}, {31, 95, 81, 87}, {99, 107, 34, 87}, {58, 46, 110, 118}, {43, 121, 94, 1}, {112, 75, 125, 116}, {122, 114, 110, 51}, {77, 23, 52, 73}, {90, 126, 83, 87}, {13, 66, 111, 59}, {111, 66, 13, 119}, {66, 128, 111, 59}, {111, 128, 66, 119}, {60, 50, 123, 64}, {123, 50, 60, 45}, {74, 104, 126, 99}, {104, 20, 74, 78}, {74, 20, 104, 99}, {45, 69, 106, 53}, {45, 106, 35, 53}, {35, 106, 45, 98}, {129, 116, 109, 125}, {109, 116, 129, 113}, {54, 10, 58, 46}, {58, 10, 54, 67}, {54, 58, 118, 46}, {118, 58, 54, 67}, {113, 129, 75, 116}, {28, 113, 75, 116}, {129, 75, 70, 72}, {129, 70, 75, 125}, {43, 117, 88, 130}, {88, 117, 43, 42}, {56, 112, 80, 71}, {56, 80, 112, 120}, {80, 112, 26, 71}, {80, 26, 112, 120}, {74, 124, 104, 78}, {74, 104, 124, 126}, {126, 104, 96, 99}, {96, 104, 126, 124}, {62, 128, 57, 59}, {57, 128, 62, 122}, {130, 29, 121, 79}, {121, 29, 130, 94}, {29, 1, 121, 79}, {121, 1, 29, 94}, {58, 50, 122, 46}, {122, 50, 58, 64}, {97, 93, 61, 85}, {97, 61, 93, 68}, {61, 93, 16, 85}, {61, 16, 93, 68}, {59, 89, 127, 63}, {127, 89, 59, 128}, {59, 127, 57, 63}, {57, 127, 59, 128}, {86, 76, 126, 90}, {86, 126, 76, 129}, {125, 51, 112, 114}, {112, 51, 125, 48}, {51, 40, 112, 114}, {112, 40, 51, 48}, {48, 124, 77, 52}, {44, 48, 124, 125}, {44, 124, 48, 52}, {61, 102, 123, 65}, {123, 102, 61, 127}, {61, 123, 57, 65}, {57, 123, 61, 127}, {106, 19, 60, 98}, {60, 19, 106, 69}, {106, 60, 45, 98}, {45, 60, 106, 69}, {122, 64, 57, 123}, {57, 64, 122, 58}, {76, 129, 70, 72}, {70, 129, 76, 126}, {84, 66, 119, 92}, {84, 119, 66, 128}, {41, 84, 119, 92}, {41, 119, 84, 128}, {124, 71, 48, 77}, {124, 48, 71, 125}, {128, 89, 83, 127}, {83, 89, 128, 84}, {111, 128, 62, 59}, {62, 111, 13, 115}, {13, 111, 62, 59}, {122, 50, 44, 46}, {44, 50, 122, 123}, {102, 127, 96, 97}, {96, 127, 102, 123}, {103, 123, 45, 49}, {103, 45, 123, 98}, {35, 103, 45, 49}, {35, 45, 103, 98}, {28, 130, 75, 113}, {75, 130, 28, 72}, {130, 129, 75, 113}, {75, 129, 130, 72}, {29, 130, 76, 72}, {76, 130, 29, 86}, {130, 129, 76, 72}, {76, 129, 130, 86}, {62, 111, 122, 128}, {122, 111, 62, 115}, {111, 109, 122, 128}, {122, 109, 111, 115}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_tetrahedron_4)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_tetrahedron_4) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_lagrange_tetrahedron_4
+ + size : 341
+ + nb_component : 4
+ + allocated size : 341
+ + memory size : 10.66KiByte
+ + values : {{0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}, {0.25, 0.25, 0.25, 0.25}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_tetrahedron_4) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_lagrange_tetrahedron_4
+ + size : 341
+ + nb_component : 12
+ + allocated size : 341
+ + memory size : 31.97KiByte
+ + values : {{-2.9332, -3.39585, 0.502232, 0, 2.96343, 0.405765, 2.9332, 0.0602741, 3.04336, 0, 0.372141, -3.95136}, {3.45053, -1.3657, -2.27011, -3.89489, -2.97354, -4.55745, 0, 0, 5.36117, 0.444357, 4.33924, 1.46638}, {0.382444, -2.89016, 0, -1.28516, 1.90393, 2.9332, 3.7515, 0.879817, 0, -2.84879, 0.106407, -2.9332}, {2.97575, 3.89171, -3.89356, 0, 0, -5.23939, 1.36374, -3.44772, 3.45502, -4.3395, -0.443995, 5.67793}, {4, -4, -4.00114, -4, -3.0469, -3.04575, 0, 0, 7.0469, 0, 7.0469, 0}, {-3.52295, -3.52395, -3.52295, -3.52295, 3.52295, 3.52395, 3.52295, -3.52295, 3.52295, 3.52295, 3.52395, -3.52395}, {2.40825, 0.953172, 2.40825, 2.50475, 5.50649, -2.73463, -1.78774, -5.2227, -1.78774, -3.12526, -1.23696, 2.11413}, {-2.9332, 1.96549, 1.23633, 0, -2.87587, -0.393776, 0, 1.01994, -3.86266, 2.9332, -0.10956, 3.0201}, {0.419151, 4, -4, 2.79404, -8.15492, 0.835098, 2.20503, 4.15492, 3.1649, -5.41822, 0, 0}, {3.52244, 3.52345, 3.52345, 3.65886, 3.65991, -3.65991, 3.52345, -3.52244, -3.52244, -10.7048, -3.66092, 3.6589}, {-1.79359, 1.79523, -1.79625, 3.5193, 3.52237, 3.52452, -7.1749, -7.18117, 0.13427, 5.44919, 1.86357, -1.86254}, {3.99728, -4.00093, 4.00321, 0, 7.04488, 0, 4.15209, 3.16185, -3.16156, -8.14937, -6.2058, -0.841653}, {-2.33012, -1.26027, 3.59031, 1.73691, -1.73691, -3.82575, -2.89531, 2.89531, -1.14913, 3.48852, 0.101865, 1.38457}, {0, 3.12067, -1.26381, 0, -0.238012, 2.52719, -2.9332, -3.29673, -0.550156, 2.9332, 0.414072, -0.713225}, {2.25842, -1.36825, -3.45027, 4.64721, -2.97306, 3.89484, -1.48742, 4.3413, -0.444568, -5.41822, 0, 0}, {-0.835098, -8.15492, -2.75583, 4, 4, -0.45685, -3.1649, 4.15492, -2.14849, 0, 0, 5.36117}, {2.74019, 0.0956852, 2.80125, -3.01086, 0.697365, -0.375193, 0.165245, 2.48398, -2.46532, 0.105421, -3.27703, 0.0392613}, {2.96943, -3.89447, -0.304082, 1.36934, 3.45016, 3.45016, 0, 0, -3.59038, -4.33877, 0.444309, 0.444309}, {3.164, 3.1649, 4.15492, -6.21002, 0.835098, -8.15492, 7.04488, 0, 0, -3.99886, -4, 4}, {-4.24471, 0, -2.22045e-16, 1.70632, 0.0142405, 4.507, 1.02929, -3.25521, -3.22316, 1.5091, 3.24097, -1.28383}, {-0.835098, -3.26304, -8.15492, -3.1649, -1.55632, 4.15492, 4, -0.0381551, 4, 0, 4.85752, 0}, {-3.09877, -0.624101, 0.936346, 2.96195, 3.42913, -0.507155, -0.240412, -3.6139, 3.58676, 0.377232, 0.808874, -4.01595}, {-7.0469, 0, 0, 4, 4, -4, 3.0469, 3.04589, 4, 0, -7.04589, 0}, {0, 0.802501, 2.70275, -2.9332, -0.102425, -2.99855, 2.9332, 2.58063, 0.364309, 0, -3.28071, -0.0685083}, {-3.1225e-17, 0, -2.4308, 3.22687, 1.27702, 1.31348, -3.25484, 3.22647, -0.701298, 0.0279753, -4.5035, 1.81862}, {1.62741e-11, -1.54712e-11, -4, 5.23939, 0, 0, -5.23939, 5.23939, 4, 0, -5.23939, 0}, {0, -7.13135e-16, 5.23939, 0, 5.23939, 0, 4, -5.23939, -5.24506, -4, -2.28255e-11, 0.00566839}, {0, -7.0469, 8.88178e-16, -4, 4, 4, 4, 3.0469, 3.0469, 0, 0, -7.0469}, {-4, 5.24608, 5.23939, 4, 1.55241e-11, 1.5915e-11, 0, -5.24608, 0, 0, 0, -5.23939}, {4, -4, 4, -7.0469, 0, 0, 3.0469, 4, 3.04589, 0, 0, -7.04589}, {2.51489, 3.01511, 3.01511, -3.88194, -3.41534, -0.482145, -2.88414, -0.0592661, -2.99246, 4.25119, 0.459499, 0.459499}, {5.23939, 5.23285, 4, 0, -5.23568, 0, -5.23939, 0, 0, 2.32699e-11, 0.00283219, -4}, {-2.75474, -0.835644, -4.18437, 0.257813, 3.33257, -1.31901, 0.305142, -0.305142, 4.63589, 2.19179, -2.19179, 0.867496}, {4.15492, -3.1649, -3.1649, -8.15492, -0.835098, 6.2118, 4, 4, 4, 0, 0, -7.0469}, {0.00566839, 4, -0.00283219, 0, 0, -5.23568, 5.23372, -4, 5.23851, -5.23939, 0, 0}, {-1.52791, 1.52994, 4.71561, -1.9516, -3.29226, 0.192739, -0.842937, 0.840096, -3.60933, 4.32244, 0.92222, -1.29903}, {2.86385, 3.21879, 0.53715, -0.233278, -0.500202, 2.48343, -2.84203, -0.0735906, -1.79686, 0.211453, -2.645, -1.22372}, {4.53179, 1.05538, 0.0281511, -1.28505, -2.42496, -3.24278, -3.24675, -1.61027, 3.21463, 0, 2.97985, 0}, {-1.02659, 3.24669, 3.21473, 3.14112, -4.52341, 0.014006, -4.24471, 0, 0, 2.13019, 1.27672, -3.22874}, {-4, -4, -4, 0.835098, 8.15492, 0.835098, 0, 0, 3.59038, 3.1649, -4.15492, -0.425481}, {0, -7.0469, 0, -4, 3.0469, 3.0469, 4, 4, 4, 0, 0, -7.0469}, {2.27701, -1.57663, -3.25, -1.49395, 3.66511, 0.0115805, -2.03803, -2.71547, -0.00857994, 1.25497, 0.626993, 3.247}, {4.33924, 5.68374, -0.444357, -2.97354, -3.89489, 3.89489, -1.3657, 3.45053, -3.45053, 0, -5.23939, 0}, {4.33729, -5.68119, -0.447948, 0, 5.23939, 0, -1.36509, -3.45133, -3.4494, -2.97221, 3.89314, 3.89735}, {0, 6.10623e-16, 3.59038, -2.97354, -3.89489, 0.304504, -1.3657, 3.45053, -3.45053, 4.33924, 0.444357, -0.444357}, {-0.960671, 0.960671, -4.13489, 2.09645, -2.09645, -0.829765, 1.35765, 2.23273, 3.97777, -2.49343, -1.09695, 0.986887}, {-3.6556, -3.65879, 3.65879, -1.79574, 1.79308, -1.79621, 3.6556, 3.65879, -0.0684102, 1.79574, -1.79308, -1.79417}, {0.307102, -2.97354, -3.89489, 3.59038, 0, 0, -0.44815, 4.33924, 0.444357, -3.44934, -1.3657, 3.45053}, {-1.64157, 0.110512, -3.2348, 1.22142, 3.1461, -3.07269e-12, -0.833409, -0.40322, 3.2348, 1.25356, -2.85339, 2.78682e-12}, {0, 7.04488, 0, 4, -3.99886, 4.00114, -4, -3.04603, 3.04575, 0, 0, -7.0469}, {-0.443995, -0.444383, -4.3395, 0, 3.59038, 0, -3.44772, -3.45073, 1.36374, 3.89171, 0.30473, 2.97575}, {-1.00556, 2.54062, 1.04976, -3.90018, -1.55367, -2.03672, 3.775, 1.86995, -1.86995, 1.13075, -2.8569, 2.8569}, {-4.90575, 0.986953, -0.986953, 1.13075, -2.8569, 2.8569, -1.91647, -0.397296, -4.84209, 5.69148, 2.26724, 2.97215}, {4.19746, -5.51046, 2.84944, 1.88954, 6.77064, -1.88954, -2.89363, -5.45245, -4.15327, -3.19336, 4.19228, 3.19336}, {8.88178e-16, 7.0469, 0, -3.99886, -4, -4, 7.04488, 0, 0, -3.04603, -3.0469, 4}, {-4, 4, -4, 0, -7.0469, 0, 4, 3.0469, -3.0469, 0, 0, 7.0469}, {5.23123, 5.81945e-16, 0, -5.23123, -5.23939, 4, 0, 5.23939, 0, 1.6327e-11, 1.54706e-11, -4}, {-0.750211, -0.75138, 4.81251, 1.07726, -4.16045, 1.64668, -2.20213, 3.03383, -5.71589, 1.87508, 1.878, -0.743302}, {4, -2.28271e-11, 2.36273e-11, -4, 5.23939, -5.23939, 0, -5.23939, 0, 0, 0, 5.23939}, {3.80063, -1.80519, -1.80851, 1.09322, 2.76209, 2.76114, -3.92166, 1.49941, -2.08755, -0.972194, -2.45631, 1.13492}, {-1.92104, 0.382436, -4.85423, 5.71942, -2.18677, 3.04452, 1.09257, 2.76234, 2.76079, -4.89095, -0.95801, -0.95108}, {3.0469, 3.0469, -4, 4, 4, 4, -7.0469, 0, 0, 0, -7.0469, 0}, {-3.52345, 3.52244, -3.52446, 3.52244, 3.52345, 3.52345, -3.52244, -3.52345, 3.52345, 3.52345, -3.52244, -3.52244}, {-3.89489, -0.305669, 2.97354, 3.45053, 3.44843, 1.3657, 0, -3.58881, 0, 0.444357, 0.446058, -4.33924}, {3.45195, 3.44854, 1.36462, 5.6826, 0.445968, -4.33837, -3.89516, -3.89451, 2.97375, -5.23939, 0, 0}, {3.2348, 1.4231, -1.28032, 0, -3.01876, 0, -3.04119e-12, 1.63545, 4.51512, -3.2348, -0.0397999, -3.2348}, {-2.82577, -2.82405, -1.11842, -1.29033, 2.2973, 4.00441, 3.2475, -0.343291, 1.28534, 0.868592, 0.870035, -4.17133}, {1.88206, -3.35082, -5.84079, -2.82615, -2.82336, -1.11723, 1.95788, 1.95275, 5.28756, -1.01379, 4.22143, 1.67046}, {4.00887, -0.711384, 1.23085, -1.07985, 3.872, 1.08301, -1.46134, -0.730093, -3.78093, -1.46768, -2.43052, 1.46707}, {-6.11172, -2.09613, -3.09899, -3.35065, 1.32617, 2.2044, 6.08523, -2.4085, 1.35769, 3.37714, 3.17846, -0.4631}, {0, -1.78762, -4.51512, 0, -1.19223, 4.51512, 2.9332, 1.45476, -2.90418, -2.9332, 1.52509, 2.90418}, {-8.88178e-16, 0, 7.0469, -3.0469, -4, -3.0469, -4, 4, -4, 7.0469, 0, 0}, {-1.83438, 2.64163, -0.00817939, 1.49822, -0.389218, 3.22599, -2.02268, -3.19987, 0.00990788, 2.35884, 0.947457, -3.22772}, {-3.58659, -3.58659, 0.548674, 1.12084, -3.39428, -1.90685, -0.156642, 4.35848, -1.19262, 2.6224, 2.6224, 2.5508}, {-3.52345, -3.52345, -3.52345, 3.52345, 3.52345, -3.52345, -3.52345, 3.52345, 3.52345, 3.52345, -3.52345, 3.52345}, {4.44089e-16, 0, 2.95197, 4.40828e-12, -4.51512, -1.73539, -3.2348, 1.28032, -0.721726, 3.2348, 3.2348, -0.494857}, {-4.24471, 8.88178e-16, -4.44089e-16, 1.287, -4, -4, -1.6658, 8.15492, 0.835098, 4.62351, -4.15492, 3.1649}, {0.885858, -4.33672, -0.444099, -4.24471, 0, 0, 3.16813, 2.96992, 3.89452, 0.190724, 1.3668, -3.45042}, {-2.32703e-11, -0.00283219, 4, 5.23939, 5.23851, -4, 0, -5.23568, 0, -5.23939, 0, 0}, {-5.23939, -4, -5.23939, 2.28255e-11, 4, 2.28255e-11, 0, 0, 5.23939, 5.23939, 0, 0}, {4.47576, -1.93017, 0, -2.90763, 1.52342, 2.9332, 2.90763, 1.45643, -2.9332, -4.47576, -1.04967, 0}, {-2.74183, 0.846161, -0.849296, 1.62977, 1.63119, -1.63119, 0.777461, 0.778141, 2.81224, 0.334598, -3.25549, -0.331753}, {-2.36134, 0, 0, 1.74759, 0, 2.9332, -0.525012, -2.9332, -2.9332, 1.13877, 2.9332, 0}, {-3.21511, 0.1024, -3.24338, 3.21511, -1.89002, -1.27174, 0, 2.97985, 0, -3.36919e-12, -1.19223, 4.51512}, {0, 5.23939, 4.12864e-16, 0, 0, 5.23939, -4, -5.23939, -5.23372, 4, 2.28255e-11, -0.00566839}, {-2.40793, -0.260266, -0.260266, 0.500707, 2.7974, 2.7974, 1.23528, -2.86224, 0.0709597, 0.671946, 0.325101, -2.6081}, {4, 5.23939, -5.23939, 0, 0, 5.23939, -4, 2.28278e-11, -2.36282e-11, 0, -5.23939, 0}, {-4.44089e-16, 7.0469, 0, -7.0469, 0, 0, 3.0469, -3.0469, -4, 4, -4, 4}, {3.22647, -1.69048, -3.25484, 1.27702, -0.254226, 3.22687, 0, 2.97985, 0, -4.5035, -1.03514, 0.0279753}, {-3.50419, 8.88178e-16, 2.01228e-16, -0.300503, -3.2348, 3.2348, 0.9543, -1.27452, -3.22084, 2.85039, 4.50932, -0.0139624}, {-2.58829, 1.58763, 2.59096, 3.47782, 1.19279, 1.76345, 1.14429, -4.10309, -1.14764, -2.03382, 1.32267, -3.20677}, {-0.0193683, 3.11794, -1.2591, 3.23344, 0.218445, 1.74096, -3.23197, -0.456248, 0.785873, 0.0178911, -2.88013, -1.26773}, {4, -4, -4, -7.0469, 0, 0, 3.0469, -3.0469, 4, 0, 7.0469, 0}, {2.09645, -2.09645, -0.829765, 1.02053, 4.21886, 1.6698, -1.9812, -3.25819, -5.80469, -1.13578, 1.13578, 4.96465}, {0, 3.04177, 0.0635186, 0, -2.06144, 2.64295, -2.9332, -0.059438, -2.99766, 2.9332, -0.920892, 0.29119}, {1.04124, -3.22316, -3.25521, -4.24471, 0, 0, -0.179146, -1.28383, 3.24097, 3.38261, 4.507, 0.0142405}, {3.21511, -2.56163, 1.27174, -3.21511, -1.61044, 3.24338, 0, 2.97985, 0, 3.36919e-12, 1.19223, -4.51512}, {-3.65939, -3.66043, -10.7063, -3.52295, 3.52295, 3.52395, 3.52295, -3.52295, 3.52295, 3.65939, 3.66043, 3.65939}, {0.841653, -8.14937, -0.83453, 0, 0, -3.59038, -4.00321, 3.99728, 3.99972, 3.16156, 4.15209, 0.425192}, {0, -8.88178e-16, -5.23939, -4, -5.23123, 5.23372, 4, -1.54883e-11, 0.00566839, 0, 5.23123, 0}, {3.88882, 3.89489, 2.97354, 5.23123, 0, 0, -3.44516, -3.45053, 1.3657, -5.6749, -0.444357, -4.33924}, {8.15548, 0.834427, -0.835156, 0, 0, -3.59038, -4.00272, -3.99679, 4.00028, -4.15276, 3.16236, 0.425261}, {1.3657, 3.45053, -3.45053, 0, 0, 3.59038, -4.33924, 0.444357, -0.444357, 2.97354, -3.89489, 0.304504}, {-0.837584, 3.2348, -1.28032, -0.944765, -3.55036e-12, 4.51512, -0.578996, -3.2348, -3.2348, 2.36134, 0, 0}, {-3.0469, 3.0469, -4, 0, -7.0469, 0, 7.0469, 0, 0, -4, 4, 4}, {0.832911, -2.82507, -0.828908, 0.808732, 3.17388, -0.81323, -3.40548, -0.230067, -1.83358, 1.76384, -0.118743, 3.47572}, {4.44089e-16, -3.01876, 0, 1.28032, 1.39906, -3.2348, -4.51512, 1.5799, -3.09855e-12, 3.2348, 0.0397999, 3.2348}, {1.27174, 3.21511, 0.89222, 0, 0, -2.4308, 3.24338, -3.21511, 0.698828, -4.51512, 3.70603e-12, 0.839751}, {-1.79652, -1.79386, -1.79496, 1.79652, 1.79386, -1.79543, -3.65719, 3.65719, -0.0700075, 3.65719, -3.65719, 3.66039}, {-2.2828e-11, 4, 0.0025524, 0, 0, 5.24273, -5.23939, 0, 0, 5.23939, -4, -5.24528}, {-1.75292, -4.51512, -4.40936e-12, 0.0630025, 1.28032, 3.2348, 2.36134, 0, 0, -0.671422, 3.2348, -3.2348}, {-1.82767, 3.81744, 1.76272, -0.114041, 1.46619, -3.70442, 2.43635, -0.964293, 2.43635, -0.494641, -4.31934, -0.494641}, {-3.45053, -1.3657, -3.45053, -0.444357, 4.33924, -5.68374, 0, 0, 5.23939, 3.89489, -2.97354, 3.89489}, {2.9332, 2.26271, -0.706418, -2.9332, 1.41766, 2.12097, 0, -0.989411, -3.33225, 0, -2.69097, 1.9177}, {0, -1.39581e-17, 4.03735, -3.2348, -3.2348, -3.14648, -1.28032, 3.2348, -2.28562, 4.51512, 4.40982e-12, 1.39475}, {3.25531, -1.69257, -3.22311, -3.621e-12, -1.19223, 4.51512, 0, 2.97985, 0, -3.25531, -0.095055, -1.29201}, {-2.43276, 1.15549, 1.15762, 2.22336, 2.22531, 2.22336, 0.45554, -3.13444, 0.45554, -0.246142, -0.246357, -3.83653}, {4.00272, -3.99679, 4.00378, -8.15548, 0.834427, -0.842284, 4.15276, 3.16236, 0.42889, 0, 0, -3.59038}, {-2.25991, 1.3285, 0.893907, -1.12519, -1.12617, -4.07005, 1.87562, 1.87726, -0.7419, 1.50948, -2.07958, 3.91804}, {-3.45053, 1.3657, -3.45053, -0.444357, -4.33924, -5.68374, 3.89489, 2.97354, 3.89489, 0, 0, 5.23939}, {-3.2348, 0.341949, -1.28032, 0, -3.12276, 0, 3.2348, 0.619904, -3.2348, -3.95817e-12, 2.1609, 4.51512}, {2.97704, 0.304595, -3.89524, -4.34434, -0.444491, 0.444879, 1.36731, -3.44735, 3.45037, 0, 3.58725, 0}, {1.27702, -1.8283, -3.22687, 3.22647, -0.102762, 3.25484, 0, 2.97985, 0, -4.5035, -1.04879, -0.0279753}, {5.67645, -4.33837, 0.445968, 3.45388, 1.36462, 3.44854, -3.89094, 2.97375, -3.89451, -5.23939, 0, 0}, {0, 0, -5.23568, -0.00566839, -4, 0.00283219, 5.24506, 4, 5.23285, -5.23939, 0, 0}, {2.97354, -3.89489, 3.89489, 1.3657, 3.45053, -3.45053, 0, -5.23939, 0, -4.33924, 5.68374, -0.444357}, {7.0469, 0, 0, 0, 0, -7.0469, -4, -4, 4, -3.0469, 4, 3.0469}, {0.676898, -0.676898, 2.91348, 1.85764, -1.85764, -1.85764, -2.8863, -0.704082, -0.704082, 0.351759, 3.23862, -0.351759}, {-1.71643, -3.77342, 1.87396, 2.40825, 0.953172, 2.40825, -0.071317, -1.44928, -3.6617, -0.620505, 4.26953, -0.620505}, {-3.52345, -3.52345, -3.52345, 3.52345, -3.52345, 3.52345, 3.52345, 3.52345, -3.52345, -3.52345, 3.52345, 3.52345}, {-1.16853, 4.05757, 2.41902, -2.70338, -1.07129, -2.70173, 3.36405, 1.3331, -0.22682, 0.507865, -4.31938, 0.509529}, {0.235286, 2.46776, -2.45659, -1.58499, 1.09747, 2.26228, -1.89674, -2.81329, -0.210235, 3.24644, -0.75193, 0.40455}, {1.72714, 0.683827, -1.72773, -2.24537, -3.98415, -1.34153, 0.964303, -1.03975, 2.62699, -0.446071, 4.34007, 0.442278}, {-7.18233, -0.137487, -7.18233, 1.86445, 1.86498, 5.45483, 3.52295, -3.52295, 3.52295, 1.79493, 1.79545, -1.79545}, {0, -8.88178e-16, -2.4308, -3.22687, 1.27702, -0.160385, -0.0279753, -4.5035, 1.80584, 3.25484, 3.22647, 0.785343}, {3.45037, 1.36731, 3.44826, -3.89524, 2.97704, -0.306029, 0, 0, -3.58881, 0.444879, -4.34434, 0.446582}, {3.24278, -1.28505, 1.07917, 0, 0, -2.6315, -3.21463, -3.24675, -0.442405, -0.0281511, 4.53179, 1.99473}, {1.7269, 0.683416, -1.72787, -1.27936, -5.02087, 1.28648, 3.27466, 5.8105, 1.9565, -3.7222, -1.47305, -1.5151}, {-5.23372, -4, 5.23939, -0.00566839, 4, -2.28255e-11, 5.23939, 0, 0, 0, 0, -5.23939}, {0.0281511, 4.53179, 2.33833, 0, 0, -2.884, 3.21463, -3.24675, 0.327026, -3.24278, -1.28505, 0.218644}, {-3.52345, -3.52345, 3.52345, -3.52345, 3.52345, -3.52345, 3.52395, 3.52295, 3.52295, 3.52295, -3.52295, -3.52295}, {1.3657, 3.45494, 3.45053, -4.33924, 5.691, 0.444357, 2.97354, -3.89986, -3.89489, 0, -5.24608, 0}, {-1.06097, 2.95229, -1.06649, 4.44047, 0.792573, -0.800037, -2.21214, -0.888535, 3.02699, -1.16736, -2.85632, -1.16047}, {4, 4, -4, -3.1649, -3.16386, -4.15492, 0, -7.04589, 0, -0.835098, 6.20975, 8.15492}, {-3.23839, -0.578016, 0.58346, 0.0195373, 3.14514, -1.26116, 3.23532, 0.0837745, 2.04552, -0.0164672, -2.6509, -1.36782}, {-3.59038, 4.44089e-16, 0, 4, 4, -4, -0.834843, -0.83804, 8.15243, 0.425226, -3.16196, -4.15243}, {-3.99679, -4.00028, -4.00272, 0, 3.59038, 0, 0.834427, 0.835156, 8.15548, 3.16236, -0.425261, -4.15276}, {-0.618598, -0.619625, 2.97076, -2.5319, -2.52969, -2.52969, -0.377606, 3.21154, -0.378844, 3.52811, -0.062223, -0.062223}, {-6.21002, 0.835098, 8.15492, 3.164, 3.1649, -4.15492, 7.04488, 0, 0, -3.99886, -4, -4}, {-2.96943, -3.89447, -0.304082, 0, 0, -3.59038, -1.36934, 3.45016, 3.45016, 4.33877, 0.444309, 0.444309}, {-4.44089e-16, 3.59038, 0, 0.834427, 0.835156, -8.15548, 3.16236, -0.425261, 4.15276, -3.99679, -4.00028, 4.00272}, {4.15492, 0.425481, -3.1649, 0, -3.59038, 0, 4, 4, 4, -8.15492, -0.835098, -0.835098}, {0.444309, -0.444309, -4.33877, -3.89447, 0.304082, 2.96943, 3.45016, -3.45016, 1.36934, 0, 3.59038, 0}, {-4.44089e-16, 7.0469, 0, -3.04603, -3.0469, -4, 7.04488, 0, 0, -3.99886, -4, 4}, {-6.34716e-16, 0, 4.03735, -3.2348, 3.2348, 1.14797, 3.2348, 1.28032, -2.18823, -4.40962e-12, -4.51512, -2.99709}, {-1.3657, -3.45053, -3.44934, 4.33924, -0.444357, -0.44815, -2.97354, 3.89489, 0.307102, 0, 0, 3.59038}, {-4, 4, -4, 0, 0, 7.0469, 0.835098, -8.15492, -6.2118, 3.1649, 4.15492, 3.1649}, {1.22258, -2.9332, -2.86482e-12, -0.434061, 0, 3.2348, 1.13877, 2.9332, 2.86495e-12, -1.92728, 0, -3.2348}, {0.619868, 0, -4.61952, 1.07793, -2.9332, 1.07793, 1.00404, 2.9332, 1.00404, -2.70184, 0, 2.53754}, {8.15492, -0.835098, -6.2118, -4, 4, -4, -4.15492, -3.1649, 3.1649, 0, 0, 7.0469}, {-1.77636e-15, 0, 7.0469, -4, -4, -4, -3.0469, 4, -3.0469, 7.0469, 0, 0}, {3.89735, -2.97221, -3.89314, -0.447948, 4.33729, 5.68119, 0, 0, -5.23939, -3.4494, -1.36509, 3.45133}, {0.300503, 3.2348, -3.2348, -3.50419, 0, 0, 0.773493, -3.22084, -1.27452, 2.43019, -0.0139624, 4.50932}, {-5.23939, 4, -5.23939, 5.23939, 0, 0, 0, 0, 5.23939, -2.28255e-11, -4, -2.28255e-11}, {5.23939, 0, -1.75044e-16, -5.24506, 4, 5.23939, 0, 0, -5.23939, 0.00566839, -4, 2.28255e-11}, {3.95255, -0.362167, 0.362483, -0.482349, -3.10803, -0.479633, -1.12077, 1.12077, 2.46863, -2.34943, 2.34943, -2.35148}, {1.27685, 3.22605, 0.364333, -1.43581, -3.62766, 3.62766, -4.79345, -0.703234, 0.703234, 4.95241, 1.10484, -4.69522}, {-3.45053, 3.45053, 1.3657, -0.444357, 0.444357, -4.33924, 3.89489, -0.304504, 2.97354, 0, -3.59038, 0}, {-1.03322, 0, 2.9332, -2.44657, -2.9332, -2.9332, -0.388139, 2.9332, 0, 3.86792, 0, 0}, {-2.86482e-12, -2.9332, 2.09032, -3.2348, 0, -0.999254, 2.86466e-12, 2.9332, 1.94703, 3.2348, 0, -3.03809}, {3.99728, -3.99972, -4.00321, -8.14937, 0.83453, 0.841653, 4.15209, -0.425192, 3.16156, 0, 3.59038, 0}, {-3.65719, -3.66039, -3.65719, -1.79386, 1.79496, 1.79652, 3.65719, 0.0700075, 3.65719, 1.79386, 1.79543, -1.79652}, {0.32313, 3.2444, -3.2106, 3.54154, -2.30319, 5.58401, -2.14916, 1.30205, 3.28335, -1.71551, -2.24325, -5.65675}, {-3.89489, 2.97354, -2.82238, 0, 0, 4.03735, 0.444357, -4.33924, -0.86478, 3.45053, 1.3657, -0.350185}, {1.84375, -4.52327, -0.014292, 0.315792, 3.2348, -3.2348, -3.14489, 0, 0, 0.985347, 1.28847, 3.24909}, {-4.33924, -0.444357, -5.6776, 0, 0, 5.23939, 1.3657, -3.45053, -3.45246, 2.97354, 3.89489, 3.89067}, {5.23939, 0, 4.44089e-16, -3.45053, 3.45053, 1.3657, -5.68374, 0.444357, -4.33924, 3.89489, -3.89489, 2.97354}, {7.0469, 8.88178e-16, 0, 3.16371, 4.15492, -3.1649, -6.20947, -8.15492, -0.835098, -4.00114, 4, 4}, {-0.782485, -3.2348, -1.28032, 2.60358, 0, 0, -0.410568, 3.2348, -3.2348, -1.41052, 3.55036e-12, 4.51512}, {-4, 4, -4, -4.15492, 0.425481, 3.1649, 0, -3.59038, 0, 8.15492, -0.835098, 0.835098}, {-1.75292, -4.51512, 4.40936e-12, -1.18742, 1.28032, -3.2348, 0.578996, 3.2348, 3.2348, 2.36134, 0, 0}, {-4, -4, -4, -6.2118, 8.15492, 0.835098, 3.1649, -4.15492, 3.1649, 7.0469, 0, 0}, {0.304504, -2.97354, 3.89489, -3.45053, -1.3657, -3.45053, -0.444357, 4.33924, -0.444357, 3.59038, 0, 0}, {-0.968585, 2.9332, 1.64782, -3.80236, -2.9332, 0.915743, 1.28259, 0, -3.64114, 3.48835, 0, 1.07758}, {8.15492, 0.835098, -3.7826, -4, -4, 0.45685, 0, 0, 5.36117, -4.15492, 3.1649, -2.03542}, {-4, 4, -4, 0, -7.0469, 0, 7.0469, 0, 0, -3.0469, 3.0469, 4}, {-2.33946, 1.78605, 2.34209, 3.03792, -2.3193, 2.20139, -2.35172, -2.20459, -2.89092, 1.65325, 2.73783, -1.65256}, {2.60358, 0, 3.0632e-16, -1.03055, -1.28032, -3.2348, 0.410568, -3.2348, 3.2348, -1.98359, 4.51512, -4.40967e-12}, {-3.59038, 1.77636e-15, -1.11022e-16, 4, -4, 4, 0.425226, -4.15243, -3.16196, -0.834843, 8.15243, -0.83804}, {0, 0, -5.23939, -4, 1.54883e-11, -0.00566839, 4, -5.23123, 5.24506, 0, 5.23123, 0}, {-1.62732e-11, 1.54703e-11, 4, 5.23939, 0, 0, 0, -5.23939, 0, -5.23939, 5.23939, -4}, {4.72393, 2.32297, -6.20162, -2.81181, -4.23508, -5.55986, 1.34415, -1.34415, 7.48662, -3.25627, 3.25627, 4.27486}, {-3.1649, -4.15492, -3.16386, -0.835098, 8.15492, 6.20975, 4, -4, 4, 0, 0, -7.04589}, {2.10128, 3.1649, 4.15492, 3.73608, 0.835098, -8.15492, -0.419151, -4, 4, -5.41822, 0, 0}, {0, 0, -7.0469, 7.0469, 0, 0, -4.00114, 4, 4, -3.04575, -4, 3.0469}, {-3.89511, 3.89452, 2.96992, -5.24608, 0, 0, 5.68769, -0.444099, -4.33672, 3.45349, -3.45042, 1.3668}, {-7.0469, 0, 0, 4.00114, 4, 4, 3.04575, -4, 3.0469, 0, 0, -7.0469}, {-5.24608, 0, 0, 5.24608, -5.24018, 4, 2.32367e-11, -0.0025524, -4, 0, 5.24273, 0}, {4.44089e-16, 4.44089e-16, 4.03735, -4.51512, 4.40818e-12, -1.39475, 3.2348, 3.2348, -1.306, 1.28032, -3.2348, -1.33659}, {6.38334, 0.936482, -0.936482, -5.90226, 2.17282, 1.41756, -3.46093, -0.129456, -3.46093, 2.97985, -2.97985, 2.97985}, {-0.252976, 0.252976, -3.84336, 0.368915, 3.22147, 0.368915, -2.40103, -1.18935, 1.18935, 2.28509, -2.28509, 2.28509}, {-1.44735, 2.54109, 0.82519, -0.346604, -3.63529, 3.61884, -1.58915, 0.412839, -3.42177, 3.3831, 0.681367, -1.02226}, {-2.32365e-11, 0.0025524, 4, -5.24608, 0, 0, 0, 5.24273, 0, 5.24608, -5.24528, -4}, {-3.59357e-12, 3.68038, 1.41455, 2.62736e-12, -2.69097, 1.9177, -3.2348, 0.574024, -0.993189, 3.2348, -1.56344, -2.33906}, {2.74148, 0.0555531, 2.80173, -2.9202, -2.12061, -0.341431, -0.0977885, 3.03978, -0.0364189, 0.27651, -0.974727, -2.42388}, {4.00321, 3.99728, 3.99972, 0, 0, -3.59038, -0.841653, -8.14937, -0.83453, -3.16156, 4.15209, 0.425192}, {0, 8.88178e-16, -7.0469, 0, 7.04488, 0, -4, -3.99886, 4, 4, -3.04603, 3.0469}, {-4.40759e-12, 4.51512, -3.21766, 0, 0, 4.03735, -3.2348, -1.28032, 0.328292, 3.2348, -3.2348, -1.14798}, {-3.2348, -3.2348, 1.306, 4.40977e-12, 4.51512, -3.21766, 0, 0, 4.03735, 3.2348, -1.28032, -2.12568}, {1.28032, 0.265417, 3.2348, -4.51512, 1.06793, -3.90061e-12, 3.2348, 1.75796, -3.2348, 0, -3.09131, 0}, {-2.85306, -1.28668, -1.28504, 3.1184, -0.694894, -0.694008, 0.0152986, 3.82424, -1.42003, -0.280638, -1.84266, 3.39908}, {3.0469, 4, -3.0469, -7.0469, 0, 0, 4, -4, -4, 0, 0, 7.0469}, {1.29201, -3.25531, 0.810704, 0, 0, -2.6315, -4.51512, -3.75807e-12, 1.37723, 3.22311, 3.25531, 0.443571}, {-3.66502, 2.14914, 1.43616, 0.752328, 1.90198, -1.90298, 4.02391, -1.24183, 1.24643, -1.11122, -2.8093, -0.779603}, {8.15492, -3.3488, 0.835098, -4.15492, -1.54688, 3.1649, 0, 4.85752, 0, -4, 0.0381551, -4}, {-3.45053, 1.3657, -3.45053, 3.59038, 0, 0, 0.304504, 2.97354, 3.89489, -0.444357, -4.33924, -0.444357}, {-4, 3.0469, -3.0469, 0, -7.0469, 0, 4, 4, -4, 0, 0, 7.0469}, {-10.7068, 3.65991, -3.65991, 3.52345, -3.52345, -3.52345, 3.52345, 3.52345, 3.52345, 3.65991, -3.65991, 3.65991}, {0, -3.59038, 4.44089e-16, 3.1649, 0.425481, 4.15492, 0.835098, -0.835098, -8.15492, -4, 4, 4}, {-1.94171, 5.28363, -1.94171, 2.66708, -5.57073, -2.5723, 2.43635, -0.964293, 2.43635, -3.16172, 1.25139, 2.07766}, {0.099584, -1.28032, 3.2348, -1.88193, 4.51512, 4.40977e-12, 2.36134, 0, 0, -0.578997, -3.2348, -3.2348}, {-6.2118, -0.835098, -8.15492, 3.1649, -3.1649, 4.15492, 7.0469, 0, 0, -4, 4, 4}, {0.75324, 1.90144, -1.90334, 5.34316, -3.13319, -2.09374, -1.32234, 1.89318, 3.34138, -4.77406, -0.661432, 0.655698}, {4.44089e-16, 7.04488, 0, -4.15492, 3.164, -3.1649, 8.15492, -6.21002, -0.835098, -4, -3.99886, 4}, {-2.97354, -3.89986, -3.89489, 4.33924, 5.691, 0.444357, -1.3657, 3.45494, 3.45053, 0, -5.24608, 0}, {0, 0, -5.23939, 4, 5.24608, 5.23939, -4, -1.55241e-11, -1.5915e-11, 0, -5.24608, 0}, {-0.444357, 5.68374, 4.33924, 3.89489, -3.89489, -2.97354, 0, -5.23939, 0, -3.45053, 3.45053, -1.3657}, {3.52345, -3.52345, -3.52345, -3.52345, -3.52345, 3.52345, 3.52345, 3.52345, 3.52345, -3.52345, 3.52345, -3.52345}, {3.59038, 0, 0, 0.304504, -3.89489, -2.97354, -0.444357, 0.444357, 4.33924, -3.45053, 3.45053, -1.3657}, {5.23123, -8.88178e-16, 0, -5.23123, -5.23939, -4, -1.6327e-11, -1.54706e-11, 4, 0, 5.23939, 0}, {-1.36374, -3.44772, 3.44954, -2.97575, 3.89171, -0.30733, 4.3395, -0.443995, 0.448176, 0, 0, -3.59038}, {-3.16371, 4.15492, -3.1649, 4.00114, 4, 4, -7.0469, 0, 0, 6.20947, -8.15492, -0.835098}, {-3.52395, -3.52295, -3.52295, -3.52295, 3.52295, 3.52295, 3.52295, -3.52295, 3.52395, 3.52395, 3.52295, -3.52395}, {4, -4, -4.00114, -8.15492, 0.835098, -6.20947, 0, 0, 7.0469, 4.15492, 3.1649, 3.16371}, {-0.425481, 4.15492, 3.1649, 0.835098, -8.15492, 0.835098, -4, 4, -4, 3.59038, 0, 0}, {-1.79519, 1.79519, -1.79519, -1.79519, -1.79519, 1.79519, -0.0700075, -3.65719, -3.65719, 3.66039, 3.65719, 3.65719}, {4, 4, -4, 0, 0, 7.0469, -7.0469, 0, 0, 3.0469, -4, -3.0469}, {1.16094, -1.15703, 4.97097, -1.66567, -3.57722, 1.41703, -2.89698, 2.8944, -1.14655, 3.40171, 1.83985, -5.24145}, {-2.7042, -1.06842, -2.70002, 1.70166, -5.90879, -3.52267, 2.19866, 5.37974, 2.18568, -1.19612, 1.59748, 4.03701}, {4.33729, -5.67235, 0.447948, -1.36509, -3.44596, 3.4494, 0, 5.23123, 0, -2.97221, 3.88708, -3.89735}, {3.2348, -3.2348, -1.14797, 0, 0, 4.03735, 1.28032, 3.2348, -1.49462, -4.51512, -4.40977e-12, -1.39475}, {4, 4, 4, -0.835098, -0.835098, -8.15492, 0, -3.59038, 0, -3.1649, 0.425481, 4.15492}, {-3.1649, -3.1649, 4.15492, -7.0469, 0, 0, 4, 4, 4, 6.2118, -0.835098, -8.15492}, {0.724826, 0.724826, -6.59499, -3.21143, -3.21143, -3.21143, 3.7299, 0.139517, 3.7299, -1.24329, 2.34709, 6.07653}, {2.48661, 2.48661, 9.80643, -3.21143, -3.21143, -3.21143, -1.7154, 5.33149, 5.33149, 2.44023, -4.60667, -11.9265}, {-4.95125, 1.10332, 1.10192, -1.44818, -1.58249, 3.65892, 0.833328, -2.10815, -2.10546, 5.5661, 2.58731, -2.65538}, {0.836183, -2.10682, -2.10682, 4.11656, 1.00419, 1.00419, -1.14088, 2.87451, -0.715871, -3.81187, -1.77188, 1.8185}, {0.343882, -3.2462, -1.28483, 0.297233, 0.297493, 4.63286, 2.13498, 2.13685, 0.845752, -2.7761, 0.811861, -4.19379}, {5.55112e-17, 5.23939, 8.88178e-16, -3.44772, -3.45309, -1.36374, 3.89171, 3.89778, -2.97575, -0.443995, -5.68407, 4.3395}, {3.58725, -4.44089e-16, 0, -3.44752, -3.45053, -1.3657, -0.443969, -0.444357, 4.33924, 0.304238, 3.89489, -2.97354}, {3.65991, -3.65991, -3.65991, 3.52345, 3.52345, -3.52345, -3.52345, -3.52345, -3.52345, -3.65991, 3.65991, 10.7068}, {3.1649, -4.15492, -3.1649, 0, 0, -7.0469, -4, -4, 4, 0.835098, 8.15492, 6.2118}, {-4, -4, 4, 0.835098, 8.15492, -0.835098, 3.59038, 0, 0, -0.425481, -4.15492, -3.1649}, {-1.3476, -0.0112467, -3.55949, 1.85019, -3.24836, -1.05487, 1.92324, 3.24442, -0.189939, -2.42583, 0.0151799, 4.80429}, {1.17675, 3.24909, 1.28847, -0.315792, -3.2348, 3.2348, -3.14489, 0, 0, 2.28393, -0.014292, -4.52327}, {8.15492, -0.835098, -0.835098, -4, 4, 4, 0, 0, -3.59038, -4.15492, -3.1649, 0.425481}, {-4.15492, -3.1649, -3.1649, -4, 4, 4, 0, -7.0469, 0, 8.15492, 6.2118, -0.835098}, {0.137487, 7.18233, 7.18233, -1.79519, 1.79519, -1.79519, 3.52295, -3.52295, -3.52295, -1.86524, -5.45458, -1.86419}, {3.52295, -3.52295, -3.52295, -3.66043, -3.65939, -3.65939, -3.52345, -3.52345, 3.52345, 3.66094, 10.7058, 3.65888}, {1.67988, -1.68212, -5.18466, -2.30896, 2.30807, 0.915293, -1.39444, -3.85015, -1.52682, 2.02352, 3.2242, 5.7962}, {3.4516, -3.45027, -1.36825, -3.89922, 3.89484, -2.97306, -5.24608, 0, 0, 5.6937, -0.444568, 4.3413}, {1.94453e-16, 2.70417, 0, 3.25531, -0.177688, 3.22311, -3.25531, -0.557762, 1.29201, 3.62091e-12, -1.96872, -4.51512}, {3.09726e-12, 1.01994, -3.86266, -3.25531, -0.69454, 0.97832, 3.25531, -2.18133, -1.3721, -3.41346e-12, 1.85593, 4.25643}, {2.90521, -1.78203, -2.9082, 2.41571, 1.84427, 2.82665, -2.85063, 1.82369, -2.38912, -2.47029, -1.88594, 2.47066}, {-5.23939, 0, -8.88178e-16, 0, 0, 5.24273, 2.28278e-11, -4, -0.0025524, 5.23939, 4, -5.24018}, {-3.52295, 3.52295, 3.52295, 1.79545, 1.79493, -1.79545, 7.18233, -7.18233, 0.137487, -5.45483, 1.86445, -1.86498}, {-3.52295, 3.52295, 3.52295, -3.52395, -3.52295, -3.52295, -3.65939, 3.65939, -3.66043, 10.7063, -3.65939, 3.66043}, {-0.835098, 0.835098, 8.15492, 0, 3.59038, 0, 4, -4, -4, -3.1649, -0.425481, -4.15492}, {-7.0469, 5.55112e-16, 0, 4, -4, -4, -3.1649, 3.1649, -4.15492, 6.2118, 0.835098, 8.15492}, {0.662971, 0.664005, -4.25288, 1.65703, 1.65961, 0.655439, -2.91351, 2.32133, -1.15244, 0.59351, -4.64495, 4.74988}, {1.19438, -3.49493, 0, -2.76951, 1.19435, 0, 1.94164, -0.567827, 2.9332, -0.366511, 2.8684, -2.9332}, {2.36134, 1.0718e-17, 0, 0.671422, -3.2348, 3.2348, -0.342675, 3.2348, 1.28032, -2.69009, 3.55093e-12, -4.51512}, {-1.10548, 3.2348, 0, -1.25586, -3.2348, 0, 0.613756, 2.30645e-12, -2.9332, 1.74759, -2.30645e-12, 2.9332}, {3.2348, 0.120997, 3.2348, 0, -3.09131, 0, -3.2348, -0.551371, 1.28032, 3.95817e-12, 3.52168, -4.51512}, {-3.2348, 0.76173, -0.403199, 2.15323e-12, -1.17552, -2.45621, 3.2348, 2.34907, 0.378214, -2.17514e-12, -1.93527, 2.4812}, {-3.53969, 3.53969, 2.69627, -1.11299, 1.11299, -6.1991, 5.13509, 1.9118, -3.91153, -0.482412, -6.56449, 7.41436}, {4.72983, -3.60283, 2.31706, -1.62186, -5.81149, 1.62186, -3.59839, 2.74098, 3.59839, 0.490411, 6.67334, -7.53731}, {-4, 4, -4, 4, -4, -3.0469, 0, 7.0469, 0, 0, -7.0469, 7.0469}, {0, 0, 7.0469, 4, -3.0469, -4, -4, -4, 4, 0, 7.0469, -7.0469}, {1.26315, 3.1826, -0.407781, -4.48373, 0.0790768, 0.0790768, -1.01464, -2.55645, -2.55645, 4.23522, -0.705229, 2.88515}, {-1.01079, -2.55709, -2.55383, 1.69808, -0.95029, 4.29031, 5.49464, 2.47799, 2.47483, -6.18193, 1.02939, -4.21131}, {-1.79519, -1.79519, 1.79519, -3.65991, 3.65991, -3.65991, 1.79519, 1.79519, 1.79519, 3.65991, -3.65991, 0.0695263}, {-1.79519, -1.79519, 1.79519, 5.4551, -1.86472, 1.86472, 3.52345, -3.52345, -3.52345, -7.18336, 7.18336, -0.13646}, {0, -4.44089e-16, 3.59038, -8.15492, -0.835098, 0.835098, 4, 4, -4, 4.15492, -3.1649, -0.425481}, {4.15492, -3.1649, 3.1649, 4, 4, -4, 0, -7.0469, 0, -8.15492, 6.2118, 0.835098}, {4.18211, -0.841369, 0.841369, 1.63378, -1.11155, -4.12784, -0.96395, -2.43548, 2.43548, -4.85193, 4.3884, 0.850991}, {-2.9332, -0.654372, 2.78087, 0, 0.366146, -3.84129, 0, 2.94119, 1.57488, 2.9332, -2.65297, -0.514459}, {4.51512, -1.06793, 3.90044e-12, 0, -3.09131, 0, -1.28032, 0.871067, 3.2348, -3.2348, 3.28817, -3.2348}, {0, -0.430374, 4.51512, -2.9332, -0.109716, -2.9332, 0, 3.52168, -4.51512, 2.9332, -2.98159, 2.9332}, {4.19026, 0.820764, 0.814826, 1.21474, -3.06912, 2.16855, -0.936049, 2.36499, 2.36631, -4.46895, -0.116634, -5.34969}, {0.972372, 0.736781, -3.03724, -3.79781, 2.2903, -1.05943, 0.111338, -3.09792, 0.84769, 2.7141, 0.0708344, 3.24899}, {-2.55729, 1.01135, -2.55763, -2.08284, -1.24835, 3.15697, 1.89416, -5.27077, 1.90402, 2.74596, 5.50777, -2.50336}, {3.77679, -1.49465, 0.187718, 0.660093, 4.25334, 0.656376, -2.557, 1.01192, -2.55789, -1.87988, -3.77061, 1.7138}, {-5.23939, 0, -5.55112e-17, 3.4502, -1.36448, 3.45065, -3.90439, -2.97758, -3.8953, 5.69358, 4.34205, 0.444645}, {-4.44089e-16, 4.44089e-16, -3.59038, 3.4494, -1.36509, 3.45059, 0.447948, 4.33729, 0.444157, -3.89735, -2.97221, -0.304367}, {4.28053, 0.593056, -0.587914, -0.673906, 1.70372, -1.70733, 1.45255, -3.67222, -1.55938, -5.05918, 1.37545, 3.85462}, {0, 4.47576, 0.618208, 0, -4.47576, 1.81259, -2.9332, -2.90763, -0.707734, 2.9332, 2.90763, -1.72306}, {-1.27174, 3.21511, 1.36527, 0, 0, -2.4308, 4.51512, -3.70603e-12, -0.839751, -3.24338, -3.21511, 1.90528}, {0.947177, -0.947177, -4.14023, -3.0344, -2.20499, -1.201, 1.74832, -1.74832, 0.691975, 0.338905, 4.90048, 4.64925}, {1.90928, 0.579177, 2.90015, -2.97176, -1.29918, -0.341631, 1.26427, 3.63788, 0.209764, -0.201792, -2.91787, -2.76828}, {3.04112e-12, -1.63545, -4.51512, 0, -3.01876, 0, 3.2348, 2.35061, 1.28032, -3.2348, 2.3036, 3.2348}, {4.04958, 1.77038, 0.465536, -2.40427, -1.3066, 2.40427, -4.10736, 1.28953, -0.407754, 2.46205, -1.7533, -2.46205}, {0.835098, -0.835098, 8.15492, -4, 4, -4, 3.59038, 0, 0, -0.425481, -3.1649, -4.15492}, {3.1649, -3.1649, -4.15492, -4, 4, -4, 0, -7.0469, 0, 0.835098, 6.2118, 8.15492}, {-3.65991, 3.65991, 3.65991, 1.79519, 1.79519, -1.79519, 1.79519, -1.79519, 1.79519, 0.0695263, -3.65991, -3.65991}, {1.79519, -1.79519, 1.79519, 1.86472, -1.86472, -5.4551, -3.52345, -3.52345, -3.52345, -0.13646, 7.18336, 7.18336}, {3.0611, -1.07112, 2.10077e-12, -0.369018, 1.30083, 3.2348, 0.267075, 1.7536, -3.2348, -2.95915, -1.98331, -2.03061e-12}, {-1.28032, 0.716498, -3.2348, -3.2348, -0.619904, 3.2348, 0, -3.12276, 0, 4.51512, 3.02616, 3.09876e-12}, {-3.24675, 0.177221, -3.21463, 0, 2.70417, 0, -1.28505, -0.665307, 3.24278, 4.53179, -2.21609, -0.0281511}, {-1.03768, -0.786269, 3.24125, 3.76174, 0.864649, -0.0233676, 1.42117, -2.10543, -3.24363, -4.14523, 2.02705, 0.0257498}, {-3.65991, -3.65991, 3.65991, -3.52345, 3.52345, 3.52345, 3.52345, -3.52345, 3.52345, 3.65991, 3.65991, -10.7068}, {-1.02588, -1.02588, -4.04576, 5.15074, -1.89616, -1.23707, -2.74863, 4.29827, 1.25677, -1.37623, -1.37623, 4.02606}, {4, -4, -4, -3.1649, -4.15492, 3.1649, 0, 0, 7.0469, -0.835098, 8.15492, -6.2118}, {4.27497, -6.68514, -1.95466, -0.750905, 7.33275, 1.46136, -3.95428, 3.55351, -2.7068, 0.430212, -4.20112, 3.20009}, {-0.675958, 1.70428, -1.70576, 3.47227, -0.944013, -2.64554, 0.813742, 1.53558, 2.05346, -3.61005, -2.29584, 2.29785}, {-2.9332, 0.268765, -0.269, 0, 1.01807, 2.57142, 0, -3.15223, -0.435397, 2.9332, 1.86539, -1.86702}, {2.9332, -2.86386e-12, 0.906086, 0, 3.2348, -2.30525, 0, -3.2348, -1.73209, -2.9332, 2.86386e-12, 3.13126}, {-1.28032, -3.2348, -0.365321, -3.2348, 3.2348, 1.14798, 0, 0, 4.03735, 4.51512, -4.40815e-12, -4.82}, {4.32811, 0.737725, -1.71304, -3.72649, -3.72649, 1.47492, -0.518804, -0.518804, 4.72046, -0.0828155, 3.50757, -4.48234}, {-5.23939, -5.55112e-17, 0, -3.90017, -3.8953, -2.97758, 3.45213, 3.45065, -1.36448, 5.68742, 0.444645, 4.34205}, {3.45053, 3.45053, -1.3657, 0, -3.59038, 0, 0.444357, 0.444357, 4.33924, -3.89489, -0.304504, -2.97354}, {0, 1.06747e-17, -2.884, -3.22311, 3.25531, -0.327888, -1.29201, -3.25531, 0.417097, 4.51512, 3.75787e-12, 2.79479}, {-0.0130226, -3.25531, 1.20877, -0.260244, 3.25531, 1.50608, 3.12118, 2.59785e-12, -0.952039, -2.84791, -2.3704e-12, -1.76282}, {0.578997, 3.2348, 3.2348, 2.36134, 0, 0, -0.250249, -3.2348, 1.28032, -2.69009, -3.55036e-12, -4.51512}, {-1.12419, -3.2348, -0.186522, 0.812252, -2.04448e-12, -2.60004, -1.39607, 3.2348, -0.0801962, 1.708, 2.2542e-12, 2.86675}, {-3.93279, 1.55848, -1.3088, 1.97526, -0.782753, -1.97415, -1.50913, 5.11867, 1.50188, 3.46666, -5.8944, 1.78108}, {-0.47019, -4.32902, 0.47019, 0.867473, 1.07771, 2.72291, 1.97453, -0.781507, -1.97453, -2.37181, 4.03281, -1.21857}, {-3.45037, 1.36731, 3.44843, 0, 0, -5.23939, 3.89524, 2.97704, -3.89946, -0.444879, -4.34434, 5.69042}, {-3.45053, 1.3657, 3.45053, 3.59038, 0, 0, -0.444357, -4.33924, 0.444357, 0.304504, 2.97354, -3.89489}, {2.40563, -3.3686, -2.16577, -4.01552, 0.313534, -3.06173, -1.35813, -0.303573, 2.96446, 2.96803, 3.35864, 2.26304}, {0.444309, 1.73608, 4.33877, 0, 4.85752, 0, 3.45016, -2.1866, -1.36934, -3.89447, -4.407, -2.96943}, {-1.77354, -2.8259, -5.08017, -1.99992, 2.80049, 1.80052, -0.192763, -1.93544, 1.91528, 3.96622, 1.96086, 1.36437}, {3.41957, -0.149544, 3.15791, -3.35877, 2.12868, 1.33307, 6.03338, 1.03375, -2.39461, -6.09418, -3.0129, -2.09638}, {1.36731, -2.16592, -3.45037, 0, 4.85752, 0, -4.34434, 1.78399, -0.444879, 2.97704, -4.4756, 3.89524}, {-2.95631, -0.302739, 1.37126, 3.02503, 0.309776, 3.95804, 2.1672, -3.36845, -2.40376, -2.23591, 3.36142, -2.92554}, {2.31112, 1.19654, -5.83206, -1.28659, 2.03806, 3.24669, -3.3095, 0.144731, -3.05627, 2.28498, -3.37933, 5.64163}, {-1.96264, -1.84718, 0.269133, -1.79514, 2.79017, 1.99109, 5.26848, -3.1772, 1.46969, -1.5107, 2.23422, -3.72992}, {-0.60788, 3.25394, -0.100754, 4.36982, -1.029, 0.544673, 0.0459483, -1.94609, 2.48692, -3.80789, -0.278843, -2.93084}, {-2.10446, -2.10356, 0.831802, -1.45971, -1.45589, -3.94218, -2.09284, 3.1452, -1.24369, 5.65702, 0.414251, 4.35407}, {3.27119, 4.85191, 0.362578, 0.814367, -4.35925, 0.134979, -0.753128, 2.3313, 2.35448, -3.33243, -2.82396, -2.85204}, {-3.50419, 0, -8.88178e-16, 2.14843, -3.22874, 1.27672, -2.43779, 0.014006, -4.52341, 3.79356, 3.21473, 3.24669}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_tetrahedron_4) [
+ Array<double> [
+ + id : my_fem:jacobians:_tetrahedron_4
+ + size : 341
+ + nb_component : 1
+ + allocated size : 341
+ + memory size : 2.66KiByte
+ + values : {{0.00479073}, {0.00199542}, {0.00508286}, {0.00204347}, {0.00083906}, {0.00095268}, {0.00292548}, {0.00493659}, {0.00105059}, {0.00091729}, {0.00180199}, {0.000808556}, {0.00355095}, {0.00749049}, {0.00197348}, {0.00106177}, {0.00690231}, {0.00297989}, {0.000808006}, {0.0026847}, {0.00117185}, {0.00474423}, {0.00083918}, {0.00644814}, {0.00470655}, {0.00151785}, {0.00151785}, {0.00083906}, {0.00151591}, {0.00083918}, {0.00487222}, {0.00151892}, {0.00469074}, {0.000807775}, {0.00151892}, {0.00334996}, {0.00767187}, {0.00381537}, {0.00269174}, {0.00158543}, {0.00083906}, {0.00445593}, {0.0020418}, {0.00204272}, {0.00297957}, {0.00490403}, {0.00353679}, {0.00297957}, {0.00693536}, {0.000839299}, {0.002982}, {0.00359869}, {0.00246606}, {0.000800576}, {0.000839299}, {0.00083906}, {0.00152021}, {0.00375734}, {0.00151785}, {0.00372221}, {0.00255222}, {0.00083906}, {0.000952816}, {0.00298087}, {0.00204311}, {0.0037801}, {0.00363992}, {0.00249551}, {0.00382669}, {0.0020549}, {0.00422323}, {0.00083906}, {0.00460922}, {0.00348647}, {0.000952544}, {0.00386563}, {0.00134104}, {0.00252173}, {0.00151892}, {0.00151785}, {0.00426036}, {0.00793308}, {0.00820365}, {0.00385292}, {0.00151785}, {0.00860188}, {0.00151785}, {0.00083906}, {0.00383935}, {0.00327077}, {0.00361116}, {0.00679806}, {0.00083906}, {0.00336058}, {0.00695467}, {0.0026847}, {0.00385292}, {0.000917159}, {0.00158651}, {0.00152021}, {0.00204498}, {0.00158671}, {0.00297957}, {0.00483251}, {0.00083906}, {0.00645464}, {0.0037801}, {0.00472318}, {0.00353524}, {0.00151688}, {0.00483251}, {0.00421987}, {0.0020418}, {0.00523002}, {0.00282642}, {0.00380534}, {0.00581509}, {0.00158671}, {0.00548144}, {0.0020418}, {0.00365422}, {0.00297867}, {0.00383935}, {0.00204311}, {0.00151892}, {0.0020418}, {0.00083906}, {0.00695993}, {0.00426911}, {0.000952544}, {0.00380007}, {0.00640143}, {0.00595062}, {0.00180012}, {0.00470655}, {0.00297737}, {0.00432043}, {0.00408022}, {0.00151785}, {0.00394217}, {0.00095268}, {0.0020392}, {0.00491487}, {0.000807891}, {0.00673925}, {0.00158661}, {0.00158671}, {0.00511093}, {0.000808006}, {0.00297989}, {0.00158671}, {0.00158543}, {0.00297989}, {0.000839299}, {0.00282642}, {0.00297957}, {0.000807775}, {0.00743876}, {0.00520896}, {0.000807775}, {0.00083906}, {0.00204272}, {0.00327077}, {0.00151785}, {0.00151785}, {0.00550306}, {0.00283408}, {0.00297957}, {0.00500828}, {0.00435075}, {0.00158651}, {0.00353524}, {0.00207381}, {0.00264971}, {0.00361055}, {0.0020418}, {0.0020418}, {0.000807775}, {0.0043829}, {0.00158543}, {0.00483251}, {0.000807775}, {0.00297957}, {0.00403452}, {0.00106177}, {0.00083906}, {0.00339716}, {0.0043829}, {0.00158661}, {0.00152021}, {0.00151785}, {0.00078511}, {0.000807891}, {0.00105059}, {0.00083906}, {0.00204038}, {0.00083906}, {0.00151494}, {0.00282642}, {0.00212821}, {0.005658}, {0.0043455}, {0.00151494}, {0.00474239}, {0.00744101}, {0.00158651}, {0.000839299}, {0.00282642}, {0.00282642}, {0.00369139}, {0.00530618}, {0.00083906}, {0.00430907}, {0.00540547}, {0.00117185}, {0.00297957}, {0.00083906}, {0.000917028}, {0.00158543}, {0.00289174}, {0.00483251}, {0.000807775}, {0.00370776}, {0.000808006}, {0.0020392}, {0.00151591}, {0.0020418}, {0.000952544}, {0.00297957}, {0.00152021}, {0.002982}, {0.000807775}, {0.00095268}, {0.000807775}, {0.00158543}, {0.00353524}, {0.00083906}, {0.00243234}, {0.00260951}, {0.0020459}, {0.00282642}, {0.00158543}, {0.000807775}, {0.00197474}, {0.00100612}, {0.00334194}, {0.00487991}, {0.00481554}, {0.00204347}, {0.00298217}, {0.000917028}, {0.000807775}, {0.00158543}, {0.00339935}, {0.00361055}, {0.00158543}, {0.000807775}, {0.00180012}, {0.000917159}, {0.00304689}, {0.00203823}, {0.00419327}, {0.00444812}, {0.00321724}, {0.00151688}, {0.00180012}, {0.000917159}, {0.00158543}, {0.000807775}, {0.00425176}, {0.0068851}, {0.00483251}, {0.00743876}, {0.00369139}, {0.00671734}, {0.000948173}, {0.000932706}, {0.00083906}, {0.00083906}, {0.00402163}, {0.0027552}, {0.00353262}, {0.00179986}, {0.00158543}, {0.000807775}, {0.00289277}, {0.00478507}, {0.00369139}, {0.00407095}, {0.002979}, {0.00490513}, {0.00275294}, {0.00402124}, {0.00204048}, {0.00298091}, {0.00413525}, {0.00522266}, {0.00472318}, {0.00402975}, {0.00676786}, {0.0037801}, {0.00496655}, {0.00158543}, {0.000807775}, {0.00353262}, {0.00179986}, {0.00557565}, {0.00365422}, {0.00420433}, {0.0045964}, {0.000917028}, {0.00243872}, {0.000807775}, {0.001568}, {0.00602516}, {0.0074155}, {0.00435075}, {0.00282642}, {0.00275892}, {0.00204048}, {0.00297957}, {0.0039318}, {0.00623354}, {0.00483251}, {0.00761117}, {0.00356241}, {0.00520686}, {0.0020394}, {0.00297957}, {0.00289006}, {0.00220255}, {0.00347634}, {0.00226248}, {0.00219973}, {0.00292886}, {0.00233772}, {0.00353589}, {0.00497258}, {0.00334717}, {0.00371176}, {0.00326057}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_triangle_3.verified b/test/test_fe_engine/test_fe_engine_precomputation_triangle_3.verified
new file mode 100644
index 000000000..4d0cde7fa
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_triangle_3.verified
@@ -0,0 +1,109 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 2
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 2
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_point_1) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_point_1
+ + size : 4
+ + nb_component : 1
+ + allocated size : 2000
+ + memory size : 7.81KiByte
+ + values : {{0}, {1}, {2}, {3}}
+ ]
+ ]
+ (not_ghost:_segment_2) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_segment_2
+ + size : 8
+ + nb_component : 2
+ + allocated size : 2000
+ + memory size : 15.62KiByte
+ + values : {{0, 4}, {4, 1}, {1, 5}, {5, 2}, {2, 6}, {6, 3}, {3, 7}, {7, 0}}
+ ]
+ ]
+ (not_ghost:_triangle_3) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_triangle_3
+ + size : 16
+ + nb_component : 3
+ + allocated size : 2000
+ + memory size : 23.44KiByte
+ + values : {{3, 9, 6}, {0, 12, 7}, {2, 10, 5}, {1, 11, 4}, {7, 8, 9}, {6, 9, 8}, {6, 8, 10}, {7, 12, 8}, {5, 10, 8}, {4, 8, 12}, {4, 11, 8}, {5, 8, 11}, {0, 4, 12}, {3, 7, 9}, {1, 5, 11}, {2, 6, 10}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_triangle_3)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_triangle_3) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_lagrange_triangle_3
+ + size : 16
+ + nb_component : 3
+ + allocated size : 16
+ + memory size : 384.00Byte
+ + values : {{0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}, {0.333333, 0.333333, 0.333333}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_triangle_3) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_lagrange_triangle_3
+ + size : 16
+ + nb_component : 6
+ + allocated size : 16
+ + memory size : 768.00Byte
+ + values : {{-2, 2, 0, -4, 2, 2}, {-2, -2, 4, 0, -2, 2}, {2, 2, -4, 0, 2, -2}, {2, -2, 0, 4, -2, -2}, {-2, -2, 2, -2, 1.04929e-11, 4}, {2, 2, -4, 1.08926e-11, 2, -2}, {-2, 2, -2, -2, 4, -1.08926e-11}, {-2, 2, -1.04929e-11, -4, 2, 2}, {2, -2, 8.43547e-12, 4, -2, -2}, {2, -2, 2, 2, -4, 8.03579e-12}, {-2, -2, 4, -8.03579e-12, -2, 2}, {2, 2, -2, 2, -8.43547e-12, -4}, {-2, -2, 2, -2, 0, 4}, {-2, 2, -2, -2, 4, 0}, {2, -2, 2, 2, -4, 0}, {2, 2, -2, 2, 0, -4}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_triangle_3) [
+ Array<double> [
+ + id : my_fem:jacobians:_triangle_3
+ + size : 16
+ + nb_component : 1
+ + allocated size : 16
+ + memory size : 128.00Byte
+ + values : {{0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}, {0.0625}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_fe_engine_precomputation_triangle_6.verified b/test/test_fe_engine/test_fe_engine_precomputation_triangle_6.verified
new file mode 100644
index 000000000..77a1efbba
--- /dev/null
+++ b/test/test_fe_engine/test_fe_engine_precomputation_triangle_6.verified
@@ -0,0 +1,109 @@
+FEEngineTemplate [
+ + parent [
+ FEEngine [
+ + id : my_fem
+ + element dimension : 2
+ + mesh [
+ Mesh [
+ + id : mesh
+ + spatial dimension : 2
+ + nodes [
+ 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}}
+ ]
+ + connectivities [
+ ElementTypeMapArray<unsigned int> [
+ (not_ghost:_point_1) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_point_1
+ + size : 4
+ + nb_component : 1
+ + allocated size : 2000
+ + memory size : 7.81KiByte
+ + values : {{0}, {1}, {2}, {3}}
+ ]
+ ]
+ (not_ghost:_segment_3) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_segment_3
+ + size : 8
+ + nb_component : 3
+ + allocated size : 2000
+ + memory size : 23.44KiByte
+ + values : {{0, 4, 5}, {4, 1, 6}, {1, 7, 8}, {7, 2, 9}, {2, 10, 11}, {10, 3, 12}, {3, 13, 14}, {13, 0, 15}}
+ ]
+ ]
+ (not_ghost:_triangle_6) [
+ Array<unsigned int> [
+ + id : mesh:connectivities:_triangle_6
+ + size : 16
+ + nb_component : 6
+ + allocated size : 2000
+ + memory size : 46.88KiByte
+ + values : {{3, 17, 10, 21, 22, 12}, {0, 20, 13, 23, 24, 15}, {2, 18, 7, 25, 26, 9}, {1, 19, 4, 27, 28, 6}, {13, 16, 17, 29, 30, 31}, {10, 17, 16, 22, 30, 32}, {10, 16, 18, 32, 33, 34}, {13, 20, 16, 24, 35, 29}, {7, 18, 16, 26, 33, 36}, {4, 16, 20, 37, 35, 38}, {4, 19, 16, 28, 39, 37}, {7, 16, 19, 36, 39, 40}, {0, 4, 20, 5, 38, 23}, {3, 13, 17, 14, 31, 21}, {1, 7, 19, 8, 40, 27}, {2, 10, 18, 11, 34, 25}}
+ ]
+ ]
+ ]
+ ]
+ GroupManager [
+ ]
+ ]
+ ]
+ ]
+ ]
+ + shape functions [
+ Shapes Lagrange [
+ Shapes [
+ ElementTypeMap<akantu::Matrix<double>> [
+ (not_ghost:_triangle_6)
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_triangle_6) [
+ Array<double> [
+ + id : my_fem:shapes_generic:_itp_lagrange_triangle_6
+ + size : 48
+ + nb_component : 6
+ + allocated size : 48
+ + memory size : 2.25KiByte
+ + values : {{0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}, {0.222222, -0.111111, -0.111111, 0.444444, 0.111111, 0.444444}, {-0.111111, 0.222222, -0.111111, 0.444444, 0.444444, 0.111111}, {-0.111111, -0.111111, 0.222222, 0.111111, 0.444444, 0.444444}}
+ ]
+ ]
+ ]
+ ElementTypeMapArray<double> [
+ (not_ghost:_itp_lagrange_triangle_6) [
+ Array<double> [
+ + id : my_fem:shapes_derivatives_generic:_itp_lagrange_triangle_6
+ + size : 48
+ + nb_component : 12
+ + allocated size : 48
+ + memory size : 4.50KiByte
+ + values : {{-3.33333, 3.33333, 0, 1.33333, -0.666667, -0.666667, -1.33333, -9.33333, 1.33333, -1.33333, 4, 6.66667}, {0.666667, -0.666667, 2.96059e-15, -6.66667, -0.666667, -0.666667, -5.33333, 2.66667, 5.33333, 2.66667, -7.40149e-16, 2.66667}, {0.666667, -0.666667, 0, 1.33333, 3.33333, 3.33333, -1.33333, -1.33333, 1.33333, -9.33333, -4, 6.66667}, {-3.33333, -3.33333, -1.33333, 0, 0.666667, -0.666667, 9.33333, -1.33333, 1.33333, 1.33333, -6.66667, 4}, {0.666667, 0.666667, 6.66667, 0, 0.666667, -0.666667, -2.66667, -5.33333, -2.66667, 5.33333, -2.66667, 4.44089e-16}, {0.666667, 0.666667, -1.33333, 0, -3.33333, 3.33333, 1.33333, -1.33333, 9.33333, 1.33333, -6.66667, -4}, {3.33333, 3.33333, 1.33333, 0, -0.666667, 0.666667, -9.33333, 1.33333, -1.33333, -1.33333, 6.66667, -4}, {-0.666667, -0.666667, -6.66667, -2.96059e-15, -0.666667, 0.666667, 2.66667, 5.33333, 2.66667, -5.33333, 2.66667, 7.40149e-16}, {-0.666667, -0.666667, 1.33333, 0, 3.33333, -3.33333, -1.33333, 1.33333, -9.33333, -1.33333, 6.66667, 4}, {3.33333, -3.33333, 0, -1.33333, 0.666667, 0.666667, 1.33333, 9.33333, -1.33333, 1.33333, -4, -6.66667}, {-0.666667, 0.666667, 0, 6.66667, 0.666667, 0.666667, 5.33333, -2.66667, -5.33333, -2.66667, -4.44089e-16, -2.66667}, {-0.666667, 0.666667, 0, -1.33333, -3.33333, -3.33333, 1.33333, 1.33333, -1.33333, 9.33333, 4, -6.66667}, {-3.33333, -3.33333, -0.666667, 0.666667, -3.49779e-12, -1.33333, 4, -6.66667, 1.33333, 1.33333, -1.33333, 9.33333}, {0.666667, 0.666667, 3.33333, -3.33333, -3.49779e-12, -1.33333, -4, -6.66667, 1.33333, 9.33333, -1.33333, 1.33333}, {0.666667, 0.666667, -0.666667, 0.666667, 1.74912e-11, 6.66667, -6.99581e-12, -2.66667, 5.33333, -2.66667, -5.33333, -2.66667}, {3.33333, 3.33333, 1.33333, -3.63028e-12, -0.666667, 0.666667, -9.33333, 1.33333, -1.33333, -1.33333, 6.66667, -4}, {-0.666667, -0.666667, -6.66667, 1.81499e-11, -0.666667, 0.666667, 2.66667, 5.33333, 2.66667, -5.33333, 2.66667, -7.26041e-12}, {-0.666667, -0.666667, 1.33333, -3.63087e-12, 3.33333, -3.33333, -1.33333, 1.33333, -9.33333, -1.33333, 6.66667, 4}, {-3.33333, 3.33333, 0.666667, 0.666667, -1.33333, 3.63087e-12, -6.66667, -4, 1.33333, -1.33333, 9.33333, 1.33333}, {0.666667, -0.666667, -3.33333, -3.33333, -1.33333, 3.63087e-12, -6.66667, 4, 9.33333, -1.33333, 1.33333, 1.33333}, {0.666667, -0.666667, 0.666667, 0.666667, 6.66667, -1.81544e-11, -2.66667, 7.26108e-12, -2.66667, -5.33333, -2.66667, 5.33333}, {-3.33333, 3.33333, 3.49705e-12, 1.33333, -0.666667, -0.666667, -1.33333, -9.33333, 1.33333, -1.33333, 4, 6.66667}, {0.666667, -0.666667, -1.74868e-11, -6.66667, -0.666667, -0.666667, -5.33333, 2.66667, 5.33333, 2.66667, 6.99515e-12, 2.66667}, {0.666667, -0.666667, 3.49765e-12, 1.33333, 3.33333, 3.33333, -1.33333, -1.33333, 1.33333, -9.33333, -4, 6.66667}, {3.33333, -3.33333, -2.81197e-12, -1.33333, 0.666667, 0.666667, 1.33333, 9.33333, -1.33333, 1.33333, -4, -6.66667}, {-0.666667, 0.666667, 1.40554e-11, 6.66667, 0.666667, 0.666667, 5.33333, -2.66667, -5.33333, -2.66667, -5.62261e-12, -2.66667}, {-0.666667, 0.666667, -2.81197e-12, -1.33333, -3.33333, -3.33333, 1.33333, 1.33333, -1.33333, 9.33333, 4, -6.66667}, {3.33333, -3.33333, -0.666667, -0.666667, 1.33333, -2.67845e-12, 6.66667, 4, -1.33333, 1.33333, -9.33333, -1.33333}, {-0.666667, 0.666667, 3.33333, 3.33333, 1.33333, -2.67904e-12, 6.66667, -4, -9.33333, 1.33333, -1.33333, -1.33333}, {-0.666667, 0.666667, -0.666667, -0.666667, -6.66667, 1.33937e-11, 2.66667, -5.35683e-12, 2.66667, 5.33333, 2.66667, -5.33333}, {-3.33333, -3.33333, -1.33333, 2.67815e-12, 0.666667, -0.666667, 9.33333, -1.33333, 1.33333, 1.33333, -6.66667, 4}, {0.666667, 0.666667, 6.66667, -1.33952e-11, 0.666667, -0.666667, -2.66667, -5.33333, -2.66667, 5.33333, -2.66667, 5.35853e-12}, {0.666667, 0.666667, -1.33333, 2.67904e-12, -3.33333, 3.33333, 1.33333, -1.33333, 9.33333, 1.33333, -6.66667, -4}, {3.33333, 3.33333, 0.666667, -0.666667, 2.81182e-12, 1.33333, -4, 6.66667, -1.33333, -1.33333, 1.33333, -9.33333}, {-0.666667, -0.666667, -3.33333, 3.33333, 2.81182e-12, 1.33333, 4, 6.66667, -1.33333, -9.33333, 1.33333, -1.33333}, {-0.666667, -0.666667, 0.666667, -0.666667, -1.40584e-11, -6.66667, 5.62269e-12, 2.66667, -5.33333, 2.66667, 5.33333, 2.66667}, {-3.33333, -3.33333, -0.666667, 0.666667, 0, -1.33333, 4, -6.66667, 1.33333, 1.33333, -1.33333, 9.33333}, {0.666667, 0.666667, 3.33333, -3.33333, 0, -1.33333, -4, -6.66667, 1.33333, 9.33333, -1.33333, 1.33333}, {0.666667, 0.666667, -0.666667, 0.666667, 0, 6.66667, 6.66134e-16, -2.66667, 5.33333, -2.66667, -5.33333, -2.66667}, {-3.33333, 3.33333, 0.666667, 0.666667, -1.33333, 0, -6.66667, -4, 1.33333, -1.33333, 9.33333, 1.33333}, {0.666667, -0.666667, -3.33333, -3.33333, -1.33333, 0, -6.66667, 4, 9.33333, -1.33333, 1.33333, 1.33333}, {0.666667, -0.666667, 0.666667, 0.666667, 6.66667, 0, -2.66667, -6.66134e-16, -2.66667, -5.33333, -2.66667, 5.33333}, {3.33333, -3.33333, -0.666667, -0.666667, 1.33333, 0, 6.66667, 4, -1.33333, 1.33333, -9.33333, -1.33333}, {-0.666667, 0.666667, 3.33333, 3.33333, 1.33333, 0, 6.66667, -4, -9.33333, 1.33333, -1.33333, -1.33333}, {-0.666667, 0.666667, -0.666667, -0.666667, -6.66667, 0, 2.66667, 6.66134e-16, 2.66667, 5.33333, 2.66667, -5.33333}, {3.33333, 3.33333, 0.666667, -0.666667, 0, 1.33333, -4, 6.66667, -1.33333, -1.33333, 1.33333, -9.33333}, {-0.666667, -0.666667, -3.33333, 3.33333, 0, 1.33333, 4, 6.66667, -1.33333, -9.33333, 1.33333, -1.33333}, {-0.666667, -0.666667, 0.666667, -0.666667, 0, -6.66667, -6.66134e-16, 2.66667, -5.33333, 2.66667, 5.33333, 2.66667}}
+ ]
+ ]
+ ]
+ ]
+ ]
+ + integrator [
+ Integrator [
+ ElementTypeMapArray<double> [
+ (not_ghost:_triangle_6) [
+ Array<double> [
+ + id : my_fem:jacobians:_triangle_6
+ + size : 48
+ + nb_component : 1
+ + allocated size : 48
+ + memory size : 384.00Byte
+ + values : {{0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}, {0.0208333}}
+ ]
+ ]
+ ]
+ ]
+ ]
+]
+
diff --git a/test/test_fe_engine/test_gradient.cc b/test/test_fe_engine/test_gradient.cc
new file mode 100644
index 000000000..15254a435
--- /dev/null
+++ b/test/test_fe_engine/test_gradient.cc
@@ -0,0 +1,138 @@
+/**
+ * @file test_gradient.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Jun 17 2011
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @section DESCRIPTION
+ *
+ * This code is computing the gradient of a linear field and check that it gives
+ * a constant result. It also compute the gradient the coordinates of the mesh
+ * and check that it gives the identity
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "fe_engine.hh"
+#include "shape_lagrange.hh"
+#include "integrator_gauss.hh"
+/* -------------------------------------------------------------------------- */
+#include <cstdlib>
+#include <iostream>
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+ akantu::initialize(argc, argv);
+ debug::setDebugLevel(dblTest);
+
+ const ElementType type = TYPE;
+ UInt dim = ElementClass<type>::getSpatialDimension();
+
+ Real eps = 1e-12;
+ std::cout << "Epsilon : " << eps << std::endl;
+
+ Mesh my_mesh(dim);
+
+ std::stringstream meshfilename; meshfilename << type << ".msh";
+ my_mesh.read(meshfilename.str());
+
+ FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
+
+ fem->initShapeFunctions();
+
+ Real alpha[2][3] = {{13, 23, 31},
+ {11, 7, 5}};
+
+ /// create the 2 component field
+ const Array<Real> & position = fem->getMesh().getNodes();
+ Array<Real> const_val(fem->getMesh().getNbNodes(), 2, "const_val");
+
+ UInt nb_element = my_mesh.getNbElement(type);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(type) * nb_element;
+
+ Array<Real> grad_on_quad(nb_quadrature_points, 2 * dim, "grad_on_quad");
+ for (UInt i = 0; i < const_val.getSize(); ++i) {
+ const_val(i, 0) = 0;
+ const_val(i, 1) = 0;
+
+ for (UInt d = 0; d < dim; ++d) {
+ const_val(i, 0) += alpha[0][d] * position(i, d);
+ const_val(i, 1) += alpha[1][d] * position(i, d);
+ }
+ }
+
+ /// compute the gradient
+ fem->gradientOnIntegrationPoints(const_val, grad_on_quad, 2, type);
+
+ std::cout << "Linear array on nodes : " << const_val << std::endl;
+ std::cout << "Gradient on quad : " <<grad_on_quad << std::endl;
+
+ /// check the results
+ Array<Real>::matrix_iterator it = grad_on_quad.begin(2,dim);
+ Array<Real>::matrix_iterator it_end = grad_on_quad.end(2,dim);
+ for (;it != it_end; ++it) {
+ for (UInt d = 0; d < dim; ++d) {
+ Matrix<Real> & grad = *it;
+ if(!(std::abs(grad(0, d) - alpha[0][d]) < eps) ||
+ !(std::abs(grad(1, d) - alpha[1][d]) < eps)) {
+ std::cout << "Error gradient is not correct "
+ << (*it)(0, d) << " " << alpha[0][d] << " (" << std::abs((*it)(0, d) - alpha[0][d]) << ")"
+ << " - "
+ << (*it)(1, d) << " " << alpha[1][d] << " (" << std::abs((*it)(1, d) - alpha[1][d]) << ")"
+ << " - " << d << std::endl;
+ std::cout << *it << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+
+ // compute gradient of coordinates
+ Array<Real> grad_coord_on_quad(nb_quadrature_points, dim * dim, "grad_coord_on_quad");
+ fem->gradientOnIntegrationPoints(my_mesh.getNodes(), grad_coord_on_quad, my_mesh.getSpatialDimension(), type);
+
+ std::cout << "Node positions : " << my_mesh.getNodes() << std::endl;
+ std::cout << "Gradient of nodes : " << grad_coord_on_quad << std::endl;
+
+ Array<Real>::matrix_iterator itp = grad_coord_on_quad.begin(dim, dim);
+ Array<Real>::matrix_iterator itp_end = grad_coord_on_quad.end(dim, dim);
+
+ for (;itp != itp_end; ++itp) {
+ for (UInt i = 0; i < dim; ++i) {
+ for (UInt j = 0; j < dim; ++j) {
+ if(!(std::abs((*itp)(i,j) - (i == j)) < eps)) {
+ std::cout << *itp << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+ }
+
+ delete fem;
+ finalize();
+
+ return EXIT_SUCCESS;
+}
diff --git a/test/test_fe_engine/test_gradient_hexahedron_20.verified b/test/test_fe_engine/test_gradient_hexahedron_20.verified
new file mode 100644
index 000000000..d7efdffdb
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_hexahedron_20.verified
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000..02a682dee
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_hexahedron_8.verified
@@ -0,0 +1,37 @@
+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_quadrangle_4.verified b/test/test_fe_engine/test_gradient_quadrangle_4.verified
new file mode 100644
index 000000000..8d57f4bb7
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_quadrangle_4.verified
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000..5c9b70533
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_quadrangle_8.verified
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000..a5962d09c
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_segment_2.verified
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000..db3a56115
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_segment_3.verified
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000..a224c8483
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_tetrahedron_10.verified
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000..e0220c9bf
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_tetrahedron_4.verified
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000..d86386d19
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_triangle_3.verified
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000..508650c8c
--- /dev/null
+++ b/test/test_fe_engine/test_gradient_triangle_6.verified
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000..f8c76af0b
--- /dev/null
+++ b/test/test_fe_engine/test_integrate.cc
@@ -0,0 +1,103 @@
+/**
+ * @file test_integrate.cc
+ *
+ * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Jun 17 2011
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "fe_engine.hh"
+#include "shape_lagrange.hh"
+#include "integrator_gauss.hh"
+/* -------------------------------------------------------------------------- */
+#include <cstdlib>
+#include <iostream>
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+ akantu::initialize(argc, argv);
+
+ debug::setDebugLevel(dblTest);
+
+ const ElementType type = TYPE;
+ UInt dim = ElementClass<type>::getSpatialDimension();
+
+ Real eps = 3e-13;
+ std::cout << "Epsilon : " << eps << std::endl;
+
+ Mesh my_mesh(dim);
+
+ std::stringstream meshfilename; meshfilename << type << ".msh";
+ my_mesh.read(meshfilename.str());
+
+ FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
+
+ fem->initShapeFunctions();
+
+ UInt nb_element = my_mesh.getNbElement(type);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(type) * nb_element;
+
+ Array<Real> const_val(fem->getMesh().getNbNodes(), 2, "const_val");
+ Array<Real> val_on_quad(nb_quadrature_points, 2 , "val_on_quad");
+
+ for (UInt i = 0; i < const_val.getSize(); ++i) {
+ const_val.storage()[i * 2 + 0] = 1.;
+ const_val.storage()[i * 2 + 1] = 2.;
+ }
+
+ //interpolate function on quadrature points
+ fem->interpolateOnIntegrationPoints(const_val, val_on_quad, 2, type);
+
+ //integrate function on elements
+ akantu::Array<akantu::Real> int_val_on_elem(nb_element, 2, "int_val_on_elem");
+ fem->integrate(val_on_quad, int_val_on_elem, 2, type);
+
+ // get global integration value
+ Real value[2] = {0,0};
+ std::cout << "Val on quads : " << val_on_quad << std::endl;
+ std::cout << "Integral on elements : " << int_val_on_elem << std::endl;
+
+ for (UInt i = 0; i < fem->getMesh().getNbElement(type); ++i) {
+ value[0] += int_val_on_elem.storage()[2*i];
+ value[1] += int_val_on_elem.storage()[2*i+1];
+ }
+
+ std::cout << "integral on the mesh of 1 is " << value[0] << " and of 2 is " << value[1] << std::endl;
+
+ delete fem;
+ finalize();
+
+ if(!(std::abs(value[0] - 1.) < eps && std::abs(value[1] - 2.) < eps)) {
+ std::cout << "|1 - " << value[0] << "| = " << std::abs(value[0] - 1.) << std::endl
+ << "|2 - " << value[1] << "| = " << std::abs(value[1] - 2.) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/test/test_fe_engine/test_integrate_hexahedron_20.verified b/test/test_fe_engine/test_integrate_hexahedron_20.verified
new file mode 100644
index 000000000..b75566bbc
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_hexahedron_20.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 216
+ + nb_component : 2
+ + allocated size : 216
+ + memory size : 3.38KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 8
+ + nb_component : 2
+ + allocated size : 8
+ + memory size : 128.00Byte
+ + values : {{0.125, 0.25}, {0.125, 0.25}, {0.125, 0.25}, {0.125, 0.25}, {0.125, 0.25}, {0.125, 0.25}, {0.125, 0.25}, {0.125, 0.25}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_integrate_hexahedron_8.verified b/test/test_fe_engine/test_integrate_hexahedron_8.verified
new file mode 100644
index 000000000..09a19f8bb
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_hexahedron_8.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 512
+ + nb_component : 2
+ + allocated size : 512
+ + memory size : 8.00KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 64
+ + nb_component : 2
+ + allocated size : 64
+ + memory size : 1.00KiByte
+ + values : {{0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}, {0.015625, 0.03125}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_integrate_quadrangle_4.verified b/test/test_fe_engine/test_integrate_quadrangle_4.verified
new file mode 100644
index 000000000..968833786
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_quadrangle_4.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 16
+ + nb_component : 2
+ + allocated size : 16
+ + memory size : 256.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 4
+ + nb_component : 2
+ + allocated size : 4
+ + memory size : 64.00Byte
+ + values : {{0.25, 0.5}, {0.25, 0.5}, {0.25, 0.5}, {0.25, 0.5}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_integrate_quadrangle_8.verified b/test/test_fe_engine/test_integrate_quadrangle_8.verified
new file mode 100644
index 000000000..8a93aea44
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_quadrangle_8.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 36
+ + nb_component : 2
+ + allocated size : 36
+ + memory size : 576.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 4
+ + nb_component : 2
+ + allocated size : 4
+ + memory size : 64.00Byte
+ + values : {{0.25, 0.5}, {0.25, 0.5}, {0.25, 0.5}, {0.25, 0.5}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_integrate_segment_2.verified b/test/test_fe_engine/test_integrate_segment_2.verified
new file mode 100644
index 000000000..ee6869199
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_segment_2.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 10
+ + nb_component : 2
+ + allocated size : 10
+ + memory size : 160.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 10
+ + nb_component : 2
+ + allocated size : 10
+ + memory size : 160.00Byte
+ + values : {{0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_integrate_segment_3.verified b/test/test_fe_engine/test_integrate_segment_3.verified
new file mode 100644
index 000000000..eb7225f4c
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_segment_3.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 20
+ + nb_component : 2
+ + allocated size : 20
+ + memory size : 320.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 10
+ + nb_component : 2
+ + allocated size : 10
+ + memory size : 160.00Byte
+ + values : {{0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}, {0.1, 0.2}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_integrate_tetrahedron_10.verified b/test/test_fe_engine/test_integrate_tetrahedron_10.verified
new file mode 100644
index 000000000..e0956ae97
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_tetrahedron_10.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 1364
+ + nb_component : 2
+ + allocated size : 1364
+ + memory size : 21.31KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 341
+ + nb_component : 2
+ + allocated size : 341
+ + memory size : 5.33KiByte
+ + values : {{0.00479073, 0.00958147}, {0.00199542, 0.00399084}, {0.00508286, 0.0101657}, {0.00204347, 0.00408693}, {0.00083906, 0.00167812}, {0.00095268, 0.00190536}, {0.00292548, 0.00585097}, {0.00493659, 0.00987319}, {0.00105059, 0.00210117}, {0.00091729, 0.00183458}, {0.00180199, 0.00360397}, {0.000808556, 0.00161711}, {0.00355095, 0.0071019}, {0.00749049, 0.014981}, {0.00197348, 0.00394695}, {0.00106177, 0.00212353}, {0.00690231, 0.0138046}, {0.00297989, 0.00595978}, {0.000808006, 0.00161601}, {0.0026847, 0.0053694}, {0.00117185, 0.00234371}, {0.00474423, 0.00948846}, {0.00083918, 0.00167836}, {0.00644814, 0.0128963}, {0.00470655, 0.0094131}, {0.00151785, 0.00303569}, {0.00151785, 0.00303569}, {0.00083906, 0.00167812}, {0.00151591, 0.00303182}, {0.00083918, 0.00167836}, {0.00487222, 0.00974443}, {0.00151892, 0.00303784}, {0.00469074, 0.00938147}, {0.000807775, 0.00161555}, {0.00151892, 0.00303784}, {0.00334996, 0.00669992}, {0.00767187, 0.0153437}, {0.00381537, 0.00763074}, {0.00269174, 0.00538349}, {0.00158543, 0.00317086}, {0.00083906, 0.00167812}, {0.00445593, 0.00891186}, {0.0020418, 0.0040836}, {0.00204272, 0.00408544}, {0.00297957, 0.00595913}, {0.00490403, 0.00980807}, {0.00353679, 0.00707358}, {0.00297957, 0.00595913}, {0.00693536, 0.0138707}, {0.000839299, 0.0016786}, {0.002982, 0.005964}, {0.00359869, 0.00719737}, {0.00246606, 0.00493213}, {0.000800576, 0.00160115}, {0.000839299, 0.0016786}, {0.00083906, 0.00167812}, {0.00152021, 0.00304042}, {0.00375734, 0.00751467}, {0.00151785, 0.00303569}, {0.00372221, 0.00744441}, {0.00255222, 0.00510444}, {0.00083906, 0.00167812}, {0.000952816, 0.00190563}, {0.00298087, 0.00596174}, {0.00204311, 0.00408621}, {0.0037801, 0.00756021}, {0.00363992, 0.00727985}, {0.00249551, 0.00499102}, {0.00382669, 0.00765337}, {0.0020549, 0.0041098}, {0.00422323, 0.00844645}, {0.00083906, 0.00167812}, {0.00460922, 0.00921845}, {0.00348647, 0.00697294}, {0.000952544, 0.00190509}, {0.00386563, 0.00773126}, {0.00134104, 0.00268207}, {0.00252173, 0.00504346}, {0.00151892, 0.00303784}, {0.00151785, 0.00303569}, {0.00426036, 0.00852072}, {0.00793308, 0.0158662}, {0.00820365, 0.0164073}, {0.00385292, 0.00770583}, {0.00151785, 0.00303569}, {0.00860188, 0.0172038}, {0.00151785, 0.00303569}, {0.00083906, 0.00167812}, {0.00383935, 0.00767869}, {0.00327077, 0.00654153}, {0.00361116, 0.00722233}, {0.00679806, 0.0135961}, {0.00083906, 0.00167812}, {0.00336058, 0.00672115}, {0.00695467, 0.0139093}, {0.0026847, 0.0053694}, {0.00385292, 0.00770583}, {0.000917159, 0.00183432}, {0.00158651, 0.00317302}, {0.00152021, 0.00304042}, {0.00204498, 0.00408997}, {0.00158671, 0.00317341}, {0.00297957, 0.00595913}, {0.00483251, 0.00966502}, {0.00083906, 0.00167812}, {0.00645464, 0.0129093}, {0.0037801, 0.00756021}, {0.00472318, 0.00944637}, {0.00353524, 0.00707049}, {0.00151688, 0.00303376}, {0.00483251, 0.00966502}, {0.00421987, 0.00843975}, {0.0020418, 0.0040836}, {0.00523002, 0.01046}, {0.00282642, 0.00565283}, {0.00380534, 0.00761068}, {0.00581509, 0.0116302}, {0.00158671, 0.00317341}, {0.00548144, 0.0109629}, {0.0020418, 0.0040836}, {0.00365422, 0.00730843}, {0.00297867, 0.00595734}, {0.00383935, 0.00767869}, {0.00204311, 0.00408621}, {0.00151892, 0.00303784}, {0.0020418, 0.0040836}, {0.00083906, 0.00167812}, {0.00695993, 0.0139199}, {0.00426911, 0.00853822}, {0.000952544, 0.00190509}, {0.00380007, 0.00760013}, {0.00640143, 0.0128029}, {0.00595062, 0.0119012}, {0.00180012, 0.00360024}, {0.00470655, 0.0094131}, {0.00297737, 0.00595474}, {0.00432043, 0.00864087}, {0.00408022, 0.00816045}, {0.00151785, 0.00303569}, {0.00394217, 0.00788434}, {0.00095268, 0.00190536}, {0.0020392, 0.00407839}, {0.00491487, 0.00982975}, {0.000807891, 0.00161578}, {0.00673925, 0.0134785}, {0.00158661, 0.00317322}, {0.00158671, 0.00317341}, {0.00511093, 0.0102219}, {0.000808006, 0.00161601}, {0.00297989, 0.00595978}, {0.00158671, 0.00317341}, {0.00158543, 0.00317086}, {0.00297989, 0.00595978}, {0.000839299, 0.0016786}, {0.00282642, 0.00565283}, {0.00297957, 0.00595913}, {0.000807775, 0.00161555}, {0.00743876, 0.0148775}, {0.00520896, 0.0104179}, {0.000807775, 0.00161555}, {0.00083906, 0.00167812}, {0.00204272, 0.00408544}, {0.00327077, 0.00654153}, {0.00151785, 0.00303569}, {0.00151785, 0.00303569}, {0.00550306, 0.0110061}, {0.00283408, 0.00566817}, {0.00297957, 0.00595913}, {0.00500828, 0.0100166}, {0.00435075, 0.0087015}, {0.00158651, 0.00317302}, {0.00353524, 0.00707049}, {0.00207381, 0.00414761}, {0.00264971, 0.00529942}, {0.00361055, 0.00722109}, {0.0020418, 0.0040836}, {0.0020418, 0.0040836}, {0.000807775, 0.00161555}, {0.0043829, 0.0087658}, {0.00158543, 0.00317086}, {0.00483251, 0.00966502}, {0.000807775, 0.00161555}, {0.00297957, 0.00595913}, {0.00403452, 0.00806904}, {0.00106177, 0.00212353}, {0.00083906, 0.00167812}, {0.00339716, 0.00679432}, {0.0043829, 0.0087658}, {0.00158661, 0.00317322}, {0.00152021, 0.00304042}, {0.00151785, 0.00303569}, {0.00078511, 0.00157022}, {0.000807891, 0.00161578}, {0.00105059, 0.00210117}, {0.00083906, 0.00167812}, {0.00204038, 0.00408077}, {0.00083906, 0.00167812}, {0.00151494, 0.00302989}, {0.00282642, 0.00565283}, {0.00212821, 0.00425641}, {0.005658, 0.011316}, {0.0043455, 0.008691}, {0.00151494, 0.00302989}, {0.00474239, 0.00948477}, {0.00744101, 0.014882}, {0.00158651, 0.00317302}, {0.000839299, 0.0016786}, {0.00282642, 0.00565283}, {0.00282642, 0.00565283}, {0.00369139, 0.00738277}, {0.00530618, 0.0106124}, {0.00083906, 0.00167812}, {0.00430907, 0.00861815}, {0.00540547, 0.0108109}, {0.00117185, 0.00234371}, {0.00297957, 0.00595913}, {0.00083906, 0.00167812}, {0.000917028, 0.00183406}, {0.00158543, 0.00317086}, {0.00289174, 0.00578349}, {0.00483251, 0.00966502}, {0.000807775, 0.00161555}, {0.00370776, 0.00741553}, {0.000808006, 0.00161601}, {0.0020392, 0.00407839}, {0.00151591, 0.00303182}, {0.0020418, 0.0040836}, {0.000952544, 0.00190509}, {0.00297957, 0.00595913}, {0.00152021, 0.00304042}, {0.002982, 0.005964}, {0.000807775, 0.00161555}, {0.00095268, 0.00190536}, {0.000807775, 0.00161555}, {0.00158543, 0.00317086}, {0.00353524, 0.00707049}, {0.00083906, 0.00167812}, {0.00243234, 0.00486469}, {0.00260951, 0.00521902}, {0.0020459, 0.00409181}, {0.00282642, 0.00565283}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00197474, 0.00394947}, {0.00100612, 0.00201225}, {0.00334194, 0.00668388}, {0.00487991, 0.00975982}, {0.00481554, 0.00963108}, {0.00204347, 0.00408693}, {0.00298217, 0.00596434}, {0.000917028, 0.00183406}, {0.000807775, 0.00161555}, {0.00158543, 0.00317086}, {0.00339935, 0.0067987}, {0.00361055, 0.00722109}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00180012, 0.00360024}, {0.000917159, 0.00183432}, {0.00304689, 0.00609378}, {0.00203823, 0.00407646}, {0.00419327, 0.00838654}, {0.00444812, 0.00889624}, {0.00321724, 0.00643448}, {0.00151688, 0.00303376}, {0.00180012, 0.00360024}, {0.000917159, 0.00183432}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00425176, 0.00850352}, {0.0068851, 0.0137702}, {0.00483251, 0.00966502}, {0.00743876, 0.0148775}, {0.00369139, 0.00738277}, {0.00671734, 0.0134347}, {0.000948173, 0.00189635}, {0.000932706, 0.00186541}, {0.00083906, 0.00167812}, {0.00083906, 0.00167812}, {0.00402163, 0.00804325}, {0.0027552, 0.0055104}, {0.00353262, 0.00706524}, {0.00179986, 0.00359973}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00289277, 0.00578554}, {0.00478507, 0.00957013}, {0.00369139, 0.00738277}, {0.00407095, 0.00814191}, {0.002979, 0.005958}, {0.00490513, 0.00981027}, {0.00275294, 0.00550588}, {0.00402124, 0.00804249}, {0.00204048, 0.00408096}, {0.00298091, 0.00596181}, {0.00413525, 0.0082705}, {0.00522266, 0.0104453}, {0.00472318, 0.00944637}, {0.00402975, 0.0080595}, {0.00676786, 0.0135357}, {0.0037801, 0.00756021}, {0.00496655, 0.00993309}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00353262, 0.00706524}, {0.00179986, 0.00359973}, {0.00557565, 0.0111513}, {0.00365422, 0.00730843}, {0.00420433, 0.00840865}, {0.0045964, 0.00919281}, {0.000917028, 0.00183406}, {0.00243872, 0.00487744}, {0.000807775, 0.00161555}, {0.001568, 0.00313599}, {0.00602516, 0.0120503}, {0.0074155, 0.014831}, {0.00435075, 0.0087015}, {0.00282642, 0.00565283}, {0.00275892, 0.00551784}, {0.00204048, 0.00408096}, {0.00297957, 0.00595913}, {0.0039318, 0.00786361}, {0.00623354, 0.0124671}, {0.00483251, 0.00966502}, {0.00761117, 0.0152223}, {0.00356241, 0.00712483}, {0.00520686, 0.0104137}, {0.0020394, 0.00407881}, {0.00297957, 0.00595913}, {0.00289006, 0.00578011}, {0.00220255, 0.0044051}, {0.00347634, 0.00695268}, {0.00226248, 0.00452496}, {0.00219973, 0.00439946}, {0.00292886, 0.00585771}, {0.00233772, 0.00467544}, {0.00353589, 0.00707177}, {0.00497258, 0.00994515}, {0.00334717, 0.00669435}, {0.00371176, 0.00742352}, {0.00326057, 0.00652115}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_integrate_tetrahedron_4.verified b/test/test_fe_engine/test_integrate_tetrahedron_4.verified
new file mode 100644
index 000000000..d50525bf2
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_tetrahedron_4.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 341
+ + nb_component : 2
+ + allocated size : 341
+ + memory size : 5.33KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 341
+ + nb_component : 2
+ + allocated size : 341
+ + memory size : 5.33KiByte
+ + values : {{0.00479073, 0.00958147}, {0.00199542, 0.00399084}, {0.00508286, 0.0101657}, {0.00204347, 0.00408693}, {0.00083906, 0.00167812}, {0.00095268, 0.00190536}, {0.00292548, 0.00585097}, {0.00493659, 0.00987319}, {0.00105059, 0.00210117}, {0.00091729, 0.00183458}, {0.00180199, 0.00360397}, {0.000808556, 0.00161711}, {0.00355095, 0.0071019}, {0.00749049, 0.014981}, {0.00197348, 0.00394695}, {0.00106177, 0.00212353}, {0.00690231, 0.0138046}, {0.00297989, 0.00595978}, {0.000808006, 0.00161601}, {0.0026847, 0.0053694}, {0.00117185, 0.00234371}, {0.00474423, 0.00948846}, {0.00083918, 0.00167836}, {0.00644814, 0.0128963}, {0.00470655, 0.0094131}, {0.00151785, 0.00303569}, {0.00151785, 0.00303569}, {0.00083906, 0.00167812}, {0.00151591, 0.00303182}, {0.00083918, 0.00167836}, {0.00487222, 0.00974443}, {0.00151892, 0.00303784}, {0.00469074, 0.00938147}, {0.000807775, 0.00161555}, {0.00151892, 0.00303784}, {0.00334996, 0.00669992}, {0.00767187, 0.0153437}, {0.00381537, 0.00763074}, {0.00269174, 0.00538349}, {0.00158543, 0.00317086}, {0.00083906, 0.00167812}, {0.00445593, 0.00891186}, {0.0020418, 0.0040836}, {0.00204272, 0.00408544}, {0.00297957, 0.00595913}, {0.00490403, 0.00980807}, {0.00353679, 0.00707358}, {0.00297957, 0.00595913}, {0.00693536, 0.0138707}, {0.000839299, 0.0016786}, {0.002982, 0.005964}, {0.00359869, 0.00719737}, {0.00246606, 0.00493213}, {0.000800576, 0.00160115}, {0.000839299, 0.0016786}, {0.00083906, 0.00167812}, {0.00152021, 0.00304042}, {0.00375734, 0.00751467}, {0.00151785, 0.00303569}, {0.00372221, 0.00744441}, {0.00255222, 0.00510444}, {0.00083906, 0.00167812}, {0.000952816, 0.00190563}, {0.00298087, 0.00596174}, {0.00204311, 0.00408621}, {0.0037801, 0.00756021}, {0.00363992, 0.00727985}, {0.00249551, 0.00499102}, {0.00382669, 0.00765337}, {0.0020549, 0.0041098}, {0.00422323, 0.00844645}, {0.00083906, 0.00167812}, {0.00460922, 0.00921845}, {0.00348647, 0.00697294}, {0.000952544, 0.00190509}, {0.00386563, 0.00773126}, {0.00134104, 0.00268207}, {0.00252173, 0.00504346}, {0.00151892, 0.00303784}, {0.00151785, 0.00303569}, {0.00426036, 0.00852072}, {0.00793308, 0.0158662}, {0.00820365, 0.0164073}, {0.00385292, 0.00770583}, {0.00151785, 0.00303569}, {0.00860188, 0.0172038}, {0.00151785, 0.00303569}, {0.00083906, 0.00167812}, {0.00383935, 0.00767869}, {0.00327077, 0.00654153}, {0.00361116, 0.00722233}, {0.00679806, 0.0135961}, {0.00083906, 0.00167812}, {0.00336058, 0.00672115}, {0.00695467, 0.0139093}, {0.0026847, 0.0053694}, {0.00385292, 0.00770583}, {0.000917159, 0.00183432}, {0.00158651, 0.00317302}, {0.00152021, 0.00304042}, {0.00204498, 0.00408997}, {0.00158671, 0.00317341}, {0.00297957, 0.00595913}, {0.00483251, 0.00966502}, {0.00083906, 0.00167812}, {0.00645464, 0.0129093}, {0.0037801, 0.00756021}, {0.00472318, 0.00944637}, {0.00353524, 0.00707049}, {0.00151688, 0.00303376}, {0.00483251, 0.00966502}, {0.00421987, 0.00843975}, {0.0020418, 0.0040836}, {0.00523002, 0.01046}, {0.00282642, 0.00565283}, {0.00380534, 0.00761068}, {0.00581509, 0.0116302}, {0.00158671, 0.00317341}, {0.00548144, 0.0109629}, {0.0020418, 0.0040836}, {0.00365422, 0.00730843}, {0.00297867, 0.00595734}, {0.00383935, 0.00767869}, {0.00204311, 0.00408621}, {0.00151892, 0.00303784}, {0.0020418, 0.0040836}, {0.00083906, 0.00167812}, {0.00695993, 0.0139199}, {0.00426911, 0.00853822}, {0.000952544, 0.00190509}, {0.00380007, 0.00760013}, {0.00640143, 0.0128029}, {0.00595062, 0.0119012}, {0.00180012, 0.00360024}, {0.00470655, 0.0094131}, {0.00297737, 0.00595474}, {0.00432043, 0.00864087}, {0.00408022, 0.00816045}, {0.00151785, 0.00303569}, {0.00394217, 0.00788434}, {0.00095268, 0.00190536}, {0.0020392, 0.00407839}, {0.00491487, 0.00982975}, {0.000807891, 0.00161578}, {0.00673925, 0.0134785}, {0.00158661, 0.00317322}, {0.00158671, 0.00317341}, {0.00511093, 0.0102219}, {0.000808006, 0.00161601}, {0.00297989, 0.00595978}, {0.00158671, 0.00317341}, {0.00158543, 0.00317086}, {0.00297989, 0.00595978}, {0.000839299, 0.0016786}, {0.00282642, 0.00565283}, {0.00297957, 0.00595913}, {0.000807775, 0.00161555}, {0.00743876, 0.0148775}, {0.00520896, 0.0104179}, {0.000807775, 0.00161555}, {0.00083906, 0.00167812}, {0.00204272, 0.00408544}, {0.00327077, 0.00654153}, {0.00151785, 0.00303569}, {0.00151785, 0.00303569}, {0.00550306, 0.0110061}, {0.00283408, 0.00566817}, {0.00297957, 0.00595913}, {0.00500828, 0.0100166}, {0.00435075, 0.0087015}, {0.00158651, 0.00317302}, {0.00353524, 0.00707049}, {0.00207381, 0.00414761}, {0.00264971, 0.00529942}, {0.00361055, 0.00722109}, {0.0020418, 0.0040836}, {0.0020418, 0.0040836}, {0.000807775, 0.00161555}, {0.0043829, 0.0087658}, {0.00158543, 0.00317086}, {0.00483251, 0.00966502}, {0.000807775, 0.00161555}, {0.00297957, 0.00595913}, {0.00403452, 0.00806904}, {0.00106177, 0.00212353}, {0.00083906, 0.00167812}, {0.00339716, 0.00679432}, {0.0043829, 0.0087658}, {0.00158661, 0.00317322}, {0.00152021, 0.00304042}, {0.00151785, 0.00303569}, {0.00078511, 0.00157022}, {0.000807891, 0.00161578}, {0.00105059, 0.00210117}, {0.00083906, 0.00167812}, {0.00204038, 0.00408077}, {0.00083906, 0.00167812}, {0.00151494, 0.00302989}, {0.00282642, 0.00565283}, {0.00212821, 0.00425641}, {0.005658, 0.011316}, {0.0043455, 0.008691}, {0.00151494, 0.00302989}, {0.00474239, 0.00948477}, {0.00744101, 0.014882}, {0.00158651, 0.00317302}, {0.000839299, 0.0016786}, {0.00282642, 0.00565283}, {0.00282642, 0.00565283}, {0.00369139, 0.00738277}, {0.00530618, 0.0106124}, {0.00083906, 0.00167812}, {0.00430907, 0.00861815}, {0.00540547, 0.0108109}, {0.00117185, 0.00234371}, {0.00297957, 0.00595913}, {0.00083906, 0.00167812}, {0.000917028, 0.00183406}, {0.00158543, 0.00317086}, {0.00289174, 0.00578349}, {0.00483251, 0.00966502}, {0.000807775, 0.00161555}, {0.00370776, 0.00741553}, {0.000808006, 0.00161601}, {0.0020392, 0.00407839}, {0.00151591, 0.00303182}, {0.0020418, 0.0040836}, {0.000952544, 0.00190509}, {0.00297957, 0.00595913}, {0.00152021, 0.00304042}, {0.002982, 0.005964}, {0.000807775, 0.00161555}, {0.00095268, 0.00190536}, {0.000807775, 0.00161555}, {0.00158543, 0.00317086}, {0.00353524, 0.00707049}, {0.00083906, 0.00167812}, {0.00243234, 0.00486469}, {0.00260951, 0.00521902}, {0.0020459, 0.00409181}, {0.00282642, 0.00565283}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00197474, 0.00394947}, {0.00100612, 0.00201225}, {0.00334194, 0.00668388}, {0.00487991, 0.00975982}, {0.00481554, 0.00963108}, {0.00204347, 0.00408693}, {0.00298217, 0.00596434}, {0.000917028, 0.00183406}, {0.000807775, 0.00161555}, {0.00158543, 0.00317086}, {0.00339935, 0.0067987}, {0.00361055, 0.00722109}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00180012, 0.00360024}, {0.000917159, 0.00183432}, {0.00304689, 0.00609378}, {0.00203823, 0.00407646}, {0.00419327, 0.00838654}, {0.00444812, 0.00889624}, {0.00321724, 0.00643448}, {0.00151688, 0.00303376}, {0.00180012, 0.00360024}, {0.000917159, 0.00183432}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00425176, 0.00850352}, {0.0068851, 0.0137702}, {0.00483251, 0.00966502}, {0.00743876, 0.0148775}, {0.00369139, 0.00738277}, {0.00671734, 0.0134347}, {0.000948173, 0.00189635}, {0.000932706, 0.00186541}, {0.00083906, 0.00167812}, {0.00083906, 0.00167812}, {0.00402163, 0.00804325}, {0.0027552, 0.0055104}, {0.00353262, 0.00706524}, {0.00179986, 0.00359973}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00289277, 0.00578554}, {0.00478507, 0.00957013}, {0.00369139, 0.00738277}, {0.00407095, 0.00814191}, {0.002979, 0.005958}, {0.00490513, 0.00981027}, {0.00275294, 0.00550588}, {0.00402124, 0.00804249}, {0.00204048, 0.00408096}, {0.00298091, 0.00596181}, {0.00413525, 0.0082705}, {0.00522266, 0.0104453}, {0.00472318, 0.00944637}, {0.00402975, 0.0080595}, {0.00676786, 0.0135357}, {0.0037801, 0.00756021}, {0.00496655, 0.00993309}, {0.00158543, 0.00317086}, {0.000807775, 0.00161555}, {0.00353262, 0.00706524}, {0.00179986, 0.00359973}, {0.00557565, 0.0111513}, {0.00365422, 0.00730843}, {0.00420433, 0.00840865}, {0.0045964, 0.00919281}, {0.000917028, 0.00183406}, {0.00243872, 0.00487744}, {0.000807775, 0.00161555}, {0.001568, 0.00313599}, {0.00602516, 0.0120503}, {0.0074155, 0.014831}, {0.00435075, 0.0087015}, {0.00282642, 0.00565283}, {0.00275892, 0.00551784}, {0.00204048, 0.00408096}, {0.00297957, 0.00595913}, {0.0039318, 0.00786361}, {0.00623354, 0.0124671}, {0.00483251, 0.00966502}, {0.00761117, 0.0152223}, {0.00356241, 0.00712483}, {0.00520686, 0.0104137}, {0.0020394, 0.00407881}, {0.00297957, 0.00595913}, {0.00289006, 0.00578011}, {0.00220255, 0.0044051}, {0.00347634, 0.00695268}, {0.00226248, 0.00452496}, {0.00219973, 0.00439946}, {0.00292886, 0.00585771}, {0.00233772, 0.00467544}, {0.00353589, 0.00707177}, {0.00497258, 0.00994515}, {0.00334717, 0.00669435}, {0.00371176, 0.00742352}, {0.00326057, 0.00652115}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_integrate_triangle_3.verified b/test/test_fe_engine/test_integrate_triangle_3.verified
new file mode 100644
index 000000000..da8f8eb2f
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_triangle_3.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 16
+ + nb_component : 2
+ + allocated size : 16
+ + memory size : 256.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 16
+ + nb_component : 2
+ + allocated size : 16
+ + memory size : 256.00Byte
+ + values : {{0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_integrate_triangle_6.verified b/test/test_fe_engine/test_integrate_triangle_6.verified
new file mode 100644
index 000000000..90595a2c4
--- /dev/null
+++ b/test/test_fe_engine/test_integrate_triangle_6.verified
@@ -0,0 +1,20 @@
+Epsilon : 3e-13
+Val on quads : Array<double> [
+ + id : val_on_quad
+ + size : 48
+ + nb_component : 2
+ + allocated size : 48
+ + memory size : 768.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Integral on elements : Array<double> [
+ + id : int_val_on_elem
+ + size : 16
+ + nb_component : 2
+ + allocated size : 16
+ + memory size : 256.00Byte
+ + values : {{0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}, {0.0625, 0.125}}
+]
+
+integral on the mesh of 1 is 1 and of 2 is 2
diff --git a/test/test_fe_engine/test_interpolate.cc b/test/test_fe_engine/test_interpolate.cc
new file mode 100644
index 000000000..1974446e3
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate.cc
@@ -0,0 +1,91 @@
+/**
+ * @file test_interpolate.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date creation: Fri Jun 17 2011
+ * @date last modification: Thu Jun 05 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "fe_engine.hh"
+#include "shape_lagrange.hh"
+#include "integrator_gauss.hh"
+/* -------------------------------------------------------------------------- */
+#include <cstdlib>
+#include <iostream>
+/* -------------------------------------------------------------------------- */
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+ akantu::initialize(argc, argv);
+
+ debug::setDebugLevel(dblTest);
+ const ElementType type = TYPE;
+ UInt dim = ElementClass<type>::getSpatialDimension();
+
+ Real eps = 3e-13;
+ std::cout << "Epsilon : " << eps << std::endl;
+
+ Mesh my_mesh(dim);
+
+ std::stringstream meshfilename; meshfilename << type << ".msh";
+ my_mesh.read(meshfilename.str());
+
+ FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
+
+ fem->initShapeFunctions();
+
+ Array<Real> const_val(fem->getMesh().getNbNodes(), 2, "const_val");
+
+ UInt nb_element = my_mesh.getNbElement(type);
+ UInt nb_quadrature_points = fem->getNbIntegrationPoints(type) * nb_element;
+
+ Array<Real> val_on_quad(nb_quadrature_points, 2, "val_on_quad");
+
+ for (UInt i = 0; i < const_val.getSize(); ++i) {
+ const_val.storage()[i * 2 + 0] = 1.;
+ const_val.storage()[i * 2 + 1] = 2.;
+ }
+
+ fem->interpolateOnIntegrationPoints(const_val, val_on_quad, 2, type);
+
+ std::cout << "Interpolation of array : " << const_val << std::endl;
+ std::cout << "Gives on quads : " << val_on_quad << std::endl;
+
+ // interpolate coordinates
+ Array<Real> coord_on_quad(nb_quadrature_points, my_mesh.getSpatialDimension(), "coord_on_quad");
+
+ fem->interpolateOnIntegrationPoints(my_mesh.getNodes(),
+ coord_on_quad,
+ my_mesh.getSpatialDimension(),
+ type);
+ std::cout << "Interpolations of node coordinates : " << my_mesh.getNodes() << std::endl;
+ std::cout << "Gives : " << coord_on_quad << std::endl;
+
+ delete fem;
+ finalize();
+
+ return EXIT_SUCCESS;
+}
diff --git a/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc b/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc
new file mode 100644
index 000000000..8aed67a1f
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_bernoulli_beam_2.cc
@@ -0,0 +1,132 @@
+/**
+ * @file test_interpolate_bernoulli_beam_2.cc
+ *
+ * @author Fabian Barras <fabian.barras@epfl.ch>
+ *
+ * @date Fri Jul 15 19:41:58 2011
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <cstdlib>
+#include <fstream>
+/* -------------------------------------------------------------------------- */
+#include "aka_common.hh"
+#include "fe_engine.hh"
+#include "integrator_gauss.hh"
+#include "shape_linked.hh"
+#include "mesh.hh"
+#include "mesh_io.hh"
+#include "mesh_io_msh.hh"
+#include "fe_engine_template.hh"
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char *argv[]){
+
+
+ Mesh beams(2);
+
+
+/* -------------------------------------------------------------------------- */
+ // Defining the mesh
+
+ Array<Real> & nodes = const_cast<Array<Real> &>(beams.getNodes());
+ nodes.resize(4);
+
+ beams.addConnectivityType(_bernoulli_beam_2);
+ Array<UInt> & connectivity = const_cast<Array<UInt> &>(beams.getConnectivity(_bernoulli_beam_2));
+ connectivity.resize(3);
+
+ for(UInt i=0; i<4; ++i) {
+
+ nodes(i,0)=(i+1)*2;
+ nodes(i,1)=1;
+ }
+ for(UInt i=0; i<3; ++i) {
+
+ connectivity(i,0)=i;
+ connectivity(i,1)=i+1;
+ }
+ akantu::MeshIOMSH mesh_io;
+ mesh_io.write("b_beam_2.msh", beams);
+
+/* -------------------------------------------------------------------------- */
+ // Interpolation
+
+
+ FEEngineTemplate<IntegratorGauss,ShapeLinked> *fem = new FEEngineTemplate<IntegratorGauss,ShapeLinked>(beams,2);
+
+ fem->initShapeFunctions();
+
+ Array<Real> displ_on_nodes(4,3);
+ Array<Real> displ_on_quad(0,3);
+
+ for(UInt i=0; i<4; ++i) {
+
+ displ_on_nodes(i,0)=(i+1)*2; // Definition of the displacement
+ displ_on_nodes(i,1)=0;
+ displ_on_nodes(i,2)=0;
+ }
+
+ fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
+ displ_on_quad,
+ 3,_not_ghost,
+ NULL, false,
+ 0, 0, 0);
+
+ fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
+ displ_on_quad,
+ 3, _not_ghost,
+ NULL, false,
+ 1, 1, 1);
+
+ fem->getShapeFunctions(). interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
+ displ_on_quad,
+ 3, _not_ghost,
+ NULL, true,
+ 2, 2, 1);
+
+ fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
+ displ_on_quad,
+ 3, _not_ghost,
+ NULL, false,
+ 3, 2, 3);
+
+ fem->getShapeFunctions().interpolateOnControlPoints<_bernoulli_beam_2>(displ_on_nodes,
+ displ_on_quad,
+ 3, _not_ghost,
+ NULL, true,
+ 4, 3, 3);
+
+ Real * don= displ_on_nodes.storage();
+ Real * doq= displ_on_quad.storage();
+
+ std::ofstream my_file("out.txt");
+ my_file << don << std::endl;
+ my_file << doq << std::endl;
+
+ return EXIT_SUCCESS;
+
+}
diff --git a/test/test_fe_engine/test_interpolate_bernoulli_beam_2.verified b/test/test_fe_engine/test_interpolate_bernoulli_beam_2.verified
new file mode 100644
index 000000000..e69de29bb
diff --git a/test/test_fe_engine/test_interpolate_hexahedron_20.verified b/test/test_fe_engine/test_interpolate_hexahedron_20.verified
new file mode 100644
index 000000000..e72db35f8
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_hexahedron_20.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 81
+ + nb_component : 2
+ + allocated size : 81
+ + memory size : 1.27KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 216
+ + nb_component : 2
+ + allocated size : 216
+ + memory size : 3.38KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 216
+ + nb_component : 3
+ + allocated size : 216
+ + memory size : 5.06KiByte
+ + values : {{-0.443649, -0.443649, -0.443649}, {-0.25, -0.443649, -0.443649}, {-0.0563508, -0.443649, -0.443649}, {-0.443649, -0.25, -0.443649}, {-0.25, -0.25, -0.443649}, {-0.0563508, -0.25, -0.443649}, {-0.443649, -0.0563508, -0.443649}, {-0.25, -0.0563508, -0.443649}, {-0.0563508, -0.0563508, -0.443649}, {-0.443649, -0.443649, -0.25}, {-0.25, -0.443649, -0.25}, {-0.0563508, -0.443649, -0.25}, {-0.443649, -0.25, -0.25}, {-0.25, -0.25, -0.25}, {-0.0563508, -0.25, -0.25}, {-0.443649, -0.0563508, -0.25}, {-0.25, -0.0563508, -0.25}, {-0.0563508, -0.0563508, -0.25}, {-0.443649, -0.443649, -0.0563508}, {-0.25, -0.443649, -0.0563508}, {-0.0563508, -0.443649, -0.0563508}, {-0.443649, -0.25, -0.0563508}, {-0.25, -0.25, -0.0563508}, {-0.0563508, -0.25, -0.0563508}, {-0.443649, -0.0563508, -0.0563508}, {-0.25, -0.0563508, -0.0563508}, {-0.0563508, -0.0563508, -0.0563508}, {-0.443649, -0.443649, 0.0563508}, {-0.25, -0.443649, 0.0563508}, {-0.0563508, -0.443649, 0.0563508}, {-0.443649, -0.25, 0.0563508}, {-0.25, -0.25, 0.0563508}, {-0.0563508, -0.25, 0.0563508}, {-0.443649, -0.0563508, 0.0563508}, {-0.25, -0.0563508, 0.0563508}, {-0.0563508, -0.0563508, 0.0563508}, {-0.443649, -0.443649, 0.25}, {-0.25, -0.443649, 0.25}, {-0.0563508, -0.443649, 0.25}, {-0.443649, -0.25, 0.25}, {-0.25, -0.25, 0.25}, {-0.0563508, -0.25, 0.25}, {-0.443649, -0.0563508, 0.25}, {-0.25, -0.0563508, 0.25}, {-0.0563508, -0.0563508, 0.25}, {-0.443649, -0.443649, 0.443649}, {-0.25, -0.443649, 0.443649}, {-0.0563508, -0.443649, 0.443649}, {-0.443649, -0.25, 0.443649}, {-0.25, -0.25, 0.443649}, {-0.0563508, -0.25, 0.443649}, {-0.443649, -0.0563508, 0.443649}, {-0.25, -0.0563508, 0.443649}, {-0.0563508, -0.0563508, 0.443649}, {-0.443649, 0.0563508, -0.443649}, {-0.25, 0.0563508, -0.443649}, {-0.0563508, 0.0563508, -0.443649}, {-0.443649, 0.25, -0.443649}, {-0.25, 0.25, -0.443649}, {-0.0563508, 0.25, -0.443649}, {-0.443649, 0.443649, -0.443649}, {-0.25, 0.443649, -0.443649}, {-0.0563508, 0.443649, -0.443649}, {-0.443649, 0.0563508, -0.25}, {-0.25, 0.0563508, -0.25}, {-0.0563508, 0.0563508, -0.25}, {-0.443649, 0.25, -0.25}, {-0.25, 0.25, -0.25}, {-0.0563508, 0.25, -0.25}, {-0.443649, 0.443649, -0.25}, {-0.25, 0.443649, -0.25}, {-0.0563508, 0.443649, -0.25}, {-0.443649, 0.0563508, -0.0563508}, {-0.25, 0.0563508, -0.0563508}, {-0.0563508, 0.0563508, -0.0563508}, {-0.443649, 0.25, -0.0563508}, {-0.25, 0.25, -0.0563508}, {-0.0563508, 0.25, -0.0563508}, {-0.443649, 0.443649, -0.0563508}, {-0.25, 0.443649, -0.0563508}, {-0.0563508, 0.443649, -0.0563508}, {-0.443649, 0.0563508, 0.0563508}, {-0.25, 0.0563508, 0.0563508}, {-0.0563508, 0.0563508, 0.0563508}, {-0.443649, 0.25, 0.0563508}, {-0.25, 0.25, 0.0563508}, {-0.0563508, 0.25, 0.0563508}, {-0.443649, 0.443649, 0.0563508}, {-0.25, 0.443649, 0.0563508}, {-0.0563508, 0.443649, 0.0563508}, {-0.443649, 0.0563508, 0.25}, {-0.25, 0.0563508, 0.25}, {-0.0563508, 0.0563508, 0.25}, {-0.443649, 0.25, 0.25}, {-0.25, 0.25, 0.25}, {-0.0563508, 0.25, 0.25}, {-0.443649, 0.443649, 0.25}, {-0.25, 0.443649, 0.25}, {-0.0563508, 0.443649, 0.25}, {-0.443649, 0.0563508, 0.443649}, {-0.25, 0.0563508, 0.443649}, {-0.0563508, 0.0563508, 0.443649}, {-0.443649, 0.25, 0.443649}, {-0.25, 0.25, 0.443649}, {-0.0563508, 0.25, 0.443649}, {-0.443649, 0.443649, 0.443649}, {-0.25, 0.443649, 0.443649}, {-0.0563508, 0.443649, 0.443649}, {0.0563508, -0.443649, -0.443649}, {0.25, -0.443649, -0.443649}, {0.443649, -0.443649, -0.443649}, {0.0563508, -0.25, -0.443649}, {0.25, -0.25, -0.443649}, {0.443649, -0.25, -0.443649}, {0.0563508, -0.0563508, -0.443649}, {0.25, -0.0563508, -0.443649}, {0.443649, -0.0563508, -0.443649}, {0.0563508, -0.443649, -0.25}, {0.25, -0.443649, -0.25}, {0.443649, -0.443649, -0.25}, {0.0563508, -0.25, -0.25}, {0.25, -0.25, -0.25}, {0.443649, -0.25, -0.25}, {0.0563508, -0.0563508, -0.25}, {0.25, -0.0563508, -0.25}, {0.443649, -0.0563508, -0.25}, {0.0563508, -0.443649, -0.0563508}, {0.25, -0.443649, -0.0563508}, {0.443649, -0.443649, -0.0563508}, {0.0563508, -0.25, -0.0563508}, {0.25, -0.25, -0.0563508}, {0.443649, -0.25, -0.0563508}, {0.0563508, -0.0563508, -0.0563508}, {0.25, -0.0563508, -0.0563508}, {0.443649, -0.0563508, -0.0563508}, {0.0563508, -0.443649, 0.0563508}, {0.25, -0.443649, 0.0563508}, {0.443649, -0.443649, 0.0563508}, {0.0563508, -0.25, 0.0563508}, {0.25, -0.25, 0.0563508}, {0.443649, -0.25, 0.0563508}, {0.0563508, -0.0563508, 0.0563508}, {0.25, -0.0563508, 0.0563508}, {0.443649, -0.0563508, 0.0563508}, {0.0563508, -0.443649, 0.25}, {0.25, -0.443649, 0.25}, {0.443649, -0.443649, 0.25}, {0.0563508, -0.25, 0.25}, {0.25, -0.25, 0.25}, {0.443649, -0.25, 0.25}, {0.0563508, -0.0563508, 0.25}, {0.25, -0.0563508, 0.25}, {0.443649, -0.0563508, 0.25}, {0.0563508, -0.443649, 0.443649}, {0.25, -0.443649, 0.443649}, {0.443649, -0.443649, 0.443649}, {0.0563508, -0.25, 0.443649}, {0.25, -0.25, 0.443649}, {0.443649, -0.25, 0.443649}, {0.0563508, -0.0563508, 0.443649}, {0.25, -0.0563508, 0.443649}, {0.443649, -0.0563508, 0.443649}, {0.0563508, 0.0563508, -0.443649}, {0.25, 0.0563508, -0.443649}, {0.443649, 0.0563508, -0.443649}, {0.0563508, 0.25, -0.443649}, {0.25, 0.25, -0.443649}, {0.443649, 0.25, -0.443649}, {0.0563508, 0.443649, -0.443649}, {0.25, 0.443649, -0.443649}, {0.443649, 0.443649, -0.443649}, {0.0563508, 0.0563508, -0.25}, {0.25, 0.0563508, -0.25}, {0.443649, 0.0563508, -0.25}, {0.0563508, 0.25, -0.25}, {0.25, 0.25, -0.25}, {0.443649, 0.25, -0.25}, {0.0563508, 0.443649, -0.25}, {0.25, 0.443649, -0.25}, {0.443649, 0.443649, -0.25}, {0.0563508, 0.0563508, -0.0563508}, {0.25, 0.0563508, -0.0563508}, {0.443649, 0.0563508, -0.0563508}, {0.0563508, 0.25, -0.0563508}, {0.25, 0.25, -0.0563508}, {0.443649, 0.25, -0.0563508}, {0.0563508, 0.443649, -0.0563508}, {0.25, 0.443649, -0.0563508}, {0.443649, 0.443649, -0.0563508}, {0.0563508, 0.0563508, 0.0563508}, {0.25, 0.0563508, 0.0563508}, {0.443649, 0.0563508, 0.0563508}, {0.0563508, 0.25, 0.0563508}, {0.25, 0.25, 0.0563508}, {0.443649, 0.25, 0.0563508}, {0.0563508, 0.443649, 0.0563508}, {0.25, 0.443649, 0.0563508}, {0.443649, 0.443649, 0.0563508}, {0.0563508, 0.0563508, 0.25}, {0.25, 0.0563508, 0.25}, {0.443649, 0.0563508, 0.25}, {0.0563508, 0.25, 0.25}, {0.25, 0.25, 0.25}, {0.443649, 0.25, 0.25}, {0.0563508, 0.443649, 0.25}, {0.25, 0.443649, 0.25}, {0.443649, 0.443649, 0.25}, {0.0563508, 0.0563508, 0.443649}, {0.25, 0.0563508, 0.443649}, {0.443649, 0.0563508, 0.443649}, {0.0563508, 0.25, 0.443649}, {0.25, 0.25, 0.443649}, {0.443649, 0.25, 0.443649}, {0.0563508, 0.443649, 0.443649}, {0.25, 0.443649, 0.443649}, {0.443649, 0.443649, 0.443649}}
+]
+
diff --git a/test/test_fe_engine/test_interpolate_hexahedron_8.verified b/test/test_fe_engine/test_interpolate_hexahedron_8.verified
new file mode 100644
index 000000000..31c853310
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_hexahedron_8.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 125
+ + nb_component : 2
+ + allocated size : 125
+ + memory size : 1.95KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 512
+ + nb_component : 2
+ + allocated size : 512
+ + memory size : 8.00KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 512
+ + nb_component : 3
+ + allocated size : 512
+ + memory size : 12.00KiByte
+ + values : {{0.947169, 0.802831, 0.802831}, {0.947169, 0.802831, 0.947169}, {0.947169, 0.947169, 0.802831}, {0.947169, 0.947169, 0.947169}, {0.802831, 0.802831, 0.802831}, {0.802831, 0.802831, 0.947169}, {0.802831, 0.947169, 0.802831}, {0.802831, 0.947169, 0.947169}, {0.697169, 0.802831, 0.802831}, {0.697169, 0.802831, 0.947169}, {0.697169, 0.947169, 0.802831}, {0.697169, 0.947169, 0.947169}, {0.552831, 0.802831, 0.802831}, {0.552831, 0.802831, 0.947169}, {0.552831, 0.947169, 0.802831}, {0.552831, 0.947169, 0.947169}, {0.447169, 0.802831, 0.802831}, {0.447169, 0.802831, 0.947169}, {0.447169, 0.947169, 0.802831}, {0.447169, 0.947169, 0.947169}, {0.302831, 0.802831, 0.802831}, {0.302831, 0.802831, 0.947169}, {0.302831, 0.947169, 0.802831}, {0.302831, 0.947169, 0.947169}, {0.197169, 0.802831, 0.802831}, {0.197169, 0.802831, 0.947169}, {0.197169, 0.947169, 0.802831}, {0.197169, 0.947169, 0.947169}, {0.0528312, 0.802831, 0.802831}, {0.0528312, 0.802831, 0.947169}, {0.0528312, 0.947169, 0.802831}, {0.0528312, 0.947169, 0.947169}, {0.947169, 0.802831, 0.552831}, {0.947169, 0.802831, 0.697169}, {0.947169, 0.947169, 0.552831}, {0.947169, 0.947169, 0.697169}, {0.802831, 0.802831, 0.552831}, {0.802831, 0.802831, 0.697169}, {0.802831, 0.947169, 0.552831}, {0.802831, 0.947169, 0.697169}, {0.697169, 0.802831, 0.552831}, {0.697169, 0.802831, 0.697169}, {0.697169, 0.947169, 0.552831}, {0.697169, 0.947169, 0.697169}, {0.552831, 0.802831, 0.552831}, {0.552831, 0.802831, 0.697169}, {0.552831, 0.947169, 0.552831}, {0.552831, 0.947169, 0.697169}, {0.447169, 0.802831, 0.552831}, {0.447169, 0.802831, 0.697169}, {0.447169, 0.947169, 0.552831}, {0.447169, 0.947169, 0.697169}, {0.302831, 0.802831, 0.552831}, {0.302831, 0.802831, 0.697169}, {0.302831, 0.947169, 0.552831}, {0.302831, 0.947169, 0.697169}, {0.197169, 0.802831, 0.552831}, {0.197169, 0.802831, 0.697169}, {0.197169, 0.947169, 0.552831}, {0.197169, 0.947169, 0.697169}, {0.0528312, 0.802831, 0.552831}, {0.0528312, 0.802831, 0.697169}, {0.0528312, 0.947169, 0.552831}, {0.0528312, 0.947169, 0.697169}, {0.947169, 0.802831, 0.302831}, {0.947169, 0.802831, 0.447169}, {0.947169, 0.947169, 0.302831}, {0.947169, 0.947169, 0.447169}, {0.802831, 0.802831, 0.302831}, {0.802831, 0.802831, 0.447169}, {0.802831, 0.947169, 0.302831}, {0.802831, 0.947169, 0.447169}, {0.697169, 0.802831, 0.302831}, {0.697169, 0.802831, 0.447169}, {0.697169, 0.947169, 0.302831}, {0.697169, 0.947169, 0.447169}, {0.552831, 0.802831, 0.302831}, {0.552831, 0.802831, 0.447169}, {0.552831, 0.947169, 0.302831}, {0.552831, 0.947169, 0.447169}, {0.447169, 0.802831, 0.302831}, {0.447169, 0.802831, 0.447169}, {0.447169, 0.947169, 0.302831}, {0.447169, 0.947169, 0.447169}, {0.302831, 0.802831, 0.302831}, {0.302831, 0.802831, 0.447169}, {0.302831, 0.947169, 0.302831}, {0.302831, 0.947169, 0.447169}, {0.197169, 0.802831, 0.302831}, {0.197169, 0.802831, 0.447169}, {0.197169, 0.947169, 0.302831}, {0.197169, 0.947169, 0.447169}, {0.0528312, 0.802831, 0.302831}, {0.0528312, 0.802831, 0.447169}, {0.0528312, 0.947169, 0.302831}, {0.0528312, 0.947169, 0.447169}, {0.947169, 0.802831, 0.0528312}, {0.947169, 0.802831, 0.197169}, {0.947169, 0.947169, 0.0528312}, {0.947169, 0.947169, 0.197169}, {0.802831, 0.802831, 0.0528312}, {0.802831, 0.802831, 0.197169}, {0.802831, 0.947169, 0.0528312}, {0.802831, 0.947169, 0.197169}, {0.697169, 0.802831, 0.0528312}, {0.697169, 0.802831, 0.197169}, {0.697169, 0.947169, 0.0528312}, {0.697169, 0.947169, 0.197169}, {0.552831, 0.802831, 0.0528312}, {0.552831, 0.802831, 0.197169}, {0.552831, 0.947169, 0.0528312}, {0.552831, 0.947169, 0.197169}, {0.447169, 0.802831, 0.0528312}, {0.447169, 0.802831, 0.197169}, {0.447169, 0.947169, 0.0528312}, {0.447169, 0.947169, 0.197169}, {0.302831, 0.802831, 0.0528312}, {0.302831, 0.802831, 0.197169}, {0.302831, 0.947169, 0.0528312}, {0.302831, 0.947169, 0.197169}, {0.197169, 0.802831, 0.0528312}, {0.197169, 0.802831, 0.197169}, {0.197169, 0.947169, 0.0528312}, {0.197169, 0.947169, 0.197169}, {0.0528312, 0.802831, 0.0528312}, {0.0528312, 0.802831, 0.197169}, {0.0528312, 0.947169, 0.0528312}, {0.0528312, 0.947169, 0.197169}, {0.947169, 0.552831, 0.802831}, {0.947169, 0.552831, 0.947169}, {0.947169, 0.697169, 0.802831}, {0.947169, 0.697169, 0.947169}, {0.802831, 0.552831, 0.802831}, {0.802831, 0.552831, 0.947169}, {0.802831, 0.697169, 0.802831}, {0.802831, 0.697169, 0.947169}, {0.697169, 0.552831, 0.802831}, {0.697169, 0.552831, 0.947169}, {0.697169, 0.697169, 0.802831}, {0.697169, 0.697169, 0.947169}, {0.552831, 0.552831, 0.802831}, {0.552831, 0.552831, 0.947169}, {0.552831, 0.697169, 0.802831}, {0.552831, 0.697169, 0.947169}, {0.447169, 0.552831, 0.802831}, {0.447169, 0.552831, 0.947169}, {0.447169, 0.697169, 0.802831}, {0.447169, 0.697169, 0.947169}, {0.302831, 0.552831, 0.802831}, {0.302831, 0.552831, 0.947169}, {0.302831, 0.697169, 0.802831}, {0.302831, 0.697169, 0.947169}, {0.197169, 0.552831, 0.802831}, {0.197169, 0.552831, 0.947169}, {0.197169, 0.697169, 0.802831}, {0.197169, 0.697169, 0.947169}, {0.0528312, 0.552831, 0.802831}, {0.0528312, 0.552831, 0.947169}, {0.0528312, 0.697169, 0.802831}, {0.0528312, 0.697169, 0.947169}, {0.947169, 0.552831, 0.552831}, {0.947169, 0.552831, 0.697169}, {0.947169, 0.697169, 0.552831}, {0.947169, 0.697169, 0.697169}, {0.802831, 0.552831, 0.552831}, {0.802831, 0.552831, 0.697169}, {0.802831, 0.697169, 0.552831}, {0.802831, 0.697169, 0.697169}, {0.697169, 0.552831, 0.552831}, {0.697169, 0.552831, 0.697169}, {0.697169, 0.697169, 0.552831}, {0.697169, 0.697169, 0.697169}, {0.552831, 0.552831, 0.552831}, {0.552831, 0.552831, 0.697169}, {0.552831, 0.697169, 0.552831}, {0.552831, 0.697169, 0.697169}, {0.447169, 0.552831, 0.552831}, {0.447169, 0.552831, 0.697169}, {0.447169, 0.697169, 0.552831}, {0.447169, 0.697169, 0.697169}, {0.302831, 0.552831, 0.552831}, {0.302831, 0.552831, 0.697169}, {0.302831, 0.697169, 0.552831}, {0.302831, 0.697169, 0.697169}, {0.197169, 0.552831, 0.552831}, {0.197169, 0.552831, 0.697169}, {0.197169, 0.697169, 0.552831}, {0.197169, 0.697169, 0.697169}, {0.0528312, 0.552831, 0.552831}, {0.0528312, 0.552831, 0.697169}, {0.0528312, 0.697169, 0.552831}, {0.0528312, 0.697169, 0.697169}, {0.947169, 0.552831, 0.302831}, {0.947169, 0.552831, 0.447169}, {0.947169, 0.697169, 0.302831}, {0.947169, 0.697169, 0.447169}, {0.802831, 0.552831, 0.302831}, {0.802831, 0.552831, 0.447169}, {0.802831, 0.697169, 0.302831}, {0.802831, 0.697169, 0.447169}, {0.697169, 0.552831, 0.302831}, {0.697169, 0.552831, 0.447169}, {0.697169, 0.697169, 0.302831}, {0.697169, 0.697169, 0.447169}, {0.552831, 0.552831, 0.302831}, {0.552831, 0.552831, 0.447169}, {0.552831, 0.697169, 0.302831}, {0.552831, 0.697169, 0.447169}, {0.447169, 0.552831, 0.302831}, {0.447169, 0.552831, 0.447169}, {0.447169, 0.697169, 0.302831}, {0.447169, 0.697169, 0.447169}, {0.302831, 0.552831, 0.302831}, {0.302831, 0.552831, 0.447169}, {0.302831, 0.697169, 0.302831}, {0.302831, 0.697169, 0.447169}, {0.197169, 0.552831, 0.302831}, {0.197169, 0.552831, 0.447169}, {0.197169, 0.697169, 0.302831}, {0.197169, 0.697169, 0.447169}, {0.0528312, 0.552831, 0.302831}, {0.0528312, 0.552831, 0.447169}, {0.0528312, 0.697169, 0.302831}, {0.0528312, 0.697169, 0.447169}, {0.947169, 0.552831, 0.0528312}, {0.947169, 0.552831, 0.197169}, {0.947169, 0.697169, 0.0528312}, {0.947169, 0.697169, 0.197169}, {0.802831, 0.552831, 0.0528312}, {0.802831, 0.552831, 0.197169}, {0.802831, 0.697169, 0.0528312}, {0.802831, 0.697169, 0.197169}, {0.697169, 0.552831, 0.0528312}, {0.697169, 0.552831, 0.197169}, {0.697169, 0.697169, 0.0528312}, {0.697169, 0.697169, 0.197169}, {0.552831, 0.552831, 0.0528312}, {0.552831, 0.552831, 0.197169}, {0.552831, 0.697169, 0.0528312}, {0.552831, 0.697169, 0.197169}, {0.447169, 0.552831, 0.0528312}, {0.447169, 0.552831, 0.197169}, {0.447169, 0.697169, 0.0528312}, {0.447169, 0.697169, 0.197169}, {0.302831, 0.552831, 0.0528312}, {0.302831, 0.552831, 0.197169}, {0.302831, 0.697169, 0.0528312}, {0.302831, 0.697169, 0.197169}, {0.197169, 0.552831, 0.0528312}, {0.197169, 0.552831, 0.197169}, {0.197169, 0.697169, 0.0528312}, {0.197169, 0.697169, 0.197169}, {0.0528312, 0.552831, 0.0528312}, {0.0528312, 0.552831, 0.197169}, {0.0528312, 0.697169, 0.0528312}, {0.0528312, 0.697169, 0.197169}, {0.947169, 0.302831, 0.802831}, {0.947169, 0.302831, 0.947169}, {0.947169, 0.447169, 0.802831}, {0.947169, 0.447169, 0.947169}, {0.802831, 0.302831, 0.802831}, {0.802831, 0.302831, 0.947169}, {0.802831, 0.447169, 0.802831}, {0.802831, 0.447169, 0.947169}, {0.697169, 0.302831, 0.802831}, {0.697169, 0.302831, 0.947169}, {0.697169, 0.447169, 0.802831}, {0.697169, 0.447169, 0.947169}, {0.552831, 0.302831, 0.802831}, {0.552831, 0.302831, 0.947169}, {0.552831, 0.447169, 0.802831}, {0.552831, 0.447169, 0.947169}, {0.447169, 0.302831, 0.802831}, {0.447169, 0.302831, 0.947169}, {0.447169, 0.447169, 0.802831}, {0.447169, 0.447169, 0.947169}, {0.302831, 0.302831, 0.802831}, {0.302831, 0.302831, 0.947169}, {0.302831, 0.447169, 0.802831}, {0.302831, 0.447169, 0.947169}, {0.197169, 0.302831, 0.802831}, {0.197169, 0.302831, 0.947169}, {0.197169, 0.447169, 0.802831}, {0.197169, 0.447169, 0.947169}, {0.0528312, 0.302831, 0.802831}, {0.0528312, 0.302831, 0.947169}, {0.0528312, 0.447169, 0.802831}, {0.0528312, 0.447169, 0.947169}, {0.947169, 0.302831, 0.552831}, {0.947169, 0.302831, 0.697169}, {0.947169, 0.447169, 0.552831}, {0.947169, 0.447169, 0.697169}, {0.802831, 0.302831, 0.552831}, {0.802831, 0.302831, 0.697169}, {0.802831, 0.447169, 0.552831}, {0.802831, 0.447169, 0.697169}, {0.697169, 0.302831, 0.552831}, {0.697169, 0.302831, 0.697169}, {0.697169, 0.447169, 0.552831}, {0.697169, 0.447169, 0.697169}, {0.552831, 0.302831, 0.552831}, {0.552831, 0.302831, 0.697169}, {0.552831, 0.447169, 0.552831}, {0.552831, 0.447169, 0.697169}, {0.447169, 0.302831, 0.552831}, {0.447169, 0.302831, 0.697169}, {0.447169, 0.447169, 0.552831}, {0.447169, 0.447169, 0.697169}, {0.302831, 0.302831, 0.552831}, {0.302831, 0.302831, 0.697169}, {0.302831, 0.447169, 0.552831}, {0.302831, 0.447169, 0.697169}, {0.197169, 0.302831, 0.552831}, {0.197169, 0.302831, 0.697169}, {0.197169, 0.447169, 0.552831}, {0.197169, 0.447169, 0.697169}, {0.0528312, 0.302831, 0.552831}, {0.0528312, 0.302831, 0.697169}, {0.0528312, 0.447169, 0.552831}, {0.0528312, 0.447169, 0.697169}, {0.947169, 0.302831, 0.302831}, {0.947169, 0.302831, 0.447169}, {0.947169, 0.447169, 0.302831}, {0.947169, 0.447169, 0.447169}, {0.802831, 0.302831, 0.302831}, {0.802831, 0.302831, 0.447169}, {0.802831, 0.447169, 0.302831}, {0.802831, 0.447169, 0.447169}, {0.697169, 0.302831, 0.302831}, {0.697169, 0.302831, 0.447169}, {0.697169, 0.447169, 0.302831}, {0.697169, 0.447169, 0.447169}, {0.552831, 0.302831, 0.302831}, {0.552831, 0.302831, 0.447169}, {0.552831, 0.447169, 0.302831}, {0.552831, 0.447169, 0.447169}, {0.447169, 0.302831, 0.302831}, {0.447169, 0.302831, 0.447169}, {0.447169, 0.447169, 0.302831}, {0.447169, 0.447169, 0.447169}, {0.302831, 0.302831, 0.302831}, {0.302831, 0.302831, 0.447169}, {0.302831, 0.447169, 0.302831}, {0.302831, 0.447169, 0.447169}, {0.197169, 0.302831, 0.302831}, {0.197169, 0.302831, 0.447169}, {0.197169, 0.447169, 0.302831}, {0.197169, 0.447169, 0.447169}, {0.0528312, 0.302831, 0.302831}, {0.0528312, 0.302831, 0.447169}, {0.0528312, 0.447169, 0.302831}, {0.0528312, 0.447169, 0.447169}, {0.947169, 0.302831, 0.0528312}, {0.947169, 0.302831, 0.197169}, {0.947169, 0.447169, 0.0528312}, {0.947169, 0.447169, 0.197169}, {0.802831, 0.302831, 0.0528312}, {0.802831, 0.302831, 0.197169}, {0.802831, 0.447169, 0.0528312}, {0.802831, 0.447169, 0.197169}, {0.697169, 0.302831, 0.0528312}, {0.697169, 0.302831, 0.197169}, {0.697169, 0.447169, 0.0528312}, {0.697169, 0.447169, 0.197169}, {0.552831, 0.302831, 0.0528312}, {0.552831, 0.302831, 0.197169}, {0.552831, 0.447169, 0.0528312}, {0.552831, 0.447169, 0.197169}, {0.447169, 0.302831, 0.0528312}, {0.447169, 0.302831, 0.197169}, {0.447169, 0.447169, 0.0528312}, {0.447169, 0.447169, 0.197169}, {0.302831, 0.302831, 0.0528312}, {0.302831, 0.302831, 0.197169}, {0.302831, 0.447169, 0.0528312}, {0.302831, 0.447169, 0.197169}, {0.197169, 0.302831, 0.0528312}, {0.197169, 0.302831, 0.197169}, {0.197169, 0.447169, 0.0528312}, {0.197169, 0.447169, 0.197169}, {0.0528312, 0.302831, 0.0528312}, {0.0528312, 0.302831, 0.197169}, {0.0528312, 0.447169, 0.0528312}, {0.0528312, 0.447169, 0.197169}, {0.947169, 0.0528312, 0.802831}, {0.947169, 0.0528312, 0.947169}, {0.947169, 0.197169, 0.802831}, {0.947169, 0.197169, 0.947169}, {0.802831, 0.0528312, 0.802831}, {0.802831, 0.0528312, 0.947169}, {0.802831, 0.197169, 0.802831}, {0.802831, 0.197169, 0.947169}, {0.697169, 0.0528312, 0.802831}, {0.697169, 0.0528312, 0.947169}, {0.697169, 0.197169, 0.802831}, {0.697169, 0.197169, 0.947169}, {0.552831, 0.0528312, 0.802831}, {0.552831, 0.0528312, 0.947169}, {0.552831, 0.197169, 0.802831}, {0.552831, 0.197169, 0.947169}, {0.447169, 0.0528312, 0.802831}, {0.447169, 0.0528312, 0.947169}, {0.447169, 0.197169, 0.802831}, {0.447169, 0.197169, 0.947169}, {0.302831, 0.0528312, 0.802831}, {0.302831, 0.0528312, 0.947169}, {0.302831, 0.197169, 0.802831}, {0.302831, 0.197169, 0.947169}, {0.197169, 0.0528312, 0.802831}, {0.197169, 0.0528312, 0.947169}, {0.197169, 0.197169, 0.802831}, {0.197169, 0.197169, 0.947169}, {0.0528312, 0.0528312, 0.802831}, {0.0528312, 0.0528312, 0.947169}, {0.0528312, 0.197169, 0.802831}, {0.0528312, 0.197169, 0.947169}, {0.947169, 0.0528312, 0.552831}, {0.947169, 0.0528312, 0.697169}, {0.947169, 0.197169, 0.552831}, {0.947169, 0.197169, 0.697169}, {0.802831, 0.0528312, 0.552831}, {0.802831, 0.0528312, 0.697169}, {0.802831, 0.197169, 0.552831}, {0.802831, 0.197169, 0.697169}, {0.697169, 0.0528312, 0.552831}, {0.697169, 0.0528312, 0.697169}, {0.697169, 0.197169, 0.552831}, {0.697169, 0.197169, 0.697169}, {0.552831, 0.0528312, 0.552831}, {0.552831, 0.0528312, 0.697169}, {0.552831, 0.197169, 0.552831}, {0.552831, 0.197169, 0.697169}, {0.447169, 0.0528312, 0.552831}, {0.447169, 0.0528312, 0.697169}, {0.447169, 0.197169, 0.552831}, {0.447169, 0.197169, 0.697169}, {0.302831, 0.0528312, 0.552831}, {0.302831, 0.0528312, 0.697169}, {0.302831, 0.197169, 0.552831}, {0.302831, 0.197169, 0.697169}, {0.197169, 0.0528312, 0.552831}, {0.197169, 0.0528312, 0.697169}, {0.197169, 0.197169, 0.552831}, {0.197169, 0.197169, 0.697169}, {0.0528312, 0.0528312, 0.552831}, {0.0528312, 0.0528312, 0.697169}, {0.0528312, 0.197169, 0.552831}, {0.0528312, 0.197169, 0.697169}, {0.947169, 0.0528312, 0.302831}, {0.947169, 0.0528312, 0.447169}, {0.947169, 0.197169, 0.302831}, {0.947169, 0.197169, 0.447169}, {0.802831, 0.0528312, 0.302831}, {0.802831, 0.0528312, 0.447169}, {0.802831, 0.197169, 0.302831}, {0.802831, 0.197169, 0.447169}, {0.697169, 0.0528312, 0.302831}, {0.697169, 0.0528312, 0.447169}, {0.697169, 0.197169, 0.302831}, {0.697169, 0.197169, 0.447169}, {0.552831, 0.0528312, 0.302831}, {0.552831, 0.0528312, 0.447169}, {0.552831, 0.197169, 0.302831}, {0.552831, 0.197169, 0.447169}, {0.447169, 0.0528312, 0.302831}, {0.447169, 0.0528312, 0.447169}, {0.447169, 0.197169, 0.302831}, {0.447169, 0.197169, 0.447169}, {0.302831, 0.0528312, 0.302831}, {0.302831, 0.0528312, 0.447169}, {0.302831, 0.197169, 0.302831}, {0.302831, 0.197169, 0.447169}, {0.197169, 0.0528312, 0.302831}, {0.197169, 0.0528312, 0.447169}, {0.197169, 0.197169, 0.302831}, {0.197169, 0.197169, 0.447169}, {0.0528312, 0.0528312, 0.302831}, {0.0528312, 0.0528312, 0.447169}, {0.0528312, 0.197169, 0.302831}, {0.0528312, 0.197169, 0.447169}, {0.947169, 0.0528312, 0.0528312}, {0.947169, 0.0528312, 0.197169}, {0.947169, 0.197169, 0.0528312}, {0.947169, 0.197169, 0.197169}, {0.802831, 0.0528312, 0.0528312}, {0.802831, 0.0528312, 0.197169}, {0.802831, 0.197169, 0.0528312}, {0.802831, 0.197169, 0.197169}, {0.697169, 0.0528312, 0.0528312}, {0.697169, 0.0528312, 0.197169}, {0.697169, 0.197169, 0.0528312}, {0.697169, 0.197169, 0.197169}, {0.552831, 0.0528312, 0.0528312}, {0.552831, 0.0528312, 0.197169}, {0.552831, 0.197169, 0.0528312}, {0.552831, 0.197169, 0.197169}, {0.447169, 0.0528312, 0.0528312}, {0.447169, 0.0528312, 0.197169}, {0.447169, 0.197169, 0.0528312}, {0.447169, 0.197169, 0.197169}, {0.302831, 0.0528312, 0.0528312}, {0.302831, 0.0528312, 0.197169}, {0.302831, 0.197169, 0.0528312}, {0.302831, 0.197169, 0.197169}, {0.197169, 0.0528312, 0.0528312}, {0.197169, 0.0528312, 0.197169}, {0.197169, 0.197169, 0.0528312}, {0.197169, 0.197169, 0.197169}, {0.0528312, 0.0528312, 0.0528312}, {0.0528312, 0.0528312, 0.197169}, {0.0528312, 0.197169, 0.0528312}, {0.0528312, 0.197169, 0.197169}}
+]
+
diff --git a/test/test_fe_engine/test_interpolate_quadrangle_4.verified b/test/test_fe_engine/test_interpolate_quadrangle_4.verified
new file mode 100644
index 000000000..293b43df2
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_quadrangle_4.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 9
+ + nb_component : 2
+ + allocated size : 9
+ + memory size : 144.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 16
+ + nb_component : 2
+ + allocated size : 16
+ + memory size : 256.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 16
+ + nb_component : 2
+ + allocated size : 16
+ + memory size : 256.00Byte
+ + values : {{0.894338, 0.894338}, {0.605662, 0.894338}, {0.894338, 0.605662}, {0.605662, 0.605662}, {0.894338, 0.394338}, {0.605662, 0.394338}, {0.894338, 0.105662}, {0.605662, 0.105662}, {0.394338, 0.894338}, {0.105662, 0.894338}, {0.394338, 0.605662}, {0.105662, 0.605662}, {0.394338, 0.394338}, {0.105662, 0.394338}, {0.394338, 0.105662}, {0.105662, 0.105662}}
+]
+
diff --git a/test/test_fe_engine/test_interpolate_quadrangle_8.verified b/test/test_fe_engine/test_interpolate_quadrangle_8.verified
new file mode 100644
index 000000000..64d19d19f
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_quadrangle_8.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 21
+ + nb_component : 2
+ + allocated size : 21
+ + memory size : 336.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 36
+ + nb_component : 2
+ + allocated size : 36
+ + memory size : 576.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 36
+ + nb_component : 2
+ + allocated size : 36
+ + memory size : 576.00Byte
+ + values : {{0.943649, 0.943649}, {0.75, 0.943649}, {0.556351, 0.943649}, {0.943649, 0.75}, {0.75, 0.75}, {0.556351, 0.75}, {0.943649, 0.556351}, {0.75, 0.556351}, {0.556351, 0.556351}, {0.943649, 0.443649}, {0.75, 0.443649}, {0.556351, 0.443649}, {0.943649, 0.25}, {0.75, 0.25}, {0.556351, 0.25}, {0.943649, 0.0563508}, {0.75, 0.0563508}, {0.556351, 0.0563508}, {0.443649, 0.943649}, {0.25, 0.943649}, {0.0563508, 0.943649}, {0.443649, 0.75}, {0.25, 0.75}, {0.0563508, 0.75}, {0.443649, 0.556351}, {0.25, 0.556351}, {0.0563508, 0.556351}, {0.443649, 0.443649}, {0.25, 0.443649}, {0.0563508, 0.443649}, {0.443649, 0.25}, {0.25, 0.25}, {0.0563508, 0.25}, {0.443649, 0.0563508}, {0.25, 0.0563508}, {0.0563508, 0.0563508}}
+]
+
diff --git a/test/test_fe_engine/test_interpolate_segment_2.verified b/test/test_fe_engine/test_interpolate_segment_2.verified
new file mode 100644
index 000000000..6c021d039
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_segment_2.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 11
+ + nb_component : 2
+ + allocated size : 11
+ + memory size : 176.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 10
+ + nb_component : 2
+ + allocated size : 10
+ + memory size : 160.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 10
+ + nb_component : 1
+ + allocated size : 10
+ + memory size : 80.00Byte
+ + values : {{0.05}, {0.15}, {0.25}, {0.35}, {0.45}, {0.55}, {0.65}, {0.75}, {0.85}, {0.95}}
+]
+
diff --git a/test/test_fe_engine/test_interpolate_segment_3.verified b/test/test_fe_engine/test_interpolate_segment_3.verified
new file mode 100644
index 000000000..f14b715ab
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_segment_3.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 21
+ + nb_component : 2
+ + allocated size : 21
+ + memory size : 336.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 20
+ + nb_component : 2
+ + allocated size : 20
+ + memory size : 320.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 20
+ + nb_component : 1
+ + allocated size : 20
+ + memory size : 160.00Byte
+ + values : {{0.0211325}, {0.0788675}, {0.121132}, {0.178868}, {0.221132}, {0.278868}, {0.321132}, {0.378868}, {0.421132}, {0.478868}, {0.521132}, {0.578868}, {0.621132}, {0.678868}, {0.721132}, {0.778868}, {0.821132}, {0.878868}, {0.921132}, {0.978868}}
+]
+
diff --git a/test/test_fe_engine/test_interpolate_tetrahedron_10.verified b/test/test_fe_engine/test_interpolate_tetrahedron_10.verified
new file mode 100644
index 000000000..4a7b53f85
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_tetrahedron_10.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 722
+ + nb_component : 2
+ + allocated size : 722
+ + memory size : 11.28KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 1364
+ + nb_component : 2
+ + allocated size : 1364
+ + memory size : 21.31KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 1364
+ + nb_component : 3
+ + allocated size : 1364
+ + memory size : 31.97KiByte
+ + values : {{0.500886, 0.386356, 0.558419}, {0.483266, 0.535345, 0.572451}, {0.653352, 0.386356, 0.558419}, {0.616507, 0.401655, 0.446681}, {0.909627, 0.282392, 0.0257773}, {0.785068, 0.295147, 0.0257773}, {0.827088, 0.262654, 0.109194}, {0.824271, 0.394195, 0.0257773}, {0.50529, 0.143859, 0.455094}, {0.470093, 0.293938, 0.494723}, {0.585714, 0.309238, 0.382984}, {0.470093, 0.293938, 0.342256}, {0.664242, 0.18961, 0.973624}, {0.565315, 0.064942, 0.888267}, {0.676997, 0.064942, 0.973624}, {0.565194, 0.150431, 0.973624}, {0.18558, 0.019611, 0.019611}, {0.0737767, 0.019611, 0.019611}, {0.137257, 0.019611, 0.0830735}, {0.137239, 0.0830735, 0.019611}, {0.0392276, 0.039222, 0.039222}, {0.0392276, 0.102684, 0.102684}, {0.102708, 0.039222, 0.102684}, {0.10269, 0.102684, 0.039222}, {0.312781, 0.373144, 0.171375}, {0.208748, 0.446671, 0.060606}, {0.247951, 0.347623, 0.060606}, {0.123392, 0.446671, 0.145962}, {0.517208, 0.293938, 0.541837}, {0.552405, 0.143859, 0.502209}, {0.632829, 0.309238, 0.430099}, {0.669674, 0.293938, 0.541837}, {0.974494, 0.232904, 0.0838791}, {0.974494, 0.184563, 0.147342}, {0.974494, 0.24566, 0.208438}, {0.891955, 0.213167, 0.167296}, {0.10269, 0.141199, 0.922287}, {0.0392276, 0.202277, 0.797729}, {0.102708, 0.0777183, 0.858825}, {0.0392276, 0.141181, 0.858825}, {0.077752, 0.182666, 0.778849}, {0.141214, 0.121588, 0.903407}, {0.141233, 0.0581074, 0.839945}, {0.20242, 0.0581074, 0.778849}, {0.224105, 0.0196166, 0.941898}, {0.175764, 0.0830972, 0.941898}, {0.236969, 0.0196166, 0.817339}, {0.175782, 0.0196166, 0.878436}, {0.77805, 0.0848678, 0.672509}, {0.817362, 0.0848678, 0.573461}, {0.797251, 0.234947, 0.61309}, {0.902609, 0.209427, 0.672509}, {0.45811, 0.553641, 0.663833}, {0.509948, 0.479159, 0.833779}, {0.475731, 0.404652, 0.649801}, {0.628197, 0.404652, 0.649801}, {0.974494, 0.282375, 0.0906277}, {0.974494, 0.29513, 0.215186}, {0.974494, 0.394124, 0.175929}, {0.891955, 0.262638, 0.174045}, {0.85293, 0.184563, 0.0257773}, {0.916392, 0.232904, 0.0257773}, {0.791834, 0.24566, 0.0257773}, {0.833853, 0.213167, 0.109194}, {0.671322, 0.634958, 0.54915}, {0.5235, 0.630025, 0.534271}, {0.693587, 0.633501, 0.367772}, {0.656742, 0.496335, 0.4085}, {0.694812, 0.810608, 0.961509}, {0.707568, 0.935166, 0.961509}, {0.694812, 0.935166, 0.83695}, {0.595764, 0.849919, 0.961509}, {0.0196166, 0.182661, 0.236821}, {0.0196166, 0.121564, 0.175724}, {0.0830972, 0.0581018, 0.175724}, {0.0196166, 0.0581018, 0.224065}, {0.862085, 0.330254, 0.582314}, {0.967443, 0.304733, 0.641733}, {0.967443, 0.265476, 0.542631}, {0.967443, 0.403291, 0.542195}, {0.85293, 0.02845, 0.181891}, {0.791834, 0.02845, 0.242987}, {0.916392, 0.02845, 0.230232}, {0.833853, 0.120516, 0.201845}, {0.5235, 0.58291, 0.581385}, {0.671322, 0.587844, 0.596265}, {0.693587, 0.43392, 0.567353}, {0.656742, 0.44922, 0.455615}, {0.916927, 0.980386, 0.862764}, {0.980389, 0.980386, 0.814423}, {0.980389, 0.980386, 0.926226}, {0.980389, 0.916915, 0.862755}, {0.483266, 0.629574, 0.478222}, {0.500886, 0.633051, 0.311724}, {0.653352, 0.633051, 0.311724}, {0.616507, 0.495885, 0.352451}, {0.381879, 0.373517, 0.75917}, {0.416097, 0.448025, 0.943148}, {0.277846, 0.447166, 0.943148}, {0.317049, 0.348106, 0.943148}, {0.0263765, 0.973624, 0.353647}, {0.111733, 0.973624, 0.465451}, {0.0263765, 0.973624, 0.465451}, {0.0263765, 0.888267, 0.465451}, {0.465609, 0.0263765, 0.111733}, {0.465488, 0.111733, 0.0263765}, {0.465488, 0.0263765, 0.0263765}, {0.353685, 0.0263765, 0.0263765}, {0.862766, 0.916927, 0.980389}, {0.814425, 0.980389, 0.980389}, {0.926229, 0.980389, 0.980389}, {0.862766, 0.980389, 0.916927}, {0.534549, 0.973657, 0.973624}, {0.646353, 0.973657, 0.973624}, {0.534549, 0.88841, 0.973624}, {0.534549, 0.973657, 0.888267}, {0.980389, 0.814423, 0.980386}, {0.916927, 0.862764, 0.980386}, {0.980389, 0.926226, 0.980386}, {0.980389, 0.862755, 0.916915}, {0.436151, 0.58246, 0.525337}, {0.453771, 0.43347, 0.511305}, {0.453771, 0.585937, 0.358838}, {0.569392, 0.44877, 0.399566}, {0.973624, 0.973605, 0.465432}, {0.973624, 0.888188, 0.465372}, {0.888267, 0.973605, 0.465432}, {0.973624, 0.973605, 0.353629}, {0.0970153, 0.765869, 0.304868}, {0.221574, 0.890428, 0.304868}, {0.0970153, 0.805072, 0.403916}, {0.286405, 0.74576, 0.291079}, {0.236821, 0.817339, 0.980389}, {0.175724, 0.878436, 0.980389}, {0.224065, 0.941898, 0.980389}, {0.175724, 0.941898, 0.916927}, {0.973624, 0.646371, 0.973605}, {0.973624, 0.534507, 0.888188}, {0.973624, 0.534568, 0.973605}, {0.888267, 0.534689, 0.973605}, {0.791799, 0.273921, 0.529575}, {0.811909, 0.123842, 0.489946}, {0.754953, 0.289221, 0.417836}, {0.897157, 0.209143, 0.489891}, {0.646167, 0.60614, 0.687646}, {0.550183, 0.526724, 0.842713}, {0.498345, 0.601206, 0.672767}, {0.668432, 0.452217, 0.658735}, {0.619422, 0.0463771, 0.684623}, {0.521354, 0.0463771, 0.585575}, {0.520495, 0.0463771, 0.723826}, {0.486156, 0.196456, 0.625204}, {0.967443, 0.446441, 0.723595}, {0.967443, 0.347453, 0.684453}, {0.862085, 0.372974, 0.625034}, {0.967443, 0.446011, 0.584915}, {0.0581018, 0.757055, 0.0384908}, {0.121564, 0.805396, 0.0384908}, {0.0581018, 0.7443, 0.16305}, {0.182661, 0.7443, 0.0384908}, {0.137234, 0.916927, 0.980389}, {0.0737711, 0.980389, 0.980389}, {0.185575, 0.980389, 0.980389}, {0.137234, 0.980389, 0.916927}, {0.923499, 0.506177, 0.261653}, {0.818141, 0.585171, 0.28712}, {0.781296, 0.448004, 0.327848}, {0.923499, 0.505742, 0.399468}, {0.434843, 0.973624, 0.150223}, {0.335795, 0.973624, 0.189426}, {0.32304, 0.973624, 0.0648672}, {0.434843, 0.888267, 0.0648672}, {0.435035, 0.0263765, 0.150223}, {0.434914, 0.111733, 0.0648672}, {0.323111, 0.0263765, 0.0648672}, {0.335975, 0.0263765, 0.189426}, {0.305188, 0.935133, 0.16305}, {0.305188, 0.810574, 0.0384908}, {0.292432, 0.935133, 0.0384908}, {0.404236, 0.849777, 0.0384908}, {0.203303, 0.91573, 0.577797}, {0.289716, 0.767585, 0.631458}, {0.242505, 0.91573, 0.676845}, {0.117947, 0.791171, 0.676845}, {0.160089, 0.160112, 0.923018}, {0.0966262, 0.221191, 0.79846}, {0.221185, 0.221299, 0.923018}, {0.221294, 0.0966318, 0.79846}, {0.0384908, 0.305221, 0.810574}, {0.16305, 0.30533, 0.935133}, {0.0384908, 0.404269, 0.849777}, {0.0384908, 0.292466, 0.935133}, {0.111604, 0.500598, 0.57155}, {0.283373, 0.57606, 0.62521}, {0.111604, 0.500598, 0.709801}, {0.300993, 0.42707, 0.611179}, {0.137239, 0.0830972, 0.980389}, {0.18558, 0.0196166, 0.980389}, {0.0737767, 0.0196166, 0.980389}, {0.137257, 0.0196166, 0.916927}, {0.150431, 0.0384908, 0.595764}, {0.064942, 0.16305, 0.694812}, {0.064942, 0.0384908, 0.707568}, {0.18961, 0.0384908, 0.694812}, {0.329163, 0.890428, 0.197279}, {0.329163, 0.765869, 0.0727203}, {0.428211, 0.805072, 0.0727203}, {0.393994, 0.74576, 0.18349}, {0.359771, 0.928919, 0.223656}, {0.424601, 0.784251, 0.209866}, {0.458819, 0.843563, 0.0990968}, {0.458819, 0.928919, 0.184453}, {0.954883, 0.165684, 0.108851}, {0.954883, 0.214025, 0.0453883}, {0.891421, 0.165684, 0.0453883}, {0.872344, 0.194287, 0.128805}, {0.0196166, 0.0830735, 0.862766}, {0.0196166, 0.019611, 0.814425}, {0.0830972, 0.019611, 0.862766}, {0.0196166, 0.019611, 0.926229}, {0.814425, 0.980389, 0.019611}, {0.862766, 0.916927, 0.019611}, {0.926229, 0.980389, 0.019611}, {0.862766, 0.980389, 0.0830735}, {0.111907, 0.0263765, 0.465451}, {0.0264176, 0.0263765, 0.465451}, {0.0264176, 0.111733, 0.465451}, {0.0264176, 0.0263765, 0.353647}, {0.0849421, 0.235803, 0.641902}, {0.170431, 0.111244, 0.542853}, {0.0849421, 0.1966, 0.542853}, {0.274331, 0.261324, 0.582482}, {0.646353, 0.973624, 0.0263765}, {0.534549, 0.973624, 0.0263765}, {0.534549, 0.888267, 0.0263765}, {0.534549, 0.973624, 0.111733}, {0.428245, 0.1966, 0.0727203}, {0.394027, 0.261324, 0.18349}, {0.329197, 0.235803, 0.0727203}, {0.329306, 0.111244, 0.197279}, {0.45889, 0.15811, 0.0990968}, {0.459011, 0.0727535, 0.184453}, {0.424672, 0.222833, 0.209866}, {0.359951, 0.0727535, 0.223656}, {0.980389, 0.980389, 0.0737711}, {0.980389, 0.980389, 0.185575}, {0.916927, 0.980389, 0.137234}, {0.980389, 0.916927, 0.137234}, {0.0392276, 0.10269, 0.897316}, {0.10269, 0.102708, 0.960778}, {0.0392276, 0.0392276, 0.960778}, {0.102708, 0.0392276, 0.897316}, {0.810574, 0.961492, 0.694795}, {0.935133, 0.961492, 0.707551}, {0.935133, 0.836879, 0.694741}, {0.849777, 0.961492, 0.595747}, {0.973624, 0.935097, 0.676925}, {0.973624, 0.849681, 0.565061}, {0.973624, 0.810484, 0.664115}, {0.888267, 0.935097, 0.565121}, {0.410652, 0.954221, 0.54719}, {0.358814, 0.806076, 0.60085}, {0.311604, 0.954221, 0.646238}, {0.272401, 0.954221, 0.54719}, {0.768073, 0.774026, 0.650918}, {0.771136, 0.917238, 0.681426}, {0.895695, 0.792625, 0.681372}, {0.810339, 0.917238, 0.582378}, {0.934186, 0.805426, 0.551692}, {0.806563, 0.747631, 0.620292}, {0.934186, 0.766229, 0.650746}, {0.84883, 0.890843, 0.551752}, {0.897123, 0.506329, 0.192706}, {0.791765, 0.585322, 0.218174}, {0.811767, 0.506383, 0.107404}, {0.75492, 0.448155, 0.258901}, {0.741125, 0.311703, 0.0725924}, {0.72348, 0.352523, 0.224089}, {0.783145, 0.27921, 0.156009}, {0.780328, 0.410751, 0.0725924}, {0.557857, 0.0927541, 0.555099}, {0.655925, 0.0927541, 0.654147}, {0.675126, 0.242833, 0.594728}, {0.52266, 0.242833, 0.594728}, {0.019611, 0.137234, 0.0830735}, {0.019611, 0.0737711, 0.019611}, {0.019611, 0.185575, 0.019611}, {0.0830735, 0.137234, 0.019611}, {0.800383, 0.582348, 0.644518}, {0.928005, 0.501892, 0.714168}, {0.822647, 0.428425, 0.615606}, {0.928005, 0.501462, 0.575488}, {0.510971, 0.35515, 0.191814}, {0.644237, 0.32963, 0.0810446}, {0.545189, 0.428678, 0.0810446}, {0.626593, 0.37045, 0.232541}, {0.897316, 0.897316, 0.039222}, {0.960778, 0.960778, 0.039222}, {0.897316, 0.960778, 0.102684}, {0.960778, 0.897316, 0.102684}, {0.679888, 0.393171, 0.198312}, {0.697533, 0.352351, 0.0468151}, {0.598484, 0.451399, 0.0468151}, {0.736735, 0.451399, 0.0468151}, {0.862085, 0.717976, 0.203101}, {0.967443, 0.750841, 0.0923313}, {0.967443, 0.799182, 0.155794}, {0.967443, 0.738085, 0.21689}, {0.967443, 0.589479, 0.184382}, {0.862085, 0.668472, 0.209849}, {0.967443, 0.688581, 0.223639}, {0.967443, 0.701337, 0.09908}, {0.973624, 0.973605, 0.646334}, {0.973624, 0.973605, 0.53453}, {0.973624, 0.888188, 0.53447}, {0.888267, 0.973605, 0.53453}, {0.0263765, 0.534549, 0.0263765}, {0.0263765, 0.646353, 0.0263765}, {0.0263765, 0.534549, 0.111733}, {0.111733, 0.534549, 0.0263765}, {0.449561, 0.0927541, 0.44677}, {0.414364, 0.242833, 0.486398}, {0.414364, 0.242833, 0.333932}, {0.349642, 0.0927541, 0.347722}, {0.13554, 0.247951, 0.741607}, {0.324929, 0.273472, 0.682188}, {0.260098, 0.24806, 0.866166}, {0.260207, 0.123392, 0.741607}, {0.175574, 0.478951, 0.442508}, {0.364963, 0.405423, 0.482137}, {0.364963, 0.405423, 0.329671}, {0.364963, 0.55789, 0.329671}, {0.278357, 0.0463771, 0.542853}, {0.417454, 0.0463771, 0.542853}, {0.382257, 0.196456, 0.582482}, {0.317535, 0.0463771, 0.641902}, {0.534587, 0.111733, 0.0263765}, {0.534707, 0.0263765, 0.111733}, {0.534587, 0.0263765, 0.0263765}, {0.64639, 0.0263765, 0.0263765}, {0.170129, 0.524991, 0.493959}, {0.341897, 0.600453, 0.54762}, {0.359518, 0.451464, 0.533588}, {0.359518, 0.60393, 0.381122}, {0.465451, 0.973624, 0.0263765}, {0.465451, 0.973624, 0.111733}, {0.353647, 0.973624, 0.0263765}, {0.465451, 0.888267, 0.0263765}, {0.980389, 0.0830735, 0.137234}, {0.916927, 0.019611, 0.137234}, {0.980389, 0.019611, 0.0737711}, {0.980389, 0.019611, 0.185575}, {0.459313, 0.0463771, 0.253551}, {0.460172, 0.0463771, 0.391802}, {0.424975, 0.196456, 0.278964}, {0.360253, 0.0463771, 0.292754}, {0.83294, 0.63566, 0.662862}, {0.960562, 0.555204, 0.732513}, {0.960562, 0.554774, 0.593833}, {0.960562, 0.654258, 0.693316}, {0.761971, 0.383114, 0.250449}, {0.904174, 0.441287, 0.184254}, {0.821635, 0.309801, 0.182369}, {0.818818, 0.441342, 0.098952}, {0.378848, 0.5764, 0.720685}, {0.430686, 0.501918, 0.890631}, {0.292435, 0.501059, 0.890631}, {0.396468, 0.42741, 0.706653}, {0.980389, 0.019611, 0.814425}, {0.916927, 0.019611, 0.862766}, {0.980389, 0.019611, 0.926229}, {0.980389, 0.0830735, 0.862766}, {0.251225, 0.741209, 0.60085}, {0.164812, 0.889353, 0.54719}, {0.079456, 0.803997, 0.54719}, {0.079456, 0.764795, 0.646238}, {0.509948, 0.864811, 0.446845}, {0.45811, 0.716666, 0.500505}, {0.475731, 0.720143, 0.334007}, {0.628197, 0.720143, 0.334007}, {0.967443, 0.554778, 0.253329}, {0.862085, 0.633772, 0.278796}, {0.967443, 0.554343, 0.391144}, {0.967443, 0.653881, 0.292586}, {0.417454, 0.0463771, 0.481638}, {0.278357, 0.0463771, 0.481638}, {0.382257, 0.196456, 0.521267}, {0.317535, 0.0463771, 0.38259}, {0.141181, 0.141175, 0.039222}, {0.0777183, 0.141175, 0.102684}, {0.141199, 0.0777127, 0.102684}, {0.202277, 0.202271, 0.039222}, {0.121564, 0.194662, 0.961509}, {0.0581018, 0.25574, 0.83695}, {0.0581018, 0.242984, 0.961509}, {0.182661, 0.255849, 0.961509}, {0.534707, 0.0264176, 0.888267}, {0.534587, 0.0264176, 0.973624}, {0.64639, 0.0264176, 0.973624}, {0.534587, 0.111907, 0.973624}, {0.0264176, 0.189426, 0.664205}, {0.111907, 0.0648672, 0.565157}, {0.0264176, 0.0648672, 0.67696}, {0.0264176, 0.150223, 0.565157}, {0.805396, 0.121622, 0.961509}, {0.7443, 0.058141, 0.83695}, {0.757055, 0.058141, 0.961509}, {0.7443, 0.182809, 0.961509}, {0.707568, 0.935133, 0.0384908}, {0.694812, 0.935133, 0.16305}, {0.595764, 0.849777, 0.0384908}, {0.694812, 0.810574, 0.0384908}, {0.0585245, 0.403949, 0.542853}, {0.0585245, 0.304901, 0.641902}, {0.0585245, 0.265699, 0.542853}, {0.247914, 0.330422, 0.582482}, {0.019611, 0.980389, 0.0737711}, {0.019611, 0.916927, 0.137234}, {0.0830735, 0.980389, 0.137234}, {0.019611, 0.980389, 0.185575}, {0.32737, 0.427108, 0.680277}, {0.309749, 0.576097, 0.694309}, {0.137981, 0.500635, 0.778899}, {0.223337, 0.500756, 0.864255}, {0.401536, 0.806076, 0.643572}, {0.453374, 0.954221, 0.589911}, {0.354326, 0.954221, 0.688959}, {0.453374, 0.954221, 0.728162}, {0.458819, 0.405307, 0.943148}, {0.424601, 0.330799, 0.75917}, {0.458819, 0.266209, 0.943148}, {0.359771, 0.305388, 0.943148}, {0.778849, 0.0966318, 0.79846}, {0.903407, 0.221191, 0.79846}, {0.778849, 0.221299, 0.923018}, {0.839945, 0.160112, 0.923018}, {0.973624, 0.646336, 0.0263597}, {0.973624, 0.534478, 0.111661}, {0.888267, 0.534532, 0.0263597}, {0.973624, 0.534532, 0.0263597}, {0.0585245, 0.347623, 0.292754}, {0.0585245, 0.446671, 0.391802}, {0.247914, 0.373144, 0.278964}, {0.0585245, 0.446671, 0.253551}, {0.0970153, 0.684657, 0.223656}, {0.221574, 0.684657, 0.0990968}, {0.286405, 0.664547, 0.209866}, {0.0970153, 0.585608, 0.184453}, {0.0648672, 0.32304, 0.0263765}, {0.150223, 0.434843, 0.0263765}, {0.0648672, 0.434843, 0.111733}, {0.189426, 0.335795, 0.0263765}, {0.669371, 0.609732, 0.226043}, {0.516905, 0.609732, 0.226043}, {0.551122, 0.530793, 0.115274}, {0.632526, 0.472566, 0.266771}, {0.485816, 0.330422, 0.144999}, {0.520034, 0.265699, 0.0342296}, {0.520034, 0.403949, 0.0342296}, {0.619082, 0.304901, 0.0342296}, {0.748566, 0.0463771, 0.542853}, {0.709255, 0.0463771, 0.641902}, {0.728456, 0.196456, 0.582482}, {0.611186, 0.0463771, 0.542853}, {0.13554, 0.247917, 0.23577}, {0.324929, 0.273438, 0.22198}, {0.260207, 0.123359, 0.23577}, {0.260098, 0.247917, 0.111211}, {0.242979, 0.058141, 0.961509}, {0.194638, 0.121622, 0.961509}, {0.255734, 0.182809, 0.961509}, {0.255843, 0.058141, 0.83695}, {0.123467, 0.209427, 0.672509}, {0.208956, 0.0848678, 0.573461}, {0.312856, 0.234947, 0.61309}, {0.248134, 0.0848678, 0.672509}, {0.0648672, 0.67696, 0.0263765}, {0.150223, 0.565157, 0.0263765}, {0.189426, 0.664205, 0.0263765}, {0.0648672, 0.565157, 0.111733}, {0.60299, 0.955745, 0.551788}, {0.698974, 0.812534, 0.620327}, {0.741241, 0.955745, 0.551788}, {0.702038, 0.955745, 0.650836}, {0.69485, 0.0385244, 0.810574}, {0.595923, 0.0385244, 0.849777}, {0.707605, 0.0385244, 0.935133}, {0.69485, 0.163192, 0.935133}, {0.460172, 0.0463771, 0.585575}, {0.459313, 0.0463771, 0.723826}, {0.424975, 0.196456, 0.625204}, {0.360253, 0.0463771, 0.684623}, {0.973624, 0.565098, 0.849681}, {0.973624, 0.676962, 0.935097}, {0.973624, 0.664152, 0.810484}, {0.888267, 0.56528, 0.935097}, {0.973624, 0.465409, 0.888188}, {0.973624, 0.353666, 0.973605}, {0.973624, 0.46547, 0.973605}, {0.888267, 0.46559, 0.973605}, {0.664205, 0.973624, 0.189426}, {0.67696, 0.973624, 0.0648672}, {0.565157, 0.888267, 0.0648672}, {0.565157, 0.973624, 0.150223}, {0.0830735, 0.862766, 0.980389}, {0.019611, 0.862766, 0.916927}, {0.019611, 0.814425, 0.980389}, {0.019611, 0.926229, 0.980389}, {0.25462, 0.75268, 0.870502}, {0.30183, 0.729094, 0.700556}, {0.130061, 0.75268, 0.745943}, {0.25462, 0.877239, 0.745943}, {0.0970153, 0.317016, 0.223656}, {0.286405, 0.342536, 0.209866}, {0.221574, 0.317016, 0.0990968}, {0.0970153, 0.416064, 0.184453}, {0.039222, 0.897316, 0.897316}, {0.102684, 0.897316, 0.960778}, {0.102684, 0.960778, 0.897316}, {0.039222, 0.960778, 0.960778}, {0.771136, 0.685127, 0.913574}, {0.768073, 0.666475, 0.758507}, {0.895695, 0.685073, 0.788961}, {0.810339, 0.5862, 0.913574}, {0.778704, 0.610031, 0.351039}, {0.756439, 0.611488, 0.532416}, {0.741859, 0.472864, 0.391767}, {0.884062, 0.530602, 0.463387}, {0.286405, 0.34257, 0.694302}, {0.0970153, 0.317049, 0.753722}, {0.221574, 0.317158, 0.87828}, {0.0970153, 0.416097, 0.792924}, {0.0581074, 0.160055, 0.141175}, {0.0581074, 0.221151, 0.202271}, {0.121588, 0.0965925, 0.141175}, {0.182666, 0.221151, 0.0777127}, {0.728119, 0.373517, 0.75917}, {0.60987, 0.448025, 0.943148}, {0.708918, 0.348106, 0.943148}, {0.748121, 0.447166, 0.943148}, {0.935133, 0.707588, 0.961492}, {0.810574, 0.694833, 0.961492}, {0.935133, 0.694778, 0.836879}, {0.849777, 0.595906, 0.961492}, {0.410652, 0.555246, 0.947484}, {0.358814, 0.629729, 0.777538}, {0.272401, 0.554388, 0.947484}, {0.311604, 0.653315, 0.947484}, {0.312781, 0.373215, 0.732793}, {0.247951, 0.347803, 0.916771}, {0.208748, 0.446863, 0.916771}, {0.123392, 0.446742, 0.831415}, {0.0263765, 0.534587, 0.973624}, {0.0263765, 0.64639, 0.973624}, {0.111733, 0.534707, 0.973624}, {0.0263765, 0.534587, 0.888267}, {0.702038, 0.654839, 0.952082}, {0.698974, 0.636187, 0.797015}, {0.741241, 0.555912, 0.952082}, {0.60299, 0.556771, 0.952082}, {0.897316, 0.897313, 0.960775}, {0.897316, 0.960775, 0.897313}, {0.960778, 0.960775, 0.960775}, {0.960778, 0.897304, 0.897304}, {0.67696, 0.973657, 0.935133}, {0.565157, 0.973657, 0.849777}, {0.664205, 0.973657, 0.810574}, {0.565157, 0.88841, 0.935133}, {0.774006, 0.582537, 0.713767}, {0.901629, 0.502081, 0.783418}, {0.816273, 0.502262, 0.868834}, {0.796271, 0.428614, 0.684856}, {0.941898, 0.980386, 0.775932}, {0.817339, 0.980386, 0.763177}, {0.941898, 0.916915, 0.824264}, {0.878436, 0.980386, 0.824273}, {0.608924, 0.503442, 0.895229}, {0.704908, 0.582858, 0.740162}, {0.747174, 0.502583, 0.895229}, {0.727172, 0.428935, 0.711251}, {0.83695, 0.941879, 0.74428}, {0.961509, 0.941879, 0.757035}, {0.961509, 0.878407, 0.805367}, {0.961509, 0.817265, 0.744226}, {0.058141, 0.0384908, 0.757055}, {0.058141, 0.16305, 0.7443}, {0.121622, 0.0384908, 0.805396}, {0.182809, 0.0384908, 0.7443}, {0.759022, 0.754188, 0.875083}, {0.755958, 0.735536, 0.720016}, {0.759022, 0.878747, 0.750525}, {0.883581, 0.754134, 0.75047}, {0.0196166, 0.121564, 0.824276}, {0.0196166, 0.182661, 0.763179}, {0.0830972, 0.0581018, 0.824276}, {0.0196166, 0.0581018, 0.775935}, {0.305188, 0.810608, 0.961509}, {0.305188, 0.935166, 0.83695}, {0.292432, 0.935166, 0.961509}, {0.404236, 0.849919, 0.961509}, {0.058141, 0.16305, 0.2557}, {0.121622, 0.0384908, 0.194604}, {0.182809, 0.0384908, 0.2557}, {0.058141, 0.0384908, 0.242945}, {0.2557, 0.961509, 0.817339}, {0.2557, 0.83695, 0.941898}, {0.242945, 0.961509, 0.941898}, {0.194604, 0.961509, 0.878436}, {0.849919, 0.0384908, 0.595764}, {0.810608, 0.0384908, 0.694812}, {0.935166, 0.0384908, 0.707568}, {0.935166, 0.16305, 0.694812}, {0.0196166, 0.0830735, 0.137234}, {0.0196166, 0.019611, 0.0737711}, {0.0830972, 0.019611, 0.137234}, {0.0196166, 0.019611, 0.185575}, {0.381879, 0.373144, 0.144999}, {0.277846, 0.446671, 0.0342296}, {0.416097, 0.446671, 0.0342296}, {0.317049, 0.347623, 0.0342296}, {0.292466, 0.0648672, 0.0384908}, {0.404269, 0.150223, 0.0384908}, {0.305221, 0.189426, 0.0384908}, {0.30533, 0.0648672, 0.16305}, {0.0581018, 0.224065, 0.019611}, {0.0581018, 0.175724, 0.0830735}, {0.121564, 0.175724, 0.019611}, {0.182661, 0.236821, 0.019611}, {0.306438, 0.428145, 0.274703}, {0.117049, 0.501672, 0.387541}, {0.306438, 0.580611, 0.274703}, {0.117049, 0.501672, 0.24929}, {0.228782, 0.501672, 0.0948356}, {0.332815, 0.428145, 0.205605}, {0.332815, 0.580611, 0.205605}, {0.143426, 0.501672, 0.180192}, {0.824276, 0.878436, 0.019611}, {0.775935, 0.941898, 0.019611}, {0.763179, 0.817339, 0.019611}, {0.824276, 0.941898, 0.0830735}, {0.019611, 0.862766, 0.0830735}, {0.019611, 0.814425, 0.019611}, {0.019611, 0.926229, 0.019611}, {0.0830735, 0.862766, 0.019611}, {0.189426, 0.335975, 0.973624}, {0.150223, 0.435035, 0.973624}, {0.0648672, 0.434914, 0.888267}, {0.0648672, 0.323111, 0.973624}, {0.960562, 0.736176, 0.55154}, {0.83294, 0.678382, 0.62014}, {0.960562, 0.597496, 0.551111}, {0.960562, 0.69698, 0.650594}, {0.0263765, 0.465451, 0.0263765}, {0.111733, 0.465451, 0.0263765}, {0.0263765, 0.465451, 0.111733}, {0.0263765, 0.353647, 0.0263765}, {0.111733, 0.465609, 0.973624}, {0.0263765, 0.465488, 0.973624}, {0.0263765, 0.465488, 0.888267}, {0.0263765, 0.353685, 0.973624}, {0.890461, 0.247951, 0.741607}, {0.765902, 0.123392, 0.741607}, {0.765902, 0.24806, 0.866166}, {0.785103, 0.273472, 0.682188}, {0.696804, 0.890428, 0.197279}, {0.716005, 0.74576, 0.18349}, {0.597756, 0.805072, 0.0727203}, {0.696804, 0.765869, 0.0727203}, {0.0648672, 0.961509, 0.707568}, {0.150223, 0.961509, 0.595764}, {0.189426, 0.961509, 0.694812}, {0.0648672, 0.83695, 0.694812}, {0.459216, 0.38743, 0.459854}, {0.459216, 0.38743, 0.307388}, {0.459216, 0.539896, 0.307388}, {0.574837, 0.40273, 0.348115}, {0.401913, 0.428145, 0.179228}, {0.29788, 0.501672, 0.0684591}, {0.401913, 0.580611, 0.179228}, {0.436131, 0.501672, 0.0684591}, {0.242984, 0.0384908, 0.0581018}, {0.194662, 0.0384908, 0.121564}, {0.255849, 0.0384908, 0.182661}, {0.25574, 0.16305, 0.0581018}, {0.160112, 0.0769815, 0.160055}, {0.0966318, 0.20154, 0.221151}, {0.221299, 0.0769815, 0.221151}, {0.221191, 0.20154, 0.0965925}, {0.930551, 0.41068, 0.222744}, {0.930551, 0.311686, 0.262002}, {0.788348, 0.352506, 0.288939}, {0.848012, 0.279193, 0.22086}, {0.778017, 0.688598, 0.0342296}, {0.797217, 0.668489, 0.144999}, {0.817219, 0.58955, 0.0342296}, {0.902575, 0.701354, 0.0342296}, {0.956057, 0.352183, 0.305171}, {0.956057, 0.451176, 0.265914}, {0.813854, 0.393003, 0.332109}, {0.956057, 0.450741, 0.403729}, {0.565194, 0.150223, 0.0263765}, {0.565315, 0.0648672, 0.111733}, {0.676997, 0.0648672, 0.0263765}, {0.664242, 0.189426, 0.0263765}, {0.111733, 0.935133, 0.565157}, {0.0263765, 0.935133, 0.67696}, {0.0263765, 0.849777, 0.565157}, {0.0263765, 0.810574, 0.664205}, {0.0830735, 0.175748, 0.941898}, {0.019611, 0.236826, 0.817339}, {0.019611, 0.17573, 0.878436}, {0.019611, 0.224071, 0.941898}, {0.0530795, 0.596648, 0.54719}, {0.224848, 0.67211, 0.60085}, {0.0530795, 0.734899, 0.54719}, {0.0530795, 0.695696, 0.646238}, {0.757055, 0.961509, 0.0581018}, {0.7443, 0.961509, 0.182661}, {0.7443, 0.83695, 0.0581018}, {0.805396, 0.961509, 0.121564}, {0.0585245, 0.347623, 0.684623}, {0.0585245, 0.446671, 0.585575}, {0.0585245, 0.446671, 0.723826}, {0.247914, 0.373144, 0.625204}, {0.019611, 0.775935, 0.0581018}, {0.019611, 0.824276, 0.121564}, {0.019611, 0.763179, 0.182661}, {0.0830735, 0.824276, 0.0581018}, {0.0384908, 0.305188, 0.189426}, {0.0384908, 0.292432, 0.0648672}, {0.0384908, 0.404236, 0.150223}, {0.16305, 0.305188, 0.0648672}, {0.46979, 0.562618, 0.226043}, {0.46979, 0.410151, 0.226043}, {0.504008, 0.483679, 0.115274}, {0.585411, 0.425451, 0.266771}, {0.818381, 0.150014, 0.0257773}, {0.77004, 0.0865518, 0.0257773}, {0.799304, 0.178618, 0.109194}, {0.757284, 0.211111, 0.0257773}, {0.019611, 0.980389, 0.814425}, {0.019611, 0.916927, 0.862766}, {0.0830735, 0.980389, 0.862766}, {0.019611, 0.980389, 0.926229}, {0.835708, 0.637865, 0.171358}, {0.941066, 0.558871, 0.145891}, {0.85571, 0.558926, 0.0605892}, {0.941066, 0.670729, 0.0605892}, {0.224848, 0.629388, 0.643572}, {0.0530795, 0.553927, 0.589911}, {0.0530795, 0.553927, 0.728162}, {0.0530795, 0.652975, 0.688959}, {0.83695, 0.74428, 0.941879}, {0.961509, 0.757035, 0.941879}, {0.961509, 0.744226, 0.817265}, {0.961509, 0.805367, 0.878407}, {0.465609, 0.0264176, 0.888267}, {0.353685, 0.0264176, 0.973624}, {0.465488, 0.0264176, 0.973624}, {0.465488, 0.111907, 0.973624}, {0.0263765, 0.973624, 0.646353}, {0.111733, 0.973624, 0.534549}, {0.0263765, 0.888267, 0.534549}, {0.0263765, 0.973624, 0.534549}, {0.954883, 0.111523, 0.163011}, {0.891421, 0.048061, 0.163011}, {0.954883, 0.048061, 0.211352}, {0.872344, 0.140127, 0.182966}, {0.817339, 0.763177, 0.980386}, {0.878436, 0.824273, 0.980386}, {0.941898, 0.775932, 0.980386}, {0.941898, 0.824264, 0.916915}, {0.974494, 0.211111, 0.242987}, {0.974494, 0.150014, 0.181891}, {0.974494, 0.0865518, 0.230232}, {0.891955, 0.178618, 0.201845}, {0.019611, 0.137239, 0.916927}, {0.0830735, 0.137257, 0.980389}, {0.019611, 0.18558, 0.980389}, {0.019611, 0.0737767, 0.980389}, {0.973657, 0.189409, 0.664188}, {0.88841, 0.0648504, 0.56514}, {0.973657, 0.150152, 0.565085}, {0.973657, 0.0648504, 0.676943}, {0.916927, 0.137257, 0.980389}, {0.980389, 0.18558, 0.980389}, {0.980389, 0.0737767, 0.980389}, {0.980389, 0.137239, 0.916927}, {0.88841, 0.0263597, 0.465434}, {0.973657, 0.0263597, 0.465434}, {0.973657, 0.0263597, 0.353631}, {0.973657, 0.111661, 0.46538}, {0.424601, 0.676662, 0.144999}, {0.359771, 0.696771, 0.0342296}, {0.458819, 0.735973, 0.0342296}, {0.458819, 0.597723, 0.0342296}, {0.807388, 0.916804, 0.155794}, {0.746291, 0.916804, 0.21689}, {0.746291, 0.792246, 0.0923313}, {0.765492, 0.772136, 0.203101}, {0.260065, 0.753755, 0.111211}, {0.260065, 0.878314, 0.23577}, {0.135506, 0.753755, 0.23577}, {0.324895, 0.733646, 0.22198}, {0.756439, 0.564373, 0.579531}, {0.778704, 0.41045, 0.55062}, {0.741859, 0.42575, 0.438881}, {0.884062, 0.483488, 0.510501}, {0.973657, 0.0263597, 0.646336}, {0.88841, 0.0263597, 0.534532}, {0.973657, 0.111661, 0.534478}, {0.973657, 0.0263597, 0.534532}, {0.722667, 0.585339, 0.191814}, {0.685821, 0.448172, 0.232541}, {0.604418, 0.5064, 0.0810446}, {0.742669, 0.5064, 0.0810446}, {0.646167, 0.72205, 0.571433}, {0.498345, 0.717116, 0.556554}, {0.550183, 0.865261, 0.502893}, {0.668432, 0.720593, 0.390056}, {0.941898, 0.242984, 0.961509}, {0.941898, 0.25574, 0.83695}, {0.878436, 0.194662, 0.961509}, {0.817339, 0.255849, 0.961509}, {0.862766, 0.0196166, 0.916927}, {0.862766, 0.0830972, 0.980389}, {0.814425, 0.0196166, 0.980389}, {0.926229, 0.0196166, 0.980389}, {0.708918, 0.654049, 0.0342296}, {0.728119, 0.63394, 0.144999}, {0.60987, 0.555001, 0.0342296}, {0.748121, 0.555001, 0.0342296}, {0.277846, 0.555001, 0.0342296}, {0.317049, 0.654049, 0.0342296}, {0.381879, 0.63394, 0.144999}, {0.416097, 0.555001, 0.0342296}, {0.458819, 0.955295, 0.391802}, {0.359771, 0.955295, 0.292754}, {0.458819, 0.955295, 0.253551}, {0.424601, 0.810627, 0.278964}, {0.461804, 0.735478, 0.703243}, {0.609626, 0.740412, 0.718122}, {0.513642, 0.883623, 0.787833}, {0.513642, 0.798376, 0.873189}, {0.980389, 0.926229, 0.019611}, {0.916927, 0.862766, 0.019611}, {0.980389, 0.814425, 0.019611}, {0.980389, 0.862766, 0.0830735}, {0.453374, 0.597965, 0.947484}, {0.401536, 0.672447, 0.777538}, {0.354326, 0.696033, 0.947484}, {0.453374, 0.735344, 0.947484}, {0.329197, 0.235987, 0.904657}, {0.394027, 0.261398, 0.720679}, {0.428245, 0.196808, 0.904657}, {0.329306, 0.111319, 0.780098}, {0.818381, 0.02845, 0.147342}, {0.757284, 0.02845, 0.208438}, {0.799304, 0.120516, 0.167296}, {0.77004, 0.02845, 0.0838791}, {0.0384908, 0.707568, 0.0648672}, {0.16305, 0.694812, 0.0648672}, {0.0384908, 0.694812, 0.189426}, {0.0384908, 0.595764, 0.150223}, {0.0737711, 0.980389, 0.019611}, {0.137234, 0.916927, 0.019611}, {0.185575, 0.980389, 0.019611}, {0.137234, 0.980389, 0.0830735}, {0.039222, 0.858825, 0.141175}, {0.102684, 0.858825, 0.0777127}, {0.102684, 0.922287, 0.141175}, {0.039222, 0.797729, 0.202271}, {0.0581018, 0.83695, 0.2557}, {0.182661, 0.961509, 0.2557}, {0.121564, 0.961509, 0.194604}, {0.0581018, 0.961509, 0.242945}, {0.247951, 0.654049, 0.060606}, {0.208748, 0.555001, 0.060606}, {0.312781, 0.63394, 0.171375}, {0.123392, 0.555001, 0.145962}, {0.0585245, 0.555001, 0.391802}, {0.0585245, 0.654049, 0.292754}, {0.247914, 0.63394, 0.278964}, {0.0585245, 0.555001, 0.253551}, {0.019611, 0.878436, 0.175724}, {0.019611, 0.817339, 0.236821}, {0.0830735, 0.941898, 0.175724}, {0.019611, 0.941898, 0.224065}, {0.424672, 0.222874, 0.694302}, {0.459011, 0.0727946, 0.792924}, {0.45889, 0.158284, 0.87828}, {0.359951, 0.0727946, 0.753722}, {0.824276, 0.0830972, 0.941898}, {0.763179, 0.0196166, 0.817339}, {0.824276, 0.0196166, 0.878436}, {0.775935, 0.0196166, 0.941898}, {0.335795, 0.973657, 0.810574}, {0.434843, 0.973657, 0.849777}, {0.32304, 0.973657, 0.935133}, {0.434843, 0.88841, 0.935133}, {0.465451, 0.973657, 0.888267}, {0.465451, 0.973657, 0.973624}, {0.353647, 0.973657, 0.973624}, {0.465451, 0.88841, 0.973624}, {0.150223, 0.973624, 0.434843}, {0.189426, 0.973624, 0.335795}, {0.0648672, 0.888267, 0.434843}, {0.0648672, 0.973624, 0.32304}, {0.102684, 0.897316, 0.039222}, {0.039222, 0.897316, 0.102684}, {0.102684, 0.960778, 0.102684}, {0.039222, 0.960778, 0.039222}, {0.16305, 0.935133, 0.305188}, {0.0384908, 0.810574, 0.305188}, {0.0384908, 0.849777, 0.404236}, {0.0384908, 0.935133, 0.292432}, {0.111907, 0.0263765, 0.534549}, {0.0264176, 0.0263765, 0.534549}, {0.0264176, 0.0263765, 0.646353}, {0.0264176, 0.111733, 0.534549}, {0.292466, 0.064942, 0.961509}, {0.305221, 0.18961, 0.961509}, {0.404269, 0.150431, 0.961509}, {0.30533, 0.064942, 0.83695}, {0.980389, 0.236826, 0.817339}, {0.980389, 0.224071, 0.941898}, {0.916927, 0.175748, 0.941898}, {0.980389, 0.17573, 0.878436}, {0.897316, 0.0392276, 0.897316}, {0.897316, 0.102708, 0.960778}, {0.960778, 0.0392276, 0.960778}, {0.960778, 0.10269, 0.897316}, {0.224071, 0.0581018, 0.019611}, {0.17573, 0.121564, 0.019611}, {0.175748, 0.0581018, 0.0830735}, {0.236826, 0.182661, 0.019611}, {0.0384908, 0.2557, 0.182661}, {0.0384908, 0.194604, 0.121564}, {0.0384908, 0.242945, 0.0581018}, {0.16305, 0.2557, 0.0581018}, {0.79846, 0.903388, 0.778829}, {0.79846, 0.778829, 0.903388}, {0.923018, 0.778775, 0.778775}, {0.923018, 0.839916, 0.839916}, {0.980389, 0.185575, 0.019611}, {0.980389, 0.137234, 0.0830735}, {0.916927, 0.137234, 0.019611}, {0.980389, 0.0737711, 0.019611}, {0.9411, 0.235786, 0.641885}, {0.855853, 0.111227, 0.542837}, {0.835742, 0.261307, 0.582465}, {0.9411, 0.196529, 0.542782}, {0.806563, 0.635849, 0.732112}, {0.934186, 0.555393, 0.801762}, {0.934186, 0.654447, 0.762566}, {0.84883, 0.555574, 0.887179}, {0.435035, 0.0264176, 0.849777}, {0.323111, 0.0264176, 0.935133}, {0.434914, 0.111907, 0.935133}, {0.335975, 0.0264176, 0.810574}, {0.458819, 0.265699, 0.0342296}, {0.424601, 0.330422, 0.144999}, {0.458819, 0.403949, 0.0342296}, {0.359771, 0.304901, 0.0342296}, {0.941898, 0.961509, 0.242945}, {0.878436, 0.961509, 0.194604}, {0.941898, 0.83695, 0.2557}, {0.817339, 0.961509, 0.2557}, {0.980389, 0.817339, 0.236821}, {0.916927, 0.941898, 0.175724}, {0.980389, 0.941898, 0.224065}, {0.980389, 0.878436, 0.175724}, {0.845878, 0.916804, 0.194285}, {0.803983, 0.772136, 0.241591}, {0.909341, 0.792246, 0.255381}, {0.784782, 0.916804, 0.255381}, {0.947832, 0.772635, 0.236501}, {0.842474, 0.752525, 0.222712}, {0.884369, 0.897193, 0.175405}, {0.947832, 0.833731, 0.175405}, {0.354326, 0.927878, 0.758058}, {0.453374, 0.842631, 0.882617}, {0.401536, 0.779733, 0.71267}, {0.453374, 0.927878, 0.79726}, {0.370928, 0.741242, 0.739047}, {0.422766, 0.80414, 0.908993}, {0.323718, 0.889387, 0.784434}, {0.323718, 0.764828, 0.908993}, {0.221717, 0.111244, 0.304868}, {0.0970489, 0.1966, 0.403916}, {0.286438, 0.261324, 0.291079}, {0.0970489, 0.235803, 0.304868}, {0.064942, 0.111733, 0.434843}, {0.064942, 0.0263765, 0.32304}, {0.18961, 0.0263765, 0.335795}, {0.150431, 0.0263765, 0.434843}, {0.163192, 0.0648672, 0.305188}, {0.0385244, 0.0648672, 0.292432}, {0.0385244, 0.150223, 0.404236}, {0.0385244, 0.189426, 0.305188}, {0.202271, 0.797729, 0.960778}, {0.141175, 0.922287, 0.897316}, {0.0777127, 0.858825, 0.897316}, {0.141175, 0.858825, 0.960778}, {0.182661, 0.763179, 0.980389}, {0.0581018, 0.824276, 0.916927}, {0.0581018, 0.775935, 0.980389}, {0.121564, 0.824276, 0.980389}, {0.0384908, 0.757055, 0.941898}, {0.0384908, 0.805396, 0.878436}, {0.16305, 0.7443, 0.941898}, {0.0384908, 0.7443, 0.817339}, {0.781296, 0.358168, 0.417684}, {0.923499, 0.27809, 0.48974}, {0.923499, 0.415905, 0.489305}, {0.818141, 0.342868, 0.529423}, {0.956057, 0.408019, 0.446451}, {0.956057, 0.270204, 0.446887}, {0.813854, 0.350281, 0.374831}, {0.956057, 0.309461, 0.347893}, {0.805396, 0.878436, 0.961509}, {0.757055, 0.941898, 0.961509}, {0.7443, 0.941898, 0.83695}, {0.7443, 0.817339, 0.961509}, {0.763179, 0.980389, 0.817339}, {0.775935, 0.980389, 0.941898}, {0.824276, 0.916927, 0.941898}, {0.824276, 0.980389, 0.878436}, {0.839945, 0.858822, 0.941895}, {0.778849, 0.922284, 0.817337}, {0.903407, 0.858813, 0.878424}, {0.778849, 0.797726, 0.941895}, {0.922287, 0.897304, 0.858813}, {0.797729, 0.960775, 0.797726}, {0.858825, 0.897313, 0.922284}, {0.858825, 0.960775, 0.858822}, {0.929714, 0.240514, 0.348044}, {0.787511, 0.281334, 0.374982}, {0.844467, 0.115955, 0.447092}, {0.929714, 0.201257, 0.447038}, {0.973657, 0.0648504, 0.323023}, {0.973657, 0.189409, 0.335778}, {0.88841, 0.0648504, 0.434826}, {0.973657, 0.150152, 0.434772}, {0.680224, 0.216484, 0.374999}, {0.73718, 0.0511049, 0.447109}, {0.599801, 0.0511049, 0.447109}, {0.697869, 0.0511049, 0.348061}, {0.686158, 0.262861, 0.417853}, {0.605734, 0.097482, 0.489963}, {0.743114, 0.097482, 0.489963}, {0.723003, 0.247561, 0.529591}, {0.948118, 0.312982, 0.052137}, {0.948118, 0.424731, 0.137439}, {0.862762, 0.424786, 0.052137}, {0.865579, 0.293245, 0.135554}, {0.888267, 0.465434, 0.0263597}, {0.973624, 0.46538, 0.111661}, {0.973624, 0.353631, 0.0263597}, {0.973624, 0.465434, 0.0263597}, {0.858825, 0.121588, 0.903407}, {0.922287, 0.182666, 0.778849}, {0.858825, 0.0581074, 0.839945}, {0.797729, 0.0581074, 0.778849}, {0.897316, 0.141199, 0.922287}, {0.897316, 0.0777183, 0.858825}, {0.960778, 0.202277, 0.797729}, {0.960778, 0.141181, 0.858825}, {0.878436, 0.0384908, 0.805396}, {0.941898, 0.16305, 0.7443}, {0.941898, 0.0384908, 0.757055}, {0.817339, 0.0384908, 0.7443}, {0.916927, 0.0581018, 0.824276}, {0.980389, 0.0581018, 0.775935}, {0.980389, 0.182661, 0.763179}, {0.980389, 0.121564, 0.824276}, {0.248134, 0.0727535, 0.38259}, {0.312856, 0.222833, 0.521267}, {0.123467, 0.15811, 0.481638}, {0.208956, 0.0727535, 0.481638}, {0.280241, 0.119131, 0.347722}, {0.155573, 0.204487, 0.44677}, {0.344963, 0.26921, 0.486398}, {0.344963, 0.26921, 0.333932}, {0.247914, 0.330422, 0.321686}, {0.0585245, 0.265699, 0.434524}, {0.0585245, 0.403949, 0.434524}, {0.0585245, 0.304901, 0.335476}, {0.117049, 0.411836, 0.477377}, {0.117049, 0.273585, 0.477377}, {0.306438, 0.338308, 0.36454}, {0.306438, 0.338308, 0.517006}, {0.748121, 0.955295, 0.434524}, {0.728119, 0.810627, 0.321686}, {0.60987, 0.955295, 0.434524}, {0.708918, 0.955295, 0.335476}, {0.608924, 0.91104, 0.486311}, {0.727172, 0.766372, 0.373474}, {0.747174, 0.91104, 0.486311}, {0.704908, 0.767829, 0.554851}, {0.837795, 0.140127, 0.148416}, {0.808531, 0.048061, 0.0649993}, {0.920334, 0.111523, 0.128462}, {0.856871, 0.048061, 0.128462}, {0.920334, 0.131134, 0.108851}, {0.808531, 0.067672, 0.0453883}, {0.837795, 0.159738, 0.128805}, {0.856871, 0.131134, 0.0453883}, {0.834036, 0.019611, 0.039222}, {0.94584, 0.019611, 0.039222}, {0.94584, 0.0830735, 0.102684}, {0.882377, 0.019611, 0.102684}, {0.94584, 0.102684, 0.0830735}, {0.94584, 0.039222, 0.019611}, {0.834036, 0.039222, 0.019611}, {0.882377, 0.102684, 0.019611}, {0.689924, 0.890912, 0.789032}, {0.590876, 0.805664, 0.913591}, {0.68686, 0.7477, 0.758524}, {0.689924, 0.766353, 0.913591}, {0.656253, 0.786191, 0.732147}, {0.560268, 0.844155, 0.887214}, {0.659316, 0.929402, 0.762656}, {0.560268, 0.929402, 0.801858}, {0.0965925, 0.778849, 0.20154}, {0.160055, 0.839945, 0.0769815}, {0.221151, 0.903407, 0.20154}, {0.221151, 0.778849, 0.0769815}, {0.0777127, 0.817339, 0.221151}, {0.202271, 0.941898, 0.221151}, {0.141175, 0.878436, 0.0965925}, {0.141175, 0.941898, 0.160055}, {0.2557, 0.941898, 0.16305}, {0.194604, 0.878436, 0.0384908}, {0.242945, 0.941898, 0.0384908}, {0.2557, 0.817339, 0.0384908}, {0.236821, 0.980389, 0.182661}, {0.224065, 0.980389, 0.0581018}, {0.175724, 0.916927, 0.0581018}, {0.175724, 0.980389, 0.121564}, {0.619082, 0.928919, 0.223656}, {0.520034, 0.843563, 0.0990968}, {0.485816, 0.784251, 0.209866}, {0.520034, 0.928919, 0.184453}, {0.522357, 0.739546, 0.217719}, {0.556575, 0.798858, 0.10695}, {0.655623, 0.884214, 0.231509}, {0.674824, 0.739546, 0.217719}, {0.619082, 0.955295, 0.292754}, {0.485816, 0.810627, 0.278964}, {0.520034, 0.955295, 0.391802}, {0.520034, 0.955295, 0.253551}, {0.556575, 0.91059, 0.399655}, {0.522357, 0.765922, 0.286817}, {0.655623, 0.91059, 0.300607}, {0.674824, 0.765922, 0.286817}, {0.619119, 0.235803, 0.060606}, {0.520192, 0.111244, 0.145962}, {0.485854, 0.261324, 0.171375}, {0.520071, 0.1966, 0.060606}, {0.644274, 0.260531, 0.107421}, {0.511009, 0.286052, 0.21819}, {0.545347, 0.135973, 0.192777}, {0.62663, 0.301352, 0.258918}, {0.835708, 0.373162, 0.694284}, {0.85571, 0.446811, 0.878262}, {0.941066, 0.347642, 0.753703}, {0.941066, 0.446629, 0.792845}, {0.902575, 0.317087, 0.780098}, {0.817219, 0.416256, 0.904657}, {0.797217, 0.342607, 0.720679}, {0.778017, 0.317196, 0.904657}, {0.888267, 0.434983, 0.935114}, {0.973624, 0.323059, 0.935114}, {0.973624, 0.335814, 0.810555}, {0.973624, 0.434802, 0.849698}, {0.935133, 0.305259, 0.83695}, {0.935133, 0.292503, 0.961509}, {0.849777, 0.404428, 0.961509}, {0.810574, 0.305368, 0.961509}, {0.619119, 0.235987, 0.916771}, {0.485854, 0.261398, 0.732793}, {0.520192, 0.111319, 0.831415}, {0.520071, 0.196808, 0.916771}, {0.556575, 0.425266, 0.886295}, {0.655623, 0.325347, 0.886295}, {0.522357, 0.350759, 0.702317}, {0.674824, 0.350759, 0.702317}, {0.520034, 0.405307, 0.943148}, {0.485816, 0.330799, 0.75917}, {0.619082, 0.305388, 0.943148}, {0.520034, 0.266209, 0.943148}, {0.242505, 0.927844, 0.386926}, {0.117947, 0.842488, 0.485975}, {0.289716, 0.779699, 0.539635}, {0.203303, 0.927844, 0.485975}, {0.321864, 0.734995, 0.504766}, {0.150095, 0.797783, 0.451106}, {0.274654, 0.883139, 0.352058}, {0.339484, 0.738471, 0.338268}, {0.311604, 0.954221, 0.386926}, {0.358814, 0.806076, 0.539635}, {0.410652, 0.954221, 0.485975}, {0.272401, 0.954221, 0.485975}, {0.4428, 0.909516, 0.451106}, {0.390962, 0.761371, 0.504766}, {0.343752, 0.909516, 0.352058}, {0.408582, 0.764848, 0.338268}, {0.0384908, 0.878436, 0.805396}, {0.0384908, 0.941898, 0.757055}, {0.16305, 0.941898, 0.7443}, {0.0384908, 0.817339, 0.7443}, {0.182661, 0.980389, 0.763179}, {0.0581018, 0.980389, 0.775935}, {0.0581018, 0.916927, 0.824276}, {0.121564, 0.980389, 0.824276}, {0.0769815, 0.839945, 0.839945}, {0.20154, 0.903407, 0.778849}, {0.20154, 0.778849, 0.903407}, {0.0769815, 0.778849, 0.778849}, {0.221151, 0.817339, 0.922287}, {0.221151, 0.941898, 0.797729}, {0.0965925, 0.878436, 0.858825}, {0.160055, 0.941898, 0.858825}, {0.609626, 0.766755, 0.649024}, {0.513642, 0.909966, 0.718735}, {0.513642, 0.909966, 0.580484}, {0.461804, 0.761821, 0.634145}, {0.560268, 0.955745, 0.594509}, {0.560268, 0.955745, 0.73276}, {0.656253, 0.812534, 0.663049}, {0.659316, 0.955745, 0.693557}, {0.556224, 0.0511049, 0.266137}, {0.637506, 0.216484, 0.332277}, {0.557083, 0.0511049, 0.404387}, {0.655151, 0.0511049, 0.305339}, {0.515901, 0.097482, 0.400126}, {0.596325, 0.262861, 0.328016}, {0.515042, 0.097482, 0.261875}, {0.480704, 0.247561, 0.287289}, {0.797729, 0.797729, 0.039222}, {0.858825, 0.922287, 0.102684}, {0.922287, 0.858825, 0.102684}, {0.858825, 0.858825, 0.039222}, {0.784782, 0.772635, 0.0734515}, {0.909341, 0.833731, 0.136914}, {0.845878, 0.897193, 0.136914}, {0.803983, 0.752525, 0.184221}, {0.941898, 0.775935, 0.019611}, {0.817339, 0.763179, 0.019611}, {0.941898, 0.824276, 0.0830735}, {0.878436, 0.824276, 0.019611}, {0.928952, 0.750841, 0.0538406}, {0.928952, 0.799182, 0.117303}, {0.804393, 0.738085, 0.0538406}, {0.823594, 0.717976, 0.16461}, {0.516461, 0.234981, 0.694302}, {0.649727, 0.0849015, 0.753722}, {0.649727, 0.209569, 0.87828}, {0.5508, 0.0849015, 0.792924}, {0.552965, 0.281358, 0.663826}, {0.68623, 0.255946, 0.847805}, {0.68623, 0.131279, 0.723246}, {0.705431, 0.281358, 0.663826}, {0.644216, 0.670447, 0.179228}, {0.525967, 0.729759, 0.0684591}, {0.525967, 0.591509, 0.0684591}, {0.49175, 0.670447, 0.179228}, {0.567148, 0.597723, 0.0342296}, {0.567148, 0.735973, 0.0342296}, {0.685397, 0.676662, 0.144999}, {0.666196, 0.696771, 0.0342296}, {0.902575, 0.792246, 0.304868}, {0.797217, 0.772136, 0.291079}, {0.817219, 0.916804, 0.403916}, {0.778017, 0.916804, 0.304868}, {0.888267, 0.935114, 0.434825}, {0.973624, 0.810555, 0.335777}, {0.973624, 0.935114, 0.323021}, {0.973624, 0.849698, 0.434764}, {0.935133, 0.961509, 0.292432}, {0.935133, 0.83695, 0.305188}, {0.849777, 0.961509, 0.404236}, {0.810574, 0.961509, 0.305188}, {0.656253, 0.678905, 0.797015}, {0.560268, 0.736869, 0.952082}, {0.560268, 0.599489, 0.952082}, {0.659316, 0.697557, 0.952082}, {0.513642, 0.592201, 0.899565}, {0.513642, 0.72958, 0.899565}, {0.609626, 0.671616, 0.744498}, {0.461804, 0.666683, 0.729619}, {0.0585245, 0.735973, 0.434524}, {0.247914, 0.676662, 0.321686}, {0.0585245, 0.597723, 0.434524}, {0.0585245, 0.696771, 0.335476}, {0.111604, 0.590434, 0.481713}, {0.300993, 0.669373, 0.368876}, {0.111604, 0.728685, 0.481713}, {0.283373, 0.665896, 0.535374}, {0.117947, 0.553964, 0.835751}, {0.289716, 0.629426, 0.751161}, {0.242505, 0.653012, 0.921107}, {0.203303, 0.554085, 0.921107}, {0.0915703, 0.584534, 0.79726}, {0.216129, 0.683582, 0.882617}, {0.263339, 0.659996, 0.71267}, {0.0915703, 0.683582, 0.758058}, {0.0648672, 0.676997, 0.973624}, {0.0648672, 0.565194, 0.888267}, {0.189426, 0.664242, 0.973624}, {0.150223, 0.565315, 0.973624}, {0.0384908, 0.707568, 0.935133}, {0.16305, 0.694812, 0.935133}, {0.0384908, 0.595764, 0.849777}, {0.0384908, 0.694812, 0.810574}, {0.948151, 0.0669408, 0.279719}, {0.865612, 0.159007, 0.251333}, {0.862904, 0.0669408, 0.391522}, {0.948151, 0.1915, 0.292474}, {0.824413, 0.02845, 0.391522}, {0.827122, 0.120516, 0.251333}, {0.90966, 0.02845, 0.279719}, {0.785102, 0.02845, 0.292474}, {0.821669, 0.210112, 0.263599}, {0.762005, 0.283425, 0.331678}, {0.818961, 0.118046, 0.403788}, {0.904208, 0.242604, 0.30474}, {0.78047, 0.0795549, 0.403788}, {0.723514, 0.244934, 0.331678}, {0.783178, 0.171621, 0.263599}, {0.741159, 0.0795549, 0.30474}, {0.72059, 0.02845, 0.0906446}, {0.749854, 0.120516, 0.174062}, {0.608907, 0.02845, 0.176001}, {0.707834, 0.02845, 0.215203}, {0.608907, 0.0669408, 0.13751}, {0.749854, 0.159007, 0.135571}, {0.72059, 0.0669408, 0.0521538}, {0.707834, 0.1915, 0.0521538}, {0.74046, 0.171621, 0.220877}, {0.680796, 0.244934, 0.288956}, {0.599513, 0.0795549, 0.222816}, {0.69844, 0.0795549, 0.262018}, {0.599513, 0.118046, 0.184325}, {0.680796, 0.283425, 0.250466}, {0.74046, 0.210112, 0.182386}, {0.69844, 0.242604, 0.0989688}, {0.816273, 0.87255, 0.455704}, {0.901629, 0.747991, 0.356656}, {0.774006, 0.729338, 0.524244}, {0.796271, 0.727882, 0.342866}, {0.806563, 0.747648, 0.559094}, {0.934186, 0.766301, 0.391506}, {0.84883, 0.890859, 0.490554}, {0.934186, 0.805443, 0.490493}, {0.928005, 0.678741, 0.356504}, {0.928005, 0.579203, 0.455062}, {0.800383, 0.660089, 0.524092}, {0.822647, 0.658632, 0.342715}, {0.83294, 0.678398, 0.558942}, {0.960562, 0.597513, 0.489912}, {0.960562, 0.697051, 0.391354}, {0.960562, 0.736193, 0.490342}}
+]
+
diff --git a/test/test_fe_engine/test_interpolate_tetrahedron_4.verified b/test/test_fe_engine/test_interpolate_tetrahedron_4.verified
new file mode 100644
index 000000000..3e557d540
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_tetrahedron_4.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 131
+ + nb_component : 2
+ + allocated size : 131
+ + memory size : 2.05KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 341
+ + nb_component : 2
+ + allocated size : 341
+ + memory size : 5.33KiByte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 341
+ + nb_component : 3
+ + allocated size : 341
+ + memory size : 7.99KiByte
+ + values : {{0.563503, 0.427428, 0.533993}, {0.836513, 0.308597, 0.0466316}, {0.507797, 0.260243, 0.418764}, {0.617937, 0.117481, 0.952285}, {0.133463, 0.0354766, 0.0354766}, {0.0709634, 0.0709532, 0.0709532}, {0.223218, 0.403527, 0.109637}, {0.593029, 0.260243, 0.503996}, {0.953859, 0.219074, 0.151739}, {0.0709634, 0.140594, 0.859416}, {0.140655, 0.105117, 0.825262}, {0.203155, 0.0354867, 0.894893}, {0.823818, 0.153527, 0.632892}, {0.517997, 0.460526, 0.699304}, {0.953859, 0.308567, 0.163947}, {0.848752, 0.219074, 0.0466316}, {0.636288, 0.598705, 0.464923}, {0.673239, 0.882715, 0.93037}, {0.0354867, 0.105107, 0.203084}, {0.941103, 0.325939, 0.577218}, {0.848752, 0.0514666, 0.214239}, {0.636288, 0.513474, 0.550155}, {0.964523, 0.964518, 0.866542}, {0.563503, 0.59789, 0.36353}, {0.348218, 0.404204, 0.897153}, {0.0477155, 0.952285, 0.4375}, {0.437568, 0.0477155, 0.0477155}, {0.866547, 0.964523, 0.964523}, {0.5625, 0.952345, 0.952285}, {0.964523, 0.866542, 0.964518}, {0.478271, 0.512659, 0.448761}, {0.952285, 0.952251, 0.437466}, {0.175502, 0.801782, 0.326183}, {0.203084, 0.894893, 0.964523}, {0.952285, 0.562534, 0.952251}, {0.813955, 0.224032, 0.481812}, {0.590782, 0.546572, 0.715465}, {0.536857, 0.0838969, 0.654807}, {0.941103, 0.40322, 0.6545}, {0.105107, 0.762762, 0.0696305}, {0.133453, 0.964523, 0.964523}, {0.861609, 0.511274, 0.319022}, {0.38213, 0.952285, 0.117346}, {0.382259, 0.0477155, 0.117346}, {0.326761, 0.882654, 0.0696305}, {0.213368, 0.847554, 0.640736}, {0.174798, 0.174809, 0.860739}, {0.0696305, 0.326822, 0.882654}, {0.201894, 0.501081, 0.629435}, {0.133463, 0.0354867, 0.964523}, {0.117481, 0.0696305, 0.673239}, {0.370133, 0.801782, 0.131552}, {0.425502, 0.871413, 0.179268}, {0.918383, 0.18492, 0.0821082}, {0.0354867, 0.0354766, 0.866547}, {0.866547, 0.964523, 0.0354766}, {0.0477899, 0.0477155, 0.4375}, {0.153662, 0.201243, 0.577523}, {0.5625, 0.952285, 0.0477155}, {0.370194, 0.201243, 0.131552}, {0.425631, 0.131612, 0.179268}, {0.964523, 0.964523, 0.133453}, {0.0709634, 0.0709634, 0.929047}, {0.882654, 0.930339, 0.673209}, {0.952285, 0.88259, 0.617805}, {0.338368, 0.917185, 0.585367}, {0.811311, 0.850282, 0.649024}, {0.880941, 0.802532, 0.59362}, {0.813894, 0.511547, 0.194296}, {0.757019, 0.338547, 0.131321}, {0.602892, 0.167794, 0.599676}, {0.0354766, 0.133453, 0.0354766}, {0.86976, 0.503532, 0.637445}, {0.581747, 0.370977, 0.146611}, {0.929047, 0.929047, 0.0709532}, {0.67816, 0.41208, 0.0846892}, {0.941103, 0.751521, 0.167029}, {0.941103, 0.661967, 0.179237}, {0.952285, 0.952251, 0.562466}, {0.0477155, 0.5625, 0.0477155}, {0.406983, 0.167794, 0.403705}, {0.245194, 0.223219, 0.757892}, {0.317616, 0.461922, 0.395997}, {0.348901, 0.0838969, 0.577523}, {0.562568, 0.0477155, 0.0477155}, {0.307765, 0.54521, 0.489072}, {0.4375, 0.952285, 0.0477155}, {0.964523, 0.0354766, 0.133453}, {0.426179, 0.0838969, 0.304268}, {0.928657, 0.599974, 0.670631}, {0.82665, 0.393886, 0.179006}, {0.374609, 0.501697, 0.80215}, {0.964523, 0.0354766, 0.866547}, {0.143737, 0.799839, 0.585367}, {0.517997, 0.755441, 0.403841}, {0.941103, 0.599193, 0.303964}, {0.348901, 0.0838969, 0.466784}, {0.140594, 0.140584, 0.0709532}, {0.105107, 0.237309, 0.93037}, {0.562568, 0.0477899, 0.952285}, {0.0477899, 0.117346, 0.61787}, {0.762762, 0.105178, 0.93037}, {0.673239, 0.882654, 0.0696305}, {0.105872, 0.326243, 0.577523}, {0.0354766, 0.964523, 0.133453}, {0.249609, 0.501149, 0.754435}, {0.415652, 0.917185, 0.662651}, {0.425502, 0.326926, 0.897153}, {0.825262, 0.174809, 0.860739}, {0.952285, 0.56247, 0.0476851}, {0.105872, 0.403527, 0.304268}, {0.175502, 0.654867, 0.179268}, {0.117346, 0.38213, 0.0477155}, {0.592481, 0.555706, 0.208533}, {0.536241, 0.326243, 0.0619219}, {0.699366, 0.0838969, 0.577523}, {0.245194, 0.223158, 0.201183}, {0.237298, 0.105178, 0.93037}, {0.223353, 0.153527, 0.632892}, {0.117346, 0.61787, 0.0477155}, {0.686311, 0.919942, 0.593684}, {0.673307, 0.0696913, 0.882654}, {0.426179, 0.0838969, 0.654807}, {0.952285, 0.617873, 0.88259}, {0.952285, 0.437534, 0.952251}, {0.61787, 0.952285, 0.117346}, {0.0354766, 0.866547, 0.964523}, {0.235283, 0.777924, 0.765736}, {0.175502, 0.348158, 0.179268}, {0.0709532, 0.929047, 0.929047}, {0.811311, 0.655719, 0.843654}, {0.790266, 0.556246, 0.434652}, {0.175502, 0.348219, 0.779807}, {0.105117, 0.174738, 0.140584}, {0.698757, 0.404204, 0.897153}, {0.882654, 0.673276, 0.930339}, {0.338368, 0.598169, 0.904997}, {0.223218, 0.403656, 0.849438}, {0.0477155, 0.562568, 0.952285}, {0.686311, 0.600927, 0.913315}, {0.929047, 0.929042, 0.929042}, {0.61787, 0.952345, 0.882654}, {0.822044, 0.503873, 0.762719}, {0.894893, 0.964518, 0.796911}, {0.697044, 0.504455, 0.810468}, {0.93037, 0.894857, 0.762727}, {0.105178, 0.0696305, 0.762762}, {0.789396, 0.780651, 0.774024}, {0.0354867, 0.105107, 0.796916}, {0.326761, 0.882715, 0.93037}, {0.105178, 0.0696305, 0.237238}, {0.237238, 0.93037, 0.894893}, {0.882715, 0.0696305, 0.673239}, {0.0354867, 0.0354766, 0.133453}, {0.348218, 0.403527, 0.0619219}, {0.326822, 0.117346, 0.0696305}, {0.105107, 0.203084, 0.0354766}, {0.211744, 0.503025, 0.296559}, {0.259459, 0.503025, 0.171559}, {0.796916, 0.894893, 0.0354766}, {0.0354766, 0.866547, 0.0354766}, {0.117346, 0.382259, 0.952285}, {0.928657, 0.677258, 0.593346}, {0.0477155, 0.4375, 0.0477155}, {0.0477155, 0.437568, 0.952285}, {0.801842, 0.223219, 0.757892}, {0.676842, 0.801782, 0.131552}, {0.117346, 0.93037, 0.673239}, {0.488122, 0.429372, 0.355686}, {0.384459, 0.503025, 0.123844}, {0.237309, 0.0696305, 0.105107}, {0.174809, 0.139261, 0.174738}, {0.874365, 0.338516, 0.248636}, {0.823757, 0.661998, 0.0619219}, {0.920506, 0.411776, 0.326731}, {0.617937, 0.117346, 0.0477155}, {0.0477155, 0.882654, 0.61787}, {0.0354766, 0.203094, 0.894893}, {0.0960217, 0.674839, 0.585367}, {0.762762, 0.93037, 0.105107}, {0.105872, 0.403527, 0.654807}, {0.0354766, 0.796916, 0.105107}, {0.0696305, 0.326761, 0.117346}, {0.50725, 0.470475, 0.208533}, {0.786252, 0.156574, 0.0466316}, {0.0354766, 0.964523, 0.866547}, {0.893388, 0.606598, 0.109607}, {0.0960217, 0.597554, 0.662651}, {0.93037, 0.762727, 0.894857}, {0.437568, 0.0477899, 0.952285}, {0.0477155, 0.952285, 0.5625}, {0.918383, 0.0869432, 0.180085}, {0.894893, 0.796911, 0.964518}, {0.953859, 0.156574, 0.214239}, {0.0354766, 0.133463, 0.964523}, {0.952345, 0.117316, 0.617839}, {0.964523, 0.133463, 0.964523}, {0.952345, 0.0476851, 0.43747}, {0.425502, 0.676782, 0.0619219}, {0.766366, 0.849498, 0.167029}, {0.245133, 0.779867, 0.201183}, {0.790266, 0.471015, 0.519883}, {0.952345, 0.0476851, 0.56247}, {0.688894, 0.511578, 0.146611}, {0.590782, 0.756255, 0.505234}, {0.894893, 0.237309, 0.93037}, {0.866547, 0.0354867, 0.964523}, {0.698757, 0.599498, 0.0619219}, {0.348218, 0.599498, 0.0619219}, {0.425502, 0.919128, 0.304268}, {0.524679, 0.789472, 0.770597}, {0.964523, 0.866547, 0.0354766}, {0.415652, 0.675447, 0.904997}, {0.370194, 0.201378, 0.827523}, {0.786252, 0.0514666, 0.151739}, {0.0696305, 0.673239, 0.117346}, {0.133453, 0.964523, 0.0354766}, {0.0709532, 0.859416, 0.140584}, {0.105107, 0.93037, 0.237238}, {0.223218, 0.599498, 0.109637}, {0.105872, 0.599498, 0.304268}, {0.0354766, 0.894893, 0.203084}, {0.425631, 0.131687, 0.779807}, {0.796916, 0.0354867, 0.894893}, {0.38213, 0.952345, 0.882654}, {0.4375, 0.952345, 0.952285}, {0.117346, 0.952285, 0.38213}, {0.0709532, 0.929047, 0.0709532}, {0.0696305, 0.882654, 0.326761}, {0.0477899, 0.0477155, 0.5625}, {0.326822, 0.117481, 0.93037}, {0.964523, 0.203094, 0.894893}, {0.929047, 0.0709634, 0.929047}, {0.203094, 0.105107, 0.0354766}, {0.0696305, 0.237238, 0.105107}, {0.860739, 0.825227, 0.825227}, {0.964523, 0.133453, 0.0354766}, {0.893448, 0.201212, 0.577492}, {0.880941, 0.600315, 0.795905}, {0.382259, 0.0477899, 0.882654}, {0.425502, 0.326243, 0.0619219}, {0.894893, 0.93037, 0.237238}, {0.964523, 0.894893, 0.203084}, {0.835996, 0.849498, 0.236659}, {0.905627, 0.814021, 0.202506}, {0.415652, 0.86953, 0.787651}, {0.360283, 0.799899, 0.835367}, {0.175563, 0.201243, 0.326183}, {0.117481, 0.0477155, 0.38213}, {0.0696913, 0.117346, 0.326761}, {0.140584, 0.859416, 0.929047}, {0.105107, 0.796916, 0.964523}, {0.0696305, 0.762762, 0.894893}, {0.861609, 0.348758, 0.481538}, {0.920506, 0.334491, 0.404015}, {0.762762, 0.894893, 0.93037}, {0.796916, 0.964523, 0.894893}, {0.825262, 0.859411, 0.894888}, {0.859416, 0.929042, 0.859411}, {0.872851, 0.209765, 0.404289}, {0.952345, 0.117316, 0.3821}, {0.678769, 0.0924497, 0.40432}, {0.689502, 0.176347, 0.481842}, {0.906144, 0.363936, 0.0943167}, {0.952285, 0.43747, 0.0476851}, {0.859416, 0.105117, 0.825262}, {0.929047, 0.140594, 0.859416}, {0.894893, 0.0696305, 0.762762}, {0.964523, 0.105107, 0.796916}, {0.223353, 0.131612, 0.466784}, {0.281435, 0.215509, 0.403705}, {0.105872, 0.326243, 0.381552}, {0.211744, 0.340509, 0.459075}, {0.698757, 0.919128, 0.381552}, {0.697044, 0.839071, 0.475237}, {0.855883, 0.0869432, 0.117585}, {0.855883, 0.12242, 0.0821082}, {0.902023, 0.0354766, 0.0709532}, {0.902023, 0.0709532, 0.0354766}, {0.664396, 0.802657, 0.843684}, {0.609026, 0.872288, 0.795969}, {0.174738, 0.825262, 0.139261}, {0.140584, 0.894893, 0.174738}, {0.237238, 0.894893, 0.0696305}, {0.203084, 0.964523, 0.105107}, {0.536241, 0.871413, 0.179268}, {0.602345, 0.790541, 0.193474}, {0.536241, 0.919128, 0.304268}, {0.602345, 0.838256, 0.318474}, {0.536309, 0.201243, 0.109637}, {0.581815, 0.245977, 0.194327}, {0.893388, 0.403561, 0.779773}, {0.823757, 0.348286, 0.827523}, {0.952285, 0.382164, 0.88262}, {0.882654, 0.326889, 0.93037}, {0.536309, 0.201378, 0.849438}, {0.602345, 0.363033, 0.794306}, {0.536241, 0.326926, 0.897153}, {0.213368, 0.869469, 0.474628}, {0.271524, 0.788597, 0.41155}, {0.338368, 0.917185, 0.474628}, {0.396524, 0.836313, 0.41155}, {0.0696305, 0.894893, 0.762762}, {0.105107, 0.964523, 0.796916}, {0.139261, 0.825262, 0.825262}, {0.174738, 0.894893, 0.859416}, {0.524679, 0.837127, 0.645597}, {0.609026, 0.919942, 0.670969}, {0.601491, 0.0924497, 0.327035}, {0.526993, 0.176347, 0.319327}, {0.859416, 0.859416, 0.0709532}, {0.835996, 0.814021, 0.132875}, {0.894893, 0.796916, 0.0354766}, {0.871473, 0.751521, 0.0973985}, {0.591679, 0.153588, 0.779807}, {0.657714, 0.237485, 0.724676}, {0.546975, 0.665541, 0.123844}, {0.621473, 0.676782, 0.0619219}, {0.823757, 0.849498, 0.326183}, {0.952285, 0.88262, 0.382097}, {0.882654, 0.93037, 0.326761}, {0.609026, 0.678205, 0.913315}, {0.524679, 0.66502, 0.818312}, {0.105872, 0.676782, 0.381552}, {0.201894, 0.663597, 0.466919}, {0.213368, 0.597622, 0.857282}, {0.165652, 0.652924, 0.787651}, {0.117346, 0.617937, 0.952285}, {0.0696305, 0.673239, 0.882654}, {0.906205, 0.121097, 0.303762}, {0.836574, 0.0514666, 0.303762}, {0.826711, 0.213547, 0.325951}, {0.75708, 0.143916, 0.325951}, {0.696797, 0.0514666, 0.163978}, {0.696797, 0.121097, 0.0943471}, {0.679803, 0.143916, 0.248667}, {0.679803, 0.213547, 0.179036}, {0.822044, 0.76944, 0.419867}, {0.880941, 0.802563, 0.482912}, {0.86976, 0.644166, 0.419593}, {0.928657, 0.677289, 0.482638}}
+]
+
diff --git a/test/test_fe_engine/test_interpolate_triangle_3.verified b/test/test_fe_engine/test_interpolate_triangle_3.verified
new file mode 100644
index 000000000..8f7394610
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_triangle_3.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 13
+ + nb_component : 2
+ + allocated size : 13
+ + memory size : 208.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 16
+ + nb_component : 2
+ + allocated size : 16
+ + memory size : 256.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 16
+ + nb_component : 2
+ + allocated size : 16
+ + memory size : 256.00Byte
+ + values : {{0.25, 0.916667}, {0.0833333, 0.25}, {0.916667, 0.75}, {0.75, 0.0833333}, {0.25, 0.583333}, {0.416667, 0.75}, {0.583333, 0.75}, {0.25, 0.416667}, {0.75, 0.583333}, {0.416667, 0.25}, {0.583333, 0.25}, {0.75, 0.416667}, {0.25, 0.0833333}, {0.0833333, 0.75}, {0.916667, 0.25}, {0.75, 0.916667}}
+]
+
diff --git a/test/test_fe_engine/test_interpolate_triangle_6.verified b/test/test_fe_engine/test_interpolate_triangle_6.verified
new file mode 100644
index 000000000..9a72e33f5
--- /dev/null
+++ b/test/test_fe_engine/test_interpolate_triangle_6.verified
@@ -0,0 +1,37 @@
+Epsilon : 3e-13
+Interpolation of array : Array<double> [
+ + id : const_val
+ + size : 41
+ + nb_component : 2
+ + allocated size : 41
+ + memory size : 656.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Gives on quads : Array<double> [
+ + id : val_on_quad
+ + size : 48
+ + nb_component : 2
+ + allocated size : 48
+ + memory size : 768.00Byte
+ + values : {{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}}
+]
+
+Interpolations of node coordinates : 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}}
+]
+
+Gives : Array<double> [
+ + id : coord_on_quad
+ + size : 48
+ + nb_component : 2
+ + allocated size : 48
+ + memory size : 768.00Byte
+ + values : {{0.125, 0.958333}, {0.25, 0.833333}, {0.375, 0.958333}, {0.0416667, 0.125}, {0.166667, 0.25}, {0.0416667, 0.375}, {0.958333, 0.875}, {0.833333, 0.75}, {0.958333, 0.625}, {0.875, 0.0416667}, {0.75, 0.166667}, {0.625, 0.0416667}, {0.125, 0.541667}, {0.375, 0.541667}, {0.25, 0.666667}, {0.458333, 0.875}, {0.333333, 0.75}, {0.458333, 0.625}, {0.541667, 0.875}, {0.541667, 0.625}, {0.666667, 0.75}, {0.125, 0.458333}, {0.25, 0.333333}, {0.375, 0.458333}, {0.875, 0.541667}, {0.75, 0.666667}, {0.625, 0.541667}, {0.458333, 0.125}, {0.458333, 0.375}, {0.333333, 0.25}, {0.541667, 0.125}, {0.666667, 0.25}, {0.541667, 0.375}, {0.875, 0.458333}, {0.625, 0.458333}, {0.75, 0.333333}, {0.125, 0.0416667}, {0.375, 0.0416667}, {0.25, 0.166667}, {0.0416667, 0.875}, {0.0416667, 0.625}, {0.166667, 0.75}, {0.958333, 0.125}, {0.958333, 0.375}, {0.833333, 0.25}, {0.875, 0.958333}, {0.625, 0.958333}, {0.75, 0.833333}}
+]
+
diff --git a/test/test_fe_engine/test_inverse_map.cc b/test/test_fe_engine/test_inverse_map.cc
new file mode 100644
index 000000000..2c23f2403
--- /dev/null
+++ b/test/test_fe_engine/test_inverse_map.cc
@@ -0,0 +1,105 @@
+/**
+ * @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
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "aka_common.hh"
+#include "fe_engine.hh"
+#include "shape_lagrange.hh"
+#include "integrator_gauss.hh"
+/* -------------------------------------------------------------------------- */
+#include <cstdlib>
+#include <iostream>
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+ akantu::initialize(argc, argv);
+
+ debug::setDebugLevel(dblTest);
+ const ElementType type = TYPE;
+ UInt dim = ElementClass<type>::getSpatialDimension();
+
+ Mesh my_mesh(dim);
+
+ my_mesh.computeBoundingBox();
+ const Vector<Real> & lower = my_mesh.getLowerBounds();
+ const Vector<Real> & upper = my_mesh.getUpperBounds();
+
+ std::stringstream meshfilename; meshfilename << type << ".msh";
+ my_mesh.read(meshfilename.str());
+
+ UInt nb_elements = my_mesh.getNbElement(type);
+ ///
+ FEEngineTemplate<IntegratorGauss,ShapeLagrange> *fem =
+ new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
+
+ fem->initShapeFunctions();
+
+ UInt nb_quad_points = fem->getNbIntegrationPoints(type);
+
+ /// get the quadrature points coordinates
+ Array<Real> coord_on_quad(nb_quad_points*nb_elements,
+ my_mesh.getSpatialDimension(),
+ "coord_on_quad");
+
+ fem->interpolateOnIntegrationPoints(my_mesh.getNodes(),
+ coord_on_quad,
+ my_mesh.getSpatialDimension(),
+ type);
+
+
+ /// loop over the quadrature points
+ Array<Real>::iterator< Vector<Real> > it = coord_on_quad.begin(dim);
+ Vector<Real> natural_coords(dim);
+
+ Matrix<Real> quad = GaussIntegrationElement<type>::getQuadraturePoints();
+
+ for(UInt el = 0 ; el < nb_elements ; ++el){
+ for(UInt q = 0 ; q < nb_quad_points ; ++q){
+ fem->inverseMap(*it, el, type, natural_coords);
+ for (UInt i = 0; i < dim; ++i) {
+ __attribute__ ((unused)) const Real eps = 1e-13;
+ AKANTU_DEBUG_ASSERT(std::abs((natural_coords(i) - quad(i,q))/(upper(i)-lower(i))) < eps,
+ "real coordinates inversion test failed:"
+ << natural_coords(i) << " - " << quad(i, q)
+ << " = " << (natural_coords(i) - quad(i, q))/(upper(i)-lower(i)));
+ }
+ ++it;
+ }
+ }
+
+ std::cout << "inverse completed over " << nb_elements << " elements" << std::endl;
+
+ delete fem;
+ finalize();
+
+ return EXIT_SUCCESS;
+}
diff --git a/test/test_fe_engine/test_inverse_map_hexahedron_20.verified b/test/test_fe_engine/test_inverse_map_hexahedron_20.verified
new file mode 100644
index 000000000..2e23c245e
--- /dev/null
+++ b/test/test_fe_engine/test_inverse_map_hexahedron_20.verified
@@ -0,0 +1 @@
+inverse completed over 8 elements
diff --git a/test/test_fem/test_inverse_map_hexahedron_8.verified b/test/test_fe_engine/test_inverse_map_hexahedron_8.verified
similarity index 100%
rename from test/test_fem/test_inverse_map_hexahedron_8.verified
rename to test/test_fe_engine/test_inverse_map_hexahedron_8.verified
diff --git a/test/test_fem/test_inverse_map_quadrangle_4.verified b/test/test_fe_engine/test_inverse_map_quadrangle_4.verified
similarity index 100%
rename from test/test_fem/test_inverse_map_quadrangle_4.verified
rename to test/test_fe_engine/test_inverse_map_quadrangle_4.verified
diff --git a/test/test_fem/test_inverse_map_quadrangle_8.verified b/test/test_fe_engine/test_inverse_map_quadrangle_8.verified
similarity index 100%
rename from test/test_fem/test_inverse_map_quadrangle_8.verified
rename to test/test_fe_engine/test_inverse_map_quadrangle_8.verified
diff --git a/test/test_fem/test_inverse_map_segment_2.verified b/test/test_fe_engine/test_inverse_map_segment_2.verified
similarity index 100%
rename from test/test_fem/test_inverse_map_segment_2.verified
rename to test/test_fe_engine/test_inverse_map_segment_2.verified
diff --git a/test/test_fem/test_inverse_map_segment_3.verified b/test/test_fe_engine/test_inverse_map_segment_3.verified
similarity index 100%
rename from test/test_fem/test_inverse_map_segment_3.verified
rename to test/test_fe_engine/test_inverse_map_segment_3.verified
diff --git a/test/test_fem/test_inverse_map_tetrahedron_10.verified b/test/test_fe_engine/test_inverse_map_tetrahedron_10.verified
similarity index 100%
rename from test/test_fem/test_inverse_map_tetrahedron_10.verified
rename to test/test_fe_engine/test_inverse_map_tetrahedron_10.verified
diff --git a/test/test_fem/test_inverse_map_tetrahedron_4.verified b/test/test_fe_engine/test_inverse_map_tetrahedron_4.verified
similarity index 100%
rename from test/test_fem/test_inverse_map_tetrahedron_4.verified
rename to test/test_fe_engine/test_inverse_map_tetrahedron_4.verified
diff --git a/test/test_fem/test_inverse_map_triangle_3.verified b/test/test_fe_engine/test_inverse_map_triangle_3.verified
similarity index 100%
rename from test/test_fem/test_inverse_map_triangle_3.verified
rename to test/test_fe_engine/test_inverse_map_triangle_3.verified
diff --git a/test/test_fem/test_inverse_map_triangle_6.verified b/test/test_fe_engine/test_inverse_map_triangle_6.verified
similarity index 100%
rename from test/test_fem/test_inverse_map_triangle_6.verified
rename to test/test_fe_engine/test_inverse_map_triangle_6.verified
diff --git a/test/test_fem/test_mesh_boundary.cc b/test/test_fe_engine/test_mesh_boundary.cc
similarity index 100%
rename from test/test_fem/test_mesh_boundary.cc
rename to test/test_fe_engine/test_mesh_boundary.cc
diff --git a/test/test_fem/test_mesh_data.cc b/test/test_fe_engine/test_mesh_data.cc
similarity index 100%
rename from test/test_fem/test_mesh_data.cc
rename to test/test_fe_engine/test_mesh_data.cc
diff --git a/test/test_fem/CMakeLists.txt b/test/test_fem/CMakeLists.txt
deleted file mode 100644
index 329b01e60..000000000
--- a/test/test_fem/CMakeLists.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-#===============================================================================
-# @file CMakeLists.txt
-#
-# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
-#
-# @date creation: Fri Sep 03 2010
-# @date last modification: Fri May 30 2014
-#
-# @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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_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
- )
-endmacro()
-#===============================================================================
-
-set(LIST_TYPES
- segment_2
- segment_3
- triangle_3
- triangle_6
- quadrangle_4
- quadrangle_8
- tetrahedron_4
- tetrahedron_10
- hexahedron_8
- )
-
-foreach(_type ${LIST_TYPES})
- register_fem_test(interpolate ${_type})
- register_fem_test(gradient ${_type})
- register_fem_test(integrate ${_type})
- register_fem_test(inverse_map ${_type})
-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
- PACKAGE core)
-
-register_test(test_facet_element_mapping
- SOURCES test_facet_element_mapping.cc
- DEPENDENCIES test_boundary_msh_physical_names
- PACKAGE core)
-
-register_test(test_igfem_integrate
- SOURCES test_igfem_integrate.cc
- PACKAGE igfem)
diff --git a/test/test_fem/cube.geo b/test/test_fem/cube.geo
deleted file mode 100644
index 1fa3a481f..000000000
--- a/test/test_fem/cube.geo
+++ /dev/null
@@ -1,37 +0,0 @@
-h = 0.25;
-
-Point(1) = {0.0, 0.0, 0.0, h};
-Point(2) = {1.0, 0.0, 0.0, h};
-Point(3) = {0.0, 1.0, 0.0, h};
-Point(4) = {1.0, 1.0, 0.0, h};
-Point(5) = {0.0, 0.0, 1.0, h};
-Point(6) = {1.0, 0.0, 1.0, h};
-Point(7) = {0.0, 1.0, 1.0, h};
-Point(8) = {1.0, 1.0, 1.0, h};
-
-Line(1) = {7, 8};
-Line(2) = {8, 4};
-Line(3) = {4, 3};
-Line(4) = {3, 7};
-Line(5) = {1, 5};
-Line(6) = {5, 6};
-Line(7) = {6, 2};
-Line(8) = {2, 1};
-Line(9) = {3, 1};
-Line(10) = {7, 5};
-Line(11) = {8, 6};
-Line(12) = {4, 2};
-Line Loop(13) = {1, 11, -6, -10};
-Plane Surface(14) = {13};
-Line Loop(15) = {3, 4, 1, 2};
-Plane Surface(16) = {15};
-Line Loop(17) = {6, 7, 8, 5};
-Plane Surface(18) = {17};
-Line Loop(19) = {3, 9, -8, -12};
-Plane Surface(20) = {19};
-Line Loop(21) = {4, 10, -5, -9};
-Plane Surface(22) = {21};
-Line Loop(23) = {11, 7, -12, -2};
-Plane Surface(24) = {23};
-Surface Loop(25) = {24, 14, 16, 20, 22, 18};
-Volume(26) = {25};
diff --git a/test/test_fem/test_gradient.cc b/test/test_fem/test_gradient.cc
deleted file mode 100644
index 5c37f438b..000000000
--- a/test/test_fem/test_gradient.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * @file test_gradient.cc
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Fri Jun 17 2011
- * @date last modification: Thu Jun 05 2014
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * 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 "aka_common.hh"
-#include "fe_engine.hh"
-#include "mesh.hh"
-#include "mesh_io.hh"
-#include "mesh_io_msh.hh"
-#include "shape_lagrange.hh"
-#include "integrator_gauss.hh"
-/* -------------------------------------------------------------------------- */
-#include <cstdlib>
-#include <fstream>
-#include <iostream>
-/* -------------------------------------------------------------------------- */
-
-using namespace akantu;
-
-int main(int argc, char *argv[]) {
- akantu::initialize(argc, argv);
- debug::setDebugLevel(dblTest);
- const ElementType type = TYPE;
- UInt dim = ElementClass<type>::getSpatialDimension();
-
- Real eps = 1e-12;
- std::cout << "Epsilon : " << eps << std::endl;
-
- MeshIOMSH mesh_io;
- Mesh my_mesh(dim);
- std::stringstream meshfilename; meshfilename << type << ".msh";
- mesh_io.read(meshfilename.str(), my_mesh);
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
-
- std::stringstream outfilename; outfilename << "out_" << type << ".txt";
- std::ofstream my_file(outfilename.str().c_str());
-
- fem->initShapeFunctions();
-
- std::cout << *fem << std::endl;
-
- 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;
-
- 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);
-
- my_file << const_val << std::endl;
- my_file << grad_on_quad << std::endl;
- std::cout << grad_on_quad << std::endl;
-
- /// check the results
- Array<Real>::matrix_iterator it = grad_on_quad.begin(2,dim);
- Array<Real>::matrix_iterator it_end = grad_on_quad.end(2,dim);
- for (;it != it_end; ++it) {
- for (UInt d = 0; d < dim; ++d) {
- Matrix<Real> & grad = *it;
- if(!(std::abs(grad(0, d) - alpha[0][d]) < eps) ||
- !(std::abs(grad(1, d) - alpha[1][d]) < eps)) {
- std::cout << "Error gradient is not correct "
- << (*it)(0, d) << " " << alpha[0][d] << " (" << std::abs((*it)(0, d) - alpha[0][d]) << ")"
- << " - "
- << (*it)(1, d) << " " << alpha[1][d] << " (" << std::abs((*it)(1, d) - alpha[1][d]) << ")"
- << " - " << d << std::endl;
- std::cout << *it << std::endl;
- exit(EXIT_FAILURE);
- }
- }
- }
-
- // compute gradient of coordinates
- Array<Real> grad_coord_on_quad(nb_quadrature_points, dim * dim, "grad_coord_on_quad");
- fem->gradientOnQuadraturePoints(my_mesh.getNodes(), grad_coord_on_quad, my_mesh.getSpatialDimension(), type);
-
- my_file << my_mesh.getNodes() << std::endl;
- my_file << grad_coord_on_quad << std::endl;
-
- Array<Real>::matrix_iterator itp = grad_coord_on_quad.begin(dim, dim);
- Array<Real>::matrix_iterator itp_end = grad_coord_on_quad.end(dim, dim);
-
- for (;itp != itp_end; ++itp) {
- for (UInt i = 0; i < dim; ++i) {
- for (UInt j = 0; j < dim; ++j) {
- if(!(std::abs((*itp)(i,j) - (i == j)) < eps)) {
- std::cout << *itp << std::endl;
- exit(EXIT_FAILURE);
- }
- }
- }
- }
-
- delete fem;
- finalize();
-
- return EXIT_SUCCESS;
-}
diff --git a/test/test_fem/test_gradient_hexahedron_8.verified b/test/test_fem/test_gradient_hexahedron_8.verified
deleted file mode 100644
index b8f6bbebb..000000000
--- a/test/test_fem/test_gradient_hexahedron_8.verified
+++ /dev/null
@@ -1,76 +0,0 @@
-Epsilon : 1e-12
-FEEngine [
- + id : my_fem
- + element dimension : 3
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 3
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 8
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 48
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{6, 8}, {8, 9}, {9, 10}, {10, 7}, {7, 11}, {11, 12}, {12, 13}, {13, 3}, {3, 14}, {14, 15}, {15, 16}, {16, 2}, {2, 17}, {17, 18}, {18, 19}, {19, 6}, {0, 20}, {20, 21}, {21, 22}, {22, 4}, {4, 23}, {23, 24}, {24, 25}, {25, 5}, {5, 26}, {26, 27}, {27, 28}, {28, 1}, {1, 29}, {29, 30}, {30, 31}, {31, 0}, {2, 32}, {32, 33}, {33, 34}, {34, 0}, {6, 35}, {35, 36}, {36, 37}, {37, 4}, {7, 38}, {38, 39}, {39, 40}, {40, 5}, {3, 41}, {41, 42}, {42, 43}, {43, 1}}
- ]
- ]
- (not_ghost:_quadrangle_4) [
- Array<unsigned int> [
- + id : mesh:connectivities:_quadrangle_4
- + size : 96
- + nb_component : 4
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{6, 8, 44, 35}, {35, 44, 45, 36}, {36, 45, 46, 37}, {37, 46, 23, 4}, {8, 9, 47, 44}, {44, 47, 48, 45}, {45, 48, 49, 46}, {46, 49, 24, 23}, {9, 10, 50, 47}, {47, 50, 51, 48}, {48, 51, 52, 49}, {49, 52, 25, 24}, {10, 7, 38, 50}, {50, 38, 39, 51}, {51, 39, 40, 52}, {52, 40, 5, 25}, {3, 14, 53, 13}, {13, 53, 54, 12}, {12, 54, 55, 11}, {11, 55, 10, 7}, {14, 15, 56, 53}, {53, 56, 57, 54}, {54, 57, 58, 55}, {55, 58, 9, 10}, {15, 16, 59, 56}, {56, 59, 60, 57}, {57, 60, 61, 58}, {58, 61, 8, 9}, {16, 2, 17, 59}, {59, 17, 18, 60}, {60, 18, 19, 61}, {61, 19, 6, 8}, {4, 23, 62, 22}, {22, 62, 63, 21}, {21, 63, 64, 20}, {20, 64, 31, 0}, {23, 24, 65, 62}, {62, 65, 66, 63}, {63, 66, 67, 64}, {64, 67, 30, 31}, {24, 25, 68, 65}, {65, 68, 69, 66}, {66, 69, 70, 67}, {67, 70, 29, 30}, {25, 5, 26, 68}, {68, 26, 27, 69}, {69, 27, 28, 70}, {70, 28, 1, 29}, {3, 14, 71, 41}, {41, 71, 72, 42}, {42, 72, 73, 43}, {43, 73, 29, 1}, {14, 15, 74, 71}, {71, 74, 75, 72}, {72, 75, 76, 73}, {73, 76, 30, 29}, {15, 16, 77, 74}, {74, 77, 78, 75}, {75, 78, 79, 76}, {76, 79, 31, 30}, {16, 2, 32, 77}, {77, 32, 33, 78}, {78, 33, 34, 79}, {79, 34, 0, 31}, {2, 17, 80, 32}, {32, 80, 81, 33}, {33, 81, 82, 34}, {34, 82, 20, 0}, {17, 18, 83, 80}, {80, 83, 84, 81}, {81, 84, 85, 82}, {82, 85, 21, 20}, {18, 19, 86, 83}, {83, 86, 87, 84}, {84, 87, 88, 85}, {85, 88, 22, 21}, {19, 6, 35, 86}, {86, 35, 36, 87}, {87, 36, 37, 88}, {88, 37, 4, 22}, {7, 38, 89, 11}, {11, 89, 90, 12}, {12, 90, 91, 13}, {13, 91, 41, 3}, {38, 39, 92, 89}, {89, 92, 93, 90}, {90, 93, 94, 91}, {91, 94, 42, 41}, {39, 40, 95, 92}, {92, 95, 96, 93}, {93, 96, 97, 94}, {94, 97, 43, 42}, {40, 5, 26, 95}, {95, 26, 27, 96}, {96, 27, 28, 97}, {97, 28, 1, 43}}
- ]
- ]
- (not_ghost:_hexahedron_8) [
- Array<unsigned int> [
- + id : mesh:connectivities:_hexahedron_8
- + size : 64
- + nb_component : 8
- + allocated size : 2000
- + memory size : 62.50KiByte
- + values : {{89, 38, 7, 11, 98, 50, 10, 55}, {98, 50, 10, 55, 99, 47, 9, 58}, {99, 47, 9, 58, 100, 44, 8, 61}, {100, 44, 8, 61, 86, 35, 6, 19}, {90, 89, 11, 12, 101, 98, 55, 54}, {101, 98, 55, 54, 102, 99, 58, 57}, {102, 99, 58, 57, 103, 100, 61, 60}, {103, 100, 61, 60, 83, 86, 19, 18}, {91, 90, 12, 13, 104, 101, 54, 53}, {104, 101, 54, 53, 105, 102, 57, 56}, {105, 102, 57, 56, 106, 103, 60, 59}, {106, 103, 60, 59, 80, 83, 18, 17}, {41, 91, 13, 3, 71, 104, 53, 14}, {71, 104, 53, 14, 74, 105, 56, 15}, {74, 105, 56, 15, 77, 106, 59, 16}, {77, 106, 59, 16, 32, 80, 17, 2}, {92, 39, 38, 89, 107, 51, 50, 98}, {107, 51, 50, 98, 108, 48, 47, 99}, {108, 48, 47, 99, 109, 45, 44, 100}, {109, 45, 44, 100, 87, 36, 35, 86}, {93, 92, 89, 90, 110, 107, 98, 101}, {110, 107, 98, 101, 111, 108, 99, 102}, {111, 108, 99, 102, 112, 109, 100, 103}, {112, 109, 100, 103, 84, 87, 86, 83}, {94, 93, 90, 91, 113, 110, 101, 104}, {113, 110, 101, 104, 114, 111, 102, 105}, {114, 111, 102, 105, 115, 112, 103, 106}, {115, 112, 103, 106, 81, 84, 83, 80}, {42, 94, 91, 41, 72, 113, 104, 71}, {72, 113, 104, 71, 75, 114, 105, 74}, {75, 114, 105, 74, 78, 115, 106, 77}, {78, 115, 106, 77, 33, 81, 80, 32}, {95, 40, 39, 92, 116, 52, 51, 107}, {116, 52, 51, 107, 117, 49, 48, 108}, {117, 49, 48, 108, 118, 46, 45, 109}, {118, 46, 45, 109, 88, 37, 36, 87}, {96, 95, 92, 93, 119, 116, 107, 110}, {119, 116, 107, 110, 120, 117, 108, 111}, {120, 117, 108, 111, 121, 118, 109, 112}, {121, 118, 109, 112, 85, 88, 87, 84}, {97, 96, 93, 94, 122, 119, 110, 113}, {122, 119, 110, 113, 123, 120, 111, 114}, {123, 120, 111, 114, 124, 121, 112, 115}, {124, 121, 112, 115, 82, 85, 84, 81}, {43, 97, 94, 42, 73, 122, 113, 72}, {73, 122, 113, 72, 76, 123, 114, 75}, {76, 123, 114, 75, 79, 124, 115, 78}, {79, 124, 115, 78, 34, 82, 81, 33}, {26, 5, 40, 95, 68, 25, 52, 116}, {68, 25, 52, 116, 65, 24, 49, 117}, {65, 24, 49, 117, 62, 23, 46, 118}, {62, 23, 46, 118, 22, 4, 37, 88}, {27, 26, 95, 96, 69, 68, 116, 119}, {69, 68, 116, 119, 66, 65, 117, 120}, {66, 65, 117, 120, 63, 62, 118, 121}, {63, 62, 118, 121, 21, 22, 88, 85}, {28, 27, 96, 97, 70, 69, 119, 122}, {70, 69, 119, 122, 67, 66, 120, 123}, {67, 66, 120, 123, 64, 63, 121, 124}, {64, 63, 121, 124, 20, 21, 85, 82}, {1, 28, 97, 43, 29, 70, 122, 73}, {29, 70, 122, 73, 30, 67, 123, 76}, {30, 67, 123, 76, 31, 64, 124, 79}, {31, 64, 124, 79, 0, 20, 82, 34}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
-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}}
-]
-
diff --git a/test/test_fem/test_gradient_quadrangle_4.verified b/test/test_fem/test_gradient_quadrangle_4.verified
deleted file mode 100644
index 5986c87d4..000000000
--- a/test/test_fem/test_gradient_quadrangle_4.verified
+++ /dev/null
@@ -1,66 +0,0 @@
-Epsilon : 1e-12
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 4
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 8
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0, 4}, {4, 1}, {1, 5}, {5, 2}, {2, 6}, {6, 3}, {3, 7}, {7, 0}}
- ]
- ]
- (not_ghost:_quadrangle_4) [
- Array<unsigned int> [
- + id : mesh:connectivities:_quadrangle_4
- + size : 4
- + nb_component : 4
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{2, 6, 8, 5}, {5, 8, 4, 1}, {6, 3, 7, 8}, {8, 7, 0, 4}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
-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}}
-]
-
diff --git a/test/test_fem/test_gradient_quadrangle_8.verified b/test/test_fem/test_gradient_quadrangle_8.verified
deleted file mode 100644
index 7d0fc07b3..000000000
--- a/test/test_fem/test_gradient_quadrangle_8.verified
+++ /dev/null
@@ -1,46 +0,0 @@
-Epsilon : 1e-12
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_quadrangle_8) [
- Array<unsigned int> [
- + id : mesh:connectivities:_quadrangle_8
- + size : 4
- + nb_component : 8
- + allocated size : 2000
- + memory size : 62.50KiByte
- + values : {{2, 10, 16, 7, 11, 17, 18, 9}, {7, 16, 4, 1, 18, 19, 6, 8}, {10, 3, 13, 16, 12, 14, 20, 17}, {16, 13, 0, 4, 20, 15, 5, 19}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
-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}}
-]
-
diff --git a/test/test_fem/test_gradient_segment_2.verified b/test/test_fem/test_gradient_segment_2.verified
deleted file mode 100644
index 0fe36c7ff..000000000
--- a/test/test_fem/test_gradient_segment_2.verified
+++ /dev/null
@@ -1,56 +0,0 @@
-Epsilon : 1e-12
-FEEngine [
- + id : my_fem
- + element dimension : 1
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 1
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 2
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 10
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}, {10, 1}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
-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}}
-]
-
diff --git a/test/test_fem/test_gradient_segment_3.verified b/test/test_fem/test_gradient_segment_3.verified
deleted file mode 100644
index 0a26f8b03..000000000
--- a/test/test_fem/test_gradient_segment_3.verified
+++ /dev/null
@@ -1,56 +0,0 @@
-Epsilon : 1e-12
-FEEngine [
- + id : my_fem
- + element dimension : 1
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 1
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 2
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}}
- ]
- ]
- (not_ghost:_segment_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_3
- + size : 10
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{0, 2, 11}, {2, 3, 12}, {3, 4, 13}, {4, 5, 14}, {5, 6, 15}, {6, 7, 16}, {7, 8, 17}, {8, 9, 18}, {9, 10, 19}, {10, 1, 20}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
-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}}
-]
-
diff --git a/test/test_fem/test_gradient_tetrahedron_10.verified b/test/test_fem/test_gradient_tetrahedron_10.verified
deleted file mode 100644
index e17f457de..000000000
--- a/test/test_fem/test_gradient_tetrahedron_10.verified
+++ /dev/null
@@ -1,76 +0,0 @@
-Epsilon : 1e-12
-FEEngine [
- + id : my_fem
- + element dimension : 3
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 3
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 8
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
- ]
- ]
- (not_ghost:_segment_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_3
- + size : 48
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{6, 8, 11}, {8, 9, 12}, {9, 10, 13}, {10, 7, 14}, {7, 15, 18}, {15, 16, 19}, {16, 17, 20}, {17, 3, 21}, {3, 22, 25}, {22, 23, 26}, {23, 24, 27}, {24, 2, 28}, {2, 29, 32}, {29, 30, 33}, {30, 31, 34}, {31, 6, 35}, {0, 36, 39}, {36, 37, 40}, {37, 38, 41}, {38, 4, 42}, {4, 43, 46}, {43, 44, 47}, {44, 45, 48}, {45, 5, 49}, {5, 50, 53}, {50, 51, 54}, {51, 52, 55}, {52, 1, 56}, {1, 57, 60}, {57, 58, 61}, {58, 59, 62}, {59, 0, 63}, {2, 64, 67}, {64, 65, 68}, {65, 66, 69}, {66, 0, 70}, {6, 71, 74}, {71, 72, 75}, {72, 73, 76}, {73, 4, 77}, {7, 78, 81}, {78, 79, 82}, {79, 80, 83}, {80, 5, 84}, {3, 85, 88}, {85, 86, 89}, {86, 87, 90}, {87, 1, 91}}
- ]
- ]
- (not_ghost:_triangle_6) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_6
- + size : 240
- + nb_component : 6
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{93, 97, 71, 105, 106, 107}, {93, 8, 98, 108, 109, 110}, {94, 78, 99, 111, 112, 113}, {43, 95, 100, 114, 115, 116}, {94, 98, 10, 117, 118, 119}, {73, 97, 95, 120, 121, 122}, {45, 100, 96, 123, 124, 125}, {80, 96, 99, 126, 127, 128}, {71, 97, 72, 106, 129, 75}, {78, 79, 99, 82, 130, 112}, {8, 9, 98, 12, 131, 109}, {43, 100, 44, 116, 132, 47}, {72, 97, 73, 129, 120, 76}, {9, 10, 98, 13, 118, 131}, {79, 80, 99, 83, 128, 130}, {44, 100, 45, 132, 123, 48}, {93, 92, 97, 133, 134, 105}, {93, 98, 92, 110, 135, 133}, {94, 92, 98, 136, 135, 117}, {92, 95, 97, 137, 121, 134}, {94, 99, 92, 113, 138, 136}, {92, 100, 95, 139, 115, 137}, {92, 99, 96, 138, 127, 140}, {92, 96, 100, 140, 124, 139}, {93, 71, 101, 107, 141, 142}, {93, 101, 8, 142, 143, 108}, {94, 102, 78, 144, 145, 111}, {43, 103, 95, 146, 147, 114}, {94, 10, 102, 119, 148, 144}, {73, 95, 103, 122, 147, 149}, {45, 96, 104, 125, 150, 151}, {80, 104, 96, 152, 150, 126}, {4, 73, 103, 77, 149, 153}, {6, 101, 71, 154, 141, 74}, {7, 102, 10, 155, 148, 14}, {7, 78, 102, 81, 145, 155}, {6, 8, 101, 11, 143, 154}, {5, 104, 80, 156, 152, 84}, {4, 103, 43, 153, 146, 46}, {5, 45, 104, 49, 151, 156}, {15, 162, 158, 170, 171, 172}, {22, 163, 159, 173, 174, 175}, {8, 164, 160, 176, 177, 178}, {29, 165, 161, 179, 180, 181}, {10, 158, 164, 182, 183, 184}, {31, 160, 165, 185, 186, 187}, {17, 159, 162, 188, 189, 190}, {24, 161, 163, 191, 192, 193}, {22, 23, 163, 26, 194, 173}, {15, 16, 162, 19, 195, 170}, {29, 30, 165, 33, 196, 179}, {8, 9, 164, 12, 197, 176}, {16, 17, 162, 20, 190, 195}, {23, 24, 163, 27, 193, 194}, {9, 10, 164, 13, 184, 197}, {30, 31, 165, 34, 187, 196}, {158, 162, 157, 171, 198, 199}, {159, 157, 162, 200, 198, 189}, {159, 163, 157, 174, 201, 200}, {161, 157, 163, 202, 201, 192}, {158, 157, 164, 199, 203, 183}, {160, 164, 157, 177, 203, 204}, {160, 157, 165, 204, 205, 186}, {161, 165, 157, 180, 205, 202}, {15, 158, 167, 172, 206, 207}, {22, 159, 166, 175, 208, 209}, {8, 160, 169, 178, 210, 211}, {29, 161, 168, 181, 212, 213}, {10, 167, 158, 214, 206, 182}, {31, 169, 160, 215, 210, 185}, {17, 166, 159, 216, 208, 188}, {24, 168, 161, 217, 212, 191}, {2, 168, 24, 218, 217, 28}, {3, 166, 17, 219, 216, 21}, {6, 169, 31, 220, 215, 35}, {7, 167, 10, 221, 214, 14}, {7, 15, 167, 18, 207, 221}, {3, 22, 166, 25, 209, 219}, {6, 8, 169, 11, 211, 220}, {2, 29, 168, 32, 213, 218}, {50, 227, 223, 235, 236, 237}, {57, 228, 224, 238, 239, 240}, {43, 229, 225, 241, 242, 243}, {36, 230, 226, 244, 245, 246}, {45, 223, 229, 247, 248, 249}, {38, 225, 230, 250, 251, 252}, {52, 224, 227, 253, 254, 255}, {59, 226, 228, 256, 257, 258}, {57, 58, 228, 61, 259, 238}, {50, 51, 227, 54, 260, 235}, {36, 37, 230, 40, 261, 244}, {43, 44, 229, 47, 262, 241}, {51, 52, 227, 55, 255, 260}, {58, 59, 228, 62, 258, 259}, {44, 45, 229, 48, 249, 262}, {37, 38, 230, 41, 252, 261}, {223, 227, 222, 236, 263, 264}, {224, 222, 227, 265, 263, 254}, {224, 228, 222, 239, 266, 265}, {222, 228, 226, 266, 257, 267}, {223, 222, 229, 264, 268, 248}, {222, 225, 229, 269, 242, 268}, {222, 230, 225, 270, 251, 269}, {222, 226, 230, 267, 245, 270}, {50, 223, 232, 237, 271, 272}, {57, 224, 231, 240, 273, 274}, {43, 225, 234, 243, 275, 276}, {36, 226, 233, 246, 277, 278}, {45, 232, 223, 279, 271, 247}, {38, 234, 225, 280, 275, 250}, {52, 231, 224, 281, 273, 253}, {59, 233, 226, 282, 277, 256}, {0, 233, 59, 283, 282, 63}, {1, 231, 52, 284, 281, 56}, {4, 234, 38, 285, 280, 42}, {5, 232, 45, 286, 279, 49}, {5, 50, 232, 53, 272, 286}, {1, 57, 231, 60, 274, 284}, {4, 43, 234, 46, 276, 285}, {0, 36, 233, 39, 278, 283}, {85, 288, 292, 300, 301, 302}, {22, 293, 288, 303, 304, 305}, {57, 290, 294, 306, 307, 308}, {64, 295, 289, 309, 310, 311}, {24, 289, 293, 312, 313, 314}, {87, 292, 290, 315, 316, 317}, {66, 291, 295, 318, 319, 320}, {59, 294, 291, 321, 322, 323}, {85, 292, 86, 302, 324, 89}, {22, 23, 293, 26, 325, 303}, {57, 294, 58, 308, 326, 61}, {64, 65, 295, 68, 327, 309}, {86, 292, 87, 324, 315, 90}, {23, 24, 293, 27, 314, 325}, {65, 66, 295, 69, 320, 327}, {58, 294, 59, 326, 321, 62}, {288, 293, 287, 304, 328, 329}, {288, 287, 292, 329, 330, 301}, {289, 287, 293, 331, 328, 313}, {290, 292, 287, 316, 330, 332}, {289, 295, 287, 310, 333, 331}, {290, 287, 294, 332, 334, 307}, {291, 294, 287, 322, 334, 335}, {291, 287, 295, 335, 333, 319}, {22, 288, 296, 305, 336, 337}, {85, 296, 288, 338, 336, 300}, {57, 298, 290, 339, 340, 306}, {64, 289, 297, 311, 341, 342}, {87, 290, 298, 317, 340, 343}, {24, 297, 289, 344, 341, 312}, {59, 291, 299, 323, 345, 346}, {66, 299, 291, 347, 345, 318}, {1, 87, 298, 91, 343, 348}, {2, 297, 24, 349, 344, 28}, {3, 296, 85, 350, 338, 88}, {3, 22, 296, 25, 337, 350}, {1, 298, 57, 348, 339, 60}, {2, 64, 297, 67, 342, 349}, {0, 59, 299, 63, 346, 351}, {0, 299, 66, 351, 347, 70}, {64, 353, 357, 365, 366, 367}, {29, 358, 353, 368, 369, 370}, {71, 359, 354, 371, 372, 373}, {36, 355, 360, 374, 375, 376}, {31, 354, 358, 377, 378, 379}, {66, 357, 355, 380, 381, 382}, {38, 360, 356, 383, 384, 385}, {73, 356, 359, 386, 387, 388}, {64, 357, 65, 367, 389, 68}, {71, 72, 359, 75, 390, 371}, {29, 30, 358, 33, 391, 368}, {36, 360, 37, 376, 392, 40}, {65, 357, 66, 389, 380, 69}, {30, 31, 358, 34, 379, 391}, {72, 73, 359, 76, 388, 390}, {37, 360, 38, 392, 383, 41}, {353, 352, 357, 393, 394, 366}, {353, 358, 352, 369, 395, 393}, {354, 352, 358, 396, 395, 378}, {355, 357, 352, 381, 394, 397}, {354, 359, 352, 372, 398, 396}, {355, 352, 360, 397, 399, 375}, {356, 352, 359, 400, 398, 387}, {356, 360, 352, 384, 399, 400}, {64, 361, 353, 401, 402, 365}, {29, 353, 361, 370, 402, 403}, {71, 354, 362, 373, 404, 405}, {36, 363, 355, 406, 407, 374}, {31, 362, 354, 408, 404, 377}, {66, 355, 363, 382, 407, 409}, {38, 356, 364, 385, 410, 411}, {73, 364, 356, 412, 410, 386}, {0, 66, 363, 70, 409, 413}, {2, 361, 64, 414, 401, 67}, {6, 362, 31, 415, 408, 35}, {6, 71, 362, 74, 405, 415}, {2, 29, 361, 32, 403, 414}, {4, 364, 73, 416, 412, 77}, {0, 363, 36, 413, 406, 39}, {4, 38, 364, 42, 411, 416}, {15, 418, 423, 430, 431, 432}, {78, 422, 418, 433, 434, 435}, {50, 424, 420, 436, 437, 438}, {85, 419, 425, 439, 440, 441}, {17, 423, 419, 442, 443, 444}, {80, 420, 422, 445, 446, 447}, {87, 425, 421, 448, 449, 450}, {52, 421, 424, 451, 452, 453}, {15, 423, 16, 432, 454, 19}, {78, 79, 422, 82, 455, 433}, {50, 51, 424, 54, 456, 436}, {85, 425, 86, 441, 457, 89}, {79, 80, 422, 83, 447, 455}, {16, 423, 17, 454, 442, 20}, {86, 425, 87, 457, 448, 90}, {51, 52, 424, 55, 453, 456}, {417, 418, 422, 458, 434, 459}, {417, 423, 418, 460, 431, 458}, {419, 423, 417, 443, 460, 461}, {420, 417, 422, 462, 459, 446}, {419, 417, 425, 461, 463, 440}, {420, 424, 417, 437, 464, 462}, {421, 417, 424, 465, 464, 452}, {421, 425, 417, 449, 463, 465}, {15, 426, 418, 466, 467, 430}, {78, 418, 426, 435, 467, 468}, {50, 420, 428, 438, 469, 470}, {85, 427, 419, 471, 472, 439}, {80, 428, 420, 473, 469, 445}, {17, 419, 427, 444, 472, 474}, {52, 429, 421, 475, 476, 451}, {87, 421, 429, 450, 476, 477}, {5, 428, 80, 478, 473, 84}, {3, 17, 427, 21, 474, 479}, {7, 78, 426, 81, 468, 480}, {7, 426, 15, 480, 466, 18}, {5, 50, 428, 53, 470, 478}, {3, 427, 85, 479, 471, 88}, {1, 429, 52, 481, 475, 56}, {1, 87, 429, 91, 477, 481}}
- ]
- ]
- (not_ghost:_tetrahedron_10) [
- Array<unsigned int> [
- + id : mesh:connectivities:_tetrahedron_10
- + size : 341
- + nb_component : 10
- + allocated size : 2000
- + memory size : 78.12KiByte
- + values : {{484, 483, 485, 489, 491, 493, 492, 496, 494, 495}, {87, 290, 490, 292, 317, 498, 497, 315, 316, 499}, {222, 484, 489, 486, 500, 496, 501, 504, 502, 503}, {96, 229, 45, 100, 505, 249, 125, 124, 506, 123}, {59, 0, 233, 299, 63, 283, 282, 346, 351, 507}, {0, 363, 233, 299, 413, 508, 283, 351, 509, 507}, {486, 295, 291, 357, 510, 319, 511, 514, 512, 513}, {484, 222, 489, 485, 500, 501, 496, 492, 515, 495}, {87, 429, 421, 490, 477, 476, 450, 497, 516, 517}, {103, 356, 234, 364, 518, 520, 519, 522, 410, 521}, {356, 103, 234, 225, 518, 519, 520, 524, 523, 275}, {43, 103, 225, 234, 146, 523, 243, 276, 519, 275}, {223, 227, 485, 420, 236, 526, 525, 529, 527, 528}, {483, 92, 484, 485, 530, 531, 491, 493, 532, 492}, {87, 421, 425, 490, 450, 449, 448, 497, 517, 533}, {298, 87, 290, 490, 343, 317, 340, 534, 497, 498}, {482, 483, 488, 489, 535, 537, 536, 539, 494, 538}, {94, 10, 158, 98, 119, 182, 540, 117, 118, 541}, {355, 363, 233, 36, 407, 508, 542, 374, 406, 278}, {485, 420, 424, 417, 528, 437, 543, 544, 462, 464}, {231, 224, 52, 490, 273, 253, 281, 547, 545, 546}, {483, 482, 485, 489, 535, 548, 493, 494, 539, 495}, {167, 15, 7, 426, 207, 18, 221, 549, 466, 480}, {483, 487, 488, 489, 550, 551, 537, 494, 552, 538}, {484, 92, 97, 95, 531, 134, 553, 554, 137, 121}, {29, 165, 30, 358, 179, 196, 33, 368, 555, 391}, {228, 294, 58, 59, 556, 326, 259, 258, 321, 62}, {102, 10, 7, 167, 148, 14, 155, 557, 214, 221}, {9, 10, 98, 164, 13, 118, 131, 197, 184, 558}, {78, 102, 7, 426, 145, 155, 81, 468, 559, 480}, {483, 484, 487, 489, 491, 560, 550, 494, 496, 552}, {16, 423, 162, 17, 454, 561, 195, 20, 442, 190}, {353, 161, 358, 487, 562, 563, 369, 566, 564, 565}, {93, 101, 8, 169, 142, 143, 108, 568, 567, 211}, {78, 422, 79, 99, 433, 455, 82, 112, 569, 130}, {485, 227, 489, 424, 526, 570, 495, 543, 571, 572}, {482, 92, 483, 485, 573, 530, 535, 548, 532, 493}, {223, 222, 229, 484, 264, 268, 248, 575, 500, 574}, {422, 420, 485, 417, 446, 528, 576, 459, 462, 544}, {64, 297, 353, 289, 342, 577, 365, 311, 341, 578}, {101, 6, 8, 169, 154, 11, 143, 567, 220, 211}, {425, 488, 489, 417, 579, 538, 580, 463, 581, 582}, {163, 161, 24, 293, 192, 191, 193, 584, 583, 314}, {228, 294, 59, 226, 556, 321, 258, 257, 585, 256}, {161, 289, 24, 293, 586, 312, 191, 583, 313, 314}, {165, 483, 160, 354, 587, 588, 186, 591, 589, 590}, {103, 356, 95, 225, 518, 592, 147, 523, 524, 593}, {356, 95, 359, 73, 592, 594, 387, 386, 122, 388}, {352, 483, 359, 484, 595, 596, 398, 598, 491, 597}, {103, 43, 4, 234, 146, 46, 153, 519, 276, 285}, {230, 356, 38, 225, 599, 385, 252, 251, 524, 250}, {161, 289, 293, 487, 586, 313, 583, 564, 600, 601}, {161, 487, 293, 163, 564, 601, 583, 192, 602, 584}, {429, 87, 298, 490, 477, 343, 603, 516, 497, 534}, {364, 38, 234, 4, 411, 280, 521, 416, 42, 285}, {22, 296, 3, 166, 337, 350, 25, 209, 604, 219}, {230, 37, 360, 36, 261, 392, 605, 244, 40, 376}, {356, 230, 360, 484, 599, 605, 384, 608, 606, 607}, {22, 23, 293, 163, 26, 325, 303, 173, 194, 584}, {294, 486, 291, 226, 609, 511, 322, 585, 610, 611}, {294, 228, 486, 226, 556, 612, 609, 585, 257, 610}, {3, 17, 166, 427, 21, 216, 219, 479, 474, 613}, {364, 103, 4, 234, 522, 153, 416, 521, 519, 285}, {158, 15, 418, 162, 172, 430, 614, 171, 170, 615}, {15, 423, 418, 162, 432, 431, 430, 170, 561, 615}, {157, 483, 160, 165, 616, 588, 204, 205, 587, 186}, {482, 158, 418, 162, 617, 614, 618, 619, 171, 615}, {423, 482, 418, 162, 620, 618, 431, 561, 619, 615}, {425, 488, 292, 489, 579, 622, 621, 580, 538, 623}, {290, 489, 490, 292, 624, 625, 498, 316, 623, 499}, {222, 223, 485, 484, 264, 525, 515, 500, 575, 492}, {363, 0, 66, 299, 413, 70, 409, 509, 351, 347}, {482, 422, 485, 417, 626, 576, 548, 627, 459, 544}, {486, 290, 287, 489, 628, 332, 629, 503, 624, 630}, {296, 3, 166, 427, 350, 219, 604, 631, 479, 613}, {489, 290, 287, 292, 624, 332, 630, 623, 316, 330}, {488, 85, 427, 419, 632, 471, 633, 634, 439, 472}, {425, 488, 419, 85, 579, 634, 440, 441, 632, 439}, {15, 16, 423, 162, 19, 454, 432, 170, 195, 561}, {65, 64, 357, 295, 68, 367, 389, 327, 309, 512}, {222, 484, 486, 226, 500, 502, 504, 267, 635, 610}, {356, 484, 95, 225, 608, 554, 592, 524, 636, 593}, {352, 484, 486, 487, 598, 502, 637, 639, 560, 638}, {230, 222, 484, 225, 270, 500, 606, 251, 269, 636}, {294, 228, 58, 57, 556, 259, 326, 308, 238, 61}, {352, 483, 484, 487, 595, 491, 598, 639, 550, 560}, {23, 163, 24, 293, 194, 193, 27, 325, 584, 314}, {429, 231, 1, 52, 640, 284, 481, 475, 281, 56}, {228, 222, 486, 226, 266, 504, 612, 257, 267, 610}, {482, 422, 417, 418, 626, 459, 627, 618, 434, 458}, {489, 425, 490, 292, 580, 533, 625, 623, 621, 499}, {483, 92, 97, 484, 530, 134, 641, 491, 531, 553}, {50, 232, 5, 428, 272, 286, 53, 470, 642, 478}, {483, 165, 358, 354, 587, 555, 643, 589, 591, 378}, {157, 483, 487, 488, 616, 550, 644, 645, 537, 551}, {425, 488, 417, 419, 579, 581, 463, 440, 634, 461}, {222, 230, 484, 226, 270, 606, 500, 267, 245, 635}, {299, 363, 233, 291, 509, 508, 507, 345, 646, 647}, {103, 356, 73, 95, 518, 386, 149, 147, 592, 122}, {229, 44, 45, 100, 262, 48, 249, 506, 132, 123}, {356, 230, 38, 360, 599, 252, 385, 384, 605, 383}, {104, 223, 45, 96, 648, 247, 151, 150, 649, 125}, {22, 159, 293, 288, 175, 650, 303, 305, 651, 304}, {352, 356, 360, 484, 400, 384, 399, 598, 608, 607}, {2, 361, 168, 29, 414, 652, 218, 32, 403, 213}, {484, 483, 359, 97, 491, 596, 597, 553, 641, 653}, {483, 157, 160, 164, 616, 204, 588, 654, 203, 177}, {92, 484, 100, 95, 531, 655, 139, 137, 554, 115}, {223, 420, 96, 104, 529, 656, 649, 648, 657, 150}, {85, 425, 292, 86, 441, 621, 302, 89, 457, 324}, {355, 352, 486, 357, 397, 637, 658, 381, 394, 514}, {353, 289, 487, 357, 578, 600, 566, 366, 659, 660}, {66, 295, 357, 291, 320, 512, 380, 318, 319, 513}, {488, 487, 287, 489, 551, 662, 661, 538, 552, 630}, {486, 294, 287, 290, 609, 334, 629, 628, 307, 332}, {227, 223, 485, 222, 236, 525, 526, 263, 264, 515}, {355, 486, 226, 291, 658, 610, 663, 664, 511, 611}, {43, 103, 95, 225, 146, 147, 114, 243, 523, 593}, {356, 230, 484, 225, 599, 606, 608, 524, 251, 636}, {64, 295, 289, 357, 309, 310, 311, 367, 512, 659}, {157, 482, 162, 158, 665, 619, 198, 199, 617, 171}, {223, 229, 45, 96, 248, 249, 247, 649, 505, 125}, {222, 229, 484, 225, 268, 574, 500, 269, 242, 636}, {422, 78, 418, 99, 433, 435, 434, 569, 112, 666}, {422, 80, 79, 99, 447, 83, 455, 569, 128, 130}, {159, 22, 293, 163, 175, 303, 650, 174, 173, 584}, {101, 362, 71, 6, 667, 405, 141, 154, 415, 74}, {93, 483, 354, 160, 668, 589, 669, 670, 588, 590}, {355, 486, 291, 357, 658, 511, 664, 381, 514, 513}, {362, 101, 169, 6, 667, 567, 671, 415, 154, 220}, {94, 482, 418, 99, 672, 618, 673, 113, 674, 666}, {488, 482, 489, 417, 536, 539, 538, 581, 627, 582}, {484, 356, 95, 359, 608, 592, 554, 597, 387, 594}, {363, 355, 233, 291, 407, 542, 508, 646, 664, 647}, {485, 92, 96, 99, 532, 140, 675, 676, 138, 127}, {78, 94, 418, 99, 111, 673, 435, 112, 113, 666}, {92, 483, 97, 93, 530, 641, 134, 133, 668, 105}, {484, 95, 97, 359, 554, 121, 553, 597, 594, 653}, {72, 71, 97, 359, 75, 106, 129, 390, 371, 653}, {94, 482, 99, 92, 672, 674, 113, 136, 573, 138}, {102, 167, 7, 426, 557, 221, 155, 559, 549, 480}, {10, 164, 158, 98, 184, 183, 182, 118, 558, 541}, {482, 422, 99, 485, 626, 569, 674, 548, 576, 676}, {15, 158, 426, 167, 172, 677, 466, 207, 206, 549}, {92, 482, 99, 485, 573, 674, 138, 532, 548, 676}, {158, 15, 426, 418, 172, 466, 677, 614, 430, 467}, {38, 356, 234, 225, 385, 520, 280, 250, 524, 275}, {94, 482, 158, 418, 672, 617, 540, 673, 618, 614}, {364, 356, 234, 38, 410, 520, 521, 411, 385, 280}, {93, 160, 8, 98, 670, 178, 108, 110, 678, 109}, {355, 233, 226, 36, 542, 277, 663, 374, 278, 246}, {160, 93, 8, 169, 670, 108, 178, 210, 568, 211}, {227, 223, 50, 420, 236, 237, 235, 527, 529, 438}, {363, 0, 233, 36, 413, 283, 508, 406, 39, 278}, {486, 295, 287, 291, 510, 333, 629, 511, 319, 335}, {59, 294, 291, 226, 321, 322, 323, 256, 585, 611}, {66, 363, 299, 291, 409, 509, 347, 318, 646, 345}, {486, 352, 487, 357, 637, 639, 638, 514, 394, 660}, {295, 486, 487, 357, 510, 638, 679, 512, 514, 660}, {296, 22, 288, 166, 337, 305, 336, 604, 209, 680}, {361, 64, 2, 297, 401, 67, 414, 681, 342, 349}, {95, 97, 359, 73, 121, 653, 594, 122, 120, 388}, {423, 482, 417, 418, 620, 627, 460, 431, 618, 458}, {65, 295, 357, 66, 327, 512, 389, 69, 320, 380}, {97, 72, 359, 73, 129, 390, 653, 120, 76, 388}, {420, 223, 96, 485, 529, 649, 656, 528, 525, 675}, {159, 488, 293, 288, 682, 683, 650, 651, 684, 304}, {31, 165, 160, 354, 187, 186, 185, 377, 591, 590}, {484, 486, 487, 489, 502, 638, 560, 496, 503, 552}, {486, 295, 487, 287, 510, 679, 638, 629, 333, 662}, {59, 233, 226, 291, 282, 277, 256, 323, 647, 611}, {233, 355, 226, 291, 542, 663, 277, 647, 664, 611}, {425, 421, 489, 490, 449, 685, 580, 533, 517, 625}, {288, 488, 292, 85, 684, 622, 301, 300, 632, 302}, {421, 425, 489, 417, 449, 580, 685, 465, 463, 582}, {294, 228, 57, 290, 556, 238, 308, 307, 686, 306}, {165, 31, 358, 354, 187, 379, 555, 591, 377, 378}, {103, 356, 364, 73, 518, 410, 522, 149, 386, 412}, {352, 483, 358, 354, 595, 643, 395, 396, 589, 378}, {22, 159, 288, 166, 175, 651, 305, 209, 208, 680}, {356, 352, 359, 484, 400, 398, 387, 608, 598, 597}, {64, 361, 353, 297, 401, 402, 365, 342, 681, 577}, {355, 66, 357, 291, 382, 380, 381, 664, 318, 513}, {487, 486, 287, 489, 638, 629, 662, 552, 503, 630}, {298, 57, 490, 290, 339, 687, 534, 340, 306, 498}, {31, 362, 169, 6, 408, 671, 215, 35, 415, 220}, {488, 425, 292, 85, 579, 621, 622, 632, 441, 302}, {483, 352, 359, 354, 595, 398, 596, 589, 396, 372}, {94, 78, 418, 426, 111, 435, 673, 688, 468, 467}, {229, 43, 44, 100, 241, 47, 262, 506, 116, 132}, {31, 165, 358, 30, 187, 555, 379, 34, 196, 391}, {429, 231, 52, 490, 640, 281, 475, 516, 547, 546}, {94, 102, 78, 426, 144, 145, 111, 688, 559, 468}, {421, 429, 52, 490, 476, 475, 451, 517, 516, 546}, {364, 103, 73, 4, 522, 149, 412, 416, 153, 77}, {420, 227, 424, 50, 527, 571, 437, 438, 235, 436}, {104, 80, 5, 428, 152, 84, 156, 689, 473, 478}, {227, 51, 52, 424, 260, 55, 255, 571, 456, 453}, {487, 289, 293, 287, 600, 313, 601, 662, 331, 328}, {166, 159, 288, 488, 208, 651, 680, 690, 682, 684}, {289, 161, 353, 487, 586, 562, 578, 600, 564, 566}, {482, 485, 489, 417, 548, 495, 539, 627, 544, 582}, {50, 227, 424, 51, 235, 571, 436, 54, 260, 456}, {488, 489, 287, 292, 538, 630, 661, 622, 623, 330}, {482, 483, 157, 488, 535, 616, 665, 536, 537, 645}, {80, 420, 104, 96, 445, 657, 152, 126, 656, 150}, {232, 104, 45, 5, 691, 151, 279, 286, 156, 49}, {288, 488, 287, 292, 684, 661, 329, 301, 622, 330}, {295, 289, 487, 287, 310, 600, 679, 333, 331, 662}, {157, 161, 163, 487, 202, 192, 201, 644, 564, 602}, {483, 482, 164, 98, 535, 692, 654, 694, 693, 558}, {3, 296, 85, 427, 350, 338, 88, 479, 631, 471}, {92, 483, 93, 98, 530, 668, 133, 135, 694, 110}, {95, 484, 100, 225, 554, 655, 115, 593, 636, 695}, {231, 224, 490, 57, 273, 545, 547, 274, 240, 687}, {64, 289, 353, 357, 311, 578, 365, 367, 659, 366}, {2, 297, 24, 168, 349, 344, 28, 218, 696, 217}, {361, 297, 168, 353, 681, 696, 652, 402, 577, 697}, {353, 161, 168, 29, 562, 212, 697, 370, 181, 213}, {289, 295, 487, 357, 310, 679, 600, 659, 512, 660}, {352, 353, 487, 357, 393, 566, 639, 394, 366, 660}, {361, 353, 168, 29, 402, 697, 652, 403, 370, 213}, {484, 229, 100, 225, 574, 506, 655, 636, 242, 695}, {104, 223, 232, 45, 648, 271, 691, 151, 247, 279}, {160, 164, 8, 98, 177, 176, 178, 678, 558, 109}, {164, 9, 8, 98, 197, 12, 176, 558, 131, 109}, {165, 161, 358, 29, 180, 563, 555, 179, 181, 368}, {297, 361, 168, 2, 681, 652, 696, 349, 414, 218}, {161, 353, 358, 29, 562, 369, 563, 181, 370, 368}, {230, 37, 38, 360, 261, 41, 252, 605, 392, 383}, {43, 95, 100, 225, 114, 115, 116, 243, 593, 695}, {420, 80, 104, 428, 445, 152, 657, 469, 473, 689}, {232, 104, 5, 428, 691, 156, 286, 642, 689, 478}, {59, 299, 233, 291, 346, 507, 282, 323, 345, 647}, {355, 363, 66, 291, 407, 409, 382, 664, 646, 318}, {158, 94, 418, 426, 540, 673, 614, 677, 688, 467}, {87, 429, 298, 1, 477, 603, 343, 91, 481, 348}, {420, 227, 485, 424, 527, 526, 528, 437, 571, 543}, {482, 422, 418, 99, 626, 434, 618, 674, 569, 666}, {229, 43, 100, 225, 241, 116, 506, 242, 243, 695}, {294, 486, 287, 291, 609, 629, 334, 322, 511, 335}, {17, 166, 419, 159, 216, 698, 444, 188, 208, 699}, {419, 166, 17, 427, 698, 216, 444, 472, 613, 474}, {166, 488, 419, 159, 690, 634, 698, 208, 682, 699}, {419, 488, 166, 427, 634, 690, 698, 472, 633, 613}, {160, 98, 483, 164, 678, 694, 588, 177, 558, 654}, {483, 98, 160, 93, 694, 678, 588, 668, 110, 670}, {226, 360, 486, 355, 700, 701, 610, 663, 375, 658}, {360, 36, 226, 230, 376, 246, 700, 605, 244, 245}, {226, 36, 360, 355, 246, 376, 700, 663, 374, 375}, {93, 169, 362, 101, 568, 671, 702, 142, 567, 667}, {93, 362, 71, 101, 702, 405, 107, 142, 667, 141}, {71, 362, 93, 354, 405, 702, 107, 373, 404, 669}, {489, 424, 417, 485, 572, 464, 582, 495, 543, 544}, {417, 424, 489, 421, 464, 572, 582, 465, 452, 685}, {102, 10, 158, 94, 148, 182, 703, 144, 119, 540}, {158, 10, 102, 167, 182, 148, 703, 206, 214, 557}, {102, 158, 426, 94, 703, 677, 559, 144, 540, 688}, {426, 158, 102, 167, 677, 703, 559, 549, 206, 557}, {421, 489, 227, 424, 685, 570, 704, 452, 572, 571}, {52, 421, 227, 424, 451, 704, 255, 453, 452, 571}, {489, 227, 222, 224, 570, 263, 501, 705, 254, 265}, {489, 222, 227, 485, 501, 263, 570, 495, 515, 526}, {87, 425, 292, 490, 448, 621, 315, 497, 533, 499}, {292, 425, 87, 86, 621, 448, 315, 324, 457, 90}, {104, 420, 232, 223, 657, 706, 691, 648, 529, 271}, {104, 232, 420, 428, 691, 706, 657, 689, 642, 469}, {232, 420, 50, 223, 706, 438, 272, 271, 529, 237}, {232, 50, 420, 428, 272, 438, 706, 642, 470, 469}, {226, 484, 360, 230, 635, 607, 700, 245, 606, 605}, {226, 360, 484, 486, 700, 607, 635, 610, 701, 502}, {486, 360, 352, 355, 701, 399, 637, 658, 375, 397}, {352, 360, 486, 484, 399, 701, 637, 598, 607, 502}, {162, 488, 157, 159, 707, 645, 198, 189, 682, 200}, {157, 488, 162, 482, 645, 707, 198, 665, 536, 619}, {490, 57, 429, 231, 687, 708, 516, 547, 274, 640}, {429, 57, 490, 298, 708, 687, 516, 603, 339, 534}, {57, 1, 429, 231, 60, 481, 708, 274, 284, 640}, {429, 1, 57, 298, 481, 60, 708, 603, 348, 339}, {158, 98, 482, 94, 541, 693, 617, 540, 117, 672}, {482, 98, 158, 164, 693, 541, 617, 692, 558, 183}, {353, 297, 161, 289, 577, 709, 562, 578, 341, 586}, {353, 161, 297, 168, 562, 709, 577, 697, 212, 696}, {161, 297, 24, 289, 709, 344, 191, 586, 341, 312}, {161, 24, 297, 168, 191, 344, 709, 212, 217, 696}, {159, 293, 487, 163, 650, 601, 710, 174, 584, 602}, {487, 293, 159, 488, 601, 650, 710, 551, 683, 682}, {159, 487, 157, 163, 710, 644, 200, 174, 602, 201}, {157, 487, 159, 488, 644, 710, 200, 645, 551, 682}, {290, 228, 486, 294, 686, 612, 628, 307, 556, 609}, {290, 486, 228, 489, 628, 612, 686, 624, 503, 711}, {485, 99, 420, 422, 676, 712, 528, 576, 569, 446}, {420, 99, 485, 96, 712, 676, 528, 656, 127, 675}, {99, 80, 420, 422, 128, 445, 712, 569, 447, 446}, {420, 80, 99, 96, 445, 128, 712, 656, 126, 127}, {96, 484, 229, 100, 713, 574, 505, 124, 655, 506}, {92, 96, 484, 485, 140, 713, 531, 532, 675, 492}, {92, 484, 96, 100, 531, 713, 140, 139, 655, 124}, {161, 358, 483, 165, 563, 643, 714, 180, 555, 587}, {483, 358, 161, 487, 643, 563, 714, 550, 565, 564}, {161, 483, 157, 165, 714, 616, 202, 180, 587, 205}, {157, 483, 161, 487, 616, 714, 202, 644, 550, 564}, {362, 31, 160, 354, 408, 185, 715, 404, 377, 590}, {160, 31, 362, 169, 185, 408, 715, 210, 215, 671}, {362, 160, 93, 354, 715, 670, 702, 404, 590, 669}, {93, 160, 362, 169, 670, 715, 702, 568, 210, 671}, {482, 164, 157, 483, 692, 203, 665, 535, 654, 616}, {157, 164, 482, 158, 203, 692, 665, 199, 183, 617}, {228, 489, 222, 224, 711, 501, 266, 239, 705, 265}, {222, 489, 228, 486, 501, 711, 266, 504, 503, 612}, {288, 166, 427, 296, 680, 613, 716, 336, 604, 631}, {288, 427, 166, 488, 716, 613, 680, 684, 633, 690}, {85, 288, 427, 296, 300, 716, 471, 338, 336, 631}, {85, 427, 288, 488, 471, 716, 300, 632, 633, 684}, {484, 223, 96, 229, 575, 649, 713, 574, 248, 505}, {484, 96, 223, 485, 713, 649, 575, 492, 675, 525}, {488, 293, 287, 487, 683, 328, 661, 551, 601, 662}, {287, 293, 488, 288, 328, 683, 661, 329, 304, 684}, {419, 488, 162, 159, 634, 707, 717, 699, 682, 189}, {162, 419, 17, 423, 717, 444, 190, 561, 443, 442}, {17, 419, 162, 159, 444, 717, 190, 188, 699, 189}, {482, 98, 92, 94, 693, 135, 573, 672, 117, 136}, {92, 98, 482, 483, 135, 693, 573, 530, 694, 535}, {358, 487, 352, 353, 565, 639, 395, 369, 566, 393}, {352, 487, 358, 483, 639, 565, 395, 595, 550, 643}, {359, 483, 93, 97, 596, 668, 718, 653, 641, 105}, {359, 93, 483, 354, 718, 668, 596, 372, 669, 589}, {71, 359, 93, 97, 371, 718, 107, 106, 653, 105}, {71, 93, 359, 354, 107, 718, 371, 373, 669, 372}, {52, 490, 227, 421, 546, 719, 255, 451, 517, 704}, {227, 490, 52, 224, 719, 546, 255, 254, 545, 253}, {490, 489, 227, 421, 625, 570, 719, 517, 685, 704}, {227, 489, 490, 224, 570, 625, 719, 254, 705, 545}, {57, 490, 228, 224, 687, 720, 238, 240, 545, 239}, {228, 490, 57, 290, 720, 687, 238, 686, 498, 306}, {490, 489, 228, 224, 625, 711, 720, 545, 705, 239}, {228, 489, 490, 290, 711, 625, 720, 686, 624, 498}, {162, 419, 482, 488, 717, 721, 619, 707, 634, 536}, {482, 419, 162, 423, 721, 717, 619, 620, 443, 561}, {419, 417, 482, 488, 461, 627, 721, 634, 581, 536}, {482, 417, 419, 423, 627, 461, 721, 620, 460, 443}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
-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}}
-]
-
diff --git a/test/test_fem/test_gradient_tetrahedron_4.verified b/test/test_fem/test_gradient_tetrahedron_4.verified
deleted file mode 100644
index 03f5ec5cf..000000000
--- a/test/test_fem/test_gradient_tetrahedron_4.verified
+++ /dev/null
@@ -1,76 +0,0 @@
-Epsilon : 1e-12
-FEEngine [
- + id : my_fem
- + element dimension : 3
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 3
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 8
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 48
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{6, 8}, {8, 9}, {9, 10}, {10, 7}, {7, 11}, {11, 12}, {12, 13}, {13, 3}, {3, 14}, {14, 15}, {15, 16}, {16, 2}, {2, 17}, {17, 18}, {18, 19}, {19, 6}, {0, 20}, {20, 21}, {21, 22}, {22, 4}, {4, 23}, {23, 24}, {24, 25}, {25, 5}, {5, 26}, {26, 27}, {27, 28}, {28, 1}, {1, 29}, {29, 30}, {30, 31}, {31, 0}, {2, 32}, {32, 33}, {33, 34}, {34, 0}, {6, 35}, {35, 36}, {36, 37}, {37, 4}, {7, 38}, {38, 39}, {39, 40}, {40, 5}, {3, 41}, {41, 42}, {42, 43}, {43, 1}}
- ]
- ]
- (not_ghost:_triangle_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_3
- + size : 240
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{45, 49, 35}, {45, 8, 50}, {46, 38, 51}, {23, 47, 52}, {46, 50, 10}, {37, 49, 47}, {25, 52, 48}, {40, 48, 51}, {35, 49, 36}, {38, 39, 51}, {8, 9, 50}, {23, 52, 24}, {36, 49, 37}, {9, 10, 50}, {39, 40, 51}, {24, 52, 25}, {45, 44, 49}, {45, 50, 44}, {46, 44, 50}, {44, 47, 49}, {46, 51, 44}, {44, 52, 47}, {44, 51, 48}, {44, 48, 52}, {45, 35, 53}, {45, 53, 8}, {46, 54, 38}, {23, 55, 47}, {46, 10, 54}, {37, 47, 55}, {25, 48, 56}, {40, 56, 48}, {4, 37, 55}, {6, 53, 35}, {7, 54, 10}, {7, 38, 54}, {6, 8, 53}, {5, 56, 40}, {4, 55, 23}, {5, 25, 56}, {11, 62, 58}, {14, 63, 59}, {8, 64, 60}, {17, 65, 61}, {10, 58, 64}, {19, 60, 65}, {13, 59, 62}, {16, 61, 63}, {14, 15, 63}, {11, 12, 62}, {17, 18, 65}, {8, 9, 64}, {12, 13, 62}, {15, 16, 63}, {9, 10, 64}, {18, 19, 65}, {58, 62, 57}, {59, 57, 62}, {59, 63, 57}, {61, 57, 63}, {58, 57, 64}, {60, 64, 57}, {60, 57, 65}, {61, 65, 57}, {11, 58, 67}, {14, 59, 66}, {8, 60, 69}, {17, 61, 68}, {10, 67, 58}, {19, 69, 60}, {13, 66, 59}, {16, 68, 61}, {2, 68, 16}, {3, 66, 13}, {6, 69, 19}, {7, 67, 10}, {7, 11, 67}, {3, 14, 66}, {6, 8, 69}, {2, 17, 68}, {26, 75, 71}, {29, 76, 72}, {23, 77, 73}, {20, 78, 74}, {25, 71, 77}, {22, 73, 78}, {28, 72, 75}, {31, 74, 76}, {29, 30, 76}, {26, 27, 75}, {20, 21, 78}, {23, 24, 77}, {27, 28, 75}, {30, 31, 76}, {24, 25, 77}, {21, 22, 78}, {71, 75, 70}, {72, 70, 75}, {72, 76, 70}, {70, 76, 74}, {71, 70, 77}, {70, 73, 77}, {70, 78, 73}, {70, 74, 78}, {26, 71, 80}, {29, 72, 79}, {23, 73, 82}, {20, 74, 81}, {25, 80, 71}, {22, 82, 73}, {28, 79, 72}, {31, 81, 74}, {0, 81, 31}, {1, 79, 28}, {4, 82, 22}, {5, 80, 25}, {5, 26, 80}, {1, 29, 79}, {4, 23, 82}, {0, 20, 81}, {41, 84, 88}, {14, 89, 84}, {29, 86, 90}, {32, 91, 85}, {16, 85, 89}, {43, 88, 86}, {34, 87, 91}, {31, 90, 87}, {41, 88, 42}, {14, 15, 89}, {29, 90, 30}, {32, 33, 91}, {42, 88, 43}, {15, 16, 89}, {33, 34, 91}, {30, 90, 31}, {84, 89, 83}, {84, 83, 88}, {85, 83, 89}, {86, 88, 83}, {85, 91, 83}, {86, 83, 90}, {87, 90, 83}, {87, 83, 91}, {14, 84, 92}, {41, 92, 84}, {29, 94, 86}, {32, 85, 93}, {43, 86, 94}, {16, 93, 85}, {31, 87, 95}, {34, 95, 87}, {1, 43, 94}, {2, 93, 16}, {3, 92, 41}, {3, 14, 92}, {1, 94, 29}, {2, 32, 93}, {0, 31, 95}, {0, 95, 34}, {32, 97, 101}, {17, 102, 97}, {35, 103, 98}, {20, 99, 104}, {19, 98, 102}, {34, 101, 99}, {22, 104, 100}, {37, 100, 103}, {32, 101, 33}, {35, 36, 103}, {17, 18, 102}, {20, 104, 21}, {33, 101, 34}, {18, 19, 102}, {36, 37, 103}, {21, 104, 22}, {97, 96, 101}, {97, 102, 96}, {98, 96, 102}, {99, 101, 96}, {98, 103, 96}, {99, 96, 104}, {100, 96, 103}, {100, 104, 96}, {32, 105, 97}, {17, 97, 105}, {35, 98, 106}, {20, 107, 99}, {19, 106, 98}, {34, 99, 107}, {22, 100, 108}, {37, 108, 100}, {0, 34, 107}, {2, 105, 32}, {6, 106, 19}, {6, 35, 106}, {2, 17, 105}, {4, 108, 37}, {0, 107, 20}, {4, 22, 108}, {11, 110, 115}, {38, 114, 110}, {26, 116, 112}, {41, 111, 117}, {13, 115, 111}, {40, 112, 114}, {43, 117, 113}, {28, 113, 116}, {11, 115, 12}, {38, 39, 114}, {26, 27, 116}, {41, 117, 42}, {39, 40, 114}, {12, 115, 13}, {42, 117, 43}, {27, 28, 116}, {109, 110, 114}, {109, 115, 110}, {111, 115, 109}, {112, 109, 114}, {111, 109, 117}, {112, 116, 109}, {113, 109, 116}, {113, 117, 109}, {11, 118, 110}, {38, 110, 118}, {26, 112, 120}, {41, 119, 111}, {40, 120, 112}, {13, 111, 119}, {28, 121, 113}, {43, 113, 121}, {5, 120, 40}, {3, 13, 119}, {7, 38, 118}, {7, 118, 11}, {5, 26, 120}, {3, 119, 41}, {1, 121, 28}, {1, 43, 121}}
- ]
- ]
- (not_ghost:_tetrahedron_4) [
- Array<unsigned int> [
- + id : mesh:connectivities:_tetrahedron_4
- + size : 341
- + nb_component : 4
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{124, 123, 125, 129}, {43, 86, 130, 88}, {70, 124, 129, 126}, {48, 77, 25, 52}, {31, 0, 81, 95}, {0, 107, 81, 95}, {126, 91, 87, 101}, {124, 70, 129, 125}, {43, 121, 113, 130}, {55, 100, 82, 108}, {100, 55, 82, 73}, {23, 55, 73, 82}, {71, 75, 125, 112}, {123, 44, 124, 125}, {43, 113, 117, 130}, {94, 43, 86, 130}, {122, 123, 128, 129}, {46, 10, 58, 50}, {99, 107, 81, 20}, {125, 112, 116, 109}, {79, 72, 28, 130}, {123, 122, 125, 129}, {67, 11, 7, 118}, {123, 127, 128, 129}, {124, 44, 49, 47}, {17, 65, 18, 102}, {76, 90, 30, 31}, {54, 10, 7, 67}, {9, 10, 50, 64}, {38, 54, 7, 118}, {123, 124, 127, 129}, {12, 115, 62, 13}, {97, 61, 102, 127}, {45, 53, 8, 69}, {38, 114, 39, 51}, {125, 75, 129, 116}, {122, 44, 123, 125}, {71, 70, 77, 124}, {114, 112, 125, 109}, {32, 93, 97, 85}, {53, 6, 8, 69}, {117, 128, 129, 109}, {63, 61, 16, 89}, {76, 90, 31, 74}, {61, 85, 16, 89}, {65, 123, 60, 98}, {55, 100, 47, 73}, {100, 47, 103, 37}, {96, 123, 103, 124}, {55, 23, 4, 82}, {78, 100, 22, 73}, {61, 85, 89, 127}, {61, 127, 89, 63}, {121, 43, 94, 130}, {108, 22, 82, 4}, {14, 92, 3, 66}, {78, 21, 104, 20}, {100, 78, 104, 124}, {14, 15, 89, 63}, {90, 126, 87, 74}, {90, 76, 126, 74}, {3, 13, 66, 119}, {108, 55, 4, 82}, {58, 11, 110, 62}, {11, 115, 110, 62}, {57, 123, 60, 65}, {122, 58, 110, 62}, {115, 122, 110, 62}, {117, 128, 88, 129}, {86, 129, 130, 88}, {70, 71, 125, 124}, {107, 0, 34, 95}, {122, 114, 125, 109}, {126, 86, 83, 129}, {92, 3, 66, 119}, {129, 86, 83, 88}, {128, 41, 119, 111}, {117, 128, 111, 41}, {11, 12, 115, 62}, {33, 32, 101, 91}, {70, 124, 126, 74}, {100, 124, 47, 73}, {96, 124, 126, 127}, {78, 70, 124, 73}, {90, 76, 30, 29}, {96, 123, 124, 127}, {15, 63, 16, 89}, {121, 79, 1, 28}, {76, 70, 126, 74}, {122, 114, 109, 110}, {129, 117, 130, 88}, {123, 44, 49, 124}, {26, 80, 5, 120}, {123, 65, 102, 98}, {57, 123, 127, 128}, {117, 128, 109, 111}, {70, 78, 124, 74}, {95, 107, 81, 87}, {55, 100, 37, 47}, {77, 24, 25, 52}, {100, 78, 22, 104}, {56, 71, 25, 48}, {14, 59, 89, 84}, {96, 100, 104, 124}, {2, 105, 68, 17}, {124, 123, 103, 49}, {123, 57, 60, 64}, {44, 124, 52, 47}, {71, 112, 48, 56}, {41, 117, 88, 42}, {99, 96, 126, 101}, {97, 85, 127, 101}, {34, 91, 101, 87}, {128, 127, 83, 129}, {126, 90, 83, 86}, {75, 71, 125, 70}, {99, 126, 74, 87}, {23, 55, 47, 73}, {100, 78, 124, 73}, {32, 91, 85, 101}, {57, 122, 62, 58}, {71, 77, 25, 48}, {70, 77, 124, 73}, {114, 38, 110, 51}, {114, 40, 39, 51}, {59, 14, 89, 63}, {53, 106, 35, 6}, {45, 123, 98, 60}, {99, 126, 87, 101}, {106, 53, 69, 6}, {46, 122, 110, 51}, {128, 122, 129, 109}, {124, 100, 47, 103}, {107, 99, 81, 87}, {125, 44, 48, 51}, {38, 46, 110, 51}, {44, 123, 49, 45}, {124, 47, 49, 103}, {36, 35, 49, 103}, {46, 122, 51, 44}, {54, 67, 7, 118}, {10, 64, 58, 50}, {122, 114, 51, 125}, {11, 58, 118, 67}, {44, 122, 51, 125}, {58, 11, 118, 110}, {22, 100, 82, 73}, {46, 122, 58, 110}, {108, 100, 82, 22}, {45, 60, 8, 50}, {99, 81, 74, 20}, {60, 45, 8, 69}, {75, 71, 26, 112}, {107, 0, 81, 20}, {126, 91, 83, 87}, {31, 90, 87, 74}, {34, 107, 95, 87}, {126, 96, 127, 101}, {91, 126, 127, 101}, {92, 14, 84, 66}, {105, 32, 2, 93}, {47, 49, 103, 37}, {115, 122, 109, 110}, {33, 91, 101, 34}, {49, 36, 103, 37}, {112, 71, 48, 125}, {59, 128, 89, 84}, {19, 65, 60, 98}, {124, 126, 127, 129}, {126, 91, 127, 83}, {31, 81, 74, 87}, {81, 99, 74, 87}, {117, 113, 129, 130}, {84, 128, 88, 41}, {113, 117, 129, 109}, {90, 76, 29, 86}, {65, 19, 102, 98}, {55, 100, 108, 37}, {96, 123, 102, 98}, {14, 59, 84, 66}, {100, 96, 103, 124}, {32, 105, 97, 93}, {99, 34, 101, 87}, {127, 126, 83, 129}, {94, 29, 130, 86}, {19, 106, 69, 6}, {128, 117, 88, 41}, {123, 96, 103, 98}, {46, 38, 110, 118}, {77, 23, 24, 52}, {19, 65, 102, 18}, {121, 79, 28, 130}, {46, 54, 38, 118}, {113, 121, 28, 130}, {108, 55, 37, 4}, {112, 75, 116, 26}, {56, 40, 5, 120}, {75, 27, 28, 116}, {127, 85, 89, 83}, {66, 59, 84, 128}, {85, 61, 97, 127}, {122, 125, 129, 109}, {26, 75, 116, 27}, {128, 129, 83, 88}, {122, 123, 57, 128}, {40, 112, 56, 48}, {80, 56, 25, 5}, {84, 128, 83, 88}, {91, 85, 127, 83}, {57, 61, 63, 127}, {123, 122, 64, 50}, {3, 92, 41, 119}, {44, 123, 45, 50}, {47, 124, 52, 73}, {79, 72, 130, 29}, {32, 85, 97, 101}, {2, 93, 16, 68}, {105, 93, 68, 97}, {97, 61, 68, 17}, {85, 91, 127, 101}, {96, 97, 127, 101}, {105, 97, 68, 17}, {124, 77, 52, 73}, {56, 71, 80, 25}, {60, 64, 8, 50}, {64, 9, 8, 50}, {65, 61, 102, 17}, {93, 105, 68, 2}, {61, 97, 102, 17}, {78, 21, 22, 104}, {23, 47, 52, 73}, {112, 40, 56, 120}, {80, 56, 5, 120}, {31, 95, 81, 87}, {99, 107, 34, 87}, {58, 46, 110, 118}, {43, 121, 94, 1}, {112, 75, 125, 116}, {122, 114, 110, 51}, {77, 23, 52, 73}, {90, 126, 83, 87}, {13, 66, 111, 59}, {111, 66, 13, 119}, {66, 128, 111, 59}, {111, 128, 66, 119}, {60, 50, 123, 64}, {123, 50, 60, 45}, {74, 104, 126, 99}, {104, 20, 74, 78}, {74, 20, 104, 99}, {45, 69, 106, 53}, {45, 106, 35, 53}, {35, 106, 45, 98}, {129, 116, 109, 125}, {109, 116, 129, 113}, {54, 10, 58, 46}, {58, 10, 54, 67}, {54, 58, 118, 46}, {118, 58, 54, 67}, {113, 129, 75, 116}, {28, 113, 75, 116}, {129, 75, 70, 72}, {129, 70, 75, 125}, {43, 117, 88, 130}, {88, 117, 43, 42}, {56, 112, 80, 71}, {56, 80, 112, 120}, {80, 112, 26, 71}, {80, 26, 112, 120}, {74, 124, 104, 78}, {74, 104, 124, 126}, {126, 104, 96, 99}, {96, 104, 126, 124}, {62, 128, 57, 59}, {57, 128, 62, 122}, {130, 29, 121, 79}, {121, 29, 130, 94}, {29, 1, 121, 79}, {121, 1, 29, 94}, {58, 50, 122, 46}, {122, 50, 58, 64}, {97, 93, 61, 85}, {97, 61, 93, 68}, {61, 93, 16, 85}, {61, 16, 93, 68}, {59, 89, 127, 63}, {127, 89, 59, 128}, {59, 127, 57, 63}, {57, 127, 59, 128}, {86, 76, 126, 90}, {86, 126, 76, 129}, {125, 51, 112, 114}, {112, 51, 125, 48}, {51, 40, 112, 114}, {112, 40, 51, 48}, {48, 124, 77, 52}, {44, 48, 124, 125}, {44, 124, 48, 52}, {61, 102, 123, 65}, {123, 102, 61, 127}, {61, 123, 57, 65}, {57, 123, 61, 127}, {106, 19, 60, 98}, {60, 19, 106, 69}, {106, 60, 45, 98}, {45, 60, 106, 69}, {122, 64, 57, 123}, {57, 64, 122, 58}, {76, 129, 70, 72}, {70, 129, 76, 126}, {84, 66, 119, 92}, {84, 119, 66, 128}, {41, 84, 119, 92}, {41, 119, 84, 128}, {124, 71, 48, 77}, {124, 48, 71, 125}, {128, 89, 83, 127}, {83, 89, 128, 84}, {111, 128, 62, 59}, {62, 111, 13, 115}, {13, 111, 62, 59}, {122, 50, 44, 46}, {44, 50, 122, 123}, {102, 127, 96, 97}, {96, 127, 102, 123}, {103, 123, 45, 49}, {103, 45, 123, 98}, {35, 103, 45, 49}, {35, 45, 103, 98}, {28, 130, 75, 113}, {75, 130, 28, 72}, {130, 129, 75, 113}, {75, 129, 130, 72}, {29, 130, 76, 72}, {76, 130, 29, 86}, {130, 129, 76, 72}, {76, 129, 130, 86}, {62, 111, 122, 128}, {122, 111, 62, 115}, {111, 109, 122, 128}, {122, 109, 111, 115}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
-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}}
-]
-
diff --git a/test/test_fem/test_gradient_triangle_3.verified b/test/test_fem/test_gradient_triangle_3.verified
deleted file mode 100644
index d258150dd..000000000
--- a/test/test_fem/test_gradient_triangle_3.verified
+++ /dev/null
@@ -1,66 +0,0 @@
-Epsilon : 1e-12
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 4
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 8
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0, 4}, {4, 1}, {1, 5}, {5, 2}, {2, 6}, {6, 3}, {3, 7}, {7, 0}}
- ]
- ]
- (not_ghost:_triangle_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_3
- + size : 16
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{3, 9, 6}, {0, 12, 7}, {2, 10, 5}, {1, 11, 4}, {7, 8, 9}, {6, 9, 8}, {6, 8, 10}, {7, 12, 8}, {5, 10, 8}, {4, 8, 12}, {4, 11, 8}, {5, 8, 11}, {0, 4, 12}, {3, 7, 9}, {1, 5, 11}, {2, 6, 10}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
-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}}
-]
-
diff --git a/test/test_fem/test_gradient_triangle_6.verified b/test/test_fem/test_gradient_triangle_6.verified
deleted file mode 100644
index 8568679dd..000000000
--- a/test/test_fem/test_gradient_triangle_6.verified
+++ /dev/null
@@ -1,66 +0,0 @@
-Epsilon : 1e-12
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 4
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}}
- ]
- ]
- (not_ghost:_segment_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_3
- + size : 8
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{0, 4, 5}, {4, 1, 6}, {1, 7, 8}, {7, 2, 9}, {2, 10, 11}, {10, 3, 12}, {3, 13, 14}, {13, 0, 15}}
- ]
- ]
- (not_ghost:_triangle_6) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_6
- + size : 16
- + nb_component : 6
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{3, 17, 10, 21, 22, 12}, {0, 20, 13, 23, 24, 15}, {2, 18, 7, 25, 26, 9}, {1, 19, 4, 27, 28, 6}, {13, 16, 17, 29, 30, 31}, {10, 17, 16, 22, 30, 32}, {10, 16, 18, 32, 33, 34}, {13, 20, 16, 24, 35, 29}, {7, 18, 16, 26, 33, 36}, {4, 16, 20, 37, 35, 38}, {4, 19, 16, 28, 39, 37}, {7, 16, 19, 36, 39, 40}, {0, 4, 20, 5, 38, 23}, {3, 13, 17, 14, 31, 21}, {1, 7, 19, 8, 40, 27}, {2, 10, 18, 11, 34, 25}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
-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}}
-]
-
diff --git a/test/test_fem/test_integrate.cc b/test/test_fem/test_integrate.cc
deleted file mode 100644
index e8417ac80..000000000
--- a/test/test_fem/test_integrate.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * @file test_integrate.cc
- *
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Fri Jun 17 2011
- * @date last modification: Thu Jun 05 2014
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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 "mesh.hh"
-#include "mesh_io.hh"
-#include "mesh_io_msh.hh"
-#include "shape_lagrange.hh"
-#include "integrator_gauss.hh"
-/* -------------------------------------------------------------------------- */
-#include <cstdlib>
-#include <fstream>
-#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;
-
- MeshIOMSH mesh_io;
- Mesh my_mesh(dim);
-
- std::stringstream meshfilename; meshfilename << type << ".msh";
- mesh_io.read(meshfilename.str(), my_mesh);
-
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
-
- std::stringstream outfilename; outfilename << "out_" << type << ".txt";
- std::ofstream my_file(outfilename.str().c_str());
-
- fem->initShapeFunctions();
-
- std::cout << *fem << std::endl;
-
- UInt nb_element = my_mesh.getNbElement(type);
- UInt nb_quadrature_points = fem->getNbQuadraturePoints(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);
-
- //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};
- my_file << val_on_quad << std::endl << 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];
- }
-
- my_file << "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_fem/test_integrate_hexahedron_8.verified b/test/test_fem/test_integrate_hexahedron_8.verified
deleted file mode 100644
index e57e20e56..000000000
--- a/test/test_fem/test_integrate_hexahedron_8.verified
+++ /dev/null
@@ -1,67 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 3
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 3
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 8
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 48
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{6, 8}, {8, 9}, {9, 10}, {10, 7}, {7, 11}, {11, 12}, {12, 13}, {13, 3}, {3, 14}, {14, 15}, {15, 16}, {16, 2}, {2, 17}, {17, 18}, {18, 19}, {19, 6}, {0, 20}, {20, 21}, {21, 22}, {22, 4}, {4, 23}, {23, 24}, {24, 25}, {25, 5}, {5, 26}, {26, 27}, {27, 28}, {28, 1}, {1, 29}, {29, 30}, {30, 31}, {31, 0}, {2, 32}, {32, 33}, {33, 34}, {34, 0}, {6, 35}, {35, 36}, {36, 37}, {37, 4}, {7, 38}, {38, 39}, {39, 40}, {40, 5}, {3, 41}, {41, 42}, {42, 43}, {43, 1}}
- ]
- ]
- (not_ghost:_quadrangle_4) [
- Array<unsigned int> [
- + id : mesh:connectivities:_quadrangle_4
- + size : 96
- + nb_component : 4
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{6, 8, 44, 35}, {35, 44, 45, 36}, {36, 45, 46, 37}, {37, 46, 23, 4}, {8, 9, 47, 44}, {44, 47, 48, 45}, {45, 48, 49, 46}, {46, 49, 24, 23}, {9, 10, 50, 47}, {47, 50, 51, 48}, {48, 51, 52, 49}, {49, 52, 25, 24}, {10, 7, 38, 50}, {50, 38, 39, 51}, {51, 39, 40, 52}, {52, 40, 5, 25}, {3, 14, 53, 13}, {13, 53, 54, 12}, {12, 54, 55, 11}, {11, 55, 10, 7}, {14, 15, 56, 53}, {53, 56, 57, 54}, {54, 57, 58, 55}, {55, 58, 9, 10}, {15, 16, 59, 56}, {56, 59, 60, 57}, {57, 60, 61, 58}, {58, 61, 8, 9}, {16, 2, 17, 59}, {59, 17, 18, 60}, {60, 18, 19, 61}, {61, 19, 6, 8}, {4, 23, 62, 22}, {22, 62, 63, 21}, {21, 63, 64, 20}, {20, 64, 31, 0}, {23, 24, 65, 62}, {62, 65, 66, 63}, {63, 66, 67, 64}, {64, 67, 30, 31}, {24, 25, 68, 65}, {65, 68, 69, 66}, {66, 69, 70, 67}, {67, 70, 29, 30}, {25, 5, 26, 68}, {68, 26, 27, 69}, {69, 27, 28, 70}, {70, 28, 1, 29}, {3, 14, 71, 41}, {41, 71, 72, 42}, {42, 72, 73, 43}, {43, 73, 29, 1}, {14, 15, 74, 71}, {71, 74, 75, 72}, {72, 75, 76, 73}, {73, 76, 30, 29}, {15, 16, 77, 74}, {74, 77, 78, 75}, {75, 78, 79, 76}, {76, 79, 31, 30}, {16, 2, 32, 77}, {77, 32, 33, 78}, {78, 33, 34, 79}, {79, 34, 0, 31}, {2, 17, 80, 32}, {32, 80, 81, 33}, {33, 81, 82, 34}, {34, 82, 20, 0}, {17, 18, 83, 80}, {80, 83, 84, 81}, {81, 84, 85, 82}, {82, 85, 21, 20}, {18, 19, 86, 83}, {83, 86, 87, 84}, {84, 87, 88, 85}, {85, 88, 22, 21}, {19, 6, 35, 86}, {86, 35, 36, 87}, {87, 36, 37, 88}, {88, 37, 4, 22}, {7, 38, 89, 11}, {11, 89, 90, 12}, {12, 90, 91, 13}, {13, 91, 41, 3}, {38, 39, 92, 89}, {89, 92, 93, 90}, {90, 93, 94, 91}, {91, 94, 42, 41}, {39, 40, 95, 92}, {92, 95, 96, 93}, {93, 96, 97, 94}, {94, 97, 43, 42}, {40, 5, 26, 95}, {95, 26, 27, 96}, {96, 27, 28, 97}, {97, 28, 1, 43}}
- ]
- ]
- (not_ghost:_hexahedron_8) [
- Array<unsigned int> [
- + id : mesh:connectivities:_hexahedron_8
- + size : 64
- + nb_component : 8
- + allocated size : 2000
- + memory size : 62.50KiByte
- + values : {{89, 38, 7, 11, 98, 50, 10, 55}, {98, 50, 10, 55, 99, 47, 9, 58}, {99, 47, 9, 58, 100, 44, 8, 61}, {100, 44, 8, 61, 86, 35, 6, 19}, {90, 89, 11, 12, 101, 98, 55, 54}, {101, 98, 55, 54, 102, 99, 58, 57}, {102, 99, 58, 57, 103, 100, 61, 60}, {103, 100, 61, 60, 83, 86, 19, 18}, {91, 90, 12, 13, 104, 101, 54, 53}, {104, 101, 54, 53, 105, 102, 57, 56}, {105, 102, 57, 56, 106, 103, 60, 59}, {106, 103, 60, 59, 80, 83, 18, 17}, {41, 91, 13, 3, 71, 104, 53, 14}, {71, 104, 53, 14, 74, 105, 56, 15}, {74, 105, 56, 15, 77, 106, 59, 16}, {77, 106, 59, 16, 32, 80, 17, 2}, {92, 39, 38, 89, 107, 51, 50, 98}, {107, 51, 50, 98, 108, 48, 47, 99}, {108, 48, 47, 99, 109, 45, 44, 100}, {109, 45, 44, 100, 87, 36, 35, 86}, {93, 92, 89, 90, 110, 107, 98, 101}, {110, 107, 98, 101, 111, 108, 99, 102}, {111, 108, 99, 102, 112, 109, 100, 103}, {112, 109, 100, 103, 84, 87, 86, 83}, {94, 93, 90, 91, 113, 110, 101, 104}, {113, 110, 101, 104, 114, 111, 102, 105}, {114, 111, 102, 105, 115, 112, 103, 106}, {115, 112, 103, 106, 81, 84, 83, 80}, {42, 94, 91, 41, 72, 113, 104, 71}, {72, 113, 104, 71, 75, 114, 105, 74}, {75, 114, 105, 74, 78, 115, 106, 77}, {78, 115, 106, 77, 33, 81, 80, 32}, {95, 40, 39, 92, 116, 52, 51, 107}, {116, 52, 51, 107, 117, 49, 48, 108}, {117, 49, 48, 108, 118, 46, 45, 109}, {118, 46, 45, 109, 88, 37, 36, 87}, {96, 95, 92, 93, 119, 116, 107, 110}, {119, 116, 107, 110, 120, 117, 108, 111}, {120, 117, 108, 111, 121, 118, 109, 112}, {121, 118, 109, 112, 85, 88, 87, 84}, {97, 96, 93, 94, 122, 119, 110, 113}, {122, 119, 110, 113, 123, 120, 111, 114}, {123, 120, 111, 114, 124, 121, 112, 115}, {124, 121, 112, 115, 82, 85, 84, 81}, {43, 97, 94, 42, 73, 122, 113, 72}, {73, 122, 113, 72, 76, 123, 114, 75}, {76, 123, 114, 75, 79, 124, 115, 78}, {79, 124, 115, 78, 34, 82, 81, 33}, {26, 5, 40, 95, 68, 25, 52, 116}, {68, 25, 52, 116, 65, 24, 49, 117}, {65, 24, 49, 117, 62, 23, 46, 118}, {62, 23, 46, 118, 22, 4, 37, 88}, {27, 26, 95, 96, 69, 68, 116, 119}, {69, 68, 116, 119, 66, 65, 117, 120}, {66, 65, 117, 120, 63, 62, 118, 121}, {63, 62, 118, 121, 21, 22, 88, 85}, {28, 27, 96, 97, 70, 69, 119, 122}, {70, 69, 119, 122, 67, 66, 120, 123}, {67, 66, 120, 123, 64, 63, 121, 124}, {64, 63, 121, 124, 20, 21, 85, 82}, {1, 28, 97, 43, 29, 70, 122, 73}, {29, 70, 122, 73, 30, 67, 123, 76}, {30, 67, 123, 76, 31, 64, 124, 79}, {31, 64, 124, 79, 0, 20, 82, 34}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_integrate_quadrangle_4.verified b/test/test_fem/test_integrate_quadrangle_4.verified
deleted file mode 100644
index 4900a757d..000000000
--- a/test/test_fem/test_integrate_quadrangle_4.verified
+++ /dev/null
@@ -1,57 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 4
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 8
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0, 4}, {4, 1}, {1, 5}, {5, 2}, {2, 6}, {6, 3}, {3, 7}, {7, 0}}
- ]
- ]
- (not_ghost:_quadrangle_4) [
- Array<unsigned int> [
- + id : mesh:connectivities:_quadrangle_4
- + size : 4
- + nb_component : 4
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{2, 6, 8, 5}, {5, 8, 4, 1}, {6, 3, 7, 8}, {8, 7, 0, 4}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_integrate_quadrangle_8.verified b/test/test_fem/test_integrate_quadrangle_8.verified
deleted file mode 100644
index 18df422b5..000000000
--- a/test/test_fem/test_integrate_quadrangle_8.verified
+++ /dev/null
@@ -1,37 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_quadrangle_8) [
- Array<unsigned int> [
- + id : mesh:connectivities:_quadrangle_8
- + size : 4
- + nb_component : 8
- + allocated size : 2000
- + memory size : 62.50KiByte
- + values : {{2, 10, 16, 7, 11, 17, 18, 9}, {7, 16, 4, 1, 18, 19, 6, 8}, {10, 3, 13, 16, 12, 14, 20, 17}, {16, 13, 0, 4, 20, 15, 5, 19}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_integrate_segment_2.verified b/test/test_fem/test_integrate_segment_2.verified
deleted file mode 100644
index 112b4645b..000000000
--- a/test/test_fem/test_integrate_segment_2.verified
+++ /dev/null
@@ -1,47 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 1
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 1
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 2
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 10
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}, {10, 1}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_integrate_segment_3.verified b/test/test_fem/test_integrate_segment_3.verified
deleted file mode 100644
index 75a64500a..000000000
--- a/test/test_fem/test_integrate_segment_3.verified
+++ /dev/null
@@ -1,47 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 1
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 1
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 2
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}}
- ]
- ]
- (not_ghost:_segment_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_3
- + size : 10
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{0, 2, 11}, {2, 3, 12}, {3, 4, 13}, {4, 5, 14}, {5, 6, 15}, {6, 7, 16}, {7, 8, 17}, {8, 9, 18}, {9, 10, 19}, {10, 1, 20}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_integrate_tetrahedron_10.verified b/test/test_fem/test_integrate_tetrahedron_10.verified
deleted file mode 100644
index 81c603ae6..000000000
--- a/test/test_fem/test_integrate_tetrahedron_10.verified
+++ /dev/null
@@ -1,67 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 3
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 3
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 8
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
- ]
- ]
- (not_ghost:_segment_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_3
- + size : 48
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{6, 8, 11}, {8, 9, 12}, {9, 10, 13}, {10, 7, 14}, {7, 15, 18}, {15, 16, 19}, {16, 17, 20}, {17, 3, 21}, {3, 22, 25}, {22, 23, 26}, {23, 24, 27}, {24, 2, 28}, {2, 29, 32}, {29, 30, 33}, {30, 31, 34}, {31, 6, 35}, {0, 36, 39}, {36, 37, 40}, {37, 38, 41}, {38, 4, 42}, {4, 43, 46}, {43, 44, 47}, {44, 45, 48}, {45, 5, 49}, {5, 50, 53}, {50, 51, 54}, {51, 52, 55}, {52, 1, 56}, {1, 57, 60}, {57, 58, 61}, {58, 59, 62}, {59, 0, 63}, {2, 64, 67}, {64, 65, 68}, {65, 66, 69}, {66, 0, 70}, {6, 71, 74}, {71, 72, 75}, {72, 73, 76}, {73, 4, 77}, {7, 78, 81}, {78, 79, 82}, {79, 80, 83}, {80, 5, 84}, {3, 85, 88}, {85, 86, 89}, {86, 87, 90}, {87, 1, 91}}
- ]
- ]
- (not_ghost:_triangle_6) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_6
- + size : 240
- + nb_component : 6
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{93, 97, 71, 105, 106, 107}, {93, 8, 98, 108, 109, 110}, {94, 78, 99, 111, 112, 113}, {43, 95, 100, 114, 115, 116}, {94, 98, 10, 117, 118, 119}, {73, 97, 95, 120, 121, 122}, {45, 100, 96, 123, 124, 125}, {80, 96, 99, 126, 127, 128}, {71, 97, 72, 106, 129, 75}, {78, 79, 99, 82, 130, 112}, {8, 9, 98, 12, 131, 109}, {43, 100, 44, 116, 132, 47}, {72, 97, 73, 129, 120, 76}, {9, 10, 98, 13, 118, 131}, {79, 80, 99, 83, 128, 130}, {44, 100, 45, 132, 123, 48}, {93, 92, 97, 133, 134, 105}, {93, 98, 92, 110, 135, 133}, {94, 92, 98, 136, 135, 117}, {92, 95, 97, 137, 121, 134}, {94, 99, 92, 113, 138, 136}, {92, 100, 95, 139, 115, 137}, {92, 99, 96, 138, 127, 140}, {92, 96, 100, 140, 124, 139}, {93, 71, 101, 107, 141, 142}, {93, 101, 8, 142, 143, 108}, {94, 102, 78, 144, 145, 111}, {43, 103, 95, 146, 147, 114}, {94, 10, 102, 119, 148, 144}, {73, 95, 103, 122, 147, 149}, {45, 96, 104, 125, 150, 151}, {80, 104, 96, 152, 150, 126}, {4, 73, 103, 77, 149, 153}, {6, 101, 71, 154, 141, 74}, {7, 102, 10, 155, 148, 14}, {7, 78, 102, 81, 145, 155}, {6, 8, 101, 11, 143, 154}, {5, 104, 80, 156, 152, 84}, {4, 103, 43, 153, 146, 46}, {5, 45, 104, 49, 151, 156}, {15, 162, 158, 170, 171, 172}, {22, 163, 159, 173, 174, 175}, {8, 164, 160, 176, 177, 178}, {29, 165, 161, 179, 180, 181}, {10, 158, 164, 182, 183, 184}, {31, 160, 165, 185, 186, 187}, {17, 159, 162, 188, 189, 190}, {24, 161, 163, 191, 192, 193}, {22, 23, 163, 26, 194, 173}, {15, 16, 162, 19, 195, 170}, {29, 30, 165, 33, 196, 179}, {8, 9, 164, 12, 197, 176}, {16, 17, 162, 20, 190, 195}, {23, 24, 163, 27, 193, 194}, {9, 10, 164, 13, 184, 197}, {30, 31, 165, 34, 187, 196}, {158, 162, 157, 171, 198, 199}, {159, 157, 162, 200, 198, 189}, {159, 163, 157, 174, 201, 200}, {161, 157, 163, 202, 201, 192}, {158, 157, 164, 199, 203, 183}, {160, 164, 157, 177, 203, 204}, {160, 157, 165, 204, 205, 186}, {161, 165, 157, 180, 205, 202}, {15, 158, 167, 172, 206, 207}, {22, 159, 166, 175, 208, 209}, {8, 160, 169, 178, 210, 211}, {29, 161, 168, 181, 212, 213}, {10, 167, 158, 214, 206, 182}, {31, 169, 160, 215, 210, 185}, {17, 166, 159, 216, 208, 188}, {24, 168, 161, 217, 212, 191}, {2, 168, 24, 218, 217, 28}, {3, 166, 17, 219, 216, 21}, {6, 169, 31, 220, 215, 35}, {7, 167, 10, 221, 214, 14}, {7, 15, 167, 18, 207, 221}, {3, 22, 166, 25, 209, 219}, {6, 8, 169, 11, 211, 220}, {2, 29, 168, 32, 213, 218}, {50, 227, 223, 235, 236, 237}, {57, 228, 224, 238, 239, 240}, {43, 229, 225, 241, 242, 243}, {36, 230, 226, 244, 245, 246}, {45, 223, 229, 247, 248, 249}, {38, 225, 230, 250, 251, 252}, {52, 224, 227, 253, 254, 255}, {59, 226, 228, 256, 257, 258}, {57, 58, 228, 61, 259, 238}, {50, 51, 227, 54, 260, 235}, {36, 37, 230, 40, 261, 244}, {43, 44, 229, 47, 262, 241}, {51, 52, 227, 55, 255, 260}, {58, 59, 228, 62, 258, 259}, {44, 45, 229, 48, 249, 262}, {37, 38, 230, 41, 252, 261}, {223, 227, 222, 236, 263, 264}, {224, 222, 227, 265, 263, 254}, {224, 228, 222, 239, 266, 265}, {222, 228, 226, 266, 257, 267}, {223, 222, 229, 264, 268, 248}, {222, 225, 229, 269, 242, 268}, {222, 230, 225, 270, 251, 269}, {222, 226, 230, 267, 245, 270}, {50, 223, 232, 237, 271, 272}, {57, 224, 231, 240, 273, 274}, {43, 225, 234, 243, 275, 276}, {36, 226, 233, 246, 277, 278}, {45, 232, 223, 279, 271, 247}, {38, 234, 225, 280, 275, 250}, {52, 231, 224, 281, 273, 253}, {59, 233, 226, 282, 277, 256}, {0, 233, 59, 283, 282, 63}, {1, 231, 52, 284, 281, 56}, {4, 234, 38, 285, 280, 42}, {5, 232, 45, 286, 279, 49}, {5, 50, 232, 53, 272, 286}, {1, 57, 231, 60, 274, 284}, {4, 43, 234, 46, 276, 285}, {0, 36, 233, 39, 278, 283}, {85, 288, 292, 300, 301, 302}, {22, 293, 288, 303, 304, 305}, {57, 290, 294, 306, 307, 308}, {64, 295, 289, 309, 310, 311}, {24, 289, 293, 312, 313, 314}, {87, 292, 290, 315, 316, 317}, {66, 291, 295, 318, 319, 320}, {59, 294, 291, 321, 322, 323}, {85, 292, 86, 302, 324, 89}, {22, 23, 293, 26, 325, 303}, {57, 294, 58, 308, 326, 61}, {64, 65, 295, 68, 327, 309}, {86, 292, 87, 324, 315, 90}, {23, 24, 293, 27, 314, 325}, {65, 66, 295, 69, 320, 327}, {58, 294, 59, 326, 321, 62}, {288, 293, 287, 304, 328, 329}, {288, 287, 292, 329, 330, 301}, {289, 287, 293, 331, 328, 313}, {290, 292, 287, 316, 330, 332}, {289, 295, 287, 310, 333, 331}, {290, 287, 294, 332, 334, 307}, {291, 294, 287, 322, 334, 335}, {291, 287, 295, 335, 333, 319}, {22, 288, 296, 305, 336, 337}, {85, 296, 288, 338, 336, 300}, {57, 298, 290, 339, 340, 306}, {64, 289, 297, 311, 341, 342}, {87, 290, 298, 317, 340, 343}, {24, 297, 289, 344, 341, 312}, {59, 291, 299, 323, 345, 346}, {66, 299, 291, 347, 345, 318}, {1, 87, 298, 91, 343, 348}, {2, 297, 24, 349, 344, 28}, {3, 296, 85, 350, 338, 88}, {3, 22, 296, 25, 337, 350}, {1, 298, 57, 348, 339, 60}, {2, 64, 297, 67, 342, 349}, {0, 59, 299, 63, 346, 351}, {0, 299, 66, 351, 347, 70}, {64, 353, 357, 365, 366, 367}, {29, 358, 353, 368, 369, 370}, {71, 359, 354, 371, 372, 373}, {36, 355, 360, 374, 375, 376}, {31, 354, 358, 377, 378, 379}, {66, 357, 355, 380, 381, 382}, {38, 360, 356, 383, 384, 385}, {73, 356, 359, 386, 387, 388}, {64, 357, 65, 367, 389, 68}, {71, 72, 359, 75, 390, 371}, {29, 30, 358, 33, 391, 368}, {36, 360, 37, 376, 392, 40}, {65, 357, 66, 389, 380, 69}, {30, 31, 358, 34, 379, 391}, {72, 73, 359, 76, 388, 390}, {37, 360, 38, 392, 383, 41}, {353, 352, 357, 393, 394, 366}, {353, 358, 352, 369, 395, 393}, {354, 352, 358, 396, 395, 378}, {355, 357, 352, 381, 394, 397}, {354, 359, 352, 372, 398, 396}, {355, 352, 360, 397, 399, 375}, {356, 352, 359, 400, 398, 387}, {356, 360, 352, 384, 399, 400}, {64, 361, 353, 401, 402, 365}, {29, 353, 361, 370, 402, 403}, {71, 354, 362, 373, 404, 405}, {36, 363, 355, 406, 407, 374}, {31, 362, 354, 408, 404, 377}, {66, 355, 363, 382, 407, 409}, {38, 356, 364, 385, 410, 411}, {73, 364, 356, 412, 410, 386}, {0, 66, 363, 70, 409, 413}, {2, 361, 64, 414, 401, 67}, {6, 362, 31, 415, 408, 35}, {6, 71, 362, 74, 405, 415}, {2, 29, 361, 32, 403, 414}, {4, 364, 73, 416, 412, 77}, {0, 363, 36, 413, 406, 39}, {4, 38, 364, 42, 411, 416}, {15, 418, 423, 430, 431, 432}, {78, 422, 418, 433, 434, 435}, {50, 424, 420, 436, 437, 438}, {85, 419, 425, 439, 440, 441}, {17, 423, 419, 442, 443, 444}, {80, 420, 422, 445, 446, 447}, {87, 425, 421, 448, 449, 450}, {52, 421, 424, 451, 452, 453}, {15, 423, 16, 432, 454, 19}, {78, 79, 422, 82, 455, 433}, {50, 51, 424, 54, 456, 436}, {85, 425, 86, 441, 457, 89}, {79, 80, 422, 83, 447, 455}, {16, 423, 17, 454, 442, 20}, {86, 425, 87, 457, 448, 90}, {51, 52, 424, 55, 453, 456}, {417, 418, 422, 458, 434, 459}, {417, 423, 418, 460, 431, 458}, {419, 423, 417, 443, 460, 461}, {420, 417, 422, 462, 459, 446}, {419, 417, 425, 461, 463, 440}, {420, 424, 417, 437, 464, 462}, {421, 417, 424, 465, 464, 452}, {421, 425, 417, 449, 463, 465}, {15, 426, 418, 466, 467, 430}, {78, 418, 426, 435, 467, 468}, {50, 420, 428, 438, 469, 470}, {85, 427, 419, 471, 472, 439}, {80, 428, 420, 473, 469, 445}, {17, 419, 427, 444, 472, 474}, {52, 429, 421, 475, 476, 451}, {87, 421, 429, 450, 476, 477}, {5, 428, 80, 478, 473, 84}, {3, 17, 427, 21, 474, 479}, {7, 78, 426, 81, 468, 480}, {7, 426, 15, 480, 466, 18}, {5, 50, 428, 53, 470, 478}, {3, 427, 85, 479, 471, 88}, {1, 429, 52, 481, 475, 56}, {1, 87, 429, 91, 477, 481}}
- ]
- ]
- (not_ghost:_tetrahedron_10) [
- Array<unsigned int> [
- + id : mesh:connectivities:_tetrahedron_10
- + size : 341
- + nb_component : 10
- + allocated size : 2000
- + memory size : 78.12KiByte
- + values : {{484, 483, 485, 489, 491, 493, 492, 496, 494, 495}, {87, 290, 490, 292, 317, 498, 497, 315, 316, 499}, {222, 484, 489, 486, 500, 496, 501, 504, 502, 503}, {96, 229, 45, 100, 505, 249, 125, 124, 506, 123}, {59, 0, 233, 299, 63, 283, 282, 346, 351, 507}, {0, 363, 233, 299, 413, 508, 283, 351, 509, 507}, {486, 295, 291, 357, 510, 319, 511, 514, 512, 513}, {484, 222, 489, 485, 500, 501, 496, 492, 515, 495}, {87, 429, 421, 490, 477, 476, 450, 497, 516, 517}, {103, 356, 234, 364, 518, 520, 519, 522, 410, 521}, {356, 103, 234, 225, 518, 519, 520, 524, 523, 275}, {43, 103, 225, 234, 146, 523, 243, 276, 519, 275}, {223, 227, 485, 420, 236, 526, 525, 529, 527, 528}, {483, 92, 484, 485, 530, 531, 491, 493, 532, 492}, {87, 421, 425, 490, 450, 449, 448, 497, 517, 533}, {298, 87, 290, 490, 343, 317, 340, 534, 497, 498}, {482, 483, 488, 489, 535, 537, 536, 539, 494, 538}, {94, 10, 158, 98, 119, 182, 540, 117, 118, 541}, {355, 363, 233, 36, 407, 508, 542, 374, 406, 278}, {485, 420, 424, 417, 528, 437, 543, 544, 462, 464}, {231, 224, 52, 490, 273, 253, 281, 547, 545, 546}, {483, 482, 485, 489, 535, 548, 493, 494, 539, 495}, {167, 15, 7, 426, 207, 18, 221, 549, 466, 480}, {483, 487, 488, 489, 550, 551, 537, 494, 552, 538}, {484, 92, 97, 95, 531, 134, 553, 554, 137, 121}, {29, 165, 30, 358, 179, 196, 33, 368, 555, 391}, {228, 294, 58, 59, 556, 326, 259, 258, 321, 62}, {102, 10, 7, 167, 148, 14, 155, 557, 214, 221}, {9, 10, 98, 164, 13, 118, 131, 197, 184, 558}, {78, 102, 7, 426, 145, 155, 81, 468, 559, 480}, {483, 484, 487, 489, 491, 560, 550, 494, 496, 552}, {16, 423, 162, 17, 454, 561, 195, 20, 442, 190}, {353, 161, 358, 487, 562, 563, 369, 566, 564, 565}, {93, 101, 8, 169, 142, 143, 108, 568, 567, 211}, {78, 422, 79, 99, 433, 455, 82, 112, 569, 130}, {485, 227, 489, 424, 526, 570, 495, 543, 571, 572}, {482, 92, 483, 485, 573, 530, 535, 548, 532, 493}, {223, 222, 229, 484, 264, 268, 248, 575, 500, 574}, {422, 420, 485, 417, 446, 528, 576, 459, 462, 544}, {64, 297, 353, 289, 342, 577, 365, 311, 341, 578}, {101, 6, 8, 169, 154, 11, 143, 567, 220, 211}, {425, 488, 489, 417, 579, 538, 580, 463, 581, 582}, {163, 161, 24, 293, 192, 191, 193, 584, 583, 314}, {228, 294, 59, 226, 556, 321, 258, 257, 585, 256}, {161, 289, 24, 293, 586, 312, 191, 583, 313, 314}, {165, 483, 160, 354, 587, 588, 186, 591, 589, 590}, {103, 356, 95, 225, 518, 592, 147, 523, 524, 593}, {356, 95, 359, 73, 592, 594, 387, 386, 122, 388}, {352, 483, 359, 484, 595, 596, 398, 598, 491, 597}, {103, 43, 4, 234, 146, 46, 153, 519, 276, 285}, {230, 356, 38, 225, 599, 385, 252, 251, 524, 250}, {161, 289, 293, 487, 586, 313, 583, 564, 600, 601}, {161, 487, 293, 163, 564, 601, 583, 192, 602, 584}, {429, 87, 298, 490, 477, 343, 603, 516, 497, 534}, {364, 38, 234, 4, 411, 280, 521, 416, 42, 285}, {22, 296, 3, 166, 337, 350, 25, 209, 604, 219}, {230, 37, 360, 36, 261, 392, 605, 244, 40, 376}, {356, 230, 360, 484, 599, 605, 384, 608, 606, 607}, {22, 23, 293, 163, 26, 325, 303, 173, 194, 584}, {294, 486, 291, 226, 609, 511, 322, 585, 610, 611}, {294, 228, 486, 226, 556, 612, 609, 585, 257, 610}, {3, 17, 166, 427, 21, 216, 219, 479, 474, 613}, {364, 103, 4, 234, 522, 153, 416, 521, 519, 285}, {158, 15, 418, 162, 172, 430, 614, 171, 170, 615}, {15, 423, 418, 162, 432, 431, 430, 170, 561, 615}, {157, 483, 160, 165, 616, 588, 204, 205, 587, 186}, {482, 158, 418, 162, 617, 614, 618, 619, 171, 615}, {423, 482, 418, 162, 620, 618, 431, 561, 619, 615}, {425, 488, 292, 489, 579, 622, 621, 580, 538, 623}, {290, 489, 490, 292, 624, 625, 498, 316, 623, 499}, {222, 223, 485, 484, 264, 525, 515, 500, 575, 492}, {363, 0, 66, 299, 413, 70, 409, 509, 351, 347}, {482, 422, 485, 417, 626, 576, 548, 627, 459, 544}, {486, 290, 287, 489, 628, 332, 629, 503, 624, 630}, {296, 3, 166, 427, 350, 219, 604, 631, 479, 613}, {489, 290, 287, 292, 624, 332, 630, 623, 316, 330}, {488, 85, 427, 419, 632, 471, 633, 634, 439, 472}, {425, 488, 419, 85, 579, 634, 440, 441, 632, 439}, {15, 16, 423, 162, 19, 454, 432, 170, 195, 561}, {65, 64, 357, 295, 68, 367, 389, 327, 309, 512}, {222, 484, 486, 226, 500, 502, 504, 267, 635, 610}, {356, 484, 95, 225, 608, 554, 592, 524, 636, 593}, {352, 484, 486, 487, 598, 502, 637, 639, 560, 638}, {230, 222, 484, 225, 270, 500, 606, 251, 269, 636}, {294, 228, 58, 57, 556, 259, 326, 308, 238, 61}, {352, 483, 484, 487, 595, 491, 598, 639, 550, 560}, {23, 163, 24, 293, 194, 193, 27, 325, 584, 314}, {429, 231, 1, 52, 640, 284, 481, 475, 281, 56}, {228, 222, 486, 226, 266, 504, 612, 257, 267, 610}, {482, 422, 417, 418, 626, 459, 627, 618, 434, 458}, {489, 425, 490, 292, 580, 533, 625, 623, 621, 499}, {483, 92, 97, 484, 530, 134, 641, 491, 531, 553}, {50, 232, 5, 428, 272, 286, 53, 470, 642, 478}, {483, 165, 358, 354, 587, 555, 643, 589, 591, 378}, {157, 483, 487, 488, 616, 550, 644, 645, 537, 551}, {425, 488, 417, 419, 579, 581, 463, 440, 634, 461}, {222, 230, 484, 226, 270, 606, 500, 267, 245, 635}, {299, 363, 233, 291, 509, 508, 507, 345, 646, 647}, {103, 356, 73, 95, 518, 386, 149, 147, 592, 122}, {229, 44, 45, 100, 262, 48, 249, 506, 132, 123}, {356, 230, 38, 360, 599, 252, 385, 384, 605, 383}, {104, 223, 45, 96, 648, 247, 151, 150, 649, 125}, {22, 159, 293, 288, 175, 650, 303, 305, 651, 304}, {352, 356, 360, 484, 400, 384, 399, 598, 608, 607}, {2, 361, 168, 29, 414, 652, 218, 32, 403, 213}, {484, 483, 359, 97, 491, 596, 597, 553, 641, 653}, {483, 157, 160, 164, 616, 204, 588, 654, 203, 177}, {92, 484, 100, 95, 531, 655, 139, 137, 554, 115}, {223, 420, 96, 104, 529, 656, 649, 648, 657, 150}, {85, 425, 292, 86, 441, 621, 302, 89, 457, 324}, {355, 352, 486, 357, 397, 637, 658, 381, 394, 514}, {353, 289, 487, 357, 578, 600, 566, 366, 659, 660}, {66, 295, 357, 291, 320, 512, 380, 318, 319, 513}, {488, 487, 287, 489, 551, 662, 661, 538, 552, 630}, {486, 294, 287, 290, 609, 334, 629, 628, 307, 332}, {227, 223, 485, 222, 236, 525, 526, 263, 264, 515}, {355, 486, 226, 291, 658, 610, 663, 664, 511, 611}, {43, 103, 95, 225, 146, 147, 114, 243, 523, 593}, {356, 230, 484, 225, 599, 606, 608, 524, 251, 636}, {64, 295, 289, 357, 309, 310, 311, 367, 512, 659}, {157, 482, 162, 158, 665, 619, 198, 199, 617, 171}, {223, 229, 45, 96, 248, 249, 247, 649, 505, 125}, {222, 229, 484, 225, 268, 574, 500, 269, 242, 636}, {422, 78, 418, 99, 433, 435, 434, 569, 112, 666}, {422, 80, 79, 99, 447, 83, 455, 569, 128, 130}, {159, 22, 293, 163, 175, 303, 650, 174, 173, 584}, {101, 362, 71, 6, 667, 405, 141, 154, 415, 74}, {93, 483, 354, 160, 668, 589, 669, 670, 588, 590}, {355, 486, 291, 357, 658, 511, 664, 381, 514, 513}, {362, 101, 169, 6, 667, 567, 671, 415, 154, 220}, {94, 482, 418, 99, 672, 618, 673, 113, 674, 666}, {488, 482, 489, 417, 536, 539, 538, 581, 627, 582}, {484, 356, 95, 359, 608, 592, 554, 597, 387, 594}, {363, 355, 233, 291, 407, 542, 508, 646, 664, 647}, {485, 92, 96, 99, 532, 140, 675, 676, 138, 127}, {78, 94, 418, 99, 111, 673, 435, 112, 113, 666}, {92, 483, 97, 93, 530, 641, 134, 133, 668, 105}, {484, 95, 97, 359, 554, 121, 553, 597, 594, 653}, {72, 71, 97, 359, 75, 106, 129, 390, 371, 653}, {94, 482, 99, 92, 672, 674, 113, 136, 573, 138}, {102, 167, 7, 426, 557, 221, 155, 559, 549, 480}, {10, 164, 158, 98, 184, 183, 182, 118, 558, 541}, {482, 422, 99, 485, 626, 569, 674, 548, 576, 676}, {15, 158, 426, 167, 172, 677, 466, 207, 206, 549}, {92, 482, 99, 485, 573, 674, 138, 532, 548, 676}, {158, 15, 426, 418, 172, 466, 677, 614, 430, 467}, {38, 356, 234, 225, 385, 520, 280, 250, 524, 275}, {94, 482, 158, 418, 672, 617, 540, 673, 618, 614}, {364, 356, 234, 38, 410, 520, 521, 411, 385, 280}, {93, 160, 8, 98, 670, 178, 108, 110, 678, 109}, {355, 233, 226, 36, 542, 277, 663, 374, 278, 246}, {160, 93, 8, 169, 670, 108, 178, 210, 568, 211}, {227, 223, 50, 420, 236, 237, 235, 527, 529, 438}, {363, 0, 233, 36, 413, 283, 508, 406, 39, 278}, {486, 295, 287, 291, 510, 333, 629, 511, 319, 335}, {59, 294, 291, 226, 321, 322, 323, 256, 585, 611}, {66, 363, 299, 291, 409, 509, 347, 318, 646, 345}, {486, 352, 487, 357, 637, 639, 638, 514, 394, 660}, {295, 486, 487, 357, 510, 638, 679, 512, 514, 660}, {296, 22, 288, 166, 337, 305, 336, 604, 209, 680}, {361, 64, 2, 297, 401, 67, 414, 681, 342, 349}, {95, 97, 359, 73, 121, 653, 594, 122, 120, 388}, {423, 482, 417, 418, 620, 627, 460, 431, 618, 458}, {65, 295, 357, 66, 327, 512, 389, 69, 320, 380}, {97, 72, 359, 73, 129, 390, 653, 120, 76, 388}, {420, 223, 96, 485, 529, 649, 656, 528, 525, 675}, {159, 488, 293, 288, 682, 683, 650, 651, 684, 304}, {31, 165, 160, 354, 187, 186, 185, 377, 591, 590}, {484, 486, 487, 489, 502, 638, 560, 496, 503, 552}, {486, 295, 487, 287, 510, 679, 638, 629, 333, 662}, {59, 233, 226, 291, 282, 277, 256, 323, 647, 611}, {233, 355, 226, 291, 542, 663, 277, 647, 664, 611}, {425, 421, 489, 490, 449, 685, 580, 533, 517, 625}, {288, 488, 292, 85, 684, 622, 301, 300, 632, 302}, {421, 425, 489, 417, 449, 580, 685, 465, 463, 582}, {294, 228, 57, 290, 556, 238, 308, 307, 686, 306}, {165, 31, 358, 354, 187, 379, 555, 591, 377, 378}, {103, 356, 364, 73, 518, 410, 522, 149, 386, 412}, {352, 483, 358, 354, 595, 643, 395, 396, 589, 378}, {22, 159, 288, 166, 175, 651, 305, 209, 208, 680}, {356, 352, 359, 484, 400, 398, 387, 608, 598, 597}, {64, 361, 353, 297, 401, 402, 365, 342, 681, 577}, {355, 66, 357, 291, 382, 380, 381, 664, 318, 513}, {487, 486, 287, 489, 638, 629, 662, 552, 503, 630}, {298, 57, 490, 290, 339, 687, 534, 340, 306, 498}, {31, 362, 169, 6, 408, 671, 215, 35, 415, 220}, {488, 425, 292, 85, 579, 621, 622, 632, 441, 302}, {483, 352, 359, 354, 595, 398, 596, 589, 396, 372}, {94, 78, 418, 426, 111, 435, 673, 688, 468, 467}, {229, 43, 44, 100, 241, 47, 262, 506, 116, 132}, {31, 165, 358, 30, 187, 555, 379, 34, 196, 391}, {429, 231, 52, 490, 640, 281, 475, 516, 547, 546}, {94, 102, 78, 426, 144, 145, 111, 688, 559, 468}, {421, 429, 52, 490, 476, 475, 451, 517, 516, 546}, {364, 103, 73, 4, 522, 149, 412, 416, 153, 77}, {420, 227, 424, 50, 527, 571, 437, 438, 235, 436}, {104, 80, 5, 428, 152, 84, 156, 689, 473, 478}, {227, 51, 52, 424, 260, 55, 255, 571, 456, 453}, {487, 289, 293, 287, 600, 313, 601, 662, 331, 328}, {166, 159, 288, 488, 208, 651, 680, 690, 682, 684}, {289, 161, 353, 487, 586, 562, 578, 600, 564, 566}, {482, 485, 489, 417, 548, 495, 539, 627, 544, 582}, {50, 227, 424, 51, 235, 571, 436, 54, 260, 456}, {488, 489, 287, 292, 538, 630, 661, 622, 623, 330}, {482, 483, 157, 488, 535, 616, 665, 536, 537, 645}, {80, 420, 104, 96, 445, 657, 152, 126, 656, 150}, {232, 104, 45, 5, 691, 151, 279, 286, 156, 49}, {288, 488, 287, 292, 684, 661, 329, 301, 622, 330}, {295, 289, 487, 287, 310, 600, 679, 333, 331, 662}, {157, 161, 163, 487, 202, 192, 201, 644, 564, 602}, {483, 482, 164, 98, 535, 692, 654, 694, 693, 558}, {3, 296, 85, 427, 350, 338, 88, 479, 631, 471}, {92, 483, 93, 98, 530, 668, 133, 135, 694, 110}, {95, 484, 100, 225, 554, 655, 115, 593, 636, 695}, {231, 224, 490, 57, 273, 545, 547, 274, 240, 687}, {64, 289, 353, 357, 311, 578, 365, 367, 659, 366}, {2, 297, 24, 168, 349, 344, 28, 218, 696, 217}, {361, 297, 168, 353, 681, 696, 652, 402, 577, 697}, {353, 161, 168, 29, 562, 212, 697, 370, 181, 213}, {289, 295, 487, 357, 310, 679, 600, 659, 512, 660}, {352, 353, 487, 357, 393, 566, 639, 394, 366, 660}, {361, 353, 168, 29, 402, 697, 652, 403, 370, 213}, {484, 229, 100, 225, 574, 506, 655, 636, 242, 695}, {104, 223, 232, 45, 648, 271, 691, 151, 247, 279}, {160, 164, 8, 98, 177, 176, 178, 678, 558, 109}, {164, 9, 8, 98, 197, 12, 176, 558, 131, 109}, {165, 161, 358, 29, 180, 563, 555, 179, 181, 368}, {297, 361, 168, 2, 681, 652, 696, 349, 414, 218}, {161, 353, 358, 29, 562, 369, 563, 181, 370, 368}, {230, 37, 38, 360, 261, 41, 252, 605, 392, 383}, {43, 95, 100, 225, 114, 115, 116, 243, 593, 695}, {420, 80, 104, 428, 445, 152, 657, 469, 473, 689}, {232, 104, 5, 428, 691, 156, 286, 642, 689, 478}, {59, 299, 233, 291, 346, 507, 282, 323, 345, 647}, {355, 363, 66, 291, 407, 409, 382, 664, 646, 318}, {158, 94, 418, 426, 540, 673, 614, 677, 688, 467}, {87, 429, 298, 1, 477, 603, 343, 91, 481, 348}, {420, 227, 485, 424, 527, 526, 528, 437, 571, 543}, {482, 422, 418, 99, 626, 434, 618, 674, 569, 666}, {229, 43, 100, 225, 241, 116, 506, 242, 243, 695}, {294, 486, 287, 291, 609, 629, 334, 322, 511, 335}, {17, 166, 419, 159, 216, 698, 444, 188, 208, 699}, {419, 166, 17, 427, 698, 216, 444, 472, 613, 474}, {166, 488, 419, 159, 690, 634, 698, 208, 682, 699}, {419, 488, 166, 427, 634, 690, 698, 472, 633, 613}, {160, 98, 483, 164, 678, 694, 588, 177, 558, 654}, {483, 98, 160, 93, 694, 678, 588, 668, 110, 670}, {226, 360, 486, 355, 700, 701, 610, 663, 375, 658}, {360, 36, 226, 230, 376, 246, 700, 605, 244, 245}, {226, 36, 360, 355, 246, 376, 700, 663, 374, 375}, {93, 169, 362, 101, 568, 671, 702, 142, 567, 667}, {93, 362, 71, 101, 702, 405, 107, 142, 667, 141}, {71, 362, 93, 354, 405, 702, 107, 373, 404, 669}, {489, 424, 417, 485, 572, 464, 582, 495, 543, 544}, {417, 424, 489, 421, 464, 572, 582, 465, 452, 685}, {102, 10, 158, 94, 148, 182, 703, 144, 119, 540}, {158, 10, 102, 167, 182, 148, 703, 206, 214, 557}, {102, 158, 426, 94, 703, 677, 559, 144, 540, 688}, {426, 158, 102, 167, 677, 703, 559, 549, 206, 557}, {421, 489, 227, 424, 685, 570, 704, 452, 572, 571}, {52, 421, 227, 424, 451, 704, 255, 453, 452, 571}, {489, 227, 222, 224, 570, 263, 501, 705, 254, 265}, {489, 222, 227, 485, 501, 263, 570, 495, 515, 526}, {87, 425, 292, 490, 448, 621, 315, 497, 533, 499}, {292, 425, 87, 86, 621, 448, 315, 324, 457, 90}, {104, 420, 232, 223, 657, 706, 691, 648, 529, 271}, {104, 232, 420, 428, 691, 706, 657, 689, 642, 469}, {232, 420, 50, 223, 706, 438, 272, 271, 529, 237}, {232, 50, 420, 428, 272, 438, 706, 642, 470, 469}, {226, 484, 360, 230, 635, 607, 700, 245, 606, 605}, {226, 360, 484, 486, 700, 607, 635, 610, 701, 502}, {486, 360, 352, 355, 701, 399, 637, 658, 375, 397}, {352, 360, 486, 484, 399, 701, 637, 598, 607, 502}, {162, 488, 157, 159, 707, 645, 198, 189, 682, 200}, {157, 488, 162, 482, 645, 707, 198, 665, 536, 619}, {490, 57, 429, 231, 687, 708, 516, 547, 274, 640}, {429, 57, 490, 298, 708, 687, 516, 603, 339, 534}, {57, 1, 429, 231, 60, 481, 708, 274, 284, 640}, {429, 1, 57, 298, 481, 60, 708, 603, 348, 339}, {158, 98, 482, 94, 541, 693, 617, 540, 117, 672}, {482, 98, 158, 164, 693, 541, 617, 692, 558, 183}, {353, 297, 161, 289, 577, 709, 562, 578, 341, 586}, {353, 161, 297, 168, 562, 709, 577, 697, 212, 696}, {161, 297, 24, 289, 709, 344, 191, 586, 341, 312}, {161, 24, 297, 168, 191, 344, 709, 212, 217, 696}, {159, 293, 487, 163, 650, 601, 710, 174, 584, 602}, {487, 293, 159, 488, 601, 650, 710, 551, 683, 682}, {159, 487, 157, 163, 710, 644, 200, 174, 602, 201}, {157, 487, 159, 488, 644, 710, 200, 645, 551, 682}, {290, 228, 486, 294, 686, 612, 628, 307, 556, 609}, {290, 486, 228, 489, 628, 612, 686, 624, 503, 711}, {485, 99, 420, 422, 676, 712, 528, 576, 569, 446}, {420, 99, 485, 96, 712, 676, 528, 656, 127, 675}, {99, 80, 420, 422, 128, 445, 712, 569, 447, 446}, {420, 80, 99, 96, 445, 128, 712, 656, 126, 127}, {96, 484, 229, 100, 713, 574, 505, 124, 655, 506}, {92, 96, 484, 485, 140, 713, 531, 532, 675, 492}, {92, 484, 96, 100, 531, 713, 140, 139, 655, 124}, {161, 358, 483, 165, 563, 643, 714, 180, 555, 587}, {483, 358, 161, 487, 643, 563, 714, 550, 565, 564}, {161, 483, 157, 165, 714, 616, 202, 180, 587, 205}, {157, 483, 161, 487, 616, 714, 202, 644, 550, 564}, {362, 31, 160, 354, 408, 185, 715, 404, 377, 590}, {160, 31, 362, 169, 185, 408, 715, 210, 215, 671}, {362, 160, 93, 354, 715, 670, 702, 404, 590, 669}, {93, 160, 362, 169, 670, 715, 702, 568, 210, 671}, {482, 164, 157, 483, 692, 203, 665, 535, 654, 616}, {157, 164, 482, 158, 203, 692, 665, 199, 183, 617}, {228, 489, 222, 224, 711, 501, 266, 239, 705, 265}, {222, 489, 228, 486, 501, 711, 266, 504, 503, 612}, {288, 166, 427, 296, 680, 613, 716, 336, 604, 631}, {288, 427, 166, 488, 716, 613, 680, 684, 633, 690}, {85, 288, 427, 296, 300, 716, 471, 338, 336, 631}, {85, 427, 288, 488, 471, 716, 300, 632, 633, 684}, {484, 223, 96, 229, 575, 649, 713, 574, 248, 505}, {484, 96, 223, 485, 713, 649, 575, 492, 675, 525}, {488, 293, 287, 487, 683, 328, 661, 551, 601, 662}, {287, 293, 488, 288, 328, 683, 661, 329, 304, 684}, {419, 488, 162, 159, 634, 707, 717, 699, 682, 189}, {162, 419, 17, 423, 717, 444, 190, 561, 443, 442}, {17, 419, 162, 159, 444, 717, 190, 188, 699, 189}, {482, 98, 92, 94, 693, 135, 573, 672, 117, 136}, {92, 98, 482, 483, 135, 693, 573, 530, 694, 535}, {358, 487, 352, 353, 565, 639, 395, 369, 566, 393}, {352, 487, 358, 483, 639, 565, 395, 595, 550, 643}, {359, 483, 93, 97, 596, 668, 718, 653, 641, 105}, {359, 93, 483, 354, 718, 668, 596, 372, 669, 589}, {71, 359, 93, 97, 371, 718, 107, 106, 653, 105}, {71, 93, 359, 354, 107, 718, 371, 373, 669, 372}, {52, 490, 227, 421, 546, 719, 255, 451, 517, 704}, {227, 490, 52, 224, 719, 546, 255, 254, 545, 253}, {490, 489, 227, 421, 625, 570, 719, 517, 685, 704}, {227, 489, 490, 224, 570, 625, 719, 254, 705, 545}, {57, 490, 228, 224, 687, 720, 238, 240, 545, 239}, {228, 490, 57, 290, 720, 687, 238, 686, 498, 306}, {490, 489, 228, 224, 625, 711, 720, 545, 705, 239}, {228, 489, 490, 290, 711, 625, 720, 686, 624, 498}, {162, 419, 482, 488, 717, 721, 619, 707, 634, 536}, {482, 419, 162, 423, 721, 717, 619, 620, 443, 561}, {419, 417, 482, 488, 461, 627, 721, 634, 581, 536}, {482, 417, 419, 423, 627, 461, 721, 620, 460, 443}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_integrate_tetrahedron_4.verified b/test/test_fem/test_integrate_tetrahedron_4.verified
deleted file mode 100644
index 02a936b1b..000000000
--- a/test/test_fem/test_integrate_tetrahedron_4.verified
+++ /dev/null
@@ -1,67 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 3
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 3
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 8
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 48
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{6, 8}, {8, 9}, {9, 10}, {10, 7}, {7, 11}, {11, 12}, {12, 13}, {13, 3}, {3, 14}, {14, 15}, {15, 16}, {16, 2}, {2, 17}, {17, 18}, {18, 19}, {19, 6}, {0, 20}, {20, 21}, {21, 22}, {22, 4}, {4, 23}, {23, 24}, {24, 25}, {25, 5}, {5, 26}, {26, 27}, {27, 28}, {28, 1}, {1, 29}, {29, 30}, {30, 31}, {31, 0}, {2, 32}, {32, 33}, {33, 34}, {34, 0}, {6, 35}, {35, 36}, {36, 37}, {37, 4}, {7, 38}, {38, 39}, {39, 40}, {40, 5}, {3, 41}, {41, 42}, {42, 43}, {43, 1}}
- ]
- ]
- (not_ghost:_triangle_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_3
- + size : 240
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{45, 49, 35}, {45, 8, 50}, {46, 38, 51}, {23, 47, 52}, {46, 50, 10}, {37, 49, 47}, {25, 52, 48}, {40, 48, 51}, {35, 49, 36}, {38, 39, 51}, {8, 9, 50}, {23, 52, 24}, {36, 49, 37}, {9, 10, 50}, {39, 40, 51}, {24, 52, 25}, {45, 44, 49}, {45, 50, 44}, {46, 44, 50}, {44, 47, 49}, {46, 51, 44}, {44, 52, 47}, {44, 51, 48}, {44, 48, 52}, {45, 35, 53}, {45, 53, 8}, {46, 54, 38}, {23, 55, 47}, {46, 10, 54}, {37, 47, 55}, {25, 48, 56}, {40, 56, 48}, {4, 37, 55}, {6, 53, 35}, {7, 54, 10}, {7, 38, 54}, {6, 8, 53}, {5, 56, 40}, {4, 55, 23}, {5, 25, 56}, {11, 62, 58}, {14, 63, 59}, {8, 64, 60}, {17, 65, 61}, {10, 58, 64}, {19, 60, 65}, {13, 59, 62}, {16, 61, 63}, {14, 15, 63}, {11, 12, 62}, {17, 18, 65}, {8, 9, 64}, {12, 13, 62}, {15, 16, 63}, {9, 10, 64}, {18, 19, 65}, {58, 62, 57}, {59, 57, 62}, {59, 63, 57}, {61, 57, 63}, {58, 57, 64}, {60, 64, 57}, {60, 57, 65}, {61, 65, 57}, {11, 58, 67}, {14, 59, 66}, {8, 60, 69}, {17, 61, 68}, {10, 67, 58}, {19, 69, 60}, {13, 66, 59}, {16, 68, 61}, {2, 68, 16}, {3, 66, 13}, {6, 69, 19}, {7, 67, 10}, {7, 11, 67}, {3, 14, 66}, {6, 8, 69}, {2, 17, 68}, {26, 75, 71}, {29, 76, 72}, {23, 77, 73}, {20, 78, 74}, {25, 71, 77}, {22, 73, 78}, {28, 72, 75}, {31, 74, 76}, {29, 30, 76}, {26, 27, 75}, {20, 21, 78}, {23, 24, 77}, {27, 28, 75}, {30, 31, 76}, {24, 25, 77}, {21, 22, 78}, {71, 75, 70}, {72, 70, 75}, {72, 76, 70}, {70, 76, 74}, {71, 70, 77}, {70, 73, 77}, {70, 78, 73}, {70, 74, 78}, {26, 71, 80}, {29, 72, 79}, {23, 73, 82}, {20, 74, 81}, {25, 80, 71}, {22, 82, 73}, {28, 79, 72}, {31, 81, 74}, {0, 81, 31}, {1, 79, 28}, {4, 82, 22}, {5, 80, 25}, {5, 26, 80}, {1, 29, 79}, {4, 23, 82}, {0, 20, 81}, {41, 84, 88}, {14, 89, 84}, {29, 86, 90}, {32, 91, 85}, {16, 85, 89}, {43, 88, 86}, {34, 87, 91}, {31, 90, 87}, {41, 88, 42}, {14, 15, 89}, {29, 90, 30}, {32, 33, 91}, {42, 88, 43}, {15, 16, 89}, {33, 34, 91}, {30, 90, 31}, {84, 89, 83}, {84, 83, 88}, {85, 83, 89}, {86, 88, 83}, {85, 91, 83}, {86, 83, 90}, {87, 90, 83}, {87, 83, 91}, {14, 84, 92}, {41, 92, 84}, {29, 94, 86}, {32, 85, 93}, {43, 86, 94}, {16, 93, 85}, {31, 87, 95}, {34, 95, 87}, {1, 43, 94}, {2, 93, 16}, {3, 92, 41}, {3, 14, 92}, {1, 94, 29}, {2, 32, 93}, {0, 31, 95}, {0, 95, 34}, {32, 97, 101}, {17, 102, 97}, {35, 103, 98}, {20, 99, 104}, {19, 98, 102}, {34, 101, 99}, {22, 104, 100}, {37, 100, 103}, {32, 101, 33}, {35, 36, 103}, {17, 18, 102}, {20, 104, 21}, {33, 101, 34}, {18, 19, 102}, {36, 37, 103}, {21, 104, 22}, {97, 96, 101}, {97, 102, 96}, {98, 96, 102}, {99, 101, 96}, {98, 103, 96}, {99, 96, 104}, {100, 96, 103}, {100, 104, 96}, {32, 105, 97}, {17, 97, 105}, {35, 98, 106}, {20, 107, 99}, {19, 106, 98}, {34, 99, 107}, {22, 100, 108}, {37, 108, 100}, {0, 34, 107}, {2, 105, 32}, {6, 106, 19}, {6, 35, 106}, {2, 17, 105}, {4, 108, 37}, {0, 107, 20}, {4, 22, 108}, {11, 110, 115}, {38, 114, 110}, {26, 116, 112}, {41, 111, 117}, {13, 115, 111}, {40, 112, 114}, {43, 117, 113}, {28, 113, 116}, {11, 115, 12}, {38, 39, 114}, {26, 27, 116}, {41, 117, 42}, {39, 40, 114}, {12, 115, 13}, {42, 117, 43}, {27, 28, 116}, {109, 110, 114}, {109, 115, 110}, {111, 115, 109}, {112, 109, 114}, {111, 109, 117}, {112, 116, 109}, {113, 109, 116}, {113, 117, 109}, {11, 118, 110}, {38, 110, 118}, {26, 112, 120}, {41, 119, 111}, {40, 120, 112}, {13, 111, 119}, {28, 121, 113}, {43, 113, 121}, {5, 120, 40}, {3, 13, 119}, {7, 38, 118}, {7, 118, 11}, {5, 26, 120}, {3, 119, 41}, {1, 121, 28}, {1, 43, 121}}
- ]
- ]
- (not_ghost:_tetrahedron_4) [
- Array<unsigned int> [
- + id : mesh:connectivities:_tetrahedron_4
- + size : 341
- + nb_component : 4
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{124, 123, 125, 129}, {43, 86, 130, 88}, {70, 124, 129, 126}, {48, 77, 25, 52}, {31, 0, 81, 95}, {0, 107, 81, 95}, {126, 91, 87, 101}, {124, 70, 129, 125}, {43, 121, 113, 130}, {55, 100, 82, 108}, {100, 55, 82, 73}, {23, 55, 73, 82}, {71, 75, 125, 112}, {123, 44, 124, 125}, {43, 113, 117, 130}, {94, 43, 86, 130}, {122, 123, 128, 129}, {46, 10, 58, 50}, {99, 107, 81, 20}, {125, 112, 116, 109}, {79, 72, 28, 130}, {123, 122, 125, 129}, {67, 11, 7, 118}, {123, 127, 128, 129}, {124, 44, 49, 47}, {17, 65, 18, 102}, {76, 90, 30, 31}, {54, 10, 7, 67}, {9, 10, 50, 64}, {38, 54, 7, 118}, {123, 124, 127, 129}, {12, 115, 62, 13}, {97, 61, 102, 127}, {45, 53, 8, 69}, {38, 114, 39, 51}, {125, 75, 129, 116}, {122, 44, 123, 125}, {71, 70, 77, 124}, {114, 112, 125, 109}, {32, 93, 97, 85}, {53, 6, 8, 69}, {117, 128, 129, 109}, {63, 61, 16, 89}, {76, 90, 31, 74}, {61, 85, 16, 89}, {65, 123, 60, 98}, {55, 100, 47, 73}, {100, 47, 103, 37}, {96, 123, 103, 124}, {55, 23, 4, 82}, {78, 100, 22, 73}, {61, 85, 89, 127}, {61, 127, 89, 63}, {121, 43, 94, 130}, {108, 22, 82, 4}, {14, 92, 3, 66}, {78, 21, 104, 20}, {100, 78, 104, 124}, {14, 15, 89, 63}, {90, 126, 87, 74}, {90, 76, 126, 74}, {3, 13, 66, 119}, {108, 55, 4, 82}, {58, 11, 110, 62}, {11, 115, 110, 62}, {57, 123, 60, 65}, {122, 58, 110, 62}, {115, 122, 110, 62}, {117, 128, 88, 129}, {86, 129, 130, 88}, {70, 71, 125, 124}, {107, 0, 34, 95}, {122, 114, 125, 109}, {126, 86, 83, 129}, {92, 3, 66, 119}, {129, 86, 83, 88}, {128, 41, 119, 111}, {117, 128, 111, 41}, {11, 12, 115, 62}, {33, 32, 101, 91}, {70, 124, 126, 74}, {100, 124, 47, 73}, {96, 124, 126, 127}, {78, 70, 124, 73}, {90, 76, 30, 29}, {96, 123, 124, 127}, {15, 63, 16, 89}, {121, 79, 1, 28}, {76, 70, 126, 74}, {122, 114, 109, 110}, {129, 117, 130, 88}, {123, 44, 49, 124}, {26, 80, 5, 120}, {123, 65, 102, 98}, {57, 123, 127, 128}, {117, 128, 109, 111}, {70, 78, 124, 74}, {95, 107, 81, 87}, {55, 100, 37, 47}, {77, 24, 25, 52}, {100, 78, 22, 104}, {56, 71, 25, 48}, {14, 59, 89, 84}, {96, 100, 104, 124}, {2, 105, 68, 17}, {124, 123, 103, 49}, {123, 57, 60, 64}, {44, 124, 52, 47}, {71, 112, 48, 56}, {41, 117, 88, 42}, {99, 96, 126, 101}, {97, 85, 127, 101}, {34, 91, 101, 87}, {128, 127, 83, 129}, {126, 90, 83, 86}, {75, 71, 125, 70}, {99, 126, 74, 87}, {23, 55, 47, 73}, {100, 78, 124, 73}, {32, 91, 85, 101}, {57, 122, 62, 58}, {71, 77, 25, 48}, {70, 77, 124, 73}, {114, 38, 110, 51}, {114, 40, 39, 51}, {59, 14, 89, 63}, {53, 106, 35, 6}, {45, 123, 98, 60}, {99, 126, 87, 101}, {106, 53, 69, 6}, {46, 122, 110, 51}, {128, 122, 129, 109}, {124, 100, 47, 103}, {107, 99, 81, 87}, {125, 44, 48, 51}, {38, 46, 110, 51}, {44, 123, 49, 45}, {124, 47, 49, 103}, {36, 35, 49, 103}, {46, 122, 51, 44}, {54, 67, 7, 118}, {10, 64, 58, 50}, {122, 114, 51, 125}, {11, 58, 118, 67}, {44, 122, 51, 125}, {58, 11, 118, 110}, {22, 100, 82, 73}, {46, 122, 58, 110}, {108, 100, 82, 22}, {45, 60, 8, 50}, {99, 81, 74, 20}, {60, 45, 8, 69}, {75, 71, 26, 112}, {107, 0, 81, 20}, {126, 91, 83, 87}, {31, 90, 87, 74}, {34, 107, 95, 87}, {126, 96, 127, 101}, {91, 126, 127, 101}, {92, 14, 84, 66}, {105, 32, 2, 93}, {47, 49, 103, 37}, {115, 122, 109, 110}, {33, 91, 101, 34}, {49, 36, 103, 37}, {112, 71, 48, 125}, {59, 128, 89, 84}, {19, 65, 60, 98}, {124, 126, 127, 129}, {126, 91, 127, 83}, {31, 81, 74, 87}, {81, 99, 74, 87}, {117, 113, 129, 130}, {84, 128, 88, 41}, {113, 117, 129, 109}, {90, 76, 29, 86}, {65, 19, 102, 98}, {55, 100, 108, 37}, {96, 123, 102, 98}, {14, 59, 84, 66}, {100, 96, 103, 124}, {32, 105, 97, 93}, {99, 34, 101, 87}, {127, 126, 83, 129}, {94, 29, 130, 86}, {19, 106, 69, 6}, {128, 117, 88, 41}, {123, 96, 103, 98}, {46, 38, 110, 118}, {77, 23, 24, 52}, {19, 65, 102, 18}, {121, 79, 28, 130}, {46, 54, 38, 118}, {113, 121, 28, 130}, {108, 55, 37, 4}, {112, 75, 116, 26}, {56, 40, 5, 120}, {75, 27, 28, 116}, {127, 85, 89, 83}, {66, 59, 84, 128}, {85, 61, 97, 127}, {122, 125, 129, 109}, {26, 75, 116, 27}, {128, 129, 83, 88}, {122, 123, 57, 128}, {40, 112, 56, 48}, {80, 56, 25, 5}, {84, 128, 83, 88}, {91, 85, 127, 83}, {57, 61, 63, 127}, {123, 122, 64, 50}, {3, 92, 41, 119}, {44, 123, 45, 50}, {47, 124, 52, 73}, {79, 72, 130, 29}, {32, 85, 97, 101}, {2, 93, 16, 68}, {105, 93, 68, 97}, {97, 61, 68, 17}, {85, 91, 127, 101}, {96, 97, 127, 101}, {105, 97, 68, 17}, {124, 77, 52, 73}, {56, 71, 80, 25}, {60, 64, 8, 50}, {64, 9, 8, 50}, {65, 61, 102, 17}, {93, 105, 68, 2}, {61, 97, 102, 17}, {78, 21, 22, 104}, {23, 47, 52, 73}, {112, 40, 56, 120}, {80, 56, 5, 120}, {31, 95, 81, 87}, {99, 107, 34, 87}, {58, 46, 110, 118}, {43, 121, 94, 1}, {112, 75, 125, 116}, {122, 114, 110, 51}, {77, 23, 52, 73}, {90, 126, 83, 87}, {13, 66, 111, 59}, {111, 66, 13, 119}, {66, 128, 111, 59}, {111, 128, 66, 119}, {60, 50, 123, 64}, {123, 50, 60, 45}, {74, 104, 126, 99}, {104, 20, 74, 78}, {74, 20, 104, 99}, {45, 69, 106, 53}, {45, 106, 35, 53}, {35, 106, 45, 98}, {129, 116, 109, 125}, {109, 116, 129, 113}, {54, 10, 58, 46}, {58, 10, 54, 67}, {54, 58, 118, 46}, {118, 58, 54, 67}, {113, 129, 75, 116}, {28, 113, 75, 116}, {129, 75, 70, 72}, {129, 70, 75, 125}, {43, 117, 88, 130}, {88, 117, 43, 42}, {56, 112, 80, 71}, {56, 80, 112, 120}, {80, 112, 26, 71}, {80, 26, 112, 120}, {74, 124, 104, 78}, {74, 104, 124, 126}, {126, 104, 96, 99}, {96, 104, 126, 124}, {62, 128, 57, 59}, {57, 128, 62, 122}, {130, 29, 121, 79}, {121, 29, 130, 94}, {29, 1, 121, 79}, {121, 1, 29, 94}, {58, 50, 122, 46}, {122, 50, 58, 64}, {97, 93, 61, 85}, {97, 61, 93, 68}, {61, 93, 16, 85}, {61, 16, 93, 68}, {59, 89, 127, 63}, {127, 89, 59, 128}, {59, 127, 57, 63}, {57, 127, 59, 128}, {86, 76, 126, 90}, {86, 126, 76, 129}, {125, 51, 112, 114}, {112, 51, 125, 48}, {51, 40, 112, 114}, {112, 40, 51, 48}, {48, 124, 77, 52}, {44, 48, 124, 125}, {44, 124, 48, 52}, {61, 102, 123, 65}, {123, 102, 61, 127}, {61, 123, 57, 65}, {57, 123, 61, 127}, {106, 19, 60, 98}, {60, 19, 106, 69}, {106, 60, 45, 98}, {45, 60, 106, 69}, {122, 64, 57, 123}, {57, 64, 122, 58}, {76, 129, 70, 72}, {70, 129, 76, 126}, {84, 66, 119, 92}, {84, 119, 66, 128}, {41, 84, 119, 92}, {41, 119, 84, 128}, {124, 71, 48, 77}, {124, 48, 71, 125}, {128, 89, 83, 127}, {83, 89, 128, 84}, {111, 128, 62, 59}, {62, 111, 13, 115}, {13, 111, 62, 59}, {122, 50, 44, 46}, {44, 50, 122, 123}, {102, 127, 96, 97}, {96, 127, 102, 123}, {103, 123, 45, 49}, {103, 45, 123, 98}, {35, 103, 45, 49}, {35, 45, 103, 98}, {28, 130, 75, 113}, {75, 130, 28, 72}, {130, 129, 75, 113}, {75, 129, 130, 72}, {29, 130, 76, 72}, {76, 130, 29, 86}, {130, 129, 76, 72}, {76, 129, 130, 86}, {62, 111, 122, 128}, {122, 111, 62, 115}, {111, 109, 122, 128}, {122, 109, 111, 115}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_integrate_triangle_3.verified b/test/test_fem/test_integrate_triangle_3.verified
deleted file mode 100644
index a74895613..000000000
--- a/test/test_fem/test_integrate_triangle_3.verified
+++ /dev/null
@@ -1,57 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 4
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 8
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0, 4}, {4, 1}, {1, 5}, {5, 2}, {2, 6}, {6, 3}, {3, 7}, {7, 0}}
- ]
- ]
- (not_ghost:_triangle_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_3
- + size : 16
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{3, 9, 6}, {0, 12, 7}, {2, 10, 5}, {1, 11, 4}, {7, 8, 9}, {6, 9, 8}, {6, 8, 10}, {7, 12, 8}, {5, 10, 8}, {4, 8, 12}, {4, 11, 8}, {5, 8, 11}, {0, 4, 12}, {3, 7, 9}, {1, 5, 11}, {2, 6, 10}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_integrate_triangle_6.verified b/test/test_fem/test_integrate_triangle_6.verified
deleted file mode 100644
index 93b1f37a8..000000000
--- a/test/test_fem/test_integrate_triangle_6.verified
+++ /dev/null
@@ -1,57 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 4
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}}
- ]
- ]
- (not_ghost:_segment_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_3
- + size : 8
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{0, 4, 5}, {4, 1, 6}, {1, 7, 8}, {7, 2, 9}, {2, 10, 11}, {10, 3, 12}, {3, 13, 14}, {13, 0, 15}}
- ]
- ]
- (not_ghost:_triangle_6) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_6
- + size : 16
- + nb_component : 6
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{3, 17, 10, 21, 22, 12}, {0, 20, 13, 23, 24, 15}, {2, 18, 7, 25, 26, 9}, {1, 19, 4, 27, 28, 6}, {13, 16, 17, 29, 30, 31}, {10, 17, 16, 22, 30, 32}, {10, 16, 18, 32, 33, 34}, {13, 20, 16, 24, 35, 29}, {7, 18, 16, 26, 33, 36}, {4, 16, 20, 37, 35, 38}, {4, 19, 16, 28, 39, 37}, {7, 16, 19, 36, 39, 40}, {0, 4, 20, 5, 38, 23}, {3, 13, 17, 14, 31, 21}, {1, 7, 19, 8, 40, 27}, {2, 10, 18, 11, 34, 25}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_interpolate.cc b/test/test_fem/test_interpolate.cc
deleted file mode 100644
index 91bccbe13..000000000
--- a/test/test_fem/test_interpolate.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * @file test_interpolate.cc
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- *
- * @date creation: Fri Jun 17 2011
- * @date last modification: Thu Jun 05 2014
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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 "mesh.hh"
-#include "mesh_io.hh"
-#include "mesh_io_msh.hh"
-#include "shape_lagrange.hh"
-#include "integrator_gauss.hh"
-/* -------------------------------------------------------------------------- */
-#include <cstdlib>
-#include <fstream>
-#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;
-
- MeshIOMSH mesh_io;
- Mesh my_mesh(dim);
-
- std::stringstream meshfilename; meshfilename << type << ".msh";
- mesh_io.read(meshfilename.str(), my_mesh);
-
- FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
-
- //UInt nb_quadrature_points = FEEngine::getNbQuadraturePoints(type);
- std::stringstream outfilename; outfilename << "out_" << type << ".txt";
- std::ofstream my_file(outfilename.str().c_str());
-
- fem->initShapeFunctions();
-
- std::cout << *fem << std::endl;
-
- 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;
-
- 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);
-
- my_file << const_val << std::endl;
- my_file << 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(),
- coord_on_quad,
- my_mesh.getSpatialDimension(),
- type);
- my_file << my_mesh.getNodes() << std::endl;
- my_file << coord_on_quad << std::endl;
-
- delete fem;
- finalize();
-
- return EXIT_SUCCESS;
-}
diff --git a/test/test_fem/test_interpolate_hexahedron_8.verified b/test/test_fem/test_interpolate_hexahedron_8.verified
deleted file mode 100644
index e57e20e56..000000000
--- a/test/test_fem/test_interpolate_hexahedron_8.verified
+++ /dev/null
@@ -1,67 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 3
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 3
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 8
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 48
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{6, 8}, {8, 9}, {9, 10}, {10, 7}, {7, 11}, {11, 12}, {12, 13}, {13, 3}, {3, 14}, {14, 15}, {15, 16}, {16, 2}, {2, 17}, {17, 18}, {18, 19}, {19, 6}, {0, 20}, {20, 21}, {21, 22}, {22, 4}, {4, 23}, {23, 24}, {24, 25}, {25, 5}, {5, 26}, {26, 27}, {27, 28}, {28, 1}, {1, 29}, {29, 30}, {30, 31}, {31, 0}, {2, 32}, {32, 33}, {33, 34}, {34, 0}, {6, 35}, {35, 36}, {36, 37}, {37, 4}, {7, 38}, {38, 39}, {39, 40}, {40, 5}, {3, 41}, {41, 42}, {42, 43}, {43, 1}}
- ]
- ]
- (not_ghost:_quadrangle_4) [
- Array<unsigned int> [
- + id : mesh:connectivities:_quadrangle_4
- + size : 96
- + nb_component : 4
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{6, 8, 44, 35}, {35, 44, 45, 36}, {36, 45, 46, 37}, {37, 46, 23, 4}, {8, 9, 47, 44}, {44, 47, 48, 45}, {45, 48, 49, 46}, {46, 49, 24, 23}, {9, 10, 50, 47}, {47, 50, 51, 48}, {48, 51, 52, 49}, {49, 52, 25, 24}, {10, 7, 38, 50}, {50, 38, 39, 51}, {51, 39, 40, 52}, {52, 40, 5, 25}, {3, 14, 53, 13}, {13, 53, 54, 12}, {12, 54, 55, 11}, {11, 55, 10, 7}, {14, 15, 56, 53}, {53, 56, 57, 54}, {54, 57, 58, 55}, {55, 58, 9, 10}, {15, 16, 59, 56}, {56, 59, 60, 57}, {57, 60, 61, 58}, {58, 61, 8, 9}, {16, 2, 17, 59}, {59, 17, 18, 60}, {60, 18, 19, 61}, {61, 19, 6, 8}, {4, 23, 62, 22}, {22, 62, 63, 21}, {21, 63, 64, 20}, {20, 64, 31, 0}, {23, 24, 65, 62}, {62, 65, 66, 63}, {63, 66, 67, 64}, {64, 67, 30, 31}, {24, 25, 68, 65}, {65, 68, 69, 66}, {66, 69, 70, 67}, {67, 70, 29, 30}, {25, 5, 26, 68}, {68, 26, 27, 69}, {69, 27, 28, 70}, {70, 28, 1, 29}, {3, 14, 71, 41}, {41, 71, 72, 42}, {42, 72, 73, 43}, {43, 73, 29, 1}, {14, 15, 74, 71}, {71, 74, 75, 72}, {72, 75, 76, 73}, {73, 76, 30, 29}, {15, 16, 77, 74}, {74, 77, 78, 75}, {75, 78, 79, 76}, {76, 79, 31, 30}, {16, 2, 32, 77}, {77, 32, 33, 78}, {78, 33, 34, 79}, {79, 34, 0, 31}, {2, 17, 80, 32}, {32, 80, 81, 33}, {33, 81, 82, 34}, {34, 82, 20, 0}, {17, 18, 83, 80}, {80, 83, 84, 81}, {81, 84, 85, 82}, {82, 85, 21, 20}, {18, 19, 86, 83}, {83, 86, 87, 84}, {84, 87, 88, 85}, {85, 88, 22, 21}, {19, 6, 35, 86}, {86, 35, 36, 87}, {87, 36, 37, 88}, {88, 37, 4, 22}, {7, 38, 89, 11}, {11, 89, 90, 12}, {12, 90, 91, 13}, {13, 91, 41, 3}, {38, 39, 92, 89}, {89, 92, 93, 90}, {90, 93, 94, 91}, {91, 94, 42, 41}, {39, 40, 95, 92}, {92, 95, 96, 93}, {93, 96, 97, 94}, {94, 97, 43, 42}, {40, 5, 26, 95}, {95, 26, 27, 96}, {96, 27, 28, 97}, {97, 28, 1, 43}}
- ]
- ]
- (not_ghost:_hexahedron_8) [
- Array<unsigned int> [
- + id : mesh:connectivities:_hexahedron_8
- + size : 64
- + nb_component : 8
- + allocated size : 2000
- + memory size : 62.50KiByte
- + values : {{89, 38, 7, 11, 98, 50, 10, 55}, {98, 50, 10, 55, 99, 47, 9, 58}, {99, 47, 9, 58, 100, 44, 8, 61}, {100, 44, 8, 61, 86, 35, 6, 19}, {90, 89, 11, 12, 101, 98, 55, 54}, {101, 98, 55, 54, 102, 99, 58, 57}, {102, 99, 58, 57, 103, 100, 61, 60}, {103, 100, 61, 60, 83, 86, 19, 18}, {91, 90, 12, 13, 104, 101, 54, 53}, {104, 101, 54, 53, 105, 102, 57, 56}, {105, 102, 57, 56, 106, 103, 60, 59}, {106, 103, 60, 59, 80, 83, 18, 17}, {41, 91, 13, 3, 71, 104, 53, 14}, {71, 104, 53, 14, 74, 105, 56, 15}, {74, 105, 56, 15, 77, 106, 59, 16}, {77, 106, 59, 16, 32, 80, 17, 2}, {92, 39, 38, 89, 107, 51, 50, 98}, {107, 51, 50, 98, 108, 48, 47, 99}, {108, 48, 47, 99, 109, 45, 44, 100}, {109, 45, 44, 100, 87, 36, 35, 86}, {93, 92, 89, 90, 110, 107, 98, 101}, {110, 107, 98, 101, 111, 108, 99, 102}, {111, 108, 99, 102, 112, 109, 100, 103}, {112, 109, 100, 103, 84, 87, 86, 83}, {94, 93, 90, 91, 113, 110, 101, 104}, {113, 110, 101, 104, 114, 111, 102, 105}, {114, 111, 102, 105, 115, 112, 103, 106}, {115, 112, 103, 106, 81, 84, 83, 80}, {42, 94, 91, 41, 72, 113, 104, 71}, {72, 113, 104, 71, 75, 114, 105, 74}, {75, 114, 105, 74, 78, 115, 106, 77}, {78, 115, 106, 77, 33, 81, 80, 32}, {95, 40, 39, 92, 116, 52, 51, 107}, {116, 52, 51, 107, 117, 49, 48, 108}, {117, 49, 48, 108, 118, 46, 45, 109}, {118, 46, 45, 109, 88, 37, 36, 87}, {96, 95, 92, 93, 119, 116, 107, 110}, {119, 116, 107, 110, 120, 117, 108, 111}, {120, 117, 108, 111, 121, 118, 109, 112}, {121, 118, 109, 112, 85, 88, 87, 84}, {97, 96, 93, 94, 122, 119, 110, 113}, {122, 119, 110, 113, 123, 120, 111, 114}, {123, 120, 111, 114, 124, 121, 112, 115}, {124, 121, 112, 115, 82, 85, 84, 81}, {43, 97, 94, 42, 73, 122, 113, 72}, {73, 122, 113, 72, 76, 123, 114, 75}, {76, 123, 114, 75, 79, 124, 115, 78}, {79, 124, 115, 78, 34, 82, 81, 33}, {26, 5, 40, 95, 68, 25, 52, 116}, {68, 25, 52, 116, 65, 24, 49, 117}, {65, 24, 49, 117, 62, 23, 46, 118}, {62, 23, 46, 118, 22, 4, 37, 88}, {27, 26, 95, 96, 69, 68, 116, 119}, {69, 68, 116, 119, 66, 65, 117, 120}, {66, 65, 117, 120, 63, 62, 118, 121}, {63, 62, 118, 121, 21, 22, 88, 85}, {28, 27, 96, 97, 70, 69, 119, 122}, {70, 69, 119, 122, 67, 66, 120, 123}, {67, 66, 120, 123, 64, 63, 121, 124}, {64, 63, 121, 124, 20, 21, 85, 82}, {1, 28, 97, 43, 29, 70, 122, 73}, {29, 70, 122, 73, 30, 67, 123, 76}, {30, 67, 123, 76, 31, 64, 124, 79}, {31, 64, 124, 79, 0, 20, 82, 34}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_interpolate_quadrangle_4.verified b/test/test_fem/test_interpolate_quadrangle_4.verified
deleted file mode 100644
index 4900a757d..000000000
--- a/test/test_fem/test_interpolate_quadrangle_4.verified
+++ /dev/null
@@ -1,57 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 4
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 8
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0, 4}, {4, 1}, {1, 5}, {5, 2}, {2, 6}, {6, 3}, {3, 7}, {7, 0}}
- ]
- ]
- (not_ghost:_quadrangle_4) [
- Array<unsigned int> [
- + id : mesh:connectivities:_quadrangle_4
- + size : 4
- + nb_component : 4
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{2, 6, 8, 5}, {5, 8, 4, 1}, {6, 3, 7, 8}, {8, 7, 0, 4}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_interpolate_quadrangle_8.verified b/test/test_fem/test_interpolate_quadrangle_8.verified
deleted file mode 100644
index 18df422b5..000000000
--- a/test/test_fem/test_interpolate_quadrangle_8.verified
+++ /dev/null
@@ -1,37 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_quadrangle_8) [
- Array<unsigned int> [
- + id : mesh:connectivities:_quadrangle_8
- + size : 4
- + nb_component : 8
- + allocated size : 2000
- + memory size : 62.50KiByte
- + values : {{2, 10, 16, 7, 11, 17, 18, 9}, {7, 16, 4, 1, 18, 19, 6, 8}, {10, 3, 13, 16, 12, 14, 20, 17}, {16, 13, 0, 4, 20, 15, 5, 19}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_interpolate_segment_2.verified b/test/test_fem/test_interpolate_segment_2.verified
deleted file mode 100644
index 112b4645b..000000000
--- a/test/test_fem/test_interpolate_segment_2.verified
+++ /dev/null
@@ -1,47 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 1
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 1
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 2
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 10
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}, {10, 1}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_interpolate_segment_3.verified b/test/test_fem/test_interpolate_segment_3.verified
deleted file mode 100644
index 75a64500a..000000000
--- a/test/test_fem/test_interpolate_segment_3.verified
+++ /dev/null
@@ -1,47 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 1
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 1
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 2
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}}
- ]
- ]
- (not_ghost:_segment_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_3
- + size : 10
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{0, 2, 11}, {2, 3, 12}, {3, 4, 13}, {4, 5, 14}, {5, 6, 15}, {6, 7, 16}, {7, 8, 17}, {8, 9, 18}, {9, 10, 19}, {10, 1, 20}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_interpolate_tetrahedron_10.verified b/test/test_fem/test_interpolate_tetrahedron_10.verified
deleted file mode 100644
index 81c603ae6..000000000
--- a/test/test_fem/test_interpolate_tetrahedron_10.verified
+++ /dev/null
@@ -1,67 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 3
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 3
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 8
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
- ]
- ]
- (not_ghost:_segment_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_3
- + size : 48
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{6, 8, 11}, {8, 9, 12}, {9, 10, 13}, {10, 7, 14}, {7, 15, 18}, {15, 16, 19}, {16, 17, 20}, {17, 3, 21}, {3, 22, 25}, {22, 23, 26}, {23, 24, 27}, {24, 2, 28}, {2, 29, 32}, {29, 30, 33}, {30, 31, 34}, {31, 6, 35}, {0, 36, 39}, {36, 37, 40}, {37, 38, 41}, {38, 4, 42}, {4, 43, 46}, {43, 44, 47}, {44, 45, 48}, {45, 5, 49}, {5, 50, 53}, {50, 51, 54}, {51, 52, 55}, {52, 1, 56}, {1, 57, 60}, {57, 58, 61}, {58, 59, 62}, {59, 0, 63}, {2, 64, 67}, {64, 65, 68}, {65, 66, 69}, {66, 0, 70}, {6, 71, 74}, {71, 72, 75}, {72, 73, 76}, {73, 4, 77}, {7, 78, 81}, {78, 79, 82}, {79, 80, 83}, {80, 5, 84}, {3, 85, 88}, {85, 86, 89}, {86, 87, 90}, {87, 1, 91}}
- ]
- ]
- (not_ghost:_triangle_6) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_6
- + size : 240
- + nb_component : 6
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{93, 97, 71, 105, 106, 107}, {93, 8, 98, 108, 109, 110}, {94, 78, 99, 111, 112, 113}, {43, 95, 100, 114, 115, 116}, {94, 98, 10, 117, 118, 119}, {73, 97, 95, 120, 121, 122}, {45, 100, 96, 123, 124, 125}, {80, 96, 99, 126, 127, 128}, {71, 97, 72, 106, 129, 75}, {78, 79, 99, 82, 130, 112}, {8, 9, 98, 12, 131, 109}, {43, 100, 44, 116, 132, 47}, {72, 97, 73, 129, 120, 76}, {9, 10, 98, 13, 118, 131}, {79, 80, 99, 83, 128, 130}, {44, 100, 45, 132, 123, 48}, {93, 92, 97, 133, 134, 105}, {93, 98, 92, 110, 135, 133}, {94, 92, 98, 136, 135, 117}, {92, 95, 97, 137, 121, 134}, {94, 99, 92, 113, 138, 136}, {92, 100, 95, 139, 115, 137}, {92, 99, 96, 138, 127, 140}, {92, 96, 100, 140, 124, 139}, {93, 71, 101, 107, 141, 142}, {93, 101, 8, 142, 143, 108}, {94, 102, 78, 144, 145, 111}, {43, 103, 95, 146, 147, 114}, {94, 10, 102, 119, 148, 144}, {73, 95, 103, 122, 147, 149}, {45, 96, 104, 125, 150, 151}, {80, 104, 96, 152, 150, 126}, {4, 73, 103, 77, 149, 153}, {6, 101, 71, 154, 141, 74}, {7, 102, 10, 155, 148, 14}, {7, 78, 102, 81, 145, 155}, {6, 8, 101, 11, 143, 154}, {5, 104, 80, 156, 152, 84}, {4, 103, 43, 153, 146, 46}, {5, 45, 104, 49, 151, 156}, {15, 162, 158, 170, 171, 172}, {22, 163, 159, 173, 174, 175}, {8, 164, 160, 176, 177, 178}, {29, 165, 161, 179, 180, 181}, {10, 158, 164, 182, 183, 184}, {31, 160, 165, 185, 186, 187}, {17, 159, 162, 188, 189, 190}, {24, 161, 163, 191, 192, 193}, {22, 23, 163, 26, 194, 173}, {15, 16, 162, 19, 195, 170}, {29, 30, 165, 33, 196, 179}, {8, 9, 164, 12, 197, 176}, {16, 17, 162, 20, 190, 195}, {23, 24, 163, 27, 193, 194}, {9, 10, 164, 13, 184, 197}, {30, 31, 165, 34, 187, 196}, {158, 162, 157, 171, 198, 199}, {159, 157, 162, 200, 198, 189}, {159, 163, 157, 174, 201, 200}, {161, 157, 163, 202, 201, 192}, {158, 157, 164, 199, 203, 183}, {160, 164, 157, 177, 203, 204}, {160, 157, 165, 204, 205, 186}, {161, 165, 157, 180, 205, 202}, {15, 158, 167, 172, 206, 207}, {22, 159, 166, 175, 208, 209}, {8, 160, 169, 178, 210, 211}, {29, 161, 168, 181, 212, 213}, {10, 167, 158, 214, 206, 182}, {31, 169, 160, 215, 210, 185}, {17, 166, 159, 216, 208, 188}, {24, 168, 161, 217, 212, 191}, {2, 168, 24, 218, 217, 28}, {3, 166, 17, 219, 216, 21}, {6, 169, 31, 220, 215, 35}, {7, 167, 10, 221, 214, 14}, {7, 15, 167, 18, 207, 221}, {3, 22, 166, 25, 209, 219}, {6, 8, 169, 11, 211, 220}, {2, 29, 168, 32, 213, 218}, {50, 227, 223, 235, 236, 237}, {57, 228, 224, 238, 239, 240}, {43, 229, 225, 241, 242, 243}, {36, 230, 226, 244, 245, 246}, {45, 223, 229, 247, 248, 249}, {38, 225, 230, 250, 251, 252}, {52, 224, 227, 253, 254, 255}, {59, 226, 228, 256, 257, 258}, {57, 58, 228, 61, 259, 238}, {50, 51, 227, 54, 260, 235}, {36, 37, 230, 40, 261, 244}, {43, 44, 229, 47, 262, 241}, {51, 52, 227, 55, 255, 260}, {58, 59, 228, 62, 258, 259}, {44, 45, 229, 48, 249, 262}, {37, 38, 230, 41, 252, 261}, {223, 227, 222, 236, 263, 264}, {224, 222, 227, 265, 263, 254}, {224, 228, 222, 239, 266, 265}, {222, 228, 226, 266, 257, 267}, {223, 222, 229, 264, 268, 248}, {222, 225, 229, 269, 242, 268}, {222, 230, 225, 270, 251, 269}, {222, 226, 230, 267, 245, 270}, {50, 223, 232, 237, 271, 272}, {57, 224, 231, 240, 273, 274}, {43, 225, 234, 243, 275, 276}, {36, 226, 233, 246, 277, 278}, {45, 232, 223, 279, 271, 247}, {38, 234, 225, 280, 275, 250}, {52, 231, 224, 281, 273, 253}, {59, 233, 226, 282, 277, 256}, {0, 233, 59, 283, 282, 63}, {1, 231, 52, 284, 281, 56}, {4, 234, 38, 285, 280, 42}, {5, 232, 45, 286, 279, 49}, {5, 50, 232, 53, 272, 286}, {1, 57, 231, 60, 274, 284}, {4, 43, 234, 46, 276, 285}, {0, 36, 233, 39, 278, 283}, {85, 288, 292, 300, 301, 302}, {22, 293, 288, 303, 304, 305}, {57, 290, 294, 306, 307, 308}, {64, 295, 289, 309, 310, 311}, {24, 289, 293, 312, 313, 314}, {87, 292, 290, 315, 316, 317}, {66, 291, 295, 318, 319, 320}, {59, 294, 291, 321, 322, 323}, {85, 292, 86, 302, 324, 89}, {22, 23, 293, 26, 325, 303}, {57, 294, 58, 308, 326, 61}, {64, 65, 295, 68, 327, 309}, {86, 292, 87, 324, 315, 90}, {23, 24, 293, 27, 314, 325}, {65, 66, 295, 69, 320, 327}, {58, 294, 59, 326, 321, 62}, {288, 293, 287, 304, 328, 329}, {288, 287, 292, 329, 330, 301}, {289, 287, 293, 331, 328, 313}, {290, 292, 287, 316, 330, 332}, {289, 295, 287, 310, 333, 331}, {290, 287, 294, 332, 334, 307}, {291, 294, 287, 322, 334, 335}, {291, 287, 295, 335, 333, 319}, {22, 288, 296, 305, 336, 337}, {85, 296, 288, 338, 336, 300}, {57, 298, 290, 339, 340, 306}, {64, 289, 297, 311, 341, 342}, {87, 290, 298, 317, 340, 343}, {24, 297, 289, 344, 341, 312}, {59, 291, 299, 323, 345, 346}, {66, 299, 291, 347, 345, 318}, {1, 87, 298, 91, 343, 348}, {2, 297, 24, 349, 344, 28}, {3, 296, 85, 350, 338, 88}, {3, 22, 296, 25, 337, 350}, {1, 298, 57, 348, 339, 60}, {2, 64, 297, 67, 342, 349}, {0, 59, 299, 63, 346, 351}, {0, 299, 66, 351, 347, 70}, {64, 353, 357, 365, 366, 367}, {29, 358, 353, 368, 369, 370}, {71, 359, 354, 371, 372, 373}, {36, 355, 360, 374, 375, 376}, {31, 354, 358, 377, 378, 379}, {66, 357, 355, 380, 381, 382}, {38, 360, 356, 383, 384, 385}, {73, 356, 359, 386, 387, 388}, {64, 357, 65, 367, 389, 68}, {71, 72, 359, 75, 390, 371}, {29, 30, 358, 33, 391, 368}, {36, 360, 37, 376, 392, 40}, {65, 357, 66, 389, 380, 69}, {30, 31, 358, 34, 379, 391}, {72, 73, 359, 76, 388, 390}, {37, 360, 38, 392, 383, 41}, {353, 352, 357, 393, 394, 366}, {353, 358, 352, 369, 395, 393}, {354, 352, 358, 396, 395, 378}, {355, 357, 352, 381, 394, 397}, {354, 359, 352, 372, 398, 396}, {355, 352, 360, 397, 399, 375}, {356, 352, 359, 400, 398, 387}, {356, 360, 352, 384, 399, 400}, {64, 361, 353, 401, 402, 365}, {29, 353, 361, 370, 402, 403}, {71, 354, 362, 373, 404, 405}, {36, 363, 355, 406, 407, 374}, {31, 362, 354, 408, 404, 377}, {66, 355, 363, 382, 407, 409}, {38, 356, 364, 385, 410, 411}, {73, 364, 356, 412, 410, 386}, {0, 66, 363, 70, 409, 413}, {2, 361, 64, 414, 401, 67}, {6, 362, 31, 415, 408, 35}, {6, 71, 362, 74, 405, 415}, {2, 29, 361, 32, 403, 414}, {4, 364, 73, 416, 412, 77}, {0, 363, 36, 413, 406, 39}, {4, 38, 364, 42, 411, 416}, {15, 418, 423, 430, 431, 432}, {78, 422, 418, 433, 434, 435}, {50, 424, 420, 436, 437, 438}, {85, 419, 425, 439, 440, 441}, {17, 423, 419, 442, 443, 444}, {80, 420, 422, 445, 446, 447}, {87, 425, 421, 448, 449, 450}, {52, 421, 424, 451, 452, 453}, {15, 423, 16, 432, 454, 19}, {78, 79, 422, 82, 455, 433}, {50, 51, 424, 54, 456, 436}, {85, 425, 86, 441, 457, 89}, {79, 80, 422, 83, 447, 455}, {16, 423, 17, 454, 442, 20}, {86, 425, 87, 457, 448, 90}, {51, 52, 424, 55, 453, 456}, {417, 418, 422, 458, 434, 459}, {417, 423, 418, 460, 431, 458}, {419, 423, 417, 443, 460, 461}, {420, 417, 422, 462, 459, 446}, {419, 417, 425, 461, 463, 440}, {420, 424, 417, 437, 464, 462}, {421, 417, 424, 465, 464, 452}, {421, 425, 417, 449, 463, 465}, {15, 426, 418, 466, 467, 430}, {78, 418, 426, 435, 467, 468}, {50, 420, 428, 438, 469, 470}, {85, 427, 419, 471, 472, 439}, {80, 428, 420, 473, 469, 445}, {17, 419, 427, 444, 472, 474}, {52, 429, 421, 475, 476, 451}, {87, 421, 429, 450, 476, 477}, {5, 428, 80, 478, 473, 84}, {3, 17, 427, 21, 474, 479}, {7, 78, 426, 81, 468, 480}, {7, 426, 15, 480, 466, 18}, {5, 50, 428, 53, 470, 478}, {3, 427, 85, 479, 471, 88}, {1, 429, 52, 481, 475, 56}, {1, 87, 429, 91, 477, 481}}
- ]
- ]
- (not_ghost:_tetrahedron_10) [
- Array<unsigned int> [
- + id : mesh:connectivities:_tetrahedron_10
- + size : 341
- + nb_component : 10
- + allocated size : 2000
- + memory size : 78.12KiByte
- + values : {{484, 483, 485, 489, 491, 493, 492, 496, 494, 495}, {87, 290, 490, 292, 317, 498, 497, 315, 316, 499}, {222, 484, 489, 486, 500, 496, 501, 504, 502, 503}, {96, 229, 45, 100, 505, 249, 125, 124, 506, 123}, {59, 0, 233, 299, 63, 283, 282, 346, 351, 507}, {0, 363, 233, 299, 413, 508, 283, 351, 509, 507}, {486, 295, 291, 357, 510, 319, 511, 514, 512, 513}, {484, 222, 489, 485, 500, 501, 496, 492, 515, 495}, {87, 429, 421, 490, 477, 476, 450, 497, 516, 517}, {103, 356, 234, 364, 518, 520, 519, 522, 410, 521}, {356, 103, 234, 225, 518, 519, 520, 524, 523, 275}, {43, 103, 225, 234, 146, 523, 243, 276, 519, 275}, {223, 227, 485, 420, 236, 526, 525, 529, 527, 528}, {483, 92, 484, 485, 530, 531, 491, 493, 532, 492}, {87, 421, 425, 490, 450, 449, 448, 497, 517, 533}, {298, 87, 290, 490, 343, 317, 340, 534, 497, 498}, {482, 483, 488, 489, 535, 537, 536, 539, 494, 538}, {94, 10, 158, 98, 119, 182, 540, 117, 118, 541}, {355, 363, 233, 36, 407, 508, 542, 374, 406, 278}, {485, 420, 424, 417, 528, 437, 543, 544, 462, 464}, {231, 224, 52, 490, 273, 253, 281, 547, 545, 546}, {483, 482, 485, 489, 535, 548, 493, 494, 539, 495}, {167, 15, 7, 426, 207, 18, 221, 549, 466, 480}, {483, 487, 488, 489, 550, 551, 537, 494, 552, 538}, {484, 92, 97, 95, 531, 134, 553, 554, 137, 121}, {29, 165, 30, 358, 179, 196, 33, 368, 555, 391}, {228, 294, 58, 59, 556, 326, 259, 258, 321, 62}, {102, 10, 7, 167, 148, 14, 155, 557, 214, 221}, {9, 10, 98, 164, 13, 118, 131, 197, 184, 558}, {78, 102, 7, 426, 145, 155, 81, 468, 559, 480}, {483, 484, 487, 489, 491, 560, 550, 494, 496, 552}, {16, 423, 162, 17, 454, 561, 195, 20, 442, 190}, {353, 161, 358, 487, 562, 563, 369, 566, 564, 565}, {93, 101, 8, 169, 142, 143, 108, 568, 567, 211}, {78, 422, 79, 99, 433, 455, 82, 112, 569, 130}, {485, 227, 489, 424, 526, 570, 495, 543, 571, 572}, {482, 92, 483, 485, 573, 530, 535, 548, 532, 493}, {223, 222, 229, 484, 264, 268, 248, 575, 500, 574}, {422, 420, 485, 417, 446, 528, 576, 459, 462, 544}, {64, 297, 353, 289, 342, 577, 365, 311, 341, 578}, {101, 6, 8, 169, 154, 11, 143, 567, 220, 211}, {425, 488, 489, 417, 579, 538, 580, 463, 581, 582}, {163, 161, 24, 293, 192, 191, 193, 584, 583, 314}, {228, 294, 59, 226, 556, 321, 258, 257, 585, 256}, {161, 289, 24, 293, 586, 312, 191, 583, 313, 314}, {165, 483, 160, 354, 587, 588, 186, 591, 589, 590}, {103, 356, 95, 225, 518, 592, 147, 523, 524, 593}, {356, 95, 359, 73, 592, 594, 387, 386, 122, 388}, {352, 483, 359, 484, 595, 596, 398, 598, 491, 597}, {103, 43, 4, 234, 146, 46, 153, 519, 276, 285}, {230, 356, 38, 225, 599, 385, 252, 251, 524, 250}, {161, 289, 293, 487, 586, 313, 583, 564, 600, 601}, {161, 487, 293, 163, 564, 601, 583, 192, 602, 584}, {429, 87, 298, 490, 477, 343, 603, 516, 497, 534}, {364, 38, 234, 4, 411, 280, 521, 416, 42, 285}, {22, 296, 3, 166, 337, 350, 25, 209, 604, 219}, {230, 37, 360, 36, 261, 392, 605, 244, 40, 376}, {356, 230, 360, 484, 599, 605, 384, 608, 606, 607}, {22, 23, 293, 163, 26, 325, 303, 173, 194, 584}, {294, 486, 291, 226, 609, 511, 322, 585, 610, 611}, {294, 228, 486, 226, 556, 612, 609, 585, 257, 610}, {3, 17, 166, 427, 21, 216, 219, 479, 474, 613}, {364, 103, 4, 234, 522, 153, 416, 521, 519, 285}, {158, 15, 418, 162, 172, 430, 614, 171, 170, 615}, {15, 423, 418, 162, 432, 431, 430, 170, 561, 615}, {157, 483, 160, 165, 616, 588, 204, 205, 587, 186}, {482, 158, 418, 162, 617, 614, 618, 619, 171, 615}, {423, 482, 418, 162, 620, 618, 431, 561, 619, 615}, {425, 488, 292, 489, 579, 622, 621, 580, 538, 623}, {290, 489, 490, 292, 624, 625, 498, 316, 623, 499}, {222, 223, 485, 484, 264, 525, 515, 500, 575, 492}, {363, 0, 66, 299, 413, 70, 409, 509, 351, 347}, {482, 422, 485, 417, 626, 576, 548, 627, 459, 544}, {486, 290, 287, 489, 628, 332, 629, 503, 624, 630}, {296, 3, 166, 427, 350, 219, 604, 631, 479, 613}, {489, 290, 287, 292, 624, 332, 630, 623, 316, 330}, {488, 85, 427, 419, 632, 471, 633, 634, 439, 472}, {425, 488, 419, 85, 579, 634, 440, 441, 632, 439}, {15, 16, 423, 162, 19, 454, 432, 170, 195, 561}, {65, 64, 357, 295, 68, 367, 389, 327, 309, 512}, {222, 484, 486, 226, 500, 502, 504, 267, 635, 610}, {356, 484, 95, 225, 608, 554, 592, 524, 636, 593}, {352, 484, 486, 487, 598, 502, 637, 639, 560, 638}, {230, 222, 484, 225, 270, 500, 606, 251, 269, 636}, {294, 228, 58, 57, 556, 259, 326, 308, 238, 61}, {352, 483, 484, 487, 595, 491, 598, 639, 550, 560}, {23, 163, 24, 293, 194, 193, 27, 325, 584, 314}, {429, 231, 1, 52, 640, 284, 481, 475, 281, 56}, {228, 222, 486, 226, 266, 504, 612, 257, 267, 610}, {482, 422, 417, 418, 626, 459, 627, 618, 434, 458}, {489, 425, 490, 292, 580, 533, 625, 623, 621, 499}, {483, 92, 97, 484, 530, 134, 641, 491, 531, 553}, {50, 232, 5, 428, 272, 286, 53, 470, 642, 478}, {483, 165, 358, 354, 587, 555, 643, 589, 591, 378}, {157, 483, 487, 488, 616, 550, 644, 645, 537, 551}, {425, 488, 417, 419, 579, 581, 463, 440, 634, 461}, {222, 230, 484, 226, 270, 606, 500, 267, 245, 635}, {299, 363, 233, 291, 509, 508, 507, 345, 646, 647}, {103, 356, 73, 95, 518, 386, 149, 147, 592, 122}, {229, 44, 45, 100, 262, 48, 249, 506, 132, 123}, {356, 230, 38, 360, 599, 252, 385, 384, 605, 383}, {104, 223, 45, 96, 648, 247, 151, 150, 649, 125}, {22, 159, 293, 288, 175, 650, 303, 305, 651, 304}, {352, 356, 360, 484, 400, 384, 399, 598, 608, 607}, {2, 361, 168, 29, 414, 652, 218, 32, 403, 213}, {484, 483, 359, 97, 491, 596, 597, 553, 641, 653}, {483, 157, 160, 164, 616, 204, 588, 654, 203, 177}, {92, 484, 100, 95, 531, 655, 139, 137, 554, 115}, {223, 420, 96, 104, 529, 656, 649, 648, 657, 150}, {85, 425, 292, 86, 441, 621, 302, 89, 457, 324}, {355, 352, 486, 357, 397, 637, 658, 381, 394, 514}, {353, 289, 487, 357, 578, 600, 566, 366, 659, 660}, {66, 295, 357, 291, 320, 512, 380, 318, 319, 513}, {488, 487, 287, 489, 551, 662, 661, 538, 552, 630}, {486, 294, 287, 290, 609, 334, 629, 628, 307, 332}, {227, 223, 485, 222, 236, 525, 526, 263, 264, 515}, {355, 486, 226, 291, 658, 610, 663, 664, 511, 611}, {43, 103, 95, 225, 146, 147, 114, 243, 523, 593}, {356, 230, 484, 225, 599, 606, 608, 524, 251, 636}, {64, 295, 289, 357, 309, 310, 311, 367, 512, 659}, {157, 482, 162, 158, 665, 619, 198, 199, 617, 171}, {223, 229, 45, 96, 248, 249, 247, 649, 505, 125}, {222, 229, 484, 225, 268, 574, 500, 269, 242, 636}, {422, 78, 418, 99, 433, 435, 434, 569, 112, 666}, {422, 80, 79, 99, 447, 83, 455, 569, 128, 130}, {159, 22, 293, 163, 175, 303, 650, 174, 173, 584}, {101, 362, 71, 6, 667, 405, 141, 154, 415, 74}, {93, 483, 354, 160, 668, 589, 669, 670, 588, 590}, {355, 486, 291, 357, 658, 511, 664, 381, 514, 513}, {362, 101, 169, 6, 667, 567, 671, 415, 154, 220}, {94, 482, 418, 99, 672, 618, 673, 113, 674, 666}, {488, 482, 489, 417, 536, 539, 538, 581, 627, 582}, {484, 356, 95, 359, 608, 592, 554, 597, 387, 594}, {363, 355, 233, 291, 407, 542, 508, 646, 664, 647}, {485, 92, 96, 99, 532, 140, 675, 676, 138, 127}, {78, 94, 418, 99, 111, 673, 435, 112, 113, 666}, {92, 483, 97, 93, 530, 641, 134, 133, 668, 105}, {484, 95, 97, 359, 554, 121, 553, 597, 594, 653}, {72, 71, 97, 359, 75, 106, 129, 390, 371, 653}, {94, 482, 99, 92, 672, 674, 113, 136, 573, 138}, {102, 167, 7, 426, 557, 221, 155, 559, 549, 480}, {10, 164, 158, 98, 184, 183, 182, 118, 558, 541}, {482, 422, 99, 485, 626, 569, 674, 548, 576, 676}, {15, 158, 426, 167, 172, 677, 466, 207, 206, 549}, {92, 482, 99, 485, 573, 674, 138, 532, 548, 676}, {158, 15, 426, 418, 172, 466, 677, 614, 430, 467}, {38, 356, 234, 225, 385, 520, 280, 250, 524, 275}, {94, 482, 158, 418, 672, 617, 540, 673, 618, 614}, {364, 356, 234, 38, 410, 520, 521, 411, 385, 280}, {93, 160, 8, 98, 670, 178, 108, 110, 678, 109}, {355, 233, 226, 36, 542, 277, 663, 374, 278, 246}, {160, 93, 8, 169, 670, 108, 178, 210, 568, 211}, {227, 223, 50, 420, 236, 237, 235, 527, 529, 438}, {363, 0, 233, 36, 413, 283, 508, 406, 39, 278}, {486, 295, 287, 291, 510, 333, 629, 511, 319, 335}, {59, 294, 291, 226, 321, 322, 323, 256, 585, 611}, {66, 363, 299, 291, 409, 509, 347, 318, 646, 345}, {486, 352, 487, 357, 637, 639, 638, 514, 394, 660}, {295, 486, 487, 357, 510, 638, 679, 512, 514, 660}, {296, 22, 288, 166, 337, 305, 336, 604, 209, 680}, {361, 64, 2, 297, 401, 67, 414, 681, 342, 349}, {95, 97, 359, 73, 121, 653, 594, 122, 120, 388}, {423, 482, 417, 418, 620, 627, 460, 431, 618, 458}, {65, 295, 357, 66, 327, 512, 389, 69, 320, 380}, {97, 72, 359, 73, 129, 390, 653, 120, 76, 388}, {420, 223, 96, 485, 529, 649, 656, 528, 525, 675}, {159, 488, 293, 288, 682, 683, 650, 651, 684, 304}, {31, 165, 160, 354, 187, 186, 185, 377, 591, 590}, {484, 486, 487, 489, 502, 638, 560, 496, 503, 552}, {486, 295, 487, 287, 510, 679, 638, 629, 333, 662}, {59, 233, 226, 291, 282, 277, 256, 323, 647, 611}, {233, 355, 226, 291, 542, 663, 277, 647, 664, 611}, {425, 421, 489, 490, 449, 685, 580, 533, 517, 625}, {288, 488, 292, 85, 684, 622, 301, 300, 632, 302}, {421, 425, 489, 417, 449, 580, 685, 465, 463, 582}, {294, 228, 57, 290, 556, 238, 308, 307, 686, 306}, {165, 31, 358, 354, 187, 379, 555, 591, 377, 378}, {103, 356, 364, 73, 518, 410, 522, 149, 386, 412}, {352, 483, 358, 354, 595, 643, 395, 396, 589, 378}, {22, 159, 288, 166, 175, 651, 305, 209, 208, 680}, {356, 352, 359, 484, 400, 398, 387, 608, 598, 597}, {64, 361, 353, 297, 401, 402, 365, 342, 681, 577}, {355, 66, 357, 291, 382, 380, 381, 664, 318, 513}, {487, 486, 287, 489, 638, 629, 662, 552, 503, 630}, {298, 57, 490, 290, 339, 687, 534, 340, 306, 498}, {31, 362, 169, 6, 408, 671, 215, 35, 415, 220}, {488, 425, 292, 85, 579, 621, 622, 632, 441, 302}, {483, 352, 359, 354, 595, 398, 596, 589, 396, 372}, {94, 78, 418, 426, 111, 435, 673, 688, 468, 467}, {229, 43, 44, 100, 241, 47, 262, 506, 116, 132}, {31, 165, 358, 30, 187, 555, 379, 34, 196, 391}, {429, 231, 52, 490, 640, 281, 475, 516, 547, 546}, {94, 102, 78, 426, 144, 145, 111, 688, 559, 468}, {421, 429, 52, 490, 476, 475, 451, 517, 516, 546}, {364, 103, 73, 4, 522, 149, 412, 416, 153, 77}, {420, 227, 424, 50, 527, 571, 437, 438, 235, 436}, {104, 80, 5, 428, 152, 84, 156, 689, 473, 478}, {227, 51, 52, 424, 260, 55, 255, 571, 456, 453}, {487, 289, 293, 287, 600, 313, 601, 662, 331, 328}, {166, 159, 288, 488, 208, 651, 680, 690, 682, 684}, {289, 161, 353, 487, 586, 562, 578, 600, 564, 566}, {482, 485, 489, 417, 548, 495, 539, 627, 544, 582}, {50, 227, 424, 51, 235, 571, 436, 54, 260, 456}, {488, 489, 287, 292, 538, 630, 661, 622, 623, 330}, {482, 483, 157, 488, 535, 616, 665, 536, 537, 645}, {80, 420, 104, 96, 445, 657, 152, 126, 656, 150}, {232, 104, 45, 5, 691, 151, 279, 286, 156, 49}, {288, 488, 287, 292, 684, 661, 329, 301, 622, 330}, {295, 289, 487, 287, 310, 600, 679, 333, 331, 662}, {157, 161, 163, 487, 202, 192, 201, 644, 564, 602}, {483, 482, 164, 98, 535, 692, 654, 694, 693, 558}, {3, 296, 85, 427, 350, 338, 88, 479, 631, 471}, {92, 483, 93, 98, 530, 668, 133, 135, 694, 110}, {95, 484, 100, 225, 554, 655, 115, 593, 636, 695}, {231, 224, 490, 57, 273, 545, 547, 274, 240, 687}, {64, 289, 353, 357, 311, 578, 365, 367, 659, 366}, {2, 297, 24, 168, 349, 344, 28, 218, 696, 217}, {361, 297, 168, 353, 681, 696, 652, 402, 577, 697}, {353, 161, 168, 29, 562, 212, 697, 370, 181, 213}, {289, 295, 487, 357, 310, 679, 600, 659, 512, 660}, {352, 353, 487, 357, 393, 566, 639, 394, 366, 660}, {361, 353, 168, 29, 402, 697, 652, 403, 370, 213}, {484, 229, 100, 225, 574, 506, 655, 636, 242, 695}, {104, 223, 232, 45, 648, 271, 691, 151, 247, 279}, {160, 164, 8, 98, 177, 176, 178, 678, 558, 109}, {164, 9, 8, 98, 197, 12, 176, 558, 131, 109}, {165, 161, 358, 29, 180, 563, 555, 179, 181, 368}, {297, 361, 168, 2, 681, 652, 696, 349, 414, 218}, {161, 353, 358, 29, 562, 369, 563, 181, 370, 368}, {230, 37, 38, 360, 261, 41, 252, 605, 392, 383}, {43, 95, 100, 225, 114, 115, 116, 243, 593, 695}, {420, 80, 104, 428, 445, 152, 657, 469, 473, 689}, {232, 104, 5, 428, 691, 156, 286, 642, 689, 478}, {59, 299, 233, 291, 346, 507, 282, 323, 345, 647}, {355, 363, 66, 291, 407, 409, 382, 664, 646, 318}, {158, 94, 418, 426, 540, 673, 614, 677, 688, 467}, {87, 429, 298, 1, 477, 603, 343, 91, 481, 348}, {420, 227, 485, 424, 527, 526, 528, 437, 571, 543}, {482, 422, 418, 99, 626, 434, 618, 674, 569, 666}, {229, 43, 100, 225, 241, 116, 506, 242, 243, 695}, {294, 486, 287, 291, 609, 629, 334, 322, 511, 335}, {17, 166, 419, 159, 216, 698, 444, 188, 208, 699}, {419, 166, 17, 427, 698, 216, 444, 472, 613, 474}, {166, 488, 419, 159, 690, 634, 698, 208, 682, 699}, {419, 488, 166, 427, 634, 690, 698, 472, 633, 613}, {160, 98, 483, 164, 678, 694, 588, 177, 558, 654}, {483, 98, 160, 93, 694, 678, 588, 668, 110, 670}, {226, 360, 486, 355, 700, 701, 610, 663, 375, 658}, {360, 36, 226, 230, 376, 246, 700, 605, 244, 245}, {226, 36, 360, 355, 246, 376, 700, 663, 374, 375}, {93, 169, 362, 101, 568, 671, 702, 142, 567, 667}, {93, 362, 71, 101, 702, 405, 107, 142, 667, 141}, {71, 362, 93, 354, 405, 702, 107, 373, 404, 669}, {489, 424, 417, 485, 572, 464, 582, 495, 543, 544}, {417, 424, 489, 421, 464, 572, 582, 465, 452, 685}, {102, 10, 158, 94, 148, 182, 703, 144, 119, 540}, {158, 10, 102, 167, 182, 148, 703, 206, 214, 557}, {102, 158, 426, 94, 703, 677, 559, 144, 540, 688}, {426, 158, 102, 167, 677, 703, 559, 549, 206, 557}, {421, 489, 227, 424, 685, 570, 704, 452, 572, 571}, {52, 421, 227, 424, 451, 704, 255, 453, 452, 571}, {489, 227, 222, 224, 570, 263, 501, 705, 254, 265}, {489, 222, 227, 485, 501, 263, 570, 495, 515, 526}, {87, 425, 292, 490, 448, 621, 315, 497, 533, 499}, {292, 425, 87, 86, 621, 448, 315, 324, 457, 90}, {104, 420, 232, 223, 657, 706, 691, 648, 529, 271}, {104, 232, 420, 428, 691, 706, 657, 689, 642, 469}, {232, 420, 50, 223, 706, 438, 272, 271, 529, 237}, {232, 50, 420, 428, 272, 438, 706, 642, 470, 469}, {226, 484, 360, 230, 635, 607, 700, 245, 606, 605}, {226, 360, 484, 486, 700, 607, 635, 610, 701, 502}, {486, 360, 352, 355, 701, 399, 637, 658, 375, 397}, {352, 360, 486, 484, 399, 701, 637, 598, 607, 502}, {162, 488, 157, 159, 707, 645, 198, 189, 682, 200}, {157, 488, 162, 482, 645, 707, 198, 665, 536, 619}, {490, 57, 429, 231, 687, 708, 516, 547, 274, 640}, {429, 57, 490, 298, 708, 687, 516, 603, 339, 534}, {57, 1, 429, 231, 60, 481, 708, 274, 284, 640}, {429, 1, 57, 298, 481, 60, 708, 603, 348, 339}, {158, 98, 482, 94, 541, 693, 617, 540, 117, 672}, {482, 98, 158, 164, 693, 541, 617, 692, 558, 183}, {353, 297, 161, 289, 577, 709, 562, 578, 341, 586}, {353, 161, 297, 168, 562, 709, 577, 697, 212, 696}, {161, 297, 24, 289, 709, 344, 191, 586, 341, 312}, {161, 24, 297, 168, 191, 344, 709, 212, 217, 696}, {159, 293, 487, 163, 650, 601, 710, 174, 584, 602}, {487, 293, 159, 488, 601, 650, 710, 551, 683, 682}, {159, 487, 157, 163, 710, 644, 200, 174, 602, 201}, {157, 487, 159, 488, 644, 710, 200, 645, 551, 682}, {290, 228, 486, 294, 686, 612, 628, 307, 556, 609}, {290, 486, 228, 489, 628, 612, 686, 624, 503, 711}, {485, 99, 420, 422, 676, 712, 528, 576, 569, 446}, {420, 99, 485, 96, 712, 676, 528, 656, 127, 675}, {99, 80, 420, 422, 128, 445, 712, 569, 447, 446}, {420, 80, 99, 96, 445, 128, 712, 656, 126, 127}, {96, 484, 229, 100, 713, 574, 505, 124, 655, 506}, {92, 96, 484, 485, 140, 713, 531, 532, 675, 492}, {92, 484, 96, 100, 531, 713, 140, 139, 655, 124}, {161, 358, 483, 165, 563, 643, 714, 180, 555, 587}, {483, 358, 161, 487, 643, 563, 714, 550, 565, 564}, {161, 483, 157, 165, 714, 616, 202, 180, 587, 205}, {157, 483, 161, 487, 616, 714, 202, 644, 550, 564}, {362, 31, 160, 354, 408, 185, 715, 404, 377, 590}, {160, 31, 362, 169, 185, 408, 715, 210, 215, 671}, {362, 160, 93, 354, 715, 670, 702, 404, 590, 669}, {93, 160, 362, 169, 670, 715, 702, 568, 210, 671}, {482, 164, 157, 483, 692, 203, 665, 535, 654, 616}, {157, 164, 482, 158, 203, 692, 665, 199, 183, 617}, {228, 489, 222, 224, 711, 501, 266, 239, 705, 265}, {222, 489, 228, 486, 501, 711, 266, 504, 503, 612}, {288, 166, 427, 296, 680, 613, 716, 336, 604, 631}, {288, 427, 166, 488, 716, 613, 680, 684, 633, 690}, {85, 288, 427, 296, 300, 716, 471, 338, 336, 631}, {85, 427, 288, 488, 471, 716, 300, 632, 633, 684}, {484, 223, 96, 229, 575, 649, 713, 574, 248, 505}, {484, 96, 223, 485, 713, 649, 575, 492, 675, 525}, {488, 293, 287, 487, 683, 328, 661, 551, 601, 662}, {287, 293, 488, 288, 328, 683, 661, 329, 304, 684}, {419, 488, 162, 159, 634, 707, 717, 699, 682, 189}, {162, 419, 17, 423, 717, 444, 190, 561, 443, 442}, {17, 419, 162, 159, 444, 717, 190, 188, 699, 189}, {482, 98, 92, 94, 693, 135, 573, 672, 117, 136}, {92, 98, 482, 483, 135, 693, 573, 530, 694, 535}, {358, 487, 352, 353, 565, 639, 395, 369, 566, 393}, {352, 487, 358, 483, 639, 565, 395, 595, 550, 643}, {359, 483, 93, 97, 596, 668, 718, 653, 641, 105}, {359, 93, 483, 354, 718, 668, 596, 372, 669, 589}, {71, 359, 93, 97, 371, 718, 107, 106, 653, 105}, {71, 93, 359, 354, 107, 718, 371, 373, 669, 372}, {52, 490, 227, 421, 546, 719, 255, 451, 517, 704}, {227, 490, 52, 224, 719, 546, 255, 254, 545, 253}, {490, 489, 227, 421, 625, 570, 719, 517, 685, 704}, {227, 489, 490, 224, 570, 625, 719, 254, 705, 545}, {57, 490, 228, 224, 687, 720, 238, 240, 545, 239}, {228, 490, 57, 290, 720, 687, 238, 686, 498, 306}, {490, 489, 228, 224, 625, 711, 720, 545, 705, 239}, {228, 489, 490, 290, 711, 625, 720, 686, 624, 498}, {162, 419, 482, 488, 717, 721, 619, 707, 634, 536}, {482, 419, 162, 423, 721, 717, 619, 620, 443, 561}, {419, 417, 482, 488, 461, 627, 721, 634, 581, 536}, {482, 417, 419, 423, 627, 461, 721, 620, 460, 443}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_interpolate_tetrahedron_4.verified b/test/test_fem/test_interpolate_tetrahedron_4.verified
deleted file mode 100644
index 02a936b1b..000000000
--- a/test/test_fem/test_interpolate_tetrahedron_4.verified
+++ /dev/null
@@ -1,67 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 3
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 3
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 8
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 48
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{6, 8}, {8, 9}, {9, 10}, {10, 7}, {7, 11}, {11, 12}, {12, 13}, {13, 3}, {3, 14}, {14, 15}, {15, 16}, {16, 2}, {2, 17}, {17, 18}, {18, 19}, {19, 6}, {0, 20}, {20, 21}, {21, 22}, {22, 4}, {4, 23}, {23, 24}, {24, 25}, {25, 5}, {5, 26}, {26, 27}, {27, 28}, {28, 1}, {1, 29}, {29, 30}, {30, 31}, {31, 0}, {2, 32}, {32, 33}, {33, 34}, {34, 0}, {6, 35}, {35, 36}, {36, 37}, {37, 4}, {7, 38}, {38, 39}, {39, 40}, {40, 5}, {3, 41}, {41, 42}, {42, 43}, {43, 1}}
- ]
- ]
- (not_ghost:_triangle_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_3
- + size : 240
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{45, 49, 35}, {45, 8, 50}, {46, 38, 51}, {23, 47, 52}, {46, 50, 10}, {37, 49, 47}, {25, 52, 48}, {40, 48, 51}, {35, 49, 36}, {38, 39, 51}, {8, 9, 50}, {23, 52, 24}, {36, 49, 37}, {9, 10, 50}, {39, 40, 51}, {24, 52, 25}, {45, 44, 49}, {45, 50, 44}, {46, 44, 50}, {44, 47, 49}, {46, 51, 44}, {44, 52, 47}, {44, 51, 48}, {44, 48, 52}, {45, 35, 53}, {45, 53, 8}, {46, 54, 38}, {23, 55, 47}, {46, 10, 54}, {37, 47, 55}, {25, 48, 56}, {40, 56, 48}, {4, 37, 55}, {6, 53, 35}, {7, 54, 10}, {7, 38, 54}, {6, 8, 53}, {5, 56, 40}, {4, 55, 23}, {5, 25, 56}, {11, 62, 58}, {14, 63, 59}, {8, 64, 60}, {17, 65, 61}, {10, 58, 64}, {19, 60, 65}, {13, 59, 62}, {16, 61, 63}, {14, 15, 63}, {11, 12, 62}, {17, 18, 65}, {8, 9, 64}, {12, 13, 62}, {15, 16, 63}, {9, 10, 64}, {18, 19, 65}, {58, 62, 57}, {59, 57, 62}, {59, 63, 57}, {61, 57, 63}, {58, 57, 64}, {60, 64, 57}, {60, 57, 65}, {61, 65, 57}, {11, 58, 67}, {14, 59, 66}, {8, 60, 69}, {17, 61, 68}, {10, 67, 58}, {19, 69, 60}, {13, 66, 59}, {16, 68, 61}, {2, 68, 16}, {3, 66, 13}, {6, 69, 19}, {7, 67, 10}, {7, 11, 67}, {3, 14, 66}, {6, 8, 69}, {2, 17, 68}, {26, 75, 71}, {29, 76, 72}, {23, 77, 73}, {20, 78, 74}, {25, 71, 77}, {22, 73, 78}, {28, 72, 75}, {31, 74, 76}, {29, 30, 76}, {26, 27, 75}, {20, 21, 78}, {23, 24, 77}, {27, 28, 75}, {30, 31, 76}, {24, 25, 77}, {21, 22, 78}, {71, 75, 70}, {72, 70, 75}, {72, 76, 70}, {70, 76, 74}, {71, 70, 77}, {70, 73, 77}, {70, 78, 73}, {70, 74, 78}, {26, 71, 80}, {29, 72, 79}, {23, 73, 82}, {20, 74, 81}, {25, 80, 71}, {22, 82, 73}, {28, 79, 72}, {31, 81, 74}, {0, 81, 31}, {1, 79, 28}, {4, 82, 22}, {5, 80, 25}, {5, 26, 80}, {1, 29, 79}, {4, 23, 82}, {0, 20, 81}, {41, 84, 88}, {14, 89, 84}, {29, 86, 90}, {32, 91, 85}, {16, 85, 89}, {43, 88, 86}, {34, 87, 91}, {31, 90, 87}, {41, 88, 42}, {14, 15, 89}, {29, 90, 30}, {32, 33, 91}, {42, 88, 43}, {15, 16, 89}, {33, 34, 91}, {30, 90, 31}, {84, 89, 83}, {84, 83, 88}, {85, 83, 89}, {86, 88, 83}, {85, 91, 83}, {86, 83, 90}, {87, 90, 83}, {87, 83, 91}, {14, 84, 92}, {41, 92, 84}, {29, 94, 86}, {32, 85, 93}, {43, 86, 94}, {16, 93, 85}, {31, 87, 95}, {34, 95, 87}, {1, 43, 94}, {2, 93, 16}, {3, 92, 41}, {3, 14, 92}, {1, 94, 29}, {2, 32, 93}, {0, 31, 95}, {0, 95, 34}, {32, 97, 101}, {17, 102, 97}, {35, 103, 98}, {20, 99, 104}, {19, 98, 102}, {34, 101, 99}, {22, 104, 100}, {37, 100, 103}, {32, 101, 33}, {35, 36, 103}, {17, 18, 102}, {20, 104, 21}, {33, 101, 34}, {18, 19, 102}, {36, 37, 103}, {21, 104, 22}, {97, 96, 101}, {97, 102, 96}, {98, 96, 102}, {99, 101, 96}, {98, 103, 96}, {99, 96, 104}, {100, 96, 103}, {100, 104, 96}, {32, 105, 97}, {17, 97, 105}, {35, 98, 106}, {20, 107, 99}, {19, 106, 98}, {34, 99, 107}, {22, 100, 108}, {37, 108, 100}, {0, 34, 107}, {2, 105, 32}, {6, 106, 19}, {6, 35, 106}, {2, 17, 105}, {4, 108, 37}, {0, 107, 20}, {4, 22, 108}, {11, 110, 115}, {38, 114, 110}, {26, 116, 112}, {41, 111, 117}, {13, 115, 111}, {40, 112, 114}, {43, 117, 113}, {28, 113, 116}, {11, 115, 12}, {38, 39, 114}, {26, 27, 116}, {41, 117, 42}, {39, 40, 114}, {12, 115, 13}, {42, 117, 43}, {27, 28, 116}, {109, 110, 114}, {109, 115, 110}, {111, 115, 109}, {112, 109, 114}, {111, 109, 117}, {112, 116, 109}, {113, 109, 116}, {113, 117, 109}, {11, 118, 110}, {38, 110, 118}, {26, 112, 120}, {41, 119, 111}, {40, 120, 112}, {13, 111, 119}, {28, 121, 113}, {43, 113, 121}, {5, 120, 40}, {3, 13, 119}, {7, 38, 118}, {7, 118, 11}, {5, 26, 120}, {3, 119, 41}, {1, 121, 28}, {1, 43, 121}}
- ]
- ]
- (not_ghost:_tetrahedron_4) [
- Array<unsigned int> [
- + id : mesh:connectivities:_tetrahedron_4
- + size : 341
- + nb_component : 4
- + allocated size : 2000
- + memory size : 31.25KiByte
- + values : {{124, 123, 125, 129}, {43, 86, 130, 88}, {70, 124, 129, 126}, {48, 77, 25, 52}, {31, 0, 81, 95}, {0, 107, 81, 95}, {126, 91, 87, 101}, {124, 70, 129, 125}, {43, 121, 113, 130}, {55, 100, 82, 108}, {100, 55, 82, 73}, {23, 55, 73, 82}, {71, 75, 125, 112}, {123, 44, 124, 125}, {43, 113, 117, 130}, {94, 43, 86, 130}, {122, 123, 128, 129}, {46, 10, 58, 50}, {99, 107, 81, 20}, {125, 112, 116, 109}, {79, 72, 28, 130}, {123, 122, 125, 129}, {67, 11, 7, 118}, {123, 127, 128, 129}, {124, 44, 49, 47}, {17, 65, 18, 102}, {76, 90, 30, 31}, {54, 10, 7, 67}, {9, 10, 50, 64}, {38, 54, 7, 118}, {123, 124, 127, 129}, {12, 115, 62, 13}, {97, 61, 102, 127}, {45, 53, 8, 69}, {38, 114, 39, 51}, {125, 75, 129, 116}, {122, 44, 123, 125}, {71, 70, 77, 124}, {114, 112, 125, 109}, {32, 93, 97, 85}, {53, 6, 8, 69}, {117, 128, 129, 109}, {63, 61, 16, 89}, {76, 90, 31, 74}, {61, 85, 16, 89}, {65, 123, 60, 98}, {55, 100, 47, 73}, {100, 47, 103, 37}, {96, 123, 103, 124}, {55, 23, 4, 82}, {78, 100, 22, 73}, {61, 85, 89, 127}, {61, 127, 89, 63}, {121, 43, 94, 130}, {108, 22, 82, 4}, {14, 92, 3, 66}, {78, 21, 104, 20}, {100, 78, 104, 124}, {14, 15, 89, 63}, {90, 126, 87, 74}, {90, 76, 126, 74}, {3, 13, 66, 119}, {108, 55, 4, 82}, {58, 11, 110, 62}, {11, 115, 110, 62}, {57, 123, 60, 65}, {122, 58, 110, 62}, {115, 122, 110, 62}, {117, 128, 88, 129}, {86, 129, 130, 88}, {70, 71, 125, 124}, {107, 0, 34, 95}, {122, 114, 125, 109}, {126, 86, 83, 129}, {92, 3, 66, 119}, {129, 86, 83, 88}, {128, 41, 119, 111}, {117, 128, 111, 41}, {11, 12, 115, 62}, {33, 32, 101, 91}, {70, 124, 126, 74}, {100, 124, 47, 73}, {96, 124, 126, 127}, {78, 70, 124, 73}, {90, 76, 30, 29}, {96, 123, 124, 127}, {15, 63, 16, 89}, {121, 79, 1, 28}, {76, 70, 126, 74}, {122, 114, 109, 110}, {129, 117, 130, 88}, {123, 44, 49, 124}, {26, 80, 5, 120}, {123, 65, 102, 98}, {57, 123, 127, 128}, {117, 128, 109, 111}, {70, 78, 124, 74}, {95, 107, 81, 87}, {55, 100, 37, 47}, {77, 24, 25, 52}, {100, 78, 22, 104}, {56, 71, 25, 48}, {14, 59, 89, 84}, {96, 100, 104, 124}, {2, 105, 68, 17}, {124, 123, 103, 49}, {123, 57, 60, 64}, {44, 124, 52, 47}, {71, 112, 48, 56}, {41, 117, 88, 42}, {99, 96, 126, 101}, {97, 85, 127, 101}, {34, 91, 101, 87}, {128, 127, 83, 129}, {126, 90, 83, 86}, {75, 71, 125, 70}, {99, 126, 74, 87}, {23, 55, 47, 73}, {100, 78, 124, 73}, {32, 91, 85, 101}, {57, 122, 62, 58}, {71, 77, 25, 48}, {70, 77, 124, 73}, {114, 38, 110, 51}, {114, 40, 39, 51}, {59, 14, 89, 63}, {53, 106, 35, 6}, {45, 123, 98, 60}, {99, 126, 87, 101}, {106, 53, 69, 6}, {46, 122, 110, 51}, {128, 122, 129, 109}, {124, 100, 47, 103}, {107, 99, 81, 87}, {125, 44, 48, 51}, {38, 46, 110, 51}, {44, 123, 49, 45}, {124, 47, 49, 103}, {36, 35, 49, 103}, {46, 122, 51, 44}, {54, 67, 7, 118}, {10, 64, 58, 50}, {122, 114, 51, 125}, {11, 58, 118, 67}, {44, 122, 51, 125}, {58, 11, 118, 110}, {22, 100, 82, 73}, {46, 122, 58, 110}, {108, 100, 82, 22}, {45, 60, 8, 50}, {99, 81, 74, 20}, {60, 45, 8, 69}, {75, 71, 26, 112}, {107, 0, 81, 20}, {126, 91, 83, 87}, {31, 90, 87, 74}, {34, 107, 95, 87}, {126, 96, 127, 101}, {91, 126, 127, 101}, {92, 14, 84, 66}, {105, 32, 2, 93}, {47, 49, 103, 37}, {115, 122, 109, 110}, {33, 91, 101, 34}, {49, 36, 103, 37}, {112, 71, 48, 125}, {59, 128, 89, 84}, {19, 65, 60, 98}, {124, 126, 127, 129}, {126, 91, 127, 83}, {31, 81, 74, 87}, {81, 99, 74, 87}, {117, 113, 129, 130}, {84, 128, 88, 41}, {113, 117, 129, 109}, {90, 76, 29, 86}, {65, 19, 102, 98}, {55, 100, 108, 37}, {96, 123, 102, 98}, {14, 59, 84, 66}, {100, 96, 103, 124}, {32, 105, 97, 93}, {99, 34, 101, 87}, {127, 126, 83, 129}, {94, 29, 130, 86}, {19, 106, 69, 6}, {128, 117, 88, 41}, {123, 96, 103, 98}, {46, 38, 110, 118}, {77, 23, 24, 52}, {19, 65, 102, 18}, {121, 79, 28, 130}, {46, 54, 38, 118}, {113, 121, 28, 130}, {108, 55, 37, 4}, {112, 75, 116, 26}, {56, 40, 5, 120}, {75, 27, 28, 116}, {127, 85, 89, 83}, {66, 59, 84, 128}, {85, 61, 97, 127}, {122, 125, 129, 109}, {26, 75, 116, 27}, {128, 129, 83, 88}, {122, 123, 57, 128}, {40, 112, 56, 48}, {80, 56, 25, 5}, {84, 128, 83, 88}, {91, 85, 127, 83}, {57, 61, 63, 127}, {123, 122, 64, 50}, {3, 92, 41, 119}, {44, 123, 45, 50}, {47, 124, 52, 73}, {79, 72, 130, 29}, {32, 85, 97, 101}, {2, 93, 16, 68}, {105, 93, 68, 97}, {97, 61, 68, 17}, {85, 91, 127, 101}, {96, 97, 127, 101}, {105, 97, 68, 17}, {124, 77, 52, 73}, {56, 71, 80, 25}, {60, 64, 8, 50}, {64, 9, 8, 50}, {65, 61, 102, 17}, {93, 105, 68, 2}, {61, 97, 102, 17}, {78, 21, 22, 104}, {23, 47, 52, 73}, {112, 40, 56, 120}, {80, 56, 5, 120}, {31, 95, 81, 87}, {99, 107, 34, 87}, {58, 46, 110, 118}, {43, 121, 94, 1}, {112, 75, 125, 116}, {122, 114, 110, 51}, {77, 23, 52, 73}, {90, 126, 83, 87}, {13, 66, 111, 59}, {111, 66, 13, 119}, {66, 128, 111, 59}, {111, 128, 66, 119}, {60, 50, 123, 64}, {123, 50, 60, 45}, {74, 104, 126, 99}, {104, 20, 74, 78}, {74, 20, 104, 99}, {45, 69, 106, 53}, {45, 106, 35, 53}, {35, 106, 45, 98}, {129, 116, 109, 125}, {109, 116, 129, 113}, {54, 10, 58, 46}, {58, 10, 54, 67}, {54, 58, 118, 46}, {118, 58, 54, 67}, {113, 129, 75, 116}, {28, 113, 75, 116}, {129, 75, 70, 72}, {129, 70, 75, 125}, {43, 117, 88, 130}, {88, 117, 43, 42}, {56, 112, 80, 71}, {56, 80, 112, 120}, {80, 112, 26, 71}, {80, 26, 112, 120}, {74, 124, 104, 78}, {74, 104, 124, 126}, {126, 104, 96, 99}, {96, 104, 126, 124}, {62, 128, 57, 59}, {57, 128, 62, 122}, {130, 29, 121, 79}, {121, 29, 130, 94}, {29, 1, 121, 79}, {121, 1, 29, 94}, {58, 50, 122, 46}, {122, 50, 58, 64}, {97, 93, 61, 85}, {97, 61, 93, 68}, {61, 93, 16, 85}, {61, 16, 93, 68}, {59, 89, 127, 63}, {127, 89, 59, 128}, {59, 127, 57, 63}, {57, 127, 59, 128}, {86, 76, 126, 90}, {86, 126, 76, 129}, {125, 51, 112, 114}, {112, 51, 125, 48}, {51, 40, 112, 114}, {112, 40, 51, 48}, {48, 124, 77, 52}, {44, 48, 124, 125}, {44, 124, 48, 52}, {61, 102, 123, 65}, {123, 102, 61, 127}, {61, 123, 57, 65}, {57, 123, 61, 127}, {106, 19, 60, 98}, {60, 19, 106, 69}, {106, 60, 45, 98}, {45, 60, 106, 69}, {122, 64, 57, 123}, {57, 64, 122, 58}, {76, 129, 70, 72}, {70, 129, 76, 126}, {84, 66, 119, 92}, {84, 119, 66, 128}, {41, 84, 119, 92}, {41, 119, 84, 128}, {124, 71, 48, 77}, {124, 48, 71, 125}, {128, 89, 83, 127}, {83, 89, 128, 84}, {111, 128, 62, 59}, {62, 111, 13, 115}, {13, 111, 62, 59}, {122, 50, 44, 46}, {44, 50, 122, 123}, {102, 127, 96, 97}, {96, 127, 102, 123}, {103, 123, 45, 49}, {103, 45, 123, 98}, {35, 103, 45, 49}, {35, 45, 103, 98}, {28, 130, 75, 113}, {75, 130, 28, 72}, {130, 129, 75, 113}, {75, 129, 130, 72}, {29, 130, 76, 72}, {76, 130, 29, 86}, {130, 129, 76, 72}, {76, 129, 130, 86}, {62, 111, 122, 128}, {122, 111, 62, 115}, {111, 109, 122, 128}, {122, 109, 111, 115}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_interpolate_triangle_3.verified b/test/test_fem/test_interpolate_triangle_3.verified
deleted file mode 100644
index a74895613..000000000
--- a/test/test_fem/test_interpolate_triangle_3.verified
+++ /dev/null
@@ -1,57 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 4
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}}
- ]
- ]
- (not_ghost:_segment_2) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_2
- + size : 8
- + nb_component : 2
- + allocated size : 2000
- + memory size : 15.62KiByte
- + values : {{0, 4}, {4, 1}, {1, 5}, {5, 2}, {2, 6}, {6, 3}, {3, 7}, {7, 0}}
- ]
- ]
- (not_ghost:_triangle_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_3
- + size : 16
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{3, 9, 6}, {0, 12, 7}, {2, 10, 5}, {1, 11, 4}, {7, 8, 9}, {6, 9, 8}, {6, 8, 10}, {7, 12, 8}, {5, 10, 8}, {4, 8, 12}, {4, 11, 8}, {5, 8, 11}, {0, 4, 12}, {3, 7, 9}, {1, 5, 11}, {2, 6, 10}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_interpolate_triangle_6.verified b/test/test_fem/test_interpolate_triangle_6.verified
deleted file mode 100644
index 93b1f37a8..000000000
--- a/test/test_fem/test_interpolate_triangle_6.verified
+++ /dev/null
@@ -1,57 +0,0 @@
-Epsilon : 3e-13
-FEEngine [
- + id : my_fem
- + element dimension : 2
- + mesh [
- Mesh [
- + id : mesh
- + spatial dimension : 2
- + nodes [
- 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}}
- ]
- + connectivities [
- ElementTypeMapArray<unsigned int> [
- (not_ghost:_point_1) [
- Array<unsigned int> [
- + id : mesh:connectivities:_point_1
- + size : 4
- + nb_component : 1
- + allocated size : 2000
- + memory size : 7.81KiByte
- + values : {{0}, {1}, {2}, {3}}
- ]
- ]
- (not_ghost:_segment_3) [
- Array<unsigned int> [
- + id : mesh:connectivities:_segment_3
- + size : 8
- + nb_component : 3
- + allocated size : 2000
- + memory size : 23.44KiByte
- + values : {{0, 4, 5}, {4, 1, 6}, {1, 7, 8}, {7, 2, 9}, {2, 10, 11}, {10, 3, 12}, {3, 13, 14}, {13, 0, 15}}
- ]
- ]
- (not_ghost:_triangle_6) [
- Array<unsigned int> [
- + id : mesh:connectivities:_triangle_6
- + size : 16
- + nb_component : 6
- + allocated size : 2000
- + memory size : 46.88KiByte
- + values : {{3, 17, 10, 21, 22, 12}, {0, 20, 13, 23, 24, 15}, {2, 18, 7, 25, 26, 9}, {1, 19, 4, 27, 28, 6}, {13, 16, 17, 29, 30, 31}, {10, 17, 16, 22, 30, 32}, {10, 16, 18, 32, 33, 34}, {13, 20, 16, 24, 35, 29}, {7, 18, 16, 26, 33, 36}, {4, 16, 20, 37, 35, 38}, {4, 19, 16, 28, 39, 37}, {7, 16, 19, 36, 39, 40}, {0, 4, 20, 5, 38, 23}, {3, 13, 17, 14, 31, 21}, {1, 7, 19, 8, 40, 27}, {2, 10, 18, 11, 34, 25}}
- ]
- ]
- ]
- ]
- GroupManager [
- ]
- ]
- ]
-]
-
diff --git a/test/test_fem/test_inverse_map.cc b/test/test_fem/test_inverse_map.cc
deleted file mode 100644
index 525e46f26..000000000
--- a/test/test_fem/test_inverse_map.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * @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
- *
- * @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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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 "mesh.hh"
-#include "mesh_io.hh"
-#include "mesh_io_msh.hh"
-#include "shape_lagrange.hh"
-#include "integrator_gauss.hh"
-/* -------------------------------------------------------------------------- */
-#include <cstdlib>
-#include <fstream>
-#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();
-
- MeshIOMSH mesh_io;
- 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";
- mesh_io.read(meshfilename.str(), my_mesh);
-
- 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);
-
- /// 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(),
- 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_geometry/CMakeLists.txt b/test/test_geometry/CMakeLists.txt
new file mode 100644
index 000000000..3f385bddb
--- /dev/null
+++ b/test/test_geometry/CMakeLists.txt
@@ -0,0 +1,57 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Lucas Frerot <lucas.frerot@epfl.ch>
+#
+# @date creation: Fri Feb 27 2015
+# @date last modification: Fri Feb 27 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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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
new file mode 100644
index 000000000..b0232c2b8
--- /dev/null
+++ b/test/test_geometry/test_geometry_intersection.cc
@@ -0,0 +1,127 @@
+/**
+ * @file test_geometry_intersection.cc
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ * @author Clément Roux-Langlois <clement.roux@epfl.ch>
+ *
+ * @date creation: Fri Feb 27 2015
+ * @date last modification: Thu Mar 5 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..8ffab37b6
--- /dev/null
+++ b/test/test_geometry/test_geometry_predicates.cc
@@ -0,0 +1,88 @@
+/**
+ * @file test_geometry_predicates.cc
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Thu Mar 26 2015
+ * @date last modification: Thu Mar 26 2015
+ *
+ * @brief Tests the geometry predicates
+ *
+ * @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 "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_geometry_tetrahedron.msh b/test/test_geometry/test_geometry_tetrahedron.msh
new file mode 100644
index 000000000..dd603538a
--- /dev/null
+++ b/test/test_geometry/test_geometry_tetrahedron.msh
@@ -0,0 +1,22 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+8
+1 0 0 0
+2 1 0 0
+3 1 1 0
+4 0 1 0
+5 0 1 1
+6 0 0 1
+7 1 0 1
+8 1 1 1
+$EndNodes
+$Elements
+5
+1 4 2 1 0 1 2 4 6
+2 4 2 1 0 6 2 4 8
+3 4 2 1 0 6 8 4 5
+4 4 2 1 0 2 4 8 3
+5 4 2 1 0 2 6 7 8
+$EndElements
diff --git a/test/test_geometry/test_geometry_triangle.msh b/test/test_geometry/test_geometry_triangle.msh
new file mode 100644
index 000000000..f27f81ed6
--- /dev/null
+++ b/test/test_geometry/test_geometry_triangle.msh
@@ -0,0 +1,15 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+4
+1 0 0 0
+2 1 0 0
+3 0 1 0
+4 0.5 0.5 0
+$EndNodes
+$Elements
+2
+1 2 2 1 0 1 2 4
+2 2 2 1 0 1 4 3
+$EndElements
diff --git a/test/test_geometry/test_segment_intersection_tetrahedron_4.cc b/test/test_geometry/test_segment_intersection_tetrahedron_4.cc
new file mode 100644
index 000000000..fdebf0637
--- /dev/null
+++ b/test/test_geometry/test_segment_intersection_tetrahedron_4.cc
@@ -0,0 +1,148 @@
+/**
+ * @file test_geometry_intersection_tetrahedron_4.cc
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date creation: Thu Mar 26 2015
+ * @date last modification: Thu Mar 26 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..7659e1f84
--- /dev/null
+++ b/test/test_geometry/test_segment_intersection_triangle_3.cc
@@ -0,0 +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>
+ *
+ * @date creation: Fri Mar 13 2015
+ * @date last modification: Tue june 16 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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/test_dumper/CMakeLists.txt b/test/test_io/test_dumper/CMakeLists.txt
index 382ac234f..954f17636 100644
--- a/test/test_io/test_dumper/CMakeLists.txt
+++ b/test/test_io/test_dumper/CMakeLists.txt
@@ -1,37 +1,38 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author David Simon Kammer <david.kammer@epfl.ch>
#
# @date creation: Tue Sep 02 2014
# @date last modification: Tue Sep 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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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_parser/CMakeLists.txt b/test/test_io/test_parser/CMakeLists.txt
index 8664d094f..06285dee7 100644
--- a/test/test_io/test_parser/CMakeLists.txt
+++ b/test/test_io/test_parser/CMakeLists.txt
@@ -1,36 +1,37 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Wed Nov 13 2013
# @date last modification: Wed Nov 13 2013
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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/input_file.dat b/test/test_io/test_parser/input_file.dat
index 26cce7d3b..e83f1dc28 100644
--- a/test/test_io/test_parser/input_file.dat
+++ b/test/test_io/test_parser/input_file.dat
@@ -1,32 +1,32 @@
seed = 123456
debug_level = 1
material elastic opt1 [
name = toto
E = 1
X135 = 1 + 3* debug_level #toto
# tptp
yop = yop
# a = b
a = c
rules material [
name = toto
E = 1
X135 = 1 + 1 #toto
# tptp
yop = yop
# a = b
]
]
general = 50
toto = 2*pi + max(2, general)
vect = [ 1, 23+2, 5, toto ]
mat = [[ 1, 23+2, 5, toto ],\
- vect ]
+ [ 0, 10, general, 5+8] ]
rand1 = 10 uniform [0.2, 0.5 ]
rand2 = 10 weibull [0.2, 0.5 ]
rand3 = 10
diff --git a/test/test_io/test_parser/test_parser.verified b/test/test_io/test_parser/test_parser.verified
index 4ddbf1b92..570ad7a06 100644
--- a/test/test_io/test_parser/test_parser.verified
+++ b/test/test_io/test_parser/test_parser.verified
@@ -1,44 +1,44 @@
123456==123456
Section(_st_global) global [
Parameters [
+ debug_level: 1 (input_file.dat:2:1)
+ general: 50 (input_file.dat:22:1)
- + mat: [[ 1, 23+2, 5, toto ],vect ] (input_file.dat:27:1)
+ + mat: [[ 1, 23+2, 5, toto ],[ 0, 10, general, 5+8] ] (input_file.dat:27:1)
+ rand1: 10 uniform [0.2, 0.5 ] (input_file.dat:30:1)
+ rand2: 10 weibull [0.2, 0.5 ] (input_file.dat:31:1)
+ rand3: 10 (input_file.dat:32:1)
+ seed: 123456 (input_file.dat:1:1)
+ toto: 2*pi + max(2, general) (input_file.dat:24:1)
+ vect: [ 1, 23+2, 5, toto ] (input_file.dat:26:1)
]
Subsections [
Section(_st_material) elastic opt1 [
Parameters [
+ E: 1 (input_file.dat:5:6)
+ X135: 1 + 3* debug_level (input_file.dat:6:6)
+ a: c (input_file.dat:11:6)
+ name: toto (input_file.dat:4:6)
+ yop: yop (input_file.dat:9:6)
]
Subsections [
Section(_st_rules) material [
Parameters [
+ E: 1 (input_file.dat:15:11)
+ X135: 1 + 1 (input_file.dat:16:11)
+ name: toto (input_file.dat:14:11)
+ yop: yop (input_file.dat:18:11)
]
]
]
]
]
]
56.2832==56.2832
-Vector<double>(4) : [1, 25, 5, 56.2832]
-Matrix<double>(2,4) :[[1, 25, 5, 56.2832], [1, 25, 5, 56.2832]]
+[1, 25, 5, 56.2832]
+[[1, 25, 5, 56.2832], [0, 10, 50, 13]]
10 Uniform [ min=0.2, max=0.5 ]
10 Weibull [ shape=0.5, scale=0.2]
10
diff --git a/test/test_mesh_utils/CMakeLists.txt b/test/test_mesh_utils/CMakeLists.txt
index 5302ae910..1b12b430c 100644
--- a/test/test_mesh_utils/CMakeLists.txt
+++ b/test/test_mesh_utils/CMakeLists.txt
@@ -1,47 +1,49 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Feb 07 2011
# @date last modification: Tue Nov 06 2012
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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_facet_extraction "Test mesh utils facet extraction")
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 DESTINATION
+ FILES_TO_COPY purify_mesh.msh
+ PACKAGE core
)
-add_akantu_test(test_mesh_partitionate "Test mesh partition creation" PACKAGE scotch)
+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
new file mode 100644
index 000000000..ed6eeb2da
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/CMakeLists.txt
@@ -0,0 +1,108 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Marco Vocialta <marco.vocialta@epfl.ch>
+# @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_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_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_8.msh b/test/test_mesh_utils/test_buildfacets/hexahedron_8.msh
new file mode 100644
index 000000000..2db30ac3a
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/hexahedron_8.msh
@@ -0,0 +1,31 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+18
+1 0 0 0
+2 1 0 0
+3 1 1 0
+4 0 1 0
+5 -1 1 0
+6 -1 0 0
+7 -1 -1 0
+8 0 -1 0
+9 1 -1 0
+10 0 0 1
+11 1 0 1
+12 1 1 1
+13 0 1 1
+14 -1 1 1
+15 -1 0 1
+16 -1 -1 1
+17 0 -1 1
+18 1 -1 1
+$EndNodes
+$Elements
+4
+1 5 2 82 75 11 10 13 12 2 1 4 3
+2 5 2 82 77 4 1 10 13 5 6 15 14
+3 5 2 82 79 10 1 8 17 15 6 7 16
+4 5 2 82 81 8 1 10 17 9 2 11 18
+$EndElements
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_20.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
new file mode 100644
index 000000000..8232dff96
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
@@ -0,0 +1,140 @@
+/**
+ * @file test_cohesive_buildfacets_hexahedron_20.cc
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @date Wed Oct 03 10:20:53 2012
+ *
+ * @brief Test to check the building of the facets. Mesh with hexahedrons
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..f65c850af
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
@@ -0,0 +1,141 @@
+/**
+ * @file test_cohesive_buildfacets_hexahedron_8.cc
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @date Wed Oct 03 10:20:53 2012
+ *
+ * @brief Test to check the building of the facets. Mesh with hexahedrons
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..9b3400949
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
@@ -0,0 +1,127 @@
+/**
+ * @file test_cohesive_buildfacets_mixed2d_linear.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 19 10:20:53 2015
+ *
+ * @brief Test to check the building of the facets. Mesh with quadrangles
+ * and triangles
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..3d9f0dd61
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
@@ -0,0 +1,127 @@
+/**
+ * @file test_cohesive_buildfacets_mixed2d_quadratic.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 19 10:20:53 2015
+ *
+ * @brief Test to check the building of the facets. Mesh with quadrangles
+ * and triangles
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..347575b18
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
@@ -0,0 +1,165 @@
+/**
+ * @file test_cohesive_buildfacets_mixed3d_linear.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 18 10:20:53 2015
+ *
+ * @brief Test to check the building of the facets. Mesh with hexahedrons
+ * and pentahedrons
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..082df996c
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
@@ -0,0 +1,167 @@
+/**
+ * @file test_cohesive_buildfacets_mixed3d_quadratic.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 18 10:20:53 2015
+ *
+ * @brief Test to check the building of the facets. Mesh with hexahedrons
+ * and pentahedrons
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..9a2519d54
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
@@ -0,0 +1,146 @@
+/**
+ * @file test_cohesive_buildfacets_hexahedron.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 18 10:20:53 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..573205d65
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
@@ -0,0 +1,146 @@
+/**
+ * @file test_cohesive_buildfacets_hexahedron.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 18 10:20:53 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..81f68854e
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
@@ -0,0 +1,115 @@
+/**
+ * @file test_cohesive_buildfacets_quadrangle_4.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 18 10:20:53 2015
+ *
+ * @brief Test to check the building of the facets. Mesh with quadrangles
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..af1672fbd
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
@@ -0,0 +1,115 @@
+/**
+ * @file test_cohesive_buildfacets_quadrangle_8.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 18 10:20:53 2015
+ *
+ * @brief Test to check the building of the facets. Mesh with quadrangles
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_10.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
new file mode 100644
index 000000000..1fc131813
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
@@ -0,0 +1,141 @@
+/**
+ * @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_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..674405ce2
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
@@ -0,0 +1,115 @@
+/**
+ * @file test_cohesive_buildfacets_triangle_3.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 18 10:20:53 2015
+ *
+ * @brief Test to check the building of the facets. Mesh with triangles
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..fb2fcf5c5
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
@@ -0,0 +1,115 @@
+/**
+ * @file test_cohesive_buildfacets_triangle_6.cc
+ *
+ * @author Mauro Corrado <mauro.corrado@epfl.ch>
+ *
+ * @date Fri Sep 18 10:20:53 2015
+ *
+ * @brief Test to check the building of the facets. Mesh with triangles
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_10.msh b/test/test_mesh_utils/test_buildfacets/tetrahedron_10.msh
new file mode 100644
index 000000000..8dfc3bebf
--- /dev/null
+++ b/test/test_mesh_utils/test_buildfacets/tetrahedron_10.msh
@@ -0,0 +1,80 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+55
+1 1 0 0
+2 0 1 0
+3 0 -1 0
+4 -1 0 0
+5 0.5 0.5 0
+6 0.5 -0.5 0
+7 -0.5 0.5 0
+8 -0.5 -0.5 0
+9 0 0 1
+10 0.2499999999993232 -0.7500000000006768 0
+11 0.7499999999993227 -0.2500000000006773 0
+12 0.7500000000006768 0.2499999999993232 0
+13 0.2500000000006773 0.7499999999993227 0
+14 -0.2499999999993232 0.7500000000006768 0
+15 -0.7499999999993227 0.2500000000006773 0
+16 -0.7500000000006768 -0.2499999999993232 0
+17 -0.2500000000006773 -0.7499999999993227 0
+18 0 -0.5000000000013294 0.4999999999986707
+19 -0.4999999999986707 0 0.5000000000013294
+20 0 0.4999999999986707 0.5000000000013294
+21 0.4999999999986707 0 0.5000000000013294
+22 0 0 0
+23 0 -0.5 0
+24 -0.5 0 0
+25 0 0.5 0
+26 0.5 0 0
+27 -0.5 -0.25 0
+28 -0.75 0 0
+29 -0.25 0.5 0
+30 0 0.75 0
+31 0 -0.75 0
+32 -0.25 -0.5 0
+33 0.25 -0.5 0
+34 -0.5 0.25 0
+35 0.25 0.5 0
+36 0.75 0 0
+37 0.5 -0.25 0
+38 0.5 0.25 0
+39 -0.25 0 0
+40 -0.25 0.25 0
+41 0.25 -0.25 0
+42 0 -0.25 0
+43 -0.25 -0.25 0
+44 0 0.25 0
+45 0.25 0.25 0
+46 0.25 0 0
+47 -0.2500000000000001 -0.2499999999999999 0.5
+48 0.2499999999999999 -0.2500000000000002 0.5000000000000002
+49 0.2500000000000001 0.2499999999999999 0.5
+50 -0.2500000000000001 0.2499999999999999 0.5
+51 0 0 0.5
+52 0.25 0 0.5
+53 0 0.25 0.5
+54 0 -0.25 0.5
+55 -0.25 0 0.5
+$EndNodes
+$Elements
+16
+1 11 2 25 24 22 5 9 26 45 49 51 46 52 38
+2 11 2 25 24 22 9 25 7 51 53 44 40 29 50
+3 11 2 25 24 6 9 1 26 48 21 11 37 36 52
+4 11 2 25 24 9 23 3 8 54 31 18 47 17 32
+5 11 2 25 24 9 23 22 6 54 42 51 48 41 33
+6 11 2 25 24 23 9 3 6 54 18 31 33 10 48
+7 11 2 25 24 9 6 22 26 48 41 51 52 46 37
+8 11 2 25 24 24 9 8 22 55 47 27 39 43 51
+9 11 2 25 24 9 23 8 22 54 32 47 51 43 42
+10 11 2 25 24 9 24 8 4 55 27 47 19 16 28
+11 11 2 25 24 2 9 25 5 20 53 30 13 35 49
+12 11 2 25 24 22 5 25 9 45 35 44 51 53 49
+13 11 2 25 24 9 1 26 5 21 36 52 49 38 12
+14 11 2 25 24 24 9 22 7 55 51 39 34 40 50
+15 11 2 25 24 24 9 7 4 55 50 34 28 15 19
+16 11 2 25 24 9 2 25 7 20 30 53 50 29 14
+$EndElements
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_facet_extraction/CMakeLists.txt b/test/test_mesh_utils/test_facet_extraction/CMakeLists.txt
deleted file mode 100644
index c6a2268e3..000000000
--- a/test/test_mesh_utils/test_facet_extraction/CMakeLists.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-#===============================================================================
-# @file CMakeLists.txt
-#
-# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
-#
-# @date creation: Fri Sep 03 2010
-# @date last modification: Tue Nov 06 2012
-#
-# @brief configuration for facet extraction 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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_facet_square_mesh square.geo 2 2)
-
-register_test(test_facet_extraction_triangle_3
- SOURCES test_facet_extraction_triangle_3.cc
- DEPENDENCIES test_facet_square_mesh
- DIRECTORIES_TO_CREATE paraview
- )
-
-#===============================================================================
-add_mesh(test_facet_cube_mesh cube.geo 3 1)
-
-register_test(test_facet_extraction_tetrahedron_4
- SOURCES test_facet_extraction_tetrahedron_4.cc
- DEPENDENCIES test_facet_cube_mesh
- DIRECTORIES_TO_CREATE paraview
- )
diff --git a/test/test_mesh_utils/test_facet_extraction/cube.geo b/test/test_mesh_utils/test_facet_extraction/cube.geo
deleted file mode 100644
index 415cca7c4..000000000
--- a/test/test_mesh_utils/test_facet_extraction/cube.geo
+++ /dev/null
@@ -1,37 +0,0 @@
-h = 0.1;
-
-Point(1) = {0.0, 0.0, 0.0, h};
-Point(2) = {1.0, 0.0, 0.0, h};
-Point(3) = {0.0, 1.0, 0.0, h};
-Point(4) = {1.0, 1.0, 0.0, h};
-Point(5) = {0.0, 0.0, 1.0, h};
-Point(6) = {1.0, 0.0, 1.0, h};
-Point(7) = {0.0, 1.0, 1.0, h};
-Point(8) = {1.0, 1.0, 1.0, h};
-
-Line(1) = {7, 8};
-Line(2) = {8, 4};
-Line(3) = {4, 3};
-Line(4) = {3, 7};
-Line(5) = {1, 5};
-Line(6) = {5, 6};
-Line(7) = {6, 2};
-Line(8) = {2, 1};
-Line(9) = {3, 1};
-Line(10) = {7, 5};
-Line(11) = {8, 6};
-Line(12) = {4, 2};
-Line Loop(13) = {1, 11, -6, -10};
-Plane Surface(14) = {13};
-Line Loop(15) = {3, 4, 1, 2};
-Plane Surface(16) = {15};
-Line Loop(17) = {6, 7, 8, 5};
-Plane Surface(18) = {17};
-Line Loop(19) = {3, 9, -8, -12};
-Plane Surface(20) = {19};
-Line Loop(21) = {4, 10, -5, -9};
-Plane Surface(22) = {21};
-Line Loop(23) = {11, 7, -12, -2};
-Plane Surface(24) = {23};
-Surface Loop(25) = {24, 14, 16, 20, 22, 18};
-Volume(26) = {25};
diff --git a/test/test_mesh_utils/test_facet_extraction/square.geo b/test/test_mesh_utils/test_facet_extraction/square.geo
deleted file mode 100644
index 33d1d3cc2..000000000
--- a/test/test_mesh_utils/test_facet_extraction/square.geo
+++ /dev/null
@@ -1,11 +0,0 @@
-Point(1) = {0.0, 0.0, 0.0, .5};
-Point(2) = {1.0, 0.0, 0.0, .5};
-Point(3) = {0.0, 1.0, 0.0, .5};
-Point(4) = {1.0, 1.0, 0.0, .5};
-
-Line(1) = {1, 2};
-Line(2) = {2, 4};
-Line(3) = {4, 3};
-Line(4) = {3, 1};
-Line Loop(1) = {1, 2, 3, 4};
-Plane Surface(1) = {1};
diff --git a/test/test_mesh_utils/test_facet_extraction/test_facet_extraction_tetrahedron_4.cc b/test/test_mesh_utils/test_facet_extraction/test_facet_extraction_tetrahedron_4.cc
deleted file mode 100644
index e7ab326b1..000000000
--- a/test/test_mesh_utils/test_facet_extraction/test_facet_extraction_tetrahedron_4.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * @file test_facet_extraction_tetrahedron_4.cc
- *
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date creation: Fri Sep 03 2010
- * @date last modification: Tue Jan 07 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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 "mesh_utils.hh"
-#include "solid_mechanics_model.hh"
-#include "material.hh"
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-# include "dumper_paraview.hh"
-#endif //AKANTU_USE_IOHELPER
-
-using namespace akantu;
-
-int main(int argc, char *argv[])
-{
- akantu::initialize(argc, argv);
- int dim = 3;
-
- Mesh mesh(dim);
- MeshIOMSH mesh_io;
- mesh_io.read("cube.msh", mesh);
- Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
-
- MeshUtils::buildAllFacets(mesh, mesh_facets);
-
-#ifdef AKANTU_USE_IOHELPER
- DumperParaview dumper1("test-facet-extraction");
- dumper1.registerMesh(mesh, dim);
- dumper1.dump();
-
- DumperParaview dumper2("test-facet-extraction_boundary");
- dumper2.registerMesh(mesh, dim - 1);
- dumper2.dump();
-
- DumperParaview dumper3("test-facet-extraction_internal");
- dumper3.registerMesh(mesh_facets, dim);
- dumper3.dump();
-#endif //AKANTU_USE_IOHELPER
-
- akantu::finalize();
- return EXIT_SUCCESS;
-}
diff --git a/test/test_mesh_utils/test_facet_extraction/test_facet_extraction_triangle_3.cc b/test/test_mesh_utils/test_facet_extraction/test_facet_extraction_triangle_3.cc
deleted file mode 100644
index 5bf0d5d8f..000000000
--- a/test/test_mesh_utils/test_facet_extraction/test_facet_extraction_triangle_3.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file test_facet_extraction_triangle_3.cc
- *
- * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date creation: Fri Sep 03 2010
- * @date last modification: Tue Jan 07 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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 "material.hh"
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-# include "dumper_paraview.hh"
-#endif //AKANTU_USE_IOHELPER
-
-using namespace akantu;
-
-int main(int argc, char *argv[])
-{
- akantu::initialize(argc, argv);
- const ElementType type = _triangle_6;
- int dim = ElementClass<type>::getSpatialDimension();
-
- Mesh mesh(dim);
- mesh.read("square.msh");
- Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
-
- MeshUtils::buildAllFacets(mesh, mesh_facets);
-
-#ifdef AKANTU_USE_IOHELPER
- DumperParaview dumper1("test-facet-extraction");
- dumper1.registerMesh(mesh, dim);
- dumper1.dump();
-
- DumperParaview dumper2("test-facet-extraction_boundary");
- dumper2.registerMesh(mesh, dim - 1);
- dumper2.dump();
-
- DumperParaview dumper3("test-facet-extraction_internal");
- dumper3.registerMesh(mesh_facets, dim);
- dumper3.dump();
-#endif //AKANTU_USE_IOHELPER
- akantu::finalize();
- return EXIT_SUCCESS;
-}
diff --git a/test/test_mesh_utils/test_mesh_io/CMakeLists.txt b/test/test_mesh_utils/test_mesh_io/CMakeLists.txt
index c46da6a3e..f6ab66dbb 100644
--- a/test/test_mesh_utils/test_mesh_io/CMakeLists.txt
+++ b/test/test_mesh_utils/test_mesh_io/CMakeLists.txt
@@ -1,52 +1,54 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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_partitionate/CMakeLists.txt b/test/test_mesh_utils/test_mesh_partitionate/CMakeLists.txt
index adf742384..9cbdc984a 100644
--- a/test/test_mesh_utils/test_mesh_partitionate/CMakeLists.txt
+++ b/test/test_mesh_utils/test_mesh_partitionate/CMakeLists.txt
@@ -1,50 +1,52 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Fri Sep 03 2010
# @date last modification: Wed May 08 2013
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
- DIRECTORIES_TO_CREATE paraview)
+ DEPENDS test_mesh_partitionate_mesh_data_mesh
+ DIRECTORIES_TO_CREATE paraview
+ PACKAGE scotch
+ )
diff --git a/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc b/test/test_mesh_utils/test_mesh_partitionate/test_mesh_partitionate_mesh_data.cc
index 03f152f39..ad680a112 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,107 +1,116 @@
/**
* @file test_mesh_partitionate_mesh_data.cc
*
* @author Dana Christen <dana.christen@epfl.ch>
*
* @date creation: Wed May 08 2013
* @date last modification: Fri Sep 05 2014
*
* @brief test of manual partitioner
*
* @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 <cmath>
/* -------------------------------------------------------------------------- */
#include "aka_common.hh"
#include "mesh.hh"
#include "mesh_partition_mesh_data.hh"
/* -------------------------------------------------------------------------- */
#ifdef AKANTU_USE_IOHELPER
# include "dumper_paraview.hh"
#include "dumper_elemental_field.hh"
#endif //AKANTU_USE_IOHELPER
using namespace akantu;
/* -------------------------------------------------------------------------- */
/* Main */
/* -------------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
initialize(argc, argv);
UInt dim = 2;
UInt nb_partitions = 8;
akantu::Mesh mesh(dim);
mesh.read("quad.msh");
+
ElementTypeMapArray<UInt> partition;
UInt nb_component = 1;
+
GhostType gt = _not_ghost;
Mesh::type_iterator tit = mesh.firstType(dim, gt);
Mesh::type_iterator tend = mesh.lastType(dim, gt);
for(; tit != tend; ++tit) {
UInt nb_element = mesh.getNbElement(*tit, gt);
partition.alloc(nb_element, nb_component, *tit, gt);
Array<UInt> & type_partition_reference = partition(*tit, gt);
for(UInt i(0); i < nb_element; ++i) {
Real barycenter[dim];
mesh.getBarycenter(i, *tit, barycenter, gt);
Real real_proc = barycenter[0] * nb_partitions;
- if(real_proc-round(real_proc) < 10*std::numeric_limits<Real>::min()) {
+ if(std::abs(real_proc - round(real_proc)) < 10*std::numeric_limits<Real>::epsilon()) {
type_partition_reference(i) = round(real_proc);
} else {
std::cout << "*";
type_partition_reference(i) = floor(real_proc);
}
std::cout << "Assigned proc " << type_partition_reference(i) << " to elem " << i << " (type " << *tit << ", barycenter x-coordinate " << barycenter[0] << ")" << std::endl;
}
}
+
akantu::MeshPartitionMeshData * partitioner = new akantu::MeshPartitionMeshData(mesh, dim);
partitioner->setPartitionMapping(partition);
partitioner->partitionate(nb_partitions);
tit = mesh.firstType(dim, gt);
for(; tit != tend; ++tit) {
UInt nb_element = mesh.getNbElement(*tit, gt);
const Array<UInt> & type_partition_reference = partition(*tit, gt);
const Array<UInt> & type_partition = partitioner->getPartitions()(*tit, gt);
for(UInt i(0); i < nb_element; ++i) {
AKANTU_DEBUG_ASSERT(type_partition(i) == type_partition_reference(i), "Incorrect partitioning");
}
}
-#ifdef AKANTU_USE_IOHELPER
+ //#define DEBUG_TEST
+
+#ifdef DEBUG_TEST
DumperParaview dumper("test-mesh-data-partition");
- dumper::Field * field =
+ dumper::Field * field1 =
new dumper::ElementalField<UInt>(partitioner->getPartitions(), dim);
+ dumper::Field * field2 =
+ new dumper::ElementalField<UInt>(partition, dim);
dumper.registerMesh(mesh, dim);
- dumper.registerField("partitions", field);
+ dumper.registerField("partitions" , field1);
+ dumper.registerField("partitions_ref", field2);
dumper.dump();
-#endif //AKANTU_USE_IOHELPER
+#endif
+
delete partitioner;
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 adccbee1b..cdcb5fde8 100644
--- a/test/test_mesh_utils/test_pbc_tweak/CMakeLists.txt
+++ b/test/test_mesh_utils/test_pbc_tweak/CMakeLists.txt
@@ -1,41 +1,42 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Wed Feb 09 2011
# @date last modification: Tue Nov 06 2012
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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_segment_nodetype/CMakeLists.txt b/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt
new file mode 100644
index 000000000..3c711cad5
--- /dev/null
+++ b/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt
@@ -0,0 +1,5 @@
+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..aa36e6111
--- /dev/null
+++ b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
@@ -0,0 +1,104 @@
+/**
+ * @file test_segment_nodetype.cc
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @date Fri Sep 18 13:39:35 2015
+ *
+ * @brief Test to verify that the node type is correctly associated to
+ * the segments in parallel
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..723b4a48e
--- /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 cf67ddfc0..5bbd78924 100644
--- a/test/test_model/CMakeLists.txt
+++ b/test/test_model/CMakeLists.txt
@@ -1,37 +1,38 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Fri Nov 26 2010
# @date last modification: Thu Jul 03 2014
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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" PACKAGE core)
-add_akantu_test(test_heat_transfer_model "Test for the heat transfer model" PACKAGE heat_transfer)
-add_akantu_test(test_structural_mechanics_model "Test for the structural mechanics model" PACKAGE structural_mechanics)
\ No newline at end of file
+add_akantu_test(test_solid_mechanics_model "Test for the solid mechanics model")
+add_akantu_test(test_heat_transfer_model "Test for the heat transfer model")
+add_akantu_test(test_structural_mechanics_model "Test for the structural mechanics model")
+add_akantu_test(test_non_local_toolbox "Test of the functionalities in the non-local toolbox")
\ No newline at end of file
diff --git a/test/test_model/test_heat_transfer_model/CMakeLists.txt b/test/test_model/test_heat_transfer_model/CMakeLists.txt
index 3a546e227..a16a1ef44 100644
--- a/test/test_model/test_heat_transfer_model/CMakeLists.txt
+++ b/test/test_model/test_heat_transfer_model/CMakeLists.txt
@@ -1,75 +1,88 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Sun May 01 2011
# @date last modification: Tue Nov 06 2012
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
+ 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_square2d_implicit.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_implicit.cc
new file mode 100644
index 000000000..1703742e6
--- /dev/null
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d_implicit.cc
@@ -0,0 +1,93 @@
+/**
+ * @file test_heat_transfer_model_square2d.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 "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_non_local_toolbox/CMakeLists.txt b/test/test_model/test_non_local_toolbox/CMakeLists.txt
new file mode 100644
index 000000000..1e9b80be3
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/CMakeLists.txt
@@ -0,0 +1,74 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
+#
+# @date creation: Sun May 01 2011
+# @date last modification: Tue Nov 06 2012
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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..864920a23
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
@@ -0,0 +1,184 @@
+/**
+ * @file test_build_neighborhood_parallel.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Sun Oct 11 11:20:23 2015
+ *
+ * @brief test in parallel for the class NonLocalNeighborhood
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..c73a76737
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_material.cc
@@ -0,0 +1,122 @@
+/**
+ * @file test_material.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Sep 23 17:16:30 2015
+ *
+ * @brief Implementation of test material for the non-local neighborhood base test
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..b8785f23e
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_material.hh
@@ -0,0 +1,75 @@
+/**
+ * @file test_material.hh
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Sep 23 17:16:30 2015
+ *
+ * @brief test material for the non-local neighborhood base test
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "material_damage.hh"
+#include "material_non_local.hh"
+
+#ifndef __TEST_MATERIAL_HH__
+#define __TEST_MATERIAL_HH__
+
+__BEGIN_AKANTU__
+
+template<UInt dim>
+class TestMaterial : public MaterialDamage<dim, MaterialElastic>,
+ public MaterialNonLocal<dim>{
+
+/* -------------------------------------------------------------------------- */
+/* Constructor/Destructor */
+/* -------------------------------------------------------------------------- */
+
+public:
+
+ TestMaterial(SolidMechanicsModel & model, const ID & id);
+ virtual ~TestMaterial() {};
+ typedef MaterialNonLocal<dim> MyNonLocalParent;
+ typedef MaterialDamage<dim, MaterialElastic> MyLocalParent;
+/* -------------------------------------------------------------------------- */
+/* Methods */
+/* -------------------------------------------------------------------------- */
+public:
+ void initMaterial();
+
+ void computeNonLocalStresses(GhostType ghost_type) {};
+
+ void insertQuadsInNeighborhoods(GhostType ghost_type);
+
+ virtual void registerNeighborhood();
+
+protected:
+
+/* -------------------------------------------------------------------------- */
+/* Members */
+/* -------------------------------------------------------------------------- */
+private:
+ InternalField<Real> grad_u_nl;
+
+};
+
+__END_AKANTU__
+
+#endif /* __TEST_MATERIAL_HH__ */
diff --git a/test/test_model/test_non_local_toolbox/test_material_damage.cc b/test/test_model/test_non_local_toolbox/test_material_damage.cc
new file mode 100644
index 000000000..a527bfd89
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_material_damage.cc
@@ -0,0 +1,113 @@
+/**
+ * @file test_material.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Sep 23 17:16:30 2015
+ *
+ * @brief Implementation of test material damage
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..3e60157c5
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_material_damage.hh
@@ -0,0 +1,76 @@
+/**
+ * @file test_material_damage.hh
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Sep 23 17:16:30 2015
+ *
+ * @brief test material damage for the non-local remove damage test
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "material_damage.hh"
+#include "material_non_local.hh"
+
+#ifndef __TEST_MATERIAL_DAMAGE_HH__
+#define __TEST_MATERIAL_DAMAGE_HH__
+
+__BEGIN_AKANTU__
+
+template<UInt dim>
+class TestMaterialDamage : public MaterialDamage<dim, MaterialElastic>,
+ public MaterialNonLocal<dim> {
+
+/* -------------------------------------------------------------------------- */
+/* Constructor/Destructor */
+/* -------------------------------------------------------------------------- */
+
+public:
+
+ TestMaterialDamage(SolidMechanicsModel & model, const ID & id);
+ virtual ~TestMaterialDamage() {};
+ typedef MaterialNonLocal<dim> MyNonLocalParent;
+
+/* -------------------------------------------------------------------------- */
+/* Methods */
+/* -------------------------------------------------------------------------- */
+public:
+ void initMaterial();
+
+ //void computeNonLocalStress(ElementType type, GhostType ghost_type = _not_ghost);
+
+ void computeNonLocalStresses(GhostType ghost_type) {};
+
+ void insertQuadsInNeighborhoods(GhostType ghost_type);
+
+protected:
+
+
+/* -------------------------------------------------------------------------- */
+/* Members */
+/* -------------------------------------------------------------------------- */
+private:
+ InternalField<Real> grad_u_nl;
+
+};
+
+__END_AKANTU__
+
+#endif /* __TEST_MATERIAL_DAMAGE_HH__ */
diff --git a/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc b/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
new file mode 100644
index 000000000..ac28176bb
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_non_local_averaging.cc
@@ -0,0 +1,109 @@
+/**
+ * @file test_weight_computation.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Sep 23 16:30:12 2015
+ *
+ * @brief test for non-local averaging of strain
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..7a33c6db5
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_non_local_neighborhood_base.cc
@@ -0,0 +1,86 @@
+/**
+ * @file test_non_local_neighborhood_base.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Sep 23 16:30:12 2015
+ *
+ * @brief test for the class NonLocalNeighborhoodBase
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..f8b955f44
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
@@ -0,0 +1,216 @@
+/**
+ * @file test_pair_computation.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Tue Nov 24 10:33:55 2015
+ *
+ * @brief test the weight computation with and without grid
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..a342c6adf
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_remove_damage_weight_function.cc
@@ -0,0 +1,179 @@
+/**
+ * @file test_remove_damage_weight_function.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Tue Oct 6 14:32:43 2015
+ *
+ * @brief test the weight function that ignores fully damaged elements
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#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..95fd780f0
--- /dev/null
+++ b/test/test_model/test_non_local_toolbox/test_weight_computation.cc
@@ -0,0 +1,72 @@
+/**
+ * @file test_weight_computation.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Sep 23 16:30:12 2015
+ *
+ * @brief test for the weight computation with base weight function
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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 0d6bdd76e..afd8b09d7 100644
--- a/test/test_model/test_solid_mechanics_model/CMakeLists.txt
+++ b/test/test_model/test_solid_mechanics_model/CMakeLists.txt
@@ -1,197 +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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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" PACKAGE cohesive_element)
-add_akantu_test(test_contact "test_contact" PACKAGE dead_contact)
+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
)
#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_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/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/material_selector.dat b/test/test_model/test_solid_mechanics_model/material_selector.dat
new file mode 100644
index 000000000..b7ecb2831
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/material_selector.dat
@@ -0,0 +1,14 @@
+material elastic [
+ name = chocolate
+ E = 2
+]
+
+material elastic [
+ name = chewing-gum
+ E = 1
+]
+
+material elastic [
+ name = candy
+ E = 3
+]
diff --git a/test/test_model/test_solid_mechanics_model/material_selector.geo b/test/test_model/test_solid_mechanics_model/material_selector.geo
new file mode 100644
index 000000000..f09b4d68d
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/material_selector.geo
@@ -0,0 +1,10 @@
+Point(1) = {0, 0, 0, 1};
+Point(2) = {1, 0, 0, 1};
+Point(3) = {2, 0, 0, 1};
+Point(4) = {3, 0, 0, 1};
+Line(5) = {1, 2};
+Line(6) = {2, 3};
+Line(7) = {3, 4};
+Physical Line("chocolate") = {5};
+Physical Line("chewing-gum") = {6};
+Physical Line("candy") = {7};
diff --git a/test/test_model/test_solid_mechanics_model/material_selector.msh b/test/test_model/test_solid_mechanics_model/material_selector.msh
new file mode 100644
index 000000000..afb5cdac7
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/material_selector.msh
@@ -0,0 +1,22 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$PhysicalNames
+3
+1 1 "chocolate"
+1 2 "chewing-gum"
+1 3 "candy"
+$EndPhysicalNames
+$Nodes
+4
+1 0 0 0
+2 1 0 0
+3 2 0 0
+4 3 0 0
+$EndNodes
+$Elements
+3
+1 1 2 1 5 1 2
+2 1 2 2 6 2 3
+3 1 2 3 7 3 4
+$EndElements
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 9124c9f9b..028cb1798 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,64 +1,67 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
-# pentahedron_6
+ 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" PACKAGE core)
-add_akantu_test(implicit "Implicit patch tests" PACKAGE implicit)
+add_akantu_test(explicit "Explicit patch tests")
+add_akantu_test(implicit "Implicit patch tests")
-add_akantu_test(lumped_mass "Test the mass lumping" PACKAGE core)
\ No newline at end of file
+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 f6018b607..aa0955831 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,166 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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.getPotentialEnergy();
- akantu::Real ekin = model.getKineticEnergy();
+ 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/_hexahedron_20.msh b/test/test_model/test_solid_mechanics_model/patch_tests/data/_hexahedron_20.msh
new file mode 100644
index 000000000..8b3304b52
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/_hexahedron_20.msh
@@ -0,0 +1,154 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+81
+1 -0.5 -0.5 -0.5
+2 0.5 -0.5 -0.5
+3 -0.5 0.5 -0.5
+4 0.5 0.5 -0.5
+5 -0.5 -0.5 0.5
+6 0.5 -0.5 0.5
+7 0.5 0.5 0.5
+8 -0.5 0.5 0.5
+9 0 -0.5 -0.5
+10 -0.2499999999999021 -0.5 -0.5
+11 0.25 -0.5 -0.5
+12 0 0.5 -0.5
+13 -0.2499999999999021 0.5 -0.5
+14 0.25 0.5 -0.5
+15 -0.5 0 -0.5
+16 -0.5 -0.2499999999999021 -0.5
+17 -0.5 0.25 -0.5
+18 0.5 0 -0.5
+19 0.5 -0.2499999999999021 -0.5
+20 0.5 0.25 -0.5
+21 0 -0.5 0.5
+22 -0.2499999999999021 -0.5 0.5
+23 0.25 -0.5 0.5
+24 0.5 0 0.5
+25 0.5 -0.2499999999999021 0.5
+26 0.5 0.25 0.5
+27 0 0.5 0.5
+28 0.2499999999999021 0.5 0.5
+29 -0.25 0.5 0.5
+30 -0.5 0 0.5
+31 -0.5 0.2499999999999021 0.5
+32 -0.5 -0.25 0.5
+33 -0.5 -0.5 0
+34 -0.5 -0.5 -0.2499999999999021
+35 -0.5 -0.5 0.25
+36 0.5 -0.5 0
+37 0.5 -0.5 -0.2499999999999021
+38 0.5 -0.5 0.25
+39 0.5 0.5 0
+40 0.5 0.5 -0.2499999999999021
+41 0.5 0.5 0.25
+42 -0.5 0.5 0
+43 -0.5 0.5 -0.2499999999999021
+44 -0.5 0.5 0.25
+45 0 0 -0.5
+46 0 -0.25 -0.5
+47 -0.25 0 -0.5
+48 0 0.25 -0.5
+49 0.25 0 -0.5
+50 0 -0.5 0
+51 0 -0.5 -0.25
+52 -0.25 -0.5 0
+53 0 -0.5 0.25
+54 0.25 -0.5 0
+55 0.5 0 0
+56 0.5 0 -0.25
+57 0.5 -0.25 0
+58 0.5 0 0.25
+59 0.5 0.25 0
+60 0 0.5 0
+61 -0.25 0.5 0
+62 0 0.5 -0.25
+63 0 0.5 0.25
+64 0.25 0.5 0
+65 -0.5 0 0
+66 -0.5 -0.25 0
+67 -0.5 0 -0.25
+68 -0.5 0 0.25
+69 -0.5 0.25 0
+70 0 0 0.5
+71 0 -0.25 0.5
+72 -0.25 0 0.5
+73 0 0.25 0.5
+74 0.25 0 0.5
+75 0 0 0
+76 0 0 -0.25
+77 0 -0.25 0
+78 -0.25 0 0
+79 0 0 0.25
+80 0 0.25 0
+81 0.25 0 0
+$EndNodes
+$Elements
+64
+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 10 7
+8 15 2 0 14 8
+9 8 2 0 1 1 9 10
+10 8 2 0 1 9 2 11
+11 8 2 0 2 3 12 13
+12 8 2 0 2 12 4 14
+13 8 2 0 3 1 15 16
+14 8 2 0 3 15 3 17
+15 8 2 0 4 2 18 19
+16 8 2 0 4 18 4 20
+17 8 2 0 7 5 21 22
+18 8 2 0 7 21 6 23
+19 8 2 0 8 6 24 25
+20 8 2 0 8 24 7 26
+21 8 2 0 9 7 27 28
+22 8 2 0 9 27 8 29
+23 8 2 0 10 8 30 31
+24 8 2 0 10 30 5 32
+25 8 2 0 12 1 33 34
+26 8 2 0 12 33 5 35
+27 8 2 0 13 2 36 37
+28 8 2 0 13 36 6 38
+29 8 2 0 17 4 39 40
+30 8 2 0 17 39 7 41
+31 8 2 0 21 3 42 43
+32 8 2 0 21 42 8 44
+33 16 2 0 5 1 9 45 15 10 46 47 16
+34 16 2 0 5 15 45 12 3 47 48 13 17
+35 16 2 0 5 9 2 18 45 11 19 49 46
+36 16 2 0 5 45 18 4 12 49 20 14 48
+37 16 2 0 14 1 9 50 33 10 51 52 34
+38 16 2 0 14 33 50 21 5 52 53 22 35
+39 16 2 0 14 9 2 36 50 11 37 54 51
+40 16 2 0 14 50 36 6 21 54 38 23 53
+41 16 2 0 18 2 18 55 36 19 56 57 37
+42 16 2 0 18 36 55 24 6 57 58 25 38
+43 16 2 0 18 18 4 39 55 20 40 59 56
+44 16 2 0 18 55 39 7 24 59 41 26 58
+45 16 2 0 22 3 42 60 12 43 61 62 13
+46 16 2 0 22 42 8 27 60 44 29 63 61
+47 16 2 0 22 12 60 39 4 62 64 40 14
+48 16 2 0 22 60 27 7 39 63 28 41 64
+49 16 2 0 26 1 33 65 15 34 66 67 16
+50 16 2 0 26 33 5 30 65 35 32 68 66
+51 16 2 0 26 15 65 42 3 67 69 43 17
+52 16 2 0 26 65 30 8 42 68 31 44 69
+53 16 2 0 27 5 21 70 30 22 71 72 32
+54 16 2 0 27 30 70 27 8 72 73 29 31
+55 16 2 0 27 21 6 24 70 23 25 74 71
+56 16 2 0 27 70 24 7 27 74 26 28 73
+57 17 2 0 1 1 9 45 15 33 50 75 65 10 16 34 46 51 47 76 67 52 66 77 78
+58 17 2 0 1 33 50 75 65 5 21 70 30 52 66 35 77 53 78 79 68 22 32 71 72
+59 17 2 0 1 15 45 12 3 65 75 60 42 47 17 67 48 76 13 62 43 78 69 80 61
+60 17 2 0 1 65 75 60 42 30 70 27 8 78 69 68 80 79 61 63 44 72 31 73 29
+61 17 2 0 1 9 2 18 45 50 36 55 75 11 46 51 19 37 49 56 76 54 77 57 81
+62 17 2 0 1 50 36 55 75 21 6 24 70 54 77 53 57 38 81 58 79 23 71 25 74
+63 17 2 0 1 45 18 4 12 75 55 39 60 49 48 76 20 56 14 40 62 81 80 59 64
+64 17 2 0 1 75 55 39 60 70 24 7 27 81 80 79 59 58 64 41 63 74 73 26 28
+$EndElements
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
new file mode 100644
index 000000000..dae9d7e52
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/_pentahedron_15.msh
@@ -0,0 +1,182 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+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.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.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.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 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 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 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/_pentahedron_6.msh b/test/test_model/test_solid_mechanics_model/patch_tests/data/_pentahedron_6.msh
new file mode 100644
index 000000000..342fde160
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/_pentahedron_6.msh
@@ -0,0 +1,116 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+27
+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 1 0.4000000004956805 1
+11 0.5999999995046822 1 1
+12 0 0.5999999995046822 1
+13 0.4000000004956805 0 0
+14 1 0.4000000004956805 0
+15 0.5999999995046822 1 0
+16 0 0.5999999995046822 0
+17 0 0 0.5999999995046822
+18 0 1 0.4000000004956805
+19 1 0 0.5999999995046822
+20 1 1 0.4000000004956805
+21 0.4800000001984172 0.5199999998019453 1
+22 1 0.4000000004956805 0.5199999998019454
+23 0.5199999998020179 0.5199999998019454 0
+24 0 0.5999999995046822 0.4800000001983448
+25 0.5999999995046822 1 0.4000000004956805
+26 0.4000000004956805 0 0.5999999995046822
+27 0.4960000000596703 0.5199999998019451 0.4960000000596124
+$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 5 9
+10 1 2 0 1 9 6
+11 1 2 0 2 6 10
+12 1 2 0 2 10 7
+13 1 2 0 3 7 11
+14 1 2 0 3 11 8
+15 1 2 0 4 8 12
+16 1 2 0 4 12 5
+17 1 2 0 5 1 13
+18 1 2 0 5 13 2
+19 1 2 0 6 2 14
+20 1 2 0 6 14 3
+21 1 2 0 7 3 15
+22 1 2 0 7 15 4
+23 1 2 0 8 4 16
+24 1 2 0 8 16 1
+25 1 2 0 9 5 17
+26 1 2 0 9 17 1
+27 1 2 0 10 4 18
+28 1 2 0 10 18 8
+29 1 2 0 11 6 19
+30 1 2 0 11 19 2
+31 1 2 0 12 3 20
+32 1 2 0 12 20 7
+33 2 2 0 22 3 15 20
+34 2 2 0 22 15 25 20
+35 2 2 0 22 15 18 25
+36 2 2 0 22 18 15 4
+37 2 2 0 22 20 11 7
+38 2 2 0 22 11 20 25
+39 2 2 0 22 25 18 11
+40 2 2 0 22 18 8 11
+41 2 2 0 24 5 17 9
+42 2 2 0 24 9 17 26
+43 2 2 0 24 9 26 19
+44 2 2 0 24 19 6 9
+45 2 2 0 24 17 1 13
+46 2 2 0 24 13 26 17
+47 2 2 0 24 26 13 19
+48 2 2 0 24 19 13 2
+49 3 2 0 14 5 9 21 12
+50 3 2 0 14 12 21 11 8
+51 3 2 0 14 9 6 10 21
+52 3 2 0 14 21 10 7 11
+53 3 2 0 16 6 19 22 10
+54 3 2 0 16 10 22 20 7
+55 3 2 0 16 19 2 14 22
+56 3 2 0 16 22 14 3 20
+57 3 2 0 18 4 15 23 16
+58 3 2 0 18 15 3 14 23
+59 3 2 0 18 16 23 13 1
+60 3 2 0 18 23 14 2 13
+61 3 2 0 20 8 18 24 12
+62 3 2 0 20 18 4 16 24
+63 3 2 0 20 12 24 17 5
+64 3 2 0 20 24 16 1 17
+65 6 2 0 26 17 5 9 24 12 21
+66 6 2 0 26 9 26 17 21 27 24
+67 6 2 0 26 24 12 21 18 8 11
+68 6 2 0 26 21 27 24 11 25 18
+69 6 2 0 26 26 9 6 27 21 10
+70 6 2 0 26 6 19 26 10 22 27
+71 6 2 0 26 27 21 10 25 11 7
+72 6 2 0 26 10 22 27 7 20 25
+73 6 2 0 26 1 17 26 16 24 27
+74 6 2 0 26 26 13 1 27 23 16
+75 6 2 0 26 16 24 27 4 18 25
+76 6 2 0 26 27 23 16 25 15 4
+77 6 2 0 26 13 26 19 23 27 22
+78 6 2 0 26 19 2 13 22 14 23
+79 6 2 0 26 23 27 22 15 25 20
+80 6 2 0 26 22 14 23 20 3 15
+$EndElements
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/data/material_anisotropic.dat b/test/test_model/test_solid_mechanics_model/patch_tests/data/material_anisotropic.dat
new file mode 100644
index 000000000..550237ab4
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/data/material_anisotropic.dat
@@ -0,0 +1,36 @@
+material elastic_anisotropic [
+ name = aluminum
+ rho = 1.6465129043044597 #gramm/mol/Å
+ C11 = 105.092023 #eV/Å^3
+ C12 = 59.4637759
+ C13 = 59.4637759
+ C14 = -9.47874286e-11
+ C15 = -9.34769857e-10
+ C16 = -3.49522561e-10
+
+ C22 = 105.092023
+ C23 = 59.4637759
+ C24 = -1.33279629e-10
+ C25 = 6.52290813e-11
+ C26 = -1.36100714e-10
+
+ C33 = 105.092023
+ C34 = 1.410383e-10
+ C35 = -3.02540691e-13
+ C36 = -8.72969656e-11
+
+ C44 = 30.6596356
+ C45 = 2.20340964e-11
+ C46 = -2.62259488e-10
+
+ C55 = 30.6596356
+ C56 = 8.56508319e-11
+
+ C66 = 30.6596356
+
+ n1 = [-1, 1, 0]
+ n2 = [ 1, 1, 1]
+ n3 = [ 1, 1, -2]
+
+# alpha = 1e-3 # viscous proportion useless unless manually activated in material_elastic_linear_anisotropic.cc
+]
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 9e8649a12..a110d27dc 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,67 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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 extra_materials
+ 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 82d0c5a1c..a9c2b30c1 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,279 +1,290 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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()/5.;
+ 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.getKineticEnergy(); ekin_mean += ekin;
+ 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
new file mode 100644
index 000000000..3e63a6c51
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit_anisotropic.cc
@@ -0,0 +1,302 @@
+/**
+ * @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
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <iostream>
+
+#include "solid_mechanics_model.hh"
+
+using namespace akantu;
+
+Real alpha [3][4] = { { 0.01, 0.02, 0.03, 0.04 },
+ { 0.05, 0.06, 0.07, 0.08 },
+ { 0.09, 0.10, 0.11, 0.12 } };
+
+//Stiffness tensor, rotated by hand
+Real C[3][3][3][3] = {{{{112.93753505, 1.85842452538e-10, -4.47654358027e-10},
+ {1.85847317471e-10, 54.2334345331, -3.69840984824},
+ {-4.4764768395e-10, -3.69840984824, 56.848605217}},
+ {{1.85847781609e-10, 25.429294233, -3.69840984816},
+ {25.429294233, 3.31613847493e-10, -8.38797920011e-11},
+ {-3.69840984816, -8.38804581349e-11, -1.97875715813e-10}},
+ {{-4.47654358027e-10, -3.69840984816, 28.044464917},
+ {-3.69840984816, 2.09374961813e-10, 9.4857455224e-12},
+ {28.044464917, 9.48308098714e-12, -2.1367885239e-10}}},
+ {{{1.85847781609e-10, 25.429294233, -3.69840984816},
+ {25.429294233, 3.31613847493e-10, -8.38793479119e-11},
+ {-3.69840984816, -8.38795699565e-11, -1.97876381947e-10}},
+ {{54.2334345331, 3.31617400207e-10, 2.09372075233e-10},
+ {3.3161562385e-10, 115.552705733, -3.15093728886e-10},
+ {2.09372075233e-10, -3.15090176173e-10, 54.2334345333}},
+ {{-3.69840984824, -8.38795699565e-11, 9.48219280872e-12},
+ {-8.38795699565e-11, -3.1509195253e-10, 25.4292942335},
+ {9.48441325477e-12, 25.4292942335, 3.69840984851}}},
+ {{{-4.47653469848e-10, -3.69840984816, 28.044464917},
+ {-3.69840984816, 2.09374073634e-10, 9.48752187924e-12},
+ {28.044464917, 9.48552347779e-12, -2.1367885239e-10}},
+ {{-3.69840984824, -8.3884899027e-11, 9.48219280872e-12},
+ {-8.3884899027e-11, -3.150972816e-10, 25.4292942335},
+ {9.48041645188e-12, 25.4292942335, 3.69840984851}},
+ {{56.848605217, -1.97875493768e-10, -2.13681516925e-10},
+ {-1.97877270125e-10, 54.2334345333, 3.69840984851},
+ {-2.13683293282e-10, 3.69840984851, 112.93753505}}}};
+
+
+
+/* -------------------------------------------------------------------------- */
+template<ElementType type>
+static Matrix<Real> prescribed_grad_u() {
+ UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
+ Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
+
+ for (UInt i = 0; i < spatial_dimension; ++i) {
+ for (UInt j = 0; j < spatial_dimension; ++j) {
+ grad_u(i, j) = alpha[i][j + 1];
+ }
+ }
+ return grad_u;
+}
+
+template<ElementType type>
+static Matrix<Real> prescribed_stress() {
+ UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
+ Matrix<Real> stress(spatial_dimension, spatial_dimension);
+
+ //plane strain in 2d
+ Matrix<Real> strain(spatial_dimension, spatial_dimension);
+ Matrix<Real> pstrain; pstrain = prescribed_grad_u<type>();
+ Real trace = 0;
+
+ /// symetric part of the strain tensor
+ for (UInt i = 0; i < spatial_dimension; ++i)
+ for (UInt j = 0; j < spatial_dimension; ++j)
+ strain(i,j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
+
+
+ for (UInt i = 0; i < spatial_dimension; ++i) trace += strain(i,i);
+
+ for (UInt i = 0 ; i < spatial_dimension ; ++i) {
+ for (UInt j = 0 ; j < spatial_dimension ; ++j) {
+ stress(i, j) = 0;
+ for (UInt k = 0 ; k < spatial_dimension ; ++k) {
+ for (UInt l = 0 ; l < spatial_dimension ; ++l) {
+ stress(i, j) += C[i][j][k][l]*strain(k, l);
+ }
+ }
+ }
+ }
+ return stress;
+}
+
+
+#define TYPE _tetrahedron_4
+/* -------------------------------------------------------------------------- */
+int main(int argc, char *argv[])
+{
+ initialize("material_anisotropic.dat", argc, argv);
+
+ UInt dim = ElementClass<TYPE>::getSpatialDimension();
+ const ElementType element_type = TYPE;
+
+ UInt damping_steps = 600000;
+ UInt damping_interval = 50;
+ Real damping_ratio = 0.99;
+
+ UInt additional_steps = 20000;
+ UInt max_steps = damping_steps + additional_steps;
+
+ /// load mesh
+ Mesh my_mesh(dim);
+
+ std::stringstream filename; filename << TYPE << ".msh";
+ my_mesh.read(filename.str());
+
+ UInt nb_nodes = my_mesh.getNbNodes();
+
+ /// declaration of model
+ SolidMechanicsModel my_model(my_mesh);
+ /// model initialization
+ my_model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass));
+
+
+ std::cout << my_model.getMaterial(0) << std::endl;
+ Real time_step = my_model.getStableTimeStep()/5.;
+ my_model.setTimeStep(time_step);
+ my_model.assembleMassLumped();
+
+ std::cout << "The number of time steps is: " << max_steps << " (" << time_step << "s)" << std::endl;
+
+ // boundary conditions
+ const Array<Real> & coordinates = my_mesh.getNodes();
+ Array<Real> & displacement = my_model.getDisplacement();
+ Array<bool> & boundary = my_model.getBlockedDOFs();
+
+ MeshUtils::buildFacets(my_mesh);
+
+ my_mesh.createBoundaryGroupFromGeometry();
+
+ // Loop over (Sub)Boundar(ies)
+ // Loop over (Sub)Boundar(ies)
+ for(GroupManager::const_element_group_iterator it(my_mesh.element_group_begin());
+ it != my_mesh.element_group_end(); ++it) {
+ for(ElementGroup::const_node_iterator nodes_it(it->second->node_begin());
+ nodes_it!= it->second->node_end(); ++nodes_it) {
+ UInt n(*nodes_it);
+ std::cout << "Node " << *nodes_it << std::endl;
+ for (UInt i = 0; i < dim; ++i) {
+ displacement(n, i) = alpha[i][0];
+ for (UInt j = 0; j < dim; ++j) {
+ displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
+ }
+ boundary(n, i) = true;
+ }
+ }
+ }
+
+ // Actually, loop over all nodes, since I wanna test a static solution
+ for (UInt n = 0 ; n < nb_nodes ; ++n) {
+ for (UInt i = 0 ; i < dim ; ++i) {
+ displacement(n, i) = alpha[i][0];
+ for (UInt j = 0 ; j < dim ; ++j) {
+ displacement(n, i) += alpha[i][j+1] * coordinates(n, j);
+ }
+ }
+ }
+
+ Array<Real> & velocity = my_model.getVelocity();
+
+ std::ofstream energy;
+ std::stringstream energy_filename; energy_filename << "energy_" << TYPE << ".csv";
+ energy.open(energy_filename.str().c_str());
+ energy << "id,time,ekin" << std::endl;
+ Real ekin_mean = 0.;
+
+ /* ------------------------------------------------------------------------ */
+ /* Main loop */
+ /* ------------------------------------------------------------------------ */
+ UInt s;
+ for(s = 1; s <= max_steps; ++s) {
+ if(s % 10000 == 0) std::cout << "passing step " << s << "/" << max_steps
+ << " (" << s*time_step << "s)" <<std::endl;
+
+ // damp velocity in order to find equilibrium
+ if((s < damping_steps) && (s % damping_interval == 0)) {
+ velocity *= damping_ratio;
+ }
+
+ if(s % 1000 == 0) {
+ ekin_mean = ekin_mean / 1000.;
+ std::cout << "Ekin mean = " << ekin_mean << std::endl;
+ if (ekin_mean < 1e-10) break;
+ ekin_mean = 0.;
+ }
+
+
+ my_model.explicitPred();
+
+ my_model.updateResidual();
+ my_model.updateAcceleration();
+
+ my_model.explicitCorr();
+
+ akantu::Real ekin = my_model.getEnergy("kinetic"); ekin_mean += ekin;
+
+ if(s % 1000 == 0)
+ energy << s << "," << s*time_step << "," << ekin << std::endl;
+ }
+
+ energy.close();
+
+ UInt nb_quadrature_points = my_model.getFEEngine().getNbIntegrationPoints(TYPE);
+ Array<Real> & stress_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getStress(element_type));
+ Array<Real> & gradu_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getGradU(element_type));
+
+ Array<Real>::iterator< Matrix<Real> > stress_it = stress_vect.begin(dim, dim);
+ Array<Real>::iterator< Matrix<Real> > gradu_it = gradu_vect.begin(dim, dim);
+
+ Matrix<Real> presc_stress; presc_stress = prescribed_stress<TYPE>();
+ Matrix<Real> presc_gradu; presc_gradu = prescribed_grad_u<TYPE>();
+
+ UInt nb_element = my_mesh.getNbElement(TYPE);
+
+ Real gradu_tolerance = 1e-9;
+ Real stress_tolerance = 1e-2;
+ if(s > max_steps) {
+ stress_tolerance = 1e-4;
+ gradu_tolerance = 1e-7;
+ }
+
+
+ for (UInt el = 0; el < nb_element; ++el) {
+ for (UInt q = 0; q < nb_quadrature_points; ++q) {
+ Matrix<Real> & stress = *stress_it;
+ Matrix<Real> & gradu = *gradu_it;
+
+ for (UInt i = 0; i < dim; ++i) {
+ for (UInt j = 0; j < dim; ++j) {
+ if(!(std::abs(gradu(i, j) - presc_gradu(i, j)) < gradu_tolerance)) {
+ std::cerr << "gradu[" << i << "," << j << "] = " << gradu(i, j) << " but should be = " << presc_gradu(i, j) << " (-" << std::abs(gradu(i, j) - presc_gradu(i, j)) << ") [el : " << el<< " - q : " << q << "]" << std::endl;
+ std::cerr << gradu << presc_gradu << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if(!(std::abs(stress(i, j) - presc_stress(i, j)) < stress_tolerance)) {
+ std::cerr << "stress[" << i << "," << j << "] = " << stress(i, j) << " but should be = " << presc_stress(i, j) << " (-" << std::abs(stress(i, j) - presc_stress(i, j)) << ") [el : " << el<< " - q : " << q << "]" << std::endl;
+ std::cerr << stress << presc_stress << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ ++stress_it;
+ ++gradu_it;
+ }
+ }
+
+
+ for (UInt n = 0; n < nb_nodes; ++n) {
+ for (UInt i = 0; i < dim; ++i) {
+ Real disp = alpha[i][0];
+ for (UInt j = 0; j < dim; ++j) {
+ disp += alpha[i][j + 1] * coordinates(n, j);
+ }
+
+ if(!(std::abs(displacement(n,i) - disp) < 1e-7)) {
+ std::cerr << "displacement(" << n << ", " << i <<")=" << displacement(n,i) << " should be equal to " << disp << "(" << displacement(n,i) - disp << ")" << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ finalize();
+
+ return EXIT_SUCCESS;
+}
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc b/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc
index 3468c3771..cc45205cb 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,232 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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/test_lumped_mass.cc b/test/test_model/test_solid_mechanics_model/patch_tests/lumped_mass/test_lumped_mass.cc
index 106188fdc..374a492e3 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
*
* @brief test the lumping of the mass matrix
*
* @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 "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) < 1e-15)) {
+ 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/square_structured.geo b/test/test_model/test_solid_mechanics_model/square_structured.geo
new file mode 100644
index 000000000..68b6d1880
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/square_structured.geo
@@ -0,0 +1,27 @@
+// Mesh size
+nb_nodes = 11.;
+
+Lx = 1;
+Ly = 1;
+
+h = Lx / nb_nodes;
+
+// ------------------------------------------
+// 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(2) = {1};
+
+Transfinite Surface "*";
+Recombine Surface "*";
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 40b7da17b..e7d555db3 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,39 +1,40 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
# @date creation: Tue May 08 2012
# @date last modification: Fri Jun 21 2013
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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_buildfacets "test_cohesive_buildfacets" PACKAGE cohesive_element)
-add_akantu_test(test_cohesive_intrinsic "test_cohesive_intrinsic" PACKAGE cohesive_element)
-add_akantu_test(test_cohesive_extrinsic "test_cohesive_extrinsic" PACKAGE cohesive_element)
-add_akantu_test(test_cohesive_buildfragments "test_cohesive_buildfragments" PACKAGE cohesive_element)
-add_akantu_test(test_cohesive_intrinsic_impl "test_cohesive_intrinsic_impl" PACKAGE cohesive_element)
-add_akantu_test(test_cohesive_1d_element "test_cohesive_1d_element" PACKAGE cohesive_element)
+add_akantu_test(test_cohesive_intrinsic "test_cohesive_intrinsic")
+add_akantu_test(test_cohesive_extrinsic "test_cohesive_extrinsic")
+add_akantu_test(test_cohesive_buildfragments "test_cohesive_buildfragments")
+add_akantu_test(test_cohesive_intrinsic_impl "test_cohesive_intrinsic_impl")
+add_akantu_test(test_cohesive_1d_element "test_cohesive_1d_element")
+add_akantu_test(test_cohesive_extrinsic_implicit "test_cohesive_extrinsic_implicit")
+add_akantu_test(test_cohesive_insertion "test_cohesive_insertion")
#===============================================================================
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/CMakeLists.txt
index ae30b356d..685e52498 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,42 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
# @date creation: Fri Jun 14 2013
# @date last modification: Fri Jun 14 2013
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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_1d_element_mesh bar.geo 1 2)
-
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
- PACKAGE cohesive_element
+ DEPENDS test_cohesive_1d_element_mesh
FILES_TO_COPY material.dat
- DIRECTORIES_TO_CREATE paraview)
+ DIRECTORIES_TO_CREATE paraview
+ PACKAGE cohesive_element)
endif()
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/material.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/material.dat
index 42c6fb6fa..5f1e159c1 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/material.dat
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/material.dat
@@ -1,11 +1,11 @@
material elastic [
name = steel
rho = 1e3 # density
E = 1.e3 # young's modulus
]
material cohesive_linear [
name = cohesive
- G_cI = 100
+ G_c = 100
sigma_c = 100
]
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
new file mode 100644
index 000000000..fdb27b9a1
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/CMakeLists.txt
@@ -0,0 +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
+ 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/material.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/material.dat
new file mode 100644
index 000000000..bfff2e8c3
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/material.dat
@@ -0,0 +1,15 @@
+seed = 1
+
+material elastic [
+ name = bulk
+ rho = 2500
+ E = 42.e9
+ nu = 0.2
+]
+
+material cohesive_linear [
+ name = cohesive
+ beta = 1
+ G_c = 100
+ sigma_c = 300e6 uniform [0, 30e6]
+]
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/mesh.geo b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/mesh.geo
new file mode 100644
index 000000000..cee7833fb
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/mesh.geo
@@ -0,0 +1,22 @@
+L = 0.03;
+s = 0.03/20.;
+h = s;
+
+Point(1) = {-L/2., 0, 0, s};
+Point(2) = {L/2., 0, 0, s};
+Point(3) = {L/2., h, 0, s};
+Point(4) = {-L/2., h, 0, s};
+Line(1) = {1, 2};
+Line(2) = {2, 3};
+Line(3) = {3, 4};
+Line(4) = {4, 1};
+Line Loop(5) = {4, 1, 2, 3};
+Plane Surface(6) = {5};
+Physical Surface(7) = {6};
+Physical Line("Left_side") = {4};
+Physical Line("Right_side") = {2};
+
+Transfinite Line {2, 4} = 2;
+Transfinite Surface "*";
+Recombine Surface "*";
+Mesh.SecondOrderIncomplete = 1;
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
new file mode 100644
index 000000000..9f04d1e74
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_buildfragments/test_cohesive_buildfragments.cc
@@ -0,0 +1,200 @@
+/**
+ * @file test_cohesive_buildfragments.cc
+ *
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ *
+ * @date Wed Jun 13 11:29:49 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 <limits>
+#include <fstream>
+#include <iostream>
+
+
+/* -------------------------------------------------------------------------- */
+#include "solid_mechanics_model_cohesive.hh"
+#include "material_cohesive.hh"
+#include "fragment_manager.hh"
+
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+ initialize("material.dat",argc, argv);
+
+ Math::setTolerance(1e-14);
+
+ const UInt spatial_dimension = 2;
+ const UInt max_steps = 200;
+ Real strain_rate = 1.e5;
+ ElementType type = _quadrangle_4;
+
+ Real L = 0.03;
+ Real theoretical_mass = L * L/20. * 2500;
+
+ ElementType type_facet = Mesh::getFacetType(type);
+ ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
+
+ Mesh mesh(spatial_dimension);
+ mesh.read("mesh.msh");
+ mesh.createGroupsFromMeshData<std::string>("physical_names");
+
+ SolidMechanicsModelCohesive model(mesh);
+
+ /// model initialization
+ model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
+
+ Real time_step = model.getStableTimeStep()*0.05;
+ model.setTimeStep(time_step);
+ // std::cout << "Time step: " << time_step << std::endl;
+
+ Real disp_increment = strain_rate * L / 2. * time_step;
+
+ model.assembleMassLumped();
+
+ Array<Real> & velocity = model.getVelocity();
+
+ const Array<Real> & position = mesh.getNodes();
+ UInt nb_nodes = mesh.getNbNodes();
+
+ /// initial conditions
+ for (UInt n = 0; n < nb_nodes; ++n)
+ velocity(n, 0) = strain_rate * position(n, 0);
+
+ /// boundary conditions
+ model.applyBC(BC::Dirichlet::FixedValue(0, _x), "Left_side");
+ model.applyBC(BC::Dirichlet::FixedValue(0, _x), "Right_side");
+
+ model.updateResidual();
+
+ model.setBaseName("extrinsic");
+ model.addDumpFieldVector("displacement");
+ model.addDumpField("velocity" );
+ model.addDumpField("acceleration");
+ model.addDumpField("residual" );
+ model.addDumpField("stress");
+ model.addDumpField("strain");
+ model.dump();
+
+ UInt cohesive_index = 1;
+
+ UInt nb_quad_per_facet = model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
+ MaterialCohesive & mat_cohesive
+ = dynamic_cast<MaterialCohesive&>(model.getMaterial(cohesive_index));
+ const Array<Real> & damage = mat_cohesive.getDamage(type_cohesive);
+
+ FragmentManager fragment_manager(model, false);
+ const Array<Real> & fragment_mass = fragment_manager.getMass();
+
+ /// Main loop
+ for (UInt s = 1; s <= max_steps; ++s) {
+
+ model.checkCohesiveStress();
+
+ model.explicitPred();
+ model.updateResidual();
+ model.updateAcceleration();
+ model.explicitCorr();
+
+ /// apply boundary conditions
+ model.applyBC(BC::Dirichlet::IncrementValue(-disp_increment, _x), "Left_side");
+ model.applyBC(BC::Dirichlet::IncrementValue( disp_increment, _x), "Right_side");
+
+ if(s % 1 == 0) {
+ // model.dump();
+ std::cout << "passing step " << s << "/" << max_steps << std::endl;
+
+ fragment_manager.computeAllData();
+
+ /// check number of fragments
+ UInt nb_fragment_num = fragment_manager.getNbFragment();
+
+ UInt nb_cohesive_elements = mesh.getNbElement(type_cohesive);
+
+ UInt nb_fragment = 1;
+ for (UInt el = 0; el < nb_cohesive_elements; ++el) {
+ UInt q = 0;
+ while (q < nb_quad_per_facet &&
+ Math::are_float_equal(damage(el*nb_quad_per_facet + q), 1)) ++q;
+
+ if (q == nb_quad_per_facet) {
+ ++nb_fragment;
+ }
+ }
+
+ if (nb_fragment != nb_fragment_num) {
+ std::cout << "The number of fragments is wrong!" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ /// check mass computation
+ Real total_mass = 0.;
+ for (UInt frag = 0; frag < nb_fragment_num; ++frag) {
+ total_mass += fragment_mass(frag);
+ }
+
+ if (!Math::are_float_equal(theoretical_mass, total_mass)) {
+ std::cout << "The fragments' mass is wrong!" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ }
+ }
+
+ model.dump();
+
+ /// check velocities
+ UInt nb_fragment = fragment_manager.getNbFragment();
+ const Array<Real> & fragment_velocity = fragment_manager.getVelocity();
+ const Array<Real> & fragment_center = fragment_manager.getCenterOfMass();
+
+ Real fragment_length = L / nb_fragment;
+ Real initial_position = -L / 2. + fragment_length / 2.;
+
+ for (UInt frag = 0; frag < nb_fragment; ++frag) {
+ Real theoretical_center = initial_position + fragment_length * frag;
+
+ if (!Math::are_float_equal(fragment_center(frag, 0), theoretical_center)) {
+ std::cout << "The fragments' center is wrong!" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ Real initial_vel = fragment_center(frag, 0) * strain_rate;
+
+ Math::setTolerance(100);
+
+ if (!Math::are_float_equal(fragment_velocity(frag), initial_vel)) {
+ std::cout << "The fragments' velocity is wrong!" << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ finalize();
+
+ std::cout << "OK: test_cohesive_buildfragments was passed!" << std::endl;
+ return EXIT_SUCCESS;
+}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/CMakeLists.txt
index 87e332435..bfb4e7a98 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,52 +1,62 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
# @date creation: Tue May 08 2012
# @date last modification: Wed Oct 09 2013
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
- PACKAGE cohesive_element
+ DEPENDS test_cohesive_extrinsic_mesh
FILES_TO_COPY material.dat
- DIRECTORIES_TO_CREATE paraview)
+ 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
- PACKAGE cohesive_element)
+ 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
- PACKAGE cohesive_element)
+ 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/fatigue.msh b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/fatigue.msh
new file mode 100644
index 000000000..ac0ee23d8
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/fatigue.msh
@@ -0,0 +1,17 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+6
+1 0 0 0
+2 2 0 0
+3 2 1 0
+4 0 1 0
+5 0.9999999999973842 0 0
+6 1.000000000004119 1 0
+$EndNodes
+$Elements
+2
+1 3 2 7 6 2 3 6 5
+2 3 2 7 6 1 5 6 4
+$EndElements
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/material.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/material.dat
index dcf925bab..eafc796bc 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/material.dat
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/material.dat
@@ -1,23 +1,20 @@
material elastic [
name = steel
rho = 1e3 # density
E = 1e3 # young's modulus
nu = 0.001 # poisson's ratio
]
material cohesive_linear [
name = cohesive
beta = 1
- G_cI = 100
- G_cII = 100
+ G_c = 100
sigma_c = 100
- volume_s = 1
]
material cohesive_linear [
name = cohesive2
beta = 1
- G_cI = 100
- G_cII = 100
+ G_c = 100
sigma_c = 1000
]
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/material_fatigue.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/material_fatigue.dat
new file mode 100644
index 000000000..115a089ac
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/material_fatigue.dat
@@ -0,0 +1,15 @@
+material elastic [
+ name = bulk
+ rho = 1 # density
+ E = 1 # young's modulus
+ nu = 0 # poisson's ratio
+]
+
+material cohesive_linear_fatigue [
+ name = cohesive
+ sigma_c = 1
+ beta = 1
+ delta_c = 1
+ delta_f = 1
+ count_switches = true
+]
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 e8b92d2b1..c082b26a0 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,166 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 % 1 == 0) {
+ 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
new file mode 100644
index 000000000..f0ea7695e
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_fatigue.cc
@@ -0,0 +1,233 @@
+/**
+ * @file test_cohesive_intrinsic_fatigue.cc
+ * @author Marco Vocialta <marco.vocialta@epfl.ch>
+ * @date Fri Feb 20 10:13:14 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_tetrahedron.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic/test_cohesive_extrinsic_tetrahedron.cc
index 6fbdde134..b1b380e0b 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,241 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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_implicit/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/CMakeLists.txt
new file mode 100644
index 000000000..0bf4aea54
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/CMakeLists.txt
@@ -0,0 +1,37 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Mauro Corrado <mauro.corrado@epfl.ch>
+#
+# @date Fri May 01 11:56:18 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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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/K_matrix_verified.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/K_matrix_verified.dat
new file mode 100644
index 000000000..9ae429d9d
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/K_matrix_verified.dat
@@ -0,0 +1,120 @@
+%%MatrixMarket matrix coordinate real symmetric
+20 20 118
+17 17 80000
+17 18 0
+17 13 -1.81898940354586e-12
+17 14 0
+17 7 -10000
+17 8 5000
+17 15 -20000
+17 16 0
+18 18 80000
+18 13 0
+18 14 -20000
+18 7 5000
+18 8 -10000
+18 15 0
+18 16 -1.81898940354586e-12
+13 13 40000
+13 14 0
+13 7 -10000
+13 8 -5000
+13 15 -10000
+13 16 -5000
+14 14 40000
+14 7 5000
+14 8 -9.09494701772928e-13
+14 15 -5000
+14 16 -10000
+7 7 20000
+7 8 -5000
+7 15 -9.09494701772928e-13
+7 16 -5000
+8 8 20000
+8 15 5000
+8 16 -10000
+15 15 40000
+15 16 0
+16 16 40000
+17 11 -10000
+17 12 -5000
+17 5 -10000
+17 6 -5000
+18 11 5000
+18 12 -9.09494701772928e-13
+18 5 -5000
+18 6 -10000
+11 11 21320.8409773605
+11 12 -4882.11803623535
+11 5 -9.09494701772928e-13
+11 6 -5000
+11 13 -10000
+11 14 5000
+12 12 19800.7540266124
+12 5 5000
+12 6 -10000
+12 13 5000
+12 14 -10000
+5 5 20000
+5 6 5000
+5 13 -10000
+5 14 -5000
+6 6 20000
+6 13 5000
+6 14 -9.09494701772928e-13
+17 9 -1.81898940354586e-12
+17 10 0
+17 3 -10000
+17 4 5000
+17 19 -10000
+17 20 5000
+18 9 0
+18 10 -20000
+18 3 5000
+18 4 -10000
+18 19 -5000
+18 20 -9.09494701772928e-13
+9 9 40000
+9 10 0
+9 3 -10000
+9 4 -5000
+9 19 -10000
+9 20 -5000
+10 10 40000
+10 3 5000
+10 4 -9.09494701772928e-13
+10 19 -5000
+10 20 -10000
+3 3 20000
+3 4 -5000
+3 19 -9.09494701772928e-13
+3 20 -5000
+4 4 20000
+4 19 5000
+4 20 -10000
+19 19 21320.8409773605
+19 20 5117.88196376465
+20 20 19800.7540266124
+17 1 -10000
+17 2 -5000
+18 1 -5000
+18 2 -10000
+15 1 -9.09494701772928e-13
+15 2 -5000
+15 9 -10000
+15 10 5000
+16 1 5000
+16 2 -10000
+16 9 5000
+16 10 -10000
+1 1 20000
+1 2 5000
+1 9 -10000
+1 10 -5000
+2 2 20000
+2 9 5000
+2 10 -9.09494701772928e-13
+11 19 -1320.84097736047
+11 20 -117.881963764652
+12 19 -117.881963764652
+12 20 199.245973387621
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/material.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/material.dat
new file mode 100644
index 000000000..090773041
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/material.dat
@@ -0,0 +1,14 @@
+material elastic [
+ name = aggregate
+ rho = 2.7e-9 # density
+ E = 40000 # young's modulus
+ nu = 0.0 # poisson's ratio
+]
+
+material cohesive_linear [
+ name = cohesive
+ beta = 1
+ G_c = 60e-3
+ penalty = 1000000
+ sigma_c = 10
+]
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/quadrangle.msh b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/quadrangle.msh
new file mode 100644
index 000000000..22a9d7f77
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/quadrangle.msh
@@ -0,0 +1,22 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$Nodes
+9
+1 1 1 0
+2 -1 1 0
+3 -1 -1 0
+4 1 -1 0
+5 0 1 0
+6 -1 0 0
+7 0 -1 0
+8 1 0 0
+9 0 0 0
+$EndNodes
+$Elements
+4
+1 3 2 7 6 9 7 4 8
+2 3 2 7 6 9 6 3 7
+3 3 2 7 6 9 5 2 6
+4 3 2 7 6 9 8 1 5
+$EndElements
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
new file mode 100644
index 000000000..0a97d4e64
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/test_assembling_K_cohe_elements.cc
@@ -0,0 +1,165 @@
+/**
+ * @file matrix_assembling_cohesive_elements.cc
+ *
+ * @author Mauro Corrado
+ *
+ * @date creation: Thu April 30 2015
+ *
+ * @brief Test to check the correct matrix assembling for cohesive elements
+ * 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <limits>
+#include <fstream>
+#include <iostream>
+
+/* -------------------------------------------------------------------------- */
+#include "solid_mechanics_model_cohesive.hh"
+#include "material_cohesive.hh"
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+int main(int argc, char *argv[]) {
+ initialize("material.dat", argc, argv);
+
+ debug::setDebugLevel(dblWarning);
+
+ const UInt spatial_dimension = 2;
+ Real increment = 0.004;
+ Real error;
+ bool passed = true;
+ Real tol = 1.0e-13;
+
+ Mesh mesh(spatial_dimension);
+ mesh.read("quadrangle.msh");
+
+ SolidMechanicsModelCohesive model(mesh);
+
+ /// model initialization
+ model.initFull(SolidMechanicsModelCohesiveOptions(_static, true));
+
+ /// CohesiveElementInserter
+ model.limitInsertion(_y, -0.001, 0.001);
+ model.updateAutomaticInsertion();
+
+ Array<bool> & boundary = model.getBlockedDOFs();
+ Array<Real> & position = mesh.getNodes();
+ Array<Real> & displacement = model.getDisplacement();
+ //SparseMatrix & K_test = model.getStiffnessMatrix();
+ Array<Real> K_verified(0,3, "K_matrix_verified");
+ Array<Real> K_test(0,3, "K_matrix_test");
+
+ /// load the verified stiffness matrix
+ Vector<Real> tmp(3);
+ UInt nb_lines;
+
+ std::ifstream infile("K_matrix_verified.dat");
+ std::string line;
+ if(!infile.good()) AKANTU_DEBUG_ERROR("Cannot open file K_matrix_verified.dat");
+ else{
+ for (UInt i = 0; i < 2; ++i){
+ getline(infile, line);
+ std::stringstream sstr_data(line);
+ if (i == 1){
+ sstr_data >> tmp(0) >> tmp(1) >> tmp(2);
+ nb_lines = tmp(2);
+ }
+ }
+
+ for (UInt i = 0; i < nb_lines; ++i){
+ getline(infile, line);
+ std::stringstream sstr_data(line);
+ sstr_data >> tmp(0) >> tmp(1) >> tmp(2);
+ K_verified.push_back(tmp);
+ }
+ }
+ infile.close();
+
+
+ /// impose boundary conditions
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (position(n,1) < -0.99){
+ boundary(n,1) = true;
+ boundary(n,0) = true;
+ }
+ if (position(n,1) > 0.99 && position(n,0) < -0.99)
+ boundary(n,1) = true;
+ }
+
+
+ /// solve step
+ for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
+ if (position(n,1) > 0.99 && position(n,0) < -0.99)
+ displacement(n,1) += increment;
+ }
+
+ model.solveStepCohesive<_scm_newton_raphson_tangent, _scc_increment>(1e-13, error, 10);
+
+
+ model.getStiffnessMatrix().saveMatrix("K_matrix_test.dat");
+
+ /// load the stiffness matrix to be tested
+ std::ifstream infile2("K_matrix_test.dat");
+ if(!infile2.good()) AKANTU_DEBUG_ERROR("Cannot open file K_matrix_test.dat");
+ else{
+ for (UInt i = 0; i < 2; ++i){
+ getline(infile2, line);
+ std::stringstream sstr_data(line);
+ if (i == 1){
+ sstr_data >> tmp(0) >> tmp(1) >> tmp(2);
+ nb_lines = tmp(2);
+ }
+ }
+
+ for (UInt i = 0; i < nb_lines; ++i){
+ getline(infile2, line);
+ std::stringstream sstr_data(line);
+ sstr_data >> tmp(0) >> tmp(1) >> tmp(2);
+ K_test.push_back(tmp);
+ }
+ }
+ infile2.close();
+
+ for (UInt i = 0; i < K_verified.getSize(); ++i){
+ for (UInt j = 0; j < K_test.getSize(); ++j){
+ if ((K_test(j,0) == K_verified(i,0)) && (K_test(j,1) == K_verified(i,1))){
+ if (std::abs(K_verified(i,2)) < tol){
+ if (std::abs(K_test(j,2)) > tol)
+ passed = false;
+ }else{
+ Real ratio = (std::abs(K_test(j,2) - K_verified(i,2))) / (std::abs(K_verified(i,2)));
+ if (ratio > tol)
+ passed = false;
+ }
+ }
+ }
+ }
+
+ finalize();
+
+ if (passed)
+ return EXIT_SUCCESS;
+ else
+ return EXIT_FAILURE;
+}
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/test_assembling_K_cohe_elements.sh b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/test_assembling_K_cohe_elements.sh
new file mode 100755
index 000000000..06106e804
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_extrinsic_implicit/test_assembling_K_cohe_elements.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+./test_assembling_K_cohe_elements -ksp_type preonly -pc_type lu -pc_factor_mat_solver_package mumps -mat_mumps_icntl_7 2 -ksp_initial_guess_nonzero 0
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/3d_spherical_inclusion.geo b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/3d_spherical_inclusion.geo
new file mode 100644
index 000000000..6f87f12e1
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/3d_spherical_inclusion.geo
@@ -0,0 +1,100 @@
+dx = 0.1;
+w = 2;
+radius = 0.2;
+
+Point(1) = {0,0,0,dx};
+Point(2) = {0,.3,0,dx};
+Point(3) = {0,-.3,0,dx};
+Point(4) = {w,0,0,dx};
+Point(5) = {w,.3,0,dx};
+Point(6) = {w,-.3,0,dx};
+Point(7) = {0,0,w,dx};
+Point(8) = {0,.3,w,dx};
+Point(9) = {0,-.3,w,dx};
+Point(10) = {w,0,w,dx};
+Point(11) = {w,.3,w,dx};
+Point(12) = {w,-.3,w,dx};
+Point(13) = {0.5*w,0,0.5*w,dx};
+Point(14) = {0.5*w+radius,0,0.5*w+radius,dx};
+Point(15) = {0.5*w-radius,0,0.5*w+radius,dx};
+Point(16) = {0.5*w+radius,0,0.5*w-radius,dx};
+Point(17) = {0.5*w-radius,0,0.5*w-radius,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};
+Line Loop(21) = {18, 12, -19, -3};
+Plane Surface(22) = {21};
+Line Loop(23) = {19, 13, -20, 6};
+Plane Surface(24) = {23};
+Line Loop(25) = {11, -16, 1, 15};
+Plane Surface(26) = {25};
+Line Loop(27) = {14, -17, -5, 16};
+Plane Surface(28) = {27};
+Line Loop(29) = {8, 12, -9, -11};
+Plane Surface(30) = {29};
+Line Loop(31) = {9, 13, -10, -14};
+Plane Surface(32) = {31};
+Line Loop(33) = {2, 3, -4, 1};
+Plane Surface(34) = {33};
+Line Loop(35) = {7, 6, -4, 5};
+Plane Surface(36) = {35};
+Line Loop(37) = {18, -8, -15, 2};
+Plane Surface(38) = {37};
+Line Loop(39) = {7, 20, -10, -17};
+Plane Surface(40) = {39};
+Circle(41) = {16, 13, 14};
+Circle(42) = {14, 13, 15};
+Circle(43) = {15, 13, 17};
+Circle(44) = {17, 13, 16};
+Translate {0.5, 0, 0.5} {
+ Duplicata { Line{44, 43, 42, 41}; }
+}
+Translate {-0.5, 0, 0.5} {
+ Duplicata { Line{44, 43, 42, 41}; }
+}
+Translate {0.5, 0, -0.5} {
+ Duplicata { Line{44, 43, 42, 41}; }
+}
+Translate {-0.5, 0, -0.5} {
+ Duplicata { Line{44, 43, 42, 41}; }
+}
+Line Loop(61) = {9, -19, -4, 16};
+Line Loop(62) = {52, 51, 50, 49};
+Line Loop(63) = {57, 60, 59, 58};
+Line Loop(64) = {44, 41, 42, 43};
+Line Loop(65) = {55, 54, 53, 56};
+Line Loop(66) = {48, 47, 46, 45};
+Plane Surface(67) = {61, 62, 63, 64, 65, 66};
+Plane Surface(68) = {62};
+Plane Surface(69) = {63};
+Plane Surface(70) = {64};
+Plane Surface(71) = {66};
+Plane Surface(72) = {65};
+Surface Loop(73) = {26, 30, 38, 22, 34, 67, 68, 69, 70, 72, 71};
+Volume(74) = {73};
+Surface Loop(75) = {32, 24, 40, 36, 28, 67, 68, 69, 70, 72, 71};
+Volume(76) = {75};
+Physical Surface("interface") = {67};
+Physical Surface("coh1") = {68};
+Physical Surface("coh2") = {69};
+Physical Surface("coh3") = {70};
+Physical Surface("coh4") = {71};
+Physical Surface("coh5") = {72};
+Physical Volume("bulk") = {74, 76};
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
new file mode 100644
index 000000000..dbe33abc3
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/CMakeLists.txt
@@ -0,0 +1,39 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Fabian Barras <fabian.barras@epfl.ch>
+#
+# @date creation: Fri Aug 7 09:07:44 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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+# @section DESCRIPTION
+#
+#===============================================================================
+
+add_mesh(3d_spherical_inclusion 3d_spherical_inclusion.geo 3 2)
+
+register_test(test_cohesive_insertion_along_physical_surfaces
+ SOURCES test_cohesive_insertion_along_physical_surfaces.cc
+ DEPENDS 3d_spherical_inclusion
+ FILES_TO_COPY input_file.dat
+ PACKAGE cohesive_element
+ )
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/input_file.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/input_file.dat
new file mode 100644
index 000000000..bbd74ab72
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/input_file.dat
@@ -0,0 +1,67 @@
+material elastic [
+ name = bulk
+ rho = 2500
+ nu = 0.29
+ E = 70e9
+# finite_deformation = 1
+]
+
+material cohesive_exponential [
+ name = coh1
+ sigma_c = 1.5e6
+ beta = 1
+ delta_c = 1e-4
+ exponential_penalty = true
+ contact_tangent = 1.0
+]
+
+material cohesive_exponential [
+ name = coh2
+ sigma_c = 1.5e6
+ beta = 1
+ delta_c = 1e-4
+ exponential_penalty = true
+ contact_tangent = 1.0
+]
+
+material cohesive_exponential [
+ name = coh3
+ sigma_c = 1.5e6
+ beta = 1
+ delta_c = 1e-4
+ exponential_penalty = true
+ contact_tangent = 1.0
+]
+
+material cohesive_exponential [
+ name = coh4
+ sigma_c = 1.5e6
+ beta = 1
+ delta_c = 1e-4
+ exponential_penalty = true
+ contact_tangent = 1.0
+]
+
+material cohesive_exponential [
+ name = coh5
+ sigma_c = 1.5e6
+ beta = 1
+ delta_c = 1e-4
+ exponential_penalty = true
+ contact_tangent = 1.0
+]
+
+material cohesive_exponential [
+ name = interface
+ sigma_c = 1.5e6
+ beta = 1
+ delta_c = 1e-4
+ exponential_penalty = true
+ contact_tangent = 1.0
+]
+
+mesh parameters [
+
+ cohesive_surfaces = coh1,coh2,coh3,coh4,coh5,interface
+
+]
\ No newline at end of file
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
new file mode 100644
index 000000000..e06086043
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_insertion/test_cohesive_insertion_along_physical_surfaces.cc
@@ -0,0 +1,97 @@
+/**
+ * @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
+ *
+ * @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 "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 6231bd426..bb6a8d167 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,59 +1,63 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Marco Vocialta <marco.vocialta@epfl.ch>
#
# @date creation: Tue May 08 2012
# @date last modification: Tue Nov 12 2013
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
- PACKAGE cohesive_element
+ DEPENDS test_cohesive_intrinsic_mesh
FILES_TO_COPY material.dat
- DIRECTORIES_TO_CREATE paraview)
+ 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
- PACKAGE cohesive_element)
+ 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)
+ PACKAGE cohesive_element
+ )
register_test(test_cohesive_intrinsic_tetrahedron_fragmentation
SOURCES test_cohesive_intrinsic_tetrahedron_fragmentation.cc
- DEPENDENCIES test_cohesive_intrinsic_tetrahedron_fragmentation_mesh
- PACKAGE cohesive_element)
+ 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/material.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/material.dat
index 0f9f4b536..d31ad403d 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/material.dat
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/material.dat
@@ -1,16 +1,15 @@
material elastic [
name = steel
rho = 10 # density
E = 10 # young's modulus
nu = 0.1 # poisson's ratio
]
material cohesive_bilinear [
name = cohesive
sigma_c = 1 uniform [0, 1]
beta = 1.5
- G_cI = 1
- G_cII = 1
+ G_c = 1
delta_0 = 1
# penalty = 1e10
]
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/material_tetrahedron.dat b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/material_tetrahedron.dat
index 11213337d..ba242d682 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/material_tetrahedron.dat
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_intrinsic/material_tetrahedron.dat
@@ -1,16 +1,16 @@
material elastic [
name = steel
rho = 10 # density
E = 10 # young's modulus
nu = 0.1 # poisson's ratio
]
material cohesive_bilinear [
name = cohesive
sigma_c = 1
beta = 1.5
- G_cI = 1
- G_cII = 1.2
+ G_c = 1
+ kappa = 1.2
delta_0 = 0.1
# penalty = 1e10
]
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 8b3040625..3b5793aaa 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,230 +1,225 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 "dumper_paraview.hh"
-#include "dumper_nodal_field.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.dump();
- DumperParaview dumper("cohesive_elements_quadrangle");
- dumper.registerMesh(mesh, spatial_dimension, _not_ghost, _ek_cohesive);
- dumper::NodalField<Real> * cohesive_displacement =
- new dumper::NodalField<Real>(model.getDisplacement());
-
- cohesive_displacement->setPadding(3);
- dumper.registerField("displacement", cohesive_displacement);
- dumper.dump();
+ 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();
- dumper.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 6e7ca68ce..006fc26a5 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,441 +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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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_cI = mat_cohesive.getParam<Real>("G_cI");
- // Real G_cII = mat_cohesive.getParam<Real>("G_cII");
+ 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_cI / sigma_c;
+ 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 ee99ef88d..3b97f1220 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,136 +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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 "dumper_paraview.hh"
-#include "dumper_nodal_field.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.dump();
-
- DumperParaview dumper("cohesive_elements_tetrahedron_fragmentation");
- dumper.registerMesh(mesh, spatial_dimension, _not_ghost, _ek_cohesive);
- dumper::NodalField<Real> * cohesive_displacement =
- new dumper::NodalField<Real>(model.getDisplacement());
-
- cohesive_displacement->setPadding(3);
+ model.setBaseNameToDumper("cohesive elements",
+ "cohesive_elements_tetrahedron_fragmentation");
+ model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
+ model.addDumpFieldToDumper("cohesive elements", "damage");
- dumper.registerField("displacement", cohesive_displacement);
-
- dumper.dump();
+ 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();
- dumper.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 14695ce1d..e251d97d0 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,38 +1,39 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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
- PACKAGE cohesive_element
FILES_TO_COPY material.dat implicit.msh
- DIRECTORIES_TO_CREATE paraview)
+ DIRECTORIES_TO_CREATE paraview
+ PACKAGE cohesive_element
+ )
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
new file mode 100644
index 000000000..3081db0b6
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/CMakeLists.txt
@@ -0,0 +1,50 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Lucas Frérot <lucas.frerot@epfl.ch>
+#
+# @date creation: Wed Mar 25 2015
+# @date last modification: Wed Mar 25 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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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/embedded_element.dat b/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_element.dat
new file mode 100644
index 000000000..d68d274d9
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_element.dat
@@ -0,0 +1,12 @@
+material reinforcement elastic [
+ name = reinforcement
+ E = 1
+ area = 1
+]
+
+material elastic [
+ name = null
+ rho = 0
+ E = 0
+ nu = 0
+]
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_mesh.msh b/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_mesh.msh
new file mode 100644
index 000000000..f7a1dfc04
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_mesh.msh
@@ -0,0 +1,30 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$PhysicalNames
+1
+2 1 "concrete"
+$EndPhysicalNames
+$Nodes
+9
+1 0 0 0
+2 0.5 0 0
+3 1 0 0
+4 0 0.5 0
+5 0.5 0.5 0
+6 1 0.5 0
+7 0 1 0
+8 0.5 1 0
+9 1 1 0
+$EndNodes
+$Elements
+8
+1 2 2 1 99 1 2 5
+2 2 2 1 99 2 3 6
+3 2 2 1 99 1 5 4
+4 2 2 1 99 2 6 5
+5 2 2 1 99 4 5 8
+6 2 2 1 99 5 6 9
+7 2 2 1 99 4 8 7
+8 2 2 1 99 5 9 8
+$EndElements
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_mesh_prestress.msh b/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_mesh_prestress.msh
new file mode 100644
index 000000000..a799996b4
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_mesh_prestress.msh
@@ -0,0 +1,15856 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$PhysicalNames
+4
+0 2 "YBlocked"
+0 3 "EndNode"
+1 1 "XBlocked"
+2 4 "concrete"
+$EndPhysicalNames
+$Nodes
+5420
+1 0 0 0
+2 10 0 0
+3 10 0.25 0
+4 10 1 0
+5 0 1 0
+6 0.04999999999996232 0 0
+7 0.09999999999992584 0 0
+8 0.1499999999998909 0 0
+9 0.199999999999856 0 0
+10 0.249999999999819 0 0
+11 0.2999999999997771 0 0
+12 0.3499999999997248 0 0
+13 0.3999999999996677 0 0
+14 0.4499999999996051 0 0
+15 0.4999999999995511 0 0
+16 0.5499999999995031 0 0
+17 0.5999999999994683 0 0
+18 0.6499999999994334 0 0
+19 0.6999999999993983 0 0
+20 0.7499999999993634 0 0
+21 0.7999999999993286 0 0
+22 0.8499999999992935 0 0
+23 0.8999999999992587 0 0
+24 0.9499999999992237 0 0
+25 0.9999999999991888 0 0
+26 1.049999999999154 0 0
+27 1.099999999999119 0 0
+28 1.149999999999084 0 0
+29 1.199999999999033 0 0
+30 1.24999999999897 0 0
+31 1.299999999998852 0 0
+32 1.349999999998722 0 0
+33 1.399999999998576 0 0
+34 1.44999999999843 0 0
+35 1.499999999998284 0 0
+36 1.549999999998138 0 0
+37 1.599999999997992 0 0
+38 1.649999999997846 0 0
+39 1.6999999999977 0 0
+40 1.749999999997554 0 0
+41 1.799999999997408 0 0
+42 1.849999999997263 0 0
+43 1.899999999997116 0 0
+44 1.949999999996971 0 0
+45 1.999999999996825 0 0
+46 2.049999999996679 0 0
+47 2.099999999996533 0 0
+48 2.149999999996387 0 0
+49 2.199999999996241 0 0
+50 2.249999999996095 0 0
+51 2.299999999995949 0 0
+52 2.349999999995803 0 0
+53 2.399999999995657 0 0
+54 2.449999999995511 0 0
+55 2.499999999995365 0 0
+56 2.54999999999522 0 0
+57 2.599999999995073 0 0
+58 2.649999999994928 0 0
+59 2.699999999994782 0 0
+60 2.749999999994635 0 0
+61 2.79999999999449 0 0
+62 2.849999999994344 0 0
+63 2.899999999994198 0 0
+64 2.949999999994052 0 0
+65 2.999999999993906 0 0
+66 3.04999999999376 0 0
+67 3.099999999993614 0 0
+68 3.149999999993468 0 0
+69 3.199999999993322 0 0
+70 3.249999999993176 0 0
+71 3.299999999993029 0 0
+72 3.349999999992884 0 0
+73 3.399999999992738 0 0
+74 3.449999999992592 0 0
+75 3.499999999992446 0 0
+76 3.5499999999923 0 0
+77 3.599999999992154 0 0
+78 3.649999999992009 0 0
+79 3.699999999991863 0 0
+80 3.749999999991717 0 0
+81 3.799999999991571 0 0
+82 3.849999999991425 0 0
+83 3.899999999991278 0 0
+84 3.949999999991132 0 0
+85 3.999999999991022 0 0
+86 4.049999999990987 0 0
+87 4.099999999991035 0 0
+88 4.149999999991111 0 0
+89 4.199999999991187 0 0
+90 4.249999999991263 0 0
+91 4.299999999991338 0 0
+92 4.349999999991415 0 0
+93 4.399999999991491 0 0
+94 4.449999999991566 0 0
+95 4.499999999991642 0 0
+96 4.549999999991719 0 0
+97 4.599999999991795 0 0
+98 4.649999999991871 0 0
+99 4.699999999991947 0 0
+100 4.749999999992022 0 0
+101 4.799999999992099 0 0
+102 4.849999999992175 0 0
+103 4.89999999999225 0 0
+104 4.949999999992326 0 0
+105 4.999999999992403 0 0
+106 5.049999999992478 0 0
+107 5.099999999992555 0 0
+108 5.14999999999263 0 0
+109 5.199999999992706 0 0
+110 5.249999999992783 0 0
+111 5.299999999992858 0 0
+112 5.349999999992933 0 0
+113 5.39999999999301 0 0
+114 5.449999999993086 0 0
+115 5.499999999993161 0 0
+116 5.549999999993238 0 0
+117 5.599999999993313 0 0
+118 5.649999999993391 0 0
+119 5.699999999993466 0 0
+120 5.749999999993543 0 0
+121 5.799999999993618 0 0
+122 5.849999999993694 0 0
+123 5.899999999993771 0 0
+124 5.949999999993846 0 0
+125 5.999999999993922 0 0
+126 6.049999999993998 0 0
+127 6.099999999994074 0 0
+128 6.14999999999415 0 0
+129 6.199999999994227 0 0
+130 6.249999999994302 0 0
+131 6.299999999994378 0 0
+132 6.349999999994455 0 0
+133 6.39999999999453 0 0
+134 6.449999999994606 0 0
+135 6.499999999994682 0 0
+136 6.549999999994759 0 0
+137 6.599999999994833 0 0
+138 6.64999999999491 0 0
+139 6.699999999994986 0 0
+140 6.749999999995062 0 0
+141 6.799999999995138 0 0
+142 6.849999999995214 0 0
+143 6.899999999995289 0 0
+144 6.949999999995366 0 0
+145 6.999999999995442 0 0
+146 7.049999999995517 0 0
+147 7.099999999995594 0 0
+148 7.14999999999567 0 0
+149 7.199999999995747 0 0
+150 7.249999999995821 0 0
+151 7.299999999995897 0 0
+152 7.349999999995973 0 0
+153 7.39999999999605 0 0
+154 7.449999999996125 0 0
+155 7.499999999996202 0 0
+156 7.549999999996278 0 0
+157 7.599999999996353 0 0
+158 7.64999999999643 0 0
+159 7.699999999996505 0 0
+160 7.749999999996582 0 0
+161 7.799999999996658 0 0
+162 7.849999999996734 0 0
+163 7.899999999996808 0 0
+164 7.949999999996885 0 0
+165 7.999999999996962 0 0
+166 8.049999999997038 0 0
+167 8.099999999997113 0 0
+168 8.14999999999719 0 0
+169 8.199999999997265 0 0
+170 8.249999999997341 0 0
+171 8.299999999997418 0 0
+172 8.349999999997493 0 0
+173 8.399999999997569 0 0
+174 8.449999999997646 0 0
+175 8.499999999997721 0 0
+176 8.549999999997798 0 0
+177 8.599999999997873 0 0
+178 8.649999999997949 0 0
+179 8.699999999998024 0 0
+180 8.749999999998101 0 0
+181 8.799999999998176 0 0
+182 8.849999999998253 0 0
+183 8.899999999998329 0 0
+184 8.949999999998404 0 0
+185 8.999999999998479 0 0
+186 9.049999999998557 0 0
+187 9.099999999998634 0 0
+188 9.149999999998709 0 0
+189 9.199999999998786 0 0
+190 9.24999999999886 0 0
+191 9.299999999998937 0 0
+192 9.349999999999012 0 0
+193 9.399999999999089 0 0
+194 9.449999999999164 0 0
+195 9.499999999999241 0 0
+196 9.549999999999315 0 0
+197 9.599999999999392 0 0
+198 9.649999999999469 0 0
+199 9.699999999999545 0 0
+200 9.749999999999622 0 0
+201 9.799999999999697 0 0
+202 9.849999999999774 0 0
+203 9.899999999999848 0 0
+204 9.949999999999925 0 0
+205 10 0.04999999999988947 0
+206 10 0.09999999999974372 0
+207 10 0.1499999999997367 0
+208 10 0.1999999999998683 0
+209 10 0.299999999999753 0
+210 10 0.3499999999995059 0
+211 10 0.3999999999992588 0
+212 10 0.4499999999990116 0
+213 10 0.4999999999987789 0
+214 10 0.5499999999988947 0
+215 10 0.5999999999990179 0
+216 10 0.6499999999991409 0
+217 10 0.6999999999992638 0
+218 10 0.7499999999993865 0
+219 10 0.7999999999995091 0
+220 10 0.8499999999996319 0
+221 10 0.8999999999997546 0
+222 10 0.9499999999998774 0
+223 9.949999999999999 1 0
+224 9.9 1 0
+225 9.85 1 0
+226 9.799999999999999 1 0
+227 9.75 1 0
+228 9.699999999999999 1 0
+229 9.649999999999999 1 0
+230 9.6 1 0
+231 9.549999999999999 1 0
+232 9.499999999999998 1 0
+233 9.449999999999999 1 0
+234 9.399999999999999 1 0
+235 9.349999999999998 1 0
+236 9.299999999999999 1 0
+237 9.249999999999998 1 0
+238 9.199999999999999 1 0
+239 9.149999999999999 1 0
+240 9.099999999999998 1 0
+241 9.049999999999999 1 0
+242 8.999999999999998 1 0
+243 8.949999999999998 1 0
+244 8.899999999999999 1 0
+245 8.849999999999998 1 0
+246 8.799999999999997 1 0
+247 8.749999999999998 1 0
+248 8.699999999999998 1 0
+249 8.649999999999997 1 0
+250 8.599999999999998 1 0
+251 8.549999999999997 1 0
+252 8.499999999999996 1 0
+253 8.449999999999998 1 0
+254 8.399999999999997 1 0
+255 8.349999999999998 1 0
+256 8.299999999999997 1 0
+257 8.249999999999996 1 0
+258 8.199999999999998 1 0
+259 8.149999999999997 1 0
+260 8.099999999999998 1 0
+261 8.049999999999997 1 0
+262 7.999999999999997 1 0
+263 7.949999999999998 1 0
+264 7.899999999999997 1 0
+265 7.849999999999998 1 0
+266 7.799999999999997 1 0
+267 7.749999999999997 1 0
+268 7.699999999999998 1 0
+269 7.649999999999998 1 0
+270 7.599999999999998 1 0
+271 7.549999999999997 1 0
+272 7.499999999999998 1 0
+273 7.449999999999998 1 0
+274 7.399999999999997 1 0
+275 7.349999999999998 1 0
+276 7.299999999999997 1 0
+277 7.249999999999997 1 0
+278 7.199999999999998 1 0
+279 7.149999999999998 1 0
+280 7.099999999999998 1 0
+281 7.049999999999997 1 0
+282 6.999999999999997 1 0
+283 6.949999999999998 1 0
+284 6.899999999999998 1 0
+285 6.849999999999998 1 0
+286 6.799999999999997 1 0
+287 6.749999999999998 1 0
+288 6.699999999999998 1 0
+289 6.649999999999998 1 0
+290 6.599999999999998 1 0
+291 6.549999999999998 1 0
+292 6.499999999999998 1 0
+293 6.449999999999998 1 0
+294 6.399999999999997 1 0
+295 6.349999999999998 1 0
+296 6.299999999999998 1 0
+297 6.249999999999998 1 0
+298 6.199999999999998 1 0
+299 6.149999999999999 1 0
+300 6.099999999999998 1 0
+301 6.049999999999998 1 0
+302 5.999999999999997 1 0
+303 5.949999999999998 1 0
+304 5.899999999999998 1 0
+305 5.849999999999998 1 0
+306 5.799999999999998 1 0
+307 5.749999999999998 1 0
+308 5.699999999999998 1 0
+309 5.649999999999998 1 0
+310 5.599999999999998 1 0
+311 5.549999999999998 1 0
+312 5.499999999999998 1 0
+313 5.449999999999998 1 0
+314 5.399999999999999 1 0
+315 5.349999999999999 1 0
+316 5.299999999999999 1 0
+317 5.249999999999998 1 0
+318 5.199999999999998 1 0
+319 5.149999999999999 1 0
+320 5.099999999999999 1 0
+321 5.049999999999998 1 0
+322 4.999999999999999 1 0
+323 4.949999999999999 1 0
+324 4.899999999999998 1 0
+325 4.849999999999999 1 0
+326 4.799999999999999 1 0
+327 4.749999999999998 1 0
+328 4.699999999999998 1 0
+329 4.649999999999999 1 0
+330 4.599999999999999 1 0
+331 4.549999999999999 1 0
+332 4.499999999999998 1 0
+333 4.449999999999998 1 0
+334 4.399999999999999 1 0
+335 4.349999999999998 1 0
+336 4.299999999999998 1 0
+337 4.249999999999999 1 0
+338 4.199999999999999 1 0
+339 4.149999999999999 1 0
+340 4.099999999999998 1 0
+341 4.049999999999999 1 0
+342 3.999999999999999 1 0
+343 3.949999999999999 1 0
+344 3.899999999999999 1 0
+345 3.849999999999999 1 0
+346 3.799999999999999 1 0
+347 3.749999999999999 1 0
+348 3.699999999999999 1 0
+349 3.649999999999999 1 0
+350 3.599999999999999 1 0
+351 3.549999999999997 1 0
+352 3.499999999999997 1 0
+353 3.449999999999998 1 0
+354 3.399999999999998 1 0
+355 3.349999999999999 1 0
+356 3.299999999999999 1 0
+357 3.249999999999998 1 0
+358 3.199999999999998 1 0
+359 3.149999999999999 1 0
+360 3.099999999999998 1 0
+361 3.049999999999998 1 0
+362 2.999999999999999 1 0
+363 2.949999999999999 1 0
+364 2.899999999999999 1 0
+365 2.85 1 0
+366 2.799999999999998 1 0
+367 2.749999999999998 1 0
+368 2.699999999999998 1 0
+369 2.649999999999998 1 0
+370 2.599999999999998 1 0
+371 2.549999999999999 1 0
+372 2.499999999999999 1 0
+373 2.449999999999999 1 0
+374 2.399999999999999 1 0
+375 2.349999999999999 1 0
+376 2.299999999999999 1 0
+377 2.249999999999998 1 0
+378 2.199999999999999 1 0
+379 2.149999999999999 1 0
+380 2.1 1 0
+381 2.049999999999999 1 0
+382 1.999999999999998 1 0
+383 1.949999999999999 1 0
+384 1.899999999999999 1 0
+385 1.849999999999998 1 0
+386 1.799999999999999 1 0
+387 1.75 1 0
+388 1.699999999999999 1 0
+389 1.649999999999999 1 0
+390 1.6 1 0
+391 1.549999999999999 1 0
+392 1.5 1 0
+393 1.449999999999999 1 0
+394 1.4 1 0
+395 1.35 1 0
+396 1.299999999999999 1 0
+397 1.249999999999998 1 0
+398 1.199999999999999 1 0
+399 1.149999999999999 1 0
+400 1.099999999999998 1 0
+401 1.049999999999999 1 0
+402 0.9999999999999982 1 0
+403 0.9499999999999993 1 0
+404 0.9000000000000004 1 0
+405 0.8499999999999996 1 0
+406 0.7999999999999989 1 0
+407 0.75 1 0
+408 0.6999999999999993 1 0
+409 0.6499999999999986 1 0
+410 0.6000000000000014 1 0
+411 0.5499999999999989 1 0
+412 0.5 1 0
+413 0.4499999999999993 1 0
+414 0.3999999999999986 1 0
+415 0.3499999999999996 1 0
+416 0.2999999999999989 1 0
+417 0.25 1 0
+418 0.1999999999999993 1 0
+419 0.1500000000000004 1 0
+420 0.09999999999999964 1 0
+421 0.05000000000000071 1 0
+422 0 0.9499999999997918 0
+423 0 0.8999999999995836 0
+424 0 0.8499999999996529 0
+425 0 0.7999999999999998 0
+426 0 0.7500000000003466 0
+427 0 0.7000000000006934 0
+428 0 0.6500000000010401 0
+429 0 0.6000000000013869 0
+430 0 0.5500000000017335 0
+431 0 0.5000000000020587 0
+432 0 0.4500000000018723 0
+433 0 0.4000000000016644 0
+434 0 0.3500000000014564 0
+435 0 0.3000000000012483 0
+436 0 0.2500000000010403 0
+437 0 0.2000000000008322 0
+438 0 0.1500000000006241 0
+439 0 0.100000000000416 0
+440 0 0.05000000000020799 0
+441 1.430518283324115 0.4976618019971546 0
+442 1.974999999996899 0.4999999999999243 0
+443 2.574999999995146 0.4999999999998804 0
+444 3.125330093894958 0.4947288460714284 0
+445 3.674886617398613 0.4990140276472064 0
+446 0.5192516935729574 0.4973828849261724 0
+447 9.475000000000112 0.5000000000000207 0
+448 8.925140624176818 0.5076652462134378 0
+449 8.37499999999995 0.5000000000000628 0
+450 7.82500000000002 0.5000000000000809 0
+451 7.225000000000063 0.5000000000001067 0
+452 6.677302008671008 0.5000666692094893 0
+453 6.125000000000027 0.5000000000001482 0
+454 5.580354820674485 0.5022662309541848 0
+455 5.028130163003213 0.5027845815212975 0
+456 4.275444121874549 0.5106119177145796 0
+457 0.9749999999990133 0.4518749999995468 0
+458 4.649999999999995 0.6093750000000562 0
+459 3.980796307925498 0.3333221928688176 0
+460 2.27499999999602 0.3393749999994408 0
+461 7.522296730190199 0.6567897313550136 0
+462 2.280320680685921 0.6627495663948291 0
+463 7.525011618601767 0.3241298754394778 0
+464 3.980388816233751 0.6615459847132322 0
+465 1.701413441777268 0.3205330984872935 0
+466 2.849700739872998 0.326161503321322 0
+467 3.39999999999272 0.3256249999995008 0
+468 3.404107659046966 0.6719662776496845 0
+469 2.84999999999435 0.6743750000003967 0
+470 1.69553827185582 0.6737313151850558 0
+471 9.199906991856491 0.674083829397035 0
+472 6.951679994184145 0.6762372373876401 0
+473 8.64206551591526 0.6783026862514169 0
+474 8.098320005815939 0.6762372373876404 0
+475 5.856300721221977 0.669681659038336 0
+476 6.40272068833024 0.6743589892498945 0
+477 5.304924497794906 0.6755630800033098 0
+478 9.195309532237422 0.3257868506881895 0
+479 5.300750818336451 0.3278685971749584 0
+480 5.850750818336455 0.3278685971749522 0
+481 6.945523676001898 0.3262846879235006 0
+482 6.397350630857521 0.3227622708962818 0
+483 8.099999999999975 0.3256250000000037 0
+484 8.647350630857398 0.3227622708962696 0
+485 4.765291527106597 0.3139598694665492 0
+486 1.18147565759812 0.6856545378892933 0
+487 0.773093765383302 0.6941478037260413 0
+488 0.3015479573498976 0.7024492606421152 0
+489 9.698513059289731 0.2987160489657017 0
+490 9.699568965517281 0.6995689655172894 0
+491 0.3004310344826103 0.3004310344826083 0
+492 1.219696596628405 0.2917615315165498 0
+493 0.733772231283824 0.2916097568124629 0
+494 4.477543878458116 0.2905197453066146 0
+495 4.885273625285833 0.7328319120596405 0
+496 4.410884831460763 0.7316537921349128 0
+497 3.724603209903936 0.2532771622766008 0
+498 4.213963217801012 0.2535305173297093 0
+499 2.041122701786737 0.2526671060872462 0
+500 2.513963217800962 0.2535305173290744 0
+501 7.758877298209226 0.7473328939127516 0
+502 7.286036782195088 0.746469482670797 0
+503 3.73382844889962 0.747993677410948 0
+504 2.033220105229129 0.746891984215232 0
+505 7.766779894767222 0.2531080157848409 0
+506 2.524632983319323 0.7431080631623237 0
+507 7.283220105226208 0.2531080157841133 0
+508 3.087008815267038 0.2510826926814131 0
+509 3.088350953697555 0.7477182430354211 0
+510 1.460169455693747 0.7472709671486114 0
+511 5.064565328796697 0.2501947261123621 0
+512 5.606355726862414 0.2534583823622315 0
+513 9.44549886542017 0.7476371557028576 0
+514 6.161649046296824 0.2522817569645304 0
+515 8.963300809856433 0.7485325338124637 0
+516 6.710723029652334 0.2522451244596808 0
+517 8.341821480760798 0.748061731302511 0
+518 6.710864399207321 0.7478148962786474 0
+519 6.162991184727303 0.7489173073183618 0
+520 5.608211324582692 0.7483825868432858 0
+521 8.409974621523153 0.2511237310761437 0
+522 8.959974621523266 0.2511237310761604 0
+523 9.440982058438616 0.2512852284112848 0
+524 1.458818016225601 0.2497832209353675 0
+525 0.5379814982609984 0.7561094425715044 0
+526 4.188337319823714 0.7672421443438967 0
+527 0.9987335222071869 0.2252347243805821 0
+528 0.5104466938178189 0.2307643406671599 0
+529 0.9712830368876003 0.7715058266252313 0
+530 5.105139642007704 0.7789239403886293 0
+531 0.2164999010538339 0.4999999999999974 0
+532 9.783500098946211 0.5000000000000109 0
+533 4.482889797266369 0.4880857878277239 0
+534 1.219911647937653 0.4858677802483762 0
+535 0.781255046309727 0.4964808227614237 0
+536 4.824128402664758 0.5088420234221455 0
+537 4.702761258913993 0.8011340588590384 0
+538 3.547617011847963 0.1886355947548539 0
+539 7.099609815120841 0.8051826085297122 0
+540 7.950390184879168 0.8051826085297218 0
+541 1.848040311008615 0.1964587085269267 0
+542 2.701959688983392 0.1964587085269179 0
+543 3.544416070144164 0.8002000283367942 0
+544 7.953792760135513 0.1956142995536484 0
+545 1.846207239861466 0.8043857004468352 0
+546 7.096207239860252 0.195614299551806 0
+547 2.703792760134993 0.8043857004487577 0
+548 3.87342775366692 0.5073780575316897 0
+549 2.173292304601875 0.5078638866840057 0
+550 7.626707695394852 0.4921361133157376 0
+551 4.078010125009483 0.5030883211925514 0
+552 2.38612267402175 0.5050436878897369 0
+553 7.414252120038888 0.4942808511838185 0
+554 2.771096932925257 0.4936306847863497 0
+555 1.617784801134905 0.4999999999999865 0
+556 3.477538148957801 0.4940978491968132 0
+557 8.182215198863579 0.5000000000000233 0
+558 8.732215198863509 0.5000000000000253 0
+559 6.48462398960972 0.5028020736419826 0
+560 5.217784801136348 0.5000000000000641 0
+561 9.278675653778635 0.5017034427309528 0
+562 6.867784801136362 0.5000000000000471 0
+563 5.765966335436372 0.504956827266235 0
+564 8.778999868877964 0.8075966643908132 0
+565 5.431010210602491 0.81138625135396 0
+566 6.535285571069373 0.804389442018221 0
+567 5.982644230439119 0.8026390903090076 0
+568 8.518989789397535 0.8113862513539932 0
+569 3.272131485441452 0.1901410608163633 0
+570 8.789834507461682 0.1941557947103974 0
+571 8.231010210602371 0.1886137486461759 0
+572 6.531010210602409 0.1886137486463453 0
+573 5.982812875076231 0.1980198006563709 0
+574 5.43101021060237 0.1886137486464472 0
+575 3.26898978939127 0.8113862513541422 0
+576 4.625962290159 0.1796334197976945 0
+577 4.8893159441874 0.1913021811452377 0
+578 9.092608517319302 0.519878486772774 0
+579 7.046392400568211 0.5223583109319037 0
+580 5.946392400568187 0.5223583109319349 0
+581 5.396392400568165 0.5223583109319556 0
+582 6.30344116422514 0.5267420088023126 0
+583 8.555898332690807 0.5238264588386284 0
+584 7.999870947003703 0.5300734707276995 0
+585 1.797972291074456 0.4753536916400541 0
+586 3.292808827173693 0.4656408254246505 0
+587 2.954835046838423 0.4803364137354721 0
+588 1.294577003608803 0.8208477907847388 0
+589 3.897186984240525 0.1793344642091185 0
+590 2.195077551816055 0.1785635394621029 0
+591 7.604922448179833 0.821436460537728 0
+592 0.1690496265403879 0.8231385953512296 0
+593 9.829534690638646 0.1791902801706995 0
+594 9.82953469063867 0.8208097198292886 0
+595 0.1734030112728576 0.173242031302223 0
+596 2.188715660953252 0.8173567085858814 0
+597 3.890911372716216 0.8244867905995334 0
+598 7.610349997497245 0.1726408203994202 0
+599 3.229877515508775 0.6378160530944251 0
+600 6.0192087535928 0.3615450947669709 0
+601 5.467531415459707 0.3569836956829541 0
+602 2.934310127771645 0.1733491995091337 0
+603 2.926969957088417 0.8279906846385793 0
+604 5.211195929504441 0.1703397198931947 0
+605 5.765689872222918 0.1733491995089993 0
+606 6.311327673860813 0.1698230051001209 0
+607 6.865689872222939 0.1733491995090737 0
+608 9.284809048754598 0.8246445575461595 0
+609 8.179270574021487 0.8297905125517524 0
+610 6.870729425978591 0.8297905125517582 0
+611 5.765689872222966 0.8266508004907505 0
+612 6.319362528595591 0.8221774026844444 0
+613 8.563525007835201 0.1743152474342938 0
+614 1.61133398536331 0.8302653295808717 0
+615 9.11558364545297 0.1703538256037047 0
+616 4.643168085738238 0.4435438895964657 0
+617 1.619718189509215 0.1752800529034305 0
+618 2.359697201326786 0.8322302093296051 0
+619 7.4444846285629 0.1697286889097305 0
+620 9.123545797262643 0.8265559269446081 0
+621 9.283523525152372 0.1750054430459759 0
+622 7.116798194016961 0.3658099429932526 0
+623 1.866798194013518 0.6341900570050308 0
+624 7.93700660019882 0.3648328448785014 0
+625 8.821764361433949 0.6456896110194781 0
+626 6.569435777915102 0.6412753717584929 0
+627 8.817287547450272 0.356520701403465 0
+628 8.264554758472334 0.3523115262633076 0
+629 6.573411913810156 0.3522295900648488 0
+630 1.022897919956678 0.6158406047139408 0
+631 9.595970349483391 0.8350654559027345 0
+632 9.58987926801224 0.170069325858913 0
+633 2.369971869716289 0.1742391908120009 0
+634 7.430028130279563 0.8257608091879793 0
+635 4.067179789439036 0.1686738815399874 0
+636 4.359482495943295 0.166648473099871 0
+637 2.671392400563293 0.6386545802353529 0
+638 3.57860759942383 0.6386545802329808 0
+639 4.925798754352337 0.3623840530515315 0
+640 2.674091084580459 0.3583755722209621 0
+641 3.571131090911882 0.3629745938753745 0
+642 0.8462222417845408 0.1715859849843672 0
+643 0.6860811775439034 0.8342212222335778 0
+644 1.341557728098243 0.6384796278018947 0
+645 4.540574029743877 0.8346536602517675 0
+646 5.260621941433885 0.8385292989172934 0
+647 1.322792537484855 0.1632053136578535 0
+648 1.902841192191762 0.3518594319947203 0
+649 7.152841192193384 0.648140568004324 0
+650 7.897158807806582 0.6481405680043476 0
+651 0.392454133599435 0.8365157200286039 0
+652 0.370749950526682 0.5525618904084757 0
+653 9.629250049473178 0.4474381095917633 0
+654 1.123542023770052 0.8448831266926744 0
+655 0.6270307030110921 0.6232120581931563 0
+656 6.028232809417121 0.6591431344811698 0
+657 5.478232809417163 0.659143134481153 0
+658 8.479067743831193 0.6523815117459542 0
+659 3.221767190577082 0.3408568655176157 0
+660 0.3703180448468898 0.1576571107486892 0
+661 9.550054025141362 0.6347849726795337 0
+662 0.4477744840394366 0.3650027380097466 0
+663 4.334171981469223 0.3545539419676255 0
+664 5.123218407880917 0.6237282578447575 0
+665 1.146619087923367 0.155031151917063 0
+666 4.045825788112269 0.8439264517075077 0
+667 0.6549228092515382 0.1562340112519045 0
+668 0.8759213419427722 0.3312701541084143 0
+669 0.155441150546656 0.6431126008992799 0
+670 9.844558849453309 0.3568873991007001 0
+671 9.842915214461156 0.6389120656714984 0
+672 0.1576730062711758 0.3590781547327187 0
+673 2.997070103297611 0.6244530782715381 0
+674 6.252929896696918 0.3755469217277503 0
+675 8.499257315055655 0.3760097639045081 0
+676 9.052929896697034 0.3755469217276394 0
+677 1.358179332868707 0.3605547599820908 0
+678 0.5959808887349669 0.3646563443849989 0
+679 4.280590075963453 0.6524018949153594 0
+680 0.8386052474869616 0.8479544010744662 0
+681 4.313425598518642 0.8484648929592054 0
+682 1.520869140205245 0.3832739753938342 0
+683 4.97398790275571 0.8489261712970225 0
+684 1.521392400566691 0.6133495896836937 0
+685 5.121392400568095 0.3866504103164812 0
+686 5.674123815411973 0.3876977073732628 0
+687 6.771392400568134 0.3866504103164936 0
+688 8.243632977908522 0.6355266792403176 0
+689 9.339876662462641 0.6392148094350276 0
+690 6.809228121246596 0.6391664199243745 0
+691 5.706367022091527 0.6355266792403891 0
+692 9.374997127274259 0.3829055742525506 0
+693 1.1122718428724 0.3946254699099378 0
+694 3.413940492792351 0.1436699989309773 0
+695 3.408765679885237 0.8541049923642942 0
+696 8.090556241250392 0.144825227241458 0
+697 2.136737340671246 0.3627295291490304 0
+698 3.772658142298661 0.3987461241839007 0
+699 7.663262659324843 0.6372704708508136 0
+700 2.418827180999553 0.3642229410638813 0
+701 4.113015914275048 0.362821813594386 0
+702 7.38549975948659 0.6360358311947402 0
+703 0.8841552183155736 0.5868177157665101 0
+704 2.490091356416006 0.6061293353119555 0
+705 7.314137156406193 0.3900899083729132 0
+706 2.070205094219137 0.6078599847697252 0
+707 7.729794905777838 0.3921400152303892 0
+708 3.770205094213505 0.6078599847690132 0
+709 4.11575836059407 0.6433746158345833 0
+710 4.498885676445229 0.1413244263935857 0
+711 4.832388872936544 0.8612169347841719 0
+712 9.564173840885777 0.3251054415020542 0
+713 4.511098012849269 0.6326865759324506 0
+714 8.648155267024029 0.858869714277732 0
+715 9.066494928838489 0.6610680296437775 0
+716 6.2624241949476 0.6550414503077703 0
+717 2.983182298445413 0.3383066185245293 0
+718 4.785276139218392 0.6451824803165739 0
+719 4.922957486141573 0.5986157483049962 0
+720 4.767831165019608 0.137863776454347 0
+721 0.486599459106605 0.6292246441214339 0
+722 3.669428695884489 0.1347705334936773 0
+723 1.969076459963331 0.1333274296234274 0
+724 2.584450219413389 0.1332693122053699 0
+725 7.831083354105248 0.8665990959337568 0
+726 7.219428695888782 0.8652294665065227 0
+727 3.666173676806756 0.8654167348789555 0
+728 1.966392913156282 0.8604898240016454 0
+729 7.832245929462478 0.1409251032027161 0
+730 2.582671728268592 0.8654623162292924 0
+731 7.217328271726725 0.1345376837709534 0
+732 3.149001004529248 0.1314273266365487 0
+733 8.901015845851118 0.867519024764336 0
+734 8.403350586792103 0.8668670420075129 0
+735 6.645634681193093 0.8681355596128106 0
+736 5.551015845851177 0.8675190247643486 0
+737 6.098895308791814 0.8704698888150899 0
+738 3.148984154142771 0.8675190247645549 0
+739 8.902472118025342 0.1333205896095784 0
+740 5.552151070022664 0.131970201950201 0
+741 6.652914425453188 0.1319617360607131 0
+742 6.102886468818719 0.1318901145369975 0
+743 8.351015845850997 0.1324809752356674 0
+744 0.3352918265898219 0.4357186617220717 0
+745 9.673209022230857 0.5710493661455918 0
+746 5.013114078686359 0.1316850739013853 0
+747 1.413412190830997 0.8705829640344993 0
+748 2.812802718273097 0.1319026116806354 0
+749 8.057410719203668 0.8743890434435777 0
+750 6.98525634365452 0.8621794836788833 0
+751 4.611084697175735 0.3137509543560204 0
+752 1.73502513314006 0.8680805376286922 0
+753 6.992629884944956 0.132036297517184 0
+754 2.813786963453993 0.868246189707388 0
+755 4.198310807302269 0.1277336127063481 0
+756 9.408373157714751 0.869296682426144 0
+757 1.739991637296969 0.1276868129164424 0
+758 4.391774235540401 0.5860221938201229 0
+759 9.469626768770269 0.1299295013145832 0
+760 2.54094138361973 0.3754123813588162 0
+761 2.391186946458545 0.6998398577420744 0
+762 7.401970103828154 0.2957192273446532 0
+763 0.6516837296116952 0.4811666364825805 0
+764 1.497733584594977 0.1300269477453789 0
+765 3.852919148031527 0.7037136979846949 0
+766 2.155409137029328 0.7102156416372459 0
+767 7.644590862967227 0.2897843583629759 0
+768 9.710399408231559 0.876289544252698 0
+769 9.710399408231488 0.1237104557472336 0
+770 5.010162027326325 0.6957206721720511 0
+771 3.851765488606839 0.2928824328033652 0
+772 4.602584596001142 0.7255590284772507 0
+773 0.5699786094543091 0.8767740848077031 0
+774 1.100801037360065 0.5266552285500364 0
+775 6.427848754627997 0.8766141587869311 0
+776 5.877848754627969 0.876614158786946 0
+777 8.675655253439196 0.1272470158080186 0
+778 6.425655253439332 0.1272470158082739 0
+779 5.877848754628046 0.1233858412135872 0
+780 5.327848754628066 0.1233858412136875 0
+781 8.944073300527728 0.6215190991043934 0
+782 3.105304199027532 0.3790326670291977 0
+783 6.144695800966657 0.6209673329704027 0
+784 3.799177437676519 0.1239942648646494 0
+785 7.709590370201393 0.8786548252820149 0
+786 2.090409629794871 0.121345174717628 0
+787 0.2816511474572365 0.8759975473050119 0
+788 4.429412624652155 0.8812419129259526 0
+789 3.785783456983805 0.8813347001423747 0
+790 2.08578345698605 0.8813347001423125 0
+791 7.714216543010698 0.1186652998578255 0
+792 1.58333048369615 0.2824812018371142 0
+793 9.312681313933961 0.2877169985458785 0
+794 0.9496516850066973 0.1168760035953118 0
+795 6.6864012248694 0.6208201467864438 0
+796 8.354953647406459 0.6198710839899033 0
+797 5.589104911656348 0.6236156890643463 0
+798 5.187337659617425 0.2795826496566871 0
+799 5.738014409278408 0.2799187859977197 0
+800 6.837293081671706 0.2819029479041557 0
+801 1.591268725927366 0.7116793320401992 0
+802 7.273320363275825 0.6046658209007597 0
+803 7.786619639816129 0.6142326745673186 0
+804 2.013380360180741 0.3857673254333099 0
+805 7.334427294638187 0.1160465450862105 0
+806 2.465572705357675 0.8839534549140724 0
+807 6.136168166177357 0.383501706538243 0
+808 3.113831833816396 0.6164982934610005 0
+809 4.155794513115211 0.8833290555267995 0
+810 8.938794127480456 0.3796261575822592 0
+811 8.385648663805204 0.3782697862298459 0
+812 0.4786845190787192 0.1146307559758333 0
+813 5.14635366407033 0.8798188689909391 0
+814 5.662440172155388 0.1136722565419794 0
+815 6.213053004485416 0.113605517031059 0
+816 6.768727824217456 0.1208118697699457 0
+817 6.2131066603917 0.887785304146526 0
+818 6.767257071806294 0.8787175665746734 0
+819 5.66559542211788 0.8851288992563958 0
+820 8.282742928193747 0.8787175665746768 0
+821 3.034404577876179 0.1148711007432793 0
+822 9.021281627200187 0.1083944956899632 0
+823 8.463053004485408 0.1136055170314698 0
+824 3.031272175776854 0.8791881302304293 0
+825 3.974999999996082 0.4550507389588322 0
+826 7.524999999999959 0.5449492610456296 0
+827 2.273005727174112 0.4506535717335504 0
+828 1.108708172492784 0.2794616287693025 0
+829 0.8868716366294677 0.7055376990161805 0
+830 2.866029937758507 0.5602480076242545 0
+831 1.717007667000605 0.5620496693641306 0
+832 3.388615657205206 0.5614804955009991 0
+833 8.627814715584293 0.4410237865815832 0
+834 6.383970062236904 0.4397519923759989 0
+835 8.079510867844954 0.4451268260296568 0
+836 5.316091949340987 0.4368960955434334 0
+837 5.869977423439892 0.4407465429694395 0
+838 6.973677572857993 0.439682180117116 0
+839 9.184646575916503 0.4337045487688155 0
+840 0.4123667289168142 0.7228227520705333 0
+841 1.008181376540124 0.3416914632498105 0
+842 1.015219830318336 0.8782964510292357 0
+843 2.463640520327183 0.1164375212336209 0
+844 7.336359479668396 0.8835624787662436 0
+845 9.013795851948963 0.8864734616033775 0
+846 4.228151573342599 0.3961810719907868 0
+847 5.123652148402528 0.1072982342028689 0
+848 4.519226111890424 0.3969091465925706 0
+849 0.2642107586113116 0.1109580778996508 0
+850 5.185129788145661 0.7092044203682063 0
+851 1.067775162744039 0.7163803870171168 0
+852 0.1197720141876461 0.5389919091778549 0
+853 9.880227985812292 0.4610080908220888 0
+854 1.526811076626504 0.8854238066787141 0
+855 4.634422799671617 0.8900702616226508 0
+856 4.377899117374187 0.4496730474154768 0
+857 0.4093228342755432 0.2609039926399251 0
+858 4.714121425793093 0.5200636310537334 0
+859 4.178454683136143 0.5528898055956797 0
+860 1.80974097332198 0.3010937453662946 0
+861 7.999056835104984 0.6978712565467718 0
+862 7.056635302688625 0.7015772123860812 0
+863 1.923330690281721 0.7261900638688368 0
+864 7.873387420683114 0.2689869194417422 0
+865 7.172621808744757 0.2732517108368719 0
+866 0.730933588629571 0.5875550615371061 0
+867 0.6449587940233172 0.7315077943001043 0
+868 5.355187249533478 0.8905239932340268 0
+869 2.267909220474905 0.8942745756221103 0
+870 7.531053954524845 0.09645012573937585 0
+871 0.7524346483238534 0.1093575499598149 0
+872 9.438574357812943 0.6016013682710053 0
+873 0.2774685787244202 0.5933218073342371 0
+874 9.723596387474057 0.4063854357981637 0
+875 0.6174462888446485 0.2583080367561444 0
+876 4.060570955118482 0.7365994146407349 0
+877 2.277829795567626 0.09992346809147172 0
+878 7.509817788024448 0.8988997724681201 0
+879 3.967009158048057 0.1031375283992548 0
+880 2.265831888529521 0.575223724516477 0
+881 7.534168111467283 0.4247762754832149 0
+882 3.961448709061109 0.5614125266947457 0
+883 0.1020536245254965 0.744025257998073 0
+884 9.903454195848347 0.2579395192420323 0
+885 9.88600957969563 0.7386387774435089 0
+886 0.1114703922261123 0.2565508501759365 0
+887 9.190812433204384 0.8928240209795023 0
+888 9.200961331119426 0.107644692392491 0
+889 3.629271571359367 0.2670494617806151 0
+890 2.627819723664792 0.2663996703502227 0
+891 2.947458677438315 0.7198930991324327 0
+892 6.301677320607148 0.2816483776059863 0
+893 8.552151939878126 0.2822207892560343 0
+894 9.063677338751642 0.2652926412950027 0
+895 1.214421470609538 0.8887654723872104 0
+896 4.580909711132274 0.5204178088106874 0
+897 0.8713095978759507 0.4352507731244732 0
+898 4.920371524283571 0.4655103684913237 0
+899 4.825392147101008 0.4038460431693147 0
+900 2.483116303229818 0.4481378690091752 0
+901 1.321144606868491 0.5284631719222198 0
+902 1.229170078963441 0.6040284039598492 0
+903 3.636400277390967 0.7256554438824269 0
+904 2.623044629396541 0.7341392357647358 0
+905 0.7191564560814898 0.3979107290598961 0
+906 4.053682063810402 0.2744614406261153 0
+907 2.354339472322317 0.2715572350047005 0
+908 7.445632138497966 0.7283958792100466 0
+909 9.201746724024922 0.573352762357514 0
+910 1.694659130298647 0.4241588814956734 0
+911 3.399999999992733 0.4321941169861923 0
+912 2.837945957074693 0.4305454076985892 0
+913 6.955495451191995 0.5709378674997533 0
+914 5.853385893780119 0.5674733449033966 0
+915 5.299999999999986 0.5678058830131445 0
+916 8.094211948522277 0.5752706494027803 0
+917 6.402154541260812 0.5698525089980319 0
+918 8.649129196058675 0.5695787631258608 0
+919 1.260004413570992 0.3943973325044675 0
+920 3.885143525613256 0.399155266932717 0
+921 3.4967539210839 0.3004450233208694 0
+922 2.753409969864845 0.2928159872227278 0
+923 1.234501472292477 0.1047486796587173 0
+924 3.499900609224502 0.7067503287458643 0
+925 2.751326999079028 0.7078570767312499 0
+926 9.504187623355481 0.8912828191495176 0
+927 2.770981435013805 0.605087032614359 0
+928 3.479018564972879 0.6050870326144039 0
+929 9.483258039900951 0.3953165643782303 0
+930 5.886779838998835 0.7751686505370522 0
+931 6.438267164646747 0.7714698691012669 0
+932 8.688538256520264 0.2280915732668652 0
+933 6.438538256520478 0.2280915732670519 0
+934 5.887724211427256 0.2304765359445681 0
+935 5.337724211427291 0.2304765359446422 0
+936 1.754591281335928 0.76690448008968 0
+937 7.004591281335681 0.2330955199097756 0
+938 9.367268927129116 0.1033733625041886 0
+939 8.828607599431702 0.5407215070782788 0
+940 6.575857559637913 0.5373343271888544 0
+941 8.283588497224402 0.4621316459084001 0
+942 8.001076123513437 0.2852856404407899 0
+943 2.348613704348856 0.6041527407306639 0
+944 7.453243929110142 0.3868200900199393 0
+945 9.573157236364459 0.5354409536644044 0
+946 5.500592738300004 0.2653289760885719 0
+947 6.050323179492803 0.2592433764767432 0
+948 3.198397720953515 0.7382102888967912 0
+949 3.299311309125453 0.7071613744440582 0
+950 8.720615194937139 0.3957361224415545 0
+951 6.469658605073944 0.3985244904844331 0
+952 8.170215165293737 0.3980433405742956 0
+953 1.969464870068749 0.599942568133727 0
+954 7.216604718764748 0.3966422375724072 0
+955 7.830535129927974 0.4000574318665838 0
+956 5.578390565929439 0.3499667346893605 0
+957 6.668218944831308 0.3965725910153698 0
+958 8.746779806324223 0.713393657744519 0
+959 8.185038275579648 0.2803760369974497 0
+960 6.771392400568195 0.5379969837195986 0
+961 5.671392400568187 0.5379969837196026 0
+962 3.506565730689533 0.1005222270731675 0
+963 8.23750969141417 0.7383947222695647 0
+964 9.337509691414221 0.7383947222696118 0
+965 6.812490308585843 0.7383947222696114 0
+966 5.710492139310598 0.7414466406345005 0
+967 3.217734690133049 0.5376598773962219 0
+968 6.029262835401692 0.4639637988743506 0
+969 5.479472762867909 0.4614637176359149 0
+970 8.852605110661582 0.7412988644000412 0
+971 6.607299126484939 0.7423592242872206 0
+972 8.851019380527843 0.2578103828707607 0
+973 8.302014180219052 0.2589315521974974 0
+974 6.601144011473353 0.2597044507737227 0
+975 2.672282890385684 0.5320843007551112 0
+976 3.579566238259984 0.5342271385361553 0
+977 4.865635792094654 0.2798318504547465 0
+978 3.50511081379044 0.9038097262249153 0
+979 7.996183191541139 0.09630587115354564 0
+980 1.054182784750804 0.1026615732182947 0
+981 7.180786441657336 0.7445439254597737 0
+982 7.866691760945714 0.7462474583139409 0
+983 1.933308239050742 0.2537525416850273 0
+984 1.633194517890775 0.5993145356960465 0
+985 5.233402837682492 0.4005196003750292 0
+986 5.782288469820391 0.4027633321870296 0
+987 6.883692524271915 0.4000184472228077 0
+988 9.269535277726169 0.3975446399402564 0
+989 0.09797584461925765 0.9025975509220073 0
+990 9.897343863512312 0.1026561364877211 0
+991 9.897343863512294 0.8973438635122891 0
+992 0.09689283781673137 0.09964360737782814 0
+993 1.366736738495928 0.2571384512539909 0
+994 2.140317464393025 0.2610337983047785 0
+995 7.659682535602922 0.738966201695102 0
+996 0.4302816038464583 0.4629398409994273 0
+997 1.358021804897507 0.7393529053370164 0
+998 4.787443931217997 0.7436113020331361 0
+999 5.395434883807368 0.7171905263498608 0
+1000 8.556653346586744 0.716258526793849 0
+1001 3.306653346580351 0.2837414732050502 0
+1002 9.541906388127462 0.739570628386168 0
+1003 3.674791690806167 0.3562657138990394 0
+1004 7.732753002419664 0.5289496721494767 0
+1005 2.067246997577106 0.4710503278510287 0
+1006 7.328797802121198 0.5240862643770704 0
+1007 2.276723693489252 0.7774532117123119 0
+1008 7.519397653653153 0.230181353541429 0
+1009 3.318404701891871 0.09923283818205036 0
+1010 1.707340214173044 0.2240989549601659 0
+1011 8.454673165258328 0.5508270458911612 0
+1012 9.378607599431906 0.532523770276455 0
+1013 3.956793341418138 0.9056840565811393 0
+1014 0.4697630075914747 0.9014821257147698 0
+1015 8.177645617208563 0.09448301247072791 0
+1016 3.319983829432994 0.9107162598402445 0
+1017 7.124619859646564 0.9015152869451711 0
+1018 7.925380140353418 0.9015152869451777 0
+1019 1.874619859643537 0.09848471305459644 0
+1020 2.675380140348479 0.09848471305458835 0
+1021 2.847150129060637 0.7657574119916335 0
+1022 1.403226261126306 0.1013911520476122 0
+1023 4.730084346729286 0.9015874961963957 0
+1024 2.851590188629002 0.2179135378313631 0
+1025 6.953244089826027 0.775648926050571 0
+1026 8.099355578800308 0.7848317307345445 0
+1027 4.286000333867424 0.1001307642515442 0
+1028 1.873091004808564 0.9017083705225617 0
+1029 7.123091004807436 0.09829162947637624 0
+1030 2.676160797666165 0.8983645759602168 0
+1031 7.132008228097444 0.4671798556846657 0
+1032 1.887551763831555 0.5317431624741745 0
+1033 7.911471537956805 0.4674065069698962 0
+1034 9.201614268678441 0.7714914939895461 0
+1035 9.202222424229291 0.2249167367581667 0
+1036 4.282305803629535 0.7528956074149702 0
+1037 2.171858029818762 0.6092986238297178 0
+1038 7.628141970178105 0.3907013761703818 0
+1039 3.875083274653653 0.6083574488572637 0
+1040 9.902391496983263 0.5590564999916023 0
+1041 0.09760850301662062 0.4409435000083599 0
+1042 4.693646229041232 0.6983887994590759 0
+1043 2.579404330844261 0.6476666143905712 0
+1044 3.677116548841837 0.6466851000834714 0
+1045 3.203644246557045 0.4450938867111517 0
+1046 6.037209736513934 0.556110227445817 0
+1047 5.492655571691823 0.5582571834014477 0
+1048 5.93528117975506 0.6218819038123468 0
+1049 5.022045277060927 0.3972033805306975 0
+1050 4.317353901377812 0.261543096886336 0
+1051 4.959310937858155 0.255057301803898 0
+1052 9.017327591633792 0.4773078303201124 0
+1053 6.223168017961723 0.4782563330103204 0
+1054 3.026831982032411 0.5217436669890072 0
+1055 5.121392400568183 0.5239550988210496 0
+1056 6.05615176777834 0.7454296037698073 0
+1057 5.510920629406412 0.752727490471191 0
+1058 8.439079370593639 0.7527274904712301 0
+1059 3.196186115823688 0.2499688807004046 0
+1060 1.208087592254619 0.7788506165951099 0
+1061 0.2063560772887988 0.7306557621240342 0
+1062 9.793643922711134 0.2693442378760341 0
+1063 9.788533766954147 0.7279746248784608 0
+1064 0.2063560772888402 0.269344237875925 0
+1065 8.739984088753136 0.9014971850118543 0
+1066 8.560015911246895 0.9014971850118632 0
+1067 0.9206820521428879 0.9032306132427997 0
+1068 4.587876842906619 0.091288144742717 0
+1069 4.726404074002581 0.2303887158091769 0
+1070 0.5741065750616468 0.09544809124907527 0
+1071 3.769885038275676 0.4895117232188005 0
+1072 0.7541799476081342 0.9051737001346341 0
+1073 1.424419722467132 0.5981542726327265 0
+1074 5.030617716755092 0.6024264157703995 0
+1075 1.521392400566706 0.4836602106336062 0
+1076 3.323078119500063 0.3773905348275628 0
+1077 5.383105675475295 0.6191236345544817 0
+1078 8.568199652574201 0.6198776679814634 0
+1079 5.058728739707893 0.9004718727799832 0
+1080 1.62090292913255 0.370128423147336 0
+1081 4.42832761320987 0.3722138120453406 0
+1082 4.508429011310015 0.7452969292668725 0
+1083 5.46099385259441 0.09636969847488797 0
+1084 6.01099385259452 0.09636969847489751 0
+1085 6.560993852594601 0.09636969847494678 0
+1086 8.810993852594903 0.09636969847505472 0
+1087 6.560993852595095 0.903630301524856 0
+1088 5.4609938525951 0.903630301524864 0
+1089 6.010993852595067 0.903630301524872 0
+1090 4.733581020344665 0.4047896506709576 0
+1091 5.943739201633544 0.3014828291394314 0
+1092 5.393739201633502 0.3014828291395358 0
+1093 3.968023847328683 0.7625330326191539 0
+1094 2.764907729003708 0.3863793109788893 0
+1095 3.482200819228765 0.3905741165546065 0
+1096 2.271521539062964 0.2473880986156212 0
+1097 7.528478460933123 0.7526119013838927 0
+1098 3.970927916055819 0.244729744499719 0
+1099 6.491372129154812 0.6929586133409223 0
+1100 6.256390809598039 0.745225579355841 0
+1101 2.993832990170146 0.2489451686680492 0
+1102 0.2796349259585124 0.2043770749176417 0
+1103 4.852497506603047 0.09586254246595177 0
+1104 8.743653511959973 0.3013701472413153 0
+1105 6.49434703190308 0.3000861783695338 0
+1106 5.218974364843493 0.6243689796942151 0
+1107 9.055474030050917 0.7491254222547679 0
+1108 8.725641983397463 0.6281058029696359 0
+1109 1.115583834935889 0.6092951362891293 0
+1110 8.458976627807548 0.4636857153438183 0
+1111 6.484783800789138 0.5886588275503534 0
+1112 8.852669594921982 0.449528856558251 0
+1113 4.547255587892531 0.2222550234004959 0
+1114 0.7709986884283341 0.7874886360105416 0
+1115 8.296832156366204 0.5526943035342723 0
+1116 4.417685557675471 0.08824360877992075 0
+1117 8.660347708111638 0.7593025583038151 0
+1118 9.013374053460572 0.5729781950330834 0
+1119 0.2349673295802572 0.4075392956135419 0
+1120 9.765032670419901 0.5924607043864091 0
+1121 6.555840184654148 0.4464461339195119 0
+1122 1.238052738892907 0.1970990399397134 0
+1123 1.272935652716031 0.7059916098083372 0
+1124 6.223961362260051 0.567470290815571 0
+1125 3.036407087520135 0.427353518928436 0
+1126 0.9547135987987223 0.5401967043658182 0
+1127 0.9044087006510035 0.2390034254544241 0
+1128 0.8187763483333139 0.2593305691158495 0
+1129 1.340592719627352 0.9159640890544613 0
+1130 0.3154777704549517 0.7904044302519373 0
+1131 3.377585034794977 0.7629128439632091 0
+1132 4.161745128814085 0.4613561903421154 0
+1133 4.673762074155774 0.08741273401397616 0
+1134 8.112909845024172 0.237326680118717 0
+1135 5.960316359457609 0.7171579318299154 0
+1136 9.668829406036432 0.21111414038295 0
+1137 9.672727421727222 0.7883125215067196 0
+1138 1.883212540397345 0.4436446095118923 0
+1139 7.151514198809333 0.5558497447605721 0
+1140 7.916787459600839 0.556355390487795 0
+1141 7.041500760540989 0.3137520085899285 0
+1142 1.791500760537952 0.6862479914080204 0
+1143 7.030303343846039 0.6131800063127482 0
+1144 8.019815806665413 0.6182084136602539 0
+1145 1.781262171923929 0.3867608589588063 0
+1146 0.7337857518875398 0.2002936502633889 0
+1147 3.868704060594455 0.08609204606518882 0
+1148 2.168080574806102 0.08853449821750928 0
+1149 7.61663900015178 0.9100174769790664 0
+1150 3.429643586475336 0.2368844043765951 0
+1151 9.324105670927409 0.9111037567165691 0
+1152 4.244301860527706 0.9110252552948782 0
+1153 5.345010816308191 0.7946774887552641 0
+1154 3.321497198669015 0.6244244493968933 0
+1155 3.228843166688361 0.0886204945537178 0
+1156 2.895378433659187 0.09098473771686569 0
+1157 8.145378433664314 0.9090152622829755 0
+1158 6.904621566335792 0.9090152622830283 0
+1159 9.525926230208679 0.2481108712517434 0
+1160 9.79685325680413 0.9078971152909124 0
+1161 9.796853256804051 0.0921028847090497 0
+1162 1.654168216827872 0.9122949307664358 0
+1163 2.896415297077262 0.9092204834003921 0
+1164 6.903087986952523 0.08891695324633089 0
+1165 3.228234827299948 0.9118433601087881 0
+1166 8.272028497853086 0.08866585507286052 0
+1167 0.521414902511702 0.3182077188191916 0
+1168 1.445481451296553 0.3365359332817964 0
+1169 1.580981944369599 0.09212787804681012 0
+1170 9.630900077617151 0.9153689852010396 0
+1171 9.626589713896161 0.08298815925951841 0
+1172 2.172036356566428 0.9081374518964777 0
+1173 7.636073780047811 0.09070894979607587 0
+1174 0.3661052940909629 0.6443822655359728 0
+1175 4.902299695960685 0.9121398434229087 0
+1176 3.86431432263896 0.9099783806013142 0
+1177 2.698334499377164 0.4468039599701591 0
+1178 3.603991805419499 0.4485900386533035 0
+1179 0.7951626498709321 0.3483628897683213 0
+1180 5.953236675721854 0.419265155658802 0
+1181 5.39790437566977 0.4162314269285761 0
+1182 3.586148386530797 0.08850704291294247 0
+1183 3.813625162640775 0.207969292790774 0
+1184 4.44025512145562 0.2090616474847614 0
+1185 8.021464602537481 0.3756775936841785 0
+1186 4.11002076048384 0.08713438975908848 0
+1187 3.590421161896058 0.9110905692479534 0
+1188 7.90927138114312 0.08523930384179816 0
+1189 4.196198810358308 0.6792560200404052 0
+1190 6.344503922335183 0.9110177962401703 0
+1191 5.796934453928326 0.9098512458351857 0
+1192 8.596804518859324 0.08456230997899671 0
+1193 6.346804518859816 0.08456230997878957 0
+1194 5.796934453928944 0.09014875416435683 0
+1195 5.244503922335757 0.08898220376003814 0
+1196 0.1995494976918412 0.9116921259506984 0
+1197 0.5199598749290806 0.4110719424371932 0
+1198 0.9747005565528359 0.6907399209438131 0
+1199 1.328137153341573 0.4442694697463191 0
+1200 9.373857156709903 0.1921046838636485 0
+1201 1.536062880972406 0.8048888301372732 0
+1202 4.04259124647511 0.5913812066783469 0
+1203 2.107268890380905 0.7954377348776932 0
+1204 3.813231588180361 0.7900082669864533 0
+1205 7.692731109615494 0.2045622651223432 0
+1206 6.344209490164359 0.7429634000201885 0
+1207 5.127265275470333 0.1967013897581864 0
+1208 2.373255368064931 0.9095056305912715 0
+1209 7.420966855348262 0.08989144240409622 0
+1210 8.470324624450805 0.9180568740613374 0
+1211 8.826946379173636 0.9150594067561594 0
+1212 4.813442580548323 0.21737277990216 0
+1213 3.017694297752662 0.7988284330155438 0
+1214 5.682305702241944 0.2011715669847009 0
+1215 6.232305702241979 0.201171566984764 0
+1216 6.786786795740863 0.1995840911220728 0
+1217 8.482305702241936 0.2011715669849314 0
+1218 7.052524727350477 0.4249777214381773 0
+1219 1.802524727348392 0.5750222785603455 0
+1220 0.8728011026503273 0.08108878447645647 0
+1221 0.652032441222357 0.9134782902428916 0
+1222 4.93703876511996 0.07899859594605377 0
+1223 5.798763695069393 0.7460204829262508 0
+1224 9.098992329304455 0.0828221171357766 0
+1225 2.443517240638722 0.7988151844931227 0
+1226 7.351746068575703 0.2058332512147071 0
+1227 1.539457555912121 0.2048012953360123 0
+1228 4.26511876076 0.1842016984326775 0
+1229 2.431735431357592 0.2263866726856309 0
+1230 4.128951810008872 0.2344173682323016 0
+1231 7.368264568638446 0.7736133273142206 0
+1232 9.093962364664572 0.9145748604037506 0
+1233 9.642627012913225 0.3587040796441973 0
+1234 1.662757667089563 0.7496569169096259 0
+1235 6.917877700285286 0.2451510578712051 0
+1236 2.383734180160873 0.08438891890323043 0
+1237 7.416265819834795 0.9156110810968098 0
+1238 4.040979438564739 0.3907817640631691 0
+1239 2.213172037705867 0.3993338727279612 0
+1240 2.34213073511094 0.3893646698089988 0
+1241 7.460932227490368 0.6027871305228768 0
+1242 7.589067772509554 0.6027871305228344 0
+1243 4.507395457888714 0.9134776601093049 0
+1244 0.3556083835352742 0.9211062090965834 0
+1245 9.280945986108074 0.08697675055060552 0
+1246 0.1899429681739539 0.07874813215525042 0
+1247 4.393598800730065 0.2894366269717669 0
+1248 0.5600012071771625 0.6734043431914687 0
+1249 0.5538379505496925 0.5869797709601254 0
+1250 0.4737636467403332 0.8127407151285359 0
+1251 5.234214516403394 0.9161254209754228 0
+1252 0.4574626705662553 0.5492925252566723 0
+1253 3.462036385999782 0.7854564078168939 0
+1254 5.020042488549805 0.7802527233527519 0
+1255 4.689784587415069 0.3364690120822927 0
+1256 9.614843596368491 0.6963388648090686 0
+1257 1.668207950614241 0.08272307029347692 0
+1258 8.03781409753508 0.2056063737604844 0
+1259 1.401618054074141 0.1868674379661285 0
+1260 9.541347655086811 0.4534633624575446 0
+1261 9.497072917428536 0.8110851332705306 0
+1262 9.544938543125634 0.09143379394778721 0
+1263 5.184662838665716 0.7970058464519166 0
+1264 5.261244580226923 0.7537259725367899 0
+1265 2.619389636688991 0.4308455089239185 0
+1266 4.901231831071173 0.8145882293166193 0
+1267 1.42567389396372 0.4177502849728216 0
+1268 0.2929574804017542 0.5025480993507047 0
+1269 9.706930452612008 0.4973046329297882 0
+1270 4.619485817487942 0.807336918685979 0
+1271 1.322822929578392 0.08000685954990773 0
+1272 2.914236053428131 0.2728784161160928 0
+1273 9.025162368969017 0.1999516744745277 0
+1274 4.080901696548188 0.9191902570600706 0
+1275 4.312404446644865 0.5782659506862171 0
+1276 4.386755237874041 0.8105839274858934 0
+1277 4.357012501080477 0.6619782778700729 0
+1278 5.00830261350989 0.3164091061958987 0
+1279 3.35498361196039 0.2023937129150092 0
+1280 9.135579212146384 0.724314035529565 0
+1281 0.08083211276605271 0.816740456772829 0
+1282 9.919565106500013 0.1820233182411789 0
+1283 9.919565106500103 0.817976681758794 0
+1284 0.08043489349988231 0.1820233182412086 0
+1285 1.094358506570013 0.917815058024946 0
+1286 4.866060774669254 0.6526101560091683 0
+1287 1.414626361270174 0.6817422323788995 0
+1288 0.4030844526509201 0.08220335917218419 0
+1289 2.912658288470344 0.3789095584928421 0
+1290 9.26206867577949 0.6234519391296051 0
+1291 9.135534385829825 0.6243939876065797 0
+1292 8.161466940086106 0.6281816424099413 0
+1293 6.888621799165451 0.6280790322330534 0
+1294 5.78734171152399 0.6210904415066121 0
+1295 6.337386931367361 0.6221619540704459 0
+1296 0.3618802550228964 0.3547905958419226 0
+1297 4.356317237479963 0.9182939374484015 0
+1298 0.897250147212592 0.793540354385087 0
+1299 0.6050587514819641 0.8028970273260273 0
+1300 2.945430653300356 0.5596681606093188 0
+1301 6.304569346694824 0.440331839389723 0
+1302 8.54861170265599 0.4448592356187249 0
+1303 9.100261819599037 0.4380095835457201 0
+1304 4.259815609321276 0.3210008126860023 0
+1305 9.484778769539314 0.6785952842223533 0
+1306 0.8519507296321727 0.5076707909693006 0
+1307 1.0543200477296 0.7984053985827967 0
+1308 0.6729083476946491 0.07890716476480164 0
+1309 5.091382955273861 0.6988166511293636 0
+1310 2.015633198421373 0.6693796602586612 0
+1311 7.784366801575421 0.3306203397414539 0
+1312 7.265702376928225 0.3322033763674328 0
+1313 0.07973314678986762 0.6143000360271021 0
+1314 9.92026685321018 0.3856999639728226 0
+1315 0.6972177415197366 0.6641730585290893 0
+1316 2.197886621501271 0.3210940132147425 0
+1317 7.602113378494717 0.6789059867849488 0
+1318 1.050684557733905 0.4513499993262554 0
+1319 3.028172825727972 0.6969772545038846 0
+1320 6.221827174266609 0.3030227454956757 0
+1321 8.474261588662133 0.3000301610183283 0
+1322 9.119319367598903 0.3295350625281987 0
+1323 6.65856281002546 0.3151406891112122 0
+1324 5.255467698329588 0.2455056570582304 0
+1325 5.80558858108377 0.2455687186681657 0
+1326 9.606240910107848 0.2577173584317954 0
+1327 8.278794928367855 0.8072201500563552 0
+1328 6.771412412139651 0.807360486589189 0
+1329 5.667493789121079 0.804874925211994 0
+1330 1.298466271022606 0.3069773927304827 0
+1331 9.923490005312576 0.6592015456028308 0
+1332 0.07526747113800566 0.3389958722498989 0
+1333 3.724179719193985 0.07633757876264137 0
+1334 7.774358373069213 0.925508464986481 0
+1335 2.025641626927192 0.07449153501339946 0
+1336 8.99082067946622 0.3250135174175403 0
+1337 5.697247926232499 0.4623236970180365 0
+1338 6.742454760687727 0.462124054002361 0
+1339 5.602120383563557 0.4181199066091606 0
+1340 9.43590533467844 0.3309365642786926 0
+1341 1.9844195454032 0.3156618365468492 0
+1342 7.815195183225327 0.685141682238726 0
+1343 7.234375743223527 0.6811701738218775 0
+1344 0.5807822081540095 0.1777728729199378 0
+1345 1.132590432509096 0.07363842095280194 0
+1346 0.4445449191332682 0.1866259763429388 0
+1347 4.236171818433139 0.8292341687333851 0
+1348 2.918001238473659 0.6331114120188717 0
+1349 8.584298498124072 0.3702356743575648 0
+1350 6.334298498124116 0.3702356743575422 0
+1351 1.077522637584689 0.2103953196349466 0
+1352 2.603846328068153 0.575132629744648 0
+1353 3.647913401257194 0.5747148957466161 0
+1354 0.8047667427540702 0.6165290222649297 0
+1355 6.890823987804183 0.7269594964743967 0
+1356 8.159176012195891 0.726959496474381 0
+1357 0.9395501709565416 0.3811114166576227 0
+1358 9.260858797436542 0.7230826325211245 0
+1359 2.503199331144571 0.5325709641500843 0
+1360 2.75173043253923 0.07882244332508967 0
+1361 8.001730432544267 0.9211775566747692 0
+1362 7.048269567455737 0.9211775566747996 0
+1363 4.465083865396021 0.8099983164565033 0
+1364 9.750429313904313 0.2014696003861693 0
+1365 9.751031763449204 0.7969105759556059 0
+1366 4.112099080559044 0.7925138662767937 0
+1367 1.170341952814511 0.5531366059684836 0
+1368 8.597091341583845 0.8019781395255942 0
+1369 1.183683741639446 0.3616777898647829 0
+1370 8.391923202276081 0.6898238368940466 0
+1371 5.558952869790807 0.6876757203796577 0
+1372 4.300964708387993 0.4258037206613771 0
+1373 2.019780828928624 0.9239604200666024 0
+1374 7.780219171068223 0.07603957993354153 0
+1375 3.719780828926052 0.923960420066012 0
+1376 9.412191560719688 0.455896216440384 0
+1377 1.79714102689964 0.921552476418924 0
+1378 2.752858973095679 0.9215524764197571 0
+1379 7.047141026899328 0.07844752358034807 0
+1380 0.189026194910785 0.577945762999047 0
+1381 9.81097380508918 0.4220542370009517 0
+1382 3.141121092694582 0.3115893090712608 0
+1383 6.109036680919353 0.6861554123070878 0
+1384 1.509074406723581 0.6925629167526985 0
+1385 5.109070775440135 0.3072595339502479 0
+1386 5.66074520055771 0.3074732695576148 0
+1387 6.759264587706591 0.3074968179027018 0
+1388 8.309846358799673 0.6778727626417056 0
+1389 5.640121507022412 0.676852351199593 0
+1390 6.740722858455707 0.6766665746101733 0
+1391 2.06276158798831 0.3267906981423575 0
+1392 7.737238412007638 0.6732093018575832 0
+1393 7.313320588859828 0.6681917949769318 0
+1394 2.099754301331176 0.1928989271830768 0
+1395 7.700245698664872 0.8071010728166885 0
+1396 2.512521417896072 0.1755104553922059 0
+1397 7.287321051808521 0.824207610945333 0
+1398 1.801081705132342 0.07533781047703619 0
+1399 1.158469406224541 0.4589553741342307 0
+1400 3.70602104789771 0.4288476566184082 0
+1401 3.735230858386777 0.1759235311963927 0
+1402 2.487790008393906 0.3303418828400448 0
+1403 3.781068211945874 0.316702358413263 0
+1404 3.735765117367345 0.8267393988472932 0
+1405 2.035885555243287 0.8266877018468889 0
+1406 7.764114444753499 0.173312298153215 0
+1407 1.164743217035401 0.2301744051507063 0
+1408 0.8304133004913958 0.9246598008152165 0
+1409 7.270427277172581 0.07346906918412821 0
+1410 2.529572722823062 0.9265309308160306 0
+1411 0.6640436809850125 0.3379153037288923 0
+1412 3.083940223330968 0.1741287759001346 0
+1413 6.169334674786912 0.8246206551212741 0
+1414 8.966002950796996 0.8258429848411849 0
+1415 1.130716476909433 0.7641404957462418 0
+1416 4.441996767532093 0.6588855657713367 0
+1417 3.77393593403755 0.6890785827361289 0
+1418 2.474271139424336 0.6877491957547786 0
+1419 9.405253333639049 0.6816156068838664 0
+1420 4.464452284142832 0.5751683978057321 0
+1421 5.087280820057898 0.4553027545687932 0
+1422 8.912236154161695 0.3110886122695723 0
+1423 8.362236154161687 0.3110886122695561 0
+1424 4.585551916303829 0.6508406183171388 0
+1425 0.6616951496497896 0.5550100300044746 0
+1426 7.283779724663682 0.1773499901415275 0
+1427 2.516361355812633 0.8222661861669119 0
+1428 6.82801723201983 0.9269340348989756 0
+1429 8.221982767980236 0.9269340348989581 0
+1430 2.969890986416825 0.07382936969496608 0
+1431 4.177887992542596 0.3239459131384522 0
+1432 2.530071145125244 0.07295807022404149 0
+1433 7.269928854870146 0.9270419297758932 0
+1434 6.662206124609451 0.6893845008254645 0
+1435 7.993726654959147 0.446728078476022 0
+1436 1.92242539182837 0.803873351572842 0
+1437 7.877574608168716 0.1961266484271381 0
+1438 7.172425391826406 0.1961266484250011 0
+1439 3.424999999992664 0.0719646785609707 0
+1440 6.82944209904753 0.07333933661525764 0
+1441 2.970557900946968 0.9266606633849835 0
+1442 6.487970721499136 0.9248996668712705 0
+1443 5.9379707214991 0.9248996668712907 0
+1444 8.737970721498922 0.07510033312889158 0
+1445 6.487970721498702 0.07510033312926187 0
+1446 5.937970721498647 0.07510033312932569 0
+1447 5.387970721498549 0.07510033312940134 0
+1448 3.136861937949401 0.688969586090833 0
+1449 6.113138062045063 0.3110304139086894 0
+1450 3.428824574694609 0.9285688676868609 0
+1451 8.075176926880864 0.06866417590247585 0
+1452 9.383102918735196 0.7990387716491164 0
+1453 8.021022532547384 0.7744925473459419 0
+1454 7.02897746745271 0.7744925473459517 0
+1455 4.722392643890726 0.6042845280692847 0
+1456 4.837604956408103 0.5825092756004389 0
+1457 8.907948015451909 0.6918301239486535 0
+1458 0.2295251359491669 0.6586030939621722 0
+1459 9.770474864050755 0.341396906037947 0
+1460 3.099077482376802 0.07563740232019261 0
+1461 6.701810288998463 0.9232826609036301 0
+1462 6.151301951082512 0.9239888907865006 0
+1463 5.600922517617139 0.9243625976796136 0
+1464 8.349077482382917 0.9243625976796533 0
+1465 8.950664281544725 0.0746983036148061 0
+1466 8.402496501897119 0.07602541625623085 0
+1467 6.702062993584829 0.0761570773572504 0
+1468 6.151198438131553 0.07618174016021753 0
+1469 5.600922517616709 0.07563740232026485 0
+1470 3.096638942644224 0.923999246547189 0
+1471 1.514466325820847 0.3028312624641283 0
+1472 1.482176087030211 0.5512830521297206 0
+1473 1.562887338534537 0.5475038276499485 0
+1474 3.058671192196945 0.319736014084369 0
+1475 6.191539251039836 0.6817218226891468 0
+1476 8.990678196019028 0.6826103873781822 0
+1477 2.77876541042418 0.1987233845161453 0
+1478 4.938900966014081 0.671619744118123 0
+1479 7.285430877741875 0.4617267296228186 0
+1480 2.034975037856891 0.5390861356214196 0
+1481 7.765024962139773 0.4609138643790237 0
+1482 4.980460653204507 0.9283966173066793 0
+1483 8.949347309589472 0.924945022685901 0
+1484 5.1621117149777 0.4496835429364069 0
+1485 3.301979558004816 0.5465391131820504 0
+1486 0.9468817143180065 0.6220258789911643 0
+1487 6.714338420581806 0.1768141093236163 0
+1488 6.163022620581796 0.1771824660046274 0
+1489 5.613674265472588 0.1769273729261728 0
+1490 8.414509568384814 0.1763734865654376 0
+1491 3.086237582014895 0.8228830424466099 0
+1492 3.617982188699485 0.1883644114087442 0
+1493 2.627465839239854 0.1927692274028019 0
+1494 2.778342353261075 0.8061377014981244 0
+1495 9.334555438409719 0.4520867068332665 0
+1496 8.212706328650651 0.5682864177685979 0
+1497 1.395905305420772 0.8018267861555154 0
+1498 6.818177921525484 0.4422778259651328 0
+1499 4.564271564915767 0.4526980749571548 0
+1500 3.475139955738982 0.1820307984490761 0
+1501 3.616798572285077 0.8146245175107992 0
+1502 2.630425331767495 0.8121512711355974 0
+1503 4.654238333979408 0.2561934202923218 0
+1504 1.780831501929844 0.2256046219275671 0
+1505 1.851322320111301 0.72839666109672 0
+1506 7.100827017877905 0.2711211017732674 0
+1507 2.138815630153798 0.4378710502277335 0
+1508 7.661184369842567 0.5621289497720868 0
+1509 7.388815630155487 0.5621289497739443 0
+1510 9.312536625973211 0.571118869706602 0
+1511 0.5840527663512176 0.448748291441004 0
+1512 0.3262656014492959 0.07102029523677617 0
+1513 5.529078162883624 0.4066523871323401 0
+1514 6.363390192577314 0.2375832037693026 0
+1515 8.609508652504726 0.2355120373099345 0
+1516 0.4916675985750147 0.7029574344602907 0
+1517 5.056864084581172 0.07324968255808155 0
+1518 4.893314382564455 0.534487087278707 0
+1519 4.13167572059697 0.7170484432431578 0
+1520 7.847311678141747 0.5768755006971633 0
+1521 1.952688321856048 0.4231244993032812 0
+1522 5.723566720348377 0.06964611113095161 0
+1523 6.273566720348318 0.06964611113110855 0
+1524 8.523566720348112 0.06964611113190186 0
+1525 6.273566720348188 0.9303538888675815 0
+1526 5.723566720348174 0.9303538888675699 0
+1527 4.519674266120275 0.07082173520627703 0
+1528 2.223827866561579 0.7228422161615762 0
+1529 7.576172133434926 0.277157783838331 0
+1530 8.672385157680329 0.9300967959136193 0
+1531 8.15918718072494 0.1735859827489369 0
+1532 2.424507258924541 0.5644319819192775 0
+1533 7.376224606593413 0.4361929396423228 0
+1534 2.401828937170615 0.4335411335165532 0
+1535 3.337147737698325 0.8216041348785474 0
+1536 0.9527927720951328 0.3012216130816511 0
+1537 5.73710109827704 0.5714581333347212 0
+1538 6.841328368901966 0.567890177973859 0
+1539 2.111488338344994 0.5476596125648349 0
+1540 7.688511661651707 0.4523403874350017 0
+1541 1.462587895995064 0.9281172236292535 0
+1542 5.509126757607094 0.1883526152416956 0
+1543 6.063105485515941 0.1877537995834923 0
+1544 3.200368199477247 0.8182956633279547 0
+1545 9.142127886107469 0.2606436344919079 0
+1546 4.215064366229283 0.6155198813056918 0
+1547 4.774133602289522 0.8192087691517078 0
+1548 8.876281612180783 0.5954951220622915 0
+1549 3.830043484074865 0.4476616224696247 0
+1550 3.528749399791319 0.4443315556275433 0
+1551 4.807616896222051 0.9298430144588037 0
+1552 0.2368008991256586 0.3351003838670938 0
+1553 9.764962623283358 0.6634163081588896 0
+1554 9.624285345481082 0.6239246797753448 0
+1555 1.575794146878483 0.4366474525790115 0
+1556 3.728129089988372 0.5490518623042527 0
+1557 3.81509699257778 0.5511722183582998 0
+1558 1.033919572049158 0.5443926695002075 0
+1559 0.172017020898098 0.4430406859770119 0
+1560 9.827982979101897 0.5569593140228577 0
+1561 4.049187139460224 0.6654973741840812 0
+1562 3.989592072016053 0.1760658074535439 0
+1563 7.505085427351585 0.8217327579224331 0
+1564 2.294914572644428 0.1782672420772835 0
+1565 8.849890360139051 0.8196518633172438 0
+1566 6.602860350936433 0.8141243779112338 0
+1567 6.608505146328838 0.1871210661122953 0
+1568 8.905454621399491 0.2042461288597069 0
+1569 8.299142521124287 0.1797900335455587 0
+1570 7.4512809754436 0.2426875435841568 0
+1571 2.346270349092835 0.7512150310837474 0
+1572 9.507288795636493 0.5642215556618884 0
+1573 4.411948611110277 0.5190078120821626 0
+1574 4.578265711175895 0.9316967942397518 0
+1575 7.772613260941813 0.8190630345783555 0
+1576 2.027386739054387 0.1809369654215353 0
+1577 2.081995081378227 0.6946019360372061 0
+1578 7.718004918618402 0.3053980639632907 0
+1579 0.8317461309430093 0.7510536513050715 0
+1580 4.774999999992039 0.06695349644024538 0
+1581 2.561437179203433 0.306953220263467 0
+1582 7.335158883848034 0.3208019631648298 0
+1583 1.751077082793908 0.6250325957572181 0
+1584 7.002765361826767 0.3737503767756301 0
+1585 0.2437246147837425 0.7904864515752045 0
+1586 5.008793185357743 0.2013823442339394 0
+1587 9.041445440623407 0.8206909876515381 0
+1588 4.964486698995318 0.5375937549565101 0
+1589 0.7134898193848496 0.742628880434865 0
+1590 7.88182902079212 0.8158165276576963 0
+1591 7.168170979207872 0.815816527657687 0
+1592 1.918170979204307 0.1841834723415055 0
+1593 9.426168648752844 0.06325484987151828 0
+1594 0.5935456199967475 0.5214640952253774 0
+1595 1.587795465140592 0.9258695965777487 0
+1596 8.712380524153678 0.8285443660270543 0
+1597 0.3478969046928685 0.2251184987556752 0
+1598 1.686640650929794 0.8247131207805701 0
+1599 6.936640650931539 0.1752868792199962 0
+1600 1.941029826553931 0.07026288842693486 0
+1601 2.610745759047529 0.0656821293187192 0
+1602 7.189670770566129 0.9298249776136651 0
+1603 7.859364837691299 0.9297880997159691 0
+1604 4.597050215418555 0.3822689828629745 0
+1605 1.938093307761353 0.9300816632733447 0
+1606 7.188093307759924 0.06991833672646637 0
+1607 2.611906692235295 0.9300816632736191 0
+1608 4.039731507639155 0.07016597415443819 0
+1609 6.62546558229659 0.9336848402551985 0
+1610 6.076046606582236 0.9379827418759891 0
+1611 5.525255969884418 0.9335658838880757 0
+1612 8.875255969884192 0.06643411611223712 0
+1613 6.625255969883684 0.06643411611283596 0
+1614 6.075255969883579 0.06643411611300089 0
+1615 5.525255969883429 0.06643411611311725 0
+1616 4.958805325019367 0.7445669197602699 0
+1617 5.760920605803523 0.6867645714113515 0
+1618 6.24195139175602 0.8206107861482453 0
+1619 3.004790962356597 0.1790854819681962 0
+1620 9.445295214530658 0.929452612288176 0
+1621 4.350277651080498 0.07069588689053077 0
+1622 4.223883971524288 0.06648390444069549 0
+1623 5.177552691666598 0.06684717685292406 0
+1624 1.285465447468889 0.2379680062635699 0
+1625 4.765638434507404 0.4735083478064284 0
+1626 6.641871033447496 0.5693013324399993 0
+1627 0.6481180469563156 0.4084561500222071 0
+1628 1.639020514149873 0.2394104211771201 0
+1629 7.100080534805061 0.5991838994308422 0
+1630 8.775907952698427 0.4453006842310374 0
+1631 1.010884815696388 0.1574472684370993 0
+1632 0.06876026046820008 0.679932303380943 0
+1633 9.931239739531739 0.3200676966190188 0
+1634 0.7957656788661265 0.4217075271971804 0
+1635 4.09633566120137 0.4370701213367055 0
+1636 3.921684130881016 0.7127765290421628 0
+1637 1.461878910505258 0.05842140609223882 0
+1638 8.345226503033746 0.8208766228831835 0
+1639 5.604168061585851 0.8203720814463489 0
+1640 6.70127387608911 0.8230551662698887 0
+1641 8.962701749606412 0.1618929385809654 0
+1642 6.376949362550385 0.822642852268435 0
+1643 5.825134836694193 0.8223667245764843 0
+1644 5.28498978236698 0.1760704447751724 0
+1645 5.83498978236699 0.1760704447750484 0
+1646 3.20144719782307 0.1767456345450055 0
+1647 5.510106068352188 0.8260028597174308 0
+1648 8.439896745942244 0.8235073614064732 0
+1649 6.047462905754812 0.8269341647314385 0
+1650 5.359213909075859 0.3614843847670847 0
+1651 5.909213909075935 0.3614843847670164 0
+1652 5.0743573154571 0.1697106409598489 0
+1653 5.060895914209248 0.8406332706174928 0
+1654 9.380456592747393 0.2896230680027898 0
+1655 4.014328811685717 0.517564102697547 0
+1656 7.489435045266999 0.482125112179762 0
+1657 2.310564954728861 0.5178748878193641 0
+1658 0.9701363544740987 0.8484666830338564 0
+1659 9.57634839639638 0.3914146912024515 0
+1660 8.340650050715798 0.4322838195101212 0
+1661 6.090696466810673 0.4331554727519737 0
+1662 3.160062560473127 0.5643506734639803 0
+1663 4.695771972463635 0.1581693891977123 0
+1664 7.370566994306738 0.7043722045792122 0
+1665 9.496701915736121 0.2987415371045092 0
+1666 4.541716854913227 0.3244384275355101 0
+1667 9.251114000323827 0.9349520209857973 0
+1668 0.5315848545257428 0.9337818307772806 0
+1669 5.173069879834423 0.5549821448836618 0
+1670 7.115306774660514 0.7371410238405585 0
+1671 7.934693225339479 0.737141023840572 0
+1672 1.86530677465733 0.2628589761584215 0
+1673 2.420528516712162 0.636274436857673 0
+1674 0.9190578068799826 0.4912263148266232 0
+1675 2.429859236795247 0.2953255939772417 0
+1676 9.516686161868721 0.1717014075038947 0
+1677 1.161072404321896 0.9325757831246756 0
+1678 4.650977597639463 0.5381903976470758 0
+1679 5.300707790672911 0.9317087507608365 0
+1680 9.614790127286454 0.7639321827841761 0
+1681 4.838817467680281 0.7910144880287848 0
+1682 0.7117371640256057 0.5137557276779471 0
+1683 2.87789829494555 0.5049035571239656 0
+1684 1.730021211348363 0.4934662947973203 0
+1685 3.375832706443365 0.5052110078045314 0
+1686 8.663991273587452 0.5010241701867038 0
+1687 8.0699787886493 0.5065337052023927 0
+1688 6.37206033713948 0.4958603548026077 0
+1689 5.330021211350716 0.5065337052024262 0
+1690 5.842558493611745 0.4980201506880138 0
+1691 6.936008726412349 0.5010241701867135 0
+1692 9.169897018097759 0.5024343835453716 0
+1693 4.343017636484294 0.5162189956623577 0
+1694 3.656670939629714 0.06772784768365191 0
+1695 4.111456507096583 0.5648218792415231 0
+1696 3.901286875688425 0.2463941086795984 0
+1697 9.702605097739987 0.6319610256376073 0
+1698 0.8034515037925029 0.07701459277003894 0
+1699 0.2951082883848204 0.3686258292607669 0
+1700 3.978857288507705 0.8337025901725198 0
+1701 3.561685119294089 0.2627903576670592 0
+1702 2.681869216689762 0.2657623551380726 0
+1703 1.468178677314773 0.8254270462326491 0
+1704 7.179224336975142 0.3411215374445956 0
+1705 1.929224336972193 0.6588784625531419 0
+1706 7.86905574618312 0.3375172492685535 0
+1707 8.763718072886176 0.5598757397777262 0
+1708 7.993569632345157 0.8563363918561986 0
+1709 7.056430367654866 0.8563363918561807 0
+1710 9.56235896406187 0.9335919991646772 0
+1711 9.24611117547602 0.2762639250129718 0
+1712 6.628387130648419 0.4511201002691674 0
+1713 0.9965558465436403 0.06744685472681988 0
+1714 8.075000000000072 0.9373413225567924 0
+1715 6.975000000000006 0.9373413225567987 0
+1716 2.824999999994418 0.06265867744297549 0
+1717 0.6832297192105035 0.2434756303691292 0
+1718 8.840798452803149 0.1756116662839234 0
+1719 3.1656260058887 0.06548050466612874 0
+1720 1.80501133473595 0.1447977660825865 0
+1721 1.800875036317054 0.850639386716547 0
+1722 7.045857706520128 0.1460547042631614 0
+1723 0.3621891483780627 0.4901803882724045 0
+1724 9.636975419449362 0.5144918663793371 0
+1725 1.269788623787813 0.9358544583254145 0
+1726 3.563007916599636 0.7070098461640192 0
+1727 2.687343271453247 0.7071755215341794 0
+1728 8.326356562309408 0.06559356592796751 0
+1729 3.173795671370935 0.9344332271135983 0
+1730 1.725000000000001 0.9378523918159786 0
+1731 6.974999999995389 0.062147608183911 0
+1732 2.825000000000005 0.9378523918162054 0
+1733 4.471622565809287 0.4329287829280689 0
+1734 7.941071217882342 0.3042841565973204 0
+1735 7.846459505817038 0.06678932586125953 0
+1736 3.65423199928192 0.9390178046182698 0
+1737 4.532747655005308 0.5694370189867213 0
+1738 1.078454518595158 0.3438736219960243 0
+1739 1.38895560590001 0.9294288137731965 0
+1740 4.019658508527534 0.9284899633538541 0
+1741 8.632300467910634 0.1702855197329138 0
+1742 6.385527572884168 0.1666876036647811 0
+1743 6.536221185167228 0.7413441839370017 0
+1744 4.129443971922266 0.2913833356164945 0
+1745 7.324742720735595 0.597402308834051 0
+1746 2.079316070829602 0.401771439574485 0
+1747 7.720683929166992 0.5982285604259274 0
+1748 2.19064271236381 0.2442800073734608 0
+1749 7.609357287632188 0.7557199926263612 0
+1750 4.359463758281662 0.7649061190165438 0
+1751 4.57202043656076 0.167425169227786 0
+1752 9.719351922784311 0.9299780769030929 0
+1753 9.719351922784067 0.07002192309682526 0
+1754 2.541055474297612 0.4487776523485719 0
+1755 1.034574838777175 0.2843042543070124 0
+1756 2.481272937183828 0.3966217485464635 0
+1757 0.7974931497502779 0.5473140326385845 0
+1758 9.0838541996361 0.5875055163460555 0
+1759 2.966062529362965 0.4125440126623393 0
+1760 6.275383276105208 0.5877214144469531 0
+1761 7.199790813430899 0.6013105564377619 0
+1762 3.911766953697564 0.3323925120428756 0
+1763 3.831878883119578 0.3593061078571074 0
+1764 5.435439786378762 0.2592823327420475 0
+1765 5.985091548956819 0.2587880093325692 0
+1766 0.9134217140116269 0.1636063687532872 0
+1767 0.9716962679883038 0.9357516459423082 0
+1768 8.787207843301617 0.2579168954232338 0
+1769 6.536511119273883 0.2574123690016891 0
+1770 1.832851638961891 0.3902381530561844 0
+1771 7.967268136435134 0.6103139883454233 0
+1772 7.590647555872838 0.3498669011011744 0
+1773 2.209352444123764 0.6501330988989636 0
+1774 4.773100561741158 0.5488099684888214 0
+1775 3.176764881932454 0.3784239738050321 0
+1776 6.07895824991363 0.6166576314677475 0
+1777 2.859134230675749 0.1585563761557318 0
+1778 6.930674131372204 0.8375558871014461 0
+1779 8.122924063295832 0.8365668216153643 0
+1780 9.443338857371096 0.1778045298654263 0
+1781 4.951765144384567 0.1576772947556157 0
+1782 2.348144879576697 0.6738123235234413 0
+1783 7.459227279708637 0.3294647421541981 0
+1784 4.684658875119521 0.9364896629951015 0
+1785 2.869497670088444 0.8373246192299229 0
+1786 1.723179150909181 0.07102613422689878 0
+1787 5.115935418041544 0.9363822696942017 0
+1788 0.5257773341162677 0.065416438890755 0
+1789 4.134718209234039 0.1597829162266059 0
+1790 1.685564915510161 0.1674371100803347 0
+1791 0.3903999286350058 0.4136662269724677 0
+1792 5.399367117023382 0.9358144800418604 0
+1793 4.188676492166108 0.1923075205263543 0
+1794 4.86614009314154 0.3487805035828371 0
+1795 9.372920818456898 0.9358931156035512 0
+1796 2.606580006716266 0.3541208045875424 0
+1797 3.443302499823557 0.7276088993076003 0
+1798 6.196504371517874 0.408225139739484 0
+1799 3.0534956284762 0.5917748602594503 0
+1800 0.3509752377195017 0.7407403545572482 0
+1801 2.737727506670502 0.1414961397876075 0
+1802 6.749970977991681 0.6025826861669178 0
+1803 5.98932030247544 0.5802615311191552 0
+1804 8.959293283552652 0.4447207148427135 0
+1805 5.649797516503107 0.6031622359978327 0
+1806 2.566305870640764 0.2149144608568379 0
+1807 9.165091720166341 0.3859084295354416 0
+1808 3.683644438144932 0.2154852530203074 0
+1809 7.228998847076508 0.7931481788120814 0
+1810 1.363755360691119 0.8404150506686617 0
+1811 5.440004717196294 0.5800660883140344 0
+1812 3.267228312454635 0.4215159060016637 0
+1813 0.06608356644610197 0.4871742122636522 0
+1814 9.933916433553808 0.5128257877363427 0
+1815 3.680086320298984 0.7904272641467714 0
+1816 5.912301916590312 0.8273830529610201 0
+1817 6.462554785612529 0.8267429823900031 0
+1818 8.712124102237771 0.1735146229823093 0
+1819 6.462124102237871 0.1735146229825588 0
+1820 5.912476375361964 0.1734260015325418 0
+1821 5.362476375361982 0.1734260015326193 0
+1822 8.061172688918825 0.270232756481823 0
+1823 3.818584382745252 0.07012473158900888 0
+1824 2.117790951138507 0.07114923095675937 0
+1825 7.680753770282748 0.9287128619190005 0
+1826 4.662461679151721 0.7486559055444169 0
+1827 8.385605980158166 0.5609726821512666 0
+1828 2.74129469813274 0.8580051932264164 0
+1829 9.331610984788263 0.351543855101037 0
+1830 0.4225246941552745 0.6056863982382399 0
+1831 8.958560361690772 0.5516370961495365 0
+1832 7.380098320403619 0.3669306594536612 0
+1833 2.573500761052992 0.7864799801787399 0
+1834 1.468750953250376 0.1729266082570629 0
+1835 2.257141005673099 0.8340285134280954 0
+1836 7.49210375003929 0.1660506343248088 0
+1837 3.141026255226185 0.2042085408312774 0
+1838 6.108973744767685 0.795791459168222 0
+1839 3.095288816265829 0.4427504568411351 0
+1840 6.157644960834797 0.5563348463417709 0
+1841 8.503672714406074 0.6020249640411808 0
+1842 3.928459705729451 0.6243638348984761 0
+1843 8.412342659583057 0.9367299924591862 0
+1844 1.575583454680246 0.6482559325377404 0
+1845 5.175583454681497 0.3517440674621367 0
+1846 5.718904648234066 0.3548310588770804 0
+1847 6.825583454681517 0.3517440674621626 0
+1848 3.372639525884696 0.2729597918046352 0
+1849 6.318227135248292 0.6796216308753101 0
+1850 6.716173059970396 0.3538386339935996 0
+1851 6.889602119820103 0.328276192496536 0
+1852 5.233719005633407 0.3289076927238402 0
+1853 5.78371900563342 0.3289076927238625 0
+1854 1.639734864142197 0.6718771033328839 0
+1855 9.335313918415826 0.8548165042339844 0
+1856 7.685588878784555 0.0700114052404695 0
+1857 2.115844398996484 0.937917535020852 0
+1858 3.934609455768764 0.5047677684509768 0
+1859 2.231306609284841 0.5066714248546215 0
+1860 7.568693390711671 0.4933285751448283 0
+1861 0.4244920956722937 0.9336957127480464 0
+1862 5.638634667276711 0.4821194022632028 0
+1863 3.523552410910818 0.5591990131296052 0
+1864 2.726708121195102 0.5591091179825384 0
+1865 5.073906387769855 0.3552355794360837 0
+1866 8.214793833369956 0.4329359034338964 0
+1867 0.540451471761065 0.8200291902763002 0
+1868 4.988729601678808 0.06980769405795478 0
+1869 8.877914155262637 0.9368418899454122 0
+1870 5.59508723464544 0.5546294592560809 0
+1871 3.865011885765474 0.7751014178048008 0
+1872 2.161333602321089 0.7691862526636533 0
+1873 7.638577412766232 0.2298611310493177 0
+1874 0.4812924551374869 0.2758492643802846 0
+1875 8.91003499822518 0.7934971837808061 0
+1876 4.22062876022567 0.4601924295476279 0
+1877 3.948232745174358 0.3972128694807525 0
+1878 5.525509368871728 0.6164083396954593 0
+1879 2.539253173876468 0.5850609728597311 0
+1880 1.532024898720292 0.0541539173735336 0
+1881 5.447356423847165 0.7498945009259403 0
+1882 8.502643576152847 0.7498945009260264 0
+1883 3.254829548441335 0.2499281183295221 0
+1884 4.566333047760172 0.777614084476329 0
+1885 2.115940692176388 0.6440147756151449 0
+1886 7.684059307820474 0.3559852243851954 0
+1887 7.365814934238837 0.06156385177431992 0
+1888 2.43418506575706 0.9384361482259073 0
+1889 1.741417818648738 0.2876038585294276 0
+1890 4.983611356449255 0.4542709859470183 0
+1891 4.364244673979744 0.2244135553563184 0
+1892 2.233333696733072 0.06013060919536315 0
+1893 3.933476072735058 0.06227132571275366 0
+1894 7.57505953508666 0.940484792463517 0
+1895 6.708230777665437 0.555870637670731 0
+1896 1.385942290234374 0.5560896495182103 0
+1897 8.442990085301497 0.3561392688706104 0
+1898 6.996464024799569 0.7126799886233254 0
+1899 8.053996696534368 0.7127367865704928 0
+1900 7.81790799334534 0.2118184243479101 0
+1901 1.982396486853509 0.7874091943430073 0
+1902 9.650678922861241 0.8476920475471111 0
+1903 9.654234017302276 0.1570407924720567 0
+1904 1.481121850169554 0.4347764617904587 0
+1905 5.304041912113105 0.07113139851526983 0
+1906 5.853807819133137 0.07162778053462507 0
+1907 6.40307537737152 0.07277605774646248 0
+1908 8.653075377371076 0.07277605774664828 0
+1909 6.403576339933283 0.9284833195036313 0
+1910 5.853807819132596 0.9283722194650736 0
+1911 4.191375877916483 0.938535118710233 0
+1912 8.428194415914476 0.62087685264397 0
+1913 5.324197594670475 0.7245902783555915 0
+1914 2.225966958871815 0.9325205156026889 0
+1915 7.568444921297388 0.05915077495237761 0
+1916 3.807775860511662 0.9332290851447579 0
+1917 6.435768453518883 0.6176782081324779 0
+1918 0.9298956846155938 0.0598984291070852 0
+1919 4.241574306889828 0.5535466278906629 0
+1920 8.357315979309027 0.2084080769928342 0
+1921 6.660053698988558 0.2125303039309493 0
+1922 4.034155349798034 0.3357278565810021 0
+1923 7.465127919053797 0.6713471404380719 0
+1924 2.334975047025725 0.3347892209581531 0
+1925 9.153836598168155 0.9304379623239922 0
+1926 9.15240084391278 0.06517084375362202 0
+1927 9.176213941748015 0.8416824007238122 0
+1928 9.222041266102634 0.1590271505375111 0
+1929 7.232130791652902 0.2162407622599772 0
+1930 9.313292243546444 0.2284698026778763 0
+1931 3.693392765589553 0.2888032305468964 0
+1932 1.071059926149195 0.6626612766880615 0
+1933 9.849095170235898 0.06548456558736203 0
+1934 9.849095170235953 0.934515434412674 0
+1935 2.813713371330909 0.2723862563967748 0
+1936 8.19056520436243 0.6727637631538584 0
+1937 6.85950362363172 0.673200565214901 0
+1938 2.423792817350498 0.1648312422952774 0
+1939 7.376088249583719 0.8347607554565694 0
+1940 4.862940262881372 0.4610414319185072 0
+1941 0.8558337723821922 0.6526779717837109 0
+1942 2.802595105485447 0.5522362790972476 0
+1943 3.438962777510219 0.5481258443221197 0
+1944 2.840654859779871 0.6196016654703622 0
+1945 3.40858170910423 0.6163288681858119 0
+1946 1.024664310918341 0.4056801790784055 0
+1947 1.467082407423866 0.6457489791603205 0
+1948 2.810545869229985 0.7261938716949493 0
+1949 8.624213301639653 0.7298611831948421 0
+1950 2.630555655539494 0.4839377336191901 0
+1951 2.434765087333115 0.06948448605775337 0
+1952 7.365234912662471 0.9305155139422044 0
+1953 0.2486097881189421 0.9406228879018064 0
+1954 2.885072153589761 0.7263754112538147 0
+1955 7.780543760419849 0.5473960477425137 0
+1956 2.019456239577246 0.4526039522580139 0
+1957 7.264567866148822 0.5486178520095191 0
+1958 6.448569976381733 0.4468990660748524 0
+1959 8.14597973429545 0.4488612719157771 0
+1960 8.8778410341219 0.3926815435018725 0
+1961 1.209009370795114 0.4354634750458747 0
+1962 5.915278150538335 0.6790167124918769 0
+1963 1.652912147683466 0.5541439730455213 0
+1964 9.246158978881668 0.4512066532550159 0
+1965 5.251839952780751 0.4545231820605335 0
+1966 2.32697088239573 0.9413941963206526 0
+1967 7.477034747420654 0.06559820131694283 0
+1968 8.606539216736103 0.9357263574931163 0
+1969 1.185288754638819 0.6292385472361798 0
+1970 3.633516644147182 0.4006271401467945 0
+1971 9.294898731079634 0.6745664808688256 0
+1972 8.666043318515516 0.3787012407809944 0
+1973 6.415877077208389 0.3789756303056026 0
+1974 8.11419720450245 0.3876078081906805 0
+1975 4.703159916660931 0.4625967890373412 0
+1976 6.104572286589404 0.2125828018172118 0
+1977 5.5576370629287 0.2110538463373572 0
+1978 3.142772235988428 0.7916329773529301 0
+1979 1.263463243537586 0.536839134739438 0
+1980 5.085877447968079 0.5743124851011452 0
+1981 1.189962774824008 0.06136227976859469 0
+1982 8.804459305861755 0.707128677637588 0
+1983 8.260204435134463 0.2903514507818848 0
+1984 0.5935226698861518 0.9382406430332204 0
+1985 5.1861897516546 0.9418986484852603 0
+1986 4.821322427501069 0.1461926436248581 0
+1987 4.42499999999997 0.943170377553355 0
+1988 1.685246948977875 0.6141135754832018 0
+1989 5.835246948979345 0.3858864245170158 0
+1990 5.28524694897937 0.3858864245170073 0
+1991 6.9352469489794 0.3858864245170103 0
+1992 6.16412573614712 0.3330262629732116 0
+1993 3.085874263847379 0.6669737370262738 0
+1994 0.7054346559584892 0.9381231787525317 0
+1995 4.600200412096694 0.594933833215787 0
+1996 1.553202942940497 0.1465802569435792 0
+1997 4.536789835577868 0.6890718143584844 0
+1998 8.701648717682531 0.4565775669042888 0
+1999 3.24566845038791 0.7035438895841462 0
+2000 1.264035960053122 0.7663396749678094 0
+2001 3.684157966676827 0.7075707380135035 0
+2002 2.564828192296801 0.7121046097934429 0
+2003 1.584352241988849 0.7733460454812828 0
+2004 2.1428223544608 0.1624682666129037 0
+2005 7.657177645535193 0.8375317333869167 0
+2006 5.801557924825824 0.4467764276129056 0
+2007 6.902648594938078 0.4582586497381131 0
+2008 4.305566634287258 0.9402706104940902 0
+2009 0.5121257545493278 0.1571551916060206 0
+2010 9.388567646605923 0.5933449708245373 0
+2011 8.236742569859999 0.5116814220013663 0
+2012 2.319144270470916 0.04902244848619167 0
+2013 7.479483238813368 0.9508468004648685 0
+2014 4.156031794467266 0.06097373949218658 0
+2015 5.51426781995112 0.3164261112984999 0
+2016 4.038467441272769 0.4590615098263713 0
+2017 7.461509308933604 0.5412134114902342 0
+2018 2.338490691062599 0.4587865885089181 0
+2019 7.358372542470158 0.2702402199908048 0
+2020 1.638640856150605 0.3207973120046082 0
+2021 1.566568479562423 0.350235459851574 0
+2022 5.185616230743535 0.2220615695698122 0
+2023 0.42496240987196 0.7817337668817865 0
+2024 0.7856524955947597 0.1672745547287962 0
+2025 3.364746492258996 0.9403477836146739 0
+2026 8.135253507737179 0.05965221638425524 0
+2027 2.433641334127216 0.518664859448816 0
+2028 0.2355559265810621 0.1634486389457663 0
+2029 2.297306366507681 0.6129473433532224 0
+2030 7.502488960082679 0.3906354590715659 0
+2031 2.787230397806079 0.4469547322440698 0
+2032 3.459546060242143 0.443419123191529 0
+2033 3.848156277749675 0.1466030482316883 0
+2034 3.82121145744915 0.6361923388528044 0
+2035 8.412168753201739 0.4405062748940196 0
+2036 1.647071506826557 0.4491312332027885 0
+2037 9.938381860880655 0.6047200398089907 0
+2038 0.06148008094711575 0.3950796732858122 0
+2039 3.370699261296192 0.06166122149390858 0
+2040 4.631201053978376 0.6803093987409605 0
+2041 8.17048482141646 0.3325392000949396 0
+2042 0.7474541993482835 0.8415454198726234 0
+2043 9.266459598827286 0.3311102109202654 0
+2044 1.237956658837047 0.8461540041617566 0
+2045 0.3339935434538535 0.8488075347857209 0
+2046 9.045027646075742 0.06587952254510142 0
+2047 2.733493407877924 0.6495349638847436 0
+2048 3.516642993033541 0.6494119918856609 0
+2049 0.579292528606081 0.3059475089061532 0
+2050 4.692214286648289 0.8624154086455549 0
+2051 5.737851463731199 0.2220141170671592 0
+2052 6.838001611838308 0.2235694759465399 0
+2053 1.160244269912131 0.3053714765368851 0
+2054 4.841101431238489 0.702536922280762 0
+2055 1.300643524632979 0.5849736179465382 0
+2056 5.917189076962542 0.4656938651403441 0
+2057 1.939005776247975 0.5490961892953347 0
+2058 7.186628778527204 0.4512075639444407 0
+2059 7.860994223748973 0.4509038107047813 0
+2060 4.163482412682888 0.4089414482775415 0
+2061 1.266090001678474 0.6470475011162142 0
+2062 1.289602343586385 0.4902439288098706 0
+2063 8.300186980540337 0.6133769144262399 0
+2064 4.033845011228175 0.7978162171087192 0
+2065 8.992423941264635 0.3993137029337582 0
+2066 9.932490051040856 0.06054439748870012 0
+2067 9.932490051040894 0.9394556025113125 0
+2068 0.06308211961276154 0.9440199296255695 0
+2069 0.06223035248747356 0.05580344853242834 0
+2070 2.143132900402788 0.8617604660686099 0
+2071 7.655416635103267 0.1367478915735336 0
+2072 3.459668889180999 0.6639796590469722 0
+2073 2.790331110806292 0.6639796590474806 0
+2074 5.411607096523208 0.8686882432530577 0
+2075 0.2309620070988828 0.8630181876522449 0
+2076 9.041727643141655 0.9401019876777694 0
+2077 0.3173880747668893 0.1590990306216976 0
+2078 3.554130835557813 0.1363239547015734 0
+2079 3.039502560354304 0.3823490515356249 0
+2080 6.210533584231533 0.6165583285320345 0
+2081 5.053746281565451 0.6481677994662023 0
+2082 7.914923059620439 0.1509679291090025 0
+2083 4.89786283050135 0.4171475345966214 0
+2084 0.4322331325398293 0.6741212262921478 0
+2085 3.314987697628645 0.772375801568845 0
+2086 4.925209297587413 0.2962230235429905 0
+2087 0.3122431749196797 0.6420483203131871 0
+2088 9.437156971257068 0.5469461216168585 0
+2089 6.63396946720704 0.6175295311330256 0
+2090 5.723945281155552 0.1298988881200175 0
+2091 6.280671313422562 0.1341752718853756 0
+2092 8.530671313422367 0.1341752718858115 0
+2093 5.725574791202712 0.8689275516042149 0
+2094 3.838792712006491 0.864316034645809 0
+2095 0.1452678325186997 0.9399371240236324 0
+2096 9.010425669330509 0.6176975927680827 0
+2097 3.5536893160797 0.863543696571287 0
+2098 4.314642298468002 0.702082024370896 0
+2099 9.759955791286462 0.1448756432018196 0
+2100 9.759955791286488 0.8551243567981398 0
+2101 0.8988132735249104 0.8471285187836586 0
+2102 5.244682422169682 0.5495143222431547 0
+2103 0.2591131143522244 0.4615076127344033 0
+2104 9.740875160586443 0.5385553900926086 0
+2105 3.627632556580211 0.3271652103041056 0
+2106 1.417496006659806 0.2862968569791662 0
+2107 4.416893181407356 0.151780641243747 0
+2108 2.440221161692591 0.7361135281006899 0
+2109 5.24623174281742 0.6704233226646021 0
+2110 6.778694304818472 0.9513245621209799 0
+2111 8.271305695181589 0.9513245621210008 0
+2112 3.021956506229051 0.05553292995389783 0
+2113 9.438237190107293 0.8225715932521382 0
+2114 2.3345764565113 0.2124848781966242 0
+2115 7.465420839753599 0.7875106564903692 0
+2116 4.038817015578882 0.2203063641174252 0
+2117 1.367392082700966 0.4889717602971339 0
+2118 8.15442047015946 0.5521879635465599 0
+2119 3.499273418676342 0.8440173955113544 0
+2120 4.628233331428465 0.05317685895199255 0
+2121 5.961541108112034 0.8698346314104716 0
+2122 8.761541108111979 0.1301653685896776 0
+2123 6.511541108112091 0.8698346314104626 0
+2124 5.970480335728962 0.1259124953038765 0
+2125 6.520282308479595 0.1258481271615349 0
+2126 5.420480335728909 0.1259124953039172 0
+2127 7.390470420673624 0.1336813219991666 0
+2128 2.409529579322355 0.8663186780010391 0
+2129 0.3568576822708232 0.2964967626674195 0
+2130 9.489846937509988 0.05374801921704161 0
+2131 3.021328964596349 0.9512422683387223 0
+2132 6.778657299273702 0.04875938588268582 0
+2133 3.275037260776837 0.05306363982850525 0
+2134 8.185444625609124 0.2272400948380527 0
+2135 3.996329226826563 0.6137468967492786 0
+2136 6.986697806037783 0.4868967835217871 0
+2137 8.61022715399741 0.4879818784325211 0
+2138 3.924914791919938 0.9515716259272394 0
+2139 0.1605430739231987 0.5052568630171074 0
+2140 9.839456926076785 0.4947431369828332 0
+2141 3.27617301466544 0.9478851211571561 0
+2142 8.224103889130545 0.05260398137863809 0
+2143 8.333151875165564 0.3872380923320078 0
+2144 6.656729779675234 0.7756638587967197 0
+2145 8.031953211258084 0.1516536137962925 0
+2146 6.820001752633225 0.1292812983706368 0
+2147 2.974722312130375 0.8726686817910529 0
+2148 0.1519631860197425 0.6964485476275397 0
+2149 9.848192701485804 0.3038712268807562 0
+2150 9.85275784981587 0.6942202293256126 0
+2151 0.1455778941159008 0.3029189635051853 0
+2152 6.005546948915624 0.5118870475134232 0
+2153 5.45640821753388 0.5119398025680154 0
+2154 3.244451093469189 0.484054493193566 0
+2155 0.2439360706439927 0.06266323712914589 0
+2156 6.082439454284811 0.3842793288862674 0
+2157 3.173266072369802 0.6185171869530415 0
+2158 0.4513707295018103 0.05695462229657147 0
+2159 9.233013981655507 0.05400746359961318 0
+2160 6.824534865825079 0.8708607055691527 0
+2161 8.225968201305889 0.8706982144596509 0
+2162 5.18226037217872 0.1350574579070771 0
+2163 0.6287099401582847 0.8558434907987493 0
+2164 0.8502376225791539 0.3748006971005947 0
+2165 2.820568879327971 0.3767313205617021 0
+2166 3.425907302226175 0.3745486627496481 0
+2167 4.476071697815978 0.3443608120746599 0
+2168 0.6227591992463229 0.05330765841236582 0
+2169 2.202581424751326 0.5547035979968169 0
+2170 7.597418575245451 0.4452964020029088 0
+2171 3.901484264294194 0.5521504391295191 0
+2172 4.716481892470169 0.2881990901515743 0
+2173 1.046398428837069 0.9427952611783843 0
+2174 5.8799175519279 0.6160340852328237 0
+2175 5.909283287418872 0.568597345318873 0
+2176 2.626361054012239 0.6727456147707068 0
+2177 3.62515949707118 0.6718441570359657 0
+2178 6.27753687431221 0.8715724422663679 0
+2179 1.274537769673715 0.05354957252174463 0
+2180 7.837626759300076 0.6315553940249332 0
+2181 1.962109047447421 0.3685412264761808 0
+2182 5.171754802062797 0.6543625180181569 0
+2183 4.373653633747365 0.3955409111127247 0
+2184 0.1601614662625759 0.7675646364240435 0
+2185 9.834264158718538 0.2304663122218376 0
+2186 9.842924347772852 0.7698097873090449 0
+2187 0.1639539020428971 0.2306754725452193 0
+2188 8.491906315115751 0.5089367427428373 0
+2189 4.73308385279275 0.7410412355430541 0
+2190 6.154962863899692 0.4531917564265052 0
+2191 3.097341987679252 0.5521938280196094 0
+2192 5.377816557622015 0.4695884466559593 0
+2193 5.210569081662324 0.8438975169200381 0
+2194 5.137320216098034 0.8245065435673563 0
+2195 4.986905195595438 0.6415061624897676 0
+2196 3.54420102473461 0.05903176355356984 0
+2197 4.180882346636821 0.8332618166078137 0
+2198 1.279934717666822 0.8721380332999239 0
+2199 7.881034673436259 0.514492737542164 0
+2200 7.107480269200887 0.5189549452416234 0
+2201 1.918651377113689 0.485295944864211 0
+2202 4.103339204604153 0.8565694169634653 0
+2203 8.789490755850521 0.8696420610425869 0
+2204 8.509811060867451 0.869769640371777 0
+2205 2.228770223207788 0.1261250512315095 0
+2206 3.922933981110398 0.1251566280372339 0
+2207 7.579623008611828 0.8744903504274087 0
+2208 0.7294695845545996 0.05516294912074261 0
+2209 7.234374980717312 0.2857626494335109 0
+2210 1.983871730200814 0.7145231631373594 0
+2211 7.816041678242307 0.2845808964509554 0
+2212 3.545032541044358 0.9413722554408523 0
+2213 7.955523063262046 0.05895677558047663 0
+2214 2.203647633741863 0.4549833164260547 0
+2215 7.596565681513575 0.5452186838830926 0
+2216 7.574881865173045 0.1304233012011507 0
+2217 4.229569619672253 0.7346891593692652 0
+2218 4.807079429661352 0.2671914792795749 0
+2219 3.895523795012298 0.4564731433667812 0
+2220 9.060861237929888 0.1522942829685132 0
+2221 4.756596125836884 0.6934092724743034 0
+2222 4.592672673599536 0.2481781205902829 0
+2223 5.321871070045207 0.6176483613721212 0
+2224 8.627464616148107 0.6230243347944778 0
+2225 0.5869909270352563 0.7259759872096696 0
+2226 5.674326998316075 0.05510676642549554 0
+2227 6.224378067677191 0.0551012047997042 0
+2228 8.474378067678357 0.0551012048002372 0
+2229 6.224418199124412 0.9449689863195849 0
+2230 5.674589935815277 0.9447933298900743 0
+2231 3.803782048620201 0.732953629907245 0
+2232 9.248323134681275 0.5481786171170367 0
+2233 1.200319309904546 0.1522606257286818 0
+2234 2.963773882613875 0.7760910763095183 0
+2235 6.290749934859065 0.2202455956815653 0
+2236 8.536226117380673 0.2239089236906812 0
+2237 1.011916119616023 0.7328615648651877 0
+2238 8.737985740580791 0.7718414516800312 0
+2239 6.519854040939943 0.54949412022647 0
+2240 0.9348214620141041 0.7294017278069671 0
+2241 5.316595122619808 0.8466860137541756 0
+2242 4.003243273024433 0.7213520960257916 0
+2243 5.420067456036516 0.6643340381408516 0
+2244 8.536769571931607 0.66511470002216 0
+2245 3.279932543957367 0.335665961857741 0
+2246 3.183241015222155 0.4906307027309981 0
+2247 6.062549989505876 0.5074724561572213 0
+2248 5.5166169823012 0.5043763272246978 0
+2249 8.522439025778493 0.9461369860065677 0
+2250 8.77756097422151 0.9461369860065568 0
+2251 4.471865460788837 0.05516635817665286 0
+2252 3.258726800336636 0.866241527972747 0
+2253 8.241240970388793 0.1334144513575303 0
+2254 5.135129187148555 0.7328250106026059 0
+2255 3.341744911652361 0.4335834219442006 0
+2256 5.358255088340409 0.5664165780547136 0
+2257 8.593297011411858 0.571084919020762 0
+2258 3.271454921949725 0.135125466715551 0
+2259 1.066396242488731 0.8502029371115457 0
+2260 0.05726171555473158 0.5605797435792595 0
+2261 9.942738284445305 0.4394202564207957 0
+2262 8.706033353956473 0.5520005433947237 0
+2263 2.334535166749272 0.8691367255484038 0
+2264 9.145312724495559 0.124592584279406 0
+2265 4.783679244600966 0.3707736593885267 0
+2266 1.533946876012719 0.7454518713406336 0
+2267 1.679138292624931 0.3799868478538064 0
+2268 0.484860815818728 0.4515131598092176 0
+2269 4.90548664961044 0.2423034438238409 0
+2270 7.51649733861792 0.6003103692067064 0
+2271 2.269072992555805 0.397212869476483 0
+2272 3.894307603429958 0.6552839988769996 0
+2273 1.120481602181347 0.6895921357408403 0
+2274 3.503679211325406 0.2345466587425376 0
+2275 9.328404915781816 0.05518774142815941 0
+2276 6.97286304447675 0.6210904415065759 0
+2277 8.077601713923144 0.6244171267092684 0
+2278 6.894361739960735 0.5515214887236967 0
+2279 5.794361739960721 0.5515214887236894 0
+2280 9.216650715787514 0.3959092042835526 0
+2281 2.302603566995582 0.732252264223783 0
+2282 7.496380355560886 0.2818144324880326 0
+2283 4.161923170890765 0.608398568171733 0
+2284 7.829631435461929 0.7907426316509407 0
+2285 1.970368564534123 0.2092573683481297 0
+2286 1.58050721626525 0.8726369866318585 0
+2287 3.44928554955116 0.3229595316102463 0
+2288 0.0557343116027233 0.7656276716089513 0
+2289 9.946030479696535 0.22636787147026 0
+2290 9.943338795249655 0.7724312759947694 0
+2291 0.05573431160255494 0.2343723283912383 0
+2292 5.137278014694301 0.2589436425892584 0
+2293 1.17961533988174 0.8533087037741109 0
+2294 2.797152175227705 0.3260395257838735 0
+2295 6.427600901300315 0.5200387333750401 0
+2296 9.695393983113334 0.363744640628502 0
+2297 3.807359969491215 0.2666847834706963 0
+2298 3.526378132662282 0.3443890595877758 0
+2299 2.72613826054187 0.3435516207617655 0
+2300 4.636914304591023 0.1286857059087355 0
+2301 5.361974241073987 0.6684139179538595 0
+2302 8.58877272617471 0.6690714765555568 0
+2303 3.3423791566596 0.3290821857479805 0
+2304 9.841948988725951 0.8774826964693712 0
+2305 9.841948988725955 0.1225173035306344 0
+2306 8.322318710761166 0.4993270704267971 0
+2307 6.01262422312525 0.7236280090220697 0
+2308 8.21022238995859 0.3562047051564695 0
+2309 8.689194121600545 0.2833776365888716 0
+2310 6.439194121600827 0.2833776365890881 0
+2311 0.1411448884074848 0.05989546511478173 0
+2312 5.889088813996358 0.2833426817507864 0
+2313 5.339088813996362 0.2833426817508515 0
+2314 7.096629959112569 0.6629363348522705 0
+2315 4.139717600131671 0.5194462430438136 0
+2316 6.498832667639947 0.4507261193495108 0
+2317 2.221031751926681 0.8789554225186386 0
+2318 6.438722956691654 0.7167787575607256 0
+2319 7.060141202419977 0.3680636578851087 0
+2320 1.810141202416609 0.6319363421131644 0
+2321 0.7266128818586526 0.4498755383768804 0
+2322 2.969803443506841 0.1330473997345902 0
+2323 5.128434802380942 0.05239715866750024 0
+2324 6.452071826012877 0.3409842353818535 0
+2325 8.705363505291109 0.3400493638755807 0
+2326 5.688758881508124 0.2581965509094357 0
+2327 6.788758881508227 0.2581965509094908 0
+2328 1.373185445846347 0.05249497210602134 0
+2329 8.703860114243426 0.6786943729071583 0
+2330 3.247526994696239 0.5867245262908216 0
+2331 6.555869146140166 0.5870688986348357 0
+2332 4.856842484599998 0.9440332030747233 0
+2333 6.528650822076253 0.395524038751967 0
+2334 5.560296795556283 0.2796863141882536 0
+2335 9.151509896712826 0.5634764967487249 0
+2336 6.348289799235898 0.5676987012831918 0
+2337 2.907153704429391 0.435919411166921 0
+2338 2.327558217932591 0.1224637612400891 0
+2339 7.470794793209408 0.8773793375011782 0
+2340 0.7079424840180334 0.1476378604008806 0
+2341 9.669212643496323 0.4132623177793734 0
+2342 4.574719608434738 0.8773758454447345 0
+2343 1.805100974816942 0.7646349296426305 0
+2344 7.055100974815832 0.2353650703559347 0
+2345 0.3117040986711642 0.9440350884558272 0
+2346 3.35461862966836 0.153738065237793 0
+2347 4.131389076920015 0.9459667649269257 0
+2348 8.741845752093333 0.2188793324523967 0
+2349 6.490787860883774 0.2182074910652258 0
+2350 9.641449963711667 0.2990887777906019 0
+2351 3.246568394814307 0.7588959934614732 0
+2352 8.759936980709128 0.3513829610076852 0
+2353 0.4123199150470901 0.317914871796828 0
+2354 9.143061498028096 0.8811497259744785 0
+2355 6.491228716816393 0.7809082337416186 0
+2356 9.254595904013616 0.8668186130148047 0
+2357 1.524943138492711 0.9580943944234307 0
+2358 8.764823452733866 0.6641377357993519 0
+2359 6.517941978983708 0.6509071163469903 0
+2360 4.002495489155296 0.2894714675971004 0
+2361 2.304626312636812 0.2878637927526339 0
+2362 7.495373687359274 0.7121362072467886 0
+2363 9.265273121445912 0.2208603839629934 0
+2364 8.902479545859231 0.4407883639781862 0
+2365 8.869238680048841 0.5061981389852468 0
+2366 1.271891713661229 0.1480746395200299 0
+2367 5.971680806584017 0.6656485138190286 0
+2368 5.940759350327435 0.2194679602914261 0
+2369 5.390597747321688 0.2184777682247474 0
+2370 0.2579074660929249 0.7442416207638247 0
+2371 9.737852459314222 0.2583963011037819 0
+2372 9.741542989551142 0.7465242279689212 0
+2373 2.82340903053472 0.4882476008397138 0
+2374 3.422702934885093 0.4841317829365348 0
+2375 0.05384435039210328 0.8682158539353787 0
+2376 9.948557434957715 0.1339159485270518 0
+2377 9.948557434957818 0.8660840514728091 0
+2378 0.05075486512925088 0.1333964203900839 0
+2379 2.931908171504539 0.328515393393891 0
+2380 1.67342246113425 0.4884783124887076 0
+2381 6.615187729226935 0.4014711053058082 0
+2382 9.135156784960907 0.7751157744180248 0
+2383 3.470377542818667 0.0516096060833055 0
+2384 1.892076512619642 0.8471238801593821 0
+2385 7.142068923077837 0.1528691440523132 0
+2386 4.887778966930301 0.05538534173565613 0
+2387 7.924058154810179 0.243869559905585 0
+2388 7.364326921466968 0.4831822647099551 0
+2389 0.8779928557905575 0.9476662512310297 0
+2390 5.407592871243676 0.3490905070385722 0
+2391 5.957853274094752 0.3494833934506548 0
+2392 3.716090294555528 0.5996987001237372 0
+2393 1.217484431924112 0.7289297064933513 0
+2394 8.788833250219694 0.5004252820817101 0
+2395 0.6205015575780386 0.6788444375042959 0
+2396 3.740349139836265 0.3510484070405442 0
+2397 1.751686667877862 0.1937089693095684 0
+2398 4.488804367904672 0.235573261312991 0
+2399 3.341471112679394 0.6781880848002744 0
+2400 5.278049804558104 0.5119243620062278 0
+2401 8.43850774059891 0.5069448037775259 0
+2402 7.009244973886705 0.5617109061777874 0
+2403 8.048332961828859 0.5509480082751214 0
+2404 1.752849987208178 0.435522014497182 0
+2405 4.478286123714315 0.865199023919776 0
+2406 8.126697037724119 0.5038890197647885 0
+2407 0.1455390618513147 0.5897000170740123 0
+2408 9.854946388393953 0.4103050473215378 0
+2409 7.472645838070708 0.1227071937283686 0
+2410 0.6764701681396718 0.7732035886675438 0
+2411 8.022199823708457 0.05185679930411124 0
+2412 3.47430117993929 0.9515677137781099 0
+2413 2.902709690281229 0.7799411900428419 0
+2414 3.942862767448681 0.2908958114035358 0
+2415 4.683339107875842 0.3841022550949182 0
+2416 5.884273008196046 0.5184573869135786 0
+2417 9.417447617288039 0.1324162368506439 0
+2418 7.160589651718709 0.4023010001238497 0
+2419 1.910589651715387 0.5976989998756942 0
+2420 7.889410348281144 0.4023010001243665 0
+2421 4.279748475564877 0.373654212824519 0
+2422 3.04259119541313 0.2208039684125522 0
+2423 6.207209618459772 0.783979609214274 0
+2424 1.014468061943088 0.4891208342907433 0
+2425 1.079378970017765 0.05235171814148168 0
+2426 9.23130502172773 0.5029434860303513 0
+2427 5.939262453956536 0.773731995618641 0
+2428 6.026197904916457 0.3027679581567828 0
+2429 0.423756655043308 0.1339059708144002 0
+2430 1.755120116268727 0.336580103553773 0
+2431 4.626500623062643 0.4898126940321233 0
+2432 1.086829224311736 0.1509359761373379 0
+2433 0.3257347032484146 0.5861145542009931 0
+2434 4.372866099587001 0.8652729544354859 0
+2435 4.95464834520222 0.8009055398915406 0
+2436 0.2616519416435748 0.2598960844124848 0
+2437 6.996193487935081 0.8085117615038655 0
+2438 8.051601287829453 0.8066112765923283 0
+2439 1.330573804442633 0.6955379935690703 0
+2440 4.895707776241139 0.1260508767959664 0
+2441 4.038878677397723 0.1244366028557762 0
+2442 4.723926221930848 0.04817266437347287 0
+2443 9.558713012494058 0.8793492864269471 0
+2444 6.99437757336063 0.2884737529571729 0
+2445 1.744358148458956 0.7114925128253811 0
+2446 9.077132546286776 0.2128497709891161 0
+2447 0.2545161023538894 0.541097787379949 0
+2448 9.745483897646267 0.4589022126200925 0
+2449 6.354577443737531 0.2820098460960521 0
+2450 8.604000159989191 0.2825147185783147 0
+2451 0.4743480350939552 0.7663508153959037 0
+2452 5.550718597754584 0.566457914261367 0
+2453 9.29324701516467 0.7660610133547272 0
+2454 9.658120049678493 0.7377493336042698 0
+2455 9.672938722502781 0.9522188368585724 0
+2456 9.672864703670074 0.04743738024770502 0
+2457 2.221212091662383 0.7803266810538498 0
+2458 7.57487205660916 0.2228666202285036 0
+2459 8.401507678002046 0.7940567077602578 0
+2460 5.548492321998043 0.7940567077601989 0
+2461 0.7408340373285525 0.3470775728361167 0
+2462 4.53836709282483 0.4953665081114378 0
+2463 2.509054220956537 0.6542221946499409 0
+2464 5.468768526582801 0.3030717885636222 0
+2465 9.616891714911086 0.5761263728805013 0
+2466 6.863105103735501 0.7681048285901064 0
+2467 8.186931331356996 0.7680612698960636 0
+2468 0.1530273516199136 0.8797801722048182 0
+2469 8.804546137612027 0.7603017154305683 0
+2470 8.25477464670538 0.2390201134729476 0
+2471 8.562759138793973 0.8458534878108996 0
+2472 6.692846070511343 0.4425511574081349 0
+2473 8.046561643983845 0.3225753906372361 0
+2474 4.462385910636775 0.7104746004770399 0
+2475 8.258880788761871 0.4136585082210694 0
+2476 5.720958303525235 0.411968787135123 0
+2477 2.313196144867511 0.8199426167634436 0
+2478 6.805964727342785 0.5053044950598576 0
+2479 7.008061281905785 0.6641747723365286 0
+2480 8.040213386463954 0.66373880239951 0
+2481 8.979999831791991 0.5083303267159694 0
+2482 1.85866244903707 0.3180760833658699 0
+2483 7.941337550961077 0.6819239166333311 0
+2484 2.637877563963746 0.143423378020723 0
+2485 0.6831908438076296 0.6103022368776768 0
+2486 0.7477223441611417 0.639891338617447 0
+2487 2.902297152814045 0.2218254429266227 0
+2488 0.6236781953783044 0.2028354360003482 0
+2489 0.5692938731549942 0.2305991642373997 0
+2490 9.048954074110162 0.5124690122459472 0
+2491 0.765981974708721 0.2463173591681278 0
+2492 0.9623088705337606 0.1944004241866267 0
+2493 1.311868546986448 0.3911833753655596 0
+2494 2.225021701023387 0.5983441025835966 0
+2495 7.574978298973581 0.4016558974163587 0
+2496 1.082565609307463 0.5711087462373207 0
+2497 9.223031758371402 0.8197038373769077 0
+2498 9.170877296417972 0.1791287672172678 0
+2499 2.744050955727169 0.7699260841343147 0
+2500 9.008364081499789 0.2753641732047126 0
+2501 9.045468394123505 0.3194748216856126 0
+2502 9.461468395296292 0.4462651091221094 0
+2503 5.716058382868165 0.795288491827 0
+2504 3.072503152435636 0.5017800313961494 0
+2505 6.177533524658408 0.4976342848334146 0
+2506 1.623303902029387 0.05026655840201168 0
+2507 3.152026140246953 0.4502180525844737 0
+2508 6.096994312744792 0.5493300541072705 0
+2509 2.350981637068247 0.5522895092469697 0
+2510 7.449018362926984 0.4477104907529214 0
+2511 6.24853256730097 0.5164295470796423 0
+2512 2.999822755040995 0.4876443384067606 0
+2513 8.417368113698977 0.30978565013812 0
+2514 1.773436293951678 0.5246627176354604 0
+2515 0.834502808612957 0.6997537466012571 0
+2516 0.2079748238366587 0.2134552353793873 0
+2517 4.69484407990551 0.6418031472500765 0
+2518 2.740709719949947 0.2321182950249431 0
+2519 9.109855884155115 0.3818200186652184 0
+2520 2.65727050762807 0.308540637013285 0
+2521 3.531933077406151 0.4971861567019664 0
+2522 3.584936127914291 0.7529043315835732 0
+2523 2.672478591282248 0.7588481403298186 0
+2524 1.251873230838698 0.336684984015782 0
+2525 9.006019442326492 0.783619924498506 0
+2526 2.663801599835761 0.8422364219261905 0
+2527 5.392846862755735 0.7714762635615793 0
+2528 8.810829343259801 0.5855498720040248 0
+2529 1.683724553097748 0.2704711568722923 0
+2530 7.980438909127291 0.3388347087072428 0
+2531 1.855326502451704 0.4852028235962432 0
+2532 7.168270974418474 0.5060175756026757 0
+2533 7.947054621052326 0.511289178160243 0
+2534 9.119177072617342 0.6690656930225701 0
+2535 2.960184944032797 0.6632438898899333 0
+2536 6.288315075045543 0.3333263062005407 0
+2537 8.538315075045542 0.3333263062006491 0
+2538 8.82746044870235 0.3028327536606841 0
+2539 6.572322798713097 0.2972010538688815 0
+2540 2.029608828784914 0.1287122801364944 0
+2541 7.770404489050748 0.8712815969931129 0
+2542 7.687871473886836 0.2593655536711795 0
+2543 2.112128526109964 0.7406344463290307 0
+2544 6.578382152160691 0.699391228577657 0
+2545 8.456756492800205 0.4107706244075467 0
+2546 9.336106875436935 0.1502122462308919 0
+2547 0.4224042120880117 0.8813314225836719 0
+2548 5.976029169680806 0.4672269514821063 0
+2549 9.493600523047069 0.6288997550944844 0
+2550 4.250421967903829 0.1367718721985057 0
+2551 5.025000292442598 0.9509751808262052 0
+2552 3.372308751749823 0.3906272748884918 0
+2553 3.191315441584635 0.6819171086986168 0
+2554 6.714069172567688 0.8756945238733331 0
+2555 8.342770245245855 0.8727511873928558 0
+2556 5.606532396329908 0.8729665066565967 0
+2557 1.447101961983583 0.1343314963065589 0
+2558 8.136316666987025 0.2919459283092358 0
+2559 4.428558812335778 0.4734813476199379 0
+2560 2.083758143031718 0.2802621137336727 0
+2561 7.71583909774852 0.7200109193437674 0
+2562 6.626859549303842 0.5040356279042199 0
+2563 4.303821461929704 0.150173291273197 0
+2564 5.047859175982491 0.7332822065639345 0
+2565 6.007028233669897 0.4114959232942192 0
+2566 5.46238645253121 0.4102000423514187 0
+2567 2.243162128475306 0.2962948065905318 0
+2568 7.557330214173331 0.7041644305558933 0
+2569 2.718837947236602 0.5012167838108063 0
+2570 3.621259188038532 0.4949590425625887 0
+2571 0.5158260514823638 0.8688976507094509 0
+2572 5.851715178115905 0.7290627794479875 0
+2573 1.757698050291764 0.8214547745703235 0
+2574 7.007698050291945 0.1785452254287391 0
+2575 7.392393676425772 0.2284299532409167 0
+2576 9.543487902896352 0.786483672632189 0
+2577 4.630419840236402 0.9462631906951192 0
+2578 2.689804309348504 0.5872379817732958 0
+2579 3.560195690639727 0.5872379817712384 0
+2580 3.506051056357553 0.7628947473402747 0
+2581 3.911024508806117 0.871572838148238 0
+2582 7.94612646969606 0.420546387934831 0
+2583 0.1259524325892267 0.1519729845805327 0
+2584 0.9237522854449264 0.4332868396579562 0
+2585 3.615027442567902 0.1409130906826226 0
+2586 3.734621697917203 0.65326416629839 0
+2587 1.343789087590907 0.7866810758237749 0
+2588 7.077637863727624 0.4732633348466632 0
+2589 3.655563409944287 0.4491875613632799 0
+2590 1.216835016094009 0.9482792011384751 0
+2591 5.629217125486565 0.352303773826356 0
+2592 0.8188963961234218 0.1246370071344973 0
+2593 3.278830230772671 0.6609920535906586 0
+2594 5.271118761471241 0.6323290896421313 0
+2595 0.7054243471132664 0.8840040330100355 0
+2596 4.971330562518136 0.4002587967784249 0
+2597 3.613804887239447 0.8596905830573266 0
+2598 7.139550736867371 0.3144700155591787 0
+2599 1.889655671644928 0.6854388140777442 0
+2600 3.983498572228215 0.04992709222565424 0
+2601 0.8674593895144748 0.2748998740751163 0
+2602 2.023938229757966 0.584383457630684 0
+2603 7.2726713906999 0.4155799763903226 0
+2604 7.776061770238834 0.4156165423697047 0
+2605 0.8562807340524328 0.2245356656533097 0
+2606 2.711667311021532 0.3954083079573789 0
+2607 7.560151546157511 0.1723658248796536 0
+2608 0.9055511615225201 0.5445766784862689 0
+2609 8.308167696508674 0.3133225723483181 0
+2610 8.858160629580031 0.6866755444223697 0
+2611 9.513157680266801 0.350255538609467 0
+2612 8.29520950881421 0.7288101294657008 0
+2613 5.700317282909475 0.6863721757704299 0
+2614 1.220323065028922 0.654726350259801 0
+2615 6.796804539844208 0.687944196436336 0
+2616 9.589300729495516 0.4838526416231419 0
+2617 9.528037210378303 0.5031904905271446 0
+2618 4.314445607659288 0.2037484290068766 0
+2619 9.065010805931081 0.8692979992486605 0
+2620 2.40614068200791 0.7741786832149551 0
+2621 0.783678073183253 0.2999212483490752 0
+2622 9.20867257123788 0.621090441506484 0
+2623 9.582138901300377 0.05266931303784347 0
+2624 5.101391821947804 0.8642811565299131 0
+2625 1.587880434871064 0.2357134163292784 0
+2626 8.553631711155031 0.7700820387600842 0
+2627 8.89624106869738 0.5455029635273296 0
+2628 7.987267971341998 0.2340367343348455 0
+2629 9.453955185882299 0.8790601742167354 0
+2630 3.299644234492778 0.23148803335743 0
+2631 1.633437531387353 0.1101870830354816 0
+2632 9.429966012447 0.4026584241929579 0
+2633 1.015891332675569 0.8297231025583481 0
+2634 2.154936381781765 0.2107609341097945 0
+2635 7.645063618214033 0.7892390658900712 0
+2636 0.7843699705439584 0.9511121989129753 0
+2637 4.81905387131247 0.04772209790811354 0
+2638 4.272603815891906 0.05006418718404896 0
+2639 0.6285985195368179 0.1128671179611764 0
+2640 2.704487199737436 0.0534414140210366 0
+2641 7.954487199742393 0.9465585859788157 0
+2642 7.09551280025762 0.9465585859788495 0
+2643 9.331600791136278 0.5022659866900139 0
+2644 0.4123491237793549 0.5132255226587679 0
+2645 7.107055864900176 0.4194521381426634 0
+2646 1.857800274086134 0.5810429541960511 0
+2647 9.945113507301173 0.7125370018513832 0
+2648 0.05303385506098789 0.2869312754533109 0
+2649 1.844306189387823 0.9468042670548613 0
+2650 7.094306189386915 0.05319573294476881 0
+2651 2.705693810608255 0.9468042670553023 0
+2652 1.356649032872272 0.2029595508447603 0
+2653 4.760635152164717 0.190551843515124 0
+2654 5.541183484647846 0.4586665438168689 0
+2655 6.755496726456244 0.7297501658927666 0
+2656 8.252347547114832 0.6882510376786041 0
+2657 5.655293194205192 0.7298016739337567 0
+2658 7.183482904316254 0.6955276688290255 0
+2659 7.860386258322984 0.6925404489641368 0
+2660 1.939541578938528 0.3075595665113193 0
+2661 8.720145007258196 0.9512459083329047 0
+2662 0.6061715456281931 0.5719321920646832 0
+2663 3.202026019616416 0.8627136669531474 0
+2664 3.916360135563087 0.777600042581377 0
+2665 0.9259082447925987 0.6691874057274095 0
+2666 9.658957916030637 0.6626432458241048 0
+2667 5.465353607205048 0.1515769470981172 0
+2668 6.015864143729771 0.1549065590003212 0
+2669 8.683516267984741 0.6047031452333802 0
+2670 9.493212668450834 0.9422497621297323 0
+2671 4.384958806284593 0.3410716668091391 0
+2672 9.352023894485839 0.6882092080607634 0
+2673 9.394207191484519 0.7297240749279561 0
+2674 4.318926774713834 0.626097861678535 0
+2675 1.846803540925747 0.05311874613504688 0
+2676 5.351695170371637 0.9393411405283866 0
+2677 9.561413550909505 0.6894471965344566 0
+2678 1.36955283541139 0.1463022139316164 0
+2679 0.5040757226710804 0.5800600020967183 0
+2680 1.375848313650597 0.6003480978467495 0
+2681 4.433850472079466 0.3185854322969767 0
+2682 0.4427021493282376 0.4139151953783943 0
+2683 7.164499222596181 0.8636656848785784 0
+2684 7.886155357853326 0.8645957539369394 0
+2685 1.915363768003231 0.1365220507156988 0
+2686 9.496492609539516 0.7568355946754266 0
+2687 6.52257420507325 0.3440303497707572 0
+2688 2.481511659560233 0.04458790514204983 0
+2689 7.31848834043524 0.9554120948579187 0
+2690 1.025685316132838 0.683357319972134 0
+2691 5.427966644328483 0.477182952509732 0
+2692 4.574685363079171 0.04386152173238386 0
+2693 1.538936214944911 0.2590855602040904 0
+2694 9.481144442827047 0.2136284964726173 0
+2695 5.606250292271886 0.304082455260216 0
+2696 4.210593469648388 0.518329091655291 0
+2697 8.815639143551163 0.4125886817626487 0
+2698 4.267792938315364 0.2338783883299448 0
+2699 4.315339734541606 0.7928396870265945 0
+2700 1.835990512965468 0.4368038598358177 0
+2701 7.964174586099413 0.5636220722167038 0
+2702 0.8260592053573091 0.4651474758910933 0
+2703 7.206385306524709 0.5486393733663238 0
+2704 9.583149953475287 0.117598197311762 0
+2705 0.5431046440968044 0.3635165425823192 0
+2706 9.889353368921476 0.6150387658407561 0
+2707 0.1107566033032333 0.383029086172708 0
+2708 2.924448616926818 0.04685161158146035 0
+2709 8.177162319121161 0.9530780924412271 0
+2710 6.872837680878893 0.9530780924412615 0
+2711 0.4777553829405877 0.9527723634415449 0
+2712 6.529576213212827 0.9502656433634459 0
+2713 5.979576213212788 0.9502656433634614 0
+2714 8.779576213212218 0.04973435663673768 0
+2715 6.529103222572687 0.04971161671218241 0
+2716 5.97910573720418 0.04971243408549375 0
+2717 5.429105737203915 0.04971243408559331 0
+2718 7.318090032033294 0.04406464430769822 0
+2719 2.481909967962526 0.9559353556924461 0
+2720 8.848799223811552 0.8640474867868342 0
+2721 1.469631908735266 0.877162640979812 0
+2722 2.925127556409988 0.9534769718087072 0
+2723 6.872006562729355 0.04852600929868773 0
+2724 0.3665705151685306 0.7924046607840808 0
+2725 9.555937304759894 0.5820392497436342 0
+2726 5.366395558353036 0.839890802930174 0
+2727 8.344617995510275 0.5755877331438092 0
+2728 6.304667833947324 0.7714900787271712 0
+2729 4.346082111606609 0.3051475889271196 0
+2730 4.005140718848374 0.8736749806179309 0
+2731 6.565433864985599 0.1507639554879552 0
+2732 6.599447273504716 0.8627519737308122 0
+2733 4.825940708535753 0.3226634858795051 0
+2734 6.535243711426889 0.4951969544496644 0
+2735 6.016126942244246 0.7695319264749735 0
+2736 8.298208513309961 0.1364007316740209 0
+2737 1.468854895257562 0.3836415519219661 0
+2738 1.413685353208293 0.7324574075301691 0
+2739 5.277092306448139 0.8841899513522621 0
+2740 5.717877623016339 0.5073262588045475 0
+2741 3.451688622417679 0.107864313544966 0
+2742 4.780625808396507 0.864934263979358 0
+2743 4.52287775595908 0.277695926538004 0
+2744 9.205922910340286 0.9442484937715777 0
+2745 8.699053410219301 0.7312998009023998 0
+2746 2.122332568085346 0.3134418566411178 0
+2747 7.6758039308405 0.6876729914687374 0
+2748 1.367919098426455 0.3060353493745022 0
+2749 5.481337657753122 0.9545223405708534 0
+2750 9.04615442698462 0.4284505405995384 0
+2751 6.24858722949721 0.4297929309693953 0
+2752 3.001412770497442 0.5702070690299514 0
+2753 3.751645896264291 0.4422972489327178 0
+2754 8.130262192731067 0.1097987497999223 0
+2755 3.36919014596086 0.8882605555717478 0
+2756 4.438872352471829 0.2624201795378672 0
+2757 2.248659167580203 0.198155076765548 0
+2758 7.551996904721001 0.8025663614580583 0
+2759 3.951602041954622 0.1941105771519591 0
+2760 3.011474873045406 0.2999592547961699 0
+2761 6.238963666339494 0.7017231100124126 0
+2762 1.730059208769056 0.3866876825746058 0
+2763 7.972303436746712 0.1463497307669211 0
+2764 0.8669369968425511 0.8920281853916118 0
+2765 4.756258912668763 0.9481576367719815 0
+2766 7.73108245505462 0.04485569759253861 0
+2767 2.068668619868546 0.9558498349167396 0
+2768 0.3940318007050439 0.2095888920913388 0
+2769 3.041504175926912 0.7476993041988018 0
+2770 6.208423533178359 0.2519420193281634 0
+2771 8.462119315234441 0.2492855741223228 0
+2772 1.984692091016647 0.26270119109599 0
+2773 7.815307908979517 0.7372988089046252 0
+2774 7.233125765161682 0.740227845411337 0
+2775 3.452561355683935 0.8821477182070484 0
+2776 9.038003222894758 0.6994177443683465 0
+2777 4.886182709463093 0.8605856476227102 0
+2778 9.193887294016241 0.2739923392114037 0
+2779 4.206668714338502 0.8721588169891275 0
+2780 1.370240325338915 0.412452705458944 0
+2781 9.186916863228465 0.7228839516757698 0
+2782 2.618711393080364 0.6203302753033686 0
+2783 3.632137642123691 0.6201743287851299 0
+2784 1.162260703018735 0.4091088862433414 0
+2785 6.068854503273704 0.3322472843751188 0
+2786 1.17045362039874 0.1105815914339322 0
+2787 4.371697422854427 0.1180568908129546 0
+2788 4.521605786835355 0.4464025127470262 0
+2789 6.659323586067331 0.2613948933651143 0
+2790 6.44819581472101 0.5654061852524223 0
+2791 6.726230147564996 0.4097933533568627 0
+2792 1.126514298832539 0.3447613775937173 0
+2793 4.475583150659896 0.9543189065589099 0
+2794 3.223263480719214 0.4005759736477016 0
+2795 5.473674853626084 0.6075558522035081 0
+2796 6.032895569363975 0.6092070024811443 0
+2797 2.521615844624252 0.1253007702080699 0
+2798 7.27876148106839 0.8744434657471393 0
+2799 0.8152631743193292 0.7993357217405926 0
+2800 7.678932818775753 0.5080631646451441 0
+2801 2.120784954866338 0.4920173348420665 0
+2802 5.013005843236134 0.2660532033809915 0
+2803 2.522547106806542 0.8734735245456605 0
+2804 7.277476198127378 0.1264769941639402 0
+2805 8.908268871614668 0.2577808992107506 0
+2806 5.651565081491448 0.4343916460698956 0
+2807 3.533029628893041 0.3949398643871149 0
+2808 3.771395933531676 0.04446752557091017 0
+2809 2.070831251040951 0.04437973609827367 0
+2810 7.729030150995972 0.9556071298898611 0
+2811 6.911705461471389 0.7951578619404663 0
+2812 8.144638968623521 0.7941757404615097 0
+2813 5.480948720932667 0.7106953982446401 0
+2814 8.469051279067401 0.710695398244682 0
+2815 3.21905127906125 0.289304601754385 0
+2816 2.867943031009944 0.2714335590156021 0
+2817 2.416296229515535 0.1128879956477841 0
+2818 7.38368791273858 0.8870576040524579 0
+2819 6.9423100555368 0.7253102523399451 0
+2820 8.106144298674648 0.7295273897040827 0
+2821 5.036085463271321 0.4497069588258635 0
+2822 5.076037500258759 0.4101529110390713 0
+2823 4.779515576964766 0.425363144254876 0
+2824 3.088900871339824 0.8736756280609951 0
+2825 5.60969138710452 0.1256120102202163 0
+2826 6.159658397592055 0.125502668006013 0
+2827 6.71088989397381 0.1260249937018433 0
+2828 8.410127066825595 0.1258080985855889 0
+2829 6.816517585546841 0.8041222405499849 0
+2830 8.233864982923691 0.8036648742624328 0
+2831 0.8071701589331481 0.2104967286132996 0
+2832 1.888274774526838 0.7655009512086751 0
+2833 7.136336904207958 0.2327225703190812 0
+2834 0.6588528292894965 0.2886560641318126 0
+2835 7.945924251080508 0.8544963317132425 0
+2836 7.104075748919501 0.8544963317131966 0
+2837 1.868026367978028 0.1418423747789363 0
+2838 0.2730717526042272 0.8262476161745598 0
+2839 3.76163630693415 0.9540914955935705 0
+2840 3.722873800980589 0.4815904830758074 0
+2841 5.072687954375638 0.5237530547448387 0
+2842 4.458908257264002 0.7609122264274539 0
+2843 0.8304847665701947 0.3100259744735622 0
+2844 3.57737108967636 0.3171747359920693 0
+2845 4.636851957852675 0.3523617948819615 0
+2846 5.056785285525507 0.3020404032195677 0
+2847 6.707069160887001 0.3027196415041497 0
+2848 9.621800220791323 0.2092577406293178 0
+2849 8.887959654019514 0.6452068605225119 0
+2850 3.718814560416589 0.1268722291281506 0
+2851 5.170168608606298 0.5016821164343878 0
+2852 0.3505023270505415 0.6897098444337568 0
+2853 1.680123649524364 0.9544878676492613 0
+2854 6.929952571033022 0.04603953606104624 0
+2855 2.869727181645765 0.9539738370583667 0
+2856 4.733545686154797 0.3561376000484331 0
+2857 2.015530264341303 0.8739084005899487 0
+2858 3.716036622665976 0.8739038027737094 0
+2859 7.783803425448334 0.1267075672030012 0
+2860 7.317788608320571 0.7865386148460596 0
+2861 2.481736310639991 0.2124197150308979 0
+2862 3.365016710901346 0.6063569026149663 0
+2863 9.873432617951883 0.8393924239528062 0
+2864 9.873432617951853 0.1606075760473303 0
+2865 3.41505256230995 0.801674556088078 0
+2866 2.869307030885755 0.04629594222624483 0
+2867 8.11956547871878 0.9536973629186876 0
+2868 6.930434521281252 0.9536973629186986 0
+2869 7.059426783608135 0.5715032862418289 0
+2870 2.692956906176679 0.1493786284783918 0
+2871 1.575507327765762 0.5972593076737005 0
+2872 9.259666175042462 0.129088887171371 0
+2873 0.5333313498561547 0.6281625335444444 0
+2874 8.910669312135502 0.7437860134352937 0
+2875 1.255962816658395 0.4515222902195742 0
+2876 5.462899310049924 0.8482925286643392 0
+2877 6.049965312411729 0.867675035630771 0
+2878 2.907782177154524 0.6780989578696954 0
+2879 5.906767709370651 0.7296658353146149 0
+2880 8.959773502286062 0.8757377646267926 0
+2881 6.450317883260501 0.6674885366009558 0
+2882 8.083387603338711 0.1946025970345958 0
+2883 5.560044212072114 0.7404260271169366 0
+2884 8.389955787927962 0.740426027116866 0
+2885 1.460774464377534 0.7025854351460529 0
+2886 5.754327606734677 0.4574987098229079 0
+2887 5.019715179440255 0.8679464274638485 0
+2888 2.630918741084337 0.8806516340764721 0
+2889 3.139991603997168 0.2549623398021155 0
+2890 6.109173287680753 0.7430061134341733 0
+2891 4.935402991001548 0.9528525886255236 0
+2892 3.370936288250136 0.7157526274316681 0
+2893 1.245799693555927 0.2484606276054622 0
+2894 4.972981784257279 0.5878820647043455 0
+2895 5.00875930055599 0.5497436610823683 0
+2896 1.919756215839495 0.8824064760119666 0
+2897 7.169756215838066 0.1175935239873909 0
+2898 0.5245216385071676 0.1113728787665811 0
+2899 8.035834390581137 0.4668260096297019 0
+2900 8.996234363003316 0.05707988288999873 0
+2901 1.914765177830249 0.4051860625253667 0
+2902 7.88520546736236 0.594824673085534 0
+2903 6.39585645722205 0.7347939975003094 0
+2904 7.239439593791952 0.4508922435507496 0
+2905 7.81394574843669 0.454700810025627 0
+2906 1.986054251560138 0.5452991899747831 0
+2907 6.631001804915744 0.351896383790817 0
+2908 9.337962922411728 0.799047040228686 0
+2909 3.093718376299266 0.1249534094335267 0
+2910 6.160735237690919 0.8760152420038122 0
+2911 5.288806331517996 0.7964339786151712 0
+2912 2.953812746769966 0.2263105282139511 0
+2913 1.310673010439973 0.744651222144628 0
+2914 8.696842427960112 0.8705228324562445 0
+2915 8.871798013009265 0.3410521393217651 0
+2916 0.7911966209194584 0.8680458874363572 0
+2917 8.501716363532561 0.4280081288520836 0
+2918 1.105470708369108 0.4444681553553191 0
+2919 7.984859100293095 0.6525142802697128 0
+2920 1.811937506996171 0.3441523698105814 0
+2921 0.4951636870099725 0.3616330039741892 0
+2922 9.708471293420621 0.1763483334952653 0
+2923 9.70938950716819 0.8245522562155374 0
+2924 3.450899495414075 0.2805500233270164 0
+2925 9.95502305249574 0.5582911148315276 0
+2926 0.0449616077072363 0.4416866310680574 0
+2927 0.5395332685147504 0.2709298259607114 0
+2928 8.993292232659419 0.9519116037739094 0
+2929 8.608411334485048 0.8882599962520962 0
+2930 8.826996478076413 0.2198235275693876 0
+2931 3.856138932324107 0.2425928160316668 0
+2932 9.391376286155335 0.2389031162254406 0
+2933 1.829910624470792 0.5330121165608219 0
+2934 6.619537575651879 0.6700287519915166 0
+2935 0.5677283330335682 0.04199164490549442 0
+2936 5.804437178779597 0.8618730836424173 0
+2937 6.354749145480912 0.8615650193407886 0
+2938 5.254169976198151 0.1436372123156546 0
+2939 5.804760592196274 0.1439635296456066 0
+2940 6.907233543554903 0.1411529975761187 0
+2941 1.653737729202194 0.8600773105080913 0
+2942 3.198234587051082 0.1335404120022042 0
+2943 8.453054102574951 0.8694831908084625 0
+2944 0.7492306873138552 0.5395564437483032 0
+2945 9.768275039707223 0.9543254442719535 0
+2946 9.768275039706973 0.04567455572802048 0
+2947 3.344517946678567 0.5368776519385534 0
+2948 9.384828627725417 0.04863040191487602 0
+2949 9.678145992079978 0.2574023734765334 0
+2950 1.135610282386558 0.8895132522717234 0
+2951 2.663372341016481 0.4113509330585086 0
+2952 4.51253321205215 0.7932438201963782 0
+2953 5.133943634085605 0.5748697514675589 0
+2954 7.33497985408632 0.7363242035375934 0
+2955 5.766601135289839 0.04723241545279052 0
+2956 6.316800642960066 0.04592305233131964 0
+2957 8.566800642960592 0.04592305233190509 0
+2958 6.316417153573101 0.9530529358411088 0
+2959 5.766601135290979 0.9527675845460279 0
+2960 2.465031719340259 0.2636407366691746 0
+2961 4.170666319513288 0.2686662839590627 0
+2962 4.263803263585786 0.6026456262001237 0
+2963 4.088917335138747 0.3202027555923733 0
+2964 9.372240932174632 0.3371376362354812 0
+2965 1.065283475270994 0.3858081256200244 0
+2966 6.7262511190254 0.5144849629327689 0
+2967 8.542269182621069 0.5791606198739728 0
+2968 4.240184605931079 0.7795497848177928 0
+2969 0.1289169871533001 0.8064012896388937 0
+2970 5.219724781516464 0.04477322037875472 0
+2971 2.39103674903826 0.3196391738921395 0
+2972 7.410219395635876 0.6806518423695378 0
+2973 0.9522680281231737 0.2479748751148026 0
+2974 7.819349061904247 0.9553843208682816 0
+2975 1.980756479419777 0.04463042915791355 0
+2976 4.432783633110049 0.6086179256069362 0
+2977 5.175874084419621 0.4021131243147534 0
+2978 1.410720423978222 0.3716150644961049 0
+2979 4.875516292859364 0.6093415917781315 0
+2980 3.976086487435338 0.9578574391145662 0
+2981 4.091013716760075 0.6882840905300953 0
+2982 4.854924107940741 0.2324362737631005 0
+2983 4.675355259582737 0.2086813077005671 0
+2984 0.1879061910153189 0.4032877666576613 0
+2985 9.812166428828249 0.5964641124045054 0
+2986 4.544450206926512 0.1175392053638537 0
+2987 3.399069536124683 0.1951197027416894 0
+2988 4.503823177377971 0.1886972607370256 0
+2989 3.141763600053692 0.7425615785327392 0
+2990 6.107774720062589 0.2586369255085055 0
+2991 1.474510142286955 0.4851208053435714 0
+2992 1.409996509719076 0.2323508674572729 0
+2993 0.678747036200899 0.1963150698770178 0
+2994 2.656019463384593 0.04963428305105336 0
+2995 7.906322650638741 0.9504330149406699 0
+2996 7.143645435157218 0.9502981840806716 0
+2997 1.568243794460003 0.5013018792583289 0
+2998 4.331948521991241 0.467420639735564 0
+2999 1.159444017069499 0.801676714541799 0
+3000 3.381355138620717 0.1061110954163149 0
+3001 8.358070197214989 0.2565401683230387 0
+3002 5.236635905143284 0.7951754193595674 0
+3003 0.7842701062891588 0.7372177751754579 0
+3004 4.394767302477942 0.04915318759773712 0
+3005 4.077432271975008 0.04535547886070287 0
+3006 8.070112111425013 0.3670077494657247 0
+3007 3.820137488631894 0.496463445048434 0
+3008 4.265326783115367 0.6993740672888936 0
+3009 0.3609064427497416 0.1086479905521398 0
+3010 8.857230633094014 0.1212499863207202 0
+3011 2.11855549632333 0.5913449522324913 0
+3012 7.681444503673434 0.4086550477676137 0
+3013 1.978330576251138 0.9559317685382263 0
+3014 1.317417519852946 0.9569735214005171 0
+3015 2.743474794487169 0.4602252744292766 0
+3016 1.892001507492771 0.9516771018928016 0
+3017 2.657776917418151 0.9510142711438183 0
+3018 7.142001507490932 0.04832289810710258 0
+3019 0.3697941801202331 0.0465909675122565 0
+3020 4.757947134773503 0.2640976217382979 0
+3021 5.507287585849829 0.8831101689343998 0
+3022 8.645337025959938 0.8088603080030371 0
+3023 0.1139369177733554 0.6682623707316832 0
+3024 9.885851562285017 0.3310534909932735 0
+3025 1.434587274651886 0.5476426409474595 0
+3026 4.462602528355564 0.1140882655314161 0
+3027 5.2894464387518 0.2732685252005844 0
+3028 5.839457951395038 0.2732745310681656 0
+3029 4.728759942113482 0.1004492256440283 0
+3030 9.092386892595567 0.7860121711687932 0
+3031 1.894222697430256 0.04954390592125987 0
+3032 1.421479978982037 0.04908917936054917 0
+3033 1.175944031753404 0.5040828326508021 0
+3034 0.4657050962588395 0.5015457479992342 0
+3035 2.963659165416086 0.2857875414551415 0
+3036 5.082578686262067 0.2115043186554708 0
+3037 2.822548707055318 0.1768976404811349 0
+3038 2.51688802063827 0.4856040661006358 0
+3039 0.1980936957469237 0.1320316794642779 0
+3040 0.9045364375491719 0.114742522568144 0
+3041 0.2885416880199907 0.04327541479945607 0
+3042 1.529951545574989 0.4339731200592798 0
+3043 0.7232981465535614 0.7919105066343328 0
+3044 7.227845652916462 0.04347911183728186 0
+3045 2.57215434707906 0.956520888162775 0
+3046 0.5660034310588502 0.4070659927062161 0
+3047 1.624000849446732 0.9534390592949241 0
+3048 6.382605411264287 0.6169900714836115 0
+3049 9.573836769692445 0.2234993979352927 0
+3050 6.608984148191276 0.1132045874495748 0
+3051 9.561906863323291 0.2755383132713249 0
+3052 0.931949224073546 0.9583497753762104 0
+3053 3.734759561411536 0.3017287506523464 0
+3054 6.29831574558846 0.7266344840424072 0
+3055 4.268008372010168 0.8680985516578 0
+3056 3.782334178499241 0.1719046706686665 0
+3057 1.473058211951805 0.5961973009084722 0
+3058 5.508926151655218 0.1131730724905203 0
+3059 6.059044812162033 0.1134825510132787 0
+3060 4.800408788185761 0.1022256096119304 0
+3061 2.385475287163744 0.2166350022352544 0
+3062 7.414473466177 0.7832631776874225 0
+3063 4.082102901395174 0.2284327454475391 0
+3064 0.4625733615997239 0.3213751915733907 0
+3065 3.764906180892686 0.2200852609314834 0
+3066 9.086343667972555 0.7091208557731101 0
+3067 6.348002882689491 0.7893877171138041 0
+3068 5.907849221878027 0.4111408858857794 0
+3069 5.355531139243565 0.4162170965790395 0
+3070 2.615902562496685 0.5327084351837543 0
+3071 7.332452414527672 0.4390646267955214 0
+3072 4.963891239938018 0.3244096343590621 0
+3073 6.870149728742743 0.8749260011061146 0
+3074 8.179850271257319 0.8749260011059899 0
+3075 6.341574044166401 0.4155433724011938 0
+3076 8.589195513796792 0.4166480328708525 0
+3077 2.904864975414128 0.5896953544537877 0
+3078 9.534031506899339 0.4037039897613279 0
+3079 4.731041688392442 0.8400976980117711 0
+3080 1.576508099348077 0.04002250128034036 0
+3081 5.805564700011415 0.7005051084160309 0
+3082 2.926194757543548 0.5168054709000026 0
+3083 6.324720225024569 0.4840658995954146 0
+3084 9.146989405280531 0.4678569335379345 0
+3085 2.518545604259328 0.6997474758971378 0
+3086 7.132857297247451 0.6921276793699439 0
+3087 0.9878039668910436 0.5840196752021517 0
+3088 1.609758801425818 0.55788842095098 0
+3089 2.824866269352488 0.8189653718640086 0
+3090 9.331189767224796 0.962091079331571 0
+3091 8.623775150962556 0.1224788026097583 0
+3092 6.37413371818209 0.122079034157755 0
+3093 6.004364178825126 0.8469189321035144 0
+3094 9.324095168070256 0.3995127100096025 0
+3095 6.448295597558715 0.9505769849166666 0
+3096 5.898324746791179 0.9505629945414437 0
+3097 8.698200017070008 0.04963880591627217 0
+3098 6.448200017069786 0.04963880591625713 0
+3099 5.898324746790627 0.04943700545855646 0
+3100 5.348354225165791 0.04937449809315922 0
+3101 3.616446203460085 0.04818448942994888 0
+3102 2.929901533327636 0.8746081413088257 0
+3103 7.202013696972079 0.6515712590391936 0
+3104 0.6789021673845415 0.4378642458928756 0
+3105 6.057088694857248 0.6980769099452451 0
+3106 9.247465030328296 0.6667072048072337 0
+3107 8.143026873829676 0.6651275903993487 0
+3108 6.906994135136486 0.6651721493172483 0
+3109 2.571710412184208 0.04276890327801521 0
+3110 7.228144609435113 0.9567247009962434 0
+3111 6.033596797495539 0.9538722062908027 0
+3112 6.583257326368988 0.9540728302925187 0
+3113 8.833354270737138 0.04618946178797609 0
+3114 6.583188069641342 0.04592721641943825 0
+3115 6.033162086127574 0.04587100186917024 0
+3116 5.483162086127216 0.04587100186927727 0
+3117 4.224181261103189 0.9561623967619571 0
+3118 5.171519203059736 0.6033990629795909 0
+3119 1.163964898074734 0.738681944200881 0
+3120 4.535797041479648 0.9541222719899568 0
+3121 3.877777274443238 0.04382348049343074 0
+3122 2.177647333330107 0.04393400007652395 0
+3123 7.624757362430588 0.9602772401627038 0
+3124 1.282477796000356 0.1059983890682306 0
+3125 4.422371429688036 0.4195787845254461 0
+3126 0.1248182213794652 0.2019408563200512 0
+3127 4.935308797670622 0.872866827129178 0
+3128 0.3158150559627009 0.2511759720118277 0
+3129 9.89284463860546 0.04420467962940603 0
+3130 9.892844638605521 0.9557953203706422 0
+3131 3.222761706676076 0.03997299496919512 0
+3132 4.917706338903179 0.7660261312020797 0
+3133 0.6195185570092619 0.3240428650959699 0
+3134 8.804016188263157 0.1461199408078978 0
+3135 2.229402672128872 0.3526491776480036 0
+3136 2.182351332415453 0.3614236394911574 0
+3137 7.57317202321792 0.6484861424488968 0
+3138 7.618183612643912 0.6389381742139153 0
+3139 1.128542440065306 0.1983448679994827 0
+3140 8.508060849702051 0.2625530441636316 0
+3141 6.255086148621811 0.2607157157230054 0
+3142 2.995312465221508 0.7390086700833519 0
+3143 6.599527103363388 0.583641386018239 0
+3144 8.254170779220685 0.5886322428733075 0
+3145 7.086545303433327 0.3226459402486521 0
+3146 1.836600337012156 0.6773004778460213 0
+3147 1.570430825208695 0.3962441242550538 0
+3148 4.814672526577731 0.4590723140409497 0
+3149 8.280014718097103 0.0400199320165702 0
+3150 3.219800390370705 0.9604252232701855 0
+3151 9.068126380886349 0.4752121139323926 0
+3152 0.7674569096685477 0.3876087919005222 0
+3153 9.881419656983931 0.2138651461256125 0
+3154 9.88275750713658 0.7911245881529949 0
+3155 1.367646034830471 0.6745629965936324 0
+3156 4.948489278947197 0.203521511290621 0
+3157 3.306469589433947 0.1564250459696084 0
+3158 4.591959530475979 0.2083566370391398 0
+3159 0.1925965356102349 0.6230100034280172 0
+3160 9.807623523237728 0.3769979677211358 0
+3161 4.65783530065585 0.2998192318629943 0
+3162 2.063832675310645 0.7821037820208122 0
+3163 3.763113934585059 0.7804853101226611 0
+3164 2.077951595051735 0.8318573201157698 0
+3165 3.778515245608455 0.8307513374698428 0
+3166 7.736167324685932 0.2178962179792409 0
+3167 7.722048404944955 0.1681426798843727 0
+3168 3.992792033439963 0.3762040009119516 0
+3169 7.13883093240446 0.776213362675947 0
+3170 7.91145935357611 0.7786277535590457 0
+3171 1.888540646420567 0.2213722464400984 0
+3172 0.1104209807647991 0.4912713000986179 0
+3173 9.88957901923512 0.5087286999013537 0
+3174 6.272730872298209 0.4770865799314771 0
+3175 2.978107629473472 0.5242493843481055 0
+3176 4.36283656925252 0.7137625685094724 0
+3177 3.878904387227028 0.9574213542820866 0
+3178 9.245190415740289 0.77624876736624 0
+3179 6.91127903399178 0.2875472096089363 0
+3180 1.666020111009874 0.7083741699029172 0
+3181 1.124439054820285 0.9616304443049378 0
+3182 6.397572298391203 0.2611400546884622 0
+3183 8.647076873522014 0.2609660220242811 0
+3184 7.886958353028986 0.04057621255694061 0
+3185 3.610868903681564 0.9538583034210235 0
+3186 9.718015944037178 0.5864934667387856 0
+3187 0.1139705296853428 0.85010772483359 0
+3188 3.047416485017551 0.8358111526330261 0
+3189 5.652049131606597 0.1628843686754853 0
+3190 6.201685235544151 0.1628848992428187 0
+3191 6.75347808430026 0.1639537955803915 0
+3192 8.452376781116904 0.1625014269146549 0
+3193 0.9382953395591789 0.8133636789902728 0
+3194 0.2852915206420736 0.4122807530812079 0
+3195 5.837759742839991 0.7788281940847382 0
+3196 8.980580507203042 0.205279119910982 0
+3197 2.467633604352288 0.558437333878691 0
+3198 1.507848366638783 0.8416328810171917 0
+3199 9.513606669792868 0.1299637469580549 0
+3200 7.972566091923103 0.7649658915485866 0
+3201 7.07682629868244 0.7573940083055875 0
+3202 0.3808957502840611 0.9588538931008932 0
+3203 8.041331240253918 0.4169508266014844 0
+3204 2.922137969911047 0.1308796917362059 0
+3205 1.400889432548257 0.459386702004953 0
+3206 5.208101007088571 0.4390323627105308 0
+3207 1.470370442494028 0.2970219336608623 0
+3208 2.572280165194312 0.2658526472060675 0
+3209 4.676917157816916 0.4914697558433385 0
+3210 2.473780810234708 0.8372326436558403 0
+3211 7.326219189761463 0.1627673563445307 0
+3212 3.041236661405377 0.642205510683142 0
+3213 6.208763338589069 0.3577944893161036 0
+3214 4.675242575334625 0.03855319039147162 0
+3215 9.615701138078876 0.9557079072463919 0
+3216 2.27756478700391 0.9551818574122279 0
+3217 7.525162606222176 0.03924564408340656 0
+3218 4.551005426131152 0.6099766184045295 0
+3219 5.75495079048288 0.7667251940427017 0
+3220 7.412879436133762 0.6015124659842429 0
+3221 9.793924782402211 0.2223330685108122 0
+3222 9.794426844721842 0.7744597903991404 0
+3223 0.9665902768204648 0.4952724056807713 0
+3224 0.5808890551620303 0.6321443879655689 0
+3225 5.074586874476687 0.9526889666565526 0
+3226 3.204787446576641 0.5867153039364417 0
+3227 6.827015387588544 0.3987027662141615 0
+3228 4.681320944186678 0.5792776566331217 0
+3229 0.4501695431607991 0.2348071397729175 0
+3230 2.173937877565212 0.9606674157170163 0
+3231 7.623263939679803 0.04340719951366678 0
+3232 4.225586043051667 0.3486712579923777 0
+3233 3.588456568233641 0.2257577902831108 0
+3234 2.663303112936716 0.2230760576956582 0
+3235 2.559663452620117 0.5502282571379703 0
+3236 6.793389906900006 0.5889523610972879 0
+3237 9.443472442049273 0.6546109143093823 0
+3238 5.134452103411864 0.6811504741738976 0
+3239 3.510524072369462 0.1554271369372512 0
+3240 5.568498419285641 0.04309616801143413 0
+3241 6.118524697430285 0.04314800971054926 0
+3242 6.669042485156655 0.04342820291402406 0
+3243 8.916853699908852 0.0430264900294432 0
+3244 5.568498419288702 0.9569038319881888 0
+3245 6.669083062751967 0.9565007762493171 0
+3246 6.116386302367056 0.956071628027602 0
+3247 4.789105936708102 0.5918428163025116 0
+3248 2.270144971268119 0.03942348690329814 0
+3249 7.531582389122379 0.9551095081162945 0
+3250 9.805953705043052 0.6819980053975633 0
+3251 0.1916251878276503 0.3180674610119497 0
+3252 8.03304006589507 0.9574149331395193 0
+3253 7.016959934104947 0.9574149331395442 0
+3254 2.783040065889685 0.04258506686034649 0
+3255 5.692709880797157 0.5890675894056475 0
+3256 0.8903674348457435 0.3894212426500503 0
+3257 7.012009800034847 0.4483618695898542 0
+3258 9.520390937087347 0.8513633709716348 0
+3259 0.848680339645246 0.5532242988461817 0
+3260 3.047804338583992 0.271011460156459 0
+3261 6.203807066486916 0.7325664000566003 0
+3262 1.373134727664988 0.8880227778314238 0
+3263 4.003099071467049 0.5622984168067893 0
+3264 5.211897639123354 0.7528067476804698 0
+3265 4.315740068740404 0.8951306131653135 0
+3266 2.134440842996712 0.1189870377063157 0
+3267 7.663699634375779 0.8808367476349025 0
+3268 1.084047338645992 0.7623863236244193 0
+3269 2.156287302741385 0.5608493227254947 0
+3270 7.64371269725535 0.4391506772744752 0
+3271 4.350440944726975 0.5599815932979914 0
+3272 2.060086249142282 0.6534075652569161 0
+3273 7.739913750854814 0.3465924347432592 0
+3274 7.298984705046913 0.2956193714627207 0
+3275 5.143622609049754 0.146954753189583 0
+3276 7.306694949637722 0.2114914134106054 0
+3277 2.489106372537233 0.7808803589987163 0
+3278 4.07480453243905 0.6297199494905902 0
+3279 6.574664870613622 0.7832713231808587 0
+3280 8.049011392081006 0.1044900721872888 0
+3281 4.98980540931977 0.3595504488868791 0
+3282 8.567736127033536 0.9569418687098782 0
+3283 0.9881894388209628 0.6452533004614407 0
+3284 8.744188318006051 0.8501778122183299 0
+3285 7.146081009943685 0.6020828169007332 0
+3286 9.428476083410496 0.5012229054273516 0
+3287 0.04758854218523682 0.7187719747392125 0
+3288 9.95310408749793 0.2806528176722137 0
+3289 8.531961155670292 0.4845330420701795 0
+3290 4.151318982491675 0.6725109545663306 0
+3291 6.55433976581672 0.8516240653147759 0
+3292 7.997392155085211 0.1858988369678289 0
+3293 5.266794032017202 0.9597740871280123 0
+3294 9.629679625091772 0.8058893018847852 0
+3295 9.002859825029187 0.7309079958588808 0
+3296 0.1522679859099491 0.1143624591870348 0
+3297 4.501247641405363 0.5396781145867295 0
+3298 3.32221772693521 0.9596037367307766 0
+3299 8.17770815373305 0.04076845565120354 0
+3300 6.956414684492072 0.2625091072734221 0
+3301 1.70637204168938 0.7364588508586769 0
+3302 4.376380806251402 0.957298436476046 0
+3303 3.454151568662957 0.8295033009944964 0
+3304 2.850177602183534 0.1016963901243955 0
+3305 8.098984820090179 0.893684435929075 0
+3306 6.949193190539091 0.8974318047368917 0
+3307 1.698979297312278 0.8993747189434603 0
+3308 6.948979297311763 0.1006252810582445 0
+3309 2.851179058599581 0.8984801386743277 0
+3310 0.9927205390583617 0.2728400231282762 0
+3311 0.2144638073501683 0.9606584627433512 0
+3312 3.328567826373116 0.04008034940591609 0
+3313 4.494926624217524 0.6711198226963377 0
+3314 7.868377697282237 0.1184706504320743 0
+3315 4.424772350518122 0.8347035795301038 0
+3316 2.783729405162299 0.9574056815549109 0
+3317 7.016270594832969 0.04259431844515713 0
+3318 1.766270594836204 0.9574056815547257 0
+3319 2.954644217733565 0.6061927845321964 0
+3320 8.544062354845307 0.3948590050316939 0
+3321 6.295055575132408 0.3948813011603003 0
+3322 5.477794390281232 0.2216479286598325 0
+3323 6.024533930525163 0.2150831824161791 0
+3324 4.646729091650051 0.8448061114560032 0
+3325 1.128292258242786 0.5650407797909005 0
+3326 6.649454777180893 0.8202630654053521 0
+3327 0.538386645163456 0.4523561815594208 0
+3328 1.569403359021265 0.8276900653808897 0
+3329 1.768664059787013 0.0424520554622753 0
+3330 4.179615143388882 0.7201769938508603 0
+3331 4.057138927854878 0.5433420449796661 0
+3332 9.114927715213351 0.03881286968071111 0
+3333 9.132786545984594 0.2163091541834923 0
+3334 5.639945739894468 0.2176153811985135 0
+3335 6.741341472142748 0.2175286207795943 0
+3336 0.4383649268693181 0.8372485598093695 0
+3337 1.827921751616198 0.2350155159571499 0
+3338 9.274999999999006 0.03886014803916983 0
+3339 8.347740763239131 0.7033256429721116 0
+3340 5.60225923676099 0.7033256429721768 0
+3341 4.958556225169338 0.4942583725662922 0
+3342 4.078588445826827 0.1220377039319747 0
+3343 0.8749999999992761 0.03882635244387774 0
+3344 9.667748076061706 0.8996126364646977 0
+3345 9.668790823458465 0.100271095359398 0
+3346 8.83138016762863 0.9615845939344114 0
+3347 8.475713403864356 0.9642275376343045 0
+3348 6.57622804400202 0.2235427167419387 0
+3349 0.5319389709320395 0.7106411967297303 0
+3350 0.9704987851398725 0.8923651791133429 0
+3351 0.2168258834061785 0.453896114807282 0
+3352 9.783174116593891 0.5461038851926308 0
+3353 3.727220545115772 0.7052486060460555 0
+3354 7.282510729546743 0.5061501352578339 0
+3355 7.774154218895701 0.5059702556508827 0
+3356 2.025523236695886 0.4941217437634477 0
+3357 4.395876701003261 0.6336417064339198 0
+3358 2.375000000000007 0.9613152401196251 0
+3359 7.423934908283673 0.03848509486475651 0
+3360 2.387298933482959 0.3963226412668979 0
+3361 9.296496398427189 0.8720226833362813 0
+3362 0.1621704785044678 0.5494804238005877 0
+3363 9.837894248194859 0.4505202514521082 0
+3364 9.369461292229264 0.889462611859662 0
+3365 4.234734363564997 0.6562324697464204 0
+3366 0.6358838303229345 0.9562056657822796 0
+3367 7.491693617356418 0.4329169927334823 0
+3368 2.308490044868236 0.5664780776192414 0
+3369 4.464807670507713 0.1680296825958382 0
+3370 6.616903067219905 0.3048951423443456 0
+3371 1.060611592938698 0.4981355721282253 0
+3372 9.749775076128275 0.9025413459145244 0
+3373 9.749775076128147 0.09745865408536485 0
+3374 1.399393503707782 0.6367019991703845 0
+3375 2.184123085681804 0.1331073087108916 0
+3376 7.6177262034327 0.8621562038318699 0
+3377 6.050343573426536 0.4202687660949451 0
+3378 5.234772291553576 0.286073199300013 0
+3379 5.784935697812139 0.286156834146979 0
+3380 8.303271886418893 0.4224101362924702 0
+3381 1.002425075107823 0.1151082137909231 0
+3382 6.864378642847741 0.1083935114148974 0
+3383 8.569779552303654 0.127641995563102 0
+3384 6.325127778475263 0.1264672661771098 0
+3385 1.496733306027697 0.3472009961877631 0
+3386 6.363685628232394 0.698923907372855 0
+3387 3.098081180641171 0.2962752429375069 0
+3388 6.151918819353277 0.7037247570624892 0
+3389 1.072046585917953 0.2563624058481413 0
+3390 9.701134362313942 0.4491721787513058 0
+3391 2.868233807961417 0.3676663250664655 0
+3392 3.826444888356018 0.5955594569288932 0
+3393 1.75586183604804 0.5767236644089957 0
+3394 3.579432035206774 0.4088458406989559 0
+3395 4.739730136782839 0.650949231757489 0
+3396 1.220001193457407 0.5426190072589586 0
+3397 0.9623920197161566 0.3414253237048925 0
+3398 1.972771040077812 0.6533739049885229 0
+3399 7.827056911500235 0.3461975018126457 0
+3400 7.221351955335383 0.3464689124946422 0
+3401 9.120451552023066 0.9610722901596662 0
+3402 0.3785341583877611 0.5976696791444961 0
+3403 5.825447491174557 0.6095582426227004 0
+3404 4.972993837610621 0.1176899974223526 0
+3405 3.127677294764267 0.03993171727410336 0
+3406 1.491029940471972 0.7836753684545679 0
+3407 0.9001738827760327 0.6313927496963274 0
+3408 5.126657153733037 0.4771676946794843 0
+3409 3.128324483484167 0.9577813120062609 0
+3410 8.37117222723152 0.04194104650893009 0
+3411 4.149833267297889 0.1172892919026116 0
+3412 5.725118723606936 0.171546176653825 0
+3413 6.271009535430051 0.1752127346118926 0
+3414 8.520699337629475 0.1763001439913546 0
+3415 4.142453235539931 0.7583694103511314 0
+3416 3.683373535837418 0.5514938046511875 0
+3417 3.331015244944585 0.5789105535314173 0
+3418 0.2548864472607498 0.6965531707944761 0
+3419 9.745108460480518 0.3034556431563817 0
+3420 9.141877290404947 0.4209319012277489 0
+3421 2.02844602847952 0.297397396117754 0
+3422 2.017541942149093 0.3437606049669026 0
+3423 7.779673010217301 0.6565953222585694 0
+3424 7.770999253144591 0.7030981114253085 0
+3425 7.272571824432171 0.6549553189138836 0
+3426 7.283979535966986 0.7030559738443114 0
+3427 1.535190032200482 0.1023967720092232 0
+3428 8.955358882899858 0.2964340156892867 0
+3429 7.977534273707809 0.3827526130997258 0
+3430 4.552308130773273 0.7251609273632904 0
+3431 7.475958432657923 0.2056587307585682 0
+3432 1.035639315798613 0.04396454660034427 0
+3433 0.5123366442998969 0.6678793231153466 0
+3434 0.04412326129555322 0.6404509399635269 0
+3435 9.955876738704413 0.3595490600365318 0
+3436 3.940922239233652 0.8183800756439283 0
+3437 7.637856205375954 0.3363615001924384 0
+3438 2.162143794620699 0.663638499807884 0
+3439 3.074118437744506 0.04167870378556763 0
+3440 6.730041372570689 0.9592094827068349 0
+3441 8.319958627429401 0.959209482706929 0
+3442 1.296715406410455 0.1954776766488581 0
+3443 4.929533600091007 0.03618166769092712 0
+3444 9.29398999191363 0.4355042472802001 0
+3445 1.679410111504367 0.03824925817767075 0
+3446 8.377668652126333 0.9578503985613428 0
+3447 9.613995462670074 0.8768409257268307 0
+3448 6.729572215664448 0.04048610388144314 0
+3449 3.070427784329719 0.9595138961184583 0
+3450 9.443300882934103 0.7025976292811893 0
+3451 9.618537512920964 0.402401966682848 0
+3452 9.529179201238856 0.04539359883282486 0
+3453 9.607882351085001 0.329381746061868 0
+3454 8.940415532008924 0.1220148606090308 0
+3455 4.08397290930553 0.3960110386951878 0
+3456 8.206475832627847 0.6096290491312134 0
+3457 5.056272578106521 0.1216369302825857 0
+3458 1.690999634645648 0.1221856987039831 0
+3459 7.051914255064321 0.6529538718412803 0
+3460 0.1787198824814716 0.03995121735198132 0
+3461 3.771917860093485 0.5376096813240187 0
+3462 9.321995550098348 0.1067036977180401 0
+3463 1.824305390098833 0.8903602072780544 0
+3464 7.07943527140171 0.1101116705217587 0
+3465 0.1015630943780993 0.9612354985834772 0
+3466 1.425972293513429 0.9577325043830469 0
+3467 4.463307816637345 0.9112320000296862 0
+3468 4.397592629995686 0.1941862539866618 0
+3469 3.853293450475631 0.1914452257920925 0
+3470 2.878609616520301 0.6332406295581503 0
+3471 4.220716600129979 0.2989220397502282 0
+3472 5.795266151809324 0.7889517906302023 0
+3473 2.979244833337078 0.8224578129290412 0
+3474 6.820665998069077 0.1764718042945107 0
+3475 4.850961705217832 0.8993465394385949 0
+3476 4.829832737082835 0.6258633258346014 0
+3477 7.950618535221428 0.1059110294006494 0
+3478 2.377604714836857 0.04260324106796283 0
+3479 7.422264571757737 0.9573843064512145 0
+3480 2.787079824680081 0.7618867948970898 0
+3481 7.416571612861258 0.3410463194584016 0
+3482 1.618724407193335 0.7441695662138544 0
+3483 6.174999999999987 0.9624805875561802 0
+3484 5.623155203054032 0.9587052227190428 0
+3485 8.423603639062254 0.04119782473882377 0
+3486 6.173165239775011 0.04134930108343661 0
+3487 5.62312598777224 0.04128367687073715 0
+3488 3.178603685952998 0.3311785219700906 0
+3489 4.908257065491747 0.6413685977225614 0
+3490 1.656184443778532 0.1997178603693175 0
+3491 9.388009308610098 0.6367884496010403 0
+3492 5.521455623607647 0.6679227330941765 0
+3493 1.801137422853435 0.8091822569560254 0
+3494 7.051066902239934 0.1905472926779492 0
+3495 7.725793439284503 0.4820504280913424 0
+3496 2.074768837413187 0.5184395621168938 0
+3497 5.981029070111055 0.6216734778021029 0
+3498 1.802847429907594 0.1881259812014194 0
+3499 2.702117125859849 0.3055639244210825 0
+3500 4.528783875797959 0.8749588164174593 0
+3501 4.894872391728312 0.6870906848691922 0
+3502 2.645883657929023 0.5785362843742843 0
+3503 3.604994519952168 0.5791384733467002 0
+3504 1.0357835526762 0.191175591569745 0
+3505 8.920275115559669 0.9597192258443854 0
+3506 6.69702867625803 0.6625233875824411 0
+3507 2.781329792545675 0.2410568518184268 0
+3508 2.06772074927573 0.1638103090569396 0
+3509 7.732280730480475 0.8361890106238618 0
+3510 2.148854736597807 0.8217474930767736 0
+3511 7.655246559333362 0.1818906268663238 0
+3512 0.3066261862100644 0.7475539839824105 0
+3513 5.276769596574867 0.7136709490979026 0
+3514 5.010437303314565 0.8177771870224915 0
+3515 5.690364979143597 0.8462557506702046 0
+3516 6.373213416861003 0.360931260670856 0
+3517 8.62323558236856 0.3608946754008977 0
+3518 0.7779068810502835 0.0405060111242689 0
+3519 9.586167144870013 0.4351316973787216 0
+3520 8.947926701719194 0.3390147495094802 0
+3521 1.982180561622199 0.09185186389470093 0
+3522 7.817819438374088 0.9081481361050093 0
+3523 2.606132413752059 0.3093628980361448 0
+3524 1.97451669056392 0.9059844642675652 0
+3525 8.430011655508823 0.6683220402678065 0
+3526 6.922841680167361 0.6026461360443247 0
+3527 8.127109806032461 0.603858751623978 0
+3528 3.856380301735553 0.5584896559976986 0
+3529 1.647540962963876 0.7959165370966633 0
+3530 6.899231030232016 0.2039455429869851 0
+3531 5.819103470279724 0.04098607962675407 0
+3532 6.369029818150894 0.04034746517183752 0
+3533 6.368787248890588 0.95918758723199 0
+3534 5.819103470280614 0.9590139203721546 0
+3535 8.619029818151269 0.04034746517244833 0
+3536 5.835718748518842 0.8884644431976191 0
+3537 6.385405409306713 0.8885937213498472 0
+3538 5.834774389911236 0.1084112293038528 0
+3539 5.28539026302649 0.1120485386071644 0
+3540 6.583772921556433 0.4821351147769126 0
+3541 6.843802552323494 0.6111905456505715 0
+3542 5.743802552323497 0.6111905456505958 0
+3543 9.593775965229426 0.6569734645782539 0
+3544 2.402304015217296 0.8235042994683793 0
+3545 7.396922239122298 0.1776967693334734 0
+3546 9.305639843442581 0.6130108929467094 0
+3547 3.848755830386309 0.8213680548723631 0
+3548 8.621678203356652 0.5333253485495479 0
+3549 1.143761797699136 0.6454215997285955 0
+3550 0.5494727936722964 0.539134892090855 0
+3551 3.269763172151886 0.3811863840480815 0
+3552 5.431202802837641 0.621151595208102 0
+3553 5.441823467286883 0.7020701439259196 0
+3554 8.513345715755694 0.7057073925207726 0
+3555 3.258746426398818 0.2980304719145784 0
+3556 9.153813829241338 0.3053719250721365 0
+3557 3.961571918918397 0.1473783840928009 0
+3558 2.262496066719249 0.1492409854475381 0
+3559 7.538428081078565 0.8526216159081556 0
+3560 7.996162973381638 0.8091854339458633 0
+3561 7.053837026618355 0.8091854339458697 0
+3562 4.842150894869214 0.186870959749209 0
+3563 9.501508737657916 0.4656459409678283 0
+3564 0.4988057526053454 0.5341310860365052 0
+3565 4.054260764234102 0.9559154642634354 0
+3566 6.422562650705379 0.1815508150928589 0
+3567 8.672132370042144 0.182030537235095 0
+3568 8.954191404199809 0.7047599993374982 0
+3569 1.831506856057919 0.1114569687351757 0
+3570 6.876396573318067 0.2567172824293311 0
+3571 2.348703902441173 0.7131952577166162 0
+3572 7.446343926936659 0.2868920618722461 0
+3573 0.1876999585241622 0.6737336452386486 0
+3574 9.812300041475787 0.3262663547613955 0
+3575 5.475921212908589 0.7936015358498207 0
+3576 3.225719323323754 0.2079161913156129 0
+3577 8.473712824544048 0.7917105302209891 0
+3578 2.475018186571107 0.1623544696101057 0
+3579 7.324695714467627 0.8376666919531691 0
+3580 1.098354238337165 0.8044709180795903 0
+3581 3.064338021638807 0.7882205948096148 0
+3582 6.185471937497753 0.2116019478408424 0
+3583 8.439048247566724 0.2113143977242739 0
+3584 2.89214808294068 0.3098808493310505 0
+3585 6.414360803613398 0.4709330960428761 0
+3586 3.584096461243242 0.1705711869265799 0
+3587 9.160968123577861 0.6862636753661165 0
+3588 0.03663894384019267 0.8249999999998265 0
+3589 9.963361056159812 0.1749999999998025 0
+3590 9.963361056159954 0.8249999999995711 0
+3591 0.03663894384001325 0.1750000000007281 0
+3592 1.229178323928807 0.04210879945454871 0
+3593 9.063310595800051 0.1081545299788604 0
+3594 9.097935849546925 0.1290332981207374 0
+3595 4.404961233217184 0.6859728041469181 0
+3596 5.002819814959818 0.7394223212907701 0
+3597 8.919276210965183 0.5848051246827299 0
+3598 3.694013964045717 0.04389427983756326 0
+3599 0.6487071323517583 0.8104678293877636 0
+3600 7.398819555980347 0.7415606289474149 0
+3601 3.582072537328383 0.8303424928190388 0
+3602 9.626842499145884 0.03719783354117178 0
+3603 5.170919263602351 0.177503610321325 0
+3604 1.51285669015783 0.1694845140093362 0
+3605 1.494921443135639 0.218366633323986 0
+3606 5.524900378978366 0.3623055246317609 0
+3607 4.841349066167172 0.7523278706260366 0
+3608 6.667213715756062 0.7350190537638078 0
+3609 0.2979093323003766 0.5501203529534495 0
+3610 9.349376378463504 0.2619213263737059 0
+3611 1.299076274124968 0.3516575562314152 0
+3612 0.4157893427273532 0.03826539123256956 0
+3613 6.972492248648589 0.5306415209068629 0
+3614 2.436771682452956 0.4045891960411333 0
+3615 2.400869250087336 0.2579823437029446 0
+3616 4.223704556195056 0.2097326399893933 0
+3617 0.41615301699759 0.5669771051059648 0
+3618 8.304383545528911 0.8378421941824791 0
+3619 6.748178486279175 0.8445674710074766 0
+3620 4.318496707514699 0.04007169905613956 0
+3621 2.166222461162679 0.4095276463879542 0
+3622 7.634062116980428 0.5907280504942365 0
+3623 6.776119239515916 0.4305191560023704 0
+3624 4.069222726502846 0.7761237393992687 0
+3625 4.267860806692193 0.2814530773419823 0
+3626 0.1186921339377784 0.3336040864127913 0
+3627 9.894834088078101 0.6938654813302765 0
+3628 3.069652006204697 0.7132677456177863 0
+3629 6.18083112594559 0.286330238158147 0
+3630 3.690624227978367 0.9569683314923569 0
+3631 7.809375772016247 0.04303166850785441 0
+3632 7.081549169103286 0.8923365997413292 0
+3633 7.968450830896654 0.8923365997414602 0
+3634 3.821988677157141 0.4050931357531394 0
+3635 1.191767446730467 0.1954348350957189 0
+3636 4.260526469602436 0.4253036141078875 0
+3637 7.22640453063509 0.09150853236953573 0
+3638 2.573595469360262 0.9084914676305743 0
+3639 8.611236593437692 0.8419422825760658 0
+3640 6.706408726510881 0.7050606382785277 0
+3641 0.9341469487871127 0.5790701273938174 0
+3642 5.567923577667944 0.3908068107398674 0
+3643 2.574328039744454 0.4044966176977633 0
+3644 2.586225864342345 0.4546451201935007 0
+3645 1.324406152679066 0.03684923217970663 0
+3646 0.8795390075696667 0.474817535233887 0
+3647 1.515740042116947 0.5242914042096392 0
+3648 2.09240157422169 0.3629356949574692 0
+3649 7.707391370099938 0.6371881770548306 0
+3650 7.340447267265903 0.6342738421428233 0
+3651 0.6088579028945115 0.8971242375193906 0
+3652 0.3919409839233838 0.6815409513815774 0
+3653 6.206808507321471 0.842141039623341 0
+3654 3.043191492672625 0.1578589603761106 0
+3655 4.573144954546454 0.2878706877905007 0
+3656 9.374991012968717 0.4303549271652579 0
+3657 5.062755732243601 0.7901338388151725 0
+3658 8.97841270076794 0.5942654481666312 0
+3659 4.121057413629034 0.03796827748605504 0
+3660 5.078028701091181 0.6170275481536095 0
+3661 1.067611632952447 0.6170445597757629 0
+3662 4.328487184507311 0.1108229300382773 0
+3663 9.586420371734354 0.7298130292656939 0
+3664 0.7053777475792251 0.5520005188227474 0
+3665 6.857234540879992 0.4428988848374477 0
+3666 0.3115328349356956 0.1108210837562967 0
+3667 9.102562056280034 0.2933922619986792 0
+3668 3.89929617895259 0.2900620777530755 0
+3669 3.071166746470557 0.406312845240859 0
+3670 6.178833253523371 0.5936871547587818 0
+3671 2.562405185653549 0.8267567941631523 0
+3672 6.337987502694626 0.32450655684762 0
+3673 8.587978558364622 0.3246221900546036 0
+3674 3.695502319715246 0.1727412682080715 0
+3675 0.5803081769336026 0.7669042004702225 0
+3676 2.51479232322916 0.2950160756310436 0
+3677 4.850606091134678 0.5435582456220321 0
+3678 2.55790080758045 0.1720768083557113 0
+3679 4.108971594890386 0.1892879983550315 0
+3680 5.124270514100348 0.4302067200645925 0
+3681 1.12325017354356 0.1171450937558392 0
+3682 0.7279561576131576 0.6981795496307801 0
+3683 7.55833732907123 0.5718663611048502 0
+3684 2.238661602252415 0.4308999684874865 0
+3685 5.147667848024969 0.7754879794506098 0
+3686 0.8794087965326044 0.750241799768237 0
+3687 5.590975618878829 0.6612086416741166 0
+3688 8.359024381121372 0.6612086416740589 0
+3689 8.266946416285306 0.1662574222742798 0
+3690 1.3596712778737 0.1033072273263224 0
+3691 7.235081502903861 0.1739380937585809 0
+3692 5.025952204219215 0.04200149908838118 0
+3693 6.477145022160479 0.8810008825732096 0
+3694 5.927123878814832 0.8810604308810788 0
+3695 8.726860884408282 0.1194564050662668 0
+3696 6.477220389042804 0.119022499291319 0
+3697 5.927521372940128 0.1185896638255303 0
+3698 5.37752434554937 0.1185833605618668 0
+3699 0.6282303992793716 0.4442833351807487 0
+3700 0.3235832177301827 0.8948388091491319 0
+3701 0.370198174978224 0.8792101770505479 0
+3702 0.7091815851275831 0.1044264812042218 0
+3703 4.276953776155397 0.8151560187004894 0
+3704 8.194320821966773 0.14396636541454 0
+3705 3.693316221715981 0.8284869470826209 0
+3706 1.583259864490655 0.1856462739843117 0
+3707 1.19747969977362 0.2491868425937527 0
+3708 4.411921122549449 0.7751239704659538 0
+3709 3.579068880046375 0.4863294247338575 0
+3710 0.5928377227124784 0.1353949601789778 0
+3711 5.224028859124361 0.9624243066547101 0
+3712 1.745173888384639 0.6658409859139071 0
+3713 6.995342550365261 0.33404315616568 0
+3714 2.03963599522385 0.7039834592642512 0
+3715 7.760364004772769 0.2960165407359202 0
+3716 0.8638439641858677 0.1254026548334967 0
+3717 2.304070382530677 0.3715766469797419 0
+3718 2.310476697061023 0.4239786238138202 0
+3719 4.303071460240384 0.3243087942559978 0
+3720 5.840220992038744 0.2191347473432134 0
+3721 5.795626866846864 0.2031492339108422 0
+3722 5.290220992038847 0.2191347473433117 0
+3723 5.244831886359715 0.2027850083748985 0
+3724 7.805401770103739 0.1746614104938056 0
+3725 1.994411321419889 0.8254934697417998 0
+3726 8.501757733053109 0.5589149371114224 0
+3727 7.30326194502114 0.3473706487051904 0
+3728 3.678687487637319 0.4034863760477906 0
+3729 0.7742424692389889 0.5857527973119814 0
+3730 8.771270482725628 0.6133965760643842 0
+3731 5.192517690103112 0.8906627541659384 0
+3732 3.528480131490975 0.6079811312315654 0
+3733 2.721572792902148 0.6079855414796012 0
+3734 4.555865536709666 0.3673982316202987 0
+3735 9.005782861279766 0.1565364396865017 0
+3736 1.323341140143452 0.8718497284066631 0
+3737 1.94850915780685 0.7659780627488141 0
+3738 7.849451680500799 0.2325090337241696 0
+3739 1.081253917091225 0.9639327560021144 0
+3740 0.6783451509162904 0.7070440474940126 0
+3741 3.312722865638643 0.8578800994499328 0
+3742 6.111245711539835 0.6416150778303624 0
+3743 3.275474163330545 0.5132579108120765 0
+3744 1.782185038219238 0.7285971933932832 0
+3745 7.031824001585593 0.2713473106687266 0
+3746 2.574901645290758 0.09062114986574858 0
+3747 7.22907172089385 0.9075736698261984 0
+3748 4.875050373671027 0.5025530673586482 0
+3749 9.005149427814358 0.8441371565046704 0
+3750 4.008635886255991 0.4266956092719115 0
+3751 3.840870213540268 0.1078352765431869 0
+3752 6.36064810357463 0.6582136773606223 0
+3753 0.9727697039993938 0.4087310013892393 0
+3754 4.583651791315267 0.8314580327810881 0
+3755 4.859001889372093 0.8274224177942736 0
+3756 9.696818828234433 0.7516922863309066 0
+3757 3.934076880252527 0.671645226943466 0
+3758 2.955503646144445 0.3738203179480664 0
+3759 6.294496353849778 0.6261796820510903 0
+3760 9.095355108500616 0.6250619926701135 0
+3761 9.516686097686424 0.706172381458917 0
+3762 4.112497440395115 0.4789990161584683 0
+3763 0.804286641278511 0.6596507136760583 0
+3764 9.454137632380849 0.2918649819008949 0
+3765 5.643771685751926 0.8376609416642941 0
+3766 2.379396452403537 0.647708851321107 0
+3767 4.660767801953301 0.7939087408412782 0
+3768 4.621459763307649 0.7642935069045551 0
+3769 3.232592058401612 0.8321143846471298 0
+3770 0.2657782264550078 0.6337588615287637 0
+3771 0.6340033565469082 0.5213962942800606 0
+3772 4.34239160862142 0.4265862505789779 0
+3773 4.424197630177088 0.5602426565062787 0
+3774 8.391970148983434 0.3407888043268634 0
+3775 2.717830700463211 0.1052553802251519 0
+3776 4.053296670772318 0.8862500076762139 0
+3777 0.3325956043899349 0.5243792032322596 0
+3778 9.666638624207229 0.4759743861139004 0
+3779 9.277533522099963 0.2580909393894435 0
+3780 0.5079422233063939 0.7882843495886854 0
+3781 0.3233142260821257 0.4772545474409318 0
+3782 8.770454813811869 0.3955321784074921 0
+3783 9.677616289684973 0.528340555405486 0
+3784 6.664336620571056 0.9033369718781433 0
+3785 5.560702856745076 0.9093441113881867 0
+3786 6.109242527553958 0.9112576375109013 0
+3787 8.908333422744585 0.09252355690350279 0
+3788 6.66070285674491 0.09065588861186141 0
+3789 5.560702856744776 0.09065588861186319 0
+3790 6.110702856744805 0.0906558886119096 0
+3791 3.724628699425145 0.3962084162187965 0
+3792 1.523093112312897 0.5704571611583928 0
+3793 3.13654259794983 0.4084346525458454 0
+3794 6.11345740204461 0.5915653474536389 0
+3795 8.873217917658474 0.2954639181411663 0
+3796 0.2263774632134052 0.1063321013700942 0
+3797 6.419719144017798 0.820817016382994 0
+3798 5.868817532196533 0.8208180372242779 0
+3799 5.320310312871156 0.179499112971085 0
+3800 5.870310312871128 0.1794991129709823 0
+3801 5.663880311261916 0.6411789931957046 0
+3802 6.767437518806952 0.6391592245157589 0
+3803 8.045385273092688 0.9108520576530863 0
+3804 7.003597512850376 0.9099118142134398 0
+3805 2.792822609802423 0.09094570927774251 0
+3806 8.817709509822965 0.832526224210114 0
+3807 2.182013755932927 0.2857164455648186 0
+3808 7.622650290091715 0.720588778452811 0
+3809 4.308511535054426 0.5355551481577187 0
+3810 1.32110649882794 0.2706367365244917 0
+3811 4.454101721370521 0.5296037348371915 0
+3812 9.03494755262089 0.238358378694004 0
+3813 9.376935495205878 0.4826231230882823 0
+3814 1.124947958234905 0.0331012250699594 0
+3815 9.478835993608808 0.1682842255256665 0
+3816 0.6750182841990592 0.03655038673581889 0
+3817 0.03385499731820188 0.328033355933905 0
+3818 9.965732314523438 0.6716554034205823 0
+3819 7.197098299820695 0.2393890820572726 0
+3820 4.798403558747639 0.6816986160893683 0
+3821 0.4076400304923672 0.3727851882508745 0
+3822 2.056018771240371 0.2104004020896736 0
+3823 7.743981393173466 0.7895995223192377 0
+3824 0.3233673063327678 0.3364149208843228 0
+3825 5.01457445708933 0.9078317480043965 0
+3826 2.722630989704407 0.8932351701801576 0
+3827 9.665563091925323 0.612993790084527 0
+3828 8.374833602320908 0.1704472335108625 0
+3829 6.667554645349409 0.1712061570228945 0
+3830 0.3901033728154807 0.7576491545041029 0
+3831 5.270835995975109 0.03917957852732858 0
+3832 3.235754797635025 0.1598759131335569 0
+3833 0.2024029303643471 0.7730707501225711 0
+3834 4.398119282866008 0.9101335903325332 0
+3835 0.2470524471700189 0.9000884354533363 0
+3836 9.416354357153006 0.9606857013367102 0
+3837 2.072470909091587 0.5649846738681599 0
+3838 7.727591566094186 0.4350697694884437 0
+3839 3.125302683213148 0.8291326755935302 0
+3840 5.566670201783741 0.1712214432277836 0
+3841 6.11700239654561 0.1716382954640103 0
+3842 0.3326138223805001 0.3869472684059097 0
+3843 9.710376453538361 0.2217649057244743 0
+3844 8.316600102975229 0.7849514393137775 0
+3845 5.633012711715056 0.7848883548763352 0
+3846 6.734478885102338 0.7861059839125886 0
+3847 6.84940876025643 0.717275183542737 0
+3848 8.200591239743581 0.7172751835427713 0
+3849 5.801524976358108 0.656280752213999 0
+3850 1.336502901340967 0.5752432489632571 0
+3851 0.6836771157964164 0.3763714013270992 0
+3852 0.6373427686783364 0.369134864042798 0
+3853 5.090830915187909 0.6582428098690348 0
+3854 7.483868589084932 0.6340888881253021 0
+3855 9.301020276245403 0.7166172125406581 0
+3856 9.45975978047993 0.7849998080774198 0
+3857 1.53349253029254 0.6540826673332749 0
+3858 5.679616699610601 0.3437642076710098 0
+3859 5.129227555263585 0.3434906769462585 0
+3860 6.778272718649378 0.3434047676592218 0
+3861 2.793541318277643 0.9092911455434159 0
+3862 7.00645868171744 0.09070885445696857 0
+3863 1.751584224475084 0.9098609666849278 0
+3864 2.372057461761186 0.12867792827031 0
+3865 7.427772844933925 0.8712630904147822 0
+3866 1.014770059952817 0.7815028735609206 0
+3867 9.96287411335005 0.480265829565781 0
+3868 0.03712588664998986 0.5197341704344344 0
+3869 4.125069711654375 0.4026435296273889 0
+3870 5.075427196633943 0.03961929094052331 0
+3871 8.624003954161564 0.7707891631325215 0
+3872 9.470996811860431 0.354730524750321 0
+3873 2.838876387520925 0.5277066469011451 0
+3874 3.411123612466099 0.5277066469011585 0
+3875 1.442601996429918 0.4568502708866244 0
+3876 7.109552849941236 0.5616004136181078 0
+3877 8.92750918907544 0.8310454443218382 0
+3878 5.748662215740143 0.9030574520045364 0
+3879 5.748481159068231 0.09681215240820017 0
+3880 0.9077100005955279 0.292429860505839 0
+3881 7.236528529345946 0.5803108206900177 0
+3882 2.52682028308033 0.3384934761058339 0
+3883 3.412080000366567 0.2802311025294346 0
+3884 3.105260625215283 0.336760429214291 0
+3885 2.023904003339772 0.966735868561004 0
+3886 2.025297247649775 0.03316007261403207 0
+3887 7.774698344795921 0.9668401428545094 0
+3888 9.349101398510314 0.5906442076391351 0
+3889 0.8583577337432362 0.8106361445032625 0
+3890 4.968674143757142 0.7035217320416167 0
+3891 4.927627987194352 0.716924514713237 0
+3892 6.743636682474614 0.2682111364455269 0
+3893 5.6429565103676 0.2685630409432 0
+3894 4.602430049946801 0.4330136245243381 0
+3895 4.154682510488209 0.3648488015122877 0
+3896 1.710065250620758 0.7861016772620811 0
+3897 6.960065250619276 0.2138983227400192 0
+3898 1.690920967057398 0.530103390467273 0
+3899 7.485600065116232 0.5663151711756585 0
+3900 8.829437643165313 0.4886574712555334 0
+3901 7.273848394947163 0.03279183277857403 0
+3902 2.526151605048617 0.9672081672215183 0
+3903 1.438146430562484 0.7852319921554711 0
+3904 8.944071118958341 0.6643143022008046 0
+3905 2.71088668119171 0.745741766615222 0
+3906 0.4739811926665978 0.1564924562745671 0
+3907 8.271795222176648 0.7698954307478336 0
+3908 1.213440562038147 0.3823287857862553 0
+3909 3.68728742952321 0.0966369418493235 0
+3910 4.638942129458462 0.4010017352457432 0
+3911 4.346300204783546 0.8221873484774879 0
+3912 3.142537941597881 0.6472709241609749 0
+3913 6.107462058395658 0.352729075838447 0
+3914 8.462399092202006 0.6001633867076612 0
+3915 3.963535838972621 0.7106371255849996 0
+3916 4.782068193468382 0.5092930036103088 0
+3917 0.8181515536268904 0.5127559852553712 0
+3918 1.844857745719558 0.8450650996239074 0
+3919 7.094854520527258 0.1546325918557214 0
+3920 2.430643929074247 0.4676054363794694 0
+3921 4.821364592601763 0.9670422316421029 0
+3922 8.263330124448203 0.8403117266689298 0
+3923 6.787049140032453 0.8408726851103621 0
+3924 5.030839920090904 0.1670048740546385 0
+3925 4.336098869041368 0.9626420681685948 0
+3926 5.631110599729609 0.3936073976015704 0
+3927 7.270165065847606 0.7852894510873604 0
+3928 6.767986549908531 0.4966223296945413 0
+3929 3.824236573767053 0.8973857654304672 0
+3930 1.261397126429205 0.2873815535966303 0
+3931 1.193509827753731 0.5858118110222462 0
+3932 9.481154684640931 0.2598054918232426 0
+3933 5.525254082683904 0.712103215320952 0
+3934 8.425058364140591 0.7124428718126896 0
+3935 0.9205373736582053 0.3437518444655021 0
+3936 1.62430798351256 0.2791799457351385 0
+3937 4.745005917220835 0.7857384455294915 0
+3938 0.9660523647022511 0.03871093934313028 0
+3939 0.5837783926338388 0.8378914550976662 0
+3940 6.536739982282043 0.6851677681624389 0
+3941 7.246988183398825 0.829510500083747 0
+3942 3.669805929433705 0.2572302259378454 0
+3943 0.6268193065356046 0.7695439529158644 0
+3944 6.14966432304169 0.6616684831950091 0
+3945 2.526105762246464 0.03257270867145734 0
+3946 7.273874907298716 0.96735977189844 0
+3947 4.716605160232063 0.9615727455988247 0
+3948 4.116046355555079 0.896452664921478 0
+3949 7.31999408184916 0.4836996046046448 0
+3950 7.54036309839842 0.3664676822493137 0
+3951 2.25513563283376 0.6305413577250978 0
+3952 3.175745441132358 0.287402614315108 0
+3953 0.8273701502434542 0.9652772230733009 0
+3954 6.249515706509591 0.616698164415597 0
+3955 2.999363325486497 0.3879620153075666 0
+3956 0.5656581362731602 0.4906231986092301 0
+3957 1.617478522576991 0.8981770420231254 0
+3958 2.520340702734383 0.4075852486227629 0
+3959 2.4449550914603 0.3316022975988551 0
+3960 9.050609497910683 0.6119592058440888 0
+3961 0.6592639630922048 0.6557969025787558 0
+3962 9.238302201316158 0.5893588379167873 0
+3963 4.190745599411801 0.6444432135482938 0
+3964 5.597291980328042 0.4580880061857223 0
+3965 2.265845589401013 0.7073738224874409 0
+3966 7.540178413437587 0.2899075451309892 0
+3967 2.574126626589042 0.6022824567892787 0
+3968 1.056258985873251 0.8975501840721457 0
+3969 4.939073988858758 0.4225648136350033 0
+3970 9.192300312783596 0.04098370456047545 0
+3971 6.392319528704845 0.7828817308280239 0
+3972 2.776895811504863 0.1563897878914616 0
+3973 4.193680406860838 0.4249898022710863 0
+3974 8.030318149019703 0.2475473196380763 0
+3975 1.147033100148481 0.2626420997420322 0
+3976 7.990374397216401 0.4860330772700354 0
+3977 0.09912159905027255 0.03778668577783832 0
+3978 9.173007141380976 0.6426336030555756 0
+3979 9.167458051160473 0.6015561851081244 0
+3980 3.681632287625003 0.9073329173610164 0
+3981 7.816776197266655 0.0960255259781531 0
+3982 4.87697780108344 0.7764708211710196 0
+3983 4.560986199072705 0.4124245883516873 0
+3984 9.084132764340696 0.3413693201868972 0
+3985 0.6092752790735846 0.4842753073458827 0
+3986 8.643106744469581 0.2113494689900036 0
+3987 6.3934448983502 0.2111408072208073 0
+3988 4.92668697881057 0.5563451193578086 0
+3989 1.32107715277464 0.1216054544290057 0
+3990 2.103308681909752 0.239295250692225 0
+3991 7.696691318086183 0.7607047493076151 0
+3992 9.012829486956251 0.3574703467615652 0
+3993 2.607859684777157 0.2241855796011938 0
+3994 6.476735530776684 0.634077432344735 0
+3995 4.578293830448063 0.6917957342290223 0
+3996 6.779039813402242 0.7706052432593944 0
+3997 5.677968879550565 0.7693486776289702 0
+3998 9.755928827727598 0.7006149340189552 0
+3999 0.3458059480329897 0.1893664023773117 0
+4000 2.460810310742461 0.6443690530865451 0
+4001 2.430440680149801 0.679235593704164 0
+4002 4.135718117881081 0.8305045939384924 0
+4003 0.7422707645349121 0.95917780505428 0
+4004 3.871656473818187 0.3381409619608148 0
+4005 5.096613516920947 0.2706517293976624 0
+4006 1.760513871150137 0.09160965231215633 0
+4007 8.785784760861285 0.3142878821880382 0
+4008 3.764337113043636 0.09469694433208625 0
+4009 7.736561087604072 0.910200037670863 0
+4010 2.06343891239217 0.08979996232899025 0
+4011 7.902514114086615 0.7027500354451824 0
+4012 1.897476264212554 0.2972632999504717 0
+4013 3.124645962382819 0.1660859780106312 0
+4014 6.12778812586521 0.8320771080041751 0
+4015 2.77994589683371 0.8475943505290853 0
+4016 7.959751802652718 0.2649913117538898 0
+4017 9.283681415638965 0.961910525735362 0
+4018 3.639955334467205 0.1056439099392282 0
+4019 3.27636696292368 0.6196293234794352 0
+4020 6.304008457228481 0.9022440776207237 0
+4021 5.09032811641362 0.740232647471449 0
+4022 2.39557944508786 0.5960952079489401 0
+4023 0.03793778435097343 0.5949737765283329 0
+4024 9.962062215649034 0.4050262234718821 0
+4025 0.4847431325636215 0.1964497204589731 0
+4026 6.675752024470346 0.34793437724047 0
+4027 3.002351812340121 0.6652801380173778 0
+4028 8.496966727422215 0.3346106777186494 0
+4029 6.246966727422204 0.334610677718587 0
+4030 3.63817182478342 0.894805740355299 0
+4031 3.638133562813901 0.7773004507601291 0
+4032 0.6711022550141187 0.9631592060162657 0
+4033 1.111825625080191 0.732547839840479 0
+4034 0.102699881434869 0.7800892579713177 0
+4035 6.82500000000002 0.9671412754207362 0
+4036 8.225000000000083 0.9671412754207619 0
+4037 2.97383948127275 0.03444809635703197 0
+4038 9.074560850993143 0.03317527891802483 0
+4039 5.236579933411996 0.8749464097438313 0
+4040 5.430647263539894 0.9556021686906927 0
+4041 3.577732465798682 0.03715262585989657 0
+4042 8.222054823012897 0.3913290135955988 0
+4043 5.295862606104987 0.4685035751040048 0
+4044 4.626395033511582 0.2269736648177676 0
+4045 0.6732825331825752 0.1194818776159368 0
+4046 7.896010926152227 0.3077598508168483 0
+4047 8.922734789702536 0.1678316942818519 0
+4048 4.101112305198988 0.7447254043063103 0
+4049 5.90713863765353 0.3203564410138601 0
+4050 5.357138637653513 0.3203564410139278 0
+4051 1.492597416080789 0.7324093169006686 0
+4052 3.469917578896693 0.2176674194642313 0
+4053 8.737156289270095 0.45914672672933 0
+4054 9.813827021058863 0.03976699178059218 0
+4055 9.813827021059023 0.9602330082194152 0
+4056 1.475000000000001 0.9673343594828987 0
+4057 4.472773031719138 0.6264968914864922 0
+4058 5.632474985313706 0.5248268922772374 0
+4059 2.009322354427706 0.2223169163016508 0
+4060 7.790677645568102 0.7776830836983254 0
+4061 3.671812854197223 0.6015060957426263 0
+4062 9.744479173026704 0.6293243677252092 0
+4063 4.86264196193896 0.1504100063489731 0
+4064 7.420739087625772 0.5362973518568783 0
+4065 7.37358360132361 0.5278798392578719 0
+4066 9.736416233925187 0.3678190623637028 0
+4067 1.179791630928757 0.8998195426710601 0
+4068 8.3052611434961 0.9170287779101441 0
+4069 6.745597433081159 0.9172358223217388 0
+4070 3.062596308760956 0.08223471704596567 0
+4071 6.824999999995115 0.03254318050485842 0
+4072 2.975000000000005 0.9674568194952068 0
+4073 8.111125066752816 0.4705136212472147 0
+4074 1.333713723889354 0.4891532380281463 0
+4075 0.2595675929989306 0.304575152931062 0
+4076 3.537906935501687 0.3004832882219236 0
+4077 1.015445351006179 0.4450628515836967 0
+4078 8.874144446866406 0.8984970661420861 0
+4079 7.604907439450855 0.3055740246546139 0
+4080 2.195092560545652 0.6944259753455284 0
+4081 3.102365102444699 0.2117666831337272 0
+4082 6.149306044532262 0.7884573824780646 0
+4083 5.67578355922956 0.4972436124474317 0
+4084 4.923539323820844 0.5127003768717582 0
+4085 9.550404686077902 0.1474722123874774 0
+4086 3.135010337975901 0.09119879169791072 0
+4087 1.932035913907428 0.8419101253290844 0
+4088 7.185792912693 0.1554970182798203 0
+4089 2.127254727047196 0.8974066942605895 0
+4090 7.674094097934751 0.1034739223388024 0
+4091 0.8318165588140132 0.04364666083544941 0
+4092 9.073233489804471 0.9662710409831881 0
+4093 1.114251551807429 0.2393271223691938 0
+4094 8.36420589204714 0.09181630958465292 0
+4095 3.135674008517642 0.9080714085487287 0
+4096 3.887562807261264 0.7341052195668002 0
+4097 9.413471974902087 0.3651856958482735 0
+4098 9.534385132353805 0.9627643324199219 0
+4099 1.330174304171794 0.3224067714693743 0
+4100 0.6097775330968855 0.4055075979321031 0
+4101 3.82187874872118 0.3196314696538133 0
+4102 3.637543145324591 0.5365589786843139 0
+4103 2.616429046617311 0.7760608109735715 0
+4104 2.293227424869364 0.8618681945729326 0
+4105 9.235477572268598 0.3543210092629969 0
+4106 3.333136196202647 0.7329288314796809 0
+4107 4.471648235647097 0.3883478161996583 0
+4108 0.2548137113310276 0.3717989846044374 0
+4109 3.792980847252903 0.3574582441958243 0
+4110 6.7450406441742 0.08354396756989214 0
+4111 3.054815126512782 0.9164734017530043 0
+4112 7.302971832840461 0.5625924303542651 0
+4113 7.755887816066258 0.5796823613407986 0
+4114 2.04411218393061 0.4203176386597249 0
+4115 3.475607866567622 0.7421858942214974 0
+4116 3.764755719286825 0.2728743364361889 0
+4117 9.804105796681998 0.1416625345551135 0
+4118 9.804105796682022 0.8583374654448509 0
+4119 6.659041864834924 0.6513495434510744 0
+4120 9.770532583515644 0.4038728114222858 0
+4121 0.2309624958707925 0.5961938645242519 0
+4122 5.868396974397617 0.3620655159542243 0
+4123 5.318396974397578 0.3620655159541437 0
+4124 3.974653751493914 0.5186830894874395 0
+4125 7.526034658152511 0.5063982948455694 0
+4126 2.273743755974463 0.4931131310178763 0
+4127 1.21137402229705 0.331707673606933 0
+4128 8.059567945679598 0.7588634955607383 0
+4129 6.990852689802081 0.7569708248858223 0
+4130 4.49979001118664 0.593485970602017 0
+4131 8.385505531098968 0.9060152083367401 0
+4132 1.14017647633498 0.5272508742589356 0
+4133 0.09918486598934734 0.5770518452177988 0
+4134 0.1192913712158157 0.6242282968915259 0
+4135 9.885296133602434 0.3758195616465922 0
+4136 9.901324856768191 0.4229534723975177 0
+4137 5.155522320282594 0.3104971542644477 0
+4138 6.805900561208914 0.3110124961015691 0
+4139 5.705403131654451 0.3111324162307717 0
+4140 1.556849802249449 0.6937417977733128 0
+4141 4.21806338147575 0.1686708357883057 0
+4142 9.223503913498126 0.7406173399800979 0
+4143 0.7849502631291234 0.8255621090529623 0
+4144 4.027194590308808 0.6360696742986491 0
+4145 2.067661893203069 0.7342694747518865 0
+4146 7.732338106793522 0.2657305252484237 0
+4147 4.024999999991006 0.03217571836666079 0
+4148 0.141795419012303 0.4174270332886886 0
+4149 9.858269938846796 0.5823496578672757 0
+4150 0.476013069157079 0.8602703735583089 0
+4151 4.813866234338239 0.8243693830310036 0
+4152 3.859514042807341 0.4658570117364841 0
+4153 9.587348987260297 0.6136612649364469 0
+4154 5.052224393273968 0.6859508889071128 0
+4155 0.3892299529433321 0.4543446043421427 0
+4156 7.436154328698816 0.637267707671815 0
+4157 8.867234717338933 0.2181889424144784 0
+4158 3.938673082117077 0.4367499149481342 0
+4159 3.540393731415517 0.7439273564791908 0
+4160 0.7230221342416456 0.2517711039616689 0
+4161 3.762963950742875 0.7285571403446013 0
+4162 0.4412819511493588 0.09607155606382975 0
+4163 2.48751305494826 0.7274905744313371 0
+4164 3.818842866527204 0.6816320632641442 0
+4165 2.526419736876519 0.2089860330537354 0
+4166 5.870729255786976 0.480045250427751 0
+4167 4.379130253845632 0.4952786658575385 0
+4168 1.426149583682777 0.8318588834218802 0
+4169 8.644841799735088 0.9598123751843509 0
+4170 8.349464446300541 0.3474055844279028 0
+4171 3.724011368485862 0.2148477197190969 0
+4172 0.8449387428364126 0.6113218474754095 0
+4173 8.873695456642936 0.7793932093998114 0
+4174 9.786926233654777 0.1786023673948282 0
+4175 9.7869262336548 0.821397632605176 0
+4176 0.7068784276144698 0.3247628946944121 0
+4177 0.5408930794517006 0.1955733092132688 0
+4178 4.977397593353549 0.966578080682295 0
+4179 1.426155859472806 0.9106120431241863 0
+4180 7.376719128325566 0.3266556521765546 0
+4181 2.44236798882821 0.6021846266927878 0
+4182 7.923629019981168 0.03693872302724831 0
+4183 3.576370980014048 0.9630612769724104 0
+4184 1.121633242364453 0.4897732776603316 0
+4185 3.75789470868304 0.9105639724200015 0
+4186 9.522501995121834 0.6650000069852061 0
+4187 5.981155359514108 0.3166855448573048 0
+4188 8.909591089561117 0.3528365265718817 0
+4189 5.375328465620869 0.2655563818871253 0
+4190 5.92532846562083 0.2655563818870466 0
+4191 4.828754218175031 0.3651725790015046 0
+4192 6.573147277788403 0.4097078349451367 0
+4193 0.4626617246077068 0.5958676144336459 0
+4194 8.915680696853954 0.9093902566971044 0
+4195 8.589542046060096 0.4544685758503373 0
+4196 7.778671381975743 0.3716293781425992 0
+4197 2.021328618021229 0.6283706218576656 0
+4198 2.05774239221597 0.9103281221564508 0
+4199 7.742257607780885 0.08967187784372189 0
+4200 9.106399697982958 0.4821268361396859 0
+4201 3.418703936851386 0.03377063747337782 0
+4202 3.948532947014415 0.8602699820263018 0
+4203 4.799654249109634 0.7837503544652353 0
+4204 4.624543477030353 0.6406262492734616 0
+4205 4.009030201278423 0.2497001603436634 0
+4206 4.733737747758727 0.5613611635798804 0
+4207 1.496848668910662 0.2656237059117525 0
+4208 1.364948574053843 0.9625988171973334 0
+4209 8.483804212729206 0.8337689763153605 0
+4210 5.527586280868172 0.2320042055452629 0
+4211 6.070492863723411 0.2263065228966065 0
+4212 3.179371451951367 0.7823961634393873 0
+4213 7.989224316276349 0.9634140052598311 0
+4214 7.060775683723668 0.9634140052598563 0
+4215 2.739224316271145 0.03658599474002451 0
+4216 2.628255801180464 0.3880341189631138 0
+4217 7.425807557341711 0.136407569741284 0
+4218 9.103645177634506 0.2476488446627486 0
+4219 0.2058679177077519 0.5422733048477373 0
+4220 0.2572287767182596 0.502104263486552 0
+4221 9.794132082292304 0.4577266951522698 0
+4222 9.742769269104942 0.4979062369846107 0
+4223 3.39996706794259 0.9597762239407355 0
+4224 8.100032932053816 0.04022377605878243 0
+4225 4.121985550294348 0.6036394292827897 0
+4226 6.327648519565967 0.2442843674528532 0
+4227 8.574792692562621 0.212518767347683 0
+4228 9.879551769224882 0.6588461105414828 0
+4229 6.474840851241912 0.7344491887376791 0
+4230 1.406136095524472 0.3282577692498772 0
+4231 1.492492328515952 0.03947964131748239 0
+4232 7.033956897086374 0.4820233345274726 0
+4233 2.675921629389342 0.4848176921598201 0
+4234 5.624562387537977 0.6346564984350179 0
+4235 6.071051239208503 0.6563851899381585 0
+4236 9.723083293458734 0.666999589210832 0
+4237 2.880061715854276 0.4075482585539688 0
+4238 0.7709437137094017 0.4547048986666629 0
+4239 3.176939044479549 0.8963402218076949 0
+4240 9.105135002624097 0.8679872754629999 0
+4241 3.439559141057555 0.1842941601384806 0
+4242 7.680445150038704 0.5973507877315185 0
+4243 7.703705297769288 0.5610618546719649 0
+4244 2.119000455078312 0.4027109553823711 0
+4245 2.096201744312427 0.4389539500618482 0
+4246 7.368089607701959 0.5985852249789212 0
+4247 1.303335237991227 0.7803938036546855 0
+4248 6.275883231466366 0.6984547226656975 0
+4249 0.09904008949202993 0.3018692342913099 0
+4250 9.420217354298558 0.78377684200912 0
+4251 0.5607299257157322 0.9613463354234749 0
+4252 8.351687830992185 0.5335144306779881 0
+4253 2.183193231621231 0.8638522044117972 0
+4254 0.324999999999751 0.03136772190188118 0
+4255 0.1792366609958639 0.9642688466670835 0
+4256 6.971504739232548 0.3994608697306014 0
+4257 3.383228171145774 0.2355959995528591 0
+4258 3.374115368267249 0.8049495135945427 0
+4259 6.347169688080493 0.1982823869380216 0
+4260 8.948948051504637 0.787878558390011 0
+4261 8.216897088991288 0.2520372018173213 0
+4262 0.9935613979617169 0.5295215956173028 0
+4263 8.123088199043313 0.1804202092279442 0
+4264 0.04080054103309298 0.9164777517460928 0
+4265 9.960373509926981 0.09437016143752659 0
+4266 9.960373509927107 0.905629838562487 0
+4267 0.04024229001190354 0.08393078278537731 0
+4268 8.281415029160623 0.6487206151985591 0
+4269 1.948749984255971 0.6955070614488016 0
+4270 7.854623696281606 0.3075033018890936 0
+4271 7.192533170569452 0.3096409562848251 0
+4272 9.19743794663548 0.4774301111467554 0
+4273 1.698986650316362 0.8575700589432647 0
+4274 6.95046672580503 0.1426095601547935 0
+4275 4.524999999991679 0.03119862571865157 0
+4276 5.315409147275983 0.8945305327782913 0
+4277 2.378008255802926 0.4648184023757018 0
+4278 5.095780612774452 0.8193324357447629 0
+4279 1.573477238633641 0.9627204105674905 0
+4280 1.741933649429733 0.2437001895540772 0
+4281 4.207044294276994 0.8018414654755288 0
+4282 7.263319710514273 0.3714367755956672 0
+4283 0.4082497328404397 0.1711629005249196 0
+4284 3.426310594632484 0.7606231053127047 0
+4285 4.946819147706266 0.9094534104304434 0
+4286 2.738586337799757 0.1802807961666834 0
+4287 9.478755806279038 0.7188389210635118 0
+4288 5.205152276890685 0.09568776322826629 0
+4289 5.262689840779396 0.5925331044691281 0
+4290 2.474934351239252 0.5013117905925972 0
+4291 9.381798584465347 0.8389094752629079 0
+4292 5.743102554702866 0.6510747932962445 0
+4293 2.739992922346921 0.9636771211512144 0
+4294 7.060007077648357 0.03632287884883908 0
+4295 1.810007077650904 0.9636771211512115 0
+4296 6.478171652809523 0.2600726597983131 0
+4297 8.728313132181935 0.2604007046889502 0
+4298 4.278692164210314 0.4658627244188239 0
+4299 4.895458065769886 0.9604006718671129 0
+4300 0.6674964430209281 0.8732813514233054 0
+4301 4.325308084320724 0.3944744269403434 0
+4302 5.023227710062743 0.09206311613881771 0
+4303 7.810439389401798 0.8272768018663486 0
+4304 1.989579847473595 0.1727143539874182 0
+4305 8.646498199382403 0.8998507864892014 0
+4306 3.224751508129439 0.7918349810655403 0
+4307 3.720945101740456 0.7847349373055752 0
+4308 3.546168341484293 0.09678498019432703 0
+4309 9.37932812237737 0.1511806595317595 0
+4310 1.719408783160828 0.599377368732426 0
+4311 8.662322790907844 0.7149259528395834 0
+4312 4.86856776975434 0.3862103797272904 0
+4313 9.238726110282407 0.09533742814680195 0
+4314 0.4570255785606565 0.7237148817465356 0
+4315 1.553611186704541 0.3075725348080885 0
+4316 0.8259578557808408 0.8855817580673561 0
+4317 9.410064772939611 0.9111726864550329 0
+4318 8.995491170854484 0.4427360134200862 0
+4319 0.4826482812043845 0.3976015591030442 0
+4320 7.491419587087939 0.7516070883487733 0
+4321 2.308580412907921 0.2483929116509195 0
+4322 9.487149822079253 0.5390047451257631 0
+4323 3.640060434422739 0.2232950101571509 0
+4324 8.364341896424332 0.7802092351539057 0
+4325 5.58565810357584 0.7802092351539645 0
+4326 1.094086185266955 0.09623759009721543 0
+4327 1.495196866332983 0.08259619697928042 0
+4328 3.549522284694204 0.9046062294815057 0
+4329 9.224901980912941 0.7047038199432027 0
+4330 1.041095735182141 0.1428707915463651 0
+4331 5.557198162377597 0.6422659154457877 0
+4332 4.190737661588275 0.08819547956150398 0
+4333 5.635862926650317 0.08322645423524078 0
+4334 6.185989071276484 0.08328356339549971 0
+4335 6.186403591360289 0.9176470288566819 0
+4336 5.635901381579604 0.9164093682418819 0
+4337 8.436283088914839 0.08328324743990395 0
+4338 4.675434305197486 0.8976013936109579 0
+4339 9.79226869896285 0.6380159140210798 0
+4340 0.2096644698069 0.3645360338248393 0
+4341 6.537590488178393 0.3095233675862113 0
+4342 2.741739055824723 0.8204065582626715 0
+4343 8.322964619358059 0.1031248917946364 0
+4344 5.433109062743562 0.3150286992934795 0
+4345 4.082314858675434 0.818966572102249 0
+4346 3.690342561451731 0.7482934914442023 0
+4347 7.773074656064463 0.03304637774145168 0
+4348 5.063300414565626 0.4858024399525396 0
+4349 4.6412182046297 0.7171260086095829 0
+4350 9.90903808959691 0.1434749405978315 0
+4351 9.909038089597002 0.8565250594021534 0
+4352 8.014204865666015 0.7371662436124858 0
+4353 7.030759825136119 0.7380145573098015 0
+4354 4.7181445485972 0.1860778481459111 0
+4355 6.621172656107508 0.2261550466096225 0
+4356 8.320150900892246 0.2147584873761778 0
+4357 4.087142381068748 0.9630926930691732 0
+4358 7.615236834168281 0.1246073491115472 0
+4359 3.069458820662336 0.3598501276852781 0
+4360 7.310287663184358 0.08593597183667229 0
+4361 2.489715444136505 0.9140574306581283 0
+4362 4.946745244053229 0.629980734738483 0
+4363 7.863447959625138 0.1592627815790437 0
+4364 2.372409796743391 0.3606443955636837 0
+4365 6.725815307783773 0.6326430317168968 0
+4366 2.370081408377515 0.8665593840999278 0
+4367 1.175 0.9694842362779486 0
+4368 1.191528742577202 0.4702245914628816 0
+4369 8.768128948761126 0.7464184224830251 0
+4370 5.498324813713054 0.425140040882954 0
+4371 4.636198724015117 0.5738307317161528 0
+4372 2.665343265369192 0.1818835963044386 0
+4373 3.783345090083521 0.6508318458817043 0
+4374 7.358363240606936 0.3997853203268033 0
+4375 9.347092689784798 0.3068455531880676 0
+4376 2.530485614176043 0.7837947747942785 0
+4377 3.339680346729659 0.2438727199444359 0
+4378 9.183156512939826 0.1420129452632182 0
+4379 4.193184811846796 0.04042580629884213 0
+4380 5.723634372193923 0.9669383625099408 0
+4381 6.27358694307276 0.9669998302065601 0
+4382 8.52363272413025 0.03287299369896744 0
+4383 6.273632724127998 0.03287299369853779 0
+4384 5.723599313856673 0.03304831699812701 0
+4385 2.360923434192175 0.4279773611074633 0
+4386 4.26844918825812 0.9569635728991509 0
+4387 4.693595111396395 0.2546509991644416 0
+4388 8.393350555515594 0.6420534920759911 0
+4389 7.873817135950083 0.5545031063138475 0
+4390 1.926137090147412 0.4454701494220681 0
+4391 7.915748147665361 0.2054602088435709 0
+4392 2.893474877277791 0.8697902999764303 0
+4393 5.230975004634633 0.7145442964904017 0
+4394 2.65656718698249 0.4509374919466982 0
+4395 4.969488458896993 0.03407561745557967 0
+4396 8.419278574940197 0.4053480225392083 0
+4397 5.88134108381112 0.7015166629859771 0
+4398 4.812140854499652 0.551373843931084 0
+4399 7.405381136412483 0.4039700679935415 0
+4400 0.09320199164883382 0.2202354510313257 0
+4401 2.319991633065134 0.7761019068024212 0
+4402 1.812435988610441 0.03537495113106858 0
+4403 3.886859979793223 0.1278313359090044 0
+4404 2.430726269637462 0.8993453016961271 0
+4405 7.369273730358293 0.1006546983041915 0
+4406 4.17301594356827 0.4989393437828759 0
+4407 5.304793358023383 0.7581225518338773 0
+4408 7.205219771387045 0.8286767125489881 0
+4409 9.213237940691817 0.8614359726768465 0
+4410 8.066756325431754 0.2314565263465316 0
+4411 9.621392032536024 0.1262417678807015 0
+4412 9.372473584969079 0.767586377672426 0
+4413 6.840029357643609 0.5276882836609891 0
+4414 3.369511120520384 0.6418610765399758 0
+4415 8.394604813923049 0.2127246430532111 0
+4416 4.428247018097196 0.03709978024253623 0
+4417 1.651199114879631 0.6334989691284263 0
+4418 5.25393143725403 0.3565612884561059 0
+4419 6.901199114881417 0.3665010308719169 0
+4420 5.803807618602684 0.3568105919907872 0
+4421 3.49859096900298 0.4260696274956258 0
+4422 3.758840968619316 0.1394776460544621 0
+4423 2.186348548207656 0.7342425567732627 0
+4424 7.613651451788912 0.2657574432269128 0
+4425 8.136995496744774 0.7590189965543852 0
+4426 6.917511985626524 0.7556347387549243 0
+4427 8.24897433739142 0.545340089847048 0
+4428 2.985594388853861 0.6976697389101204 0
+4429 8.516609123336607 0.3007520039203953 0
+4430 6.264052700573967 0.3020271776726223 0
+4431 0.3666424952831575 0.2514965478358874 0
+4432 6.906377790890651 0.8698718310084007 0
+4433 8.14385903648242 0.8692403064358378 0
+4434 3.725717242303368 0.9671406367419036 0
+4435 9.555541609327772 0.3656368547420082 0
+4436 5.773364397901338 0.5845413627484848 0
+4437 6.876582284702973 0.5896907716662234 0
+4438 1.785542190911448 0.2676651171174699 0
+4439 2.612387268133026 0.8412335467645283 0
+4440 2.991922773574025 0.4448277756381793 0
+4441 6.273570772649511 0.5541157437776647 0
+4442 2.574941308529202 0.7526657808881168 0
+4443 4.360261236084621 0.2685922584387401 0
+4444 7.916658648053739 0.8243465203897329 0
+4445 7.133467334136943 0.823900592397529 0
+4446 7.428762229760181 0.2107553205098624 0
+4447 6.96861654877454 0.3630581861373807 0
+4448 9.05757439762554 0.555366559648782 0
+4449 3.15680752018369 0.5226760411957564 0
+4450 6.075808498682976 0.4656057299947098 0
+4451 3.407940891380705 0.8931548899802901 0
+4452 8.092059108613789 0.1068451100197916 0
+4453 9.456387666089118 0.08634093818404849 0
+4454 5.935239665931966 0.9638506847270144 0
+4455 6.48523966593208 0.963850684726981 0
+4456 8.735239665931891 0.03614931527341586 0
+4457 6.48523966593192 0.03614931527429419 0
+4458 5.935239665931915 0.03614931527449867 0
+4459 5.385239665931932 0.03614931527470508 0
+4460 9.329802225603268 0.1915048901192387 0
+4461 1.156508785646462 0.59690694003232 0
+4462 6.078862795926028 0.2923632171860449 0
+4463 8.781865507957541 0.9077633248945841 0
+4464 8.517563295432867 0.9082841660003318 0
+4465 2.997948056794363 0.1009517931624391 0
+4466 1.290674676365454 0.4314682973517099 0
+4467 6.627645536255914 0.708155533869222 0
+4468 8.154130304029282 0.2505003777004029 0
+4469 2.568585382721985 0.3452981525059062 0
+4470 7.35999573586773 0.6685223753839729 0
+4471 9.59369404464181 0.9096422368845289 0
+4472 7.808233260733751 0.5802457266821865 0
+4473 7.825838945377719 0.5396003094770188 0
+4474 1.991766739263717 0.4197542733184847 0
+4475 1.974096076738404 0.4603857798143752 0
+4476 0.7949698720751388 0.9092415739859184 0
+4477 8.153042643275921 0.210394482445011 0
+4478 7.095624997649356 0.7079963982939794 0
+4479 8.590552638395586 0.751134898619731 0
+4480 9.335072582452959 0.5440865174884842 0
+4481 6.699011791768909 0.213720963438839 0
+4482 1.718149825366003 0.636675340453795 0
+4483 9.454657169844324 0.03867412701428415 0
+4484 3.284855071197948 0.7476439717763859 0
+4485 0.03070975758306403 0.4760446379442356 0
+4486 9.969290242416577 0.5239553620558401 0
+4487 8.275172886087349 0.2060010944693672 0
+4488 1.098106911443701 0.8790640941995399 0
+4489 2.12348896124342 0.6883737709709171 0
+4490 7.676511038753221 0.3116262290294152 0
+4491 4.011417533755373 0.6828330259134507 0
+4492 7.344210568114509 0.359361382785393 0
+4493 1.61046673880336 0.4170393738543775 0
+4494 6.790527124074813 0.9099422930801226 0
+4495 8.25965442841966 0.9098930216773186 0
+4496 1.599830878299655 0.3235750393009389 0
+4497 4.584237341576301 0.4810858582903354 0
+4498 3.498148530395547 0.4616124043676585 0
+4499 5.565936059627955 0.8280197952130552 0
+4500 8.384404657386884 0.8277022108914124 0
+4501 2.636491188794103 0.09894672319319436 0
+4502 3.912965518785708 0.3678570732989478 0
+4503 4.975423215310199 0.2905280562056295 0
+4504 1.647601428262437 0.4047247170630987 0
+4505 2.39497881478746 0.5457162351344814 0
+4506 7.405025918100096 0.4545320129636035 0
+4507 8.219714409281314 0.3115837204238375 0
+4508 7.781168521805046 0.213518050359066 0
+4509 2.021898062995124 0.7840596637115895 0
+4510 4.317862024804139 0.6633648668515766 0
+4511 8.698181068125612 0.7896973531166812 0
+4512 4.598668121662858 0.1355025216379432 0
+4513 6.305734499278326 0.09142369198006206 0
+4514 8.555734499278232 0.0914236919802056 0
+4515 3.105397763972603 0.7126105751756832 0
+4516 6.144605096325699 0.2874956231998841 0
+4517 7.190915497574788 0.7843340547919929 0
+4518 2.165290282854608 0.4662877208084164 0
+4519 7.63470971714204 0.5337122791912315 0
+4520 9.574999999999967 0.9702986212887561 0
+4521 2.162764579087882 0.3285482588627096 0
+4522 7.63768015291105 0.6724893259148186 0
+4523 3.72914449633079 0.03335317882990878 0
+4524 2.844139490148665 0.7151852525302652 0
+4525 8.980219615482499 0.640184699056998 0
+4526 1.928531216968152 0.9676830216674186 0
+4527 7.178531216966367 0.03231697833328043 0
+4528 2.621468783028953 0.9676830216666146 0
+4529 2.935592935531003 0.09302459260388306 0
+4530 5.727191860775208 0.8314421695306813 0
+4531 4.577597679052263 0.9677261392437785 0
+4532 6.79009073793353 0.09008632975823241 0
+4533 3.006475633932237 0.9120353540091182 0
+4534 7.30293004473866 0.631437514730111 0
+4535 7.748934121356792 0.6278541252391481 0
+4536 2.050733422716831 0.3721991857874202 0
+4537 9.102459439926212 0.7463237155478389 0
+4538 7.016809913632122 0.4098886867845516 0
+4539 2.490143612584509 0.08729662264050551 0
+4540 7.309856387410997 0.9127033773594206 0
+4541 5.972381333303139 0.9070518766054807 0
+4542 6.52238133330321 0.9070518766055197 0
+4543 8.77238133330296 0.09294812339464514 0
+4544 6.517414931597628 0.09270935418287056 0
+4545 5.967441335230811 0.09271793660185167 0
+4546 5.417441335230708 0.09271793660192945 0
+4547 9.27646441210122 0.5817178881431508 0
+4548 5.402066158345419 0.5772194520135892 0
+4549 3.30620731069189 0.4181270002090086 0
+4550 4.988318115391157 0.1649069884055683 0
+4551 5.040231069862649 0.2143391333784675 0
+4552 8.979764429852809 0.1089092513235091 0
+4553 0.6462023987151299 0.5910733219750329 0
+4554 6.266290523981967 0.7884320341223919 0
+4555 0.472734738157216 0.6677192171623939 0
+4556 0.2802974215704486 0.9666732333621323 0
+4557 8.82552041738537 0.7929316298779527 0
+4558 8.208109838066898 0.5332953071947609 0
+4559 3.55367537736501 0.6682334198171974 0
+4560 2.696324622623375 0.6682334198169275 0
+4561 8.275404792442517 0.5103586725420544 0
+4562 2.539628586525028 0.5164974914738411 0
+4563 0.2782985055978466 0.7797101044326621 0
+4564 3.026790323663482 0.3446570575238374 0
+4565 6.222779028071999 0.6537339020518504 0
+4566 5.092593678561638 0.0860862285176382 0
+4567 1.008088973371661 0.9621991348316041 0
+4568 3.141122144215832 0.3580729121528389 0
+4569 5.346663832796224 0.08657879810440305 0
+4570 5.896632620398935 0.08664498237360059 0
+4571 6.44624249467223 0.08731290928112001 0
+4572 8.696242494672134 0.08731290928095918 0
+4573 6.446601756505689 0.9133698309651296 0
+4574 5.896632620398912 0.9133550176266667 0
+4575 3.163213990608513 0.1684027215159166 0
+4576 6.086786009385063 0.831597278483973 0
+4577 4.134371391270817 0.3315764958126591 0
+4578 2.327650203648355 0.6427543311850927 0
+4579 7.494741611456416 0.3479353504027271 0
+4580 1.792089155887312 0.4236092036353283 0
+4581 8.009052598725329 0.57775287931379 0
+4582 0.2783156005206999 0.149692896167419 0
+4583 0.489838119500794 0.03784028393517283 0
+4584 2.744276916951801 0.419034061076362 0
+4585 9.023099718949522 0.6554283153113771 0
+4586 8.882880535609765 0.1693186381938698 0
+4587 1.04183970874296 0.5821885150157213 0
+4588 4.502187521427171 0.8304483295054067 0
+4589 0.2802620919270863 0.3333596127301509 0
+4590 1.072950382393189 0.299608783486618 0
+4591 2.618195235948723 0.03211919837016509 0
+4592 7.870134038519098 0.9670565395776548 0
+4593 7.179865961480934 0.9670565395775979 0
+4594 6.48211176649658 0.5386061559097828 0
+4595 4.209783259407885 0.575439606767608 0
+4596 7.437211795037771 0.5712020072056756 0
+4597 3.793471808351845 0.4506062389589425 0
+4598 4.354095633598973 0.5985037430707268 0
+4599 8.961163206790411 0.03588292098286516 0
+4600 6.679468278415101 0.5805420178593352 0
+4601 2.596399307833548 0.1699303956550818 0
+4602 5.219891586155738 0.2480839466957429 0
+4603 4.159008320759606 0.7972015456021717 0
+4604 5.318238386783921 0.9660397355309172 0
+4605 9.168804289957446 0.9681467116262084 0
+4606 5.952525197751252 0.5787196413980998 0
+4607 5.595298107254239 0.2127873773747329 0
+4608 5.144789912533086 0.9618608489576327 0
+4609 8.187925246058393 0.9090306055224793 0
+4610 6.862141829559154 0.9090522710038591 0
+4611 4.070611610200589 0.3603380969145951 0
+4612 6.625346643802235 0.8961114423533881 0
+4613 5.548653335827842 0.5280385940728431 0
+4614 1.41809490673388 0.1544098297675123 0
+4615 3.653510516108923 0.1760745672230765 0
+4616 2.886076717571417 0.1315212775962274 0
+4617 4.544910658399217 0.5355058648413884 0
+4618 0.5776300558401165 0.266798031269687 0
+4619 2.937798341322319 0.9091380126309919 0
+4620 8.424431365224377 0.8995975016352756 0
+4621 5.97938490717351 0.7571688559483079 0
+4622 3.929211028297352 0.5823963460143472 0
+4623 9.714300860249462 0.7829610025188615 0
+4624 0.6751296811975048 0.5179063146873409 0
+4625 7.270433910645093 0.2135364993137914 0
+4626 3.651465266252381 0.8304988957043907 0
+4627 3.852767912572685 0.6636587069870564 0
+4628 0.9892891329392081 0.3726917633483923 0
+4629 8.73052067701366 0.5879903296658909 0
+4630 3.499309439039329 0.7993219221267227 0
+4631 8.322666212932011 0.6434531932903896 0
+4632 0.9262226420366602 0.2076374489286911 0
+4633 6.618300711926569 0.784448171576917 0
+4634 8.989622847245574 0.914761012062938 0
+4635 1.046672454315077 0.7564700817025697 0
+4636 4.247801869914196 0.09648920020195283 0
+4637 0.9737583180880501 0.7304544836554153 0
+4638 2.931784983218653 0.7549107085778856 0
+4639 4.885784705751955 0.3131877350420483 0
+4640 3.27958619850123 0.9013234789493278 0
+4641 8.221104619353104 0.09970319228051583 0
+4642 1.930579481166537 0.03304734755580462 0
+4643 0.6163913165767655 0.1656281105896338 0
+4644 2.363934591197315 0.7884556035973871 0
+4645 2.66034487551296 0.7980434178845798 0
+4646 1.628296368672435 0.7090747710555703 0
+4647 3.434504944787467 0.9661483563059657 0
+4648 8.057722294664416 0.03752005324445143 0
+4649 0.4408671018949242 0.2841362053848119 0
+4650 8.09412066687406 0.2888047011581109 0
+4651 1.884341416310865 0.8078635268539091 0
+4652 1.464368965605743 0.5205520418876128 0
+4653 8.841504810041318 0.6115097686254791 0
+4654 3.479355865031609 0.5421300439151947 0
+4655 2.765362501036423 0.5378658241389983 0
+4656 9.277234091503821 0.9071292579236593 0
+4657 9.408797919175759 0.09090628625307756 0
+4658 1.499932551811656 0.9198582452446327 0
+4659 0.8908785316196739 0.2027842185062196 0
+4660 1.038105569050168 0.3230588727159788 0
+4661 3.178753407258582 0.2104526578319794 0
+4662 6.065815796792437 0.7885495458880953 0
+4663 4.736475548178325 0.4453100704882725 0
+4664 4.725954891581568 0.4856051508813508 0
+4665 4.773401885050581 0.2265958402203138 0
+4666 7.1342731104475 0.1920736910613121 0
+4667 3.266063414296298 0.09738330531964438 0
+4668 3.997287594855325 0.2123243229880583 0
+4669 1.38780432551981 0.7633094227384583 0
+4670 9.672907076636669 0.3278155196591501 0
+4671 2.503804506501164 0.5707824532927305 0
+4672 6.250984496589187 0.8995332134917101 0
+4673 4.533076413516896 0.1646932681149279 0
+4674 0.7483475542643585 0.1473334478635089 0
+4675 0.5546287891155716 0.1447191828171498 0
+4676 5.813852191671516 0.3121722290428983 0
+4677 5.263845378304795 0.3121270364763454 0
+4678 1.24144000501482 0.8037394952480331 0
+4679 8.598631391951809 0.1562403813352169 0
+4680 6.348484732785049 0.1555172714059048 0
+4681 3.88642894524551 0.2164647117345778 0
+4682 8.557754194130338 0.8075861732075227 0
+4683 6.93132350998246 0.4238572685932491 0
+4684 5.831323509982429 0.4238572685932014 0
+4685 7.957562260145859 0.463509710728049 0
+4686 0.2167337423020433 0.8226768412851629 0
+4687 0.8372037558513383 0.4122611465918414 0
+4688 5.354856659582561 0.7493512913964567 0
+4689 4.774999999992039 0.0288093295397496 0
+4690 5.174999999992686 0.02879748606630752 0
+4691 8.004628903067623 0.4102019461280034 0
+4692 8.861195676785286 0.5604915328489281 0
+4693 0.9663405321271765 0.08029084987417728 0
+4694 8.627331933913347 0.3997074835843868 0
+4695 6.378199254836234 0.3994425566730391 0
+4696 3.363878251142379 0.8469690878274528 0
+4697 4.402693689902061 0.2382141464996532 0
+4698 4.544098331382854 0.6516958792520338 0
+4699 7.150668473712047 0.7278486151973413 0
+4700 5.746920234367825 0.7221613483517746 0
+4701 3.704994716174747 0.3261900001041503 0
+4702 4.756563081871858 0.6154449385394588 0
+4703 7.499495110550095 0.8592766198266494 0
+4704 2.298761521785058 0.1407939055940625 0
+4705 6.673365689480922 0.5380170697462064 0
+4706 8.188074518667284 0.4542294187173647 0
+4707 8.668552886376801 0.4239421273835667 0
+4708 5.700556575153421 0.09991825877085074 0
+4709 6.250556575153456 0.09991825877105809 0
+4710 8.500556575153269 0.09991825877161872 0
+4711 5.703335976647563 0.8976402328862877 0
+4712 4.980113166382174 0.8895520345376181 0
+4713 3.174999999993406 0.02863881605626397 0
+4714 8.940761470120151 0.21832621345652 0
+4715 4.176162917519719 0.2255514852582524 0
+4716 8.885472126978556 0.8280918749709323 0
+4717 2.332017992327566 0.1597609838033161 0
+4718 7.467586146163222 0.8402223692558457 0
+4719 9.461165151342938 0.9655847841894823 0
+4720 8.321877221490061 0.4584643926243682 0
+4721 9.965451434069927 0.6362486755325886 0
+4722 0.03430946327943528 0.3634427765078396 0
+4723 3.306922342561893 0.8094894960542566 0
+4724 0.6464975678512328 0.2338590568715825 0
+4725 8.033172058643867 0.8456483254523319 0
+4726 7.02227581344294 0.8449179063569735 0
+4727 5.642893149330019 0.5656421209344266 0
+4728 1.599587750104838 0.4622643047858874 0
+4729 3.175000000000002 0.9714438297041086 0
+4730 8.324999999997369 0.02855617029506825 0
+4731 0.5583830192387368 0.9124958616512584 0
+4732 6.313948114394251 0.8645498786726695 0
+4733 5.524999999993207 0.02851364273337658 0
+4734 6.074999999993992 0.02851364273333118 0
+4735 6.624999999994843 0.02851364273319832 0
+4736 8.874999999998312 0.02851364273284639 0
+4737 6.624999999999968 0.9714863572673312 0
+4738 5.524999999999967 0.9714863572673063 0
+4739 6.074999999999967 0.9714863572673035 0
+4740 5.520047437049815 0.1519037310090224 0
+4741 6.070804172849629 0.1523540029543259 0
+4742 4.987114510478222 0.7757390444094683 0
+4743 1.601515533351546 0.1425800754715243 0
+4744 8.422696147181851 0.5774830559175358 0
+4745 1.615516084717585 0.209703691087375 0
+4746 0.9732253524783864 0.1544044259727771 0
+4747 3.263902214057216 0.5532796923403251 0
+4748 8.187465975947958 0.1892383534192961 0
+4749 8.679001363302245 0.9677149451244748 0
+4750 0.1884825109549131 0.8601758493177869 0
+4751 0.5241213662709872 0.97086366682549 0
+4752 8.575510570519786 0.2483323563583834 0
+4753 1.441160549653699 0.2031397354186789 0
+4754 2.86547087444458 0.5965449688757724 0
+4755 2.292143934039289 0.2159260568455678 0
+4756 7.506869057361133 0.7860971123853208 0
+4757 1.814477979901929 0.7161457473881838 0
+4758 7.064356463576396 0.2837754106139458 0
+4759 8.367833384429048 0.4616788237326702 0
+4760 1.327781295791846 0.233299464639499 0
+4761 3.508636073219232 0.1998549190583453 0
+4762 1.681928765229657 0.5764886214860216 0
+4763 5.283017055722167 0.4240318461222944 0
+4764 4.172202219666527 0.1601284374392414 0
+4765 9.295011218956576 0.5399303061607181 0
+4766 5.770725959994325 0.2483482148314035 0
+4767 3.754423609464987 0.8636119957635707 0
+4768 7.745634467499481 0.1363603955158646 0
+4769 2.054276691136359 0.863721733523334 0
+4770 9.051675882329119 0.9026953211453798 0
+4771 8.408060471979418 0.4820647624797645 0
+4772 3.710144621264028 0.5182668739694474 0
+4773 3.053445876659788 0.5498850733553666 0
+4774 6.196866327158991 0.4507549134007098 0
+4775 3.439261657630476 0.4120581008125857 0
+4776 2.797283166390321 0.4057062246627675 0
+4777 9.595725822949396 0.2964003446385589 0
+4778 6.173505959025446 0.3783661809363799 0
+4779 3.076494040968539 0.621633819062141 0
+4780 3.99251259415325 0.7978352522422422 0
+4781 8.237206859844715 0.4701780656855637 0
+4782 6.418297299197308 0.4228218474603036 0
+4783 8.117465323667302 0.4248261107232808 0
+4784 5.761946808481472 0.1347603874961363 0
+4785 5.764197064718194 0.8642917376777449 0
+4786 1.768301211806515 0.1536842036714396 0
+4787 1.160546916821807 0.03423429141397211 0
+4788 4.192432177309091 0.3774124474225381 0
+4789 4.620707009986418 0.2746995646554165 0
+4790 4.043381969795847 0.7031165702988964 0
+4791 9.030448495512571 0.03020099185268332 0
+4792 9.571191383422923 0.7634527025776799 0
+4793 3.757621248608181 0.5724071481292562 0
+4794 8.388438572163302 0.2819668043695996 0
+4795 6.133314698126712 0.4166542142621859 0
+4796 3.122732085953416 0.5799494562557724 0
+4797 0.08929840225767749 0.1406329937021185 0
+4798 3.511948465950695 0.03566382538673057 0
+4799 9.23514518293493 0.3122380870012746 0
+4800 5.173255287203451 0.7512347561483046 0
+4801 9.27454892736025 0.2980669710272659 0
+4802 5.046992261657121 0.552519897178389 0
+4803 1.449824983164266 0.09419444612219802 0
+4804 0.1427519598241574 0.461869599026722 0
+4805 9.857255302160134 0.5381055888794382 0
+4806 2.810074396539616 0.2184861737804255 0
+4807 7.237002393684364 0.631735293318657 0
+4808 3.442246503622007 0.5854074691194225 0
+4809 2.828210376486624 0.5815943785957696 0
+4810 2.707477994984803 0.8491448400042867 0
+4811 5.213030033942542 0.5775880832481324 0
+4812 2.540477089015814 0.6266983470411933 0
+4813 8.437586878753349 0.9645465596495313 0
+4814 8.567541092194457 0.4810095427889698 0
+4815 4.082586246206369 0.5880610284685198 0
+4816 4.776073833442021 0.9062023099402392 0
+4817 3.819888054505511 0.1687541073359482 0
+4818 2.76449717680331 0.1164611687972977 0
+4819 1.846001926750206 0.7661647214870703 0
+4820 7.09559639799049 0.2334588259114011 0
+4821 8.998276902892941 0.2379149466332646 0
+4822 4.150278792781333 0.1937696417120761 0
+4823 4.007914129938789 0.4781174481377758 0
+4824 3.177197021808329 0.09825002029601262 0
+4825 0.1832714887241638 0.4744381813060085 0
+4826 9.816729479540431 0.525558510414749 0
+4827 1.888011580560491 0.7253420268530647 0
+4828 7.137743013398161 0.2767371645637259 0
+4829 0.03156996602696446 0.677962896712469 0
+4830 9.968522384597387 0.321960408942502 0
+4831 4.500391384982297 0.1011854725850241 0
+4832 4.025173117214346 0.1766499701852192 0
+4833 2.238632162536453 0.6792693756703455 0
+4834 7.562129507834347 0.3186383853771753 0
+4835 5.691512132791921 0.1477188399772516 0
+4836 6.241830552831685 0.1485940325084014 0
+4837 8.491872924806307 0.1486722477367677 0
+4838 9.296647126433681 0.1351310749785115 0
+4839 0.6991220794376676 0.2797124768167641 0
+4840 8.657262163381992 0.4625971800369019 0
+4841 7.529904667059107 0.1438078936421813 0
+4842 1.23244940797702 0.6880868744535821 0
+4843 5.190355660177382 0.472681404425762 0
+4844 4.931712391601038 0.8369223644233722 0
+4845 6.208251770703844 0.5242718797868506 0
+4846 3.037279905570581 0.4718892480681094 0
+4847 9.483457694083947 0.8495431723924797 0
+4848 3.690418232891526 0.4628970435002626 0
+4849 4.096796209258533 0.2673929845948125 0
+4850 6.943105453900232 0.4624973055275915 0
+4851 6.833366367773404 0.4779145020755115 0
+4852 6.243836516272882 0.8589404486812037 0
+4853 6.744061648073058 0.564636334186768 0
+4854 5.383577454614832 0.9663895716032932 0
+4855 6.715273311318573 0.5913640099578999 0
+4856 5.836639167423276 0.4629077965531676 0
+4857 4.060006153361555 0.4281986720327202 0
+4858 4.074820198901754 0.4676580378180585 0
+4859 9.300081484645855 0.4694905202407139 0
+4860 8.083722219989605 0.4063400205901584 0
+4861 9.477936536322392 0.5787905845783031 0
+4862 4.914840775912417 0.1575951072211953 0
+4863 3.433591928699865 0.690745155357375 0
+4864 9.193852626215143 0.5287608529438219 0
+4865 1.549125974537621 0.9207087009850922 0
+4866 6.874339674114226 0.2948974837047391 0
+4867 0.749171291954397 0.7451507573381797 0
+4868 9.012426959132492 0.5268348739940107 0
+4869 0.7721994227174589 0.2075590775453731 0
+4870 4.809306332692379 0.8906358830427811 0
+4871 8.703538630523342 0.9095428397223001 0
+4872 1.612372779516919 0.6388391968097398 0
+4873 5.212071839552222 0.3600554278236409 0
+4874 6.862580926393627 0.3606550645942768 0
+4875 5.760645975790541 0.361770504443881 0
+4876 1.648496072028387 0.1518176533795838 0
+4877 5.7535821578814 0.541930692425757 0
+4878 4.147640005108239 0.5739287106003952 0
+4879 4.682469168431144 0.1283969073107132 0
+4880 3.373674119662725 0.4658786590697616 0
+4881 5.328571945684097 0.5438143735751459 0
+4882 9.963066034177999 0.03686566792464895 0
+4883 9.963066034178064 0.9631343320753167 0
+4884 0.03165871623781736 0.9635919960311343 0
+4885 0.03147071381827914 0.03643892566079619 0
+4886 1.378105499221352 0.7063476189036415 0
+4887 1.361771460464886 0.4554612846313676 0
+4888 5.566304770698796 0.4273374247851437 0
+4889 3.009642064972504 0.1387857474333086 0
+4890 8.698328681454033 0.5155298610758491 0
+4891 4.556058093426993 0.07883299525862314 0
+4892 9.418375039013796 0.2814379133147085 0
+4893 9.422611214242352 0.2119894745375899 0
+4894 2.766354238826739 0.8840400421551097 0
+4895 9.536330266652914 0.5409221522860761 0
+4896 0.7699852529796362 0.07654822721820355 0
+4897 6.620660721147272 0.1512063632485465 0
+4898 4.624794307210288 0.0935286749150879 0
+4899 0.4068129148210217 0.6393039404444083 0
+4900 4.385281564644163 0.5423921349582257 0
+4901 4.043412935324118 0.4956328141450798 0
+4902 7.455453950330299 0.5043163841076719 0
+4903 2.344448509387484 0.4957325373701347 0
+4904 0.9270157750131313 0.7711869649262193 0
+4905 6.809509997822771 0.5457133767696628 0
+4906 9.418012148217315 0.03250374890160455 0
+4907 2.242775512711052 0.4675189646341656 0
+4908 7.55655733900447 0.5322253805047429 0
+4909 1.147057858181908 0.376522018847146 0
+4910 6.447819681712516 0.4859646165415705 0
+4911 3.601091271217485 0.7057006468975291 0
+4912 2.651406244127552 0.707766611395918 0
+4913 7.161512518888931 0.9056613368104602 0
+4914 7.856228199146072 0.8944818825860025 0
+4915 1.913358277699443 0.09294017441629188 0
+4916 5.335826937960373 0.463079013920588 0
+4917 6.706869367101418 0.4809620965542865 0
+4918 6.901677286219826 0.5151323312939374 0
+4919 5.83312334642574 0.5286816839733673 0
+4920 5.389535131661986 0.9054288320532333 0
+4921 1.274999999999999 0.9725872689906347 0
+4922 7.349141390204917 0.562695423178993 0
+4923 0.936438409476672 0.8630428280358121 0
+4924 3.539552995139006 0.2305949819564505 0
+4925 9.780981590333562 0.3082836772471135 0
+4926 5.611806520900429 0.5953382079640596 0
+4927 3.166685233212538 0.8285750827781879 0
+4928 5.199757022760909 0.3208120243077531 0
+4929 5.748936611325616 0.3214628133288234 0
+4930 6.849345161268641 0.3221040310891733 0
+4931 1.600323625412281 0.6781133451123342 0
+4932 0.219016564576051 0.6917181183066433 0
+4933 4.174999999999981 0.9726035120911628 0
+4934 0.3441792229821614 0.6183059968888874 0
+4935 3.176765531595396 0.4177085660166982 0
+4936 6.073468684134159 0.5830403409497225 0
+4937 8.977004598169025 0.3613410150046529 0
+4938 2.382280546043566 0.7418072188125513 0
+4939 4.674999999999993 0.972621243386825 0
+4940 9.238910747264431 0.9646228526605166 0
+4941 4.991985205334 0.2344268921548478 0
+4942 6.05798519101533 0.9079068719357836 0
+4943 0.09796345089159246 0.7044552863580082 0
+4944 9.9020365491082 0.2955447136420358 0
+4945 2.254601883389497 0.7464254004264853 0
+4946 7.545026572716722 0.256531390355646 0
+4947 7.986188965134219 0.03941173619485145 0
+4948 3.51099553599507 0.9646125698311201 0
+4949 8.376347489452771 0.4181668583274306 0
+4950 1.994787183345509 0.7568571604682308 0
+4951 7.805839457584861 0.2430450776074641 0
+4952 0.5081032712265571 0.905129134543542 0
+4953 8.875000000000044 0.9726637276538228 0
+4954 2.305629565836286 0.4758813180725373 0
+4955 7.491793814475457 0.52418596451371 0
+4956 0.6940825407783742 0.4813296988549045 0
+4957 3.650062265489323 0.2976965234107388 0
+4958 5.803421919746019 0.4906416545710798 0
+4959 1.859628666335595 0.359498767738413 0
+4960 7.939960184687928 0.6401304044586303 0
+4961 5.899577402652674 0.6456581695326372 0
+4962 5.427856581270168 0.3886965433578823 0
+4963 5.977856581270121 0.3886965433578072 0
+4964 8.174009207144513 0.5906279602173677 0
+4965 3.859162476921221 0.4325050052005567 0
+4966 0.502041670823781 0.7401581131269374 0
+4967 4.795640866277073 0.1785370043078378 0
+4968 2.968663656993805 0.1871144002586992 0
+4969 3.102178563702781 0.783831477417778 0
+4970 6.142550812938693 0.2147144179274401 0
+4971 8.678527786952403 0.8319097689430669 0
+4972 5.712993995955895 0.547974716836488 0
+4973 0.8121777333503446 0.3833735483694203 0
+4974 2.452122291631517 0.1924582429777153 0
+4975 7.347731022855434 0.8073036718875523 0
+4976 5.208132048177646 0.6743315336315159 0
+4977 5.55683022075405 0.3204854905135715 0
+4978 7.488211590534799 0.2436382844079987 0
+4979 1.545086810322259 0.8499923125101638 0
+4980 0.286000593118823 0.917526275936929 0
+4981 6.277965268004735 0.8366017605052366 0
+4982 9.079018657440805 0.8288746967357339 0
+4983 5.158948118101633 0.09955432297560728 0
+4984 9.551537264640622 0.8276606599812748 0
+4985 4.587402767242474 0.3408001380307062 0
+4986 5.217944353964155 0.1299799010727244 0
+4987 1.719150873879207 0.8314241470465663 0
+4988 6.970362184185453 0.1686153801862832 0
+4989 3.934599383116784 0.2305332701290963 0
+4990 5.867965503997623 0.4029171739164807 0
+4991 5.318922910917911 0.3994236019582731 0
+4992 8.333316710237112 0.170709644941206 0
+4993 9.533579615371591 0.2991540262863973 0
+4994 4.826574454629211 0.6628332976687331 0
+4995 9.526204248568794 0.9263704507756966 0
+4996 4.360602144268632 0.03530684979796661 0
+4997 5.39101119685997 0.8142499657948488 0
+4998 9.024999999999906 0.9729324413321699 0
+4999 0.08523218267977557 0.6471934804940178 0
+5000 9.915351281970405 0.3527216822076973 0
+5001 9.35348770601137 0.2232955084769474 0
+5002 1.076386505897599 0.4218725347321231 0
+5003 7.554070382534649 0.6142600396460436 0
+5004 8.389620759963742 0.5992338841014246 0
+5005 8.882170879525827 0.7155617939535442 0
+5006 9.167430890162375 0.2369688674077141 0
+5007 8.676819733190165 0.6449866763572134 0
+5008 8.737680052566478 0.8090807367735879 0
+5009 1.734483950176237 0.5348311575326253 0
+5010 7.066612530195532 0.6192096271602512 0
+5011 3.700972914627622 0.6771791435617565 0
+5012 8.126830270543779 0.3506129539258745 0
+5013 1.034728277304596 0.2420688288142762 0
+5014 2.549763826582018 0.6725114014846114 0
+5015 3.838606918031231 0.9650265853450432 0
+5016 8.097332723412027 0.5311219971379266 0
+5017 3.167945552362387 0.7124919938467092 0
+5018 9.502990674118884 0.431214610843055 0
+5019 2.505459924932421 0.3692578794087729 0
+5020 2.799437806559718 0.6283625124173484 0
+5021 3.442670507932609 0.6284900783545588 0
+5022 3.564616966016494 0.4555524974402896 0
+5023 4.323364821867543 0.7431337476249384 0
+5024 1.900621475546108 0.5637523589340656 0
+5025 7.89987019871354 0.436370809661781 0
+5026 7.149177318440995 0.4362012850219106 0
+5027 1.671028463673349 0.3469757048096125 0
+5028 4.545140215186247 0.9119400097527383 0
+5029 6.0211979185862 0.8059644839930821 0
+5030 3.007372963555934 0.8461010004185463 0
+5031 6.790830406141023 0.1566467144123768 0
+5032 7.186179595207913 0.3719508456852164 0
+5033 1.936750160011605 0.6275728374055283 0
+5034 7.86417341077856 0.369094545090251 0
+5035 5.389891022519242 0.3845128950794559 0
+5036 5.940945793924297 0.3842929490059538 0
+5037 4.882331556600792 0.5698483800232684 0
+5038 7.033986444680864 0.8829283130470753 0
+5039 8.013833590678018 0.8864983549673927 0
+5040 3.615336303215166 0.3617751561203696 0
+5041 4.280494898531989 0.9115227328429886 0
+5042 6.61530581469852 0.5416921966165826 0
+5043 7.865501729577701 0.7829377556058915 0
+5044 1.934498270418502 0.2170622443931871 0
+5045 1.252514322277658 0.9012364632770219 0
+5046 4.698426952325486 0.7626683726635739 0
+5047 0.9815175888878809 0.8113110136477538 0
+5048 4.602839852720088 0.9044479441389083 0
+5049 1.944857730479128 0.1054509516205668 0
+5050 7.889116773711101 0.9071139387381306 0
+5051 2.641006481298221 0.3414301088531597 0
+5052 6.346531144933184 0.4535157351613009 0
+5053 2.90311053962836 0.5474007994085397 0
+5054 1.781073181574998 0.6102219662107154 0
+5055 1.776933792626213 0.6464628836531665 0
+5056 7.029214931599228 0.3483233015996778 0
+5057 9.720319411126896 0.3330207919635402 0
+5058 4.312132611833946 0.07506724350406097 0
+5059 5.686477644488405 0.4250527053549155 0
+5060 2.877087065686221 0.4569131653771451 0
+5061 6.37630087473194 0.538468317394334 0
+5062 9.139912149905983 0.5275274594121878 0
+5063 3.998586592466976 0.137870117758666 0
+5064 1.553561915242183 0.466100273750902 0
+5065 9.538964097342321 0.2030388917619859 0
+5066 4.025076688514195 0.7542855056793694 0
+5067 5.205891964442737 0.5364478835814992 0
+5068 4.014446243422643 0.8250282482071097 0
+5069 8.030486921510128 0.5058852687586728 0
+5070 3.292144633001368 0.5861141173516119 0
+5071 0.8892855811602111 0.6689941673807166 0
+5072 3.330857186998679 0.4963579053041852 0
+5073 5.147475046050633 0.9196184844013197 0
+5074 9.521381811837815 0.5980110179467267 0
+5075 8.760349884910097 0.5234225777890682 0
+5076 1.036238223295099 0.3609090672470726 0
+5077 0.3773881086574299 0.7153991981815198 0
+5078 2.913265362634089 0.4727908525099839 0
+5079 6.343264535308604 0.5241597027312388 0
+5080 0.526112504886467 0.02827495811333659 0
+5081 5.98355500496337 0.5466904983818096 0
+5082 3.661641036302288 0.6806150403366638 0
+5083 2.588358963687779 0.6806150403397075 0
+5084 1.069707736248457 0.5368743679755473 0
+5085 7.686583219828749 0.1622931402849153 0
+5086 2.113770224360409 0.83799305672653 0
+5087 7.674999999996523 0.02668271539108838 0
+5088 2.125000000000003 0.9733172846089809 0
+5089 8.896669193762028 0.4768867773829486 0
+5090 0.07996267091104757 0.5292748390984667 0
+5091 9.920093964950837 0.470725751747682 0
+5092 2.123835938065821 0.03015188450609164 0
+5093 7.676272171161243 0.9703894753743083 0
+5094 3.824999999991495 0.02667046666505109 0
+5095 6.487111698788079 0.3594296790706583 0
+5096 7.244579954587372 0.2443030797458927 0
+5097 4.659350432502298 0.1610982800030445 0
+5098 3.240526650766048 0.4477270868584299 0
+5099 5.428256672786927 0.5402398616901993 0
+5100 2.437618961533495 0.8487082032305537 0
+5101 7.361768767747201 0.1519417417152132 0
+5102 7.334284069891649 0.6973599145636332 0
+5103 1.724500442958651 0.0291101423380686 0
+5104 9.402948610913491 0.5597638255591288 0
+5105 4.505466145359732 0.3185652689194102 0
+5106 1.204998582907555 0.8180702614099112 0
+5107 4.020837462782217 0.9693804172651119 0
+5108 2.141819706310935 0.5273137491777186 0
+5109 7.658180293685843 0.472686250822141 0
+5110 6.692770557906901 0.7815420712974763 0
+5111 3.843357944359224 0.7442026335633241 0
+5112 9.924999999999971 0.02660719903026835 0
+5113 9.924999999999994 0.9733928009697578 0
+5114 2.872890248067743 0.8009853175105183 0
+5115 1.530862752673216 0.3377285484434935 0
+5116 3.873137785846022 0.8581744154668495 0
+5117 0.8150122975113091 0.5826039986389213 0
+5118 8.531482900079574 0.6278872724835322 0
+5119 6.956671660096971 0.8119662885253468 0
+5120 8.079158375247474 0.8404613978171155 0
+5121 5.104025177114029 0.1397928235214676 0
+5122 3.590556806599848 0.7949530825516142 0
+5123 5.469667509892702 0.1869525682048943 0
+5124 9.121188154673114 0.5923306964352847 0
+5125 1.598769896111984 0.5251430450594937 0
+5126 8.932458440590041 0.4200422562740591 0
+5127 9.056026346878626 0.7872794337087351 0
+5128 2.932328131780512 0.4095794532084356 0
+5129 6.309509322452765 0.583986793867205 0
+5130 8.443463458892193 0.2805745954243081 0
+5131 3.314602779153277 0.1954205227228797 0
+5132 4.071673251428791 0.0876733953724068 0
+5133 1.010725976676553 0.9193608245806111 0
+5134 4.514310361293014 0.3566150851886279 0
+5135 3.81403163680098 0.8364259470297799 0
+5136 7.034645010349734 0.1119370155724253 0
+5137 1.772465922930708 0.876609457181777 0
+5138 8.956014102428147 0.4809632320594735 0
+5139 3.933434758701528 0.7423331382268629 0
+5140 4.728070990342903 0.322394018539841 0
+5141 1.722918494594943 0.1627282642237735 0
+5142 1.707731539458873 0.4633005488101288 0
+5143 6.117334120160269 0.4571385435816887 0
+5144 0.8357209929028147 0.08880431751407722 0
+5145 7.37499999999599 0.02639108165422489 0
+5146 2.424999999999998 0.9736089183458889 0
+5147 9.375000000000009 0.9736099213683929 0
+5148 6.931579123122986 0.5348969923302985 0
+5149 4.160793456381274 0.9226636902518691 0
+5150 4.725410153808334 0.1457017133898856 0
+5151 6.677574417239232 0.8553746553797598 0
+5152 3.341860160635542 0.29274585104851 0
+5153 3.841003735490997 0.5273102989973349 0
+5154 0.2271656738223588 0.2993882874371135 0
+5155 3.48011651941587 0.3477808002736435 0
+5156 4.895321019177791 0.0942489887035023 0
+5157 5.094834871527678 0.4947974071464423 0
+5158 1.87992716891943 0.1770104515202601 0
+5159 8.134252897770576 0.7005386470279317 0
+5160 6.915747102229642 0.7005386470278724 0
+5161 8.075000000000074 0.9736579992298716 0
+5162 6.975000000000004 0.9736579992298459 0
+5163 2.824999999994418 0.02634200077004679 0
+5164 9.194208668711259 0.3614762426711436 0
+5165 3.594653231140602 0.2780134004914764 0
+5166 4.610782058488294 0.8576612307378358 0
+5167 1.267384742642544 0.5829168396980664 0
+5168 7.415070914206849 0.2582581302304446 0
+5169 6.661327565221199 0.4663728713350605 0
+5170 3.417617702002348 0.1074948042214244 0
+5171 4.228960129758504 0.03123395161394118 0
+5172 8.60500619622144 0.1940410551676887 0
+5173 8.668238464515779 0.5351747379752234 0
+5174 5.095639239547809 0.9063269037324785 0
+5175 4.678623333423412 0.4303401165750717 0
+5176 1.616440515858496 0.8644765431369098 0
+5177 4.989528734081171 0.5095011479651397 0
+5178 5.845666655144933 0.1449104578842106 0
+5179 5.295670022760569 0.14535192348074 0
+5180 5.844236417657478 0.8552850894942305 0
+5181 6.394598386346391 0.8552979322543786 0
+5182 5.360361039842386 0.5263816533939587 0
+5183 0.2486492723530488 0.2260590495093596 0
+5184 8.309468031268215 0.3544182693201113 0
+5185 7.114997478723927 0.6284080673244236 0
+5186 1.304362363488866 0.662417659000035 0
+5187 1.948516155986011 0.1643693999305753 0
+5188 7.851483844010558 0.8356306000690523 0
+5189 1.957831781034434 0.8115949513301165 0
+5190 3.924999999991198 0.02621122822313044 0
+5191 2.224999999996172 0.02621122822162307 0
+5192 7.575000000000037 0.9737887717783583 0
+5193 4.474882746183972 0.2009782398219984 0
+5194 7.009931690019087 0.5194039617675947 0
+5195 4.007988265472838 0.0962160554108191 0
+5196 9.597021805557297 0.3636122365938417 0
+5197 3.790052360405581 0.5753815879246561 0
+5198 5.570998975806374 0.2406182094621506 0
+5199 1.760416997293524 0.4738530420413424 0
+5200 5.172012886814989 0.848060094127401 0
+5201 3.00685597620827 0.2151986535790349 0
+5202 7.842209030086707 0.1885404571010504 0
+5203 2.894845374114033 0.175753898469175 0
+5204 3.907227997752409 0.9165462410903322 0
+5205 2.228797037370398 0.2507400016850749 0
+5206 7.5715589996673 0.7506009207591532 0
+5207 3.372491461534629 0.3490520533704406 0
+5208 0.2142154337014438 0.03321494994268382 0
+5209 2.466241769297036 0.3019964321319613 0
+5210 5.030022986249199 0.3472900495740348 0
+5211 4.279342938196913 0.5569768784039121 0
+5212 9.473612748691108 0.9089082937184925 0
+5213 2.207159189769983 0.2145521300769999 0
+5214 7.592975758138908 0.785722851345255 0
+5215 2.76882181544205 0.3468746087836488 0
+5216 1.725000000000001 0.9739545471049432 0
+5217 6.974999999995389 0.02604545289498315 0
+5218 2.825000000000005 0.9739545471050822 0
+5219 7.193471495397268 0.8934483274717101 0
+5220 9.704269535639236 0.5526728003463384 0
+5221 8.12081619368867 0.6410339583540789 0
+5222 6.929253938687003 0.64042097808191 0
+5223 2.211941449029532 0.09150631611389798 0
+5224 7.557655866553962 0.9048717009972466 0
+5225 3.910494317629371 0.09112380601355574 0
+5226 0.2980444207061307 0.454372672796132 0
+5227 5.103016629483064 0.2369821150599964 0
+5228 8.844790080044399 0.08419809208670374 0
+5229 1.296527907368538 0.9093723236265833 0
+5230 4.862127653290869 0.4216988945185822 0
+5231 1.873089920072843 0.4005610274335549 0
+5232 7.926892787779284 0.5995076371507594 0
+5233 7.590681598117947 0.0903860346402393 0
+5234 9.289686850172151 0.361095768533833 0
+5235 6.569150101418354 0.1862917314995795 0
+5236 1.036379754899257 0.6492550218237241 0
+5237 3.473373873620266 0.1460469689235405 0
+5238 1.105496547602886 0.3155203593896739 0
+5239 9.402468789541841 0.3175658198817492 0
+5240 4.787373767199693 0.9662790927620195 0
+5241 5.494410118220586 0.9167617633965978 0
+5242 3.521970224175509 0.2652213596375004 0
+5243 6.78971912174846 0.467605759775893 0
+5244 4.229565284310579 0.6953723743418999 0
+5245 2.80023071406287 0.5185258538983722 0
+5246 3.447239058779993 0.518059871432804 0
+5247 0.7531946292480202 0.4215450576262703 0
+5248 2.816837441718559 0.6882805842783039 0
+5249 8.403240143417346 0.5289838726184622 0
+5250 5.017410273266225 0.6605157447738675 0
+5251 4.208083475938393 0.9080729291036117 0
+5252 0.8840315363506294 0.5137413639738051 0
+5253 2.427517528228043 0.02949102435836268 0
+5254 7.372465043314078 0.9705073153108443 0
+5255 2.310128944725139 0.9048513917191376 0
+5256 5.954271766888034 0.833985796501943 0
+5257 6.503736045084825 0.8347680117445443 0
+5258 8.753736045084676 0.1652319882554807 0
+5259 6.506451874609579 0.1635184899335754 0
+5260 5.4065167507804 0.1635873651261336 0
+5261 5.956791398713177 0.165113160597503 0
+5262 8.96173263990578 0.9667121558197515 0
+5263 0.8318480784365742 0.3460106010067318 0
+5264 4.766887531448259 0.1016978649845782 0
+5265 2.225329283125456 0.9711892067108923 0
+5266 7.574999999996329 0.02578029536014626 0
+5267 8.811892945725207 0.4576132132312229 0
+5268 4.677960777888218 0.8270957713199865 0
+5269 0.4870939843485013 0.07972636610488283 0
+5270 9.723075424665897 0.9696147444997938 0
+5271 9.723065555487905 0.03033941778102538 0
+5272 9.303529159136954 0.3226028692822312 0
+5273 0.5043322725205207 0.8313669745546359 0
+5274 8.792771332932316 0.5388090982611549 0
+5275 9.15489509935197 0.3468849355868329 0
+5276 9.502667976463103 0.08939826149626219 0
+5277 1.786211839601848 0.1157153508833774 0
+5278 4.131863741604845 0.4390034220364086 0
+5279 3.741945188545109 0.5149070023849631 0
+5280 2.273760545809536 0.5326113557499518 0
+5281 7.526235240448825 0.4672671438289895 0
+5282 9.16774594065855 0.7554811842428908 0
+5283 3.89091188903795 0.6920029701288669 0
+5284 0.3172900654889783 0.2073145967120385 0
+5285 1.106738926786456 0.6470362742604133 0
+5286 2.310742780361894 0.6873125159055733 0
+5287 0.9939007945647431 0.3118491906055703 0
+5288 0.3919297997619894 0.913181749941136 0
+5289 2.465007136647178 0.3629366120278129 0
+5290 4.858527127463819 0.03476095089209974 0
+5291 7.901570928101811 0.3458134223363263 0
+5292 0.8006464072169169 0.7688557028045225 0
+5293 4.61182341482748 0.5451568058570931 0
+5294 6.657804784715053 0.4307847343076275 0
+5295 6.592565377540988 0.4380809409224458 0
+5296 3.406867245876116 0.7255550563665275 0
+5297 9.23239254143531 0.9021115709138987 0
+5298 2.597352275405785 0.8090414797438999 0
+5299 0.4474051440849159 0.6342917338110365 0
+5300 1.712654159557123 0.3536833908836245 0
+5301 2.893010139121588 0.3437234998803593 0
+5302 6.181158306126851 0.6371055545768843 0
+5303 5.358967377270869 0.7066020978324629 0
+5304 3.479445641376071 0.2575587508025328 0
+5305 0.9972069639119741 0.1867555714894059 0
+5306 9.589284315241539 0.7942322254327916 0
+5307 0.7411036171043515 0.4882471090067912 0
+5308 0.4260857638529251 0.9708842780893991 0
+5309 1.643724739599596 0.5224377782444579 0
+5310 4.659094961831244 0.6518527005782818 0
+5311 1.672609723860475 0.2351197001309341 0
+5312 5.494305788276598 0.39130825564693 0
+5313 8.743012616118799 0.4285641171670878 0
+5314 4.101475839239257 0.5245460079198929 0
+5315 9.229257151362155 0.2007804164667104 0
+5316 0.2877484756000891 0.08076932594327285 0
+5317 4.570251392032454 0.5612632601971547 0
+5318 3.946007370656725 0.3503376908566362 0
+5319 9.641763617569802 0.2450631663031701 0
+5320 6.597509873373237 0.9117543402753163 0
+5321 9.406680173274486 0.1737379290671185 0
+5322 6.594630592093398 0.08190320589707806 0
+5323 1.835614782434062 0.1630579413166721 0
+5324 0.33987509901309 0.9658432144451841 0
+5325 4.92898309555402 0.1219273968080765 0
+5326 8.061779504893247 0.1721886726832319 0
+5327 3.238210509101557 0.1232015246302381 0
+5328 7.693770372582369 0.8472735039823747 0
+5329 2.103886513952175 0.1543048439501196 0
+5330 4.506575382746956 0.7079145978018493 0
+5331 7.153015378398721 0.3631388013192097 0
+5332 1.903015378394879 0.6368611986779734 0
+5333 3.585870843312132 0.6764283943075099 0
+5334 2.664711723945424 0.6768461406555333 0
+5335 2.005579879787091 0.5189419584768377 0
+5336 7.794366362808823 0.4810733747591929 0
+5337 7.257384658949765 0.4806040711548711 0
+5338 5.512029915920369 0.7904793149668614 0
+5339 8.43790955937085 0.7897482309769358 0
+5340 2.339705967850013 0.08720169533622417 0
+5341 7.460294032145667 0.9127983046638701 0
+5342 6.044544591661918 0.08174314068187057 0
+5343 5.494524814910637 0.08169156092813586 0
+5344 0.5700555186088474 0.3402994918135884 0
+5345 7.524785404794978 0.1905118724249263 0
+5346 8.148704695521696 0.1402320984276318 0
+5347 7.857816227110013 0.4863163442672548 0
+5348 1.942183772887103 0.5136836557329877 0
+5349 9.171166351948672 0.7986513053693113 0
+5350 1.777403293888337 0.3072501254095289 0
+5351 8.292564698646663 0.3839770417820347 0
+5352 4.108113585789023 0.1382584095783649 0
+5353 8.498444144386401 0.4669241065314896 0
+5354 5.601498669136422 0.3786075267695184 0
+5355 2.228452891257687 0.1602622709524011 0
+5356 7.571547108738281 0.8397377290476221 0
+5357 3.92845289125875 0.1602622709528048 0
+5358 1.831162211765161 0.2727075096876907 0
+5359 3.961435548959206 0.5981345582047872 0
+5360 3.962071628997936 0.6345246262053852 0
+5361 3.374999999992812 0.0252545613186351 0
+5362 2.324999999999999 0.9747477406511419 0
+5363 7.474999999996172 0.02525225934884498 0
+5364 5.566937852382351 0.6002918616397022 0
+5365 2.643524552042089 0.9138714240364614 0
+5366 0.9727564435243047 0.9719805428959265 0
+5367 6.567629408592817 0.8186793740420168 0
+5368 6.994245767042883 0.5934227296021678 0
+5369 8.050274039146096 0.5918158030008559 0
+5370 0.1434850457250269 0.7312325247833699 0
+5371 9.859315904368501 0.2624130912862179 0
+5372 9.828632127141509 0.7320332406580344 0
+5373 0.1661885659923887 0.2724300478853384 0
+5374 0.7809591987083483 0.1203305515016041 0
+5375 8.331668342488991 0.2850265078935631 0
+5376 1.905456041673904 0.9168080527294421 0
+5377 7.155456041672561 0.08319194727010755 0
+5378 7.971169534305693 0.7249333432935063 0
+5379 6.521559291113391 0.6096447011519952 0
+5380 1.394957565018542 0.5131166017613222 0
+5381 1.357782462606894 0.5255252284659532 0
+5382 4.684929955646268 0.5396176245470022 0
+5383 7.319327067559374 0.2476165954564935 0
+5384 0.9446149733699863 0.4665755848693958 0
+5385 1.294920837685269 0.5545793863570431 0
+5386 4.383388629405832 0.08250581057238336 0
+5387 0.2752005337254705 0.6686535947294937 0
+5388 8.590664362416421 0.7063119304033237 0
+5389 7.079019189701547 0.5426897707228137 0
+5390 2.216570461268943 0.8375618458912103 0
+5391 4.308469760513203 0.4987072374386244 0
+5392 4.749289057398861 0.5188290730471402 0
+5393 7.889060810444306 0.2298929027082631 0
+5394 4.240512608625841 0.4919354338997147 0
+5395 5.317049402593732 0.03104204046133895 0
+5396 5.865181272356719 0.03195412890318961 0
+5397 6.415057162542113 0.03204899066521547 0
+5398 8.665057162543029 0.03204899066568995 0
+5399 6.415104359048979 0.9680857053991614 0
+5400 5.865181272358544 0.9680458710960086 0
+5401 5.420873567214272 0.911621205503603 0
+5402 1.251849152936285 0.503518147917106 0
+5403 6.004779879398498 0.689590137114126 0
+5404 9.076897205644617 0.4047440561315863 0
+5405 1.302886133968276 0.6184187958557862 0
+5406 1.574268230054201 0.7363113154328539 0
+5407 5.431389190964421 0.4358943539280283 0
+5408 9.62359830505191 0.7274441273920709 0
+5409 1.235312833153848 0.1470706380704994 0
+5410 9.650028543102769 0.700088534342628 0
+5411 3.467017368198885 0.9155118982276278 0
+5412 9.106546634721502 0.5576980744714589 0
+5413 3.196248697693924 0.06507240476996952 0
+5414 2.238072752826715 0.5490539537925477 0
+5415 7.561926685338281 0.4509298461510347 0
+5416 3.9384600914276 0.5426347490032941 0
+5417 2.945825331629905 0.442274640615306 0
+5418 9.232154690126857 0.2437627217964675 0
+5419 2.703195875829863 0.2352253446414983 0
+5420 2.718622588313248 0.2667259958442457 0
+$EndNodes
+$Elements
+10420
+1 15 2 2 1 1
+2 15 2 3 3 3
+3 1 2 1 2 2 205
+4 1 2 1 2 205 206
+5 1 2 1 2 206 207
+6 1 2 1 2 207 208
+7 1 2 1 2 208 3
+8 1 2 1 3 3 209
+9 1 2 1 3 209 210
+10 1 2 1 3 210 211
+11 1 2 1 3 211 212
+12 1 2 1 3 212 213
+13 1 2 1 3 213 214
+14 1 2 1 3 214 215
+15 1 2 1 3 215 216
+16 1 2 1 3 216 217
+17 1 2 1 3 217 218
+18 1 2 1 3 218 219
+19 1 2 1 3 219 220
+20 1 2 1 3 220 221
+21 1 2 1 3 221 222
+22 1 2 1 3 222 4
+23 2 2 4 8 1497 4168 1810
+24 2 2 4 8 747 1810 4168
+25 2 2 4 8 1007 1835 2457
+26 2 2 4 8 660 2077 3009
+27 2 2 4 8 898 1940 2083
+28 2 2 4 8 464 2135 4144
+29 2 2 4 8 927 2073 2047
+30 2 2 4 8 928 2048 2072
+31 2 2 4 8 533 1733 2788
+32 2 2 4 8 1729 1165 3150
+33 2 2 4 8 1166 3149 1728
+34 2 2 4 8 932 1818 2348
+35 2 2 4 8 933 1819 2349
+36 2 2 4 8 633 1938 3061
+37 2 2 4 8 1229 3061 1938
+38 2 2 4 8 634 1939 3062
+39 2 2 4 8 1231 3062 1939
+40 2 2 4 8 95 4275 2251
+41 2 2 4 8 489 2949 2371
+42 2 2 4 8 464 4144 4491
+43 2 2 4 8 1438 3691 1929
+44 2 2 4 8 593 3153 2185
+45 2 2 4 8 594 2186 3154
+46 2 2 4 8 619 2409 1836
+47 2 2 4 8 744 4155 1723
+48 2 2 4 8 23 24 1918
+49 2 2 4 8 822 2900 2046
+50 2 2 4 8 900 3614 1756
+51 2 2 4 8 1055 2851 1669
+52 2 2 4 8 829 3686 2515
+53 2 2 4 8 1272 2912 3035
+54 2 2 4 8 942 2530 1734
+55 2 2 4 8 624 1734 2530
+56 2 2 4 8 839 2280 1964
+57 2 2 4 8 988 1964 2280
+58 2 2 4 8 723 3521 2540
+59 2 2 4 8 725 3522 2541
+60 2 2 4 8 660 3009 2429
+61 2 2 4 8 1137 1680 2454
+62 2 2 4 8 528 2927 1874
+63 2 2 4 8 1167 1874 2927
+64 2 2 4 8 1046 1803 5081
+65 2 2 4 8 931 2355 1817
+66 2 2 4 8 745 2465 1724
+67 2 2 4 8 945 1724 2465
+68 2 2 4 8 1047 1811 5099
+69 2 2 4 8 586 5098 1812
+70 2 2 4 8 1299 1867 3675
+71 2 2 4 8 1172 2317 1914
+72 2 2 4 8 869 1914 2317
+73 2 2 4 8 1662 4449 967
+74 2 2 4 8 914 2416 2175
+75 2 2 4 8 465 2529 1889
+76 2 2 4 8 652 1723 2644
+77 2 2 4 8 549 1859 2169
+78 2 2 4 8 550 1860 2170
+79 2 2 4 8 548 1858 2171
+80 2 2 4 8 638 3503 2783
+81 2 2 4 8 637 2782 3502
+82 2 2 4 8 606 4259 2235
+83 2 2 4 8 4226 2235 4259
+84 2 2 4 8 1798 4795 4778
+85 2 2 4 8 1799 4796 4779
+86 2 2 4 8 794 3040 1918
+87 2 2 4 8 1220 1918 3040
+88 2 2 4 8 1439 2383 2741
+89 2 2 4 8 962 2741 2383
+90 2 2 4 8 1783 2282 4579
+91 2 2 4 8 888 2264 1926
+92 2 2 4 8 1224 1926 2264
+93 2 2 4 8 685 1865 3859
+94 2 2 4 8 486 3119 2273
+95 2 2 4 8 2086 977 2269
+96 2 2 4 8 2086 2269 1051
+97 2 2 4 8 2740 1337 2886
+98 2 2 4 8 470 3301 3180
+99 2 2 4 8 481 3179 3300
+100 2 2 4 8 2431 4497 3894
+101 2 2 4 8 1624 2893 1122
+102 2 2 4 8 1834 4753 4614
+103 2 2 4 8 1257 2631 2506
+104 2 2 4 8 1169 2506 2631
+105 2 2 4 8 1624 1122 3442
+106 2 2 4 8 1021 3089 3480
+107 2 2 4 8 866 2486 2485
+108 2 2 4 8 1315 2485 2486
+109 2 2 4 8 482 3516 3672
+110 2 2 4 8 484 3517 3673
+111 2 2 4 8 924 4559 1726
+112 2 2 4 8 925 1727 4560
+113 2 2 4 8 934 1820 2368
+114 2 2 4 8 935 1821 2369
+115 2 2 4 8 1586 3156 4550
+116 2 2 4 8 1341 2181 2660
+117 2 2 4 8 648 2660 2181
+118 2 2 4 8 1342 2180 2659
+119 2 2 4 8 650 2659 2180
+120 2 2 4 8 560 1965 2400
+121 2 2 4 8 1180 2565 2548
+122 2 2 4 8 1140 2199 2533
+123 2 2 4 8 1033 2533 2199
+124 2 2 4 8 1031 2532 2200
+125 2 2 4 8 1139 2200 2532
+126 2 2 4 8 1138 2201 2531
+127 2 2 4 8 1032 2531 2201
+128 2 2 4 8 1497 1810 2587
+129 2 2 4 8 566 2355 1743
+130 2 2 4 8 421 2068 3465
+131 2 2 4 8 1431 1744 2961
+132 2 2 4 8 557 2406 1959
+133 2 2 4 8 1231 1939 4975
+134 2 2 4 8 1229 1938 4974
+135 2 2 4 8 616 5175 3209
+136 2 2 4 8 2273 3119 4033
+137 2 2 4 8 463 4579 2282
+138 2 2 4 8 470 2445 3301
+139 2 2 4 8 481 3300 2444
+140 2 2 4 8 2567 3807 5205
+141 2 2 4 8 2568 3808 5206
+142 2 2 4 8 1798 2190 4795
+143 2 2 4 8 1799 2191 4796
+144 2 2 4 8 768 1752 3344
+145 2 2 4 8 769 3345 1753
+146 2 2 4 8 681 2434 3265
+147 2 2 4 8 2509 4505 4022
+148 2 2 4 8 1079 1653 2624
+149 2 2 4 8 465 2020 2529
+150 2 2 4 8 543 2097 2119
+151 2 2 4 8 2097 978 2119
+152 2 2 4 8 2515 3686 1579
+153 2 2 4 8 1834 4614 2557
+154 2 2 4 8 2918 4184 3371
+155 2 2 4 8 614 2003 3529
+156 2 2 4 8 496 3708 1750
+157 2 2 4 8 1276 1750 3708
+158 2 2 4 8 2652 4760 3442
+159 2 2 4 8 1218 2319 2645
+160 2 2 4 8 622 2645 2319
+161 2 2 4 8 1219 2646 2320
+162 2 2 4 8 623 2320 2646
+163 2 2 4 8 528 1874 3229
+164 2 2 4 8 993 2652 2992
+165 2 2 4 8 1257 1786 3458
+166 2 2 4 8 757 3458 1786
+167 2 2 4 8 925 5248 1948
+168 2 2 4 8 1073 1947 3374
+169 2 2 4 8 1287 3374 1947
+170 2 2 4 8 549 2214 1859
+171 2 2 4 8 550 2215 1860
+172 2 2 4 8 924 2072 2048
+173 2 2 4 8 925 2047 2073
+174 2 2 4 8 842 1658 2633
+175 2 2 4 8 2371 2949 3843
+176 2 2 4 8 1276 3911 1750
+177 2 2 4 8 736 1647 4499
+178 2 2 4 8 734 4500 1648
+179 2 2 4 8 621 1930 2363
+180 2 2 4 8 1036 3703 2968
+181 2 2 4 8 548 2219 1858
+182 2 2 4 8 593 2864 3153
+183 2 2 4 8 594 3154 2863
+184 2 2 4 8 35 36 1880
+185 2 2 4 8 924 1797 4863
+186 2 2 4 8 1316 3807 2567
+187 2 2 4 8 1317 3808 2568
+188 2 2 4 8 51 52 2012
+189 2 2 4 8 272 273 2013
+190 2 2 4 8 1104 4297 1768
+191 2 2 4 8 1105 4296 1769
+192 2 2 4 8 444 2191 2504
+193 2 2 4 8 453 2190 2505
+194 2 2 4 8 736 3021 1647
+195 2 2 4 8 1385 3859 1865
+196 2 2 4 8 943 2509 4022
+197 2 2 4 8 1318 2918 3371
+198 2 2 4 8 599 2553 2157
+199 2 2 4 8 920 3634 1763
+200 2 2 4 8 604 3723 2022
+201 2 2 4 8 839 1807 2280
+202 2 2 4 8 2279 3403 4436
+203 2 2 4 8 1060 2999 3119
+204 2 2 4 8 582 5129 4441
+205 2 2 4 8 570 1768 2348
+206 2 2 4 8 572 1769 2349
+207 2 2 4 8 573 1765 2368
+208 2 2 4 8 574 1764 2369
+209 2 2 4 8 725 2541 4303
+210 2 2 4 8 723 2540 4304
+211 2 2 4 8 946 2464 1764
+212 2 2 4 8 2102 2400 915
+213 2 2 4 8 1078 2257 2224
+214 2 2 4 8 1077 2223 2256
+215 2 2 4 8 915 2256 2223
+216 2 2 4 8 918 2224 2257
+217 2 2 4 8 1099 1743 4229
+218 2 2 4 8 2085 1131 4258
+219 2 2 4 8 869 3216 1914
+220 2 2 4 8 870 3217 1915
+221 2 2 4 8 647 2652 3442
+222 2 2 4 8 2139 4219 3362
+223 2 2 4 8 2140 4221 3363
+224 2 2 4 8 1198 2240 2665
+225 2 2 4 8 829 2665 2240
+226 2 2 4 8 1702 2520 890
+227 2 2 4 8 2003 3482 3529
+228 2 2 4 8 925 2073 5248
+229 2 2 4 8 1384 1947 3857
+230 2 2 4 8 1188 3314 1735
+231 2 2 4 8 1796 3643 4469
+232 2 2 4 8 1975 3209 5175
+233 2 2 4 8 687 1850 3860
+234 2 2 4 8 1850 1387 3860
+235 2 2 4 8 1479 2603 3071
+236 2 2 4 8 705 3071 2603
+237 2 2 4 8 872 3491 2010
+238 2 2 4 8 690 1937 2615
+239 2 2 4 8 1889 2529 4280
+240 2 2 4 8 949 2593 2399
+241 2 2 4 8 620 1927 2354
+242 2 2 4 8 1248 2395 2225
+243 2 2 4 8 843 1951 4539
+244 2 2 4 8 844 1952 4540
+245 2 2 4 8 531 4219 2139
+246 2 2 4 8 532 4221 2140
+247 2 2 4 8 686 1846 2476
+248 2 2 4 8 653 1724 2616
+249 2 2 4 8 1039 1842 2272
+250 2 2 4 8 918 2262 2669
+251 2 2 4 8 994 2634 1748
+252 2 2 4 8 995 2635 1749
+253 2 2 4 8 744 1791 4155
+254 2 2 4 8 980 1713 3432
+255 2 2 4 8 1674 1126 2608
+256 2 2 4 8 533 2559 1733
+257 2 2 4 8 1047 5099 2153
+258 2 2 4 8 586 2154 5098
+259 2 2 4 8 1567 3829 1921
+260 2 2 4 8 754 1785 3309
+261 2 2 4 8 1012 2010 3888
+262 2 2 4 8 1136 2848 1903
+263 2 2 4 8 632 1903 2848
+264 2 2 4 8 627 1960 2697
+265 2 2 4 8 1112 2697 1960
+266 2 2 4 8 1734 4046 2387
+267 2 2 4 8 864 2387 4046
+268 2 2 4 8 1046 5081 2152
+269 2 2 4 8 877 1892 3248
+270 2 2 4 8 1011 2401 2188
+271 2 2 4 8 1110 2188 2401
+272 2 2 4 8 825 1858 4158
+273 2 2 4 8 671 2985 4149
+274 2 2 4 8 672 2984 4148
+275 2 2 4 8 3039 595 3296
+276 2 2 4 8 639 4312 1794
+277 2 2 4 8 583 2137 3548
+278 2 2 4 8 629 2539 3370
+279 2 2 4 8 78 3598 1694
+280 2 2 4 8 1702 890 3234
+281 2 2 4 8 883 2288 3287
+282 2 2 4 8 884 2289 3288
+283 2 2 4 8 1351 3504 2432
+284 2 2 4 8 825 1877 3750
+285 2 2 4 8 914 3403 2279
+286 2 2 4 8 2095 989 2468
+287 2 2 4 8 2095 2468 1196
+288 2 2 4 8 870 2409 1967
+289 2 2 4 8 1209 1967 2409
+290 2 2 4 8 1951 2688 4539
+291 2 2 4 8 1952 2689 4540
+292 2 2 4 8 870 1967 3217
+293 2 2 4 8 1343 2774 2658
+294 2 2 4 8 981 2658 2774
+295 2 2 4 8 1342 2659 2773
+296 2 2 4 8 982 2773 2659
+297 2 2 4 8 983 2772 2660
+298 2 2 4 8 1341 2660 2772
+299 2 2 4 8 1166 2736 2253
+300 2 2 4 8 1331 2706 2037
+301 2 2 4 8 1332 2707 2038
+302 2 2 4 8 861 2480 1899
+303 2 2 4 8 862 1898 2479
+304 2 2 4 8 642 3716 1766
+305 2 2 4 8 730 2803 3671
+306 2 2 4 8 34 1637 3032
+307 2 2 4 8 1048 2367 1962
+308 2 2 4 8 1135 1962 2367
+309 2 2 4 8 945 2616 1724
+310 2 2 4 8 2432 3504 4330
+311 2 2 4 8 762 4180 2019
+312 2 2 4 8 1582 2019 4180
+313 2 2 4 8 1394 2004 2634
+314 2 2 4 8 1395 2005 2635
+315 2 2 4 8 600 2156 3377
+316 2 2 4 8 1048 2174 2175
+317 2 2 4 8 914 2175 2174
+318 2 2 4 8 1710 4471 3215
+319 2 2 4 8 616 2431 3894
+320 2 2 4 8 825 4124 1858
+321 2 2 4 8 947 2428 1765
+322 2 2 4 8 2336 5129 582
+323 2 2 4 8 798 2292 2022
+324 2 2 4 8 94 95 2251
+325 2 2 4 8 595 2583 3296
+326 2 2 4 8 1211 1869 3346
+327 2 2 4 8 646 2193 3002
+328 2 2 4 8 1263 3002 2193
+329 2 2 4 8 1123 2000 2393
+330 2 2 4 8 1060 2393 2000
+331 2 2 4 8 900 3958 1754
+332 2 2 4 8 1288 2429 3009
+333 2 2 4 8 638 2579 3503
+334 2 2 4 8 637 3502 2578
+335 2 2 4 8 907 3615 2971
+336 2 2 4 8 34 4231 1637
+337 2 2 4 8 629 3370 2907
+338 2 2 4 8 900 1756 3958
+339 2 2 4 8 880 2029 3951
+340 2 2 4 8 881 2030 3950
+341 2 2 4 8 911 2032 2374
+342 2 2 4 8 912 2373 2031
+343 2 2 4 8 1675 2971 3615
+344 2 2 4 8 731 2804 3691
+345 2 2 4 8 563 2740 2886
+346 2 2 4 8 497 3942 1808
+347 2 2 4 8 930 2427 1816
+348 2 2 4 8 459 1922 3168
+349 2 2 4 8 1238 3168 1922
+350 2 2 4 8 665 3635 3139
+351 2 2 4 8 875 3133 2049
+352 2 2 4 8 842 3350 1658
+353 2 2 4 8 1165 2663 2252
+354 2 2 4 8 78 1694 3101
+355 2 2 4 8 1311 2211 3399
+356 2 2 4 8 1310 2210 3398
+357 2 2 4 8 1312 3400 2209
+358 2 2 4 8 668 3256 2164
+359 2 2 4 8 1027 2563 2550
+360 2 2 4 8 1228 2550 2563
+361 2 2 4 8 1414 2525 3749
+362 2 2 4 8 583 3548 2257
+363 2 2 4 8 869 2317 1835
+364 2 2 4 8 748 3304 1777
+365 2 2 4 8 750 3306 1778
+366 2 2 4 8 477 1913 3513
+367 2 2 4 8 1299 3939 1867
+368 2 2 4 8 596 1872 2457
+369 2 2 4 8 598 1873 2458
+370 2 2 4 8 759 1780 2417
+371 2 2 4 8 2461 3851 4176
+372 2 2 4 8 1091 4190 1765
+373 2 2 4 8 1092 4189 1764
+374 2 2 4 8 731 3637 2804
+375 2 2 4 8 730 3638 2803
+376 2 2 4 8 653 3778 1724
+377 2 2 4 8 420 421 3465
+378 2 2 4 8 612 1642 2937
+379 2 2 4 8 611 1643 2936
+380 2 2 4 8 872 3237 3491
+381 2 2 4 8 968 2247 2152
+382 2 2 4 8 1047 2153 2248
+383 2 2 4 8 969 2248 2153
+384 2 2 4 8 1046 2152 2247
+385 2 2 4 8 1045 2154 2246
+386 2 2 4 8 967 2246 2154
+387 2 2 4 8 1056 3105 2890
+388 2 2 4 8 611 3472 1643
+389 2 2 4 8 652 3777 1723
+390 2 2 4 8 612 3067 1642
+391 2 2 4 8 1542 3840 1977
+392 2 2 4 8 1543 3841 1976
+393 2 2 4 8 1110 2035 2545
+394 2 2 4 8 1042 5046 1826
+395 2 2 4 8 781 2849 3597
+396 2 2 4 8 734 1648 2943
+397 2 2 4 8 753 1722 2574
+398 2 2 4 8 923 2786 1981
+399 2 2 4 8 737 3786 4942
+400 2 2 4 8 1113 4673 1751
+401 2 2 4 8 1438 4088 3691
+402 2 2 4 8 492 2053 3707
+403 2 2 4 8 482 3672 2449
+404 2 2 4 8 484 3673 2450
+405 2 2 4 8 35 1880 4231
+406 2 2 4 8 958 2238 2745
+407 2 2 4 8 908 3600 2972
+408 2 2 4 8 906 1922 2360
+409 2 2 4 8 460 2361 1924
+410 2 2 4 8 461 2362 1923
+411 2 2 4 8 525 3675 1867
+412 2 2 4 8 1023 3947 1784
+413 2 2 4 8 901 5385 2062
+414 2 2 4 8 1579 3686 3889
+415 2 2 4 8 688 1936 3456
+416 2 2 4 8 1292 3456 1936
+417 2 2 4 8 2062 5385 1979
+418 2 2 4 8 760 4469 3643
+419 2 2 4 8 1207 1652 5121
+420 2 2 4 8 1082 2952 2842
+421 2 2 4 8 1079 2887 1653
+422 2 2 4 8 1296 2129 2353
+423 2 2 4 8 535 1757 2944
+424 2 2 4 8 998 2189 2221
+425 2 2 4 8 1042 2221 2189
+426 2 2 4 8 1024 1777 5203
+427 2 2 4 8 684 3857 1947
+428 2 2 4 8 4206 3247 4702
+429 2 2 4 8 1160 2304 1934
+430 2 2 4 8 1161 1933 2305
+431 2 2 4 8 1774 3247 4206
+432 2 2 4 8 910 5142 2036
+433 2 2 4 8 1781 4550 3156
+434 2 2 4 8 1207 3036 1652
+435 2 2 4 8 698 3634 4597
+436 2 2 4 8 1048 1962 4961
+437 2 2 4 8 1130 2724 2045
+438 2 2 4 8 651 2045 2724
+439 2 2 4 8 971 1743 2544
+440 2 2 4 8 724 3746 4501
+441 2 2 4 8 1251 2739 1679
+442 2 2 4 8 1617 4700 2613
+443 2 2 4 8 851 1932 2273
+444 2 2 4 8 1664 2972 3600
+445 2 2 4 8 895 2044 5045
+446 2 2 4 8 968 2548 2565
+447 2 2 4 8 466 2294 1935
+448 2 2 4 8 626 3143 2089
+449 2 2 4 8 653 2341 3778
+450 2 2 4 8 1221 2595 1994
+451 2 2 4 8 2062 1979 5402
+452 2 2 4 8 2022 3723 4602
+453 2 2 4 8 2107 3026 3369
+454 2 2 4 8 877 3248 2012
+455 2 2 4 8 878 3249 2013
+456 2 2 4 8 942 1822 2473
+457 2 2 4 8 349 3185 1736
+458 2 2 4 8 162 3184 1735
+459 2 2 4 8 982 1671 3170
+460 2 2 4 8 983 1672 3171
+461 2 2 4 8 996 1791 2682
+462 2 2 4 8 771 2931 3668
+463 2 2 4 8 2172 3161 4387
+464 2 2 4 8 2036 5142 2380
+465 2 2 4 8 920 1763 4004
+466 2 2 4 8 884 3288 4944
+467 2 2 4 8 883 3287 4943
+468 2 2 4 8 1055 1669 2953
+469 2 2 4 8 2077 3666 3009
+470 2 2 4 8 1145 1770 4580
+471 2 2 4 8 1144 1771 4581
+472 2 2 4 8 1024 2487 2816
+473 2 2 4 8 1272 2816 2487
+474 2 2 4 8 888 1926 3970
+475 2 2 4 8 2083 639 3969
+476 2 2 4 8 448 1831 2627
+477 2 2 4 8 1000 2244 2302
+478 2 2 4 8 1078 2302 2244
+479 2 2 4 8 999 2301 2243
+480 2 2 4 8 1077 2243 2301
+481 2 2 4 8 1001 2303 2245
+482 2 2 4 8 1076 2245 2303
+483 2 2 4 8 944 1783 4579
+484 2 2 4 8 469 5020 1944
+485 2 2 4 8 468 1945 5021
+486 2 2 4 8 1037 2494 1773
+487 2 2 4 8 1038 2495 1772
+488 2 2 4 8 924 4863 2072
+489 2 2 4 8 1696 3668 2931
+490 2 2 4 8 482 2324 1973
+491 2 2 4 8 951 1973 2324
+492 2 2 4 8 950 1972 2325
+493 2 2 4 8 484 2325 1972
+494 2 2 4 8 1617 4292 3849
+495 2 2 4 8 443 3038 1754
+496 2 2 4 8 963 2830 2467
+497 2 2 4 8 965 2466 2829
+498 2 2 4 8 821 2909 3654
+499 2 2 4 8 744 1723 3781
+500 2 2 4 8 1012 3888 4480
+501 2 2 4 8 499 3822 3990
+502 2 2 4 8 501 3823 3991
+503 2 2 4 8 1273 2220 2446
+504 2 2 4 8 615 2446 2220
+505 2 2 4 8 794 4746 1766
+506 2 2 4 8 476 2318 2903
+507 2 2 4 8 1036 2699 3703
+508 2 2 4 8 855 4338 2577
+509 2 2 4 8 1159 4993 1665
+510 2 2 4 8 903 2001 4346
+511 2 2 4 8 905 3851 2461
+512 2 2 4 8 2107 1116 3026
+513 2 2 4 8 1248 3224 2395
+514 2 2 4 8 902 2614 1969
+515 2 2 4 8 588 2198 2044
+516 2 2 4 8 2341 3390 3778
+517 2 2 4 8 1662 967 3226
+518 2 2 4 8 215 2037 2925
+519 2 2 4 8 433 2038 2926
+520 2 2 4 8 1113 2222 3655
+521 2 2 4 8 805 4360 1887
+522 2 2 4 8 806 4361 1888
+523 2 2 4 8 1026 1779 5120
+524 2 2 4 8 750 1778 5119
+525 2 2 4 8 745 1724 3783
+526 2 2 4 8 922 1935 2294
+527 2 2 4 8 2044 2198 5045
+528 2 2 4 8 84 2600 5190
+529 2 2 4 8 1617 2613 4292
+530 2 2 4 8 1154 2399 2593
+531 2 2 4 8 202 3129 1933
+532 2 2 4 8 225 1934 3130
+533 2 2 4 8 616 3209 2431
+534 2 2 4 8 1010 1790 5141
+535 2 2 4 8 737 2910 3786
+536 2 2 4 8 694 2987 2346
+537 2 2 4 8 1279 2346 2987
+538 2 2 4 8 991 1934 2304
+539 2 2 4 8 990 2305 1933
+540 2 2 4 8 952 1866 4706
+541 2 2 4 8 923 1981 3592
+542 2 2 4 8 1203 3162 2543
+543 2 2 4 8 1205 3166 2542
+544 2 2 4 8 636 1891 2618
+545 2 2 4 8 1050 2618 1891
+546 2 2 4 8 1159 1665 3932
+547 2 2 4 8 1902 3344 3447
+548 2 2 4 8 603 1785 5114
+549 2 2 4 8 1010 4280 2529
+550 2 2 4 8 600 3377 2565
+551 2 2 4 8 976 1863 2521
+552 2 2 4 8 605 3721 2051
+553 2 2 4 8 658 1841 5118
+554 2 2 4 8 869 5255 3216
+555 2 2 4 8 544 2628 2387
+556 2 2 4 8 449 2306 4759
+557 2 2 4 8 2306 4720 4759
+558 2 2 4 8 472 2479 1898
+559 2 2 4 8 474 1899 2480
+560 2 2 4 8 972 2538 1768
+561 2 2 4 8 974 2539 1769
+562 2 2 4 8 1129 1739 4208
+563 2 2 4 8 676 2750 2065
+564 2 2 4 8 1784 2577 4338
+565 2 2 4 8 879 5225 1893
+566 2 2 4 8 1149 1894 5224
+567 2 2 4 8 877 5223 1892
+568 2 2 4 8 561 2426 1964
+569 2 2 4 8 1354 2486 3729
+570 2 2 4 8 499 3990 2560
+571 2 2 4 8 501 3991 2561
+572 2 2 4 8 1294 3849 4292
+573 2 2 4 8 497 1931 3942
+574 2 2 4 8 2053 3975 3707
+575 2 2 4 8 768 2923 2100
+576 2 2 4 8 769 2099 2922
+577 2 2 4 8 2099 1364 2922
+578 2 2 4 8 2100 2923 1365
+579 2 2 4 8 982 4011 1671
+580 2 2 4 8 983 4012 1672
+581 2 2 4 8 2145 2763 979
+582 2 2 4 8 52 3478 2012
+583 2 2 4 8 273 3479 2013
+584 2 2 4 8 1567 4897 3829
+585 2 2 4 8 671 4149 2706
+586 2 2 4 8 672 4148 2707
+587 2 2 4 8 2211 4270 3399
+588 2 2 4 8 2210 4269 3398
+589 2 2 4 8 2209 3400 4271
+590 2 2 4 8 1723 4155 2644
+591 2 2 4 8 1261 2686 2576
+592 2 2 4 8 1002 2576 2686
+593 2 2 4 8 688 2656 1936
+594 2 2 4 8 1431 2961 3471
+595 2 2 4 8 880 3951 2494
+596 2 2 4 8 881 3950 2495
+597 2 2 4 8 565 2527 1881
+598 2 2 4 8 1881 2527 999
+599 2 2 4 8 585 2933 2514
+600 2 2 4 8 1136 1903 2922
+601 2 2 4 8 769 2922 1903
+602 2 2 4 8 768 1902 2923
+603 2 2 4 8 1137 2923 1902
+604 2 2 4 8 2003 1201 2266
+605 2 2 4 8 2501 3667 3984
+606 2 2 4 8 807 3913 1992
+607 2 2 4 8 1449 1992 3913
+608 2 2 4 8 808 3912 1993
+609 2 2 4 8 1448 1993 3912
+610 2 2 4 8 888 2872 1928
+611 2 2 4 8 611 2503 3219
+612 2 2 4 8 1259 4614 4753
+613 2 2 4 8 1494 3480 3089
+614 2 2 4 8 900 3920 3614
+615 2 2 4 8 914 4919 2416
+616 2 2 4 8 1031 2588 2645
+617 2 2 4 8 1185 2530 2473
+618 2 2 4 8 942 2473 2530
+619 2 2 4 8 469 2878 1954
+620 2 2 4 8 669 2407 3159
+621 2 2 4 8 1380 3159 2407
+622 2 2 4 8 670 2408 3160
+623 2 2 4 8 1381 3160 2408
+624 2 2 4 8 928 4654 1863
+625 2 2 4 8 927 1864 4655
+626 2 2 4 8 674 2751 1798
+627 2 2 4 8 673 2752 1799
+628 2 2 4 8 3065 2297 4116
+629 2 2 4 8 535 3917 1757
+630 2 2 4 8 475 3403 2174
+631 2 2 4 8 444 1839 2507
+632 2 2 4 8 453 1840 2508
+633 2 2 4 8 951 2316 1958
+634 2 2 4 8 1735 3314 3981
+635 2 2 4 8 848 2788 1733
+636 2 2 4 8 867 3740 2410
+637 2 2 4 8 1589 2410 3740
+638 2 2 4 8 458 3228 2517
+639 2 2 4 8 1455 2517 3228
+640 2 2 4 8 469 2073 5020
+641 2 2 4 8 468 5021 2072
+642 2 2 4 8 2745 2238 4511
+643 2 2 4 8 741 2827 3829
+644 2 2 4 8 743 2828 3828
+645 2 2 4 8 1255 3161 2172
+646 2 2 4 8 917 2790 1917
+647 2 2 4 8 1111 1917 2790
+648 2 2 4 8 934 2312 3028
+649 2 2 4 8 935 2313 3027
+650 2 2 4 8 2052 3530 3570
+651 2 2 4 8 767 1873 2542
+652 2 2 4 8 1205 2542 1873
+653 2 2 4 8 766 1872 2543
+654 2 2 4 8 1203 2543 1872
+655 2 2 4 8 777 3567 1741
+656 2 2 4 8 778 3566 1742
+657 2 2 4 8 2392 4061 3416
+658 2 2 4 8 635 3063 2116
+659 2 2 4 8 907 2114 3061
+660 2 2 4 8 908 2115 3062
+661 2 2 4 8 552 3920 2027
+662 2 2 4 8 927 1942 4809
+663 2 2 4 8 832 1943 4808
+664 2 2 4 8 1674 3223 1126
+665 2 2 4 8 832 4808 1945
+666 2 2 4 8 1354 3763 2486
+667 2 2 4 8 1251 1679 3293
+668 2 2 4 8 1232 2354 1925
+669 2 2 4 8 887 1925 2354
+670 2 2 4 8 2825 3840 740
+671 2 2 4 8 742 2826 3841
+672 2 2 4 8 738 2824 3839
+673 2 2 4 8 1173 3231 1856
+674 2 2 4 8 1172 3230 1857
+675 2 2 4 8 835 1687 2899
+676 2 2 4 8 915 2223 4289
+677 2 2 4 8 1285 2950 1677
+678 2 2 4 8 887 2354 1927
+679 2 2 4 8 4206 4702 1455
+680 2 2 4 8 1137 3294 1680
+681 2 2 4 8 1331 4228 2706
+682 2 2 4 8 1170 3447 3344
+683 2 2 4 8 1094 5215 2165
+684 2 2 4 8 1858 2219 4158
+685 2 2 4 8 2543 3162 4145
+686 2 2 4 8 2542 3166 4146
+687 2 2 4 8 559 4910 2316
+688 2 2 4 8 1958 2316 4910
+689 2 2 4 8 952 4706 1959
+690 2 2 4 8 978 2775 2119
+691 2 2 4 8 1274 1740 3776
+692 2 2 4 8 2165 5215 2294
+693 2 2 4 8 778 3092 1907
+694 2 2 4 8 1193 1907 3092
+695 2 2 4 8 777 3091 1908
+696 2 2 4 8 1192 1908 3091
+697 2 2 4 8 2825 740 3789
+698 2 2 4 8 742 3790 2826
+699 2 2 4 8 741 3788 2827
+700 2 2 4 8 762 2019 5168
+701 2 2 4 8 459 2360 1922
+702 2 2 4 8 908 1923 2362
+703 2 2 4 8 907 1924 2361
+704 2 2 4 8 832 2947 1685
+705 2 2 4 8 996 4155 1791
+706 2 2 4 8 467 5152 1848
+707 2 2 4 8 346 2839 1916
+708 2 2 4 8 958 2358 1982
+709 2 2 4 8 625 1982 2358
+710 2 2 4 8 902 5167 2061
+711 2 2 4 8 870 1915 5233
+712 2 2 4 8 830 1683 5053
+713 2 2 4 8 834 1688 5052
+714 2 2 4 8 23 1918 3343
+715 2 2 4 8 498 3625 3471
+716 2 2 4 8 98 2120 97
+717 2 2 4 8 1148 1824 3122
+718 2 2 4 8 1149 1825 3123
+719 2 2 4 8 1147 1823 3121
+720 2 2 4 8 1213 2234 3142
+721 2 2 4 8 1215 2235 3141
+722 2 2 4 8 1217 2236 3140
+723 2 2 4 8 570 1718 2930
+724 2 2 4 8 3513 1913 4407
+725 2 2 4 8 1285 1677 3181
+726 2 2 4 8 1183 2297 3065
+727 2 2 4 8 1013 1740 2980
+728 2 2 4 8 996 2644 4155
+729 2 2 4 8 927 5020 2073
+730 2 2 4 8 928 2072 5021
+731 2 2 4 8 448 2481 1831
+732 2 2 4 8 1092 1764 4344
+733 2 2 4 8 1095 2166 5155
+734 2 2 4 8 1415 3119 2999
+735 2 2 4 8 491 3128 2129
+736 2 2 4 8 898 3748 1940
+737 2 2 4 8 903 4346 4031
+738 2 2 4 8 639 2596 3969
+739 2 2 4 8 218 2290 2647
+740 2 2 4 8 436 2291 2648
+741 2 2 4 8 940 2239 2734
+742 2 2 4 8 925 4560 2047
+743 2 2 4 8 924 2048 4559
+744 2 2 4 8 487 4867 3682
+745 2 2 4 8 1796 4216 3643
+746 2 2 4 8 1207 2022 2292
+747 2 2 4 8 1007 2477 1835
+748 2 2 4 8 607 3530 2052
+749 2 2 4 8 451 1957 2703
+750 2 2 4 8 709 2283 3290
+751 2 2 4 8 2223 2594 4289
+752 2 2 4 8 668 3935 3256
+753 2 2 4 8 191 2275 3338
+754 2 2 4 8 2166 2287 5155
+755 2 2 4 8 626 2331 3143
+756 2 2 4 8 425 2288 3588
+757 2 2 4 8 208 2289 3589
+758 2 2 4 8 219 3590 2290
+759 2 2 4 8 437 3591 2291
+760 2 2 4 8 644 5405 3850
+761 2 2 4 8 1319 3212 1993
+762 2 2 4 8 1320 3213 1992
+763 2 2 4 8 1113 3655 2743
+764 2 2 4 8 97 2120 2692
+765 2 2 4 8 973 4487 4356
+766 2 2 4 8 488 2087 2852
+767 2 2 4 8 2087 1174 2852
+768 2 2 4 8 607 2146 3382
+769 2 2 4 8 690 3541 1937
+770 2 2 4 8 1293 1937 3541
+771 2 2 4 8 1091 1765 4187
+772 2 2 4 8 937 3494 2344
+773 2 2 4 8 936 2343 3493
+774 2 2 4 8 737 4942 2877
+775 2 2 4 8 1425 3664 2485
+776 2 2 4 8 689 2672 1971
+777 2 2 4 8 2019 2575 5168
+778 2 2 4 8 834 3585 1688
+779 2 2 4 8 973 2470 4487
+780 2 2 4 8 308 309 2230
+781 2 2 4 8 298 2229 297
+782 2 2 4 8 175 2228 174
+783 2 2 4 8 130 2227 129
+784 2 2 4 8 118 119 2226
+785 2 2 4 8 835 4073 1687
+786 2 2 4 8 830 3873 1683
+787 2 2 4 8 832 1685 3874
+788 2 2 4 8 2991 3647 4652
+789 2 2 4 8 902 2061 2614
+790 2 2 4 8 2083 4312 639
+791 2 2 4 8 651 2724 2023
+792 2 2 4 8 957 2381 2907
+793 2 2 4 8 1178 1970 2589
+794 2 2 4 8 920 1877 4158
+795 2 2 4 8 927 4655 1942
+796 2 2 4 8 962 4798 2196
+797 2 2 4 8 1104 2352 2325
+798 2 2 4 8 950 2325 2352
+799 2 2 4 8 2262 4629 2669
+800 2 2 4 8 2085 4258 1535
+801 2 2 4 8 1112 1960 2364
+802 2 2 4 8 1050 2729 3719
+803 2 2 4 8 1050 3719 3625
+804 2 2 4 8 2061 5167 5405
+805 2 2 4 8 477 5303 1913
+806 2 2 4 8 1108 2358 2329
+807 2 2 4 8 958 2329 2358
+808 2 2 4 8 975 2569 1864
+809 2 2 4 8 1363 2842 2952
+810 2 2 4 8 1042 2189 5046
+811 2 2 4 8 611 3219 3472
+812 2 2 4 8 659 2794 1775
+813 2 2 4 8 318 4608 1985
+814 2 2 4 8 1216 2327 3335
+815 2 2 4 8 1214 2326 3334
+816 2 2 4 8 1209 1887 3359
+817 2 2 4 8 1208 1888 3358
+818 2 2 4 8 444 2504 1839
+819 2 2 4 8 453 2505 1840
+820 2 2 4 8 1127 2973 3880
+821 2 2 4 8 895 2293 2044
+822 2 2 4 8 473 1949 5388
+823 2 2 4 8 2387 2628 4016
+824 2 2 4 8 465 1889 2430
+825 2 2 4 8 639 1794 4639
+826 2 2 4 8 794 1918 4693
+827 2 2 4 8 994 1748 3807
+828 2 2 4 8 995 1749 3808
+829 2 2 4 8 928 4808 4654
+830 2 2 4 8 1542 4740 3840
+831 2 2 4 8 1543 4741 3841
+832 2 2 4 8 822 4552 2900
+833 2 2 4 8 1118 1831 4868
+834 2 2 4 8 1321 1897 2513
+835 2 2 4 8 557 4706 4781
+836 2 2 4 8 962 2383 4798
+837 2 2 4 8 878 5224 3249
+838 2 2 4 8 1612 3787 3010
+839 2 2 4 8 1257 3445 1786
+840 2 2 4 8 1047 2452 1878
+841 2 2 4 8 162 1735 3631
+842 2 2 4 8 349 1736 3630
+843 2 2 4 8 927 4809 5020
+844 2 2 4 8 978 2212 4948
+845 2 2 4 8 979 2213 4947
+846 2 2 4 8 1013 2730 1740
+847 2 2 4 8 1863 4654 2521
+848 2 2 4 8 1548 3597 2849
+849 2 2 4 8 1804 5126 2065
+850 2 2 4 8 810 2065 5126
+851 2 2 4 8 802 4112 1745
+852 2 2 4 8 1776 4235 2796
+853 2 2 4 8 952 2041 2308
+854 2 2 4 8 753 5136 1722
+855 2 2 4 8 1012 5104 2010
+856 2 2 4 8 656 2796 4235
+857 2 2 4 8 888 3970 2159
+858 2 2 4 8 1557 3461 3007
+859 2 2 4 8 425 426 2288
+860 2 2 4 8 208 3 2289
+861 2 2 4 8 218 219 2290
+862 2 2 4 8 436 437 2291
+863 2 2 4 8 764 4803 4327
+864 2 2 4 8 1099 3940 1743
+865 2 2 4 8 970 4173 4557
+866 2 2 4 8 1149 3123 1894
+867 2 2 4 8 1204 5111 1871
+868 2 2 4 8 925 1948 3480
+869 2 2 4 8 191 192 2275
+870 2 2 4 8 952 1974 5012
+871 2 2 4 8 1558 3087 4262
+872 2 2 4 8 948 1999 2351
+873 2 2 4 8 978 4948 2412
+874 2 2 4 8 979 4947 2411
+875 2 2 4 8 308 2230 4380
+876 2 2 4 8 297 2229 4381
+877 2 2 4 8 175 4382 2228
+878 2 2 4 8 130 4383 2227
+879 2 2 4 8 119 4384 2226
+880 2 2 4 8 923 2233 2786
+881 2 2 4 8 534 1961 2875
+882 2 2 4 8 25 3432 1713
+883 2 2 4 8 1222 1868 3404
+884 2 2 4 8 879 2206 5225
+885 2 2 4 8 1149 5224 2207
+886 2 2 4 8 877 2205 5223
+887 2 2 4 8 1151 1795 3090
+888 2 2 4 8 946 2334 2015
+889 2 2 4 8 923 3592 2179
+890 2 2 4 8 556 2521 4654
+891 2 2 4 8 2336 917 3048
+892 2 2 4 8 2336 3048 1295
+893 2 2 4 8 500 1806 3208
+894 2 2 4 8 2078 1182 2585
+895 2 2 4 8 946 4210 2334
+896 2 2 4 8 2395 3961 3740
+897 2 2 4 8 633 3864 1938
+898 2 2 4 8 634 3865 1939
+899 2 2 4 8 618 2263 2477
+900 2 2 4 8 607 3382 2940
+901 2 2 4 8 761 1782 3766
+902 2 2 4 8 1139 2703 1761
+903 2 2 4 8 603 2413 2234
+904 2 2 4 8 189 190 2159
+905 2 2 4 8 924 4115 1797
+906 2 2 4 8 825 4823 4124
+907 2 2 4 8 1359 3235 4671
+908 2 2 4 8 744 3842 1791
+909 2 2 4 8 1296 1791 3842
+910 2 2 4 8 557 4781 2011
+911 2 2 4 8 1124 1760 3954
+912 2 2 4 8 1125 1839 4846
+913 2 2 4 8 1124 1840 4845
+914 2 2 4 8 31 2179 30
+915 2 2 4 8 1061 2370 3833
+916 2 2 4 8 1585 3833 2370
+917 2 2 4 8 588 2587 1810
+918 2 2 4 8 937 2574 3494
+919 2 2 4 8 936 3493 2573
+920 2 2 4 8 764 1834 2557
+921 2 2 4 8 1062 2371 3221
+922 2 2 4 8 1364 3221 2371
+923 2 2 4 8 1063 3222 2372
+924 2 2 4 8 1365 2372 3222
+925 2 2 4 8 1021 1954 2413
+926 2 2 4 8 573 2668 3323
+927 2 2 4 8 1543 3323 2668
+928 2 2 4 8 500 4165 1806
+929 2 2 4 8 1893 5190 2600
+930 2 2 4 8 1077 2301 2223
+931 2 2 4 8 477 2223 2301
+932 2 2 4 8 1078 2224 2302
+933 2 2 4 8 473 2302 2224
+934 2 2 4 8 497 1808 4171
+935 2 2 4 8 920 4502 1877
+936 2 2 4 8 574 3322 1764
+937 2 2 4 8 947 1765 3323
+938 2 2 4 8 476 3048 1917
+939 2 2 4 8 1132 1876 4406
+940 2 2 4 8 333 334 1987
+941 2 2 4 8 1791 3821 2682
+942 2 2 4 8 959 4507 2041
+943 2 2 4 8 1218 2645 2588
+944 2 2 4 8 875 2834 3133
+945 2 2 4 8 735 2732 3326
+946 2 2 4 8 1566 3326 2732
+947 2 2 4 8 1332 3626 2707
+948 2 2 4 8 799 2326 2051
+949 2 2 4 8 1214 2051 2326
+950 2 2 4 8 800 2327 2052
+951 2 2 4 8 1216 2052 2327
+952 2 2 4 8 1943 4654 4808
+953 2 2 4 8 1259 2992 2652
+954 2 2 4 8 4210 5198 2334
+955 2 2 4 8 693 1738 2792
+956 2 2 4 8 948 4306 4212
+957 2 2 4 8 2417 4657 4453
+958 2 2 4 8 1249 2662 3224
+959 2 2 4 8 913 3526 2278
+960 2 2 4 8 2278 3526 4437
+961 2 2 4 8 615 2264 2498
+962 2 2 4 8 1312 2209 3274
+963 2 2 4 8 507 3274 2209
+964 2 2 4 8 963 3907 2830
+965 2 2 4 8 1104 1768 4007
+966 2 2 4 8 689 1971 3546
+967 2 2 4 8 1290 3546 1971
+968 2 2 4 8 2231 3163 4161
+969 2 2 4 8 757 1786 4006
+970 2 2 4 8 1204 3163 2231
+971 2 2 4 8 706 1885 3272
+972 2 2 4 8 1577 3272 1885
+973 2 2 4 8 707 1886 3273
+974 2 2 4 8 1578 3273 1886
+975 2 2 4 8 980 3381 1713
+976 2 2 4 8 1768 4297 2348
+977 2 2 4 8 1769 4296 2349
+978 2 2 4 8 1582 3274 2019
+979 2 2 4 8 467 3883 2287
+980 2 2 4 8 592 2468 3187
+981 2 2 4 8 863 2599 4269
+982 2 2 4 8 865 4271 2598
+983 2 2 4 8 894 3667 2501
+984 2 2 4 8 1710 3215 4520
+985 2 2 4 8 944 3481 1783
+986 2 2 4 8 1363 3315 3708
+987 2 2 4 8 580 2056 2548
+988 2 2 4 8 318 319 4608
+989 2 2 4 8 1383 2890 3105
+990 2 2 4 8 948 2351 4306
+991 2 2 4 8 934 3028 3720
+992 2 2 4 8 935 3027 3722
+993 2 2 4 8 971 3279 1743
+994 2 2 4 8 1677 4067 2590
+995 2 2 4 8 419 3465 2095
+996 2 2 4 8 759 2417 4453
+997 2 2 4 8 2504 2191 4773
+998 2 2 4 8 2505 2190 4774
+999 2 2 4 8 1399 2918 2784
+1000 2 2 4 8 558 4890 1998
+1001 2 2 4 8 1686 1998 4890
+1002 2 2 4 8 643 2042 2595
+1003 2 2 4 8 1072 2595 2042
+1004 2 2 4 8 1262 2623 2704
+1005 2 2 4 8 1171 2704 2623
+1006 2 2 4 8 1267 2737 1904
+1007 2 2 4 8 952 5012 2041
+1008 2 2 4 8 1104 2325 2309
+1009 2 2 4 8 484 2309 2325
+1010 2 2 4 8 482 2310 2324
+1011 2 2 4 8 1105 2324 2310
+1012 2 2 4 8 3426 5102 2954
+1013 2 2 4 8 2097 2597 1187
+1014 2 2 4 8 1255 2856 2415
+1015 2 2 4 8 1090 2415 2856
+1016 2 2 4 8 1611 3021 3785
+1017 2 2 4 8 1431 4577 1744
+1018 2 2 4 8 1297 3265 2434
+1019 2 2 4 8 1223 4700 3081
+1020 2 2 4 8 570 3134 1718
+1021 2 2 4 8 1708 2835 3560
+1022 2 2 4 8 540 3560 2835
+1023 2 2 4 8 1709 3561 2836
+1024 2 2 4 8 539 2836 3561
+1025 2 2 4 8 946 2015 2464
+1026 2 2 4 8 764 2557 4803
+1027 2 2 4 8 802 1745 4534
+1028 2 2 4 8 2108 3277 1225
+1029 2 2 4 8 1014 1861 2547
+1030 2 2 4 8 2051 3721 4766
+1031 2 2 4 8 970 4557 2469
+1032 2 2 4 8 1146 1717 2993
+1033 2 2 4 8 693 2784 2918
+1034 2 2 4 8 791 1856 4199
+1035 2 2 4 8 790 1857 4198
+1036 2 2 4 8 776 3798 1816
+1037 2 2 4 8 775 3797 1817
+1038 2 2 4 8 779 1820 3800
+1039 2 2 4 8 780 1821 3799
+1040 2 2 4 8 280 2642 2996
+1041 2 2 4 8 263 2995 2641
+1042 2 2 4 8 59 2640 2994
+1043 2 2 4 8 951 1958 4782
+1044 2 2 4 8 952 1959 4783
+1045 2 2 4 8 42 3031 2675
+1046 2 2 4 8 576 1751 4512
+1047 2 2 4 8 466 2165 2294
+1048 2 2 4 8 8 2311 3977
+1049 2 2 4 8 1011 4744 5249
+1050 2 2 4 8 665 3139 2432
+1051 2 2 4 8 1351 2432 3139
+1052 2 2 4 8 2055 3850 5405
+1053 2 2 4 8 25 1713 3938
+1054 2 2 4 8 1014 2711 1861
+1055 2 2 4 8 2108 4163 3277
+1056 2 2 4 8 1846 4875 2476
+1057 2 2 4 8 915 2400 4881
+1058 2 2 4 8 1111 2239 5379
+1059 2 2 4 8 641 2298 2844
+1060 2 2 4 8 803 2180 3423
+1061 2 2 4 8 1342 3423 2180
+1062 2 2 4 8 1341 3422 2181
+1063 2 2 4 8 804 2181 3422
+1064 2 2 4 8 870 5233 2216
+1065 2 2 4 8 965 2829 3996
+1066 2 2 4 8 1849 3759 1295
+1067 2 2 4 8 716 3759 1849
+1068 2 2 4 8 2738 3903 4669
+1069 2 2 4 8 1249 2679 3550
+1070 2 2 4 8 1665 3872 3764
+1071 2 2 4 8 554 2031 2373
+1072 2 2 4 8 556 2374 2032
+1073 2 2 4 8 1277 4598 3357
+1074 2 2 4 8 1877 3168 3750
+1075 2 2 4 8 2679 3564 3550
+1076 2 2 4 8 2239 2331 5379
+1077 2 2 4 8 951 4782 1973
+1078 2 2 4 8 952 4783 1974
+1079 2 2 4 8 2056 1180 2548
+1080 2 2 4 8 498 2698 3625
+1081 2 2 4 8 916 2118 3527
+1082 2 2 4 8 986 2006 2886
+1083 2 2 4 8 1115 2727 2063
+1084 2 2 4 8 796 2063 2727
+1085 2 2 4 8 953 4197 3398
+1086 2 2 4 8 955 4196 3399
+1087 2 2 4 8 1439 2039 4201
+1088 2 2 4 8 1009 2039 3000
+1089 2 2 4 8 17 18 2168
+1090 2 2 4 8 1527 2251 4275
+1091 2 2 4 8 1879 4671 3235
+1092 2 2 4 8 658 5118 2244
+1093 2 2 4 8 2755 3741 4696
+1094 2 2 4 8 1556 2392 3416
+1095 2 2 4 8 555 2036 2380
+1096 2 2 4 8 777 1818 3567
+1097 2 2 4 8 778 1819 3566
+1098 2 2 4 8 1023 1784 4338
+1099 2 2 4 8 487 3003 4867
+1100 2 2 4 8 943 2029 3368
+1101 2 2 4 8 944 2030 3367
+1102 2 2 4 8 773 2571 1867
+1103 2 2 4 8 1236 3478 1951
+1104 2 2 4 8 1237 3479 1952
+1105 2 2 4 8 1146 4160 1717
+1106 2 2 4 8 500 3208 3676
+1107 2 2 4 8 829 2515 5071
+1108 2 2 4 8 1577 1885 4489
+1109 2 2 4 8 1578 1886 4490
+1110 2 2 4 8 473 2329 4311
+1111 2 2 4 8 467 2287 2166
+1112 2 2 4 8 1887 4360 2718
+1113 2 2 4 8 1888 4361 2719
+1114 2 2 4 8 1257 3458 2631
+1115 2 2 4 8 948 2553 1999
+1116 2 2 4 8 975 1864 2578
+1117 2 2 4 8 976 2579 1863
+1118 2 2 4 8 1091 2391 4049
+1119 2 2 4 8 1651 4049 2391
+1120 2 2 4 8 1650 4050 2390
+1121 2 2 4 8 1092 2390 4050
+1122 2 2 4 8 570 2930 1768
+1123 2 2 4 8 473 5388 2302
+1124 2 2 4 8 1270 3754 1884
+1125 2 2 4 8 1937 3847 2615
+1126 2 2 4 8 462 2029 4578
+1127 2 2 4 8 944 4579 2030
+1128 2 2 4 8 627 3782 2352
+1129 2 2 4 8 950 4707 1972
+1130 2 2 4 8 624 5291 1734
+1131 2 2 4 8 2327 3892 3335
+1132 2 2 4 8 2326 3893 3334
+1133 2 2 4 8 895 2590 4067
+1134 2 2 4 8 1172 1914 3230
+1135 2 2 4 8 977 4639 2733
+1136 2 2 4 8 867 3943 2225
+1137 2 2 4 8 552 4277 3920
+1138 2 2 4 8 1485 3743 5072
+1139 2 2 4 8 736 2556 3785
+1140 2 2 4 8 572 3348 1769
+1141 2 2 4 8 2253 2736 3689
+1142 2 2 4 8 2745 4311 2329
+1143 2 2 4 8 666 2064 4345
+1144 2 2 4 8 502 3426 2954
+1145 2 2 4 8 8 3977 7
+1146 2 2 4 8 2287 3883 2924
+1147 2 2 4 8 620 5349 1927
+1148 2 2 4 8 2612 3844 3907
+1149 2 2 4 8 848 1733 4107
+1150 2 2 4 8 942 1734 4016
+1151 2 2 4 8 70 71 2133
+1152 2 2 4 8 4566 5121 3457
+1153 2 2 4 8 2157 2553 3912
+1154 2 2 4 8 675 2545 1897
+1155 2 2 4 8 1587 3749 2525
+1156 2 2 4 8 533 3811 2559
+1157 2 2 4 8 949 1999 2593
+1158 2 2 4 8 1359 4562 3235
+1159 2 2 4 8 485 2733 2265
+1160 2 2 4 8 475 3849 3403
+1161 2 2 4 8 587 3175 3082
+1162 2 2 4 8 582 3174 3083
+1163 2 2 4 8 885 2647 2290
+1164 2 2 4 8 886 2648 2291
+1165 2 2 4 8 1485 5072 2947
+1166 2 2 4 8 443 1754 3644
+1167 2 2 4 8 610 1778 4432
+1168 2 2 4 8 609 4433 1779
+1169 2 2 4 8 1130 2045 2838
+1170 2 2 4 8 787 2838 2045
+1171 2 2 4 8 1966 3216 5255
+1172 2 2 4 8 1270 1884 3768
+1173 2 2 4 8 644 3850 2680
+1174 2 2 4 8 1274 3565 1740
+1175 2 2 4 8 1228 2618 2698
+1176 2 2 4 8 1233 2296 2341
+1177 2 2 4 8 54 2688 5253
+1178 2 2 4 8 275 2689 5254
+1179 2 2 4 8 477 2301 5303
+1180 2 2 4 8 465 5027 2020
+1181 2 2 4 8 603 4392 1785
+1182 2 2 4 8 2364 5138 5089
+1183 2 2 4 8 950 1998 4707
+1184 2 2 4 8 1424 1995 4204
+1185 2 2 4 8 1612 3010 5228
+1186 2 2 4 8 747 4168 2721
+1187 2 2 4 8 517 3844 2612
+1188 2 2 4 8 621 5315 1928
+1189 2 2 4 8 1024 5203 2487
+1190 2 2 4 8 1391 2746 3648
+1191 2 2 4 8 1392 2747 3649
+1192 2 2 4 8 693 2965 1738
+1193 2 2 4 8 476 2903 3386
+1194 2 2 4 8 724 2797 3746
+1195 2 2 4 8 726 2798 3747
+1196 2 2 4 8 560 3206 1965
+1197 2 2 4 8 959 2041 2558
+1198 2 2 4 8 2129 3128 4431
+1199 2 2 4 8 1070 1788 2935
+1200 2 2 4 8 562 3665 2007
+1201 2 2 4 8 1355 1937 5160
+1202 2 2 4 8 1356 5159 1936
+1203 2 2 4 8 2631 3458 4876
+1204 2 2 4 8 1179 2461 2621
+1205 2 2 4 8 493 2621 2461
+1206 2 2 4 8 1586 4941 3156
+1207 2 2 4 8 562 2007 4918
+1208 2 2 4 8 1691 4918 2007
+1209 2 2 4 8 969 2654 2248
+1210 2 2 4 8 970 2469 1982
+1211 2 2 4 8 973 1983 2470
+1212 2 2 4 8 580 2548 2152
+1213 2 2 4 8 610 2811 1778
+1214 2 2 4 8 1026 2812 1779
+1215 2 2 4 8 609 1779 2812
+1216 2 2 4 8 599 2157 3226
+1217 2 2 4 8 2515 1941 5071
+1218 2 2 4 8 1705 4269 2599
+1219 2 2 4 8 1704 2598 4271
+1220 2 2 4 8 925 3905 1727
+1221 2 2 4 8 481 4419 1851
+1222 2 2 4 8 470 1854 4417
+1223 2 2 4 8 755 4332 4636
+1224 2 2 4 8 42 43 3031
+1225 2 2 4 8 2308 2041 4507
+1226 2 2 4 8 924 1726 4159
+1227 2 2 4 8 557 1959 4706
+1228 2 2 4 8 1099 3994 2359
+1229 2 2 4 8 945 2465 2725
+1230 2 2 4 8 2283 3963 3290
+1231 2 2 4 8 1130 1800 2724
+1232 2 2 4 8 1277 2674 4598
+1233 2 2 4 8 1272 2487 2912
+1234 2 2 4 8 628 4042 2308
+1235 2 2 4 8 1003 1970 5040
+1236 2 2 4 8 1011 5249 2401
+1237 2 2 4 8 986 2476 4875
+1238 2 2 4 8 580 2416 2056
+1239 2 2 4 8 902 3396 5167
+1240 2 2 4 8 1743 2355 4229
+1241 2 2 4 8 759 3815 1780
+1242 2 2 4 8 867 2395 3740
+1243 2 2 4 8 1000 2626 1882
+1244 2 2 4 8 568 1882 2626
+1245 2 2 4 8 857 2353 2129
+1246 2 2 4 8 1070 2898 1788
+1247 2 2 4 8 1230 2961 1744
+1248 2 2 4 8 2608 3259 5252
+1249 2 2 4 8 2084 4555 4314
+1250 2 2 4 8 343 344 2138
+1251 2 2 4 8 1213 3142 2769
+1252 2 2 4 8 1215 3141 2770
+1253 2 2 4 8 1217 3140 2771
+1254 2 2 4 8 279 280 2996
+1255 2 2 4 8 263 264 2995
+1256 2 2 4 8 58 59 2994
+1257 2 2 4 8 957 1850 2791
+1258 2 2 4 8 1166 1728 4343
+1259 2 2 4 8 1208 1966 5255
+1260 2 2 4 8 1729 4239 1165
+1261 2 2 4 8 717 2379 3035
+1262 2 2 4 8 1573 2559 3811
+1263 2 2 4 8 543 4159 2522
+1264 2 2 4 8 1822 4650 2473
+1265 2 2 4 8 1250 2023 2451
+1266 2 2 4 8 1260 2616 2617
+1267 2 2 4 8 945 2617 2616
+1268 2 2 4 8 469 3470 2878
+1269 2 2 4 8 662 2682 3821
+1270 2 2 4 8 1662 2191 4449
+1271 2 2 4 8 444 4449 2191
+1272 2 2 4 8 454 1862 4058
+1273 2 2 4 8 610 2160 2829
+1274 2 2 4 8 609 2830 2161
+1275 2 2 4 8 849 2028 3796
+1276 2 2 4 8 922 3507 1935
+1277 2 2 4 8 152 5145 2718
+1278 2 2 4 8 373 5146 2719
+1279 2 2 4 8 169 170 2142
+1280 2 2 4 8 356 357 2141
+1281 2 2 4 8 1267 2978 2737
+1282 2 2 4 8 528 3229 4025
+1283 2 2 4 8 1804 5138 2364
+1284 2 2 4 8 543 2580 4159
+1285 2 2 4 8 1040 1814 2925
+1286 2 2 4 8 1041 1813 2926
+1287 2 2 4 8 821 4070 2909
+1288 2 2 4 8 1071 3007 3461
+1289 2 2 4 8 1049 1890 2596
+1290 2 2 4 8 1937 3108 5160
+1291 2 2 4 8 1936 5159 3107
+1292 2 2 4 8 884 3153 2289
+1293 2 2 4 8 1282 2289 3153
+1294 2 2 4 8 885 2290 3154
+1295 2 2 4 8 1283 3154 2290
+1296 2 2 4 8 1067 1767 3052
+1297 2 2 4 8 1003 4957 4701
+1298 2 2 4 8 954 2058 2418
+1299 2 2 4 8 953 2419 2057
+1300 2 2 4 8 955 2420 2059
+1301 2 2 4 8 807 4778 4795
+1302 2 2 4 8 808 4779 4796
+1303 2 2 4 8 627 2538 2915
+1304 2 2 4 8 569 2630 1883
+1305 2 2 4 8 1001 1883 2630
+1306 2 2 4 8 1249 3550 2662
+1307 2 2 4 8 1594 2662 3550
+1308 2 2 4 8 601 2464 2015
+1309 2 2 4 8 547 3905 2499
+1310 2 2 4 8 1558 4587 3087
+1311 2 2 4 8 805 1887 4405
+1312 2 2 4 8 806 1888 4404
+1313 2 2 4 8 618 2477 4644
+1314 2 2 4 8 1413 2423 3653
+1315 2 2 4 8 1412 2422 3654
+1316 2 2 4 8 2477 4401 4644
+1317 2 2 4 8 592 3187 2969
+1318 2 2 4 8 649 3285 1761
+1319 2 2 4 8 1139 1761 3285
+1320 2 2 4 8 1010 5141 2397
+1321 2 2 4 8 1188 1735 3184
+1322 2 2 4 8 2085 575 4484
+1323 2 2 4 8 1024 3037 1777
+1324 2 2 4 8 879 1893 2600
+1325 2 2 4 8 547 2523 3905
+1326 2 2 4 8 1864 2569 4655
+1327 2 2 4 8 454 4058 1870
+1328 2 2 4 8 1358 3106 1971
+1329 2 2 4 8 4201 2039 5361
+1330 2 2 4 8 467 2303 5152
+1331 2 2 4 8 627 2697 3782
+1332 2 2 4 8 628 4507 1983
+1333 2 2 4 8 984 1963 4762
+1334 2 2 4 8 985 4763 1965
+1335 2 2 4 8 1760 4441 5129
+1336 2 2 4 8 483 2473 4650
+1337 2 2 4 8 2554 3784 5151
+1338 2 2 4 8 685 2822 1865
+1339 2 2 4 8 637 3733 2047
+1340 2 2 4 8 638 2048 3732
+1341 2 2 4 8 755 4636 2550
+1342 2 2 4 8 1575 4303 2541
+1343 2 2 4 8 1576 4304 2540
+1344 2 2 4 8 1129 3262 1739
+1345 2 2 4 8 2053 1369 2792
+1346 2 2 4 8 140 141 2132
+1347 2 2 4 8 362 2131 361
+1348 2 2 4 8 847 5121 4566
+1349 2 2 4 8 1050 2698 2618
+1350 2 2 4 8 1030 4810 3826
+1351 2 2 4 8 454 1870 4613
+1352 2 2 4 8 585 2531 2933
+1353 2 2 4 8 724 3678 2797
+1354 2 2 4 8 628 2475 4042
+1355 2 2 4 8 754 3089 1785
+1356 2 2 4 8 564 2238 4369
+1357 2 2 4 8 554 4655 2569
+1358 2 2 4 8 560 2400 2102
+1359 2 2 4 8 1384 2885 1947
+1360 2 2 4 8 31 3645 2179
+1361 2 2 4 8 2524 3908 4127
+1362 2 2 4 8 777 1741 3091
+1363 2 2 4 8 778 1742 3092
+1364 2 2 4 8 1113 2988 4673
+1365 2 2 4 8 19 20 2208
+1366 2 2 4 8 1010 3490 1790
+1367 2 2 4 8 1099 2881 3994
+1368 2 2 4 8 900 1754 3038
+1369 2 2 4 8 1037 1773 3438
+1370 2 2 4 8 1038 1772 3437
+1371 2 2 4 8 65 66 2112
+1372 2 2 4 8 286 287 2110
+1373 2 2 4 8 256 257 2111
+1374 2 2 4 8 1208 3358 1966
+1375 2 2 4 8 1209 3359 1967
+1376 2 2 4 8 469 5248 2073
+1377 2 2 4 8 784 4008 1823
+1378 2 2 4 8 786 4010 1824
+1379 2 2 4 8 785 4009 1825
+1380 2 2 4 8 1335 2540 3521
+1381 2 2 4 8 1334 2541 3522
+1382 2 2 4 8 460 2567 2361
+1383 2 2 4 8 461 2568 2362
+1384 2 2 4 8 887 2744 1925
+1385 2 2 4 8 1230 1744 4849
+1386 2 2 4 8 1098 2360 2414
+1387 2 2 4 8 459 2414 2360
+1388 2 2 4 8 566 1743 3279
+1389 2 2 4 8 984 4762 1988
+1390 2 2 4 8 985 1990 4763
+1391 2 2 4 8 368 3017 2651
+1392 2 2 4 8 147 3018 2650
+1393 2 2 4 8 385 2649 3016
+1394 2 2 4 8 1700 2730 4202
+1395 2 2 4 8 1204 2231 5111
+1396 2 2 4 8 940 2331 2239
+1397 2 2 4 8 810 5126 1960
+1398 2 2 4 8 625 2849 2610
+1399 2 2 4 8 684 2871 1844
+1400 2 2 4 8 1170 3215 4471
+1401 2 2 4 8 581 2691 2153
+1402 2 2 4 8 576 3158 1751
+1403 2 2 4 8 1113 1751 3158
+1404 2 2 4 8 729 3981 3314
+1405 2 2 4 8 2225 3943 3675
+1406 2 2 4 8 875 2489 2488
+1407 2 2 4 8 1344 2488 2489
+1408 2 2 4 8 1052 5138 4318
+1409 2 2 4 8 990 2864 2305
+1410 2 2 4 8 991 2304 2863
+1411 2 2 4 8 977 2733 2218
+1412 2 2 4 8 1536 3880 2973
+1413 2 2 4 8 737 4014 2910
+1414 2 2 4 8 1145 2920 1770
+1415 2 2 4 8 1144 2919 1771
+1416 2 2 4 8 973 2609 1983
+1417 2 2 4 8 970 1982 2610
+1418 2 2 4 8 768 3372 1752
+1419 2 2 4 8 769 1753 3373
+1420 2 2 4 8 972 1768 2930
+1421 2 2 4 8 557 2118 2406
+1422 2 2 4 8 651 2023 3336
+1423 2 2 4 8 1250 3336 2023
+1424 2 2 4 8 1686 4840 1998
+1425 2 2 4 8 920 4004 4502
+1426 2 2 4 8 496 1750 3176
+1427 2 2 4 8 1016 3741 2755
+1428 2 2 4 8 1026 5120 2438
+1429 2 2 4 8 750 5119 2437
+1430 2 2 4 8 516 2847 2789
+1431 2 2 4 8 920 4158 2219
+1432 2 2 4 8 4103 2523 4645
+1433 2 2 4 8 603 5114 2413
+1434 2 2 4 8 405 3953 2389
+1435 2 2 4 8 1039 4622 1842
+1436 2 2 4 8 692 3094 1829
+1437 2 2 4 8 698 4597 2753
+1438 2 2 4 8 597 1871 2664
+1439 2 2 4 8 664 2182 3238
+1440 2 2 4 8 1121 2316 2333
+1441 2 2 4 8 951 2333 2316
+1442 2 2 4 8 1703 2721 4168
+1443 2 2 4 8 558 4053 2394
+1444 2 2 4 8 1630 2394 4053
+1445 2 2 4 8 1124 4441 1760
+1446 2 2 4 8 2087 873 2433
+1447 2 2 4 8 869 1835 4104
+1448 2 2 4 8 1067 3350 1767
+1449 2 2 4 8 685 1845 2977
+1450 2 2 4 8 1046 2796 1803
+1451 2 2 4 8 2054 1286 3501
+1452 2 2 4 8 495 2054 3501
+1453 2 2 4 8 866 2485 3664
+1454 2 2 4 8 595 2028 2516
+1455 2 2 4 8 649 1761 3103
+1456 2 2 4 8 898 4084 3748
+1457 2 2 4 8 642 1766 4659
+1458 2 2 4 8 404 405 2389
+1459 2 2 4 8 451 2532 2058
+1460 2 2 4 8 1031 2058 2532
+1461 2 2 4 8 1222 4395 1868
+1462 2 2 4 8 2118 4964 3527
+1463 2 2 4 8 506 4442 4376
+1464 2 2 4 8 1866 4781 4706
+1465 2 2 4 8 636 2563 3662
+1466 2 2 4 8 1794 2733 4639
+1467 2 2 4 8 987 1991 4683
+1468 2 2 4 8 986 1989 4684
+1469 2 2 4 8 1021 3480 1948
+1470 2 2 4 8 872 2010 5104
+1471 2 2 4 8 739 3010 3787
+1472 2 2 4 8 1030 2526 4810
+1473 2 2 4 8 599 1999 2553
+1474 2 2 4 8 1047 2795 1811
+1475 2 2 4 8 561 1964 4859
+1476 2 2 4 8 724 4501 2484
+1477 2 2 4 8 472 2276 2479
+1478 2 2 4 8 474 2480 2277
+1479 2 2 4 8 794 1766 3040
+1480 2 2 4 8 977 2218 2982
+1481 2 2 4 8 1212 2982 2218
+1482 2 2 4 8 599 3226 2330
+1483 2 2 4 8 1101 3035 2912
+1484 2 2 4 8 908 2972 1923
+1485 2 2 4 8 953 2602 4197
+1486 2 2 4 8 955 2604 4196
+1487 2 2 4 8 907 2971 1924
+1488 2 2 4 8 772 3995 2040
+1489 2 2 4 8 1424 2040 3995
+1490 2 2 4 8 581 2192 2691
+1491 2 2 4 8 1750 3911 2699
+1492 2 2 4 8 906 2963 1922
+1493 2 2 4 8 1042 1826 4349
+1494 2 2 4 8 1870 4926 5364
+1495 2 2 4 8 687 1847 3227
+1496 2 2 4 8 1869 4953 3346
+1497 2 2 4 8 355 2025 4223
+1498 2 2 4 8 168 2026 4224
+1499 2 2 4 8 1296 3821 1791
+1500 2 2 4 8 2252 2663 3769
+1501 2 2 4 8 987 4683 2007
+1502 2 2 4 8 986 4684 2006
+1503 2 2 4 8 2064 3624 4345
+1504 2 2 4 8 734 2555 4500
+1505 2 2 4 8 736 4499 2556
+1506 2 2 4 8 2105 1003 5040
+1507 2 2 4 8 635 3679 3063
+1508 2 2 4 8 652 2433 3777
+1509 2 2 4 8 1003 3791 3728
+1510 2 2 4 8 916 5016 2118
+1511 2 2 4 8 84 85 2600
+1512 2 2 4 8 534 2875 5402
+1513 2 2 4 8 288 3245 3440
+1514 2 2 4 8 1323 2789 2847
+1515 2 2 4 8 920 4965 3634
+1516 2 2 4 8 564 4369 2469
+1517 2 2 4 8 445 2570 2589
+1518 2 2 4 8 1178 2589 2570
+1519 2 2 4 8 1486 3283 2665
+1520 2 2 4 8 1198 2665 3283
+1521 2 2 4 8 1075 3647 2991
+1522 2 2 4 8 1765 4190 2368
+1523 2 2 4 8 1764 4189 2369
+1524 2 2 4 8 704 1879 4812
+1525 2 2 4 8 1083 2667 2126
+1526 2 2 4 8 1084 2668 2124
+1527 2 2 4 8 1167 3064 1874
+1528 2 2 4 8 2571 4731 4952
+1529 2 2 4 8 2089 4600 795
+1530 2 2 4 8 2089 1626 4600
+1531 2 2 4 8 658 3914 1841
+1532 2 2 4 8 488 2852 1800
+1533 2 2 4 8 946 1764 3322
+1534 2 2 4 8 573 3323 1765
+1535 2 2 4 8 1391 2560 2746
+1536 2 2 4 8 1392 2561 2747
+1537 2 2 4 8 608 2908 1855
+1538 2 2 4 8 1337 1862 2806
+1539 2 2 4 8 1580 2637 3060
+1540 2 2 4 8 1103 3060 2637
+1541 2 2 4 8 1868 4302 3404
+1542 2 2 4 8 571 4261 2134
+1543 2 2 4 8 1210 2943 2204
+1544 2 2 4 8 967 4449 2246
+1545 2 2 4 8 453 2247 4450
+1546 2 2 4 8 2084 4314 840
+1547 2 2 4 8 1236 1951 2817
+1548 2 2 4 8 843 2817 1951
+1549 2 2 4 8 844 2818 1952
+1550 2 2 4 8 1237 1952 2818
+1551 2 2 4 8 717 3035 2760
+1552 2 2 4 8 874 2341 2296
+1553 2 2 4 8 482 3182 2310
+1554 2 2 4 8 484 3183 2309
+1555 2 2 4 8 1931 4701 4957
+1556 2 2 4 8 2522 4031 5122
+1557 2 2 4 8 1752 2455 3344
+1558 2 2 4 8 1753 3345 2456
+1559 2 2 4 8 743 4094 2828
+1560 2 2 4 8 738 4095 2824
+1561 2 2 4 8 577 2269 2982
+1562 2 2 4 8 773 4731 2571
+1563 2 2 4 8 645 1884 3754
+1564 2 2 4 8 580 2175 2416
+1565 2 2 4 8 320 1787 4608
+1566 2 2 4 8 1066 2204 2471
+1567 2 2 4 8 568 2471 2204
+1568 2 2 4 8 486 1969 2614
+1569 2 2 4 8 2105 4957 1003
+1570 2 2 4 8 964 2908 2453
+1571 2 2 4 8 899 5230 3148
+1572 2 2 4 8 442 2201 4475
+1573 2 2 4 8 450 2199 4473
+1574 2 2 4 8 1073 2680 1896
+1575 2 2 4 8 770 3890 2195
+1576 2 2 4 8 1478 2195 3890
+1577 2 2 4 8 394 4208 3466
+1578 2 2 4 8 1120 3352 2985
+1579 2 2 4 8 1119 3351 2984
+1580 2 2 4 8 1032 5348 2057
+1581 2 2 4 8 1033 5347 2059
+1582 2 2 4 8 761 3766 4001
+1583 2 2 4 8 1024 1935 4806
+1584 2 2 4 8 462 4578 5286
+1585 2 2 4 8 708 2586 2392
+1586 2 2 4 8 957 2907 4026
+1587 2 2 4 8 789 1916 4185
+1588 2 2 4 8 575 2351 4484
+1589 2 2 4 8 470 4417 1988
+1590 2 2 4 8 480 1989 4420
+1591 2 2 4 8 481 1991 4419
+1592 2 2 4 8 479 1990 4418
+1593 2 2 4 8 748 1777 3037
+1594 2 2 4 8 886 3126 2187
+1595 2 2 4 8 1951 5253 2688
+1596 2 2 4 8 1952 5254 2689
+1597 2 2 4 8 636 3662 2787
+1598 2 2 4 8 867 2225 2395
+1599 2 2 4 8 1049 1865 2822
+1600 2 2 4 8 919 3908 2524
+1601 2 2 4 8 1072 1994 2595
+1602 2 2 4 8 1703 3406 3198
+1603 2 2 4 8 563 4958 2279
+1604 2 2 4 8 1226 2575 2019
+1605 2 2 4 8 218 2647 217
+1606 2 2 4 8 435 436 2648
+1607 2 2 4 8 773 3939 2163
+1608 2 2 4 8 506 2002 4442
+1609 2 2 4 8 1691 2007 4850
+1610 2 2 4 8 1695 4815 3331
+1611 2 2 4 8 640 3499 2299
+1612 2 2 4 8 2279 4958 4919
+1613 2 2 4 8 2086 639 4639
+1614 2 2 4 8 1298 3889 3686
+1615 2 2 4 8 599 2593 1999
+1616 2 2 4 8 1589 3043 2410
+1617 2 2 4 8 1617 3081 4700
+1618 2 2 4 8 560 4843 3206
+1619 2 2 4 8 628 1983 2609
+1620 2 2 4 8 903 4031 2522
+1621 2 2 4 8 625 2610 1982
+1622 2 2 4 8 1220 3343 1918
+1623 2 2 4 8 2088 872 5104
+1624 2 2 4 8 1105 1769 4341
+1625 2 2 4 8 1451 2026 4452
+1626 2 2 4 8 1450 2025 4451
+1627 2 2 4 8 510 3903 2738
+1628 2 2 4 8 621 4460 1930
+1629 2 2 4 8 1017 2836 2683
+1630 2 2 4 8 1018 2684 2835
+1631 2 2 4 8 339 340 2347
+1632 2 2 4 8 2201 4390 4475
+1633 2 2 4 8 2199 4389 4473
+1634 2 2 4 8 851 2690 1932
+1635 2 2 4 8 1003 2396 3791
+1636 2 2 4 8 736 3785 3021
+1637 2 2 4 8 1771 2701 4581
+1638 2 2 4 8 1770 2700 4580
+1639 2 2 4 8 772 3768 1884
+1640 2 2 4 8 595 2516 2187
+1641 2 2 4 8 1064 2187 2516
+1642 2 2 4 8 659 1775 3488
+1643 2 2 4 8 687 2791 1850
+1644 2 2 4 8 905 3104 3851
+1645 2 2 4 8 761 3571 1782
+1646 2 2 4 8 1944 5020 4809
+1647 2 2 4 8 1306 5252 3259
+1648 2 2 4 8 862 4353 1898
+1649 2 2 4 8 861 1899 4352
+1650 2 2 4 8 953 2057 2906
+1651 2 2 4 8 955 2059 2905
+1652 2 2 4 8 954 2904 2058
+1653 2 2 4 8 677 2493 3611
+1654 2 2 4 8 1201 3198 3406
+1655 2 2 4 8 586 1812 4549
+1656 2 2 4 8 1870 5364 2452
+1657 2 2 4 8 998 3820 2054
+1658 2 2 4 8 974 1769 3348
+1659 2 2 4 8 553 4064 4065
+1660 2 2 4 8 553 4065 2388
+1661 2 2 4 8 660 2768 3999
+1662 2 2 4 8 862 4478 3201
+1663 2 2 4 8 1835 5390 2457
+1664 2 2 4 8 207 2376 206
+1665 2 2 4 8 423 424 2375
+1666 2 2 4 8 220 221 2377
+1667 2 2 4 8 438 439 2378
+1668 2 2 4 8 1611 5241 3021
+1669 2 2 4 8 368 369 3017
+1670 2 2 4 8 148 3018 147
+1671 2 2 4 8 384 385 3016
+1672 2 2 4 8 608 2356 2497
+1673 2 2 4 8 1739 3466 4208
+1674 2 2 4 8 976 4102 3503
+1675 2 2 4 8 1021 1948 4524
+1676 2 2 4 8 458 4204 1995
+1677 2 2 4 8 639 3281 2596
+1678 2 2 4 8 733 3877 2880
+1679 2 2 4 8 2433 3609 3777
+1680 2 2 4 8 620 2382 5349
+1681 2 2 4 8 2035 4396 2545
+1682 2 2 4 8 139 3448 3242
+1683 2 2 4 8 776 1816 3694
+1684 2 2 4 8 775 1817 3693
+1685 2 2 4 8 777 3695 1818
+1686 2 2 4 8 778 3696 1819
+1687 2 2 4 8 779 3697 1820
+1688 2 2 4 8 780 3698 1821
+1689 2 2 4 8 887 1927 4409
+1690 2 2 4 8 2492 1766 4746
+1691 2 2 4 8 883 2184 4034
+1692 2 2 4 8 2298 4076 2844
+1693 2 2 4 8 1208 5255 2263
+1694 2 2 4 8 911 2374 4880
+1695 2 2 4 8 494 2756 2398
+1696 2 2 4 8 1184 2398 2756
+1697 2 2 4 8 1021 4524 1954
+1698 2 2 4 8 1210 4813 1843
+1699 2 2 4 8 1013 4202 2730
+1700 2 2 4 8 1009 3000 2346
+1701 2 2 4 8 446 3034 2268
+1702 2 2 4 8 1340 3764 3872
+1703 2 2 4 8 735 5151 3784
+1704 2 2 4 8 533 2788 2462
+1705 2 2 4 8 483 2558 5012
+1706 2 2 4 8 2041 5012 2558
+1707 2 2 4 8 417 3311 1953
+1708 2 2 4 8 642 2024 2592
+1709 2 2 4 8 837 3068 2056
+1710 2 2 4 8 2056 3068 1180
+1711 2 2 4 8 761 2108 4938
+1712 2 2 4 8 1376 2632 2502
+1713 2 2 4 8 1037 2169 2494
+1714 2 2 4 8 1038 2170 2495
+1715 2 2 4 8 1318 1946 5002
+1716 2 2 4 8 1919 2962 4595
+1717 2 2 4 8 975 3070 1950
+1718 2 2 4 8 2107 2787 1116
+1719 2 2 4 8 2107 636 2787
+1720 2 2 4 8 657 2795 1878
+1721 2 2 4 8 1047 1878 2795
+1722 2 2 4 8 474 2820 1899
+1723 2 2 4 8 472 1898 2819
+1724 2 2 4 8 562 4851 3665
+1725 2 2 4 8 956 3642 3606
+1726 2 2 4 8 788 3315 2405
+1727 2 2 4 8 1363 2405 3315
+1728 2 2 4 8 2085 4106 1131
+1729 2 2 4 8 1520 2902 2180
+1730 2 2 4 8 1521 2901 2181
+1731 2 2 4 8 850 3238 2182
+1732 2 2 4 8 1427 3671 2803
+1733 2 2 4 8 469 1954 4524
+1734 2 2 4 8 1818 5258 2348
+1735 2 2 4 8 1819 5259 2349
+1736 2 2 4 8 561 2232 2426
+1737 2 2 4 8 682 1904 2737
+1738 2 2 4 8 332 2793 3120
+1739 2 2 4 8 1850 2847 1387
+1740 2 2 4 8 768 3344 1902
+1741 2 2 4 8 769 1903 3345
+1742 2 2 4 8 1288 3009 3019
+1743 2 2 4 8 1512 3019 3009
+1744 2 2 4 8 1307 2259 2633
+1745 2 2 4 8 842 2633 2259
+1746 2 2 4 8 1831 2481 4868
+1747 2 2 4 8 907 3061 3615
+1748 2 2 4 8 624 2582 2420
+1749 2 2 4 8 453 4450 5143
+1750 2 2 4 8 475 4961 1962
+1751 2 2 4 8 621 2363 5315
+1752 2 2 4 8 1211 2203 2720
+1753 2 2 4 8 2062 5402 2875
+1754 2 2 4 8 18 3816 2168
+1755 2 2 4 8 608 3178 2453
+1756 2 2 4 8 214 215 2925
+1757 2 2 4 8 432 433 2926
+1758 2 2 4 8 908 3062 3600
+1759 2 2 4 8 1385 1865 2846
+1760 2 2 4 8 1148 3266 1824
+1761 2 2 4 8 786 1824 3266
+1762 2 2 4 8 1149 3267 1825
+1763 2 2 4 8 785 1825 3267
+1764 2 2 4 8 2118 5016 2406
+1765 2 2 4 8 586 2255 5072
+1766 2 2 4 8 1004 1955 4113
+1767 2 2 4 8 1005 1956 4114
+1768 2 2 4 8 802 1957 4112
+1769 2 2 4 8 1560 2985 3352
+1770 2 2 4 8 1559 2984 3351
+1771 2 2 4 8 1265 1950 3644
+1772 2 2 4 8 443 3644 1950
+1773 2 2 4 8 1964 3444 4859
+1774 2 2 4 8 1532 2027 3197
+1775 2 2 4 8 2655 3996 3846
+1776 2 2 4 8 2657 3997 3845
+1777 2 2 4 8 1181 2192 3069
+1778 2 2 4 8 482 2449 3182
+1779 2 2 4 8 484 2450 3183
+1780 2 2 4 8 2494 2169 5414
+1781 2 2 4 8 2495 2170 5415
+1782 2 2 4 8 1394 2634 3990
+1783 2 2 4 8 1395 2635 3991
+1784 2 2 4 8 455 5177 1890
+1785 2 2 4 8 159 2766 5087
+1786 2 2 4 8 380 2767 5088
+1787 2 2 4 8 1032 2201 5348
+1788 2 2 4 8 1033 2199 5347
+1789 2 2 4 8 1031 2200 2588
+1790 2 2 4 8 880 2494 5414
+1791 2 2 4 8 881 2495 5415
+1792 2 2 4 8 444 2507 2246
+1793 2 2 4 8 453 2508 2247
+1794 2 2 4 8 1546 4595 2962
+1795 2 2 4 8 1887 2718 5145
+1796 2 2 4 8 1888 2719 5146
+1797 2 2 4 8 904 2002 5083
+1798 2 2 4 8 903 5082 2001
+1799 2 2 4 8 1068 2692 2120
+1800 2 2 4 8 989 2068 4264
+1801 2 2 4 8 990 2066 4265
+1802 2 2 4 8 991 4266 2067
+1803 2 2 4 8 992 4267 2069
+1804 2 2 4 8 865 3819 2209
+1805 2 2 4 8 1256 3543 2666
+1806 2 2 4 8 1554 2666 3543
+1807 2 2 4 8 498 3471 2961
+1808 2 2 4 8 791 4090 1856
+1809 2 2 4 8 790 4089 1857
+1810 2 2 4 8 665 2233 3635
+1811 2 2 4 8 2335 5062 4864
+1812 2 2 4 8 885 3627 2647
+1813 2 2 4 8 590 2634 2004
+1814 2 2 4 8 591 2635 2005
+1815 2 2 4 8 6 3977 2069
+1816 2 2 4 8 608 2497 3178
+1817 2 2 4 8 745 3827 2465
+1818 2 2 4 8 1554 2465 3827
+1819 2 2 4 8 477 2109 2594
+1820 2 2 4 8 538 3239 2078
+1821 2 2 4 8 671 4228 2150
+1822 2 2 4 8 1096 2361 2567
+1823 2 2 4 8 1097 2362 2568
+1824 2 2 4 8 447 3286 2502
+1825 2 2 4 8 1376 2502 3286
+1826 2 2 4 8 1376 3656 2632
+1827 2 2 4 8 1696 4989 2414
+1828 2 2 4 8 1979 5167 3396
+1829 2 2 4 8 1690 2416 4919
+1830 2 2 4 8 1817 2355 5257
+1831 2 2 4 8 466 1935 2816
+1832 2 2 4 8 1181 5407 2192
+1833 2 2 4 8 480 4420 4676
+1834 2 2 4 8 479 4418 4677
+1835 2 2 4 8 1499 3894 4497
+1836 2 2 4 8 1503 4387 3161
+1837 2 2 4 8 1426 3691 2804
+1838 2 2 4 8 1567 1921 4355
+1839 2 2 4 8 1308 2639 2168
+1840 2 2 4 8 658 1912 3914
+1841 2 2 4 8 1337 4083 1862
+1842 2 2 4 8 957 4026 1850
+1843 2 2 4 8 1102 5183 2028
+1844 2 2 4 8 677 3611 4099
+1845 2 2 4 8 868 2726 2074
+1846 2 2 4 8 2124 2668 5261
+1847 2 2 4 8 2126 2667 5260
+1848 2 2 4 8 2255 4880 5072
+1849 2 2 4 8 1023 2765 3947
+1850 2 2 4 8 320 3225 1787
+1851 2 2 4 8 1182 3101 4018
+1852 2 2 4 8 1641 4552 3735
+1853 2 2 4 8 2106 993 2992
+1854 2 2 4 8 654 2293 2950
+1855 2 2 4 8 1259 2652 2678
+1856 2 2 4 8 647 2678 2652
+1857 2 2 4 8 706 3011 1885
+1858 2 2 4 8 707 3012 1886
+1859 2 2 4 8 877 2012 5340
+1860 2 2 4 8 878 2013 5341
+1861 2 2 4 8 419 420 3465
+1862 2 2 4 8 813 2624 2194
+1863 2 2 4 8 941 4781 2475
+1864 2 2 4 8 1866 2475 4781
+1865 2 2 4 8 10 3041 2155
+1866 2 2 4 8 1686 2137 4840
+1867 2 2 4 8 833 4840 2137
+1868 2 2 4 8 1031 5026 2058
+1869 2 2 4 8 1032 2057 5024
+1870 2 2 4 8 1033 2059 5025
+1871 2 2 4 8 189 2159 3970
+1872 2 2 4 8 1066 2471 2929
+1873 2 2 4 8 716 1849 4248
+1874 2 2 4 8 850 2254 3238
+1875 2 2 4 8 645 2952 1884
+1876 2 2 4 8 1082 1884 2952
+1877 2 2 4 8 1881 2813 1057
+1878 2 2 4 8 1058 2814 1882
+1879 2 2 4 8 1059 1883 2815
+1880 2 2 4 8 773 2163 3651
+1881 2 2 4 8 1836 2409 4841
+1882 2 2 4 8 870 4841 2409
+1883 2 2 4 8 1407 3139 3635
+1884 2 2 4 8 692 1829 2964
+1885 2 2 4 8 1085 2731 2125
+1886 2 2 4 8 925 3480 2499
+1887 2 2 4 8 949 4484 1999
+1888 2 2 4 8 2061 1123 4842
+1889 2 2 4 8 246 247 2250
+1890 2 2 4 8 251 252 2249
+1891 2 2 4 8 1624 3810 3930
+1892 2 2 4 8 663 2729 2671
+1893 2 2 4 8 1247 2671 2729
+1894 2 2 4 8 540 3170 3200
+1895 2 2 4 8 1671 3200 3170
+1896 2 2 4 8 1670 3169 3201
+1897 2 2 4 8 539 3201 3169
+1898 2 2 4 8 1338 2472 2791
+1899 2 2 4 8 931 1817 3797
+1900 2 2 4 8 930 1816 3798
+1901 2 2 4 8 934 3800 1820
+1902 2 2 4 8 935 3799 1821
+1903 2 2 4 8 2504 4846 1839
+1904 2 2 4 8 2505 4845 1840
+1905 2 2 4 8 1076 2552 2255
+1906 2 2 4 8 911 2255 2552
+1907 2 2 4 8 1516 4314 4555
+1908 2 2 4 8 1691 4850 2136
+1909 2 2 4 8 838 2136 4850
+1910 2 2 4 8 464 5360 2135
+1911 2 2 4 8 628 2308 4507
+1912 2 2 4 8 1187 4030 3185
+1913 2 2 4 8 1152 5041 4386
+1914 2 2 4 8 967 2154 3743
+1915 2 2 4 8 909 2335 4864
+1916 2 2 4 8 1176 5015 1916
+1917 2 2 4 8 451 3354 1957
+1918 2 2 4 8 196 197 2623
+1919 2 2 4 8 1009 3312 2039
+1920 2 2 4 8 455 1890 2821
+1921 2 2 4 8 1049 2821 1890
+1922 2 2 4 8 655 2395 3224
+1923 2 2 4 8 894 2501 2500
+1924 2 2 4 8 1336 2500 2501
+1925 2 2 4 8 943 3368 2509
+1926 2 2 4 8 944 3367 2510
+1927 2 2 4 8 476 1917 2881
+1928 2 2 4 8 1581 3676 3208
+1929 2 2 4 8 640 2520 3499
+1930 2 2 4 8 825 4158 1877
+1931 2 2 4 8 1287 1947 2885
+1932 2 2 4 8 1752 3372 2945
+1933 2 2 4 8 1753 2946 3373
+1934 2 2 4 8 1016 2025 3298
+1935 2 2 4 8 1015 2026 3299
+1936 2 2 4 8 864 2211 3738
+1937 2 2 4 8 863 2210 3737
+1938 2 2 4 8 70 2133 3131
+1939 2 2 4 8 212 2261 4024
+1940 2 2 4 8 430 2260 4023
+1941 2 2 4 8 494 2167 2681
+1942 2 2 4 8 845 3749 2619
+1943 2 2 4 8 1587 2619 3749
+1944 2 2 4 8 2145 3280 696
+1945 2 2 4 8 196 2623 3452
+1946 2 2 4 8 1876 2696 4406
+1947 2 2 4 8 703 3259 2608
+1948 2 2 4 8 450 4473 3355
+1949 2 2 4 8 442 4475 3356
+1950 2 2 4 8 2214 4518 3621
+1951 2 2 4 8 2215 4519 3622
+1952 2 2 4 8 1389 2657 3340
+1953 2 2 4 8 518 2655 3846
+1954 2 2 4 8 1186 2014 3411
+1955 2 2 4 8 787 2075 2838
+1956 2 2 4 8 520 2657 3845
+1957 2 2 4 8 1955 3355 4473
+1958 2 2 4 8 1956 3356 4475
+1959 2 2 4 8 971 3608 2144
+1960 2 2 4 8 956 3606 4977
+1961 2 2 4 8 944 4399 3481
+1962 2 2 4 8 1463 3785 2556
+1963 2 2 4 8 1461 3784 2554
+1964 2 2 4 8 571 2470 4261
+1965 2 2 4 8 942 3974 1822
+1966 2 2 4 8 639 3072 3281
+1967 2 2 4 8 968 2152 2548
+1968 2 2 4 8 2027 4290 3197
+1969 2 2 4 8 949 2399 4106
+1970 2 2 4 8 1936 2656 3848
+1971 2 2 4 8 829 2240 3686
+1972 2 2 4 8 1697 4236 2666
+1973 2 2 4 8 1281 3187 2375
+1974 2 2 4 8 989 2375 3187
+1975 2 2 4 8 1894 3249 5224
+1976 2 2 4 8 1579 3889 2799
+1977 2 2 4 8 188 1926 3332
+1978 2 2 4 8 1409 2804 3637
+1979 2 2 4 8 1410 2803 3638
+1980 2 2 4 8 1147 3751 1823
+1981 2 2 4 8 1151 3364 1795
+1982 2 2 4 8 2192 5407 2691
+1983 2 2 4 8 2510 4506 4399
+1984 2 2 4 8 1130 3512 1800
+1985 2 2 4 8 657 3492 2813
+1986 2 2 4 8 1821 5260 2369
+1987 2 2 4 8 1820 5261 2368
+1988 2 2 4 8 1291 3978 2534
+1989 2 2 4 8 911 2552 2166
+1990 2 2 4 8 1262 2704 4085
+1991 2 2 4 8 3040 1766 3716
+1992 2 2 4 8 674 1798 3213
+1993 2 2 4 8 673 1799 3212
+1994 2 2 4 8 1689 4881 2400
+1995 2 2 4 8 397 2590 4921
+1996 2 2 4 8 467 1848 3883
+1997 2 2 4 8 2202 3948 3776
+1998 2 2 4 8 1601 4501 3746
+1999 2 2 4 8 1938 3864 2817
+2000 2 2 4 8 1939 3865 2818
+2001 2 2 4 8 573 5261 2668
+2002 2 2 4 8 574 5260 2667
+2003 2 2 4 8 1399 2784 1961
+2004 2 2 4 8 1736 3185 4030
+2005 2 2 4 8 202 203 3129
+2006 2 2 4 8 224 225 3130
+2007 2 2 4 8 991 3130 1934
+2008 2 2 4 8 990 1933 3129
+2009 2 2 4 8 1247 4443 4697
+2010 2 2 4 8 488 1800 3512
+2011 2 2 4 8 1526 4380 2230
+2012 2 2 4 8 1525 4381 2229
+2013 2 2 4 8 1524 2228 4382
+2014 2 2 4 8 1523 2227 4383
+2015 2 2 4 8 1522 2226 4384
+2016 2 2 4 8 684 1844 3857
+2017 2 2 4 8 685 3859 1845
+2018 2 2 4 8 686 3858 1846
+2019 2 2 4 8 687 3860 1847
+2020 2 2 4 8 904 2523 4103
+2021 2 2 4 8 1168 2737 2978
+2022 2 2 4 8 1472 4652 3647
+2023 2 2 4 8 1042 3395 2221
+2024 2 2 4 8 657 3553 2243
+2025 2 2 4 8 658 2244 3554
+2026 2 2 4 8 659 3555 2245
+2027 2 2 4 8 1045 2246 2507
+2028 2 2 4 8 1046 2247 2508
+2029 2 2 4 8 1143 2479 2276
+2030 2 2 4 8 1144 2277 2480
+2031 2 2 4 8 1666 3655 4985
+2032 2 2 4 8 1262 4085 3199
+2033 2 2 4 8 625 4653 2849
+2034 2 2 4 8 944 2510 4399
+2035 2 2 4 8 2145 3292 2763
+2036 2 2 4 8 861 2919 2480
+2037 2 2 4 8 998 2221 3820
+2038 2 2 4 8 998 3937 2189
+2039 2 2 4 8 1833 4376 4442
+2040 2 2 4 8 1960 5126 2364
+2041 2 2 4 8 188 3970 1926
+2042 2 2 4 8 2109 1106 2594
+2043 2 2 4 8 1009 3157 2258
+2044 2 2 4 8 1428 2160 4610
+2045 2 2 4 8 1429 4609 2161
+2046 2 2 4 8 1674 3646 2584
+2047 2 2 4 8 986 2886 2476
+2048 2 2 4 8 840 4314 2023
+2049 2 2 4 8 1134 4650 1822
+2050 2 2 4 8 565 3575 2876
+2051 2 2 4 8 1647 2876 3575
+2052 2 2 4 8 1695 3331 5314
+2053 2 2 4 8 998 2054 3607
+2054 2 2 4 8 477 2594 2223
+2055 2 2 4 8 659 3488 2815
+2056 2 2 4 8 552 2027 4505
+2057 2 2 4 8 1532 4505 2027
+2058 2 2 4 8 667 2993 2488
+2059 2 2 4 8 1239 2214 3621
+2060 2 2 4 8 1242 2215 3622
+2061 2 2 4 8 1060 2000 4678
+2062 2 2 4 8 1024 2816 1935
+2063 2 2 4 8 1694 4018 3101
+2064 2 2 4 8 456 1919 5394
+2065 2 2 4 8 733 2880 4194
+2066 2 2 4 8 1041 3172 1813
+2067 2 2 4 8 1040 3173 1814
+2068 2 2 4 8 250 1968 4169
+2069 2 2 4 8 843 1938 2817
+2070 2 2 4 8 844 1939 2818
+2071 2 2 4 8 1081 2681 2167
+2072 2 2 4 8 588 1810 3736
+2073 2 2 4 8 1004 4113 4243
+2074 2 2 4 8 1005 4114 4245
+2075 2 2 4 8 1037 3438 1885
+2076 2 2 4 8 1038 3437 1886
+2077 2 2 4 8 1134 1822 4410
+2078 2 2 4 8 1850 4026 2847
+2079 2 2 4 8 527 2973 2492
+2080 2 2 4 8 454 3964 1862
+2081 2 2 4 8 839 3420 1807
+2082 2 2 4 8 2020 3936 2529
+2083 2 2 4 8 705 2603 4282
+2084 2 2 4 8 976 2570 4102
+2085 2 2 4 8 1255 2415 2845
+2086 2 2 4 8 646 2241 2739
+2087 2 2 4 8 1007 4945 2281
+2088 2 2 4 8 1008 4946 2282
+2089 2 2 4 8 1042 2040 5310
+2090 2 2 4 8 1023 4338 2050
+2091 2 2 4 8 570 2348 5258
+2092 2 2 4 8 572 2349 5259
+2093 2 2 4 8 2847 4026 1323
+2094 2 2 4 8 644 2680 3374
+2095 2 2 4 8 677 2780 2493
+2096 2 2 4 8 1199 2493 2780
+2097 2 2 4 8 1779 3305 5120
+2098 2 2 4 8 2617 4895 4322
+2099 2 2 4 8 747 3262 1810
+2100 2 2 4 8 2281 4945 3965
+2101 2 2 4 8 2282 4946 3966
+2102 2 2 4 8 912 5060 2373
+2103 2 2 4 8 3492 3933 2813
+2104 2 2 4 8 1893 5225 3121
+2105 2 2 4 8 1892 5223 3122
+2106 2 2 4 8 108 2323 107
+2107 2 2 4 8 782 3793 1839
+2108 2 2 4 8 783 3794 1840
+2109 2 2 4 8 3069 2192 4916
+2110 2 2 4 8 932 3567 1818
+2111 2 2 4 8 933 3566 1819
+2112 2 2 4 8 1487 3829 2827
+2113 2 2 4 8 1490 3828 2828
+2114 2 2 4 8 642 2831 2024
+2115 2 2 4 8 1425 2662 3771
+2116 2 2 4 8 650 2180 2902
+2117 2 2 4 8 648 2181 2901
+2118 2 2 4 8 2108 2620 4938
+2119 2 2 4 8 515 4260 2874
+2120 2 2 4 8 2108 1225 2620
+2121 2 2 4 8 940 2734 3540
+2122 2 2 4 8 637 2578 3733
+2123 2 2 4 8 638 3732 2579
+2124 2 2 4 8 635 5352 3679
+2125 2 2 4 8 475 1962 4397
+2126 2 2 4 8 1281 3588 2288
+2127 2 2 4 8 1282 3589 2289
+2128 2 2 4 8 1283 2290 3590
+2129 2 2 4 8 1284 2291 3591
+2130 2 2 4 8 807 4795 2156
+2131 2 2 4 8 1661 2156 4795
+2132 2 2 4 8 1662 2157 4796
+2133 2 2 4 8 808 4796 2157
+2134 2 2 4 8 1160 2945 3372
+2135 2 2 4 8 1161 3373 2946
+2136 2 2 4 8 2145 696 5326
+2137 2 2 4 8 1859 5414 2169
+2138 2 2 4 8 1860 5415 2170
+2139 2 2 4 8 1858 5416 2171
+2140 2 2 4 8 247 2661 2250
+2141 2 2 4 8 1245 3338 2275
+2142 2 2 4 8 1875 2874 4260
+2143 2 2 4 8 1849 1206 3054
+2144 2 2 4 8 980 3432 2425
+2145 2 2 4 8 1321 4028 1897
+2146 2 2 4 8 675 1897 4028
+2147 2 2 4 8 705 4282 3727
+2148 2 2 4 8 2538 3795 2915
+2149 2 2 4 8 911 4775 2032
+2150 2 2 4 8 1881 1057 3575
+2151 2 2 4 8 1058 1882 3577
+2152 2 2 4 8 1059 3576 1883
+2153 2 2 4 8 1748 5205 3807
+2154 2 2 4 8 1749 5206 3808
+2155 2 2 4 8 1345 1981 2786
+2156 2 2 4 8 927 3733 1864
+2157 2 2 4 8 928 1863 3732
+2158 2 2 4 8 2632 4097 3872
+2159 2 2 4 8 1040 2037 2706
+2160 2 2 4 8 1041 2038 2707
+2161 2 2 4 8 992 2069 3977
+2162 2 2 4 8 2864 990 4350
+2163 2 2 4 8 991 2863 4351
+2164 2 2 4 8 704 4671 1879
+2165 2 2 4 8 1066 1968 3282
+2166 2 2 4 8 333 1987 2793
+2167 2 2 4 8 1613 3788 3050
+2168 2 2 4 8 773 1867 3939
+2169 2 2 4 8 1221 1994 4032
+2170 2 2 4 8 1491 3839 2824
+2171 2 2 4 8 2826 1488 3841
+2172 2 2 4 8 2825 1489 3840
+2173 2 2 4 8 902 3931 3396
+2174 2 2 4 8 904 5083 2176
+2175 2 2 4 8 903 2177 5082
+2176 2 2 4 8 1785 4392 3309
+2177 2 2 4 8 54 55 2688
+2178 2 2 4 8 275 276 2689
+2179 2 2 4 8 494 2681 2756
+2180 2 2 4 8 1247 2756 2681
+2181 2 2 4 8 566 5257 2355
+2182 2 2 4 8 726 3941 2798
+2183 2 2 4 8 170 3149 2142
+2184 2 2 4 8 357 3150 2141
+2185 2 2 4 8 473 4311 1949
+2186 2 2 4 8 1610 4942 3786
+2187 2 2 4 8 912 2165 4237
+2188 2 2 4 8 1118 3658 1831
+2189 2 2 4 8 784 1823 3751
+2190 2 2 4 8 866 3729 2486
+2191 2 2 4 8 19 2208 3816
+2192 2 2 4 8 846 3232 2421
+2193 2 2 4 8 1304 2421 3232
+2194 2 2 4 8 2015 4977 3606
+2195 2 2 4 8 756 2113 2629
+2196 2 2 4 8 621 1928 2872
+2197 2 2 4 8 1009 2133 3312
+2198 2 2 4 8 2534 3978 3587
+2199 2 2 4 8 490 2666 4236
+2200 2 2 4 8 859 2696 4595
+2201 2 2 4 8 1919 4595 2696
+2202 2 2 4 8 1316 2567 3135
+2203 2 2 4 8 460 3135 2567
+2204 2 2 4 8 461 3137 2568
+2205 2 2 4 8 1317 2568 3137
+2206 2 2 4 8 2748 4099 3810
+2207 2 2 4 8 1074 2081 5250
+2208 2 2 4 8 516 2789 4481
+2209 2 2 4 8 615 3333 2446
+2210 2 2 4 8 2108 4001 1418
+2211 2 2 4 8 761 4001 2108
+2212 2 2 4 8 2815 3488 3952
+2213 2 2 4 8 782 1839 3669
+2214 2 2 4 8 783 1840 3670
+2215 2 2 4 8 1122 3707 3635
+2216 2 2 4 8 1804 4318 5138
+2217 2 2 4 8 2088 1012 3286
+2218 2 2 4 8 1798 2751 4774
+2219 2 2 4 8 1799 2752 4773
+2220 2 2 4 8 640 2299 2606
+2221 2 2 4 8 1094 2606 2299
+2222 2 2 4 8 2076 4634 845
+2223 2 2 4 8 1921 4481 2789
+2224 2 2 4 8 521 3001 4415
+2225 2 2 4 8 1052 2481 5138
+2226 2 2 4 8 1022 2328 3032
+2227 2 2 4 8 1043 2782 2176
+2228 2 2 4 8 1044 2177 2783
+2229 2 2 4 8 36 3080 1880
+2230 2 2 4 8 1880 3080 1169
+2231 2 2 4 8 1009 2346 3157
+2232 2 2 4 8 534 4368 1961
+2233 2 2 4 8 1209 4405 1887
+2234 2 2 4 8 1208 4404 1888
+2235 2 2 4 8 764 3604 1834
+2236 2 2 4 8 1203 1872 3510
+2237 2 2 4 8 596 3510 1872
+2238 2 2 4 8 1205 1873 3511
+2239 2 2 4 8 598 3511 1873
+2240 2 2 4 8 579 2588 2200
+2241 2 2 4 8 565 2074 4997
+2242 2 2 4 8 410 1984 3366
+2243 2 2 4 8 598 2607 2216
+2244 2 2 4 8 1439 3000 2039
+2245 2 2 4 8 1329 2503 3515
+2246 2 2 4 8 2082 1188 3477
+2247 2 2 4 8 2088 5104 1012
+2248 2 2 4 8 2079 1125 3955
+2249 2 2 4 8 2080 1124 3954
+2250 2 2 4 8 832 1945 2862
+2251 2 2 4 8 2095 1196 4255
+2252 2 2 4 8 1495 3656 3813
+2253 2 2 4 8 1338 2791 3623
+2254 2 2 4 8 1132 3973 1876
+2255 2 2 4 8 1028 3918 2384
+2256 2 2 4 8 1029 2385 3919
+2257 2 2 4 8 2735 4662 5029
+2258 2 2 4 8 1619 3654 2422
+2259 2 2 4 8 1618 3653 2423
+2260 2 2 4 8 1424 3218 1995
+2261 2 2 4 8 868 2241 2726
+2262 2 2 4 8 1287 2885 2738
+2263 2 2 4 8 510 2738 2885
+2264 2 2 4 8 2653 4354 5150
+2265 2 2 4 8 2684 4444 2835
+2266 2 2 4 8 2683 2836 4445
+2267 2 2 4 8 583 3726 2188
+2268 2 2 4 8 720 2653 5150
+2269 2 2 4 8 1809 4517 2774
+2270 2 2 4 8 1125 3669 1839
+2271 2 2 4 8 1124 3670 1840
+2272 2 2 4 8 1729 3150 4729
+2273 2 2 4 8 1728 3149 4730
+2274 2 2 4 8 1638 4500 2555
+2275 2 2 4 8 1639 2556 4499
+2276 2 2 4 8 1414 4260 2525
+2277 2 2 4 8 681 3911 2434
+2278 2 2 4 8 1320 4029 3213
+2279 2 2 4 8 1319 4027 3212
+2280 2 2 4 8 152 2718 151
+2281 2 2 4 8 372 373 2719
+2282 2 2 4 8 1061 5370 2148
+2283 2 2 4 8 1062 5371 2149
+2284 2 2 4 8 885 5372 2150
+2285 2 2 4 8 886 5373 2151
+2286 2 2 4 8 397 398 2590
+2287 2 2 4 8 1016 2755 2025
+2288 2 2 4 8 1015 2754 2026
+2289 2 2 4 8 2825 3789 1469
+2290 2 2 4 8 1468 2826 3790
+2291 2 2 4 8 1467 2827 3788
+2292 2 2 4 8 1920 4415 3001
+2293 2 2 4 8 588 4678 2000
+2294 2 2 4 8 2399 2892 4106
+2295 2 2 4 8 644 3374 3155
+2296 2 2 4 8 475 2174 4961
+2297 2 2 4 8 2119 2775 3303
+2298 2 2 4 8 1167 2927 2049
+2299 2 2 4 8 1039 4627 2034
+2300 2 2 4 8 658 2814 3525
+2301 2 2 4 8 1016 3298 2141
+2302 2 2 4 8 1015 3299 2142
+2303 2 2 4 8 1076 2303 5207
+2304 2 2 4 8 520 3340 2657
+2305 2 2 4 8 575 3741 2252
+2306 2 2 4 8 571 3704 2253
+2307 2 2 4 8 1597 3999 2768
+2308 2 2 4 8 1413 4082 2423
+2309 2 2 4 8 1412 4081 2422
+2310 2 2 4 8 559 2316 2734
+2311 2 2 4 8 1687 5016 2403
+2312 2 2 4 8 655 3224 2662
+2313 2 2 4 8 340 4357 2347
+2314 2 2 4 8 1160 1934 4055
+2315 2 2 4 8 1161 4054 1933
+2316 2 2 4 8 1935 3507 4806
+2317 2 2 4 8 1971 2672 3855
+2318 2 2 4 8 1229 2960 3615
+2319 2 2 4 8 1675 3615 2960
+2320 2 2 4 8 708 3392 2034
+2321 2 2 4 8 989 4264 2375
+2322 2 2 4 8 990 4265 2376
+2323 2 2 4 8 991 2377 4266
+2324 2 2 4 8 992 2378 4267
+2325 2 2 4 8 1628 3936 2625
+2326 2 2 4 8 792 2625 3936
+2327 2 2 4 8 2003 3328 1201
+2328 2 2 4 8 614 3328 2003
+2329 2 2 4 8 1550 2807 3394
+2330 2 2 4 8 891 1954 2878
+2331 2 2 4 8 1042 4349 2040
+2332 2 2 4 8 1234 3896 3529
+2333 2 2 4 8 1235 3530 3897
+2334 2 2 4 8 619 1836 3431
+2335 2 2 4 8 899 3148 2823
+2336 2 2 4 8 1072 4003 1994
+2337 2 2 4 8 26 27 2425
+2338 2 2 4 8 2096 1118 3960
+2339 2 2 4 8 868 2676 4276
+2340 2 2 4 8 1037 1885 3011
+2341 2 2 4 8 1038 1886 3012
+2342 2 2 4 8 1462 3786 2910
+2343 2 2 4 8 1061 2184 5370
+2344 2 2 4 8 1062 2185 5371
+2345 2 2 4 8 885 2186 5372
+2346 2 2 4 8 886 2187 5373
+2347 2 2 4 8 703 3641 3407
+2348 2 2 4 8 574 2369 5260
+2349 2 2 4 8 573 2368 5261
+2350 2 2 4 8 886 4400 3126
+2351 2 2 4 8 734 4131 2555
+2352 2 2 4 8 526 2217 2968
+2353 2 2 4 8 1055 1980 2841
+2354 2 2 4 8 75 2383 74
+2355 2 2 4 8 1055 2953 1980
+2356 2 2 4 8 938 2275 2948
+2357 2 2 4 8 1363 3708 2842
+2358 2 2 4 8 408 1994 4003
+2359 2 2 4 8 228 229 2455
+2360 2 2 4 8 198 199 2456
+2361 2 2 4 8 1210 1843 4620
+2362 2 2 4 8 1173 1856 4090
+2363 2 2 4 8 1172 1857 4089
+2364 2 2 4 8 1075 1904 3042
+2365 2 2 4 8 460 2271 3135
+2366 2 2 4 8 1239 3135 2271
+2367 2 2 4 8 781 3904 2849
+2368 2 2 4 8 1056 4662 2735
+2369 2 2 4 8 1075 2991 1904
+2370 2 2 4 8 33 2328 32
+2371 2 2 4 8 1425 2485 4553
+2372 2 2 4 8 767 4424 1873
+2373 2 2 4 8 766 4423 1872
+2374 2 2 4 8 1627 3851 3104
+2375 2 2 4 8 1412 3654 2909
+2376 2 2 4 8 1013 2980 2138
+2377 2 2 4 8 919 2875 1961
+2378 2 2 4 8 1135 2879 1962
+2379 2 2 4 8 2062 4466 1199
+2380 2 2 4 8 1607 3638 2888
+2381 2 2 4 8 1036 3008 2098
+2382 2 2 4 8 1856 2766 4199
+2383 2 2 4 8 1857 2767 4198
+2384 2 2 4 8 1070 2168 2639
+2385 2 2 4 8 487 2486 3763
+2386 2 2 4 8 1117 2745 4511
+2387 2 2 4 8 578 2490 3151
+2388 2 2 4 8 1849 3386 1206
+2389 2 2 4 8 1849 1295 3752
+2390 2 2 4 8 2184 2969 4034
+2391 2 2 4 8 1121 2734 2316
+2392 2 2 4 8 622 2418 2645
+2393 2 2 4 8 623 2646 2419
+2394 2 2 4 8 587 2512 3175
+2395 2 2 4 8 582 2511 3174
+2396 2 2 4 8 481 1851 3179
+2397 2 2 4 8 470 3180 1854
+2398 2 2 4 8 1081 2183 2671
+2399 2 2 4 8 663 2671 2183
+2400 2 2 4 8 998 3607 4203
+2401 2 2 4 8 1082 3430 1884
+2402 2 2 4 8 88 4379 2014
+2403 2 2 4 8 1550 3394 5022
+2404 2 2 4 8 1685 4880 2374
+2405 2 2 4 8 525 1867 3780
+2406 2 2 4 8 1204 1871 3547
+2407 2 2 4 8 597 3547 1871
+2408 2 2 4 8 1195 3831 1905
+2409 2 2 4 8 888 4313 2872
+2410 2 2 4 8 1856 5087 2766
+2411 2 2 4 8 1857 5088 2767
+2412 2 2 4 8 679 2962 2674
+2413 2 2 4 8 1275 2674 2962
+2414 2 2 4 8 878 5341 2339
+2415 2 2 4 8 877 5340 2338
+2416 2 2 4 8 596 2457 5390
+2417 2 2 4 8 1687 2403 5069
+2418 2 2 4 8 1061 2148 3573
+2419 2 2 4 8 1062 2149 3574
+2420 2 2 4 8 1145 2762 2430
+2421 2 2 4 8 1151 3361 1855
+2422 2 2 4 8 608 1855 3361
+2423 2 2 4 8 1073 1896 3025
+2424 2 2 4 8 1764 2464 4344
+2425 2 2 4 8 2147 1441 4619
+2426 2 2 4 8 1074 5250 2195
+2427 2 2 4 8 627 2915 1960
+2428 2 2 4 8 2065 2750 4318
+2429 2 2 4 8 1151 1855 3364
+2430 2 2 4 8 1549 4597 3634
+2431 2 2 4 8 2125 2731 5259
+2432 2 2 4 8 494 5105 2167
+2433 2 2 4 8 1915 3231 5233
+2434 2 2 4 8 588 2044 4678
+2435 2 2 4 8 981 2774 4517
+2436 2 2 4 8 555 4728 2036
+2437 2 2 4 8 965 2615 3847
+2438 2 2 4 8 952 4042 1866
+2439 2 2 4 8 1201 3406 2266
+2440 2 2 4 8 481 4447 1991
+2441 2 2 4 8 1231 2954 3600
+2442 2 2 4 8 1664 3600 2954
+2443 2 2 4 8 3039 3796 2028
+2444 2 2 4 8 684 1947 3057
+2445 2 2 4 8 1789 3679 5352
+2446 2 2 4 8 192 2948 2275
+2447 2 2 4 8 2503 4530 3515
+2448 2 2 4 8 1520 2180 4472
+2449 2 2 4 8 1521 2181 4474
+2450 2 2 4 8 1832 3481 4399
+2451 2 2 4 8 2008 4386 5041
+2452 2 2 4 8 2465 4153 2725
+2453 2 2 4 8 250 3282 1968
+2454 2 2 4 8 1128 2491 2831
+2455 2 2 4 8 997 2587 2913
+2456 2 2 4 8 99 100 2442
+2457 2 2 4 8 646 2911 2241
+2458 2 2 4 8 2241 2911 1153
+2459 2 2 4 8 1039 2171 4622
+2460 2 2 4 8 600 2785 2156
+2461 2 2 4 8 1348 3319 2535
+2462 2 2 4 8 673 2535 3319
+2463 2 2 4 8 674 2536 3321
+2464 2 2 4 8 1350 3321 2536
+2465 2 2 4 8 675 2537 3320
+2466 2 2 4 8 1349 3320 2537
+2467 2 2 4 8 1940 3148 5230
+2468 2 2 4 8 1326 3051 3049
+2469 2 2 4 8 2075 4686 2838
+2470 2 2 4 8 1561 3278 2981
+2471 2 2 4 8 709 2981 3278
+2472 2 2 4 8 1123 2913 2000
+2473 2 2 4 8 456 5211 1919
+2474 2 2 4 8 2814 3934 3525
+2475 2 2 4 8 1777 3304 4616
+2476 2 2 4 8 1614 3790 3059
+2477 2 2 4 8 1615 3789 3058
+2478 2 2 4 8 715 2534 3066
+2479 2 2 4 8 470 1988 4482
+2480 2 2 4 8 1151 4017 4656
+2481 2 2 4 8 1224 2046 4038
+2482 2 2 4 8 1458 4121 3770
+2483 2 2 4 8 560 2102 5067
+2484 2 2 4 8 1080 2020 5027
+2485 2 2 4 8 657 2243 3552
+2486 2 2 4 8 659 2245 3551
+2487 2 2 4 8 680 2101 2764
+2488 2 2 4 8 1660 2143 4949
+2489 2 2 4 8 811 4949 2143
+2490 2 2 4 8 1076 5207 2552
+2491 2 2 4 8 1647 2460 4499
+2492 2 2 4 8 1648 4500 2459
+2493 2 2 4 8 580 4606 2175
+2494 2 2 4 8 1063 3250 5372
+2495 2 2 4 8 1064 3251 5373
+2496 2 2 4 8 682 3042 1904
+2497 2 2 4 8 1605 2896 3524
+2498 2 2 4 8 167 168 4224
+2499 2 2 4 8 354 355 4223
+2500 2 2 4 8 2019 3274 5383
+2501 2 2 4 8 985 4418 1990
+2502 2 2 4 8 987 4419 1991
+2503 2 2 4 8 986 4420 1989
+2504 2 2 4 8 984 1988 4417
+2505 2 2 4 8 1399 1961 4368
+2506 2 2 4 8 2516 2028 5183
+2507 2 2 4 8 1088 2749 4040
+2508 2 2 4 8 1066 2929 1968
+2509 2 2 4 8 239 3401 4605
+2510 2 2 4 8 1765 2428 4187
+2511 2 2 4 8 4443 1891 4697
+2512 2 2 4 8 1271 2179 3645
+2513 2 2 4 8 2150 4228 3627
+2514 2 2 4 8 1047 2248 4613
+2515 2 2 4 8 1036 2098 5023
+2516 2 2 4 8 206 2376 4265
+2517 2 2 4 8 423 2375 4264
+2518 2 2 4 8 221 4266 2377
+2519 2 2 4 8 439 4267 2378
+2520 2 2 4 8 1049 5210 1865
+2521 2 2 4 8 883 5370 2184
+2522 2 2 4 8 1064 5373 2187
+2523 2 2 4 8 2209 3819 5096
+2524 2 2 4 8 1870 2452 4613
+2525 2 2 4 8 1278 2802 2846
+2526 2 2 4 8 511 2846 2802
+2527 2 2 4 8 114 2717 113
+2528 2 2 4 8 124 125 2716
+2529 2 2 4 8 135 136 2715
+2530 2 2 4 8 180 181 2714
+2531 2 2 4 8 291 292 2712
+2532 2 2 4 8 302 303 2713
+2533 2 2 4 8 969 2153 2691
+2534 2 2 4 8 1416 2474 3595
+2535 2 2 4 8 496 3595 2474
+2536 2 2 4 8 21 4091 3518
+2537 2 2 4 8 1274 3776 3948
+2538 2 2 4 8 728 3524 2896
+2539 2 2 4 8 589 4989 4681
+2540 2 2 4 8 541 3171 3337
+2541 2 2 4 8 1672 3337 3171
+2542 2 2 4 8 868 2074 4920
+2543 2 2 4 8 499 2560 3421
+2544 2 2 4 8 1391 3421 2560
+2545 2 2 4 8 1392 3424 2561
+2546 2 2 4 8 501 2561 3424
+2547 2 2 4 8 452 2966 4705
+2548 2 2 4 8 897 2584 3646
+2549 2 2 4 8 917 1917 3048
+2550 2 2 4 8 487 2515 3003
+2551 2 2 4 8 2515 1579 3003
+2552 2 2 4 8 1712 2562 3540
+2553 2 2 4 8 1074 2195 2894
+2554 2 2 4 8 989 3465 2068
+2555 2 2 4 8 1023 2050 3079
+2556 2 2 4 8 2026 2754 4452
+2557 2 2 4 8 2755 4451 2025
+2558 2 2 4 8 730 2888 3638
+2559 2 2 4 8 1125 4440 3955
+2560 2 2 4 8 988 4105 5234
+2561 2 2 4 8 1042 2517 3395
+2562 2 2 4 8 922 2518 3507
+2563 2 2 4 8 1088 4040 5401
+2564 2 2 4 8 1508 2800 4243
+2565 2 2 4 8 1507 2801 4245
+2566 2 2 4 8 544 2082 2763
+2567 2 2 4 8 165 166 2411
+2568 2 2 4 8 352 353 2412
+2569 2 2 4 8 1145 2404 2762
+2570 2 2 4 8 910 2762 2404
+2571 2 2 4 8 966 2613 4700
+2572 2 2 4 8 2055 5405 5167
+2573 2 2 4 8 1388 3339 2612
+2574 2 2 4 8 517 2612 3339
+2575 2 2 4 8 211 212 4024
+2576 2 2 4 8 429 430 4023
+2577 2 2 4 8 811 1897 4396
+2578 2 2 4 8 2061 4842 2614
+2579 2 2 4 8 626 2089 2934
+2580 2 2 4 8 1653 3514 3657
+2581 2 2 4 8 1145 2430 2920
+2582 2 2 4 8 557 2011 4558
+2583 2 2 4 8 254 3446 4813
+2584 2 2 4 8 988 2280 4105
+2585 2 2 4 8 2960 3676 5209
+2586 2 2 4 8 1965 4043 2400
+2587 2 2 4 8 421 4884 2068
+2588 2 2 4 8 6 2069 4885
+2589 2 2 4 8 2265 2733 4191
+2590 2 2 4 8 1128 2621 2491
+2591 2 2 4 8 493 2491 2621
+2592 2 2 4 8 1294 4436 3403
+2593 2 2 4 8 1296 2353 3821
+2594 2 2 4 8 2150 5372 3250
+2595 2 2 4 8 2151 5373 3251
+2596 2 2 4 8 846 1876 3973
+2597 2 2 4 8 1801 4286 2870
+2598 2 2 4 8 343 2138 2980
+2599 2 2 4 8 2106 2748 993
+2600 2 2 4 8 2101 1067 2764
+2601 2 2 4 8 1679 4276 2676
+2602 2 2 4 8 549 2169 3269
+2603 2 2 4 8 550 2170 3270
+2604 2 2 4 8 1211 4078 1869
+2605 2 2 4 8 1067 2389 2764
+2606 2 2 4 8 1408 2764 2389
+2607 2 2 4 8 990 3129 2066
+2608 2 2 4 8 991 2067 3130
+2609 2 2 4 8 572 5259 2731
+2610 2 2 4 8 998 4203 3937
+2611 2 2 4 8 929 2632 3872
+2612 2 2 4 8 1941 3763 4172
+2613 2 2 4 8 1221 4300 2595
+2614 2 2 4 8 664 1980 2953
+2615 2 2 4 8 898 3969 1890
+2616 2 2 4 8 497 3053 1931
+2617 2 2 4 8 1326 5319 2350
+2618 2 2 4 8 141 4071 2132
+2619 2 2 4 8 362 4072 2131
+2620 2 2 4 8 2095 3465 989
+2621 2 2 4 8 406 407 2636
+2622 2 2 4 8 789 3929 1916
+2623 2 2 4 8 1983 4507 4261
+2624 2 2 4 8 983 2285 2772
+2625 2 2 4 8 982 2284 2773
+2626 2 2 4 8 1129 4208 3014
+2627 2 2 4 8 458 1995 4371
+2628 2 2 4 8 1118 4448 3960
+2629 2 2 4 8 1959 2406 4073
+2630 2 2 4 8 846 3636 1876
+2631 2 2 4 8 811 3774 1897
+2632 2 2 4 8 905 2321 3104
+2633 2 2 4 8 851 2237 2690
+2634 2 2 4 8 813 5073 5174
+2635 2 2 4 8 1676 5065 2694
+2636 2 2 4 8 2160 3073 4610
+2637 2 2 4 8 2161 4609 3074
+2638 2 2 4 8 665 2786 2233
+2639 2 2 4 8 1497 4669 3903
+2640 2 2 4 8 1090 4663 5175
+2641 2 2 4 8 1816 2427 5256
+2642 2 2 4 8 1461 3440 3245
+2643 2 2 4 8 918 2669 2224
+2644 2 2 4 8 2240 4904 3686
+2645 2 2 4 8 771 2297 2931
+2646 2 2 4 8 1044 2392 2586
+2647 2 2 4 8 447 2617 4322
+2648 2 2 4 8 597 3436 2581
+2649 2 2 4 8 1152 4386 3117
+2650 2 2 4 8 1999 4484 2351
+2651 2 2 4 8 468 2072 4863
+2652 2 2 4 8 454 2248 2654
+2653 2 2 4 8 24 3938 1918
+2654 2 2 4 8 1354 4172 3763
+2655 2 2 4 8 548 2171 3528
+2656 2 2 4 8 1589 4867 3043
+2657 2 2 4 8 1843 4813 3446
+2658 2 2 4 8 1318 4077 1946
+2659 2 2 4 8 498 4715 3616
+2660 2 2 4 8 1053 4774 2751
+2661 2 2 4 8 1054 4773 2752
+2662 2 2 4 8 1178 3394 1970
+2663 2 2 4 8 1267 1904 3875
+2664 2 2 4 8 1065 2250 2661
+2665 2 2 4 8 334 3302 1987
+2666 2 2 4 8 1053 2505 4774
+2667 2 2 4 8 1054 2504 4773
+2668 2 2 4 8 812 2898 2009
+2669 2 2 4 8 1074 1980 3660
+2670 2 2 4 8 657 1878 3492
+2671 2 2 4 8 1152 2779 3055
+2672 2 2 4 8 1347 3055 2779
+2673 2 2 4 8 2498 2264 4378
+2674 2 2 4 8 813 5174 2624
+2675 2 2 4 8 589 2759 4989
+2676 2 2 4 8 1408 2389 3953
+2677 2 2 4 8 1415 2999 3580
+2678 2 2 4 8 159 160 2766
+2679 2 2 4 8 380 381 2767
+2680 2 2 4 8 1073 3057 1947
+2681 2 2 4 8 849 4582 2028
+2682 2 2 4 8 1778 3306 4432
+2683 2 2 4 8 1779 4433 3305
+2684 2 2 4 8 1155 3131 2133
+2685 2 2 4 8 542 2870 4286
+2686 2 2 4 8 1880 1169 3427
+2687 2 2 4 8 2087 4934 1174
+2688 2 2 4 8 1036 2217 3008
+2689 2 2 4 8 910 2036 4504
+2690 2 2 4 8 579 2200 5389
+2691 2 2 4 8 1432 3746 2797
+2692 2 2 4 8 1433 3747 2798
+2693 2 2 4 8 632 4411 1903
+2694 2 2 4 8 1359 3197 4290
+2695 2 2 4 8 890 3993 3234
+2696 2 2 4 8 1827 5249 4744
+2697 2 2 4 8 992 3977 2311
+2698 2 2 4 8 1673 4001 3766
+2699 2 2 4 8 346 347 2839
+2700 2 2 4 8 696 5346 4263
+2701 2 2 4 8 647 2366 3989
+2702 2 2 4 8 1453 2438 3560
+2703 2 2 4 8 1454 3561 2437
+2704 2 2 4 8 1060 3119 2393
+2705 2 2 4 8 1002 2686 3761
+2706 2 2 4 8 967 3743 4747
+2707 2 2 4 8 943 4578 2029
+2708 2 2 4 8 696 2754 5346
+2709 2 2 4 8 565 1881 3575
+2710 2 2 4 8 568 3577 1882
+2711 2 2 4 8 569 1883 3576
+2712 2 2 4 8 1620 4317 2629
+2713 2 2 4 8 443 1950 3070
+2714 2 2 4 8 1098 2414 4989
+2715 2 2 4 8 969 4370 2654
+2716 2 2 4 8 898 1890 3341
+2717 2 2 4 8 664 3238 3853
+2718 2 2 4 8 839 1964 4272
+2719 2 2 4 8 1000 1882 3554
+2720 2 2 4 8 1881 999 3553
+2721 2 2 4 8 1001 3555 1883
+2722 2 2 4 8 577 3156 2269
+2723 2 2 4 8 772 1884 3430
+2724 2 2 4 8 697 3648 2746
+2725 2 2 4 8 699 3649 2747
+2726 2 2 4 8 1543 1976 4211
+2727 2 2 4 8 1542 1977 4210
+2728 2 2 4 8 1194 3531 1906
+2729 2 2 4 8 1193 3532 1907
+2730 2 2 4 8 1192 3535 1908
+2731 2 2 4 8 1190 1909 3533
+2732 2 2 4 8 1191 1910 3534
+2733 2 2 4 8 2686 4287 3761
+2734 2 2 4 8 1050 1891 4443
+2735 2 2 4 8 2012 3478 5340
+2736 2 2 4 8 2013 3479 5341
+2737 2 2 4 8 500 3676 2960
+2738 2 2 4 8 1186 3659 2014
+2739 2 2 4 8 704 4812 2463
+2740 2 2 4 8 909 4864 2232
+2741 2 2 4 8 1198 2690 2237
+2742 2 2 4 8 1080 4496 2020
+2743 2 2 4 8 1080 2021 4496
+2744 2 2 4 8 1308 2168 3816
+2745 2 2 4 8 2234 2413 4638
+2746 2 2 4 8 1440 2723 3382
+2747 2 2 4 8 1164 3382 2723
+2748 2 2 4 8 656 2367 3497
+2749 2 2 4 8 694 5237 4241
+2750 2 2 4 8 1698 2592 5374
+2751 2 2 4 8 694 2741 5237
+2752 2 2 4 8 1103 4063 1986
+2753 2 2 4 8 1307 3580 2259
+2754 2 2 4 8 654 2259 3580
+2755 2 2 4 8 468 4414 1945
+2756 2 2 4 8 1292 1936 3107
+2757 2 2 4 8 1293 3108 1937
+2758 2 2 4 8 3513 4407 1264
+2759 2 2 4 8 205 4265 4882
+2760 2 2 4 8 222 4883 4266
+2761 2 2 4 8 422 4264 4884
+2762 2 2 4 8 440 4885 4267
+2763 2 2 4 8 993 2748 3810
+2764 2 2 4 8 1137 1902 3294
+2765 2 2 4 8 631 3294 1902
+2766 2 2 4 8 1506 2598 3145
+2767 2 2 4 8 1505 3146 2599
+2768 2 2 4 8 958 1982 4369
+2769 2 2 4 8 1117 1949 4311
+2770 2 2 4 8 636 3468 1891
+2771 2 2 4 8 321 322 2551
+2772 2 2 4 8 3088 5125 5309
+2773 2 2 4 8 1895 4705 2966
+2774 2 2 4 8 1698 5374 4896
+2775 2 2 4 8 17 2168 2935
+2776 2 2 4 8 780 3539 1905
+2777 2 2 4 8 1195 1905 3539
+2778 2 2 4 8 779 3538 1906
+2779 2 2 4 8 1194 1906 3538
+2780 2 2 4 8 1190 3537 1909
+2781 2 2 4 8 776 1910 3536
+2782 2 2 4 8 775 1909 3537
+2783 2 2 4 8 1191 3536 1910
+2784 2 2 4 8 2562 4705 5042
+2785 2 2 4 8 228 2455 5270
+2786 2 2 4 8 199 5271 2456
+2787 2 2 4 8 604 3603 2162
+2788 2 2 4 8 2101 4923 1067
+2789 2 2 4 8 912 2031 4776
+2790 2 2 4 8 1095 2032 4775
+2791 2 2 4 8 964 4412 2908
+2792 2 2 4 8 862 3201 4353
+2793 2 2 4 8 1533 2388 3071
+2794 2 2 4 8 2104 5220 1269
+2795 2 2 4 8 1887 5145 3359
+2796 2 2 4 8 1888 5146 3358
+2797 2 2 4 8 451 2058 2904
+2798 2 2 4 8 485 2172 3020
+2799 2 2 4 8 598 2458 2607
+2800 2 2 4 8 2350 5319 2949
+2801 2 2 4 8 1502 4103 4645
+2802 2 2 4 8 996 2682 2268
+2803 2 2 4 8 1056 2307 3105
+2804 2 2 4 8 391 392 2357
+2805 2 2 4 8 1042 5310 2517
+2806 2 2 4 8 448 2627 2365
+2807 2 2 4 8 450 5347 2199
+2808 2 2 4 8 442 5348 2201
+2809 2 2 4 8 595 2187 3126
+2810 2 2 4 8 329 330 2577
+2811 2 2 4 8 2103 5226 1268
+2812 2 2 4 8 485 2218 2733
+2813 2 2 4 8 605 2051 3412
+2814 2 2 4 8 1214 3412 2051
+2815 2 2 4 8 65 2112 4037
+2816 2 2 4 8 286 2110 4035
+2817 2 2 4 8 257 4036 2111
+2818 2 2 4 8 461 1923 3854
+2819 2 2 4 8 460 1924 3717
+2820 2 2 4 8 1240 3717 1924
+2821 2 2 4 8 536 3148 1940
+2822 2 2 4 8 959 4261 4507
+2823 2 2 4 8 859 4878 2315
+2824 2 2 4 8 1047 4613 2452
+2825 2 2 4 8 1925 4605 3401
+2826 2 2 4 8 741 3050 3788
+2827 2 2 4 8 2054 4994 1286
+2828 2 2 4 8 1585 2838 4686
+2829 2 2 4 8 1151 3090 4017
+2830 2 2 4 8 780 1905 4569
+2831 2 2 4 8 779 1906 4570
+2832 2 2 4 8 778 1907 4571
+2833 2 2 4 8 777 1908 4572
+2834 2 2 4 8 776 4574 1910
+2835 2 2 4 8 775 4573 1909
+2836 2 2 4 8 467 2166 5207
+2837 2 2 4 8 1467 3242 3448
+2838 2 2 4 8 2101 1298 3193
+2839 2 2 4 8 1111 3994 1917
+2840 2 2 4 8 1072 2042 2916
+2841 2 2 4 8 1347 2779 2197
+2842 2 2 4 8 809 2197 2779
+2843 2 2 4 8 1040 2925 2037
+2844 2 2 4 8 1041 2926 2038
+2845 2 2 4 8 2083 1940 5230
+2846 2 2 4 8 984 3088 1963
+2847 2 2 4 8 1166 2142 3149
+2848 2 2 4 8 1165 2141 3150
+2849 2 2 4 8 631 1902 3447
+2850 2 2 4 8 1110 4771 2035
+2851 2 2 4 8 1093 5066 4780
+2852 2 2 4 8 1115 2306 4252
+2853 2 2 4 8 2066 4882 4265
+2854 2 2 4 8 2067 4266 4883
+2855 2 2 4 8 2068 4884 4264
+2856 2 2 4 8 2069 4267 4885
+2857 2 2 4 8 2241 1153 2726
+2858 2 2 4 8 803 4472 2180
+2859 2 2 4 8 804 4474 2181
+2860 2 2 4 8 486 3549 1969
+2861 2 2 4 8 210 211 3435
+2862 2 2 4 8 428 429 3434
+2863 2 2 4 8 1080 3147 2021
+2864 2 2 4 8 955 2905 2604
+2865 2 2 4 8 953 2906 2602
+2866 2 2 4 8 954 2603 2904
+2867 2 2 4 8 1029 3919 3464
+2868 2 2 4 8 1028 3463 3918
+2869 2 2 4 8 637 2176 2782
+2870 2 2 4 8 638 2783 2177
+2871 2 2 4 8 720 3060 1986
+2872 2 2 4 8 1039 2272 4627
+2873 2 2 4 8 658 3525 1912
+2874 2 2 4 8 2211 4951 3738
+2875 2 2 4 8 2210 4950 3737
+2876 2 2 4 8 1725 4921 2590
+2877 2 2 4 8 1176 1916 3929
+2878 2 2 4 8 492 4127 2053
+2879 2 2 4 8 2053 4127 1369
+2880 2 2 4 8 1946 2965 5002
+2881 2 2 4 8 1564 4717 2114
+2882 2 2 4 8 633 2114 4717
+2883 2 2 4 8 634 2115 4718
+2884 2 2 4 8 1563 4718 2115
+2885 2 2 4 8 657 2813 3553
+2886 2 2 4 8 658 3554 2814
+2887 2 2 4 8 659 2815 3555
+2888 2 2 4 8 525 3349 2225
+2889 2 2 4 8 1248 2225 3349
+2890 2 2 4 8 497 3065 4116
+2891 2 2 4 8 1228 2563 2618
+2892 2 2 4 8 565 2876 2074
+2893 2 2 4 8 2074 2876 1088
+2894 2 2 4 8 715 3066 2776
+2895 2 2 4 8 1695 2315 4878
+2896 2 2 4 8 1808 4323 4615
+2897 2 2 4 8 1007 2281 4401
+2898 2 2 4 8 1571 4401 2281
+2899 2 2 4 8 559 2734 2239
+2900 2 2 4 8 1353 3416 4061
+2901 2 2 4 8 593 2185 3221
+2902 2 2 4 8 594 3222 2186
+2903 2 2 4 8 567 5256 2427
+2904 2 2 4 8 687 3227 3623
+2905 2 2 4 8 346 1916 5015
+2906 2 2 4 8 1438 1929 3819
+2907 2 2 4 8 891 4638 1954
+2908 2 2 4 8 1856 3231 5087
+2909 2 2 4 8 1857 3230 5088
+2910 2 2 4 8 1355 4426 2466
+2911 2 2 4 8 1356 2467 4425
+2912 2 2 4 8 1062 3419 2371
+2913 2 2 4 8 1061 3418 2370
+2914 2 2 4 8 638 2177 5333
+2915 2 2 4 8 637 5334 2176
+2916 2 2 4 8 1224 3332 1926
+2917 2 2 4 8 1082 2842 2474
+2918 2 2 4 8 1451 3280 2411
+2919 2 2 4 8 979 2411 3280
+2920 2 2 4 8 1290 1971 3106
+2921 2 2 4 8 994 3807 2746
+2922 2 2 4 8 995 3808 2747
+2923 2 2 4 8 1240 1924 4364
+2924 2 2 4 8 1546 2962 3365
+2925 2 2 4 8 679 3365 2962
+2926 2 2 4 8 1305 3237 2549
+2927 2 2 4 8 872 2549 3237
+2928 2 2 4 8 1594 3771 2662
+2929 2 2 4 8 584 2701 2533
+2930 2 2 4 8 1140 2533 2701
+2931 2 2 4 8 1138 2531 2700
+2932 2 2 4 8 585 2700 2531
+2933 2 2 4 8 875 2049 4618
+2934 2 2 4 8 1103 1986 3060
+2935 2 2 4 8 1238 1922 4611
+2936 2 2 4 8 417 1953 4556
+2937 2 2 4 8 632 5065 4085
+2938 2 2 4 8 2064 4780 5066
+2939 2 2 4 8 798 4137 2292
+2940 2 2 4 8 746 3404 4302
+2941 2 2 4 8 485 3020 2218
+2942 2 2 4 8 451 2703 2532
+2943 2 2 4 8 1139 2532 2703
+2944 2 2 4 8 195 2130 4483
+2945 2 2 4 8 1232 1925 3401
+2946 2 2 4 8 1952 3479 5254
+2947 2 2 4 8 1951 3478 5253
+2948 2 2 4 8 888 1928 4378
+2949 2 2 4 8 1226 2019 5383
+2950 2 2 4 8 2757 5205 5213
+2951 2 2 4 8 5206 5214 2758
+2952 2 2 4 8 1096 5205 2757
+2953 2 2 4 8 1097 5206 2758
+2954 2 2 4 8 1355 3847 1937
+2955 2 2 4 8 1356 1936 3848
+2956 2 2 4 8 202 1933 4054
+2957 2 2 4 8 225 4055 1934
+2958 2 2 4 8 865 2833 3819
+2959 2 2 4 8 832 3874 1943
+2960 2 2 4 8 1102 2028 4582
+2961 2 2 4 8 721 2679 2873
+2962 2 2 4 8 1249 2873 2679
+2963 2 2 4 8 764 1996 3604
+2964 2 2 4 8 1227 3604 1996
+2965 2 2 4 8 1100 2761 4248
+2966 2 2 4 8 4200 3084 5062
+2967 2 2 4 8 564 2203 3284
+2968 2 2 4 8 1388 2612 2656
+2969 2 2 4 8 1389 2613 2657
+2970 2 2 4 8 576 4512 2300
+2971 2 2 4 8 1527 4831 2251
+2972 2 2 4 8 1390 2615 2655
+2973 2 2 4 8 2098 1277 3176
+2974 2 2 4 8 1853 4676 4420
+2975 2 2 4 8 1852 4677 4418
+2976 2 2 4 8 471 2622 3106
+2977 2 2 4 8 1290 3106 2622
+2978 2 2 4 8 410 4251 1984
+2979 2 2 4 8 930 2572 2879
+2980 2 2 4 8 506 3277 4163
+2981 2 2 4 8 1985 3731 1251
+2982 2 2 4 8 1117 3871 1949
+2983 2 2 4 8 316 3293 4604
+2984 2 2 4 8 2853 3307 1730
+2985 2 2 4 8 6 7 3977
+2986 2 2 4 8 1093 3436 2664
+2987 2 2 4 8 522 2500 3428
+2988 2 2 4 8 1336 3428 2500
+2989 2 2 4 8 1683 2373 5060
+2990 2 2 4 8 614 3529 2941
+2991 2 2 4 8 1598 2941 3529
+2992 2 2 4 8 1599 3530 2940
+2993 2 2 4 8 607 2940 3530
+2994 2 2 4 8 692 2632 3656
+2995 2 2 4 8 788 2434 3315
+2996 2 2 4 8 1276 3315 2434
+2997 2 2 4 8 1762 4502 4004
+2998 2 2 4 8 1014 2547 4150
+2999 2 2 4 8 2076 845 4770
+3000 2 2 4 8 672 2707 3626
+3001 2 2 4 8 2023 4314 2451
+3002 2 2 4 8 710 3369 3026
+3003 2 2 4 8 1793 3616 4715
+3004 2 2 4 8 810 1960 4188
+3005 2 2 4 8 4121 4219 2447
+3006 2 2 4 8 4120 4221 2448
+3007 2 2 4 8 490 3998 2372
+3008 2 2 4 8 1279 5131 2346
+3009 2 2 4 8 793 3779 1930
+3010 2 2 4 8 1310 3714 2210
+3011 2 2 4 8 504 2210 3714
+3012 2 2 4 8 505 2211 3715
+3013 2 2 4 8 1311 3715 2211
+3014 2 2 4 8 756 4291 2113
+3015 2 2 4 8 1452 2113 4291
+3016 2 2 4 8 592 2184 3833
+3017 2 2 4 8 629 2333 2687
+3018 2 2 4 8 1606 3637 2897
+3019 2 2 4 8 1063 3998 3250
+3020 2 2 4 8 1837 2889 4081
+3021 2 2 4 8 1838 2890 4082
+3022 2 2 4 8 846 2421 3636
+3023 2 2 4 8 1372 3636 2421
+3024 2 2 4 8 1095 4421 2032
+3025 2 2 4 8 1093 4780 3436
+3026 2 2 4 8 1768 2538 4007
+3027 2 2 4 8 1108 2329 5007
+3028 2 2 4 8 1202 2135 3263
+3029 2 2 4 8 1300 3082 3175
+3030 2 2 4 8 1301 3083 3174
+3031 2 2 4 8 2076 1232 4092
+3032 2 2 4 8 985 1965 3206
+3033 2 2 4 8 554 3015 2031
+3034 2 2 4 8 792 2693 2625
+3035 2 2 4 8 1837 4661 2889
+3036 2 2 4 8 1838 4662 2890
+3037 2 2 4 8 793 1930 3610
+3038 2 2 4 8 448 5089 5138
+3039 2 2 4 8 47 5092 2809
+3040 2 2 4 8 268 5093 2810
+3041 2 2 4 8 81 5094 2808
+3042 2 2 4 8 558 5075 2262
+3043 2 2 4 8 1707 2262 5075
+3044 2 2 4 8 1755 4660 5287
+3045 2 2 4 8 512 2695 2334
+3046 2 2 4 8 1116 4416 2251
+3047 2 2 4 8 1196 1953 3311
+3048 2 2 4 8 802 3881 1957
+3049 2 2 4 8 535 4238 2702
+3050 2 2 4 8 536 1940 3748
+3051 2 2 4 8 1659 3519 3078
+3052 2 2 4 8 1260 3078 3519
+3053 2 2 4 8 1652 4551 3924
+3054 2 2 4 8 637 2047 4560
+3055 2 2 4 8 638 4559 2048
+3056 2 2 4 8 1122 2893 3707
+3057 2 2 4 8 923 5409 2233
+3058 2 2 4 8 1103 5290 2386
+3059 2 2 4 8 1640 3846 3619
+3060 2 2 4 8 1638 3618 3844
+3061 2 2 4 8 975 1950 4233
+3062 2 2 4 8 624 2420 5291
+3063 2 2 4 8 581 2153 5099
+3064 2 2 4 8 1045 5098 2154
+3065 2 2 4 8 1396 2797 3678
+3066 2 2 4 8 1348 2878 3470
+3067 2 2 4 8 666 2202 3776
+3068 2 2 4 8 731 2897 3637
+3069 2 2 4 8 1715 2868 3306
+3070 2 2 4 8 1714 3305 2867
+3071 2 2 4 8 2866 3304 1716
+3072 2 2 4 8 1665 2611 3872
+3073 2 2 4 8 788 3467 1987
+3074 2 2 4 8 2074 2726 4997
+3075 2 2 4 8 770 2195 5250
+3076 2 2 4 8 747 2721 4179
+3077 2 2 4 8 1182 2196 4041
+3078 2 2 4 8 2232 4864 2426
+3079 2 2 4 8 1078 2967 2257
+3080 2 2 4 8 506 3085 2002
+3081 2 2 4 8 910 2267 2762
+3082 2 2 4 8 1056 2735 2307
+3083 2 2 4 8 643 3043 2042
+3084 2 2 4 8 1114 2042 3043
+3085 2 2 4 8 691 4292 2613
+3086 2 2 4 8 1061 3573 4932
+3087 2 2 4 8 1062 3574 4925
+3088 2 2 4 8 919 1961 3908
+3089 2 2 4 8 1308 3816 2208
+3090 2 2 4 8 843 3578 1938
+3091 2 2 4 8 844 3579 1939
+3092 2 2 4 8 1100 4248 3054
+3093 2 2 4 8 469 1944 3470
+3094 2 2 4 8 902 1969 3931
+3095 2 2 4 8 1004 3355 1955
+3096 2 2 4 8 1005 3356 1956
+3097 2 2 4 8 1890 5177 3341
+3098 2 2 4 8 580 2152 5081
+3099 2 2 4 8 595 3039 2028
+3100 2 2 4 8 1459 4120 4066
+3101 2 2 4 8 957 2791 2472
+3102 2 2 4 8 2165 3391 4237
+3103 2 2 4 8 1090 2265 2823
+3104 2 2 4 8 105 3692 4395
+3105 2 2 4 8 1197 2268 4319
+3106 2 2 4 8 1698 3518 4091
+3107 2 2 4 8 1265 4394 1950
+3108 2 2 4 8 1079 3225 2551
+3109 2 2 4 8 740 3058 3789
+3110 2 2 4 8 742 3059 3790
+3111 2 2 4 8 513 2673 3450
+3112 2 2 4 8 1419 3450 2673
+3113 2 2 4 8 556 2032 4498
+3114 2 2 4 8 1580 3029 2442
+3115 2 2 4 8 452 4705 2562
+3116 2 2 4 8 480 4122 1989
+3117 2 2 4 8 479 4123 1990
+3118 2 2 4 8 485 5140 2172
+3119 2 2 4 8 916 2403 5016
+3120 2 2 4 8 211 4024 3435
+3121 2 2 4 8 429 4023 3434
+3122 2 2 4 8 1206 3971 3067
+3123 2 2 4 8 836 3069 4916
+3124 2 2 4 8 929 2611 3078
+3125 2 2 4 8 2446 3333 4218
+3126 2 2 4 8 1035 2498 5315
+3127 2 2 4 8 2498 1928 5315
+3128 2 2 4 8 1206 2903 3971
+3129 2 2 4 8 2993 4724 2488
+3130 2 2 4 8 751 4985 3655
+3131 2 2 4 8 588 2000 4247
+3132 2 2 4 8 2673 4250 4412
+3133 2 2 4 8 929 2502 2632
+3134 2 2 4 8 580 5081 4606
+3135 2 2 4 8 1551 3475 2332
+3136 2 2 4 8 581 5182 2192
+3137 2 2 4 8 1689 2192 5182
+3138 2 2 4 8 1196 3835 1953
+3139 2 2 4 8 784 2033 4817
+3140 2 2 4 8 1095 2298 2807
+3141 2 2 4 8 1068 2120 4898
+3142 2 2 4 8 939 2365 4692
+3143 2 2 4 8 1486 3407 3641
+3144 2 2 4 8 1448 4515 1993
+3145 2 2 4 8 1449 4516 1992
+3146 2 2 4 8 78 79 3598
+3147 2 2 4 8 38 2506 37
+3148 2 2 4 8 612 4554 2728
+3149 2 2 4 8 1219 2514 2933
+3150 2 2 4 8 485 2265 2856
+3151 2 2 4 8 3204 5203 4616
+3152 2 2 4 8 907 4321 2114
+3153 2 2 4 8 908 4320 2115
+3154 2 2 4 8 852 3172 2139
+3155 2 2 4 8 853 3173 2140
+3156 2 2 4 8 1157 2867 3305
+3157 2 2 4 8 1158 3306 2868
+3158 2 2 4 8 1156 3304 2866
+3159 2 2 4 8 886 2151 4249
+3160 2 2 4 8 2266 3406 4051
+3161 2 2 4 8 636 2618 2563
+3162 2 2 4 8 708 2034 4373
+3163 2 2 4 8 1080 5027 2267
+3164 2 2 4 8 683 2435 3514
+3165 2 2 4 8 605 2939 3721
+3166 2 2 4 8 1645 3721 2939
+3167 2 2 4 8 604 2938 3723
+3168 2 2 4 8 1644 3723 2938
+3169 2 2 4 8 1254 3657 3514
+3170 2 2 4 8 1108 2669 4629
+3171 2 2 4 8 666 5068 2064
+3172 2 2 4 8 1652 3036 4551
+3173 2 2 4 8 503 4161 3163
+3174 2 2 4 8 619 4217 2409
+3175 2 2 4 8 963 3848 2656
+3176 2 2 4 8 629 4341 2539
+3177 2 2 4 8 1222 3443 4395
+3178 2 2 4 8 108 4690 2323
+3179 2 2 4 8 2746 3807 4521
+3180 2 2 4 8 2747 3808 4522
+3181 2 2 4 8 1066 3282 2249
+3182 2 2 4 8 1592 5158 2685
+3183 2 2 4 8 325 2332 4299
+3184 2 2 4 8 607 2052 3474
+3185 2 2 4 8 1216 3474 2052
+3186 2 2 4 8 509 2989 4969
+3187 2 2 4 8 514 2990 4970
+3188 2 2 4 8 1358 1971 3855
+3189 2 2 4 8 2061 5186 1123
+3190 2 2 4 8 1440 2132 4071
+3191 2 2 4 8 1441 2131 4072
+3192 2 2 4 8 2109 4976 1106
+3193 2 2 4 8 1507 4518 2801
+3194 2 2 4 8 1508 4519 2800
+3195 2 2 4 8 2086 1051 4503
+3196 2 2 4 8 524 3207 2106
+3197 2 2 4 8 2106 3207 1168
+3198 2 2 4 8 1074 3660 2081
+3199 2 2 4 8 961 3255 4727
+3200 2 2 4 8 868 4920 2676
+3201 2 2 4 8 988 3444 1964
+3202 2 2 4 8 612 4981 4554
+3203 2 2 4 8 1641 4714 4047
+3204 2 2 4 8 1243 3120 2793
+3205 2 2 4 8 1534 3614 3920
+3206 2 2 4 8 958 2745 2329
+3207 2 2 4 8 2420 5034 5291
+3208 2 2 4 8 2077 1102 4582
+3209 2 2 4 8 956 2695 2591
+3210 2 2 4 8 1740 2730 3776
+3211 2 2 4 8 1435 2899 3976
+3212 2 2 4 8 1386 2591 2695
+3213 2 2 4 8 1197 2921 2705
+3214 2 2 4 8 1337 2476 2886
+3215 2 2 4 8 1127 2601 2605
+3216 2 2 4 8 1128 2605 2601
+3217 2 2 4 8 692 3656 3094
+3218 2 2 4 8 813 2194 5200
+3219 2 2 4 8 1263 5200 2194
+3220 2 2 4 8 1263 2193 5200
+3221 2 2 4 8 2853 1162 3307
+3222 2 2 4 8 1733 3125 4107
+3223 2 2 4 8 1034 2497 5349
+3224 2 2 4 8 2497 1927 5349
+3225 2 2 4 8 1743 3940 2544
+3226 2 2 4 8 1209 2127 4405
+3227 2 2 4 8 1208 2128 4404
+3228 2 2 4 8 2778 1711 4799
+3229 2 2 4 8 2899 5069 3976
+3230 2 2 4 8 2685 5158 2837
+3231 2 2 4 8 4551 2802 4941
+3232 2 2 4 8 1712 3540 5295
+3233 2 2 4 8 654 3580 2999
+3234 2 2 4 8 1144 2480 2919
+3235 2 2 4 8 100 4689 2442
+3236 2 2 4 8 1507 3621 4518
+3237 2 2 4 8 1508 3622 4519
+3238 2 2 4 8 1696 2414 3668
+3239 2 2 4 8 1584 2319 4538
+3240 2 2 4 8 1003 3728 1970
+3241 2 2 4 8 558 1998 4053
+3242 2 2 4 8 964 2672 2673
+3243 2 2 4 8 1419 2673 2672
+3244 2 2 4 8 408 4032 1994
+3245 2 2 4 8 1246 3296 2311
+3246 2 2 4 8 992 2311 3296
+3247 2 2 4 8 1430 4037 2112
+3248 2 2 4 8 2110 1428 4035
+3249 2 2 4 8 2111 4036 1429
+3250 2 2 4 8 917 2295 2790
+3251 2 2 4 8 584 5069 2403
+3252 2 2 4 8 1169 4743 1996
+3253 2 2 4 8 1458 3159 4121
+3254 2 2 4 8 1459 3160 4120
+3255 2 2 4 8 856 2183 3125
+3256 2 2 4 8 2085 4723 575
+3257 2 2 4 8 2085 1535 4723
+3258 2 2 4 8 2105 5040 2844
+3259 2 2 4 8 641 2844 5040
+3260 2 2 4 8 772 2040 4349
+3261 2 2 4 8 1322 5275 2519
+3262 2 2 4 8 2074 1088 5401
+3263 2 2 4 8 330 4531 2577
+3264 2 2 4 8 873 4121 2447
+3265 2 2 4 8 874 4120 2448
+3266 2 2 4 8 906 4205 2116
+3267 2 2 4 8 86 3005 4147
+3268 2 2 4 8 2466 4426 2811
+3269 2 2 4 8 2467 2812 4425
+3270 2 2 4 8 1345 4787 1981
+3271 2 2 4 8 886 4249 2648
+3272 2 2 4 8 1495 3813 2643
+3273 2 2 4 8 1963 3088 5309
+3274 2 2 4 8 912 4776 2165
+3275 2 2 4 8 1095 4775 2166
+3276 2 2 4 8 482 1973 3516
+3277 2 2 4 8 484 1972 3517
+3278 2 2 4 8 355 3298 2025
+3279 2 2 4 8 168 3299 2026
+3280 2 2 4 8 446 3564 3034
+3281 2 2 4 8 1472 3057 3025
+3282 2 2 4 8 1073 3025 3057
+3283 2 2 4 8 682 2021 3147
+3284 2 2 4 8 1093 2242 5066
+3285 2 2 4 8 2076 2928 4634
+3286 2 2 4 8 1218 4538 2319
+3287 2 2 4 8 1147 3121 5225
+3288 2 2 4 8 1148 3122 5223
+3289 2 2 4 8 586 4549 2255
+3290 2 2 4 8 581 4548 2256
+3291 2 2 4 8 720 1986 4967
+3292 2 2 4 8 876 2981 4048
+3293 2 2 4 8 1043 2176 5083
+3294 2 2 4 8 1044 5082 2177
+3295 2 2 4 8 635 2116 4832
+3296 2 2 4 8 899 2823 2265
+3297 2 2 4 8 29 3592 1981
+3298 2 2 4 8 1872 4423 2457
+3299 2 2 4 8 1873 4424 2458
+3300 2 2 4 8 822 3735 4552
+3301 2 2 4 8 1668 2711 4952
+3302 2 2 4 8 1169 1996 3427
+3303 2 2 4 8 764 3427 1996
+3304 2 2 4 8 1731 3308 2854
+3305 2 2 4 8 1732 3309 2855
+3306 2 2 4 8 1059 2889 4661
+3307 2 2 4 8 1056 2890 4662
+3308 2 2 4 8 1783 3572 2282
+3309 2 2 4 8 1390 2655 3640
+3310 2 2 4 8 1089 2121 3093
+3311 2 2 4 8 1707 2528 3730
+3312 2 2 4 8 1420 4057 2976
+3313 2 2 4 8 2471 3639 2929
+3314 2 2 4 8 1103 2637 5290
+3315 2 2 4 8 950 5313 1998
+3316 2 2 4 8 939 4692 2528
+3317 2 2 4 8 689 3491 2672
+3318 2 2 4 8 1419 2672 3491
+3319 2 2 4 8 494 2398 2743
+3320 2 2 4 8 1113 2743 2398
+3321 2 2 4 8 1975 5175 4663
+3322 2 2 4 8 947 4462 2428
+3323 2 2 4 8 1351 5013 3504
+3324 2 2 4 8 1916 2839 4185
+3325 2 2 4 8 590 2004 3375
+3326 2 2 4 8 591 2005 3376
+3327 2 2 4 8 922 2294 5215
+3328 2 2 4 8 1188 4182 2213
+3329 2 2 4 8 1187 4183 2212
+3330 2 2 4 8 1868 4395 3692
+3331 2 2 4 8 1221 3366 1984
+3332 2 2 4 8 476 2881 2318
+3333 2 2 4 8 453 5143 2190
+3334 2 2 4 8 10 11 3041
+3335 2 2 4 8 951 5095 2333
+3336 2 2 4 8 922 5215 2299
+3337 2 2 4 8 756 2629 4317
+3338 2 2 4 8 641 2807 2298
+3339 2 2 4 8 322 4178 2551
+3340 2 2 4 8 1179 2621 2843
+3341 2 2 4 8 310 3244 3484
+3342 2 2 4 8 299 3246 3483
+3343 2 2 4 8 128 3486 3241
+3344 2 2 4 8 117 3487 3240
+3345 2 2 4 8 2104 1120 3186
+3346 2 2 4 8 1450 4223 2025
+3347 2 2 4 8 1451 4224 2026
+3348 2 2 4 8 1247 4697 2756
+3349 2 2 4 8 1497 2587 4669
+3350 2 2 4 8 524 2106 2992
+3351 2 2 4 8 1420 4130 4057
+3352 2 2 4 8 2098 3008 679
+3353 2 2 4 8 921 5155 2287
+3354 2 2 4 8 675 2917 2545
+3355 2 2 4 8 1676 2694 3815
+3356 2 2 4 8 577 2982 3562
+3357 2 2 4 8 1159 3049 3051
+3358 2 2 4 8 2147 4619 3102
+3359 2 2 4 8 1143 2402 2869
+3360 2 2 4 8 579 2869 2402
+3361 2 2 4 8 1296 3824 2129
+3362 2 2 4 8 491 2129 3824
+3363 2 2 4 8 74 2383 4201
+3364 2 2 4 8 807 1992 4778
+3365 2 2 4 8 808 1993 4779
+3366 2 2 4 8 2528 4692 4653
+3367 2 2 4 8 1150 3883 4257
+3368 2 2 4 8 1384 4140 2266
+3369 2 2 4 8 544 4391 2082
+3370 2 2 4 8 2082 4391 1437
+3371 2 2 4 8 1090 5175 2415
+3372 2 2 4 8 578 3151 4200
+3373 2 2 4 8 776 5180 3798
+3374 2 2 4 8 775 5181 3797
+3375 2 2 4 8 779 3800 5178
+3376 2 2 4 8 780 3799 5179
+3377 2 2 4 8 29 1981 4787
+3378 2 2 4 8 921 2298 5155
+3379 2 2 4 8 562 2278 4413
+3380 2 2 4 8 1538 4413 2278
+3381 2 2 4 8 1168 3207 3385
+3382 2 2 4 8 1058 2459 2884
+3383 2 2 4 8 1057 2883 2460
+3384 2 2 4 8 1634 2702 4238
+3385 2 2 4 8 1074 4802 1980
+3386 2 2 4 8 1106 4976 2182
+3387 2 2 4 8 1369 4909 2792
+3388 2 2 4 8 1331 2647 3627
+3389 2 2 4 8 1087 2123 3291
+3390 2 2 4 8 1299 2163 3939
+3391 2 2 4 8 604 2162 4986
+3392 2 2 4 8 1395 5328 2005
+3393 2 2 4 8 1394 5329 2004
+3394 2 2 4 8 1421 2821 2822
+3395 2 2 4 8 1049 2822 2821
+3396 2 2 4 8 476 3752 3048
+3397 2 2 4 8 1985 1251 3711
+3398 2 2 4 8 1893 3121 5190
+3399 2 2 4 8 1892 3122 5191
+3400 2 2 4 8 1894 3123 5192
+3401 2 2 4 8 3022 4511 4971
+3402 2 2 4 8 788 1987 3834
+3403 2 2 4 8 971 4467 3608
+3404 2 2 4 8 1297 2008 3265
+3405 2 2 4 8 664 3660 1980
+3406 2 2 4 8 51 2012 3248
+3407 2 2 4 8 272 2013 3249
+3408 2 2 4 8 1474 3260 3387
+3409 2 2 4 8 1475 3261 3388
+3410 2 2 4 8 910 4504 2267
+3411 2 2 4 8 629 2687 4341
+3412 2 2 4 8 1162 3047 3957
+3413 2 2 4 8 1070 2935 2168
+3414 2 2 4 8 2346 5131 3157
+3415 2 2 4 8 1496 2118 4558
+3416 2 2 4 8 557 4558 2118
+3417 2 2 4 8 513 4250 2673
+3418 2 2 4 8 1115 2063 3144
+3419 2 2 4 8 906 2360 4205
+3420 2 2 4 8 1330 3930 3810
+3421 2 2 4 8 323 324 2891
+3422 2 2 4 8 1747 4243 4113
+3423 2 2 4 8 1746 4245 4114
+3424 2 2 4 8 1146 4674 2024
+3425 2 2 4 8 1755 5287 3310
+3426 2 2 4 8 904 4442 2002
+3427 2 2 4 8 1707 3730 4629
+3428 2 2 4 8 336 2008 3925
+3429 2 2 4 8 349 350 3185
+3430 2 2 4 8 163 3184 162
+3431 2 2 4 8 2103 1119 3194
+3432 2 2 4 8 2105 5165 4957
+3433 2 2 4 8 2043 5234 4105
+3434 2 2 4 8 2003 2266 5406
+3435 2 2 4 8 559 4594 2295
+3436 2 2 4 8 860 2482 2920
+3437 2 2 4 8 861 2483 2919
+3438 2 2 4 8 917 5061 2295
+3439 2 2 4 8 1688 2295 5061
+3440 2 2 4 8 318 1985 3711
+3441 2 2 4 8 473 2224 5007
+3442 2 2 4 8 602 5203 3204
+3443 2 2 4 8 508 4081 2889
+3444 2 2 4 8 519 4082 2890
+3445 2 2 4 8 2101 3889 1298
+3446 2 2 4 8 680 3889 2101
+3447 2 2 4 8 1670 3201 4478
+3448 2 2 4 8 1221 1984 3651
+3449 2 2 4 8 1809 2774 3927
+3450 2 2 4 8 1126 4262 3087
+3451 2 2 4 8 1164 2854 3308
+3452 2 2 4 8 1163 2855 3309
+3453 2 2 4 8 1064 5154 3251
+3454 2 2 4 8 2404 5199 5142
+3455 2 2 4 8 2086 4639 977
+3456 2 2 4 8 608 2453 2908
+3457 2 2 4 8 1090 2856 2265
+3458 2 2 4 8 2263 4104 2477
+3459 2 2 4 8 1135 2307 4621
+3460 2 2 4 8 1624 3442 4760
+3461 2 2 4 8 1108 5007 2669
+3462 2 2 4 8 2581 3436 4202
+3463 2 2 4 8 2204 2943 4209
+3464 2 2 4 8 1978 4969 2989
+3465 2 2 4 8 1976 4970 2990
+3466 2 2 4 8 1269 5220 3783
+3467 2 2 4 8 1751 2986 4512
+3468 2 2 4 8 46 47 2809
+3469 2 2 4 8 268 2810 267
+3470 2 2 4 8 80 81 2808
+3471 2 2 4 8 2089 3143 1626
+3472 2 2 4 8 862 2479 3459
+3473 2 2 4 8 1320 1992 3629
+3474 2 2 4 8 1319 1993 3628
+3475 2 2 4 8 2166 2552 5207
+3476 2 2 4 8 889 5165 3233
+3477 2 2 4 8 2492 2973 4632
+3478 2 2 4 8 2430 5350 2920
+3479 2 2 4 8 1176 3177 5015
+3480 2 2 4 8 1455 3395 2517
+3481 2 2 4 8 1167 2049 5344
+3482 2 2 4 8 1133 2120 3214
+3483 2 2 4 8 1271 3124 2179
+3484 2 2 4 8 923 2179 3124
+3485 2 2 4 8 583 2967 3726
+3486 2 2 4 8 1227 1996 3706
+3487 2 2 4 8 1598 3529 3896
+3488 2 2 4 8 1599 3897 3530
+3489 2 2 4 8 664 3118 2182
+3490 2 2 4 8 1448 3912 2553
+3491 2 2 4 8 404 2389 3052
+3492 2 2 4 8 657 3552 2795
+3493 2 2 4 8 659 3551 2794
+3494 2 2 4 8 455 2841 4802
+3495 2 2 4 8 910 2404 5142
+3496 2 2 4 8 1748 2634 5213
+3497 2 2 4 8 1749 2635 5214
+3498 2 2 4 8 1233 2341 3451
+3499 2 2 4 8 1752 5270 2455
+3500 2 2 4 8 1753 2456 5271
+3501 2 2 4 8 1424 4204 2040
+3502 2 2 4 8 1235 3570 3530
+3503 2 2 4 8 809 4002 2197
+3504 2 2 4 8 531 2139 4825
+3505 2 2 4 8 532 2140 4826
+3506 2 2 4 8 1162 2941 3307
+3507 2 2 4 8 1164 3308 2940
+3508 2 2 4 8 1268 5226 3781
+3509 2 2 4 8 685 2977 3680
+3510 2 2 4 8 1246 5208 2155
+3511 2 2 4 8 1532 4022 4505
+3512 2 2 4 8 2071 1173 4090
+3513 2 2 4 8 2070 1172 4089
+3514 2 2 4 8 1297 3925 2008
+3515 2 2 4 8 2547 3336 4150
+3516 2 2 4 8 1115 4252 2727
+3517 2 2 4 8 1064 2436 5154
+3518 2 2 4 8 797 5364 4926
+3519 2 2 4 8 589 2033 4403
+3520 2 2 4 8 809 2202 4002
+3521 2 2 4 8 656 3497 2796
+3522 2 2 4 8 2077 5284 1102
+3523 2 2 4 8 1686 3548 2137
+3524 2 2 4 8 626 5379 2331
+3525 2 2 4 8 2086 3072 639
+3526 2 2 4 8 965 2655 2615
+3527 2 2 4 8 963 2656 2612
+3528 2 2 4 8 966 2657 2613
+3529 2 2 4 8 1492 4615 4323
+3530 2 2 4 8 1267 2780 2978
+3531 2 2 4 8 677 2978 2780
+3532 2 2 4 8 1415 4033 3119
+3533 2 2 4 8 455 4802 2895
+3534 2 2 4 8 592 2969 2184
+3535 2 2 4 8 889 3233 4323
+3536 2 2 4 8 1674 2584 5384
+3537 2 2 4 8 2365 2627 4692
+3538 2 2 4 8 1970 3728 2589
+3539 2 2 4 8 575 4723 3741
+3540 2 2 4 8 1331 2037 4721
+3541 2 2 4 8 1332 2038 4722
+3542 2 2 4 8 1807 2519 5275
+3543 2 2 4 8 1862 3964 2806
+3544 2 2 4 8 1339 2806 3964
+3545 2 2 4 8 1792 2676 4920
+3546 2 2 4 8 1452 4291 2908
+3547 2 2 4 8 1855 2908 4291
+3548 2 2 4 8 828 2053 5238
+3549 2 2 4 8 1196 3311 4255
+3550 2 2 4 8 1022 3032 4803
+3551 2 2 4 8 1573 4167 2559
+3552 2 2 4 8 856 2559 4167
+3553 2 2 4 8 688 3144 2063
+3554 2 2 4 8 490 4236 3998
+3555 2 2 4 8 2023 2724 3830
+3556 2 2 4 8 1224 3593 2046
+3557 2 2 4 8 822 2046 3593
+3558 2 2 4 8 964 3855 2672
+3559 2 2 4 8 1930 3779 2363
+3560 2 2 4 8 336 4386 2008
+3561 2 2 4 8 1662 3226 2157
+3562 2 2 4 8 600 2428 2785
+3563 2 2 4 8 571 4748 3704
+3564 2 2 4 8 316 317 3293
+3565 2 2 4 8 848 4107 5134
+3566 2 2 4 8 511 2802 4551
+3567 2 2 4 8 401 4567 2173
+3568 2 2 4 8 765 2231 4164
+3569 2 2 4 8 1417 4164 2231
+3570 2 2 4 8 2366 3124 3989
+3571 2 2 4 8 1048 4961 2174
+3572 2 2 4 8 812 2009 3906
+3573 2 2 4 8 2160 3923 2829
+3574 2 2 4 8 2830 3922 2161
+3575 2 2 4 8 626 2359 5379
+3576 2 2 4 8 1504 2397 3498
+3577 2 2 4 8 1154 4414 2399
+3578 2 2 4 8 960 3236 4853
+3579 2 2 4 8 1062 4925 3419
+3580 2 2 4 8 1572 4322 4895
+3581 2 2 4 8 880 3368 2029
+3582 2 2 4 8 881 3367 2030
+3583 2 2 4 8 1919 2696 5394
+3584 2 2 4 8 784 3751 2033
+3585 2 2 4 8 1105 5095 2324
+3586 2 2 4 8 1117 4511 3022
+3587 2 2 4 8 593 2305 2864
+3588 2 2 4 8 594 2863 2304
+3589 2 2 4 8 633 3061 2114
+3590 2 2 4 8 634 3062 2115
+3591 2 2 4 8 906 2116 3063
+3592 2 2 4 8 1061 4932 3418
+3593 2 2 4 8 669 2148 3023
+3594 2 2 4 8 670 2149 3024
+3595 2 2 4 8 1102 3128 2436
+3596 2 2 4 8 987 2007 3665
+3597 2 2 4 8 863 4827 2599
+3598 2 2 4 8 865 2598 4828
+3599 2 2 4 8 1064 5183 2436
+3600 2 2 4 8 1093 3915 2242
+3601 2 2 4 8 691 3801 3255
+3602 2 2 4 8 1805 3255 3801
+3603 2 2 4 8 1081 4107 3125
+3604 2 2 4 8 577 4862 3156
+3605 2 2 4 8 2010 3491 3888
+3606 2 2 4 8 689 3888 3491
+3607 2 2 4 8 1036 2968 2217
+3608 2 2 4 8 1535 4696 3741
+3609 2 2 4 8 1513 3606 3642
+3610 2 2 4 8 690 3802 3236
+3611 2 2 4 8 1802 3236 3802
+3612 2 2 4 8 1069 3020 2172
+3613 2 2 4 8 2914 4871 4305
+3614 2 2 4 8 519 2423 4082
+3615 2 2 4 8 508 2422 4081
+3616 2 2 4 8 850 2182 4976
+3617 2 2 4 8 1964 2426 4272
+3618 2 2 4 8 2405 4588 3500
+3619 2 2 4 8 4212 4927 1978
+3620 2 2 4 8 113 2717 4459
+3621 2 2 4 8 124 2716 4458
+3622 2 2 4 8 135 2715 4457
+3623 2 2 4 8 180 2714 4456
+3624 2 2 4 8 292 4455 2712
+3625 2 2 4 8 303 4454 2713
+3626 2 2 4 8 975 3502 3070
+3627 2 2 4 8 620 2354 4240
+3628 2 2 4 8 1618 2423 4554
+3629 2 2 4 8 1100 4554 2423
+3630 2 2 4 8 1276 3708 3315
+3631 2 2 4 8 1028 2649 3463
+3632 2 2 4 8 1377 3463 2649
+3633 2 2 4 8 1379 2650 3464
+3634 2 2 4 8 1029 3464 2650
+3635 2 2 4 8 937 3897 2574
+3636 2 2 4 8 936 2573 3896
+3637 2 2 4 8 507 2209 5096
+3638 2 2 4 8 1173 5233 3231
+3639 2 2 4 8 601 2015 3606
+3640 2 2 4 8 904 2176 4912
+3641 2 2 4 8 903 4911 2177
+3642 2 2 4 8 1039 2034 3392
+3643 2 2 4 8 2430 2762 5300
+3644 2 2 4 8 88 2014 3659
+3645 2 2 4 8 603 3102 4392
+3646 2 2 4 8 1464 2555 4131
+3647 2 2 4 8 571 2134 4748
+3648 2 2 4 8 1824 5092 3122
+3649 2 2 4 8 1825 5093 3123
+3650 2 2 4 8 1823 5094 3121
+3651 2 2 4 8 934 4190 2312
+3652 2 2 4 8 935 4189 2313
+3653 2 2 4 8 2082 3477 2763
+3654 2 2 4 8 1351 3389 5013
+3655 2 2 4 8 1804 2065 4318
+3656 2 2 4 8 2438 4725 3560
+3657 2 2 4 8 2437 3561 4726
+3658 2 2 4 8 1146 2993 2340
+3659 2 2 4 8 667 2340 2993
+3660 2 2 4 8 462 3951 2029
+3661 2 2 4 8 1499 2462 2788
+3662 2 2 4 8 2103 3351 1119
+3663 2 2 4 8 2104 3352 1120
+3664 2 2 4 8 654 2999 2293
+3665 2 2 4 8 2071 4358 1173
+3666 2 2 4 8 1128 2601 2843
+3667 2 2 4 8 601 2390 4344
+3668 2 2 4 8 1817 5257 3693
+3669 2 2 4 8 1816 5256 3694
+3670 2 2 4 8 1818 3695 5258
+3671 2 2 4 8 1820 3697 5261
+3672 2 2 4 8 1821 3698 5260
+3673 2 2 4 8 1819 3696 5259
+3674 2 2 4 8 338 4933 3117
+3675 2 2 4 8 604 2022 3603
+3676 2 2 4 8 1207 3603 2022
+3677 2 2 4 8 675 3320 2917
+3678 2 2 4 8 1877 5318 3168
+3679 2 2 4 8 480 2312 4049
+3680 2 2 4 8 479 2313 4050
+3681 2 2 4 8 1227 2625 2693
+3682 2 2 4 8 840 2023 3830
+3683 2 2 4 8 1914 5265 3230
+3684 2 2 4 8 1915 5266 3231
+3685 2 2 4 8 1100 2423 3261
+3686 2 2 4 8 1101 2422 3260
+3687 2 2 4 8 1589 3682 4867
+3688 2 2 4 8 2094 789 5135
+3689 2 2 4 8 1122 2233 5409
+3690 2 2 4 8 1107 2525 3295
+3691 2 2 4 8 682 5115 2021
+3692 2 2 4 8 1218 2588 4232
+3693 2 2 4 8 642 2605 2831
+3694 2 2 4 8 1692 5062 3084
+3695 2 2 4 8 906 4849 2963
+3696 2 2 4 8 589 3469 2033
+3697 2 2 4 8 2564 4021 3657
+3698 2 2 4 8 1546 2283 4595
+3699 2 2 4 8 859 4595 2283
+3700 2 2 4 8 1352 3967 3235
+3701 2 2 4 8 1879 3235 3967
+3702 2 2 4 8 600 2391 4187
+3703 2 2 4 8 798 2022 4602
+3704 2 2 4 8 2435 4742 3514
+3705 2 2 4 8 1641 3196 4714
+3706 2 2 4 8 1064 2516 5183
+3707 2 2 4 8 1128 2843 2621
+3708 2 2 4 8 2098 679 4510
+3709 2 2 4 8 1146 2024 4869
+3710 2 2 4 8 1848 4257 3883
+3711 2 2 4 8 930 2879 2427
+3712 2 2 4 8 1135 2427 2879
+3713 2 2 4 8 1293 4437 3526
+3714 2 2 4 8 1099 2318 2881
+3715 2 2 4 8 1081 2671 2681
+3716 2 2 4 8 1247 2681 2671
+3717 2 2 4 8 1144 5369 2277
+3718 2 2 4 8 1143 2276 5368
+3719 2 2 4 8 2062 2875 4466
+3720 2 2 4 8 921 2287 2924
+3721 2 2 4 8 1824 2809 5092
+3722 2 2 4 8 1825 2810 5093
+3723 2 2 4 8 1823 2808 5094
+3724 2 2 4 8 1111 4594 2239
+3725 2 2 4 8 2101 3193 4923
+3726 2 2 4 8 980 4326 2432
+3727 2 2 4 8 583 2257 2967
+3728 2 2 4 8 994 2746 2560
+3729 2 2 4 8 995 2747 2561
+3730 2 2 4 8 837 2056 4166
+3731 2 2 4 8 688 2063 4268
+3732 2 2 4 8 1624 3930 2893
+3733 2 2 4 8 522 3428 2805
+3734 2 2 4 8 1422 2805 3428
+3735 2 2 4 8 2079 3669 1125
+3736 2 2 4 8 2080 3670 1124
+3737 2 2 4 8 4107 2167 5134
+3738 2 2 4 8 1079 5174 3225
+3739 2 2 4 8 648 2482 4012
+3740 2 2 4 8 650 2483 4011
+3741 2 2 4 8 537 3079 5268
+3742 2 2 4 8 344 3177 2138
+3743 2 2 4 8 1133 4898 2120
+3744 2 2 4 8 1236 5340 3478
+3745 2 2 4 8 1237 5341 3479
+3746 2 2 4 8 1350 3672 3516
+3747 2 2 4 8 1349 3673 3517
+3748 2 2 4 8 1265 3643 4216
+3749 2 2 4 8 1322 3984 3667
+3750 2 2 4 8 533 2462 3297
+3751 2 2 4 8 709 3290 2981
+3752 2 2 4 8 1519 2981 3290
+3753 2 2 4 8 1824 4010 2809
+3754 2 2 4 8 1825 4009 2810
+3755 2 2 4 8 1823 4008 2808
+3756 2 2 4 8 610 4432 3073
+3757 2 2 4 8 609 3074 4433
+3758 2 2 4 8 595 3126 2583
+3759 2 2 4 8 2096 3658 1118
+3760 2 2 4 8 1700 5068 2730
+3761 2 2 4 8 1480 3837 2602
+3762 2 2 4 8 706 2602 3837
+3763 2 2 4 8 1481 3838 2604
+3764 2 2 4 8 707 2604 3838
+3765 2 2 4 8 1623 2323 4690
+3766 2 2 4 8 1597 4431 3128
+3767 2 2 4 8 1183 2931 2297
+3768 2 2 4 8 1086 3134 2122
+3769 2 2 4 8 610 3073 2160
+3770 2 2 4 8 609 2161 3074
+3771 2 2 4 8 2060 1132 5278
+3772 2 2 4 8 889 4957 5165
+3773 2 2 4 8 1385 2292 4137
+3774 2 2 4 8 931 2903 2318
+3775 2 2 4 8 33 3032 2328
+3776 2 2 4 8 600 4187 2428
+3777 2 2 4 8 1150 4241 4052
+3778 2 2 4 8 192 193 2948
+3779 2 2 4 8 774 3325 2496
+3780 2 2 4 8 610 2466 2811
+3781 2 2 4 8 609 2812 2467
+3782 2 2 4 8 931 2318 4229
+3783 2 2 4 8 3358 5362 1966
+3784 2 2 4 8 1967 3359 5363
+3785 2 2 4 8 962 2078 3239
+3786 2 2 4 8 265 266 2974
+3787 2 2 4 8 44 45 2975
+3788 2 2 4 8 1197 3046 3327
+3789 2 2 4 8 77 78 3101
+3790 2 2 4 8 1263 2194 3685
+3791 2 2 4 8 530 3685 2194
+3792 2 2 4 8 1155 2133 4667
+3793 2 2 4 8 1775 2794 4935
+3794 2 2 4 8 907 2361 4321
+3795 2 2 4 8 908 2362 4320
+3796 2 2 4 8 518 3640 2655
+3797 2 2 4 8 195 3452 2130
+3798 2 2 4 8 977 2982 2269
+3799 2 2 4 8 934 2368 4190
+3800 2 2 4 8 935 2369 4189
+3801 2 2 4 8 2082 1437 4363
+3802 2 2 4 8 1400 2753 2840
+3803 2 2 4 8 1776 2796 4936
+3804 2 2 4 8 959 4468 2134
+3805 2 2 4 8 2428 4462 2785
+3806 2 2 4 8 932 4297 2309
+3807 2 2 4 8 933 4296 2310
+3808 2 2 4 8 2251 4831 3026
+3809 2 2 4 8 1032 2646 2933
+3810 2 2 4 8 1219 2933 2646
+3811 2 2 4 8 215 4721 2037
+3812 2 2 4 8 433 4722 2038
+3813 2 2 4 8 1273 3735 2220
+3814 2 2 4 8 822 2220 3735
+3815 2 2 4 8 2135 5359 3263
+3816 2 2 4 8 1292 3527 4964
+3817 2 2 4 8 1511 3327 3046
+3818 2 2 4 8 1067 3052 2389
+3819 2 2 4 8 14 2158 3612
+3820 2 2 4 8 901 2062 4074
+3821 2 2 4 8 1983 4261 2470
+3822 2 2 4 8 2436 4075 5154
+3823 2 2 4 8 251 2249 3282
+3824 2 2 4 8 603 2147 3102
+3825 2 2 4 8 1243 2405 3500
+3826 2 2 4 8 601 4344 2464
+3827 2 2 4 8 1689 4916 2192
+3828 2 2 4 8 1416 3313 2474
+3829 2 2 4 8 765 5111 2231
+3830 2 2 4 8 626 3940 2359
+3831 2 2 4 8 1903 4411 3345
+3832 2 2 4 8 2333 5095 2687
+3833 2 2 4 8 1430 2112 4465
+3834 2 2 4 8 821 4465 2112
+3835 2 2 4 8 1727 2523 4912
+3836 2 2 4 8 904 4912 2523
+3837 2 2 4 8 903 2522 4911
+3838 2 2 4 8 1726 4911 2522
+3839 2 2 4 8 1568 2805 4157
+3840 2 2 4 8 796 4631 2063
+3841 2 2 4 8 1411 4176 3851
+3842 2 2 4 8 926 2443 4995
+3843 2 2 4 8 1710 4995 2443
+3844 2 2 4 8 1114 4143 2042
+3845 2 2 4 8 871 3702 2208
+3846 2 2 4 8 1308 2208 3702
+3847 2 2 4 8 480 4049 4122
+3848 2 2 4 8 479 4050 4123
+3849 2 2 4 8 962 4308 2078
+3850 2 2 4 8 1681 4203 3607
+3851 2 2 4 8 1348 3470 3077
+3852 2 2 4 8 791 5085 2071
+3853 2 2 4 8 790 5086 2070
+3854 2 2 4 8 1254 2564 3657
+3855 2 2 4 8 2078 2585 3586
+3856 2 2 4 8 1315 3740 3961
+3857 2 2 4 8 931 4229 2355
+3858 2 2 4 8 2491 4869 2831
+3859 2 2 4 8 1806 4601 3993
+3860 2 2 4 8 1253 4284 4115
+3861 2 2 4 8 2682 4319 2268
+3862 2 2 4 8 1094 2165 4776
+3863 2 2 4 8 911 2166 4775
+3864 2 2 4 8 610 2829 2466
+3865 2 2 4 8 609 2467 2830
+3866 2 2 4 8 3033 4132 4184
+3867 2 2 4 8 4169 1968 4305
+3868 2 2 4 8 828 3975 2053
+3869 2 2 4 8 1245 2275 3462
+3870 2 2 4 8 938 3462 2275
+3871 2 2 4 8 3029 5150 4879
+3872 2 2 4 8 1786 3445 5103
+3873 2 2 4 8 1123 2439 2913
+3874 2 2 4 8 524 4753 3605
+3875 2 2 4 8 800 2052 3570
+3876 2 2 4 8 98 3214 2120
+3877 2 2 4 8 1110 2401 4771
+3878 2 2 4 8 696 3280 4452
+3879 2 2 4 8 2082 3314 1188
+3880 2 2 4 8 787 2045 3700
+3881 2 2 4 8 651 3701 2045
+3882 2 2 4 8 627 2352 4007
+3883 2 2 4 8 447 2088 3286
+3884 2 2 4 8 1426 2804 3211
+3885 2 2 4 8 805 3211 2804
+3886 2 2 4 8 1427 2803 3210
+3887 2 2 4 8 806 3210 2803
+3888 2 2 4 8 1430 2322 4529
+3889 2 2 4 8 660 2429 4283
+3890 2 2 4 8 555 5309 5125
+3891 2 2 4 8 1016 2141 4640
+3892 2 2 4 8 1015 2142 4641
+3893 2 2 4 8 1000 2302 5388
+3894 2 2 4 8 826 3683 2270
+3895 2 2 4 8 1112 2364 5089
+3896 2 2 4 8 1112 5089 2365
+3897 2 2 4 8 2014 4332 3411
+3898 2 2 4 8 1399 3033 4184
+3899 2 2 4 8 1116 2251 3026
+3900 2 2 4 8 1267 3205 2780
+3901 2 2 4 8 1089 4541 2121
+3902 2 2 4 8 1086 2122 4543
+3903 2 2 4 8 1085 2125 4544
+3904 2 2 4 8 1083 2126 4546
+3905 2 2 4 8 1084 2124 4545
+3906 2 2 4 8 1087 4542 2123
+3907 2 2 4 8 1249 3224 2873
+3908 2 2 4 8 2111 1429 4495
+3909 2 2 4 8 2110 4494 1428
+3910 2 2 4 8 932 2348 4297
+3911 2 2 4 8 933 2349 4296
+3912 2 2 4 8 495 3607 2054
+3913 2 2 4 8 2587 4247 2913
+3914 2 2 4 8 488 5387 2087
+3915 2 2 4 8 1262 3452 2623
+3916 2 2 4 8 447 4322 2088
+3917 2 2 4 8 450 3355 5336
+3918 2 2 4 8 442 3356 5335
+3919 2 2 4 8 451 5337 3354
+3920 2 2 4 8 1620 2629 5212
+3921 2 2 4 8 625 2358 3730
+3922 2 2 4 8 1028 2384 2896
+3923 2 2 4 8 1029 2897 2385
+3924 2 2 4 8 927 2047 3733
+3925 2 2 4 8 928 3732 2048
+3926 2 2 4 8 1266 4844 2777
+3927 2 2 4 8 502 3927 2774
+3928 2 2 4 8 2094 5116 1176
+3929 2 2 4 8 707 3838 3012
+3930 2 2 4 8 706 3837 3011
+3931 2 2 4 8 2420 2582 5025
+3932 2 2 4 8 629 2907 2381
+3933 2 2 4 8 1580 2442 4689
+3934 2 2 4 8 994 3990 2634
+3935 2 2 4 8 995 3991 2635
+3936 2 2 4 8 67 3405 3439
+3937 2 2 4 8 526 3330 2217
+3938 2 2 4 8 2293 4067 2950
+3939 2 2 4 8 799 2051 4766
+3940 2 2 4 8 496 2474 2842
+3941 2 2 4 8 598 4358 2071
+3942 2 2 4 8 515 2874 3568
+3943 2 2 4 8 762 3572 3481
+3944 2 2 4 8 1783 3481 3572
+3945 2 2 4 8 1133 3029 4879
+3946 2 2 4 8 1212 2218 4665
+3947 2 2 4 8 1193 3092 3384
+3948 2 2 4 8 1192 3091 3383
+3949 2 2 4 8 3077 3470 4754
+3950 2 2 4 8 504 4950 2210
+3951 2 2 4 8 505 4951 2211
+3952 2 2 4 8 2060 3973 1132
+3953 2 2 4 8 468 2892 2399
+3954 2 2 4 8 2070 4253 1172
+3955 2 2 4 8 1106 2182 3118
+3956 2 2 4 8 1348 2535 2878
+3957 2 2 4 8 891 2878 2535
+3958 2 2 4 8 2062 1199 4074
+3959 2 2 4 8 1669 2851 5067
+3960 2 2 4 8 1692 4864 5062
+3961 2 2 4 8 663 2421 3719
+3962 2 2 4 8 2097 1187 4328
+3963 2 2 4 8 1010 2397 4280
+3964 2 2 4 8 1504 4280 2397
+3965 2 2 4 8 1072 2636 4003
+3966 2 2 4 8 1641 3454 4552
+3967 2 2 4 8 1358 4329 3106
+3968 2 2 4 8 14 4583 2158
+3969 2 2 4 8 1210 3347 4813
+3970 2 2 4 8 1234 3529 3482
+3971 2 2 4 8 489 2350 2949
+3972 2 2 4 8 771 4101 2297
+3973 2 2 4 8 1403 2297 4101
+3974 2 2 4 8 769 3373 2099
+3975 2 2 4 8 2099 3373 1161
+3976 2 2 4 8 2100 1160 3372
+3977 2 2 4 8 768 2100 3372
+3978 2 2 4 8 1081 3125 2183
+3979 2 2 4 8 817 4672 2229
+3980 2 2 4 8 1525 2229 4672
+3981 2 2 4 8 1457 2849 3904
+3982 2 2 4 8 331 332 3120
+3983 2 2 4 8 1439 4201 2383
+3984 2 2 4 8 971 2144 4633
+3985 2 2 4 8 459 3168 5318
+3986 2 2 4 8 1725 5229 3014
+3987 2 2 4 8 2097 3601 2597
+3988 2 2 4 8 1441 4533 2131
+3989 2 2 4 8 1440 4532 2132
+3990 2 2 4 8 687 3623 2791
+3991 2 2 4 8 1514 2449 4226
+3992 2 2 4 8 892 4226 2449
+3993 2 2 4 8 662 3821 2353
+3994 2 2 4 8 1398 2675 3569
+3995 2 2 4 8 1019 3569 2675
+3996 2 2 4 8 1068 4512 2986
+3997 2 2 4 8 1122 5409 2366
+3998 2 2 4 8 996 2268 3034
+3999 2 2 4 8 2075 1196 4750
+4000 2 2 4 8 791 2071 4090
+4001 2 2 4 8 790 2070 4089
+4002 2 2 4 8 708 4373 2586
+4003 2 2 4 8 1411 2834 4176
+4004 2 2 4 8 1078 2244 5118
+4005 2 2 4 8 598 2071 3511
+4006 2 2 4 8 417 418 3311
+4007 2 2 4 8 2100 4118 1160
+4008 2 2 4 8 2099 1161 4117
+4009 2 2 4 8 2091 3384 606
+4010 2 2 4 8 2092 3383 613
+4011 2 2 4 8 1414 2880 3877
+4012 2 2 4 8 941 4561 4781
+4013 2 2 4 8 1215 3413 2235
+4014 2 2 4 8 606 2235 3413
+4015 2 2 4 8 613 2236 3414
+4016 2 2 4 8 1217 3414 2236
+4017 2 2 4 8 531 3351 2103
+4018 2 2 4 8 532 3352 2104
+4019 2 2 4 8 676 2065 3992
+4020 2 2 4 8 1541 4179 2721
+4021 2 2 4 8 810 4937 2065
+4022 2 2 4 8 1466 2828 4094
+4023 2 2 4 8 1470 2824 4095
+4024 2 2 4 8 854 2286 4865
+4025 2 2 4 8 1595 4865 2286
+4026 2 2 4 8 648 5231 4959
+4027 2 2 4 8 650 5232 4960
+4028 2 2 4 8 1008 5345 2458
+4029 2 2 4 8 2078 4308 1182
+4030 2 2 4 8 941 2306 4561
+4031 2 2 4 8 1544 4927 4212
+4032 2 2 4 8 1460 2909 4070
+4033 2 2 4 8 1012 3813 3286
+4034 2 2 4 8 2091 606 3413
+4035 2 2 4 8 2092 613 3414
+4036 2 2 4 8 537 3937 3079
+4037 2 2 4 8 2094 1176 3929
+4038 2 2 4 8 857 2129 4431
+4039 2 2 4 8 419 2095 4255
+4040 2 2 4 8 885 3154 2186
+4041 2 2 4 8 838 3257 2136
+4042 2 2 4 8 538 4761 3239
+4043 2 2 4 8 1377 5137 3463
+4044 2 2 4 8 695 4258 2865
+4045 2 2 4 8 1185 3006 3203
+4046 2 2 4 8 102 2637 101
+4047 2 2 4 8 563 2886 4958
+4048 2 2 4 8 2006 4958 2886
+4049 2 2 4 8 1662 4796 2191
+4050 2 2 4 8 1815 4626 4031
+4051 2 2 4 8 932 2309 3183
+4052 2 2 4 8 933 2310 3182
+4053 2 2 4 8 1328 3619 3846
+4054 2 2 4 8 1327 3844 3618
+4055 2 2 4 8 1150 2987 4241
+4056 2 2 4 8 1020 2870 2484
+4057 2 2 4 8 538 2078 3586
+4058 2 2 4 8 2107 3369 1184
+4059 2 2 4 8 1691 2136 3613
+4060 2 2 4 8 478 2778 4799
+4061 2 2 4 8 2102 915 4289
+4062 2 2 4 8 249 250 4169
+4063 2 2 4 8 1219 3393 2514
+4064 2 2 4 8 947 3323 4211
+4065 2 2 4 8 1957 3881 2703
+4066 2 2 4 8 1574 2577 4531
+4067 2 2 4 8 2075 3835 1196
+4068 2 2 4 8 90 91 2638
+4069 2 2 4 8 86 87 3005
+4070 2 2 4 8 1423 4170 2609
+4071 2 2 4 8 1089 3111 2713
+4072 2 2 4 8 1087 3112 2712
+4073 2 2 4 8 1086 2714 3113
+4074 2 2 4 8 1085 2715 3114
+4075 2 2 4 8 1084 2716 3115
+4076 2 2 4 8 1083 2717 3116
+4077 2 2 4 8 454 2654 3964
+4078 2 2 4 8 324 325 4299
+4079 2 2 4 8 1393 5102 3426
+4080 2 2 4 8 849 2155 5316
+4081 2 2 4 8 1159 3051 4993
+4082 2 2 4 8 1013 2138 5204
+4083 2 2 4 8 71 3312 2133
+4084 2 2 4 8 1134 2882 4263
+4085 2 2 4 8 632 3049 5065
+4086 2 2 4 8 684 3792 2871
+4087 2 2 4 8 1009 4667 2133
+4088 2 2 4 8 852 2139 3362
+4089 2 2 4 8 853 2140 3363
+4090 2 2 4 8 653 3451 2341
+4091 2 2 4 8 1116 3004 4416
+4092 2 2 4 8 1471 3385 3207
+4093 2 2 4 8 671 2150 3250
+4094 2 2 4 8 672 2151 3251
+4095 2 2 4 8 2777 4844 3127
+4096 2 2 4 8 648 4012 2660
+4097 2 2 4 8 650 4011 2659
+4098 2 2 4 8 712 5196 4435
+4099 2 2 4 8 1798 4774 2190
+4100 2 2 4 8 1799 4773 2191
+4101 2 2 4 8 1506 3145 4758
+4102 2 2 4 8 1505 4757 3146
+4103 2 2 4 8 306 307 2959
+4104 2 2 4 8 295 296 2958
+4105 2 2 4 8 176 177 2957
+4106 2 2 4 8 132 2956 131
+4107 2 2 4 8 120 121 2955
+4108 2 2 4 8 2301 999 5303
+4109 2 2 4 8 2050 5268 3079
+4110 2 2 4 8 583 4814 2137
+4111 2 2 4 8 814 2226 4708
+4112 2 2 4 8 1522 4708 2226
+4113 2 2 4 8 815 2227 4709
+4114 2 2 4 8 1523 4709 2227
+4115 2 2 4 8 1524 4710 2228
+4116 2 2 4 8 823 2228 4710
+4117 2 2 4 8 1526 2230 4711
+4118 2 2 4 8 819 4711 2230
+4119 2 2 4 8 1647 3021 2876
+4120 2 2 4 8 694 2346 3000
+4121 2 2 4 8 2820 4128 1899
+4122 2 2 4 8 1898 4129 2819
+4123 2 2 4 8 1220 5144 4091
+4124 2 2 4 8 1244 2345 3700
+4125 2 2 4 8 997 2913 2439
+4126 2 2 4 8 480 3028 2312
+4127 2 2 4 8 479 3027 2313
+4128 2 2 4 8 356 2141 3298
+4129 2 2 4 8 169 2142 3299
+4130 2 2 4 8 1762 2414 5318
+4131 2 2 4 8 459 5318 2414
+4132 2 2 4 8 1835 2317 5390
+4133 2 2 4 8 2123 3693 5257
+4134 2 2 4 8 2121 3694 5256
+4135 2 2 4 8 2122 5258 3695
+4136 2 2 4 8 2124 5261 3697
+4137 2 2 4 8 2126 5260 3698
+4138 2 2 4 8 2125 5259 3696
+4139 2 2 4 8 652 3402 2433
+4140 2 2 4 8 816 4532 2146
+4141 2 2 4 8 824 4533 2147
+4142 2 2 4 8 1440 2146 4532
+4143 2 2 4 8 2147 4533 1441
+4144 2 2 4 8 662 2353 3064
+4145 2 2 4 8 1805 4727 3255
+4146 2 2 4 8 820 2161 3922
+4147 2 2 4 8 818 3923 2160
+4148 2 2 4 8 882 3263 5359
+4149 2 2 4 8 2097 4328 978
+4150 2 2 4 8 247 248 2661
+4151 2 2 4 8 190 3338 2159
+4152 2 2 4 8 1245 2159 3338
+4153 2 2 4 8 265 2974 4592
+4154 2 2 4 8 1438 3819 2833
+4155 2 2 4 8 2145 979 3280
+4156 2 2 4 8 443 4562 3038
+4157 2 2 4 8 2107 1184 3468
+4158 2 2 4 8 2107 3468 636
+4159 2 2 4 8 531 2103 4220
+4160 2 2 4 8 532 2104 4222
+4161 2 2 4 8 660 3999 2077
+4162 2 2 4 8 719 5037 3988
+4163 2 2 4 8 161 162 3631
+4164 2 2 4 8 348 349 3630
+4165 2 2 4 8 1482 2551 4178
+4166 2 2 4 8 1660 3380 2143
+4167 2 2 4 8 1207 5121 3275
+4168 2 2 4 8 2076 4770 1232
+4169 2 2 4 8 2099 4174 1364
+4170 2 2 4 8 2100 1365 4175
+4171 2 2 4 8 1498 3623 3227
+4172 2 2 4 8 1234 4646 3180
+4173 2 2 4 8 939 3900 2365
+4174 2 2 4 8 1234 3482 4646
+4175 2 2 4 8 581 5099 4548
+4176 2 2 4 8 1261 4847 2113
+4177 2 2 4 8 2145 1258 3292
+4178 2 2 4 8 38 3445 2506
+4179 2 2 4 8 26 2425 3432
+4180 2 2 4 8 535 2944 5307
+4181 2 2 4 8 1595 3957 3047
+4182 2 2 4 8 564 5008 2238
+4183 2 2 4 8 1261 2576 4984
+4184 2 2 4 8 1668 4751 2711
+4185 2 2 4 8 1165 4640 2141
+4186 2 2 4 8 1166 4641 2142
+4187 2 2 4 8 1223 3081 2572
+4188 2 2 4 8 475 2572 3081
+4189 2 2 4 8 1175 2332 3475
+4190 2 2 4 8 1220 4091 3343
+4191 2 2 4 8 820 4495 2161
+4192 2 2 4 8 1429 2161 4495
+4193 2 2 4 8 818 2160 4494
+4194 2 2 4 8 1428 4494 2160
+4195 2 2 4 8 407 4003 2636
+4196 2 2 4 8 1842 3757 2272
+4197 2 2 4 8 997 2439 4886
+4198 2 2 4 8 787 3835 2075
+4199 2 2 4 8 1658 4923 3193
+4200 2 2 4 8 1558 2424 3371
+4201 2 2 4 8 2941 4273 3307
+4202 2 2 4 8 2940 3308 4274
+4203 2 2 4 8 446 2268 3327
+4204 2 2 4 8 1197 3327 2268
+4205 2 2 4 8 774 3371 4184
+4206 2 2 4 8 88 89 4379
+4207 2 2 4 8 543 3601 2097
+4208 2 2 4 8 1759 3955 4440
+4209 2 2 4 8 588 3736 2198
+4210 2 2 4 8 287 3440 2110
+4211 2 2 4 8 256 2111 3441
+4212 2 2 4 8 66 3439 2112
+4213 2 2 4 8 1545 3556 3667
+4214 2 2 4 8 1062 3221 2185
+4215 2 2 4 8 486 2273 3549
+4216 2 2 4 8 1037 3269 2169
+4217 2 2 4 8 1038 3270 2170
+4218 2 2 4 8 1210 2249 3347
+4219 2 2 4 8 1211 3346 2250
+4220 2 2 4 8 252 3347 2249
+4221 2 2 4 8 246 2250 3346
+4222 2 2 4 8 1733 2559 3125
+4223 2 2 4 8 1457 3568 2874
+4224 2 2 4 8 1529 2458 4424
+4225 2 2 4 8 1528 2457 4423
+4226 2 2 4 8 892 3141 2235
+4227 2 2 4 8 893 3140 2236
+4228 2 2 4 8 891 3142 2234
+4229 2 2 4 8 1105 2687 5095
+4230 2 2 4 8 1226 3545 2575
+4231 2 2 4 8 919 3611 2493
+4232 2 2 4 8 2509 3368 1657
+4233 2 2 4 8 2510 3367 1656
+4234 2 2 4 8 1128 2831 2605
+4235 2 2 4 8 1640 3619 2554
+4236 2 2 4 8 1638 2555 3618
+4237 2 2 4 8 1135 5403 2307
+4238 2 2 4 8 938 2948 4657
+4239 2 2 4 8 2307 2735 4621
+4240 2 2 4 8 1113 3158 2222
+4241 2 2 4 8 1136 3843 2949
+4242 2 2 4 8 2084 840 3652
+4243 2 2 4 8 426 3287 2288
+4244 2 2 4 8 3 3288 2289
+4245 2 2 4 8 1167 2921 3064
+4246 2 2 4 8 2083 3969 898
+4247 2 2 4 8 648 2901 5231
+4248 2 2 4 8 650 2902 5232
+4249 2 2 4 8 1113 2398 2988
+4250 2 2 4 8 939 2394 3900
+4251 2 2 4 8 602 2912 2487
+4252 2 2 4 8 4169 4305 1530
+4253 2 2 4 8 2415 3910 2845
+4254 2 2 4 8 2494 3951 1773
+4255 2 2 4 8 2495 3950 1772
+4256 2 2 4 8 668 2164 5263
+4257 2 2 4 8 1030 2888 2526
+4258 2 2 4 8 1107 3295 2776
+4259 2 2 4 8 1123 5186 2439
+4260 2 2 4 8 483 3006 2473
+4261 2 2 4 8 1299 3599 2163
+4262 2 2 4 8 643 2163 3599
+4263 2 2 4 8 1453 4128 2438
+4264 2 2 4 8 1025 4129 2437
+4265 2 2 4 8 1026 2438 4128
+4266 2 2 4 8 1454 2437 4129
+4267 2 2 4 8 626 2544 3940
+4268 2 2 4 8 913 5368 2276
+4269 2 2 4 8 916 2277 5369
+4270 2 2 4 8 848 3983 2788
+4271 2 2 4 8 1911 3117 4933
+4272 2 2 4 8 114 3116 2717
+4273 2 2 4 8 125 3115 2716
+4274 2 2 4 8 136 3114 2715
+4275 2 2 4 8 181 3113 2714
+4276 2 2 4 8 302 2713 3111
+4277 2 2 4 8 291 2712 3112
+4278 2 2 4 8 1495 3094 3656
+4279 2 2 4 8 856 3125 2559
+4280 2 2 4 8 2088 4861 872
+4281 2 2 4 8 640 2606 2951
+4282 2 2 4 8 1177 2951 2606
+4283 2 2 4 8 1608 4147 3005
+4284 2 2 4 8 508 3387 3260
+4285 2 2 4 8 519 3388 3261
+4286 2 2 4 8 668 2843 2601
+4287 2 2 4 8 919 2524 3611
+4288 2 2 4 8 2089 795 4119
+4289 2 2 4 8 1048 2175 4606
+4290 2 2 4 8 1841 3914 3726
+4291 2 2 4 8 140 2132 3448
+4292 2 2 4 8 361 2131 3449
+4293 2 2 4 8 1122 2366 3442
+4294 2 2 4 8 1103 2440 4063
+4295 2 2 4 8 2087 3770 873
+4296 2 2 4 8 360 3449 3409
+4297 2 2 4 8 477 3513 2109
+4298 2 2 4 8 1403 2396 3053
+4299 2 2 4 8 1484 3680 2977
+4300 2 2 4 8 1695 5314 2315
+4301 2 2 4 8 1020 2994 2640
+4302 2 2 4 8 1017 2996 2642
+4303 2 2 4 8 1018 2641 2995
+4304 2 2 4 8 971 2544 4467
+4305 2 2 4 8 2098 4510 1277
+4306 2 2 4 8 1440 3382 2146
+4307 2 2 4 8 2094 3929 789
+4308 2 2 4 8 1052 4868 2481
+4309 2 2 4 8 1159 2694 5065
+4310 2 2 4 8 1304 3719 2421
+4311 2 2 4 8 2458 5345 2607
+4312 2 2 4 8 1177 2606 4584
+4313 2 2 4 8 1252 2644 3034
+4314 2 2 4 8 996 3034 2644
+4315 2 2 4 8 528 2489 2927
+4316 2 2 4 8 1557 3007 5153
+4317 2 2 4 8 1661 3377 2156
+4318 2 2 4 8 486 4842 2393
+4319 2 2 4 8 1028 3016 2649
+4320 2 2 4 8 1029 2650 3018
+4321 2 2 4 8 1030 2651 3017
+4322 2 2 4 8 1358 2453 3178
+4323 2 2 4 8 2108 1418 4163
+4324 2 2 4 8 44 2975 4642
+4325 2 2 4 8 1019 2675 3031
+4326 2 2 4 8 1052 2490 4868
+4327 2 2 4 8 2295 4594 2790
+4328 2 2 4 8 1202 3331 4815
+4329 2 2 4 8 1150 5304 2924
+4330 2 2 4 8 2224 2669 5007
+4331 2 2 4 8 583 2188 3289
+4332 2 2 4 8 629 4192 2333
+4333 2 2 4 8 590 5213 2634
+4334 2 2 4 8 591 5214 2635
+4335 2 2 4 8 794 4693 3381
+4336 2 2 4 8 959 2558 4468
+4337 2 2 4 8 1358 3855 2453
+4338 2 2 4 8 964 2453 3855
+4339 2 2 4 8 1457 2610 2849
+4340 2 2 4 8 627 4007 2538
+4341 2 2 4 8 1418 4000 2463
+4342 2 2 4 8 704 2463 4000
+4343 2 2 4 8 625 3730 2528
+4344 2 2 4 8 569 2258 3157
+4345 2 2 4 8 258 259 2709
+4346 2 2 4 8 284 285 2710
+4347 2 2 4 8 64 2708 63
+4348 2 2 4 8 554 2569 3015
+4349 2 2 4 8 1177 3015 2569
+4350 2 2 4 8 897 4687 3256
+4351 2 2 4 8 2164 3256 4687
+4352 2 2 4 8 1435 2582 4691
+4353 2 2 4 8 1045 4935 2794
+4354 2 2 4 8 1134 4263 4477
+4355 2 2 4 8 1133 2300 4898
+4356 2 2 4 8 1758 3960 4448
+4357 2 2 4 8 663 2183 4301
+4358 2 2 4 8 1150 4052 5304
+4359 2 2 4 8 2103 1268 4220
+4360 2 2 4 8 2104 1269 4222
+4361 2 2 4 8 695 4696 4258
+4362 2 2 4 8 1094 2299 5215
+4363 2 2 4 8 1208 4366 2128
+4364 2 2 4 8 1046 4936 2796
+4365 2 2 4 8 1154 2862 4414
+4366 2 2 4 8 466 3391 2165
+4367 2 2 4 8 385 4295 2649
+4368 2 2 4 8 147 2650 4294
+4369 2 2 4 8 368 2651 4293
+4370 2 2 4 8 620 3030 2382
+4371 2 2 4 8 1022 3690 2328
+4372 2 2 4 8 1271 2328 3690
+4373 2 2 4 8 1637 4327 4803
+4374 2 2 4 8 957 5294 2381
+4375 2 2 4 8 1712 2381 5294
+4376 2 2 4 8 1051 2269 3156
+4377 2 2 4 8 1209 4217 2127
+4378 2 2 4 8 1272 3035 2379
+4379 2 2 4 8 855 2577 5048
+4380 2 2 4 8 468 4863 5296
+4381 2 2 4 8 649 3086 2314
+4382 2 2 4 8 1564 2114 4755
+4383 2 2 4 8 1563 2115 4756
+4384 2 2 4 8 96 97 2692
+4385 2 2 4 8 855 3324 4338
+4386 2 2 4 8 2050 4338 3324
+4387 2 2 4 8 1221 3651 2163
+4388 2 2 4 8 1957 3354 4112
+4389 2 2 4 8 1006 4112 3354
+4390 2 2 4 8 959 2134 4261
+4391 2 2 4 8 1737 3218 4130
+4392 2 2 4 8 821 2112 4070
+4393 2 2 4 8 1982 2469 4369
+4394 2 2 4 8 859 2315 4406
+4395 2 2 4 8 630 3283 3087
+4396 2 2 4 8 1486 3087 3283
+4397 2 2 4 8 1135 2367 5403
+4398 2 2 4 8 847 2323 4983
+4399 2 2 4 8 1623 4983 2323
+4400 2 2 4 8 1065 3284 2203
+4401 2 2 4 8 2106 1168 4230
+4402 2 2 4 8 602 2322 4968
+4403 2 2 4 8 1619 4968 2322
+4404 2 2 4 8 1213 3473 2234
+4405 2 2 4 8 603 2234 3473
+4406 2 2 4 8 1834 3605 4753
+4407 2 2 4 8 205 206 4265
+4408 2 2 4 8 422 423 4264
+4409 2 2 4 8 221 222 4266
+4410 2 2 4 8 439 440 4267
+4411 2 2 4 8 4176 2834 4839
+4412 2 2 4 8 1218 4232 3257
+4413 2 2 4 8 1617 3849 3081
+4414 2 2 4 8 1285 3739 2173
+4415 2 2 4 8 870 2216 4841
+4416 2 2 4 8 914 2174 3403
+4417 2 2 4 8 1035 5006 2498
+4418 2 2 4 8 1688 3083 5052
+4419 2 2 4 8 1683 3082 5053
+4420 2 2 4 8 1110 2545 2917
+4421 2 2 4 8 1831 3658 3597
+4422 2 2 4 8 781 3597 3658
+4423 2 2 4 8 1533 4506 2388
+4424 2 2 4 8 553 2388 4506
+4425 2 2 4 8 467 5207 2303
+4426 2 2 4 8 1688 3585 2295
+4427 2 2 4 8 635 4832 2441
+4428 2 2 4 8 1285 2173 3968
+4429 2 2 4 8 1023 3079 2742
+4430 2 2 4 8 972 4157 2805
+4431 2 2 4 8 578 4448 2490
+4432 2 2 4 8 749 5120 3305
+4433 2 2 4 8 1198 3283 2690
+4434 2 2 4 8 603 3473 2147
+4435 2 2 4 8 607 3474 2146
+4436 2 2 4 8 194 195 4483
+4437 2 2 4 8 1946 4628 5076
+4438 2 2 4 8 340 341 4357
+4439 2 2 4 8 1261 2113 3856
+4440 2 2 4 8 1326 3049 2848
+4441 2 2 4 8 63 2708 2866
+4442 2 2 4 8 259 2867 2709
+4443 2 2 4 8 284 2710 2868
+4444 2 2 4 8 263 2641 4213
+4445 2 2 4 8 59 4215 2640
+4446 2 2 4 8 280 4214 2642
+4447 2 2 4 8 1032 2933 2531
+4448 2 2 4 8 645 3500 4588
+4449 2 2 4 8 2853 3047 1162
+4450 2 2 4 8 1452 4250 2113
+4451 2 2 4 8 1227 2693 3605
+4452 2 2 4 8 1501 5122 4031
+4453 2 2 4 8 1920 4356 4992
+4454 2 2 4 8 1221 4032 3366
+4455 2 2 4 8 1302 5353 2917
+4456 2 2 4 8 2018 3718 4385
+4457 2 2 4 8 1725 3014 4921
+4458 2 2 4 8 619 3545 4217
+4459 2 2 4 8 2127 4217 3545
+4460 2 2 4 8 1025 2819 4129
+4461 2 2 4 8 1026 4128 2820
+4462 2 2 4 8 1213 3581 3188
+4463 2 2 4 8 1215 3582 3190
+4464 2 2 4 8 1827 5004 2727
+4465 2 2 4 8 796 2727 5004
+4466 2 2 4 8 412 413 2711
+4467 2 2 4 8 3092 4680 3384
+4468 2 2 4 8 3091 4679 3383
+4469 2 2 4 8 1054 4846 2504
+4470 2 2 4 8 1053 4845 2505
+4471 2 2 4 8 1302 3289 5353
+4472 2 2 4 8 1496 4964 2118
+4473 2 2 4 8 1053 2511 4845
+4474 2 2 4 8 1054 2512 4846
+4475 2 2 4 8 142 143 2723
+4476 2 2 4 8 363 364 2722
+4477 2 2 4 8 629 2381 4192
+4478 2 2 4 8 1019 2685 2837
+4479 2 2 4 8 1387 2327 4138
+4480 2 2 4 8 799 4139 2326
+4481 2 2 4 8 800 4138 2327
+4482 2 2 4 8 1386 2326 4139
+4483 2 2 4 8 626 2934 2544
+4484 2 2 4 8 1795 5147 3090
+4485 2 2 4 8 2664 4096 5139
+4486 2 2 4 8 622 2319 3145
+4487 2 2 4 8 623 3146 2320
+4488 2 2 4 8 143 2854 2723
+4489 2 2 4 8 364 2855 2722
+4490 2 2 4 8 543 2119 4630
+4491 2 2 4 8 982 2659 4011
+4492 2 2 4 8 983 2660 4012
+4493 2 2 4 8 188 189 3970
+4494 2 2 4 8 523 4893 2694
+4495 2 2 4 8 1780 2694 4893
+4496 2 2 4 8 1463 3484 3244
+4497 2 2 4 8 1462 3483 3246
+4498 2 2 4 8 1468 3241 3486
+4499 2 2 4 8 1469 3240 3487
+4500 2 2 4 8 1315 2486 3682
+4501 2 2 4 8 487 3682 2486
+4502 2 2 4 8 240 3401 239
+4503 2 2 4 8 1004 4243 2800
+4504 2 2 4 8 1005 4245 2801
+4505 2 2 4 8 703 2608 3641
+4506 2 2 4 8 1017 2642 3632
+4507 2 2 4 8 1362 3632 2642
+4508 2 2 4 8 1018 3633 2641
+4509 2 2 4 8 1361 2641 3633
+4510 2 2 4 8 1355 2466 3847
+4511 2 2 4 8 965 3847 2466
+4512 2 2 4 8 963 2467 3848
+4513 2 2 4 8 1356 3848 2467
+4514 2 2 4 8 767 2542 4490
+4515 2 2 4 8 1578 4490 2542
+4516 2 2 4 8 1577 4489 2543
+4517 2 2 4 8 766 2543 4489
+4518 2 2 4 8 461 2270 5003
+4519 2 2 4 8 1100 3261 2761
+4520 2 2 4 8 1101 3260 2760
+4521 2 2 4 8 1683 3873 2373
+4522 2 2 4 8 1685 2374 3874
+4523 2 2 4 8 888 2159 4313
+4524 2 2 4 8 1095 5155 2298
+4525 2 2 4 8 2515 3763 1941
+4526 2 2 4 8 1309 3238 2254
+4527 2 2 4 8 1069 2172 4387
+4528 2 2 4 8 922 2299 3499
+4529 2 2 4 8 1396 2861 3578
+4530 2 2 4 8 1397 2860 3579
+4531 2 2 4 8 1570 2282 3572
+4532 2 2 4 8 1571 2281 3571
+4533 2 2 4 8 1133 3214 2442
+4534 2 2 4 8 549 3269 5108
+4535 2 2 4 8 550 3270 5109
+4536 2 2 4 8 103 3443 2386
+4537 2 2 4 8 1413 2910 4014
+4538 2 2 4 8 669 3573 2148
+4539 2 2 4 8 670 3574 2149
+4540 2 2 4 8 4167 4900 1693
+4541 2 2 4 8 1687 4073 2406
+4542 2 2 4 8 712 3453 5196
+4543 2 2 4 8 1149 2207 3376
+4544 2 2 4 8 1513 2654 4370
+4545 2 2 4 8 811 2143 4170
+4546 2 2 4 8 76 2196 4798
+4547 2 2 4 8 1185 2473 3006
+4548 2 2 4 8 643 2410 3043
+4549 2 2 4 8 1132 2315 3762
+4550 2 2 4 8 166 4648 2411
+4551 2 2 4 8 353 4647 2412
+4552 2 2 4 8 407 408 4003
+4553 2 2 4 8 1831 3597 2627
+4554 2 2 4 8 1001 5152 2303
+4555 2 2 4 8 1397 2798 3941
+4556 2 2 4 8 1257 2506 3445
+4557 2 2 4 8 763 3699 3104
+4558 2 2 4 8 1627 3104 3699
+4559 2 2 4 8 1479 2904 2603
+4560 2 2 4 8 1480 2602 2906
+4561 2 2 4 8 1481 2604 2905
+4562 2 2 4 8 1011 3726 3914
+4563 2 2 4 8 1124 2511 4441
+4564 2 2 4 8 587 4440 2512
+4565 2 2 4 8 1133 2442 3029
+4566 2 2 4 8 833 2137 4195
+4567 2 2 4 8 1697 2666 3827
+4568 2 2 4 8 714 2914 4305
+4569 2 2 4 8 561 4765 2232
+4570 2 2 4 8 351 4948 2212
+4571 2 2 4 8 164 4947 2213
+4572 2 2 4 8 2044 2293 5106
+4573 2 2 4 8 575 2252 3769
+4574 2 2 4 8 1039 3528 2171
+4575 2 2 4 8 401 2173 3739
+4576 2 2 4 8 1252 4193 3617
+4577 2 2 4 8 1221 2163 4300
+4578 2 2 4 8 885 2150 3627
+4579 2 2 4 8 672 3626 2151
+4580 2 2 4 8 1141 3145 2319
+4581 2 2 4 8 1142 2320 3146
+4582 2 2 4 8 2441 4832 5063
+4583 2 2 4 8 642 4659 2605
+4584 2 2 4 8 915 4881 2256
+4585 2 2 4 8 911 4880 2255
+4586 2 2 4 8 1127 3880 2601
+4587 2 2 4 8 1288 3612 2158
+4588 2 2 4 8 700 5289 3614
+4589 2 2 4 8 940 3143 2331
+4590 2 2 4 8 708 5197 3392
+4591 2 2 4 8 490 2372 3756
+4592 2 2 4 8 872 4861 2549
+4593 2 2 4 8 982 5043 2284
+4594 2 2 4 8 983 5044 2285
+4595 2 2 4 8 1077 3552 2243
+4596 2 2 4 8 1076 3551 2245
+4597 2 2 4 8 599 2330 4019
+4598 2 2 4 8 680 4143 2799
+4599 2 2 4 8 1202 4144 2135
+4600 2 2 4 8 515 2525 4260
+4601 2 2 4 8 1859 2214 4907
+4602 2 2 4 8 1860 2215 4908
+4603 2 2 4 8 2145 5326 1258
+4604 2 2 4 8 719 2979 5037
+4605 2 2 4 8 1640 3326 5110
+4606 2 2 4 8 1689 2400 4043
+4607 2 2 4 8 382 383 3013
+4608 2 2 4 8 1871 4096 2664
+4609 2 2 4 8 558 2262 4890
+4610 2 2 4 8 1324 3027 3378
+4611 2 2 4 8 1325 3028 3379
+4612 2 2 4 8 32 2328 3645
+4613 2 2 4 8 1271 3645 2328
+4614 2 2 4 8 552 2509 4903
+4615 2 2 4 8 2509 1657 4903
+4616 2 2 4 8 553 2510 4902
+4617 2 2 4 8 2510 1656 4902
+4618 2 2 4 8 1539 3011 3837
+4619 2 2 4 8 1540 3012 3838
+4620 2 2 4 8 4140 5406 2266
+4621 2 2 4 8 1407 3707 3975
+4622 2 2 4 8 860 2920 5350
+4623 2 2 4 8 1161 2305 4117
+4624 2 2 4 8 1160 4118 2304
+4625 2 2 4 8 874 3390 2341
+4626 2 2 4 8 598 2216 4358
+4627 2 2 4 8 718 2221 3395
+4628 2 2 4 8 1684 3898 2380
+4629 2 2 4 8 1325 3720 3028
+4630 2 2 4 8 1324 3722 3027
+4631 2 2 4 8 1182 4308 2196
+4632 2 2 4 8 937 2344 3745
+4633 2 2 4 8 936 3744 2343
+4634 2 2 4 8 1224 4038 3332
+4635 2 2 4 8 1009 2258 4667
+4636 2 2 4 8 392 4056 2357
+4637 2 2 4 8 2217 3330 5244
+4638 2 2 4 8 1346 3229 2768
+4639 2 2 4 8 857 2768 3229
+4640 2 2 4 8 913 2402 5368
+4641 2 2 4 8 916 5369 2403
+4642 2 2 4 8 682 3147 3042
+4643 2 2 4 8 1555 3042 3147
+4644 2 2 4 8 1289 2379 3758
+4645 2 2 4 8 717 3758 2379
+4646 2 2 4 8 1014 4952 2711
+4647 2 2 4 8 8 3460 2311
+4648 2 2 4 8 643 4300 2163
+4649 2 2 4 8 561 2643 4765
+4650 2 2 4 8 698 2396 4109
+4651 2 2 4 8 1403 4109 2396
+4652 2 2 4 8 1071 2840 2753
+4653 2 2 4 8 1435 3203 2899
+4654 2 2 4 8 923 3124 2366
+4655 2 2 4 8 1288 2158 4162
+4656 2 2 4 8 2195 4362 2894
+4657 2 2 4 8 1253 4630 3303
+4658 2 2 4 8 2105 2844 5165
+4659 2 2 4 8 2119 3303 4630
+4660 2 2 4 8 923 2366 5409
+4661 2 2 4 8 586 3743 2154
+4662 2 2 4 8 1241 3854 4156
+4663 2 2 4 8 30 2179 3592
+4664 2 2 4 8 1797 4115 4284
+4665 2 2 4 8 1078 5118 2967
+4666 2 2 4 8 17 2935 16
+4667 2 2 4 8 391 2357 4279
+4668 2 2 4 8 1164 2723 2854
+4669 2 2 4 8 1163 2722 2855
+4670 2 2 4 8 1165 2252 4640
+4671 2 2 4 8 1166 2253 4641
+4672 2 2 4 8 457 2424 3223
+4673 2 2 4 8 816 3191 2827
+4674 2 2 4 8 1487 2827 3191
+4675 2 2 4 8 815 3190 2826
+4676 2 2 4 8 2826 3190 1488
+4677 2 2 4 8 1490 2828 3192
+4678 2 2 4 8 2825 814 3189
+4679 2 2 4 8 2825 3189 1489
+4680 2 2 4 8 823 3192 2828
+4681 2 2 4 8 1491 2824 3188
+4682 2 2 4 8 824 3188 2824
+4683 2 2 4 8 677 2748 4230
+4684 2 2 4 8 818 4069 2554
+4685 2 2 4 8 820 2555 4068
+4686 2 2 4 8 1461 2554 4069
+4687 2 2 4 8 1464 4068 2555
+4688 2 2 4 8 2778 5418 1711
+4689 2 2 4 8 1240 4385 3718
+4690 2 2 4 8 1418 2463 3085
+4691 2 2 4 8 1761 3881 4807
+4692 2 2 4 8 649 2314 5185
+4693 2 2 4 8 312 313 2749
+4694 2 2 4 8 979 3477 2213
+4695 2 2 4 8 849 3796 2155
+4696 2 2 4 8 1246 2155 3796
+4697 2 2 4 8 1376 3813 3656
+4698 2 2 4 8 1570 4978 2282
+4699 2 2 4 8 1008 2282 4978
+4700 2 2 4 8 1419 3491 3237
+4701 2 2 4 8 10 2155 5208
+4702 2 2 4 8 656 5403 2367
+4703 2 2 4 8 188 3332 187
+4704 2 2 4 8 1245 4313 2159
+4705 2 2 4 8 2578 1864 3733
+4706 2 2 4 8 1863 2579 3732
+4707 2 2 4 8 816 2146 5031
+4708 2 2 4 8 824 2147 5030
+4709 2 2 4 8 520 2883 3340
+4710 2 2 4 8 517 3339 2884
+4711 2 2 4 8 1371 3340 2883
+4712 2 2 4 8 1370 2884 3339
+4713 2 2 4 8 1188 2213 3477
+4714 2 2 4 8 1156 2866 2708
+4715 2 2 4 8 1157 2709 2867
+4716 2 2 4 8 1158 2868 2710
+4717 2 2 4 8 978 4328 2212
+4718 2 2 4 8 457 2584 3753
+4719 2 2 4 8 1357 3753 2584
+4720 2 2 4 8 1626 5042 4705
+4721 2 2 4 8 667 4643 2639
+4722 2 2 4 8 341 3565 4357
+4723 2 2 4 8 1678 2431 3209
+4724 2 2 4 8 337 338 3117
+4725 2 2 4 8 1343 3426 2774
+4726 2 2 4 8 501 3424 2773
+4727 2 2 4 8 1342 2773 3424
+4728 2 2 4 8 502 2774 3426
+4729 2 2 4 8 499 3421 2772
+4730 2 2 4 8 1341 2772 3421
+4731 2 2 4 8 631 3447 2443
+4732 2 2 4 8 409 410 3366
+4733 2 2 4 8 862 3459 2314
+4734 2 2 4 8 895 5045 2590
+4735 2 2 4 8 1725 2590 5045
+4736 2 2 4 8 2090 4784 3412
+4737 2 2 4 8 602 3204 2322
+4738 2 2 4 8 647 3989 2678
+4739 2 2 4 8 744 3194 3842
+4740 2 2 4 8 1699 3842 3194
+4741 2 2 4 8 807 2156 3913
+4742 2 2 4 8 808 2157 3912
+4743 2 2 4 8 486 2393 3119
+4744 2 2 4 8 549 4518 2214
+4745 2 2 4 8 550 4519 2215
+4746 2 2 4 8 1744 2963 4849
+4747 2 2 4 8 1146 2340 4674
+4748 2 2 4 8 1697 3827 3186
+4749 2 2 4 8 745 3186 3827
+4750 2 2 4 8 1675 3959 2971
+4751 2 2 4 8 700 2971 3959
+4752 2 2 4 8 1309 2254 4021
+4753 2 2 4 8 530 4021 2254
+4754 2 2 4 8 1182 4041 3101
+4755 2 2 4 8 1081 2167 4107
+4756 2 2 4 8 343 2980 342
+4757 2 2 4 8 294 3533 5399
+4758 2 2 4 8 305 3534 5400
+4759 2 2 4 8 178 5398 3535
+4760 2 2 4 8 133 5397 3532
+4761 2 2 4 8 122 5396 3531
+4762 2 2 4 8 812 3906 2429
+4763 2 2 4 8 1346 2429 3906
+4764 2 2 4 8 596 4253 3510
+4765 2 2 4 8 2070 3510 4253
+4766 2 2 4 8 1255 2172 5140
+4767 2 2 4 8 713 4130 3218
+4768 2 2 4 8 324 4299 2891
+4769 2 2 4 8 1065 2203 4463
+4770 2 2 4 8 1066 4464 2204
+4771 2 2 4 8 1307 2633 3866
+4772 2 2 4 8 562 4918 2278
+4773 2 2 4 8 914 2279 4919
+4774 2 2 4 8 1553 3250 3998
+4775 2 2 4 8 20 3518 2208
+4776 2 2 4 8 832 2862 3417
+4777 2 2 4 8 1737 5317 3218
+4778 2 2 4 8 118 2226 3487
+4779 2 2 4 8 129 2227 3486
+4780 2 2 4 8 174 2228 3485
+4781 2 2 4 8 298 3483 2229
+4782 2 2 4 8 309 3484 2230
+4783 2 2 4 8 442 2906 5348
+4784 2 2 4 8 450 2905 5347
+4785 2 2 4 8 2098 3176 5023
+4786 2 2 4 8 1189 5244 3330
+4787 2 2 4 8 3326 2144 5110
+4788 2 2 4 8 2611 4435 3078
+4789 2 2 4 8 605 3412 4784
+4790 2 2 4 8 468 5296 2892
+4791 2 2 4 8 319 320 4608
+4792 2 2 4 8 1483 4194 2880
+4793 2 2 4 8 646 3002 2911
+4794 2 2 4 8 1264 2911 3002
+4795 2 2 4 8 788 2405 3467
+4796 2 2 4 8 1243 3467 2405
+4797 2 2 4 8 294 295 3533
+4798 2 2 4 8 305 306 3534
+4799 2 2 4 8 178 3535 177
+4800 2 2 4 8 132 133 3532
+4801 2 2 4 8 121 122 3531
+4802 2 2 4 8 1199 4887 4074
+4803 2 2 4 8 691 2613 3801
+4804 2 2 4 8 1389 3801 2613
+4805 2 2 4 8 1473 2871 3792
+4806 2 2 4 8 332 333 2793
+4807 2 2 4 8 483 5012 3006
+4808 2 2 4 8 690 2615 3802
+4809 2 2 4 8 1390 3802 2615
+4810 2 2 4 8 876 4790 2981
+4811 2 2 4 8 1274 3948 2347
+4812 2 2 4 8 1302 2917 3320
+4813 2 2 4 8 674 3321 2751
+4814 2 2 4 8 1300 2752 3319
+4815 2 2 4 8 673 3319 2752
+4816 2 2 4 8 1301 2751 3321
+4817 2 2 4 8 879 3557 2206
+4818 2 2 4 8 877 3558 2205
+4819 2 2 4 8 2507 1839 3793
+4820 2 2 4 8 2508 1840 3794
+4821 2 2 4 8 646 4039 2193
+4822 2 2 4 8 1802 4853 3236
+4823 2 2 4 8 114 115 3116
+4824 2 2 4 8 125 126 3115
+4825 2 2 4 8 136 137 3114
+4826 2 2 4 8 181 182 3113
+4827 2 2 4 8 301 302 3111
+4828 2 2 4 8 290 291 3112
+4829 2 2 4 8 1140 4389 2199
+4830 2 2 4 8 1138 4390 2201
+4831 2 2 4 8 614 2286 3328
+4832 2 2 4 8 967 2330 3226
+4833 2 2 4 8 403 404 3052
+4834 2 2 4 8 2574 3897 4988
+4835 2 2 4 8 2573 4987 3896
+4836 2 2 4 8 680 2916 4143
+4837 2 2 4 8 1584 5056 2319
+4838 2 2 4 8 891 2234 4638
+4839 2 2 4 8 548 3528 5153
+4840 2 2 4 8 856 3772 2183
+4841 2 2 4 8 1244 5324 2345
+4842 2 2 4 8 2117 4074 4887
+4843 2 2 4 8 1198 2237 4637
+4844 2 2 4 8 1211 4463 2203
+4845 2 2 4 8 1210 2204 4464
+4846 2 2 4 8 567 2427 4621
+4847 2 2 4 8 2057 5348 2906
+4848 2 2 4 8 2059 5347 2905
+4849 2 2 4 8 1400 2589 3728
+4850 2 2 4 8 974 2789 3370
+4851 2 2 4 8 1323 3370 2789
+4852 2 2 4 8 1827 2727 4252
+4853 2 2 4 8 1179 3152 2461
+4854 2 2 4 8 905 2461 3152
+4855 2 2 4 8 1499 2788 3983
+4856 2 2 4 8 962 2196 4308
+4857 2 2 4 8 1616 2435 3132
+4858 2 2 4 8 1266 3132 2435
+4859 2 2 4 8 1106 4289 2594
+4860 2 2 4 8 1347 2968 3703
+4861 2 2 4 8 530 2194 4278
+4862 2 2 4 8 1519 4048 2981
+4863 2 2 4 8 2654 4888 3964
+4864 2 2 4 8 529 4637 2237
+4865 2 2 4 8 1286 3476 2979
+4866 2 2 4 8 1456 2979 3476
+4867 2 2 4 8 571 2253 3689
+4868 2 2 4 8 556 4498 2521
+4869 2 2 4 8 1550 2521 4498
+4870 2 2 4 8 1493 3993 4601
+4871 2 2 4 8 1352 3502 2782
+4872 2 2 4 8 1353 2783 3503
+4873 2 2 4 8 512 2334 5198
+4874 2 2 4 8 563 2279 4877
+4875 2 2 4 8 1011 2188 3726
+4876 2 2 4 8 37 2506 3080
+4877 2 2 4 8 1169 3080 2506
+4878 2 2 4 8 1954 4638 2413
+4879 2 2 4 8 508 2889 3387
+4880 2 2 4 8 1382 3387 2889
+4881 2 2 4 8 519 2890 3388
+4882 2 2 4 8 1383 3388 2890
+4883 2 2 4 8 2497 2356 4409
+4884 2 2 4 8 666 4345 2202
+4885 2 2 4 8 759 3199 3815
+4886 2 2 4 8 1676 3815 3199
+4887 2 2 4 8 486 2614 4842
+4888 2 2 4 8 1721 5137 2573
+4889 2 2 4 8 752 2573 5137
+4890 2 2 4 8 107 2323 3870
+4891 2 2 4 8 1425 4553 2662
+4892 2 2 4 8 1306 3259 3917
+4893 2 2 4 8 1757 3917 3259
+4894 2 2 4 8 686 2591 3858
+4895 2 2 4 8 1386 3858 2591
+4896 2 2 4 8 1580 5264 3029
+4897 2 2 4 8 490 3756 2454
+4898 2 2 4 8 660 4283 2768
+4899 2 2 4 8 529 2240 4637
+4900 2 2 4 8 385 386 4295
+4901 2 2 4 8 146 147 4294
+4902 2 2 4 8 367 368 4293
+4903 2 2 4 8 1663 2983 5097
+4904 2 2 4 8 1333 4008 2850
+4905 2 2 4 8 920 2219 4965
+4906 2 2 4 8 1110 5353 2188
+4907 2 2 4 8 1574 5028 2342
+4908 2 2 4 8 1987 3302 3834
+4909 2 2 4 8 615 2220 3594
+4910 2 2 4 8 822 3593 2220
+4911 2 2 4 8 1628 2529 3936
+4912 2 2 4 8 1347 2197 4281
+4913 2 2 4 8 859 2283 4878
+4914 2 2 4 8 2162 3603 3275
+4915 2 2 4 8 1061 3833 2184
+4916 2 2 4 8 1261 4984 3258
+4917 2 2 4 8 1554 4153 2465
+4918 2 2 4 8 1690 4919 4958
+4919 2 2 4 8 1327 2830 3907
+4920 2 2 4 8 832 3417 2947
+4921 2 2 4 8 1187 2212 4328
+4922 2 2 4 8 948 5017 2553
+4923 2 2 4 8 666 2730 5068
+4924 2 2 4 8 844 2798 3579
+4925 2 2 4 8 1397 3579 2798
+4926 2 2 4 8 843 2797 3578
+4927 2 2 4 8 1396 3578 2797
+4928 2 2 4 8 1198 4637 2240
+4929 2 2 4 8 1008 3431 5345
+4930 2 2 4 8 1679 4604 3293
+4931 2 2 4 8 584 2403 4581
+4932 2 2 4 8 585 2404 4580
+4933 2 2 4 8 1663 4354 2983
+4934 2 2 4 8 868 4276 2241
+4935 2 2 4 8 1417 3353 2586
+4936 2 2 4 8 2549 4861 5074
+4937 2 2 4 8 1258 2628 3292
+4938 2 2 4 8 544 3292 2628
+4939 2 2 4 8 1167 2705 2921
+4940 2 2 4 8 1633 4944 3288
+4941 2 2 4 8 1632 4943 3287
+4942 2 2 4 8 1897 2545 4396
+4943 2 2 4 8 1324 4602 3723
+4944 2 2 4 8 491 2436 3128
+4945 2 2 4 8 559 2295 4910
+4946 2 2 4 8 974 4355 2789
+4947 2 2 4 8 1921 2789 4355
+4948 2 2 4 8 1781 3156 4862
+4949 2 2 4 8 1974 3006 5012
+4950 2 2 4 8 1830 3617 4193
+4951 2 2 4 8 1474 2760 3260
+4952 2 2 4 8 1475 2761 3261
+4953 2 2 4 8 454 4613 2248
+4954 2 2 4 8 890 3523 3208
+4955 2 2 4 8 1581 3208 3523
+4956 2 2 4 8 2307 5403 3105
+4957 2 2 4 8 656 3105 5403
+4958 2 2 4 8 1239 3684 2214
+4959 2 2 4 8 1242 3683 2215
+4960 2 2 4 8 1134 2558 4650
+4961 2 2 4 8 614 5176 2286
+4962 2 2 4 8 581 2256 5182
+4963 2 2 4 8 2203 3806 2720
+4964 2 2 4 8 1273 3196 3735
+4965 2 2 4 8 1641 3735 3196
+4966 2 2 4 8 865 2209 4271
+4967 2 2 4 8 863 4269 2210
+4968 2 2 4 8 864 4270 2211
+4969 2 2 4 8 1923 4156 3854
+4970 2 2 4 8 809 5251 5149
+4971 2 2 4 8 1325 4766 3721
+4972 2 2 4 8 559 2239 4594
+4973 2 2 4 8 1141 3713 2444
+4974 2 2 4 8 1142 2445 3712
+4975 2 2 4 8 1109 3661 2496
+4976 2 2 4 8 1478 4362 2195
+4977 2 2 4 8 1235 3179 3570
+4978 2 2 4 8 35 4231 34
+4979 2 2 4 8 1177 4584 3015
+4980 2 2 4 8 3071 2388 3949
+4981 2 2 4 8 2624 4278 2194
+4982 2 2 4 8 299 300 3246
+4983 2 2 4 8 310 311 3244
+4984 2 2 4 8 288 289 3245
+4985 2 2 4 8 183 184 3243
+4986 2 2 4 8 138 139 3242
+4987 2 2 4 8 127 128 3241
+4988 2 2 4 8 116 117 3240
+4989 2 2 4 8 892 2449 3672
+4990 2 2 4 8 893 2450 3673
+4991 2 2 4 8 937 3745 2444
+4992 2 2 4 8 936 2445 3744
+4993 2 2 4 8 918 5173 2262
+4994 2 2 4 8 719 3988 2894
+4995 2 2 4 8 1588 2894 3988
+4996 2 2 4 8 2432 4326 3681
+4997 2 2 4 8 456 3809 5211
+4998 2 2 4 8 838 4538 3257
+4999 2 2 4 8 1160 4055 2945
+5000 2 2 4 8 1161 2946 4054
+5001 2 2 4 8 951 2324 5095
+5002 2 2 4 8 568 2204 4209
+5003 2 2 4 8 1369 4127 3908
+5004 2 2 4 8 1773 3951 4833
+5005 2 2 4 8 1772 3950 4834
+5006 2 2 4 8 1476 3295 3568
+5007 2 2 4 8 1716 3304 3805
+5008 2 2 4 8 748 3805 3304
+5009 2 2 4 8 749 3305 3803
+5010 2 2 4 8 1714 3803 3305
+5011 2 2 4 8 750 3804 3306
+5012 2 2 4 8 1715 3306 3804
+5013 2 2 4 8 1855 4291 3364
+5014 2 2 4 8 1280 3066 2534
+5015 2 2 4 8 76 4041 2196
+5016 2 2 4 8 1576 2540 3508
+5017 2 2 4 8 1575 2541 3509
+5018 2 2 4 8 1276 2434 3911
+5019 2 2 4 8 2001 3353 4346
+5020 2 2 4 8 503 4346 3353
+5021 2 2 4 8 1000 3554 2244
+5022 2 2 4 8 999 2243 3553
+5023 2 2 4 8 1001 2245 3555
+5024 2 2 4 8 1769 2539 4341
+5025 2 2 4 8 856 4167 2998
+5026 2 2 4 8 1693 2998 4167
+5027 2 2 4 8 1608 5132 2441
+5028 2 2 4 8 838 4256 4538
+5029 2 2 4 8 1386 2695 3893
+5030 2 2 4 8 874 2448 3390
+5031 2 2 4 8 555 2380 5309
+5032 2 2 4 8 564 3806 2203
+5033 2 2 4 8 1224 2264 3594
+5034 2 2 4 8 615 3594 2264
+5035 2 2 4 8 1225 3544 2620
+5036 2 2 4 8 351 2212 4183
+5037 2 2 4 8 164 2213 4182
+5038 2 2 4 8 1622 2638 4636
+5039 2 2 4 8 262 263 4213
+5040 2 2 4 8 60 4215 59
+5041 2 2 4 8 280 281 4214
+5042 2 2 4 8 644 3155 2439
+5043 2 2 4 8 2011 4781 4561
+5044 2 2 4 8 1175 4299 2332
+5045 2 2 4 8 703 3407 4172
+5046 2 2 4 8 1941 4172 3407
+5047 2 2 4 8 2336 1295 5129
+5048 2 2 4 8 1556 4793 2392
+5049 2 2 4 8 708 2392 4793
+5050 2 2 4 8 1141 2319 5056
+5051 2 2 4 8 1219 2320 5054
+5052 2 2 4 8 1142 5055 2320
+5053 2 2 4 8 1122 3635 2233
+5054 2 2 4 8 752 3863 3307
+5055 2 2 4 8 1730 3307 3863
+5056 2 2 4 8 754 3309 3861
+5057 2 2 4 8 1732 3861 3309
+5058 2 2 4 8 1731 3862 3308
+5059 2 2 4 8 753 3308 3862
+5060 2 2 4 8 62 63 2866
+5061 2 2 4 8 259 260 2867
+5062 2 2 4 8 283 284 2868
+5063 2 2 4 8 684 3057 3792
+5064 2 2 4 8 525 2225 3675
+5065 2 2 4 8 1139 3876 2200
+5066 2 2 4 8 2850 4008 4422
+5067 2 2 4 8 547 2499 4342
+5068 2 2 4 8 2499 1494 4342
+5069 2 2 4 8 930 3195 2572
+5070 2 2 4 8 1223 2572 3195
+5071 2 2 4 8 918 2257 3548
+5072 2 2 4 8 1111 2790 4594
+5073 2 2 4 8 913 2278 5148
+5074 2 2 4 8 1033 4685 2533
+5075 2 2 4 8 452 2562 5169
+5076 2 2 4 8 1712 5169 2562
+5077 2 2 4 8 1613 3050 5322
+5078 2 2 4 8 1350 4695 3075
+5079 2 2 4 8 1349 4694 3076
+5080 2 2 4 8 665 3681 2786
+5081 2 2 4 8 1211 2250 4463
+5082 2 2 4 8 1210 4464 2249
+5083 2 2 4 8 1133 4879 2300
+5084 2 2 4 8 1460 3439 3405
+5085 2 2 4 8 630 3087 4587
+5086 2 2 4 8 809 3948 2202
+5087 2 2 4 8 592 3833 4686
+5088 2 2 4 8 814 4333 2226
+5089 2 2 4 8 815 4334 2227
+5090 2 2 4 8 823 4337 2228
+5091 2 2 4 8 817 2229 4335
+5092 2 2 4 8 819 2230 4336
+5093 2 2 4 8 1707 4629 2262
+5094 2 2 4 8 873 3609 2433
+5095 2 2 4 8 681 3265 3055
+5096 2 2 4 8 701 3895 3869
+5097 2 2 4 8 2060 3869 3895
+5098 2 2 4 8 871 2208 4896
+5099 2 2 4 8 677 4230 2978
+5100 2 2 4 8 574 5123 3322
+5101 2 2 4 8 1226 5383 3276
+5102 2 2 4 8 488 3512 2370
+5103 2 2 4 8 1547 4151 2742
+5104 2 2 4 8 711 2742 4151
+5105 2 2 4 8 1472 3792 3057
+5106 2 2 4 8 984 4872 2871
+5107 2 2 4 8 1844 2871 4872
+5108 2 2 4 8 1866 4042 2475
+5109 2 2 4 8 1231 2860 2954
+5110 2 2 4 8 502 2954 2860
+5111 2 2 4 8 1208 2263 4366
+5112 2 2 4 8 364 365 2855
+5113 2 2 4 8 144 2854 143
+5114 2 2 4 8 1576 3508 3822
+5115 2 2 4 8 1575 3509 3823
+5116 2 2 4 8 2544 2934 4467
+5117 2 2 4 8 890 2520 3523
+5118 2 2 4 8 1074 2894 2895
+5119 2 2 4 8 1588 2895 2894
+5120 2 2 4 8 1623 2970 4288
+5121 2 2 4 8 896 2431 5293
+5122 2 2 4 8 1678 5293 2431
+5123 2 2 4 8 1321 2513 5130
+5124 2 2 4 8 2780 3205 4887
+5125 2 2 4 8 4173 1565 4557
+5126 2 2 4 8 618 3544 4366
+5127 2 2 4 8 2128 4366 3544
+5128 2 2 4 8 1229 2861 2960
+5129 2 2 4 8 500 2960 2861
+5130 2 2 4 8 548 4152 2219
+5131 2 2 4 8 444 2246 4449
+5132 2 2 4 8 968 4450 2247
+5133 2 2 4 8 1547 3079 3937
+5134 2 2 4 8 1304 3471 3625
+5135 2 2 4 8 718 3820 2221
+5136 2 2 4 8 1239 2271 3684
+5137 2 2 4 8 827 3684 2271
+5138 2 2 4 8 873 2447 3609
+5139 2 2 4 8 1076 2255 4549
+5140 2 2 4 8 1077 2256 4548
+5141 2 2 4 8 1590 4444 2684
+5142 2 2 4 8 1591 2683 4445
+5143 2 2 4 8 1234 3180 3301
+5144 2 2 4 8 1235 3300 3179
+5145 2 2 4 8 809 2779 5251
+5146 2 2 4 8 1739 3262 4179
+5147 2 2 4 8 1066 2249 4464
+5148 2 2 4 8 1065 4463 2250
+5149 2 2 4 8 473 5007 2329
+5150 2 2 4 8 1807 5164 2280
+5151 2 2 4 8 913 2276 3526
+5152 2 2 4 8 916 3527 2277
+5153 2 2 4 8 851 4635 2237
+5154 2 2 4 8 1155 2942 4824
+5155 2 2 4 8 1501 4031 4626
+5156 2 2 4 8 940 3540 2562
+5157 2 2 4 8 1649 2877 3093
+5158 2 2 4 8 1861 2711 5308
+5159 2 2 4 8 1146 2491 4160
+5160 2 2 4 8 370 371 3045
+5161 2 2 4 8 150 3044 149
+5162 2 2 4 8 1514 3182 2449
+5163 2 2 4 8 1515 3183 2450
+5164 2 2 4 8 1322 2519 3984
+5165 2 2 4 8 1275 3809 3271
+5166 2 2 4 8 1693 3271 3809
+5167 2 2 4 8 4170 5184 2609
+5168 2 2 4 8 958 4369 2238
+5169 2 2 4 8 1491 3188 3581
+5170 2 2 4 8 1488 3190 3582
+5171 2 2 4 8 1172 4253 2317
+5172 2 2 4 8 1593 4453 4657
+5173 2 2 4 8 2643 4480 4765
+5174 2 2 4 8 2514 1684 5199
+5175 2 2 4 8 585 2514 5199
+5176 2 2 4 8 2513 1897 3774
+5177 2 2 4 8 2336 5061 917
+5178 2 2 4 8 1264 3002 3264
+5179 2 2 4 8 229 3215 2455
+5180 2 2 4 8 94 2251 4416
+5181 2 2 4 8 1970 3394 5040
+5182 2 2 4 8 556 5246 2374
+5183 2 2 4 8 554 2373 5245
+5184 2 2 4 8 1101 2760 3035
+5185 2 2 4 8 893 2236 4752
+5186 2 2 4 8 2148 5370 4943
+5187 2 2 4 8 2149 5371 4944
+5188 2 2 4 8 545 4819 2832
+5189 2 2 4 8 103 2386 5290
+5190 2 2 4 8 981 3169 4699
+5191 2 2 4 8 529 4904 2240
+5192 2 2 4 8 1246 2311 3460
+5193 2 2 4 8 1417 2231 4161
+5194 2 2 4 8 1651 3068 4990
+5195 2 2 4 8 3069 4991 1650
+5196 2 2 4 8 1162 3957 2941
+5197 2 2 4 8 1052 3151 2490
+5198 2 2 4 8 865 4828 2833
+5199 2 2 4 8 1188 3184 4182
+5200 2 2 4 8 1187 3185 4183
+5201 2 2 4 8 542 4286 2518
+5202 2 2 4 8 1477 2518 4286
+5203 2 2 4 8 2336 582 5079
+5204 2 2 4 8 608 3361 2356
+5205 2 2 4 8 1109 4461 3549
+5206 2 2 4 8 756 3364 4291
+5207 2 2 4 8 530 2254 3685
+5208 2 2 4 8 12 13 3019
+5209 2 2 4 8 685 3680 2822
+5210 2 2 4 8 1421 2822 3680
+5211 2 2 4 8 1314 2261 4136
+5212 2 2 4 8 1313 2260 4133
+5213 2 2 4 8 2418 5026 2645
+5214 2 2 4 8 2419 2646 5024
+5215 2 2 4 8 545 2832 4651
+5216 2 2 4 8 1027 4636 2638
+5217 2 2 4 8 755 2550 4141
+5218 2 2 4 8 25 26 3432
+5219 2 2 4 8 1019 2837 3569
+5220 2 2 4 8 99 2442 3214
+5221 2 2 4 8 892 2235 4226
+5222 2 2 4 8 613 4227 2236
+5223 2 2 4 8 794 3381 4746
+5224 2 2 4 8 1153 2527 4997
+5225 2 2 4 8 1283 2863 3154
+5226 2 2 4 8 2864 1282 3153
+5227 2 2 4 8 1350 3516 4695
+5228 2 2 4 8 1349 3517 4694
+5229 2 2 4 8 846 3973 4788
+5230 2 2 4 8 3006 4860 3203
+5231 2 2 4 8 1143 5368 2402
+5232 2 2 4 8 978 2412 5411
+5233 2 2 4 8 667 4045 2340
+5234 2 2 4 8 792 4315 2693
+5235 2 2 4 8 1536 3935 3880
+5236 2 2 4 8 529 2237 3866
+5237 2 2 4 8 1080 2267 4504
+5238 2 2 4 8 1684 5142 5199
+5239 2 2 4 8 1087 3291 2732
+5240 2 2 4 8 989 3187 2468
+5241 2 2 4 8 1164 2940 3382
+5242 2 2 4 8 2056 2416 4166
+5243 2 2 4 8 892 3672 2536
+5244 2 2 4 8 893 3673 2537
+5245 2 2 4 8 1995 3218 5317
+5246 2 2 4 8 1548 2849 4653
+5247 2 2 4 8 1197 4319 2921
+5248 2 2 4 8 508 3260 2422
+5249 2 2 4 8 519 3261 2423
+5250 2 2 4 8 1053 3174 2511
+5251 2 2 4 8 1054 3175 2512
+5252 2 2 4 8 1574 2342 5048
+5253 2 2 4 8 909 2232 3962
+5254 2 2 4 8 1106 4811 4289
+5255 2 2 4 8 2138 3177 5204
+5256 2 2 4 8 852 3362 2407
+5257 2 2 4 8 853 3363 2408
+5258 2 2 4 8 939 2528 5274
+5259 2 2 4 8 1707 5274 2528
+5260 2 2 4 8 388 389 2853
+5261 2 2 4 8 930 3798 3195
+5262 2 2 4 8 1643 3195 3798
+5263 2 2 4 8 600 4963 2391
+5264 2 2 4 8 601 4962 2390
+5265 2 2 4 8 2015 2334 4977
+5266 2 2 4 8 255 3441 3446
+5267 2 2 4 8 570 5258 3134
+5268 2 2 4 8 1721 3463 5137
+5269 2 2 4 8 1170 2455 3215
+5270 2 2 4 8 1489 3189 3334
+5271 2 2 4 8 1214 3334 3189
+5272 2 2 4 8 1487 3191 3335
+5273 2 2 4 8 1216 3335 3191
+5274 2 2 4 8 2241 4276 2739
+5275 2 2 4 8 1505 2343 4757
+5276 2 2 4 8 1506 4758 2344
+5277 2 2 4 8 1493 3234 3993
+5278 2 2 4 8 1330 3810 4099
+5279 2 2 4 8 1651 4990 4122
+5280 2 2 4 8 1650 4991 4123
+5281 2 2 4 8 1020 2640 3775
+5282 2 2 4 8 1360 3775 2640
+5283 2 2 4 8 1034 3178 2497
+5284 2 2 4 8 726 2683 4408
+5285 2 2 4 8 1591 4408 2683
+5286 2 2 4 8 2941 3957 5176
+5287 2 2 4 8 999 2527 4688
+5288 2 2 4 8 1340 3872 4097
+5289 2 2 4 8 1807 3420 2519
+5290 2 2 4 8 1303 2519 3420
+5291 2 2 4 8 1750 2699 5023
+5292 2 2 4 8 1036 5023 2699
+5293 2 2 4 8 850 4800 2254
+5294 2 2 4 8 888 4378 2264
+5295 2 2 4 8 905 5247 2321
+5296 2 2 4 8 460 3717 2271
+5297 2 2 4 8 827 2271 3718
+5298 2 2 4 8 1559 4148 2984
+5299 2 2 4 8 1560 4149 2985
+5300 2 2 4 8 1841 2967 5118
+5301 2 2 4 8 1762 4004 3668
+5302 2 2 4 8 576 2300 5097
+5303 2 2 4 8 1357 2584 3256
+5304 2 2 4 8 897 3256 2584
+5305 2 2 4 8 926 3258 2443
+5306 2 2 4 8 2692 4891 4275
+5307 2 2 4 8 1241 2270 3854
+5308 2 2 4 8 618 4366 2263
+5309 2 2 4 8 1619 2322 4889
+5310 2 2 4 8 1241 3899 2270
+5311 2 2 4 8 1518 3748 4084
+5312 2 2 4 8 383 4526 3013
+5313 2 2 4 8 1246 3460 5208
+5314 2 2 4 8 2151 3626 4249
+5315 2 2 4 8 261 262 3252
+5316 2 2 4 8 282 3253 281
+5317 2 2 4 8 61 3254 60
+5318 2 2 4 8 649 3103 2658
+5319 2 2 4 8 1369 3908 2784
+5320 2 2 4 8 1961 2784 3908
+5321 2 2 4 8 1455 4702 3395
+5322 2 2 4 8 1189 3330 3290
+5323 2 2 4 8 1519 3290 3330
+5324 2 2 4 8 34 3032 33
+5325 2 2 4 8 569 3832 2258
+5326 2 2 4 8 654 4488 2259
+5327 2 2 4 8 416 2345 5324
+5328 2 2 4 8 2267 5027 5300
+5329 2 2 4 8 1804 2364 5126
+5330 2 2 4 8 2514 3393 5009
+5331 2 2 4 8 1233 3453 2350
+5332 2 2 4 8 1520 4473 4389
+5333 2 2 4 8 1521 4475 4390
+5334 2 2 4 8 1352 3070 3502
+5335 2 2 4 8 1176 5204 3177
+5336 2 2 4 8 1762 3668 2414
+5337 2 2 4 8 1801 2870 3775
+5338 2 2 4 8 1827 4252 5249
+5339 2 2 4 8 941 4720 2306
+5340 2 2 4 8 545 3493 2343
+5341 2 2 4 8 546 2344 3494
+5342 2 2 4 8 430 3868 2260
+5343 2 2 4 8 212 3867 2261
+5344 2 2 4 8 863 3737 2832
+5345 2 2 4 8 1436 2832 3737
+5346 2 2 4 8 2582 3429 4691
+5347 2 2 4 8 488 2370 3418
+5348 2 2 4 8 1168 3385 2737
+5349 2 2 4 8 489 2371 3419
+5350 2 2 4 8 1470 3409 3449
+5351 2 2 4 8 896 2462 4497
+5352 2 2 4 8 1499 4497 2462
+5353 2 2 4 8 2086 4503 3072
+5354 2 2 4 8 788 3834 2434
+5355 2 2 4 8 1297 2434 3834
+5356 2 2 4 8 1493 2484 4372
+5357 2 2 4 8 1969 3549 4461
+5358 2 2 4 8 2439 3155 4886
+5359 2 2 4 8 1530 4305 4871
+5360 2 2 4 8 1171 3602 2456
+5361 2 2 4 8 1284 2583 3126
+5362 2 2 4 8 663 4301 2421
+5363 2 2 4 8 448 2365 5089
+5364 2 2 4 8 647 3442 2366
+5365 2 2 4 8 2778 3556 1545
+5366 2 2 4 8 1380 2407 3362
+5367 2 2 4 8 1381 2408 3363
+5368 2 2 4 8 854 4979 2286
+5369 2 2 4 8 1677 2590 4367
+5370 2 2 4 8 842 2259 3968
+5371 2 2 4 8 366 367 3316
+5372 2 2 4 8 145 146 3317
+5373 2 2 4 8 386 387 3318
+5374 2 2 4 8 937 2444 3300
+5375 2 2 4 8 936 3301 2445
+5376 2 2 4 8 1812 5098 2794
+5377 2 2 4 8 1045 2794 5098
+5378 2 2 4 8 461 3854 2270
+5379 2 2 4 8 1684 2380 5142
+5380 2 2 4 8 1048 3497 2367
+5381 2 2 4 8 645 2342 3500
+5382 2 2 4 8 1280 2382 4537
+5383 2 2 4 8 1538 2278 4437
+5384 2 2 4 8 1416 3595 3357
+5385 2 2 4 8 424 3588 2375
+5386 2 2 4 8 1281 2375 3588
+5387 2 2 4 8 1284 3591 2378
+5388 2 2 4 8 1283 3590 2377
+5389 2 2 4 8 438 2378 3591
+5390 2 2 4 8 220 2377 3590
+5391 2 2 4 8 207 3589 2376
+5392 2 2 4 8 1282 2376 3589
+5393 2 2 4 8 1566 2732 5367
+5394 2 2 4 8 649 2658 3086
+5395 2 2 4 8 1314 4024 2261
+5396 2 2 4 8 1313 4023 2260
+5397 2 2 4 8 899 2265 4191
+5398 2 2 4 8 622 3145 2598
+5399 2 2 4 8 623 2599 3146
+5400 2 2 4 8 895 4067 2293
+5401 2 2 4 8 401 402 4567
+5402 2 2 4 8 1551 4870 3475
+5403 2 2 4 8 966 3219 2503
+5404 2 2 4 8 4226 4259 1514
+5405 2 2 4 8 1107 2776 3066
+5406 2 2 4 8 826 2270 3899
+5407 2 2 4 8 339 2347 4933
+5408 2 2 4 8 1233 4670 2296
+5409 2 2 4 8 635 3342 5352
+5410 2 2 4 8 1693 4900 3271
+5411 2 2 4 8 1653 2887 3514
+5412 2 2 4 8 754 4015 3089
+5413 2 2 4 8 2397 4786 3498
+5414 2 2 4 8 250 251 3282
+5415 2 2 4 8 1639 3845 3765
+5416 2 2 4 8 1033 5025 2582
+5417 2 2 4 8 56 57 3109
+5418 2 2 4 8 277 278 3110
+5419 2 2 4 8 1384 2266 4051
+5420 2 2 4 8 1932 5285 2273
+5421 2 2 4 8 841 5076 4628
+5422 2 2 4 8 1197 2705 3046
+5423 2 2 4 8 1083 3058 2667
+5424 2 2 4 8 1084 3059 2668
+5425 2 2 4 8 1378 2651 3826
+5426 2 2 4 8 1030 3826 2651
+5427 2 2 4 8 1345 2425 3814
+5428 2 2 4 8 27 3814 2425
+5429 2 2 4 8 1476 2776 3295
+5430 2 2 4 8 1318 3371 2424
+5431 2 2 4 8 747 4179 3262
+5432 2 2 4 8 1155 4824 5413
+5433 2 2 4 8 474 2277 5221
+5434 2 2 4 8 472 5222 2276
+5435 2 2 4 8 1502 2526 4439
+5436 2 2 4 8 1222 2386 3443
+5437 2 2 4 8 1103 2386 5156
+5438 2 2 4 8 1223 3219 4700
+5439 2 2 4 8 635 2441 3342
+5440 2 2 4 8 1703 3198 2721
+5441 2 2 4 8 886 2291 4400
+5442 2 2 4 8 599 4019 2593
+5443 2 2 4 8 1554 3827 2666
+5444 2 2 4 8 1186 3005 3659
+5445 2 2 4 8 851 2273 4033
+5446 2 2 4 8 1625 3148 3916
+5447 2 2 4 8 1373 3524 2857
+5448 2 2 4 8 728 2857 3524
+5449 2 2 4 8 2633 5047 3866
+5450 2 2 4 8 678 3046 2705
+5451 2 2 4 8 1100 3054 2728
+5452 2 2 4 8 1206 2728 3054
+5453 2 2 4 8 883 4034 2288
+5454 2 2 4 8 1281 2288 4034
+5455 2 2 4 8 1115 4561 2306
+5456 2 2 4 8 1889 5350 2430
+5457 2 2 4 8 806 4404 5100
+5458 2 2 4 8 805 4405 5101
+5459 2 2 4 8 909 3979 2335
+5460 2 2 4 8 1322 3667 3556
+5461 2 2 4 8 1043 3967 2782
+5462 2 2 4 8 1175 3475 2777
+5463 2 2 4 8 399 3181 4367
+5464 2 2 4 8 967 4747 2330
+5465 2 2 4 8 1319 2769 3142
+5466 2 2 4 8 1320 2770 3141
+5467 2 2 4 8 1321 2771 3140
+5468 2 2 4 8 1328 3996 2829
+5469 2 2 4 8 321 2551 3225
+5470 2 2 4 8 1561 4491 4144
+5471 2 2 4 8 1234 3301 3896
+5472 2 2 4 8 1235 3897 3300
+5473 2 2 4 8 2498 5006 3333
+5474 2 2 4 8 1496 3144 3456
+5475 2 2 4 8 688 3456 3144
+5476 2 2 4 8 1380 4219 4121
+5477 2 2 4 8 1381 4221 4120
+5478 2 2 4 8 1170 3344 2455
+5479 2 2 4 8 1171 2456 3345
+5480 2 2 4 8 2322 3204 4529
+5481 2 2 4 8 463 2282 3966
+5482 2 2 4 8 512 3893 2695
+5483 2 2 4 8 1665 4993 2611
+5484 2 2 4 8 712 2611 4993
+5485 2 2 4 8 1700 3436 4780
+5486 2 2 4 8 1407 3635 3707
+5487 2 2 4 8 1089 3093 2877
+5488 2 2 4 8 1750 5023 3176
+5489 2 2 4 8 1546 3963 2283
+5490 2 2 4 8 586 5072 3743
+5491 2 2 4 8 709 4225 2283
+5492 2 2 4 8 1001 2630 4377
+5493 2 2 4 8 1595 2286 3957
+5494 2 2 4 8 1365 4623 2372
+5495 2 2 4 8 1411 3133 2834
+5496 2 2 4 8 1179 2843 5263
+5497 2 2 4 8 1184 5193 2398
+5498 2 2 4 8 1277 3357 3595
+5499 2 2 4 8 971 4633 3279
+5500 2 2 4 8 546 4820 2344
+5501 2 2 4 8 1506 2344 4820
+5502 2 2 4 8 1505 4819 2343
+5503 2 2 4 8 545 2343 4819
+5504 2 2 4 8 981 4517 3169
+5505 2 2 4 8 1890 3969 2596
+5506 2 2 4 8 1676 4085 5065
+5507 2 2 4 8 1232 3401 4092
+5508 2 2 4 8 1167 5344 2705
+5509 2 2 4 8 852 5090 3172
+5510 2 2 4 8 853 5091 3173
+5511 2 2 4 8 1085 3050 2731
+5512 2 2 4 8 1550 5022 2521
+5513 2 2 4 8 585 5199 2404
+5514 2 2 4 8 1622 4636 4332
+5515 2 2 4 8 976 2521 3709
+5516 2 2 4 8 2162 3275 4983
+5517 2 2 4 8 847 4983 3275
+5518 2 2 4 8 1206 3067 2728
+5519 2 2 4 8 612 2728 3067
+5520 2 2 4 8 925 2499 3905
+5521 2 2 4 8 1284 4400 2291
+5522 2 2 4 8 1770 5231 2700
+5523 2 2 4 8 1138 2700 5231
+5524 2 2 4 8 1140 2701 5232
+5525 2 2 4 8 1771 5232 2701
+5526 2 2 4 8 1269 3390 2448
+5527 2 2 4 8 897 2702 4687
+5528 2 2 4 8 1634 4687 2702
+5529 2 2 4 8 1385 4005 2292
+5530 2 2 4 8 342 2980 5107
+5531 2 2 4 8 938 2417 4309
+5532 2 2 4 8 1436 4087 2384
+5533 2 2 4 8 1438 2385 4088
+5534 2 2 4 8 624 2530 3429
+5535 2 2 4 8 1207 2292 5227
+5536 2 2 4 8 42 2675 4402
+5537 2 2 4 8 1400 3728 3791
+5538 2 2 4 8 1159 3932 2694
+5539 2 2 4 8 3179 4866 3570
+5540 2 2 4 8 1422 3795 2805
+5541 2 2 4 8 972 2805 3795
+5542 2 2 4 8 526 2968 4281
+5543 2 2 4 8 1117 4311 2745
+5544 2 2 4 8 1985 5073 3731
+5545 2 2 4 8 1109 2496 3325
+5546 2 2 4 8 1343 2658 3103
+5547 2 2 4 8 465 2430 5300
+5548 2 2 4 8 185 2900 4599
+5549 2 2 4 8 1639 3765 2556
+5550 2 2 4 8 1975 4664 3209
+5551 2 2 4 8 858 3209 4664
+5552 2 2 4 8 3039 3296 1246
+5553 2 2 4 8 1222 5156 2386
+5554 2 2 4 8 651 2547 3701
+5555 2 2 4 8 698 2753 3791
+5556 2 2 4 8 1400 3791 2753
+5557 2 2 4 8 2572 4397 2879
+5558 2 2 4 8 1869 4194 3505
+5559 2 2 4 8 1511 3046 4100
+5560 2 2 4 8 1326 2350 4777
+5561 2 2 4 8 615 2498 3333
+5562 2 2 4 8 1717 2834 4724
+5563 2 2 4 8 875 4724 2834
+5564 2 2 4 8 1810 3262 3736
+5565 2 2 4 8 1129 3736 3262
+5566 2 2 4 8 515 3295 2525
+5567 2 2 4 8 2482 4959 2920
+5568 2 2 4 8 2483 4960 2919
+5569 2 2 4 8 226 227 2945
+5570 2 2 4 8 200 201 2946
+5571 2 2 4 8 1291 2534 3760
+5572 2 2 4 8 715 3760 2534
+5573 2 2 4 8 1272 2379 3584
+5574 2 2 4 8 1788 2898 5269
+5575 2 2 4 8 961 4972 3255
+5576 2 2 4 8 874 2296 4066
+5577 2 2 4 8 2122 3134 5258
+5578 2 2 4 8 1660 4759 4720
+5579 2 2 4 8 1403 4116 2297
+5580 2 2 4 8 871 2340 3702
+5581 2 2 4 8 877 2338 4704
+5582 2 2 4 8 878 2339 4703
+5583 2 2 4 8 921 4076 2298
+5584 2 2 4 8 2837 5323 3569
+5585 2 2 4 8 1330 2524 3930
+5586 2 2 4 8 492 3930 2524
+5587 2 2 4 8 306 2959 3534
+5588 2 2 4 8 295 2958 3533
+5589 2 2 4 8 177 3535 2957
+5590 2 2 4 8 132 3532 2956
+5591 2 2 4 8 121 3531 2955
+5592 2 2 4 8 1195 4288 2970
+5593 2 2 4 8 2357 4865 4279
+5594 2 2 4 8 1273 2446 3812
+5595 2 2 4 8 894 3812 2446
+5596 2 2 4 8 2498 4378 1928
+5597 2 2 4 8 527 3310 2973
+5598 2 2 4 8 1013 5204 2581
+5599 2 2 4 8 558 2394 5075
+5600 2 2 4 8 1345 2786 3681
+5601 2 2 4 8 969 5407 2566
+5602 2 2 4 8 941 2475 3380
+5603 2 2 4 8 997 4669 2587
+5604 2 2 4 8 593 4117 2305
+5605 2 2 4 8 594 2304 4118
+5606 2 2 4 8 974 3370 2539
+5607 2 2 4 8 184 185 4599
+5608 2 2 4 8 449 4252 2306
+5609 2 2 4 8 166 167 4648
+5610 2 2 4 8 353 354 4647
+5611 2 2 4 8 1166 4343 2736
+5612 2 2 4 8 1233 2350 4670
+5613 2 2 4 8 664 2953 3118
+5614 2 2 4 8 536 3916 3148
+5615 2 2 4 8 847 4566 2323
+5616 2 2 4 8 1195 2970 3831
+5617 2 2 4 8 325 3921 2332
+5618 2 2 4 8 1165 4239 2663
+5619 2 2 4 8 567 4621 2735
+5620 2 2 4 8 1176 5116 2581
+5621 2 2 4 8 1650 2390 5035
+5622 2 2 4 8 1651 2391 5036
+5623 2 2 4 8 1104 2309 4297
+5624 2 2 4 8 1105 2310 4296
+5625 2 2 4 8 1132 4406 2315
+5626 2 2 4 8 871 4674 2340
+5627 2 2 4 8 972 3795 2538
+5628 2 2 4 8 1569 4992 4356
+5629 2 2 4 8 1278 2846 5210
+5630 2 2 4 8 2846 1865 5210
+5631 2 2 4 8 676 3992 2501
+5632 2 2 4 8 1336 2501 3992
+5633 2 2 4 8 952 2308 4042
+5634 2 2 4 8 1630 5267 2394
+5635 2 2 4 8 960 4905 3236
+5636 2 2 4 8 784 4817 3056
+5637 2 2 4 8 1483 3505 4194
+5638 2 2 4 8 1680 5408 2454
+5639 2 2 4 8 572 5235 3348
+5640 2 2 4 8 1075 2997 3647
+5641 2 2 4 8 1473 3647 2997
+5642 2 2 4 8 1878 2452 5364
+5643 2 2 4 8 731 3691 4088
+5644 2 2 4 8 695 3303 2775
+5645 2 2 4 8 1547 2742 3079
+5646 2 2 4 8 645 3754 2342
+5647 2 2 4 8 976 3709 2570
+5648 2 2 4 8 1232 4240 2354
+5649 2 2 4 8 1171 3345 4411
+5650 2 2 4 8 985 2977 4873
+5651 2 2 4 8 1845 4873 2977
+5652 2 2 4 8 2639 4643 3710
+5653 2 2 4 8 859 4406 2696
+5654 2 2 4 8 1672 2482 5358
+5655 2 2 4 8 860 5358 2482
+5656 2 2 4 8 1196 2468 4750
+5657 2 2 4 8 110 2970 109
+5658 2 2 4 8 819 2556 3765
+5659 2 2 4 8 3027 4677 3378
+5660 2 2 4 8 3028 4676 3379
+5661 2 2 4 8 1430 4465 2322
+5662 2 2 4 8 2693 4207 3605
+5663 2 2 4 8 1169 2631 4743
+5664 2 2 4 8 1091 4049 2312
+5665 2 2 4 8 1092 4050 2313
+5666 2 2 4 8 1655 4124 4823
+5667 2 2 4 8 1101 5201 2422
+5668 2 2 4 8 1619 2422 5201
+5669 2 2 4 8 1091 2312 4190
+5670 2 2 4 8 1092 2313 4189
+5671 2 2 4 8 1685 5072 4880
+5672 2 2 4 8 1153 4997 2726
+5673 2 2 4 8 1568 4714 2805
+5674 2 2 4 8 465 5300 5027
+5675 2 2 4 8 1522 2955 3879
+5676 2 2 4 8 1194 3879 2955
+5677 2 2 4 8 1526 3878 2959
+5678 2 2 4 8 1191 2959 3878
+5679 2 2 4 8 399 400 3181
+5680 2 2 4 8 1544 4212 4306
+5681 2 2 4 8 624 3429 2582
+5682 2 2 4 8 1386 3893 2326
+5683 2 2 4 8 1387 3892 2327
+5684 2 2 4 8 1671 2483 5378
+5685 2 2 4 8 861 5378 2483
+5686 2 2 4 8 862 2314 4478
+5687 2 2 4 8 1395 3991 3823
+5688 2 2 4 8 1394 3990 3822
+5689 2 2 4 8 489 4670 2350
+5690 2 2 4 8 1209 2409 4217
+5691 2 2 4 8 544 2763 3292
+5692 2 2 4 8 924 4159 2580
+5693 2 2 4 8 1787 3225 5174
+5694 2 2 4 8 968 2565 3377
+5695 2 2 4 8 1108 3730 2358
+5696 2 2 4 8 683 4712 3127
+5697 2 2 4 8 2060 4788 3973
+5698 2 2 4 8 1463 2556 4336
+5699 2 2 4 8 819 4336 2556
+5700 2 2 4 8 771 3668 4004
+5701 2 2 4 8 1375 2858 4185
+5702 2 2 4 8 600 2565 4963
+5703 2 2 4 8 601 2566 4962
+5704 2 2 4 8 651 3336 2547
+5705 2 2 4 8 724 2484 4601
+5706 2 2 4 8 1493 4601 2484
+5707 2 2 4 8 1225 3277 3210
+5708 2 2 4 8 1427 3210 3277
+5709 2 2 4 8 1226 3276 3211
+5710 2 2 4 8 1426 3211 3276
+5711 2 2 4 8 857 4431 2768
+5712 2 2 4 8 1597 2768 4431
+5713 2 2 4 8 950 2352 3782
+5714 2 2 4 8 1021 2413 5114
+5715 2 2 4 8 1876 4298 5394
+5716 2 2 4 8 2861 4974 3578
+5717 2 2 4 8 3579 2860 4975
+5718 2 2 4 8 1551 2332 3921
+5719 2 2 4 8 2216 2607 4841
+5720 2 2 4 8 719 2894 4362
+5721 2 2 4 8 1401 3674 2850
+5722 2 2 4 8 722 2850 3674
+5723 2 2 4 8 1778 2811 5119
+5724 2 2 4 8 258 2709 4036
+5725 2 2 4 8 285 4035 2710
+5726 2 2 4 8 64 4037 2708
+5727 2 2 4 8 632 2704 4411
+5728 2 2 4 8 1088 2876 3021
+5729 2 2 4 8 913 3613 2402
+5730 2 2 4 8 584 4581 2701
+5731 2 2 4 8 585 4580 2700
+5732 2 2 4 8 643 3599 2410
+5733 2 2 4 8 676 3984 2519
+5734 2 2 4 8 1059 4661 3576
+5735 2 2 4 8 857 4649 2353
+5736 2 2 4 8 101 2637 4689
+5737 2 2 4 8 1099 4229 2318
+5738 2 2 4 8 1308 4045 2639
+5739 2 2 4 8 1614 3059 5342
+5740 2 2 4 8 1615 3058 5343
+5741 2 2 4 8 1052 4318 2750
+5742 2 2 4 8 992 4797 2378
+5743 2 2 4 8 975 4233 2569
+5744 2 2 4 8 1486 2665 3407
+5745 2 2 4 8 966 2503 3997
+5746 2 2 4 8 1329 3997 2503
+5747 2 2 4 8 1945 4414 2862
+5748 2 2 4 8 1310 3398 4197
+5749 2 2 4 8 1311 3399 4196
+5750 2 2 4 8 589 4403 5357
+5751 2 2 4 8 416 4556 2345
+5752 2 2 4 8 887 5297 2744
+5753 2 2 4 8 1843 3446 4131
+5754 2 2 4 8 1464 4131 3446
+5755 2 2 4 8 641 5040 3394
+5756 2 2 4 8 1057 2460 5338
+5757 2 2 4 8 1058 5339 2459
+5758 2 2 4 8 1647 5338 2460
+5759 2 2 4 8 1648 2459 5339
+5760 2 2 4 8 510 4051 3406
+5761 2 2 4 8 549 2801 4518
+5762 2 2 4 8 550 2800 4519
+5763 2 2 4 8 992 3296 2583
+5764 2 2 4 8 2997 5064 4728
+5765 2 2 4 8 1815 4031 4346
+5766 2 2 4 8 1473 3088 2871
+5767 2 2 4 8 984 2871 3088
+5768 2 2 4 8 653 2616 3519
+5769 2 2 4 8 1260 3519 2616
+5770 2 2 4 8 1687 2406 5016
+5771 2 2 4 8 919 2493 4466
+5772 2 2 4 8 2347 5149 4933
+5773 2 2 4 8 1580 4689 2637
+5774 2 2 4 8 1143 3459 2479
+5775 2 2 4 8 579 2402 5194
+5776 2 2 4 8 1108 4629 3730
+5777 2 2 4 8 1637 4803 3032
+5778 2 2 4 8 1357 3256 3935
+5779 2 2 4 8 1368 3639 2471
+5780 2 2 4 8 1668 4952 4731
+5781 2 2 4 8 1020 3775 2870
+5782 2 2 4 8 679 3008 3365
+5783 2 2 4 8 560 5067 2851
+5784 2 2 4 8 710 2988 3369
+5785 2 2 4 8 2624 1653 4278
+5786 2 2 4 8 526 3415 3330
+5787 2 2 4 8 1519 3330 3415
+5788 2 2 4 8 655 2485 3961
+5789 2 2 4 8 1315 3961 2485
+5790 2 2 4 8 1611 4738 2749
+5791 2 2 4 8 530 3657 4021
+5792 2 2 4 8 1666 4985 3734
+5793 2 2 4 8 1182 4018 2585
+5794 2 2 4 8 1373 2857 4198
+5795 2 2 4 8 1374 2859 4199
+5796 2 2 4 8 1025 5119 2811
+5797 2 2 4 8 1121 2333 4192
+5798 2 2 4 8 1183 3469 2931
+5799 2 2 4 8 2053 2792 5238
+5800 2 2 4 8 939 5274 2394
+5801 2 2 4 8 1530 4871 2661
+5802 2 2 4 8 443 3070 3235
+5803 2 2 4 8 1352 3235 3070
+5804 2 2 4 8 1388 2656 4268
+5805 2 2 4 8 389 390 3047
+5806 2 2 4 8 1049 2596 3281
+5807 2 2 4 8 1372 2421 4301
+5808 2 2 4 8 1309 4154 3853
+5809 2 2 4 8 2081 3853 4154
+5810 2 2 4 8 75 4798 2383
+5811 2 2 4 8 2089 4119 2934
+5812 2 2 4 8 1919 5211 2962
+5813 2 2 4 8 2357 4056 4658
+5814 2 2 4 8 515 3568 3295
+5815 2 2 4 8 1044 2783 4061
+5816 2 2 4 8 893 4752 2450
+5817 2 2 4 8 1515 2450 4752
+5818 2 2 4 8 1274 2347 4357
+5819 2 2 4 8 1255 2845 3161
+5820 2 2 4 8 751 3161 2845
+5821 2 2 4 8 817 2910 3653
+5822 2 2 4 8 1413 3653 2910
+5823 2 2 4 8 1171 2623 3602
+5824 2 2 4 8 1756 3614 5289
+5825 2 2 4 8 1603 4592 2974
+5826 2 2 4 8 1402 5209 3676
+5827 2 2 4 8 884 5371 3153
+5828 2 2 4 8 2185 3153 5371
+5829 2 2 4 8 389 3047 2853
+5830 2 2 4 8 632 2848 3049
+5831 2 2 4 8 956 4977 2695
+5832 2 2 4 8 1429 4036 2709
+5833 2 2 4 8 1428 2710 4035
+5834 2 2 4 8 1430 2708 4037
+5835 2 2 4 8 1608 2441 5195
+5836 2 2 4 8 395 396 3014
+5837 2 2 4 8 1123 2393 4842
+5838 2 2 4 8 1102 2436 5183
+5839 2 2 4 8 973 5375 2609
+5840 2 2 4 8 644 2439 5186
+5841 2 2 4 8 2077 3999 5284
+5842 2 2 4 8 867 2410 3943
+5843 2 2 4 8 1185 3429 2530
+5844 2 2 4 8 2575 3545 4446
+5845 2 2 4 8 2499 3480 1494
+5846 2 2 4 8 1511 4100 3699
+5847 2 2 4 8 1567 2731 4897
+5848 2 2 4 8 2678 3989 3690
+5849 2 2 4 8 2253 3704 4641
+5850 2 2 4 8 1015 4641 3704
+5851 2 2 4 8 1364 2371 3843
+5852 2 2 4 8 410 411 4251
+5853 2 2 4 8 1404 2858 3705
+5854 2 2 4 8 727 3705 2858
+5855 2 2 4 8 578 5412 4448
+5856 2 2 4 8 1104 4007 2352
+5857 2 2 4 8 2218 3020 4665
+5858 2 2 4 8 2092 4710 4514
+5859 2 2 4 8 2091 4709 4513
+5860 2 2 4 8 1112 2365 3900
+5861 2 2 4 8 953 5033 2419
+5862 2 2 4 8 954 2418 5032
+5863 2 2 4 8 955 5034 2420
+5864 2 2 4 8 1625 2823 3148
+5865 2 2 4 8 755 4141 4764
+5866 2 2 4 8 2156 2785 3913
+5867 2 2 4 8 2058 5026 2418
+5868 2 2 4 8 2057 2419 5024
+5869 2 2 4 8 2059 2420 5025
+5870 2 2 4 8 1187 2597 4030
+5871 2 2 4 8 1103 5156 2440
+5872 2 2 4 8 1099 2359 3940
+5873 2 2 4 8 926 2629 4847
+5874 2 2 4 8 1318 2424 4077
+5875 2 2 4 8 457 4077 2424
+5876 2 2 4 8 575 4306 2351
+5877 2 2 4 8 1250 2451 3780
+5878 2 2 4 8 1416 4057 3313
+5879 2 2 4 8 352 2412 4948
+5880 2 2 4 8 165 2411 4947
+5881 2 2 4 8 1008 4978 3431
+5882 2 2 4 8 512 3334 3893
+5883 2 2 4 8 516 3335 3892
+5884 2 2 4 8 720 4967 2653
+5885 2 2 4 8 2128 5100 4404
+5886 2 2 4 8 2127 5101 4405
+5887 2 2 4 8 1297 3834 3302
+5888 2 2 4 8 1268 3609 2447
+5889 2 2 4 8 1175 2777 3127
+5890 2 2 4 8 1896 2680 3850
+5891 2 2 4 8 1195 2938 4986
+5892 2 2 4 8 1569 4356 4487
+5893 2 2 4 8 1380 3362 4219
+5894 2 2 4 8 1381 3363 4221
+5895 2 2 4 8 1020 4501 2994
+5896 2 2 4 8 1704 5331 2598
+5897 2 2 4 8 622 2598 5331
+5898 2 2 4 8 623 5332 2599
+5899 2 2 4 8 1705 2599 5332
+5900 2 2 4 8 1191 4785 2936
+5901 2 2 4 8 1194 2939 4784
+5902 2 2 4 8 1190 4732 2937
+5903 2 2 4 8 1534 3920 4277
+5904 2 2 4 8 1562 2759 3557
+5905 2 2 4 8 1564 2757 3558
+5906 2 2 4 8 1563 2758 3559
+5907 2 2 4 8 698 3791 2396
+5908 2 2 4 8 1206 3386 2903
+5909 2 2 4 8 1200 4460 2546
+5910 2 2 4 8 1527 4275 4891
+5911 2 2 4 8 198 2456 3602
+5912 2 2 4 8 938 4309 2546
+5913 2 2 4 8 1254 3596 2564
+5914 2 2 4 8 770 2564 3596
+5915 2 2 4 8 1025 2437 5119
+5916 2 2 4 8 535 2702 3917
+5917 2 2 4 8 447 3563 2617
+5918 2 2 4 8 1260 2617 3563
+5919 2 2 4 8 1585 2370 4563
+5920 2 2 4 8 897 3646 2702
+5921 2 2 4 8 1306 2702 3646
+5922 2 2 4 8 547 2526 4645
+5923 2 2 4 8 1502 4645 2526
+5924 2 2 4 8 1616 3132 3891
+5925 2 2 4 8 495 3891 3132
+5926 2 2 4 8 1052 2750 3151
+5927 2 2 4 8 729 3724 2859
+5928 2 2 4 8 1406 2859 3724
+5929 2 2 4 8 1405 2857 3725
+5930 2 2 4 8 728 3725 2857
+5931 2 2 4 8 1335 4010 2540
+5932 2 2 4 8 786 2540 4010
+5933 2 2 4 8 785 2541 4009
+5934 2 2 4 8 1334 4009 2541
+5935 2 2 4 8 713 4698 3313
+5936 2 2 4 8 1997 3313 4698
+5937 2 2 4 8 1417 2586 4373
+5938 2 2 4 8 1303 3151 2750
+5939 2 2 4 8 534 3396 3033
+5940 2 2 4 8 1367 3033 3396
+5941 2 2 4 8 1574 5048 2577
+5942 2 2 4 8 1987 3467 2793
+5943 2 2 4 8 665 2432 3681
+5944 2 2 4 8 2732 3291 5367
+5945 2 2 4 8 1096 4321 2361
+5946 2 2 4 8 1097 4320 2362
+5947 2 2 4 8 1222 5325 5156
+5948 2 2 4 8 1436 2384 4651
+5949 2 2 4 8 1254 3514 4742
+5950 2 2 4 8 1702 3499 2520
+5951 2 2 4 8 1438 4666 2385
+5952 2 2 4 8 854 2721 3198
+5953 2 2 4 8 1053 2751 3174
+5954 2 2 4 8 1054 2752 3175
+5955 2 2 4 8 1407 4093 3139
+5956 2 2 4 8 1477 3507 2518
+5957 2 2 4 8 1010 5311 3490
+5958 2 2 4 8 3127 4712 4285
+5959 2 2 4 8 1098 4205 2360
+5960 2 2 4 8 1063 2372 3998
+5961 2 2 4 8 1717 4724 2993
+5962 2 2 4 8 1090 2823 4663
+5963 2 2 4 8 938 2546 3462
+5964 2 2 4 8 1651 4122 4049
+5965 2 2 4 8 1650 4123 4050
+5966 2 2 4 8 1082 5330 3430
+5967 2 2 4 8 969 2691 5407
+5968 2 2 4 8 96 2692 4275
+5969 2 2 4 8 1280 5282 2382
+5970 2 2 4 8 1298 3686 4904
+5971 2 2 4 8 370 3045 4528
+5972 2 2 4 8 149 3044 4527
+5973 2 2 4 8 1289 5301 2379
+5974 2 2 4 8 1530 2661 4749
+5975 2 2 4 8 1284 2378 4797
+5976 2 2 4 8 564 3284 5008
+5977 2 2 4 8 802 4807 3881
+5978 2 2 4 8 1353 3503 4102
+5979 2 2 4 8 1301 3174 2751
+5980 2 2 4 8 1300 3175 2752
+5981 2 2 4 8 1652 3457 5121
+5982 2 2 4 8 1283 2377 4351
+5983 2 2 4 8 1282 4350 2376
+5984 2 2 4 8 1201 4979 3198
+5985 2 2 4 8 2252 3741 4640
+5986 2 2 4 8 1016 4640 3741
+5987 2 2 4 8 1319 3628 2769
+5988 2 2 4 8 509 2769 3628
+5989 2 2 4 8 514 2770 3629
+5990 2 2 4 8 1320 3629 2770
+5991 2 2 4 8 447 2502 3563
+5992 2 2 4 8 2148 4943 3023
+5993 2 2 4 8 3024 2149 4944
+5994 2 2 4 8 991 4351 2377
+5995 2 2 4 8 990 2376 4350
+5996 2 2 4 8 1006 3949 2388
+5997 2 2 4 8 1464 3446 3441
+5998 2 2 4 8 1911 4933 5149
+5999 2 2 4 8 4210 1977 5198
+6000 2 2 4 8 470 3712 2445
+6001 2 2 4 8 481 2444 3713
+6002 2 2 4 8 363 2722 4072
+6003 2 2 4 8 1441 4072 2722
+6004 2 2 4 8 142 2723 4071
+6005 2 2 4 8 1440 4071 2723
+6006 2 2 4 8 1713 3381 4693
+6007 2 2 4 8 1667 4656 4017
+6008 2 2 4 8 1089 4942 3111
+6009 2 2 4 8 413 5308 2711
+6010 2 2 4 8 1394 3822 3508
+6011 2 2 4 8 1395 3823 3509
+6012 2 2 4 8 1129 3014 5229
+6013 2 2 4 8 1669 3118 2953
+6014 2 2 4 8 1204 3165 3163
+6015 2 2 4 8 1404 3163 3165
+6016 2 2 4 8 1405 3162 3164
+6017 2 2 4 8 1203 3164 3162
+6018 2 2 4 8 1406 3166 3167
+6019 2 2 4 8 1205 3167 3166
+6020 2 2 4 8 697 3136 3621
+6021 2 2 4 8 699 3138 3622
+6022 2 2 4 8 786 3508 2540
+6023 2 2 4 8 785 3509 2541
+6024 2 2 4 8 587 5417 4440
+6025 2 2 4 8 662 3064 2921
+6026 2 2 4 8 1734 2387 4016
+6027 2 2 4 8 232 4719 2670
+6028 2 2 4 8 1643 3472 3195
+6029 2 2 4 8 1895 2966 4853
+6030 2 2 4 8 960 4853 2966
+6031 2 2 4 8 466 2816 3584
+6032 2 2 4 8 1593 4657 2948
+6033 2 2 4 8 655 3961 2395
+6034 2 2 4 8 1712 5295 2381
+6035 2 2 4 8 590 3375 5355
+6036 2 2 4 8 591 3376 5356
+6037 2 2 4 8 1142 3744 2445
+6038 2 2 4 8 1141 2444 3745
+6039 2 2 4 8 527 2492 5305
+6040 2 2 4 8 1095 2807 4421
+6041 2 2 4 8 2113 4847 2629
+6042 2 2 4 8 1366 3624 4048
+6043 2 2 4 8 1484 2977 3206
+6044 2 2 4 8 985 3206 2977
+6045 2 2 4 8 1630 3782 2697
+6046 2 2 4 8 2031 4584 4776
+6047 2 2 4 8 1201 3328 4979
+6048 2 2 4 8 1450 5411 2412
+6049 2 2 4 8 2087 2433 4934
+6050 2 2 4 8 1600 4642 2975
+6051 2 2 4 8 2285 4059 2772
+6052 2 2 4 8 2284 4060 2773
+6053 2 2 4 8 1509 4065 4064
+6054 2 2 4 8 545 4651 3918
+6055 2 2 4 8 2384 3918 4651
+6056 2 2 4 8 661 2549 5074
+6057 2 2 4 8 542 2518 5419
+6058 2 2 4 8 922 5420 2518
+6059 2 2 4 8 1006 2388 4065
+6060 2 2 4 8 103 104 3443
+6061 2 2 4 8 197 3602 2623
+6062 2 2 4 8 839 4272 3084
+6063 2 2 4 8 1692 3084 4272
+6064 2 2 4 8 1677 4367 3181
+6065 2 2 4 8 544 2387 4391
+6066 2 2 4 8 1420 3297 4130
+6067 2 2 4 8 1737 4130 3297
+6068 2 2 4 8 845 2880 3749
+6069 2 2 4 8 1414 3749 2880
+6070 2 2 4 8 1044 4061 2392
+6071 2 2 4 8 1471 2693 4315
+6072 2 2 4 8 2440 5156 5325
+6073 2 2 4 8 1200 4893 2932
+6074 2 2 4 8 1465 2900 4552
+6075 2 2 4 8 864 5393 2387
+6076 2 2 4 8 452 4917 2966
+6077 2 2 4 8 1086 3010 3134
+6078 2 2 4 8 1718 3134 3010
+6079 2 2 4 8 2314 5010 5185
+6080 2 2 4 8 676 2519 5404
+6081 2 2 4 8 1721 2573 3493
+6082 2 2 4 8 1722 3494 2574
+6083 2 2 4 8 1092 4344 2390
+6084 2 2 4 8 490 2454 5410
+6085 2 2 4 8 1031 2645 5026
+6086 2 2 4 8 1032 5024 2646
+6087 2 2 4 8 1091 4187 2391
+6088 2 2 4 8 546 3919 4666
+6089 2 2 4 8 2385 4666 3919
+6090 2 2 4 8 42 4402 41
+6091 2 2 4 8 1329 3845 3997
+6092 2 2 4 8 167 4224 4648
+6093 2 2 4 8 354 4223 4647
+6094 2 2 4 8 1328 3846 3996
+6095 2 2 4 8 623 2419 5332
+6096 2 2 4 8 622 5331 2418
+6097 2 2 4 8 1145 4580 2404
+6098 2 2 4 8 2009 4177 4025
+6099 2 2 4 8 1543 2668 4741
+6100 2 2 4 8 1542 2667 4740
+6101 2 2 4 8 1582 3727 3274
+6102 2 2 4 8 1312 3274 3727
+6103 2 2 4 8 4173 1875 4716
+6104 2 2 4 8 631 2443 4984
+6105 2 2 4 8 1330 3611 2524
+6106 2 2 4 8 1310 3272 3714
+6107 2 2 4 8 1577 3714 3272
+6108 2 2 4 8 1578 3715 3273
+6109 2 2 4 8 1311 3273 3715
+6110 2 2 4 8 1137 2454 3756
+6111 2 2 4 8 2173 5133 3968
+6112 2 2 4 8 1451 2411 4648
+6113 2 2 4 8 1450 2412 4647
+6114 2 2 4 8 426 427 3287
+6115 2 2 4 8 209 3288 3
+6116 2 2 4 8 1280 2534 3587
+6117 2 2 4 8 812 5269 2898
+6118 2 2 4 8 545 3918 3493
+6119 2 2 4 8 546 3494 3919
+6120 2 2 4 8 1780 3815 2694
+6121 2 2 4 8 975 2578 3502
+6122 2 2 4 8 976 3503 2579
+6123 2 2 4 8 578 4200 5062
+6124 2 2 4 8 2093 4711 3515
+6125 2 2 4 8 819 3515 4711
+6126 2 2 4 8 737 2877 4576
+6127 2 2 4 8 1649 4576 2877
+6128 2 2 4 8 1003 4701 2396
+6129 2 2 4 8 468 2399 4414
+6130 2 2 4 8 1718 3010 4586
+6131 2 2 4 8 739 4586 3010
+6132 2 2 4 8 841 5287 4660
+6133 2 2 4 8 2205 5355 3375
+6134 2 2 4 8 2207 5356 3376
+6135 2 2 4 8 1000 4479 2626
+6136 2 2 4 8 602 2487 5203
+6137 2 2 4 8 938 4657 2417
+6138 2 2 4 8 2462 4617 3297
+6139 2 2 4 8 2339 3865 4718
+6140 2 2 4 8 2338 3864 4717
+6141 2 2 4 8 14 3612 13
+6142 2 2 4 8 1649 5029 4662
+6143 2 2 4 8 634 4718 3865
+6144 2 2 4 8 633 4717 3864
+6145 2 2 4 8 1780 5321 2417
+6146 2 2 4 8 1266 2435 4844
+6147 2 2 4 8 37 3080 36
+6148 2 2 4 8 1227 3706 2625
+6149 2 2 4 8 1876 3636 4298
+6150 2 2 4 8 789 3165 5135
+6151 2 2 4 8 2853 1730 5216
+6152 2 2 4 8 774 4132 3325
+6153 2 2 4 8 1316 3135 3136
+6154 2 2 4 8 1239 3136 3135
+6155 2 2 4 8 1242 3138 3137
+6156 2 2 4 8 1317 3137 3138
+6157 2 2 4 8 852 2407 4133
+6158 2 2 4 8 669 4134 2407
+6159 2 2 4 8 670 4135 2408
+6160 2 2 4 8 853 2408 4136
+6161 2 2 4 8 1784 4939 2577
+6162 2 2 4 8 329 2577 4939
+6163 2 2 4 8 1213 2769 3581
+6164 2 2 4 8 1215 2770 3582
+6165 2 2 4 8 521 3583 2771
+6166 2 2 4 8 15 4583 14
+6167 2 2 4 8 1576 4059 4304
+6168 2 2 4 8 2285 4304 4059
+6169 2 2 4 8 1575 4060 4303
+6170 2 2 4 8 2284 4303 4060
+6171 2 2 4 8 683 4844 2435
+6172 2 2 4 8 1721 3493 3918
+6173 2 2 4 8 1722 3919 3494
+6174 2 2 4 8 1586 4551 4941
+6175 2 2 4 8 593 3221 4174
+6176 2 2 4 8 594 4175 3222
+6177 2 2 4 8 1350 3075 3321
+6178 2 2 4 8 1301 3321 3075
+6179 2 2 4 8 1302 3320 3076
+6180 2 2 4 8 1349 3076 3320
+6181 2 2 4 8 1348 3077 3319
+6182 2 2 4 8 1300 3319 3077
+6183 2 2 4 8 527 5013 3310
+6184 2 2 4 8 1063 5372 3222
+6185 2 2 4 8 3222 5372 2186
+6186 2 2 4 8 1363 4588 2405
+6187 2 2 4 8 1416 3357 2976
+6188 2 2 4 8 1636 5139 4096
+6189 2 2 4 8 873 3770 4121
+6190 2 2 4 8 1093 5139 3915
+6191 2 2 4 8 1533 4399 4506
+6192 2 2 4 8 1065 2914 3284
+6193 2 2 4 8 1596 3284 2914
+6194 2 2 4 8 1752 2945 5270
+6195 2 2 4 8 1753 5271 2946
+6196 2 2 4 8 1107 5127 2525
+6197 2 2 4 8 1587 2525 5127
+6198 2 2 4 8 327 3947 2765
+6199 2 2 4 8 1035 5418 2778
+6200 2 2 4 8 730 3671 4439
+6201 2 2 4 8 448 5138 2481
+6202 2 2 4 8 312 2749 4738
+6203 2 2 4 8 1329 3765 3845
+6204 2 2 4 8 232 2670 4098
+6205 2 2 4 8 1625 4663 2823
+6206 2 2 4 8 457 3753 4077
+6207 2 2 4 8 1946 4077 3753
+6208 2 2 4 8 2335 3979 5124
+6209 2 2 4 8 173 3485 3410
+6210 2 2 4 8 3671 5298 4439
+6211 2 2 4 8 1874 4649 3229
+6212 2 2 4 8 857 3229 4649
+6213 2 2 4 8 287 288 3440
+6214 2 2 4 8 255 256 3441
+6215 2 2 4 8 66 67 3439
+6216 2 2 4 8 1623 4690 2970
+6217 2 2 4 8 235 236 3090
+6218 2 2 4 8 1690 4166 2416
+6219 2 2 4 8 4185 2858 4767
+6220 2 2 4 8 1407 3975 4093
+6221 2 2 4 8 2123 4542 3693
+6222 2 2 4 8 1442 3693 4542
+6223 2 2 4 8 1443 3694 4541
+6224 2 2 4 8 2121 4541 3694
+6225 2 2 4 8 2122 3695 4543
+6226 2 2 4 8 1444 4543 3695
+6227 2 2 4 8 1445 4544 3696
+6228 2 2 4 8 2125 3696 4544
+6229 2 2 4 8 2124 3697 4545
+6230 2 2 4 8 1446 4545 3697
+6231 2 2 4 8 1447 4546 3698
+6232 2 2 4 8 2126 3698 4546
+6233 2 2 4 8 1528 4945 2457
+6234 2 2 4 8 1007 2457 4945
+6235 2 2 4 8 1529 4946 2458
+6236 2 2 4 8 1008 2458 4946
+6237 2 2 4 8 820 3618 2555
+6238 2 2 4 8 818 2554 3619
+6239 2 2 4 8 1616 4742 2435
+6240 2 2 4 8 1135 4621 2427
+6241 2 2 4 8 40 41 3329
+6242 2 2 4 8 812 2429 4162
+6243 2 2 4 8 1253 4115 2580
+6244 2 2 4 8 1920 3001 4356
+6245 2 2 4 8 973 4356 3001
+6246 2 2 4 8 1268 2447 4220
+6247 2 2 4 8 1269 2448 4222
+6248 2 2 4 8 783 3742 3794
+6249 2 2 4 8 1776 3794 3742
+6250 2 2 4 8 750 2437 4726
+6251 2 2 4 8 1073 3374 2680
+6252 2 2 4 8 1525 4020 2958
+6253 2 2 4 8 1190 2958 4020
+6254 2 2 4 8 1148 5223 3375
+6255 2 2 4 8 2205 3375 5223
+6256 2 2 4 8 1629 3876 3285
+6257 2 2 4 8 1139 3285 3876
+6258 2 2 4 8 1718 4586 4157
+6259 2 2 4 8 751 3655 4789
+6260 2 2 4 8 2222 4789 3655
+6261 2 2 4 8 957 2472 5294
+6262 2 2 4 8 1337 5059 2476
+6263 2 2 4 8 954 4282 2603
+6264 2 2 4 8 1608 5195 2600
+6265 2 2 4 8 1558 4262 2424
+6266 2 2 4 8 942 4016 2628
+6267 2 2 4 8 1443 2713 4454
+6268 2 2 4 8 1442 2712 4455
+6269 2 2 4 8 1444 4456 2714
+6270 2 2 4 8 1445 4457 2715
+6271 2 2 4 8 1446 4458 2716
+6272 2 2 4 8 1447 4459 2717
+6273 2 2 4 8 1350 2536 3672
+6274 2 2 4 8 1349 2537 3673
+6275 2 2 4 8 1344 2489 4177
+6276 2 2 4 8 528 4177 2489
+6277 2 2 4 8 513 4287 2686
+6278 2 2 4 8 970 2610 5005
+6279 2 2 4 8 1101 2912 5201
+6280 2 2 4 8 2690 3283 5236
+6281 2 2 4 8 1288 4162 2429
+6282 2 2 4 8 980 2425 4326
+6283 2 2 4 8 1345 4326 2425
+6284 2 2 4 8 412 2711 4751
+6285 2 2 4 8 661 2677 4186
+6286 2 2 4 8 1051 3156 4941
+6287 2 2 4 8 528 4025 4177
+6288 2 2 4 8 1401 3056 3065
+6289 2 2 4 8 487 3763 2515
+6290 2 2 4 8 1264 3264 4393
+6291 2 2 4 8 393 394 3466
+6292 2 2 4 8 1492 3586 2585
+6293 2 2 4 8 82 83 3121
+6294 2 2 4 8 48 49 3122
+6295 2 2 4 8 269 270 3123
+6296 2 2 4 8 1492 2585 4615
+6297 2 2 4 8 722 4615 2585
+6298 2 2 4 8 668 5263 2843
+6299 2 2 4 8 1550 4421 2807
+6300 2 2 4 8 896 4497 2431
+6301 2 2 4 8 1346 4283 2429
+6302 2 2 4 8 491 4075 2436
+6303 2 2 4 8 1490 3192 3583
+6304 2 2 4 8 1217 3583 3192
+6305 2 2 4 8 1010 2529 5311
+6306 2 2 4 8 1628 5311 2529
+6307 2 2 4 8 317 318 3711
+6308 2 2 4 8 1782 5286 4578
+6309 2 2 4 8 1740 5107 2980
+6310 2 2 4 8 1423 2513 3774
+6311 2 2 4 8 1439 5170 3000
+6312 2 2 4 8 662 4319 2682
+6313 2 2 4 8 894 2500 3812
+6314 2 2 4 8 1536 3397 3935
+6315 2 2 4 8 2121 5256 3093
+6316 2 2 4 8 567 3093 5256
+6317 2 2 4 8 355 356 3298
+6318 2 2 4 8 168 169 3299
+6319 2 2 4 8 1069 2653 4665
+6320 2 2 4 8 1183 3065 3056
+6321 2 2 4 8 2267 5300 2762
+6322 2 2 4 8 980 2432 4330
+6323 2 2 4 8 1114 3043 4867
+6324 2 2 4 8 445 4102 2570
+6325 2 2 4 8 70 3131 69
+6326 2 2 4 8 2459 4324 2884
+6327 2 2 4 8 2460 2883 4325
+6328 2 2 4 8 195 196 3452
+6329 2 2 4 8 360 361 3449
+6330 2 2 4 8 140 3448 139
+6331 2 2 4 8 1001 4377 5152
+6332 2 2 4 8 1211 2720 4078
+6333 2 2 4 8 932 3183 3986
+6334 2 2 4 8 933 3182 3987
+6335 2 2 4 8 1501 4626 2597
+6336 2 2 4 8 727 2597 4626
+6337 2 2 4 8 1929 5096 3819
+6338 2 2 4 8 1228 4141 2550
+6339 2 2 4 8 774 2496 5084
+6340 2 2 4 8 1562 5063 4832
+6341 2 2 4 8 1291 5124 3979
+6342 2 2 4 8 1109 5285 3661
+6343 2 2 4 8 92 3620 91
+6344 2 2 4 8 1027 3662 2563
+6345 2 2 4 8 1813 3172 5090
+6346 2 2 4 8 1814 3173 5091
+6347 2 2 4 8 597 2664 3436
+6348 2 2 4 8 4198 2857 4769
+6349 2 2 4 8 4199 2859 4768
+6350 2 2 4 8 4206 3228 5382
+6351 2 2 4 8 2284 5043 5188
+6352 2 2 4 8 2285 5044 5187
+6353 2 2 4 8 2484 2870 4372
+6354 2 2 4 8 1548 2627 3597
+6355 2 2 4 8 900 4290 3920
+6356 2 2 4 8 238 2744 4940
+6357 2 2 4 8 1605 3013 4526
+6358 2 2 4 8 1543 4211 3323
+6359 2 2 4 8 1710 2443 4471
+6360 2 2 4 8 2334 2695 4977
+6361 2 2 4 8 1435 4691 3203
+6362 2 2 4 8 1266 3755 3982
+6363 2 2 4 8 464 4491 3915
+6364 2 2 4 8 2242 3915 4491
+6365 2 2 4 8 1452 4412 4250
+6366 2 2 4 8 648 4959 2482
+6367 2 2 4 8 650 4960 2483
+6368 2 2 4 8 2321 5307 4956
+6369 2 2 4 8 441 3025 5380
+6370 2 2 4 8 1131 4106 2892
+6371 2 2 4 8 999 4688 5303
+6372 2 2 4 8 1195 4986 4288
+6373 2 2 4 8 1323 4026 2907
+6374 2 2 4 8 1960 2915 4188
+6375 2 2 4 8 471 2781 3587
+6376 2 2 4 8 1280 3587 2781
+6377 2 2 4 8 233 234 3836
+6378 2 2 4 8 988 3094 3444
+6379 2 2 4 8 1495 3444 3094
+6380 2 2 4 8 960 2478 4905
+6381 2 2 4 8 541 3337 3498
+6382 2 2 4 8 1504 3498 3337
+6383 2 2 4 8 960 3928 2478
+6384 2 2 4 8 894 2446 4218
+6385 2 2 4 8 2526 2888 4439
+6386 2 2 4 8 1629 2869 3876
+6387 2 2 4 8 2740 4877 4972
+6388 2 2 4 8 2155 3041 5316
+6389 2 2 4 8 1501 2597 3601
+6390 2 2 4 8 1086 3113 5228
+6391 2 2 4 8 1084 3115 5342
+6392 2 2 4 8 1083 3116 5343
+6393 2 2 4 8 531 2447 4219
+6394 2 2 4 8 531 4220 2447
+6395 2 2 4 8 532 2448 4221
+6396 2 2 4 8 532 4222 2448
+6397 2 2 4 8 2356 5297 4409
+6398 2 2 4 8 1788 5080 2935
+6399 2 2 4 8 883 4943 5370
+6400 2 2 4 8 884 4944 5371
+6401 2 2 4 8 71 72 3312
+6402 2 2 4 8 170 171 3149
+6403 2 2 4 8 357 358 3150
+6404 2 2 4 8 682 2737 3385
+6405 2 2 4 8 1256 2677 3543
+6406 2 2 4 8 661 3543 2677
+6407 2 2 4 8 1701 3233 5165
+6408 2 2 4 8 1455 3228 4206
+6409 2 2 4 8 1085 3114 5322
+6410 2 2 4 8 643 2595 4300
+6411 2 2 4 8 1178 2570 3709
+6412 2 2 4 8 709 3278 4225
+6413 2 2 4 8 1087 5320 3112
+6414 2 2 4 8 1547 3937 4203
+6415 2 2 4 8 669 3159 3573
+6416 2 2 4 8 1458 3573 3159
+6417 2 2 4 8 1459 3574 3160
+6418 2 2 4 8 670 3160 3574
+6419 2 2 4 8 592 4750 2468
+6420 2 2 4 8 706 4197 2602
+6421 2 2 4 8 707 4196 2604
+6422 2 2 4 8 1327 3907 3844
+6423 2 2 4 8 441 5380 3205
+6424 2 2 4 8 2117 3205 5380
+6425 2 2 4 8 57 4591 3109
+6426 2 2 4 8 278 4593 3110
+6427 2 2 4 8 498 3616 2698
+6428 2 2 4 8 1275 4598 2674
+6429 2 2 4 8 1670 4699 3169
+6430 2 2 4 8 1631 4330 3504
+6431 2 2 4 8 1524 4514 4710
+6432 2 2 4 8 1523 4513 4709
+6433 2 2 4 8 1383 3742 3944
+6434 2 2 4 8 1449 3913 2785
+6435 2 2 4 8 1672 4012 2482
+6436 2 2 4 8 1671 4011 2483
+6437 2 2 4 8 1968 2929 4305
+6438 2 2 4 8 1494 3089 4015
+6439 2 2 4 8 732 2942 4575
+6440 2 2 4 8 1646 4575 2942
+6441 2 2 4 8 1803 4606 5081
+6442 2 2 4 8 835 2899 3203
+6443 2 2 4 8 896 4617 2462
+6444 2 2 4 8 2077 4582 3666
+6445 2 2 4 8 849 3666 4582
+6446 2 2 4 8 493 2461 4176
+6447 2 2 4 8 1470 4095 3409
+6448 2 2 4 8 1729 3409 4095
+6449 2 2 4 8 1466 4094 3410
+6450 2 2 4 8 1728 3410 4094
+6451 2 2 4 8 2027 3920 4290
+6452 2 2 4 8 1366 4002 4345
+6453 2 2 4 8 2202 4345 4002
+6454 2 2 4 8 1909 5399 3533
+6455 2 2 4 8 1910 5400 3534
+6456 2 2 4 8 1908 3535 5398
+6457 2 2 4 8 1907 3532 5397
+6458 2 2 4 8 1906 3531 5396
+6459 2 2 4 8 1420 2976 3773
+6460 2 2 4 8 758 3773 2976
+6461 2 2 4 8 1861 5288 2547
+6462 2 2 4 8 1022 2557 4614
+6463 2 2 4 8 3055 3265 5041
+6464 2 2 4 8 3050 4897 2731
+6465 2 2 4 8 1492 3233 3586
+6466 2 2 4 8 538 3586 3233
+6467 2 2 4 8 2514 5009 1684
+6468 2 2 4 8 577 4063 4862
+6469 2 2 4 8 1664 4470 2972
+6470 2 2 4 8 702 2972 4470
+6471 2 2 4 8 1232 4770 2619
+6472 2 2 4 8 813 3731 5073
+6473 2 2 4 8 1146 4869 2491
+6474 2 2 4 8 1757 3729 2944
+6475 2 2 4 8 866 2944 3729
+6476 2 2 4 8 1248 2873 3224
+6477 2 2 4 8 2620 3544 4644
+6478 2 2 4 8 1119 2984 4340
+6479 2 2 4 8 1120 2985 4339
+6480 2 2 4 8 1666 2743 3655
+6481 2 2 4 8 1565 4716 2720
+6482 2 2 4 8 733 2720 4716
+6483 2 2 4 8 568 4682 2471
+6484 2 2 4 8 2440 4862 4063
+6485 2 2 4 8 229 230 3215
+6486 2 2 4 8 718 3247 3476
+6487 2 2 4 8 1456 3476 3247
+6488 2 2 4 8 962 5237 2741
+6489 2 2 4 8 699 3622 4242
+6490 2 2 4 8 697 3621 4244
+6491 2 2 4 8 1079 2551 3825
+6492 2 2 4 8 344 345 3177
+6493 2 2 4 8 678 5344 3133
+6494 2 2 4 8 2049 3133 5344
+6495 2 2 4 8 676 2501 3984
+6496 2 2 4 8 1727 3905 2523
+6497 2 2 4 8 1076 4549 3551
+6498 2 2 4 8 1077 4548 3552
+6499 2 2 4 8 640 5051 2520
+6500 2 2 4 8 1835 2477 4104
+6501 2 2 4 8 1731 2854 5217
+6502 2 2 4 8 1732 2855 5218
+6503 2 2 4 8 1608 2600 4147
+6504 2 2 4 8 2441 5132 3342
+6505 2 2 4 8 13 3612 3019
+6506 2 2 4 8 1126 3641 2608
+6507 2 2 4 8 1352 2782 3967
+6508 2 2 4 8 1875 4173 2874
+6509 2 2 4 8 970 2874 4173
+6510 2 2 4 8 1046 2508 4936
+6511 2 2 4 8 1045 2507 4935
+6512 2 2 4 8 1120 4339 4062
+6513 2 2 4 8 1272 3584 2816
+6514 2 2 4 8 8 9 3460
+6515 2 2 4 8 390 4279 3047
+6516 2 2 4 8 1482 3825 2551
+6517 2 2 4 8 1338 4917 2472
+6518 2 2 4 8 571 4487 2470
+6519 2 2 4 8 25 3938 24
+6520 2 2 4 8 522 2805 4714
+6521 2 2 4 8 1770 2920 4959
+6522 2 2 4 8 1771 2919 4960
+6523 2 2 4 8 1452 2908 4412
+6524 2 2 4 8 564 2469 4557
+6525 2 2 4 8 1082 2474 5330
+6526 2 2 4 8 1191 3878 4785
+6527 2 2 4 8 1194 4784 3879
+6528 2 2 4 8 1666 5105 2743
+6529 2 2 4 8 494 2743 5105
+6530 2 2 4 8 555 2997 4728
+6531 2 2 4 8 628 5351 2475
+6532 2 2 4 8 98 99 3214
+6533 2 2 4 8 102 103 5290
+6534 2 2 4 8 1751 4673 2986
+6535 2 2 4 8 1368 2471 4682
+6536 2 2 4 8 686 2476 5059
+6537 2 2 4 8 1790 4876 3458
+6538 2 2 4 8 398 4367 2590
+6539 2 2 4 8 1244 3202 5324
+6540 2 2 4 8 1281 2969 3187
+6541 2 2 4 8 875 2488 4724
+6542 2 2 4 8 414 415 3202
+6543 2 2 4 8 982 3170 5043
+6544 2 2 4 8 983 3171 5044
+6545 2 2 4 8 1719 4086 3405
+6546 2 2 4 8 1460 3405 4086
+6547 2 2 4 8 543 4630 2580
+6548 2 2 4 8 461 5003 3137
+6549 2 2 4 8 1629 5185 5010
+6550 2 2 4 8 388 2853 5216
+6551 2 2 4 8 1190 4020 4732
+6552 2 2 4 8 642 2592 3716
+6553 2 2 4 8 842 3968 5133
+6554 2 2 4 8 68 3405 67
+6555 2 2 4 8 1194 2955 3531
+6556 2 2 4 8 1193 2956 3532
+6557 2 2 4 8 1192 2957 3535
+6558 2 2 4 8 1190 3533 2958
+6559 2 2 4 8 1191 3534 2959
+6560 2 2 4 8 493 4160 2491
+6561 2 2 4 8 2206 5357 4403
+6562 2 2 4 8 1007 4401 2477
+6563 2 2 4 8 2281 5286 3571
+6564 2 2 4 8 565 4997 2527
+6565 2 2 4 8 1124 4845 2511
+6566 2 2 4 8 1366 4048 3415
+6567 2 2 4 8 655 4553 2485
+6568 2 2 4 8 667 2488 4643
+6569 2 2 4 8 1517 4566 3457
+6570 2 2 4 8 106 3692 105
+6571 2 2 4 8 91 3620 2638
+6572 2 2 4 8 1020 2484 4501
+6573 2 2 4 8 320 321 3225
+6574 2 2 4 8 3025 1896 5380
+6575 2 2 4 8 1303 5404 2519
+6576 2 2 4 8 1400 2840 4848
+6577 2 2 4 8 875 4618 2489
+6578 2 2 4 8 1474 3387 3884
+6579 2 2 4 8 1539 3269 3011
+6580 2 2 4 8 1037 3011 3269
+6581 2 2 4 8 1540 3270 3012
+6582 2 2 4 8 1038 3012 3270
+6583 2 2 4 8 2912 4968 5201
+6584 2 2 4 8 156 3217 155
+6585 2 2 4 8 376 377 3216
+6586 2 2 4 8 110 111 3831
+6587 2 2 4 8 1585 4563 2838
+6588 2 2 4 8 1130 2838 4563
+6589 2 2 4 8 1601 2994 4501
+6590 2 2 4 8 72 5361 3312
+6591 2 2 4 8 551 5314 3331
+6592 2 2 4 8 1466 3410 3485
+6593 2 2 4 8 1344 4643 2488
+6594 2 2 4 8 2492 4632 1766
+6595 2 2 4 8 1119 4340 4108
+6596 2 2 4 8 1405 3725 4509
+6597 2 2 4 8 1406 3724 4508
+6598 2 2 4 8 652 2644 3617
+6599 2 2 4 8 1252 3617 2644
+6600 2 2 4 8 458 2517 5310
+6601 2 2 4 8 217 2647 3818
+6602 2 2 4 8 435 2648 3817
+6603 2 2 4 8 1453 3560 3200
+6604 2 2 4 8 540 3200 3560
+6605 2 2 4 8 539 3561 3201
+6606 2 2 4 8 1454 3201 3561
+6607 2 2 4 8 1200 5321 4893
+6608 2 2 4 8 313 314 4040
+6609 2 2 4 8 661 5074 2725
+6610 2 2 4 8 671 4339 2985
+6611 2 2 4 8 672 4340 2984
+6612 2 2 4 8 1708 3633 2835
+6613 2 2 4 8 1709 2836 3632
+6614 2 2 4 8 2415 5175 3910
+6615 2 2 4 8 1278 3281 3072
+6616 2 2 4 8 824 2824 4111
+6617 2 2 4 8 1470 4111 2824
+6618 2 2 4 8 816 2827 4110
+6619 2 2 4 8 1467 4110 2827
+6620 2 2 4 8 879 2600 5195
+6621 2 2 4 8 1253 3303 2865
+6622 2 2 4 8 584 2533 3976
+6623 2 2 4 8 514 4516 2990
+6624 2 2 4 8 509 4515 2989
+6625 2 2 4 8 271 272 3249
+6626 2 2 4 8 51 3248 50
+6627 2 2 4 8 1408 3953 2636
+6628 2 2 4 8 406 2636 3953
+6629 2 2 4 8 1199 4466 2493
+6630 2 2 4 8 1431 3471 3232
+6631 2 2 4 8 1304 3232 3471
+6632 2 2 4 8 1270 3767 3324
+6633 2 2 4 8 2533 4685 3976
+6634 2 2 4 8 1648 4209 2943
+6635 2 2 4 8 695 2865 3303
+6636 2 2 4 8 172 173 3410
+6637 2 2 4 8 359 360 3409
+6638 2 2 4 8 1383 3944 3388
+6639 2 2 4 8 755 3411 4332
+6640 2 2 4 8 1252 3564 2679
+6641 2 2 4 8 2497 4409 1927
+6642 2 2 4 8 1368 2626 4479
+6643 2 2 4 8 641 3394 2807
+6644 2 2 4 8 1682 5307 2944
+6645 2 2 4 8 1232 2619 4240
+6646 2 2 4 8 1098 2759 4668
+6647 2 2 4 8 1562 4668 2759
+6648 2 2 4 8 758 3357 4598
+6649 2 2 4 8 1245 4838 2872
+6650 2 2 4 8 378 379 3230
+6651 2 2 4 8 157 158 3231
+6652 2 2 4 8 1230 4849 3063
+6653 2 2 4 8 700 3614 3360
+6654 2 2 4 8 1534 3360 3614
+6655 2 2 4 8 1367 3396 3931
+6656 2 2 4 8 327 328 3947
+6657 2 2 4 8 1867 2571 5273
+6658 2 2 4 8 929 5018 2502
+6659 2 2 4 8 522 4821 2500
+6660 2 2 4 8 616 3910 5175
+6661 2 2 4 8 1640 2554 5151
+6662 2 2 4 8 446 3550 3564
+6663 2 2 4 8 492 2524 4127
+6664 2 2 4 8 1689 4043 4916
+6665 2 2 4 8 673 4027 2535
+6666 2 2 4 8 674 4029 2536
+6667 2 2 4 8 675 4028 2537
+6668 2 2 4 8 457 5384 2584
+6669 2 2 4 8 3030 4982 5127
+6670 2 2 4 8 232 233 4719
+6671 2 2 4 8 721 2873 3433
+6672 2 2 4 8 1667 2744 5297
+6673 2 2 4 8 1726 2522 4159
+6674 2 2 4 8 4177 2009 4675
+6675 2 2 4 8 611 4530 2503
+6676 2 2 4 8 1175 2891 4299
+6677 2 2 4 8 1423 4794 2513
+6678 2 2 4 8 2866 1716 5163
+6679 2 2 4 8 1715 5162 2868
+6680 2 2 4 8 1714 2867 5161
+6681 2 2 4 8 1978 4927 3839
+6682 2 2 4 8 184 4599 3243
+6683 2 2 4 8 547 4810 2526
+6684 2 2 4 8 1005 2801 3496
+6685 2 2 4 8 1539 3496 2801
+6686 2 2 4 8 1004 2800 3495
+6687 2 2 4 8 1540 3495 2800
+6688 2 2 4 8 2323 4566 3870
+6689 2 2 4 8 576 5097 2983
+6690 2 2 4 8 1997 3430 5330
+6691 2 2 4 8 1102 5284 3128
+6692 2 2 4 8 552 4505 2509
+6693 2 2 4 8 553 4506 2510
+6694 2 2 4 8 979 2763 3477
+6695 2 2 4 8 1512 3009 3666
+6696 2 2 4 8 4104 2263 5255
+6697 2 2 4 8 582 4441 2511
+6698 2 2 4 8 1096 2567 5205
+6699 2 2 4 8 1097 2568 5206
+6700 2 2 4 8 521 5130 4794
+6701 2 2 4 8 831 5009 3393
+6702 2 2 4 8 21 3518 20
+6703 2 2 4 8 335 336 3925
+6704 2 2 4 8 1654 3610 2932
+6705 2 2 4 8 225 226 4055
+6706 2 2 4 8 201 202 4054
+6707 2 2 4 8 1415 3580 3268
+6708 2 2 4 8 4133 2260 5090
+6709 2 2 4 8 4136 2261 5091
+6710 2 2 4 8 1434 2934 4119
+6711 2 2 4 8 1777 4616 5203
+6712 2 2 4 8 1794 4191 2733
+6713 2 2 4 8 2513 4794 5130
+6714 2 2 4 8 688 4268 2656
+6715 2 2 4 8 1153 4407 4688
+6716 2 2 4 8 1305 3450 3237
+6717 2 2 4 8 1419 3237 3450
+6718 2 2 4 8 144 5217 2854
+6719 2 2 4 8 365 5218 2855
+6720 2 2 4 8 1541 2721 4658
+6721 2 2 4 8 854 4658 2721
+6722 2 2 4 8 1792 5401 4040
+6723 2 2 4 8 1431 3232 4788
+6724 2 2 4 8 1127 4632 2973
+6725 2 2 4 8 563 4877 2740
+6726 2 2 4 8 236 237 4017
+6727 2 2 4 8 547 4645 2523
+6728 2 2 4 8 4191 1794 4312
+6729 2 2 4 8 994 2560 3990
+6730 2 2 4 8 995 2561 3991
+6731 2 2 4 8 2330 4747 5070
+6732 2 2 4 8 1019 3031 4915
+6733 2 2 4 8 1147 4403 3751
+6734 2 2 4 8 2033 3751 4403
+6735 2 2 4 8 690 3236 3541
+6736 2 2 4 8 1538 3541 3236
+6737 2 2 4 8 1153 4688 2527
+6738 2 2 4 8 1595 3047 4279
+6739 2 2 4 8 1503 4044 2983
+6740 2 2 4 8 576 2983 4044
+6741 2 2 4 8 882 4124 3263
+6742 2 2 4 8 1655 3263 4124
+6743 2 2 4 8 2463 4812 5014
+6744 2 2 4 8 2018 4954 3718
+6745 2 2 4 8 887 4409 5297
+6746 2 2 4 8 441 3875 2991
+6747 2 2 4 8 3337 5358 4438
+6748 2 2 4 8 1306 3917 2702
+6749 2 2 4 8 1121 3540 2734
+6750 2 2 4 8 543 2522 5122
+6751 2 2 4 8 621 4838 2546
+6752 2 2 4 8 711 2777 3475
+6753 2 2 4 8 1622 5171 2638
+6754 2 2 4 8 1696 4681 4989
+6755 2 2 4 8 1828 3826 4810
+6756 2 2 4 8 1385 2846 4005
+6757 2 2 4 8 1639 4499 4325
+6758 2 2 4 8 2460 4325 4499
+6759 2 2 4 8 1638 4324 4500
+6760 2 2 4 8 2459 4500 4324
+6761 2 2 4 8 1625 5392 4664
+6762 2 2 4 8 1070 2639 3710
+6763 2 2 4 8 92 93 4996
+6764 2 2 4 8 1577 2543 4145
+6765 2 2 4 8 1578 2542 4146
+6766 2 2 4 8 942 2628 3974
+6767 2 2 4 8 1150 2924 3883
+6768 2 2 4 8 1649 3093 5029
+6769 2 2 4 8 516 3892 2847
+6770 2 2 4 8 2847 3892 1387
+6771 2 2 4 8 505 4146 3166
+6772 2 2 4 8 504 4145 3162
+6773 2 2 4 8 1836 5345 3431
+6774 2 2 4 8 1309 4021 2564
+6775 2 2 4 8 760 3643 3958
+6776 2 2 4 8 1754 3958 3643
+6777 2 2 4 8 1043 5014 4812
+6778 2 2 4 8 625 2528 4653
+6779 2 2 4 8 891 2535 4428
+6780 2 2 4 8 892 2536 4430
+6781 2 2 4 8 893 2537 4429
+6782 2 2 4 8 1027 2638 5058
+6783 2 2 4 8 1256 3663 2677
+6784 2 2 4 8 1376 3286 3813
+6785 2 2 4 8 394 395 4208
+6786 2 2 4 8 1269 3778 3390
+6787 2 2 4 8 1305 2549 4186
+6788 2 2 4 8 2024 5374 2592
+6789 2 2 4 8 1228 2698 3616
+6790 2 2 4 8 22 4091 21
+6791 2 2 4 8 691 3255 3542
+6792 2 2 4 8 1537 3542 3255
+6793 2 2 4 8 702 4156 2972
+6794 2 2 4 8 1718 4157 2930
+6795 2 2 4 8 1481 3355 3495
+6796 2 2 4 8 1004 3495 3355
+6797 2 2 4 8 1005 3496 3356
+6798 2 2 4 8 1480 3356 3496
+6799 2 2 4 8 1050 3625 2698
+6800 2 2 4 8 940 2562 5042
+6801 2 2 4 8 351 352 4948
+6802 2 2 4 8 164 165 4947
+6803 2 2 4 8 1241 4596 3899
+6804 2 2 4 8 1243 2793 3467
+6805 2 2 4 8 1646 2942 3832
+6806 2 2 4 8 227 5270 2945
+6807 2 2 4 8 200 2946 5271
+6808 2 2 4 8 1057 5338 3575
+6809 2 2 4 8 1058 3577 5339
+6810 2 2 4 8 334 335 3302
+6811 2 2 4 8 1504 3337 4438
+6812 2 2 4 8 1287 3155 3374
+6813 2 2 4 8 1154 3417 2862
+6814 2 2 4 8 1787 5174 5073
+6815 2 2 4 8 1814 4486 2925
+6816 2 2 4 8 1813 4485 2926
+6817 2 2 4 8 237 238 4940
+6818 2 2 4 8 1070 4675 2898
+6819 2 2 4 8 1176 2581 5204
+6820 2 2 4 8 1484 2851 3408
+6821 2 2 4 8 1055 3408 2851
+6822 2 2 4 8 686 3926 2591
+6823 2 2 4 8 314 4854 4040
+6824 2 2 4 8 1295 3048 3752
+6825 2 2 4 8 1002 2677 3663
+6826 2 2 4 8 668 2601 3880
+6827 2 2 4 8 1263 3264 3002
+6828 2 2 4 8 1901 4509 3725
+6829 2 2 4 8 1900 4508 3724
+6830 2 2 4 8 661 4186 2549
+6831 2 2 4 8 1210 4620 2943
+6832 2 2 4 8 498 2961 4715
+6833 2 2 4 8 1842 5360 3757
+6834 2 2 4 8 1993 4515 3628
+6835 2 2 4 8 1992 4516 3629
+6836 2 2 4 8 770 4154 2564
+6837 2 2 4 8 1126 3087 3641
+6838 2 2 4 8 1486 3641 3087
+6839 2 2 4 8 1761 2703 3881
+6840 2 2 4 8 1808 4615 3674
+6841 2 2 4 8 1069 2983 4354
+6842 2 2 4 8 1346 4025 3229
+6843 2 2 4 8 242 5262 2928
+6844 2 2 4 8 1606 4527 3044
+6845 2 2 4 8 1607 4528 3045
+6846 2 2 4 8 929 3872 2611
+6847 2 2 4 8 1284 4797 2583
+6848 2 2 4 8 746 3457 3924
+6849 2 2 4 8 1652 3924 3457
+6850 2 2 4 8 2345 4980 3700
+6851 2 2 4 8 62 2866 5163
+6852 2 2 4 8 283 2868 5162
+6853 2 2 4 8 260 5161 2867
+6854 2 2 4 8 1067 4923 3350
+6855 2 2 4 8 1309 2564 4154
+6856 2 2 4 8 93 3004 4996
+6857 2 2 4 8 1200 2546 4309
+6858 2 2 4 8 2049 2927 4618
+6859 2 2 4 8 700 4364 2971
+6860 2 2 4 8 1510 4480 3888
+6861 2 2 4 8 1180 4963 2565
+6862 2 2 4 8 2039 3312 5361
+6863 2 2 4 8 1681 3982 3755
+6864 2 2 4 8 1368 3022 3639
+6865 2 2 4 8 714 3639 3022
+6866 2 2 4 8 722 2585 4018
+6867 2 2 4 8 655 2662 4553
+6868 2 2 4 8 1252 2679 4193
+6869 2 2 4 8 1536 2973 3310
+6870 2 2 4 8 76 4798 75
+6871 2 2 4 8 1022 2678 3690
+6872 2 2 4 8 956 2591 5354
+6873 2 2 4 8 1920 4992 3828
+6874 2 2 4 8 1803 2796 3497
+6875 2 2 4 8 490 5410 2666
+6876 2 2 4 8 1014 4150 2571
+6877 2 2 4 8 1323 2907 3370
+6878 2 2 4 8 109 2970 4690
+6879 2 2 4 8 728 4087 5189
+6880 2 2 4 8 242 243 5262
+6881 2 2 4 8 621 2546 4460
+6882 2 2 4 8 1022 4803 2557
+6883 2 2 4 8 1621 2787 3662
+6884 2 2 4 8 597 2581 5116
+6885 2 2 4 8 1882 2814 3554
+6886 2 2 4 8 1881 3553 2813
+6887 2 2 4 8 1883 3555 2815
+6888 2 2 4 8 1014 2571 4952
+6889 2 2 4 8 729 5202 3724
+6890 2 2 4 8 190 191 3338
+6891 2 2 4 8 85 4147 2600
+6892 2 2 4 8 1269 3783 3778
+6893 2 2 4 8 1724 3778 3783
+6894 2 2 4 8 1998 5313 4053
+6895 2 2 4 8 701 4611 2963
+6896 2 2 4 8 1812 3551 4549
+6897 2 2 4 8 1811 3552 4548
+6898 2 2 4 8 948 4212 2989
+6899 2 2 4 8 1978 2989 4212
+6900 2 2 4 8 947 4211 2990
+6901 2 2 4 8 1976 2990 4211
+6902 2 2 4 8 1027 2550 4636
+6903 2 2 4 8 963 2612 3907
+6904 2 2 4 8 317 3711 3293
+6905 2 2 4 8 1252 3034 3564
+6906 2 2 4 8 1397 3927 2860
+6907 2 2 4 8 502 2860 3927
+6908 2 2 4 8 1448 2553 5017
+6909 2 2 4 8 22 23 3343
+6910 2 2 4 8 1657 3368 5280
+6911 2 2 4 8 1656 3367 5281
+6912 2 2 4 8 478 3556 2778
+6913 2 2 4 8 1065 2661 4871
+6914 2 2 4 8 1268 3781 3777
+6915 2 2 4 8 1723 3777 3781
+6916 2 2 4 8 245 246 3346
+6917 2 2 4 8 252 253 3347
+6918 2 2 4 8 729 4363 5202
+6919 2 2 4 8 1590 5188 5043
+6920 2 2 4 8 1592 5187 5044
+6921 2 2 4 8 1012 2643 3813
+6922 2 2 4 8 1177 2569 4233
+6923 2 2 4 8 924 2580 4115
+6924 2 2 4 8 1050 4443 2729
+6925 2 2 4 8 646 2739 4039
+6926 2 2 4 8 1704 4271 3400
+6927 2 2 4 8 1706 3399 4270
+6928 2 2 4 8 1705 3398 4269
+6929 2 2 4 8 620 4982 3030
+6930 2 2 4 8 509 3581 2769
+6931 2 2 4 8 514 3582 2770
+6932 2 2 4 8 1217 2771 3583
+6933 2 2 4 8 231 232 4098
+6934 2 2 4 8 919 4466 2875
+6935 2 2 4 8 579 4232 2588
+6936 2 2 4 8 1388 3688 3339
+6937 2 2 4 8 1389 3340 3687
+6938 2 2 4 8 1588 3988 4084
+6939 2 2 4 8 1603 2974 3522
+6940 2 2 4 8 1600 2975 3521
+6941 2 2 4 8 1261 3856 2686
+6942 2 2 4 8 1154 2593 4019
+6943 2 2 4 8 1544 3769 2663
+6944 2 2 4 8 1625 3916 5392
+6945 2 2 4 8 1736 3980 3630
+6946 2 2 4 8 1375 3630 3980
+6947 2 2 4 8 1735 3981 3631
+6948 2 2 4 8 1374 3631 3981
+6949 2 2 4 8 662 2921 4319
+6950 2 2 4 8 667 2639 4045
+6951 2 2 4 8 499 2772 4059
+6952 2 2 4 8 501 2773 4060
+6953 2 2 4 8 1492 4323 3233
+6954 2 2 4 8 601 5312 2566
+6955 2 2 4 8 752 4987 2573
+6956 2 2 4 8 753 2574 4988
+6957 2 2 4 8 1564 4755 2757
+6958 2 2 4 8 1096 2757 4755
+6959 2 2 4 8 1563 4756 2758
+6960 2 2 4 8 1097 2758 4756
+6961 2 2 4 8 483 4650 2558
+6962 2 2 4 8 2109 4393 4976
+6963 2 2 4 8 374 375 3358
+6964 2 2 4 8 153 154 3359
+6965 2 2 4 8 681 3703 2699
+6966 2 2 4 8 1611 2749 5241
+6967 2 2 4 8 1331 3818 2647
+6968 2 2 4 8 1332 3817 2648
+6969 2 2 4 8 1134 4468 2558
+6970 2 2 4 8 1565 2720 3806
+6971 2 2 4 8 327 2765 5240
+6972 2 2 4 8 1694 3598 3909
+6973 2 2 4 8 1333 3909 3598
+6974 2 2 4 8 746 4550 3404
+6975 2 2 4 8 790 3164 5086
+6976 2 2 4 8 791 3167 5085
+6977 2 2 4 8 1841 3726 2967
+6978 2 2 4 8 1248 3433 2873
+6979 2 2 4 8 728 5189 3725
+6980 2 2 4 8 969 2566 4370
+6981 2 2 4 8 909 3962 2622
+6982 2 2 4 8 1290 2622 3962
+6983 2 2 4 8 1017 4913 2996
+6984 2 2 4 8 30 3592 29
+6985 2 2 4 8 640 2951 4216
+6986 2 2 4 8 727 4030 2597
+6987 2 2 4 8 345 346 5015
+6988 2 2 4 8 1812 2794 3551
+6989 2 2 4 8 2795 3552 1811
+6990 2 2 4 8 1515 3986 3183
+6991 2 2 4 8 1514 3987 3182
+6992 2 2 4 8 1682 4956 5307
+6993 2 2 4 8 1002 3761 2677
+6994 2 2 4 8 758 2976 3357
+6995 2 2 4 8 1013 2581 4202
+6996 2 2 4 8 1353 4061 2783
+6997 2 2 4 8 415 416 5324
+6998 2 2 4 8 1022 4614 2678
+6999 2 2 4 8 1698 5144 2592
+7000 2 2 4 8 253 254 4813
+7001 2 2 4 8 197 198 3602
+7002 2 2 4 8 475 4397 2572
+7003 2 2 4 8 1268 3777 3609
+7004 2 2 4 8 2668 3059 4741
+7005 2 2 4 8 2667 3058 4740
+7006 2 2 4 8 2342 5028 3500
+7007 2 2 4 8 2270 3683 5003
+7008 2 2 4 8 1174 3652 2852
+7009 2 2 4 8 852 4133 5090
+7010 2 2 4 8 853 4136 5091
+7011 2 2 4 8 1002 4792 2576
+7012 2 2 4 8 692 2964 4097
+7013 2 2 4 8 1548 4653 4692
+7014 2 2 4 8 1591 3169 4517
+7015 2 2 4 8 1427 4376 3671
+7016 2 2 4 8 1404 3705 4307
+7017 2 2 4 8 90 2638 5171
+7018 2 2 4 8 471 3978 2622
+7019 2 2 4 8 909 2622 3979
+7020 2 2 4 8 1332 2648 4249
+7021 2 2 4 8 1701 2844 4076
+7022 2 2 4 8 1646 3832 3576
+7023 2 2 4 8 569 3576 3832
+7024 2 2 4 8 28 29 4787
+7025 2 2 4 8 396 4921 3014
+7026 2 2 4 8 987 3665 3227
+7027 2 2 4 8 1498 3227 3665
+7028 2 2 4 8 315 2676 4854
+7029 2 2 4 8 1431 4788 3895
+7030 2 2 4 8 1094 4776 4584
+7031 2 2 4 8 4225 3278 4815
+7032 2 2 4 8 1946 5076 2965
+7033 2 2 4 8 1746 4114 4536
+7034 2 2 4 8 1747 4113 4535
+7035 2 2 4 8 2017 3899 4596
+7036 2 2 4 8 588 4247 2587
+7037 2 2 4 8 1569 3689 2736
+7038 2 2 4 8 703 4172 3259
+7039 2 2 4 8 1572 4895 2725
+7040 2 2 4 8 945 2725 4895
+7041 2 2 4 8 511 4005 2846
+7042 2 2 4 8 1806 3678 4601
+7043 2 2 4 8 878 3559 5224
+7044 2 2 4 8 2207 5224 3559
+7045 2 2 4 8 1485 5070 4747
+7046 2 2 4 8 2082 4363 3314
+7047 2 2 4 8 1900 3738 4951
+7048 2 2 4 8 1901 3737 4950
+7049 2 2 4 8 4173 4716 1565
+7050 2 2 4 8 315 4604 2676
+7051 2 2 4 8 1488 4970 3841
+7052 2 2 4 8 1491 4969 3839
+7053 2 2 4 8 992 2583 4797
+7054 2 2 4 8 1223 3472 3219
+7055 2 2 4 8 1674 2608 5252
+7056 2 2 4 8 1485 2947 3417
+7057 2 2 4 8 1033 2582 4685
+7058 2 2 4 8 1435 4685 2582
+7059 2 2 4 8 1460 4086 2909
+7060 2 2 4 8 732 2909 4086
+7061 2 2 4 8 1294 4292 3542
+7062 2 2 4 8 1258 3974 2628
+7063 2 2 4 8 1253 2580 4630
+7064 2 2 4 8 663 3719 2729
+7065 2 2 4 8 1227 3605 3604
+7066 2 2 4 8 1834 3604 3605
+7067 2 2 4 8 462 4833 3951
+7068 2 2 4 8 463 4834 3950
+7069 2 2 4 8 1781 3404 4550
+7070 2 2 4 8 1044 2586 5011
+7071 2 2 4 8 671 3250 4339
+7072 2 2 4 8 672 3251 4340
+7073 2 2 4 8 1861 3202 5288
+7074 2 2 4 8 569 5131 2630
+7075 2 2 4 8 1152 3117 5251
+7076 2 2 4 8 1911 5251 3117
+7077 2 2 4 8 869 4104 5255
+7078 2 2 4 8 1595 4279 4865
+7079 2 2 4 8 926 4847 3258
+7080 2 2 4 8 112 113 4459
+7081 2 2 4 8 124 4458 123
+7082 2 2 4 8 134 135 4457
+7083 2 2 4 8 179 180 4456
+7084 2 2 4 8 292 293 4455
+7085 2 2 4 8 303 304 4454
+7086 2 2 4 8 1761 4807 3103
+7087 2 2 4 8 1200 5001 4460
+7088 2 2 4 8 254 255 3446
+7089 2 2 4 8 1720 3569 5323
+7090 2 2 4 8 1686 5173 3548
+7091 2 2 4 8 521 4794 3001
+7092 2 2 4 8 507 5383 3274
+7093 2 2 4 8 1400 4848 2589
+7094 2 2 4 8 518 5110 3608
+7095 2 2 4 8 1806 4165 3678
+7096 2 2 4 8 1396 3678 4165
+7097 2 2 4 8 628 2609 5184
+7098 2 2 4 8 1080 4493 3147
+7099 2 2 4 8 1475 5302 4565
+7100 2 2 4 8 1786 3329 4006
+7101 2 2 4 8 1398 4006 3329
+7102 2 2 4 8 1808 3674 4171
+7103 2 2 4 8 1401 4171 3674
+7104 2 2 4 8 2831 4869 2024
+7105 2 2 4 8 1153 2911 4407
+7106 2 2 4 8 719 3489 2979
+7107 2 2 4 8 1286 2979 3489
+7108 2 2 4 8 2144 3608 5110
+7109 2 2 4 8 1299 3675 3943
+7110 2 2 4 8 1800 3830 2724
+7111 2 2 4 8 1620 5212 2670
+7112 2 2 4 8 926 2670 5212
+7113 2 2 4 8 1561 2981 4790
+7114 2 2 4 8 445 2589 4848
+7115 2 2 4 8 1861 5308 3202
+7116 2 2 4 8 738 4927 2663
+7117 2 2 4 8 1544 2663 4927
+7118 2 2 4 8 1266 2777 3755
+7119 2 2 4 8 2031 3015 4584
+7120 2 2 4 8 1847 4874 3227
+7121 2 2 4 8 987 3227 4874
+7122 2 2 4 8 513 2686 3856
+7123 2 2 4 8 1087 2732 5320
+7124 2 2 4 8 1555 4728 5064
+7125 2 2 4 8 1684 5009 3898
+7126 2 2 4 8 1655 3331 3263
+7127 2 2 4 8 1549 4152 3007
+7128 2 2 4 8 548 3007 4152
+7129 2 2 4 8 1815 3705 4626
+7130 2 2 4 8 666 3776 2730
+7131 2 2 4 8 4177 4675 1344
+7132 2 2 4 8 1304 3625 3719
+7133 2 2 4 8 38 39 3445
+7134 2 2 4 8 1553 3998 4236
+7135 2 2 4 8 1568 4157 4586
+7136 2 2 4 8 2130 3452 5276
+7137 2 2 4 8 1262 5276 3452
+7138 2 2 4 8 1815 4307 3705
+7139 2 2 4 8 262 4213 3252
+7140 2 2 4 8 281 3253 4214
+7141 2 2 4 8 60 3254 4215
+7142 2 2 4 8 2433 3402 4934
+7143 2 2 4 8 441 3205 3875
+7144 2 2 4 8 1829 4375 2964
+7145 2 2 4 8 243 244 3505
+7146 2 2 4 8 1833 3671 4376
+7147 2 2 4 8 1630 2697 5267
+7148 2 2 4 8 1112 5267 2697
+7149 2 2 4 8 1453 3200 4352
+7150 2 2 4 8 1454 4353 3201
+7151 2 2 4 8 1782 3571 5286
+7152 2 2 4 8 1253 2865 4284
+7153 2 2 4 8 3030 4537 2382
+7154 2 2 4 8 1432 2688 3945
+7155 2 2 4 8 55 3945 2688
+7156 2 2 4 8 1433 2689 3946
+7157 2 2 4 8 276 3946 2689
+7158 2 2 4 8 683 3514 2887
+7159 2 2 4 8 1136 2922 3843
+7160 2 2 4 8 1364 3843 2922
+7161 2 2 4 8 692 4097 2632
+7162 2 2 4 8 1506 4828 2598
+7163 2 2 4 8 1505 2599 4827
+7164 2 2 4 8 2385 2897 4088
+7165 2 2 4 8 2384 4087 2896
+7166 2 2 4 8 698 4109 3634
+7167 2 2 4 8 1763 3634 4109
+7168 2 2 4 8 1868 3692 4302
+7169 2 2 4 8 1517 4302 3692
+7170 2 2 4 8 1018 2995 5050
+7171 2 2 4 8 1545 4218 3333
+7172 2 2 4 8 386 3318 4295
+7173 2 2 4 8 146 4294 3317
+7174 2 2 4 8 367 4293 3316
+7175 2 2 4 8 686 2806 3926
+7176 2 2 4 8 1339 3926 2806
+7177 2 2 4 8 1079 2624 5174
+7178 2 2 4 8 471 4329 2781
+7179 2 2 4 8 2123 5257 3291
+7180 2 2 4 8 566 3291 5257
+7181 2 2 4 8 1069 4665 3020
+7182 2 2 4 8 1706 5291 5034
+7183 2 2 4 8 965 3996 2655
+7184 2 2 4 8 966 3997 2657
+7185 2 2 4 8 1568 4047 4714
+7186 2 2 4 8 748 3037 3972
+7187 2 2 4 8 1477 3972 3037
+7188 2 2 4 8 248 4749 2661
+7189 2 2 4 8 1516 4966 4314
+7190 2 2 4 8 53 3478 52
+7191 2 2 4 8 273 274 3479
+7192 2 2 4 8 458 4371 3228
+7193 2 2 4 8 1678 3228 4371
+7194 2 2 4 8 782 4568 3793
+7195 2 2 4 8 680 2764 4316
+7196 2 2 4 8 981 4699 2658
+7197 2 2 4 8 1634 5247 3152
+7198 2 2 4 8 1409 3901 2718
+7199 2 2 4 8 151 2718 3901
+7200 2 2 4 8 1410 3902 2719
+7201 2 2 4 8 372 2719 3902
+7202 2 2 4 8 1017 3632 2836
+7203 2 2 4 8 1018 2835 3633
+7204 2 2 4 8 298 299 3483
+7205 2 2 4 8 309 310 3484
+7206 2 2 4 8 173 174 3485
+7207 2 2 4 8 128 129 3486
+7208 2 2 4 8 118 3487 117
+7209 2 2 4 8 1189 3290 3963
+7210 2 2 4 8 1277 4510 2674
+7211 2 2 4 8 1596 4971 4511
+7212 2 2 4 8 1094 4584 2606
+7213 2 2 4 8 267 2810 3887
+7214 2 2 4 8 46 2809 3886
+7215 2 2 4 8 1335 3886 2809
+7216 2 2 4 8 1334 3887 2810
+7217 2 2 4 8 102 5290 2637
+7218 2 2 4 8 1127 2605 4659
+7219 2 2 4 8 1587 4982 2619
+7220 2 2 4 8 1309 3853 3238
+7221 2 2 4 8 732 4013 2909
+7222 2 2 4 8 1412 2909 4013
+7223 2 2 4 8 1331 4721 3818
+7224 2 2 4 8 1332 4722 3817
+7225 2 2 4 8 681 2699 3911
+7226 2 2 4 8 1896 3850 5381
+7227 2 2 4 8 1236 3864 5340
+7228 2 2 4 8 1237 3865 5341
+7229 2 2 4 8 926 5212 2629
+7230 2 2 4 8 945 4895 2617
+7231 2 2 4 8 712 4435 2611
+7232 2 2 4 8 711 3755 2777
+7233 2 2 4 8 523 2694 3932
+7234 2 2 4 8 2106 4230 2748
+7235 2 2 4 8 668 3880 3935
+7236 2 2 4 8 1423 2609 5375
+7237 2 2 4 8 702 3220 4156
+7238 2 2 4 8 1654 2932 4892
+7239 2 2 4 8 523 4892 2932
+7240 2 2 4 8 1072 4476 2636
+7241 2 2 4 8 1408 2636 4476
+7242 2 2 4 8 1474 3884 4359
+7243 2 2 4 8 1457 5005 2610
+7244 2 2 4 8 1231 3600 3062
+7245 2 2 4 8 1121 5295 3540
+7246 2 2 4 8 3200 5378 4352
+7247 2 2 4 8 697 2746 4521
+7248 2 2 4 8 699 2747 4522
+7249 2 2 4 8 2451 4314 4966
+7250 2 2 4 8 1432 3109 3746
+7251 2 2 4 8 1601 3746 3109
+7252 2 2 4 8 1433 3110 3747
+7253 2 2 4 8 1602 3747 3110
+7254 2 2 4 8 1397 3941 3927
+7255 2 2 4 8 3927 3941 1809
+7256 2 2 4 8 235 3090 5147
+7257 2 2 4 8 1551 2765 4816
+7258 2 2 4 8 1023 4816 2765
+7259 2 2 4 8 1811 4548 5099
+7260 2 2 4 8 2060 5278 3869
+7261 2 2 4 8 597 5116 3547
+7262 2 2 4 8 2094 3547 5116
+7263 2 2 4 8 727 2858 3980
+7264 2 2 4 8 1375 3980 2858
+7265 2 2 4 8 729 2859 3981
+7266 2 2 4 8 1374 3981 2859
+7267 2 2 4 8 866 3664 2944
+7268 2 2 4 8 1682 2944 3664
+7269 2 2 4 8 759 5276 3199
+7270 2 2 4 8 2521 5022 3709
+7271 2 2 4 8 1409 3637 3044
+7272 2 2 4 8 1606 3044 3637
+7273 2 2 4 8 1410 3638 3045
+7274 2 2 4 8 1607 3045 3638
+7275 2 2 4 8 1590 2684 5188
+7276 2 2 4 8 725 5188 2684
+7277 2 2 4 8 723 5187 2685
+7278 2 2 4 8 1592 2685 5187
+7279 2 2 4 8 1134 4410 2882
+7280 2 2 4 8 1059 3952 2889
+7281 2 2 4 8 1382 2889 3952
+7282 2 2 4 8 801 5406 4140
+7283 2 2 4 8 845 2619 4770
+7284 2 2 4 8 839 3084 3420
+7285 2 2 4 8 1303 3420 3084
+7286 2 2 4 8 1755 3310 5013
+7287 2 2 4 8 1288 3019 3612
+7288 2 2 4 8 1236 2817 3864
+7289 2 2 4 8 1237 2818 3865
+7290 2 2 4 8 400 401 3739
+7291 2 2 4 8 1537 4972 4877
+7292 2 2 4 8 1368 4682 2626
+7293 2 2 4 8 1057 3933 2883
+7294 2 2 4 8 1058 2884 3934
+7295 2 2 4 8 1371 2883 3933
+7296 2 2 4 8 1370 3934 2884
+7297 2 2 4 8 1360 2640 4215
+7298 2 2 4 8 1362 2642 4214
+7299 2 2 4 8 1361 4213 2641
+7300 2 2 4 8 1327 3922 2830
+7301 2 2 4 8 1328 2829 3923
+7302 2 2 4 8 1190 2937 3537
+7303 2 2 4 8 1191 2936 3536
+7304 2 2 4 8 1195 3539 2938
+7305 2 2 4 8 1194 3538 2939
+7306 2 2 4 8 1212 3562 2982
+7307 2 2 4 8 83 5190 3121
+7308 2 2 4 8 49 5191 3122
+7309 2 2 4 8 270 5192 3123
+7310 2 2 4 8 82 3121 5094
+7311 2 2 4 8 48 3122 5092
+7312 2 2 4 8 269 3123 5093
+7313 2 2 4 8 1214 3189 4835
+7314 2 2 4 8 1215 3190 4836
+7315 2 2 4 8 1217 3192 4837
+7316 2 2 4 8 1373 2767 3885
+7317 2 2 4 8 381 3885 2767
+7318 2 2 4 8 743 4992 2736
+7319 2 2 4 8 1569 2736 4992
+7320 2 2 4 8 69 3131 4713
+7321 2 2 4 8 1277 3595 3176
+7322 2 2 4 8 111 5395 3831
+7323 2 2 4 8 1258 5326 2882
+7324 2 2 4 8 1658 5047 2633
+7325 2 2 4 8 1373 3013 3524
+7326 2 2 4 8 1605 3524 3013
+7327 2 2 4 8 1628 2625 4745
+7328 2 2 4 8 568 2626 4682
+7329 2 2 4 8 1631 4746 3381
+7330 2 2 4 8 2338 5340 3864
+7331 2 2 4 8 2339 5341 3865
+7332 2 2 4 8 536 4398 3916
+7333 2 2 4 8 1028 5376 3016
+7334 2 2 4 8 1029 3018 5377
+7335 2 2 4 8 759 4453 5276
+7336 2 2 4 8 1383 3105 4235
+7337 2 2 4 8 1601 3109 4591
+7338 2 2 4 8 1602 3110 4593
+7339 2 2 4 8 584 3976 5069
+7340 2 2 4 8 1335 3521 2975
+7341 2 2 4 8 1334 3522 2974
+7342 2 2 4 8 652 3617 3402
+7343 2 2 4 8 1830 3402 3617
+7344 2 2 4 8 1521 4390 2901
+7345 2 2 4 8 1138 2901 4390
+7346 2 2 4 8 1520 4389 2902
+7347 2 2 4 8 1140 2902 4389
+7348 2 2 4 8 1229 3615 3061
+7349 2 2 4 8 1148 3375 3266
+7350 2 2 4 8 2004 3266 3375
+7351 2 2 4 8 2005 3267 3376
+7352 2 2 4 8 1149 3376 3267
+7353 2 2 4 8 2825 4333 814
+7354 2 2 4 8 2825 1469 4333
+7355 2 2 4 8 815 2826 4334
+7356 2 2 4 8 1468 4334 2826
+7357 2 2 4 8 1466 4337 2828
+7358 2 2 4 8 823 2828 4337
+7359 2 2 4 8 1255 5140 2856
+7360 2 2 4 8 1541 4658 4056
+7361 2 2 4 8 1377 2649 4295
+7362 2 2 4 8 1379 4294 2650
+7363 2 2 4 8 1378 4293 2651
+7364 2 2 4 8 1089 2713 4541
+7365 2 2 4 8 1443 4541 2713
+7366 2 2 4 8 1442 4542 2712
+7367 2 2 4 8 1087 2712 4542
+7368 2 2 4 8 1086 4543 2714
+7369 2 2 4 8 1444 2714 4543
+7370 2 2 4 8 1445 2715 4544
+7371 2 2 4 8 1085 4544 2715
+7372 2 2 4 8 1446 2716 4545
+7373 2 2 4 8 1084 4545 2716
+7374 2 2 4 8 1447 2717 4546
+7375 2 2 4 8 1083 4546 2717
+7376 2 2 4 8 1548 4692 2627
+7377 2 2 4 8 1286 3489 3501
+7378 2 2 4 8 1478 3501 3489
+7379 2 2 4 8 2005 5328 3267
+7380 2 2 4 8 785 3267 5328
+7381 2 2 4 8 786 3266 5329
+7382 2 2 4 8 2004 5329 3266
+7383 2 2 4 8 358 4729 3150
+7384 2 2 4 8 171 4730 3149
+7385 2 2 4 8 1048 4606 3497
+7386 2 2 4 8 961 4083 2740
+7387 2 2 4 8 2740 4083 1337
+7388 2 2 4 8 1119 4108 3194
+7389 2 2 4 8 1699 3194 4108
+7390 2 2 4 8 1371 3933 3492
+7391 2 2 4 8 524 2992 4753
+7392 2 2 4 8 496 2842 3708
+7393 2 2 4 8 1450 2775 5411
+7394 2 2 4 8 529 3866 5047
+7395 2 2 4 8 1482 2891 4285
+7396 2 2 4 8 1175 4285 2891
+7397 2 2 4 8 1294 3403 3849
+7398 2 2 4 8 2271 3717 3718
+7399 2 2 4 8 1240 3718 3717
+7400 2 2 4 8 112 4459 3100
+7401 2 2 4 8 123 4458 3099
+7402 2 2 4 8 134 4457 3098
+7403 2 2 4 8 179 4456 3097
+7404 2 2 4 8 293 3095 4455
+7405 2 2 4 8 304 3096 4454
+7406 2 2 4 8 1244 5288 3202
+7407 2 2 4 8 2102 4289 4811
+7408 2 2 4 8 1495 2643 4859
+7409 2 2 4 8 561 4859 2643
+7410 2 2 4 8 1708 3560 4725
+7411 2 2 4 8 1709 4726 3561
+7412 2 2 4 8 1114 2799 4143
+7413 2 2 4 8 1641 4047 3454
+7414 2 2 4 8 739 3454 4047
+7415 2 2 4 8 1256 2666 5410
+7416 2 2 4 8 326 327 5240
+7417 2 2 4 8 1932 3661 5285
+7418 2 2 4 8 1976 3841 4970
+7419 2 2 4 8 1978 3839 4969
+7420 2 2 4 8 962 3239 5237
+7421 2 2 4 8 738 2663 4239
+7422 2 2 4 8 1424 3995 4698
+7423 2 2 4 8 1572 5074 4861
+7424 2 2 4 8 271 3249 5192
+7425 2 2 4 8 50 3248 5191
+7426 2 2 4 8 3326 4633 2144
+7427 2 2 4 8 1566 4633 3326
+7428 2 2 4 8 1260 5018 3078
+7429 2 2 4 8 1744 4577 2963
+7430 2 2 4 8 701 2963 4577
+7431 2 2 4 8 1287 2738 4886
+7432 2 2 4 8 1212 4967 3562
+7433 2 2 4 8 1012 4480 2643
+7434 2 2 4 8 425 3588 424
+7435 2 2 4 8 207 208 3589
+7436 2 2 4 8 219 220 3590
+7437 2 2 4 8 437 438 3591
+7438 2 2 4 8 1333 2850 3909
+7439 2 2 4 8 722 3909 2850
+7440 2 2 4 8 517 2884 4324
+7441 2 2 4 8 520 4325 2883
+7442 2 2 4 8 740 3840 4740
+7443 2 2 4 8 742 3841 4741
+7444 2 2 4 8 1398 4402 2675
+7445 2 2 4 8 1408 4316 2764
+7446 2 2 4 8 1669 4811 3118
+7447 2 2 4 8 718 3476 4994
+7448 2 2 4 8 700 3360 4364
+7449 2 2 4 8 1015 5346 2754
+7450 2 2 4 8 988 5234 3094
+7451 2 2 4 8 1829 3094 5234
+7452 2 2 4 8 1337 2806 5059
+7453 2 2 4 8 1245 3462 4838
+7454 2 2 4 8 632 4085 2704
+7455 2 2 4 8 1382 3952 3488
+7456 2 2 4 8 1069 4354 2653
+7457 2 2 4 8 934 3720 3800
+7458 2 2 4 8 1645 3800 3720
+7459 2 2 4 8 935 3722 3799
+7460 2 2 4 8 1644 3799 3722
+7461 2 2 4 8 87 88 3659
+7462 2 2 4 8 2478 5243 4851
+7463 2 2 4 8 1021 5114 3089
+7464 2 2 4 8 1785 3089 5114
+7465 2 2 4 8 1156 2708 4529
+7466 2 2 4 8 1430 4529 2708
+7467 2 2 4 8 721 4193 2679
+7468 2 2 4 8 695 2775 4451
+7469 2 2 4 8 1450 4451 2775
+7470 2 2 4 8 216 217 3818
+7471 2 2 4 8 434 435 3817
+7472 2 2 4 8 1202 3263 3331
+7473 2 2 4 8 1296 3842 3824
+7474 2 2 4 8 1699 3824 3842
+7475 2 2 4 8 1894 5192 3249
+7476 2 2 4 8 1892 5191 3248
+7477 2 2 4 8 757 5277 4786
+7478 2 2 4 8 414 3202 5308
+7479 2 2 4 8 715 4585 3960
+7480 2 2 4 8 2096 3960 4585
+7481 2 2 4 8 1803 3497 4606
+7482 2 2 4 8 733 4078 2720
+7483 2 2 4 8 433 434 4722
+7484 2 2 4 8 215 216 4721
+7485 2 2 4 8 1500 4761 4052
+7486 2 2 4 8 2274 4052 4761
+7487 2 2 4 8 1513 4888 2654
+7488 2 2 4 8 1345 3814 4787
+7489 2 2 4 8 155 3217 5363
+7490 2 2 4 8 376 3216 5362
+7491 2 2 4 8 1285 3181 3739
+7492 2 2 4 8 717 2760 4564
+7493 2 2 4 8 1474 4564 2760
+7494 2 2 4 8 1475 4565 2761
+7495 2 2 4 8 716 2761 4565
+7496 2 2 4 8 1967 5363 3217
+7497 2 2 4 8 1966 5362 3216
+7498 2 2 4 8 1697 3186 4062
+7499 2 2 4 8 1120 4062 3186
+7500 2 2 4 8 827 3718 4954
+7501 2 2 4 8 1040 2706 4149
+7502 2 2 4 8 1041 2707 4148
+7503 2 2 4 8 716 4565 3954
+7504 2 2 4 8 2080 3954 4565
+7505 2 2 4 8 717 4564 3955
+7506 2 2 4 8 2079 3955 4564
+7507 2 2 4 8 714 2929 3639
+7508 2 2 4 8 1489 4607 3840
+7509 2 2 4 8 16 2935 5080
+7510 2 2 4 8 1986 3562 4967
+7511 2 2 4 8 12 3019 4254
+7512 2 2 4 8 1512 4254 3019
+7513 2 2 4 8 1280 2781 5282
+7514 2 2 4 8 1093 2664 5139
+7515 2 2 4 8 551 3762 5314
+7516 2 2 4 8 2315 5314 3762
+7517 2 2 4 8 1471 4207 2693
+7518 2 2 4 8 1417 4161 3353
+7519 2 2 4 8 993 4760 2652
+7520 2 2 4 8 1251 4039 2739
+7521 2 2 4 8 156 5266 3217
+7522 2 2 4 8 1914 3216 5265
+7523 2 2 4 8 377 5265 3216
+7524 2 2 4 8 1915 3217 5266
+7525 2 2 4 8 1265 2951 4394
+7526 2 2 4 8 1796 4469 3523
+7527 2 2 4 8 1581 3523 4469
+7528 2 2 4 8 1716 3805 3254
+7529 2 2 4 8 1360 3254 3805
+7530 2 2 4 8 1714 3252 3803
+7531 2 2 4 8 1362 3253 3804
+7532 2 2 4 8 1715 3804 3253
+7533 2 2 4 8 1361 3803 3252
+7534 2 2 4 8 1088 5241 2749
+7535 2 2 4 8 1143 2869 5010
+7536 2 2 4 8 1629 5010 2869
+7537 2 2 4 8 1214 4835 3412
+7538 2 2 4 8 1215 4836 3413
+7539 2 2 4 8 1217 4837 3414
+7540 2 2 4 8 820 3922 3618
+7541 2 2 4 8 818 3619 3923
+7542 2 2 4 8 661 2725 4153
+7543 2 2 4 8 492 3707 2893
+7544 2 2 4 8 680 2799 3889
+7545 2 2 4 8 2090 4708 3879
+7546 2 2 4 8 1522 3879 4708
+7547 2 2 4 8 1526 4711 3878
+7548 2 2 4 8 2093 3878 4711
+7549 2 2 4 8 1570 5168 4446
+7550 2 2 4 8 1303 2750 5404
+7551 2 2 4 8 829 5071 2665
+7552 2 2 4 8 378 3230 5265
+7553 2 2 4 8 157 3231 5266
+7554 2 2 4 8 1525 4672 4020
+7555 2 2 4 8 2178 4020 4672
+7556 2 2 4 8 2496 4587 5084
+7557 2 2 4 8 1571 4644 4401
+7558 2 2 4 8 1374 2766 4347
+7559 2 2 4 8 1030 3017 5365
+7560 2 2 4 8 669 3023 4134
+7561 2 2 4 8 670 3024 4135
+7562 2 2 4 8 32 3645 31
+7563 2 2 4 8 158 5087 3231
+7564 2 2 4 8 379 5088 3230
+7565 2 2 4 8 1558 3371 5084
+7566 2 2 4 8 964 2673 4412
+7567 2 2 4 8 1793 4764 4141
+7568 2 2 4 8 1245 2872 4313
+7569 2 2 4 8 1505 2832 4819
+7570 2 2 4 8 574 2667 5123
+7571 2 2 4 8 1542 5123 2667
+7572 2 2 4 8 715 2776 4585
+7573 2 2 4 8 1476 4585 2776
+7574 2 2 4 8 671 2706 4228
+7575 2 2 4 8 2347 3948 5149
+7576 2 2 4 8 1384 4051 2885
+7577 2 2 4 8 510 2885 4051
+7578 2 2 4 8 2575 4446 5168
+7579 2 2 4 8 1278 4503 2802
+7580 2 2 4 8 834 4782 3585
+7581 2 2 4 8 1958 3585 4782
+7582 2 2 4 8 850 4976 4393
+7583 2 2 4 8 683 2887 4712
+7584 2 2 4 8 87 3659 3005
+7585 2 2 4 8 1074 2895 4802
+7586 2 2 4 8 1876 5394 2696
+7587 2 2 4 8 1711 5418 3779
+7588 2 2 4 8 2363 3779 5418
+7589 2 2 4 8 701 3455 4611
+7590 2 2 4 8 2321 4956 3104
+7591 2 2 4 8 313 4040 2749
+7592 2 2 4 8 679 2674 4510
+7593 2 2 4 8 1571 4938 4644
+7594 2 2 4 8 1105 4341 2687
+7595 2 2 4 8 230 4520 3215
+7596 2 2 4 8 1506 2833 4828
+7597 2 2 4 8 1917 3994 2881
+7598 2 2 4 8 1000 5388 4479
+7599 2 2 4 8 2620 4644 4938
+7600 2 2 4 8 1977 3840 4607
+7601 2 2 4 8 1279 4377 5131
+7602 2 2 4 8 2630 5131 4377
+7603 2 2 4 8 926 4995 2670
+7604 2 2 4 8 1479 3071 3949
+7605 2 2 4 8 1297 3302 3925
+7606 2 2 4 8 1646 3576 4661
+7607 2 2 4 8 1607 2888 5365
+7608 2 2 4 8 2520 5051 3523
+7609 2 2 4 8 233 3836 4719
+7610 2 2 4 8 1024 4806 3037
+7611 2 2 4 8 1370 3525 3934
+7612 2 2 4 8 1860 5281 5415
+7613 2 2 4 8 1859 5280 5414
+7614 2 2 4 8 1163 4619 2722
+7615 2 2 4 8 1441 2722 4619
+7616 2 2 4 8 818 4494 4069
+7617 2 2 4 8 2111 4495 4068
+7618 2 2 4 8 820 4068 4495
+7619 2 2 4 8 2110 4069 4494
+7620 2 2 4 8 1503 4789 4044
+7621 2 2 4 8 1377 3318 3863
+7622 2 2 4 8 1730 3863 3318
+7623 2 2 4 8 3317 1379 3862
+7624 2 2 4 8 3317 3862 1731
+7625 2 2 4 8 1732 3316 3861
+7626 2 2 4 8 1378 3861 3316
+7627 2 2 4 8 1620 2670 4719
+7628 2 2 4 8 899 4191 4312
+7629 2 2 4 8 1347 3703 3055
+7630 2 2 4 8 681 3055 3703
+7631 2 2 4 8 1588 4084 3341
+7632 2 2 4 8 1885 3438 4489
+7633 2 2 4 8 766 4489 3438
+7634 2 2 4 8 767 4490 3437
+7635 2 2 4 8 1886 3437 4490
+7636 2 2 4 8 726 5219 2683
+7637 2 2 4 8 828 4590 3389
+7638 2 2 4 8 1755 3389 4590
+7639 2 2 4 8 677 4099 2748
+7640 2 2 4 8 876 3624 5066
+7641 2 2 4 8 2064 5066 3624
+7642 2 2 4 8 1679 2676 4604
+7643 2 2 4 8 1932 2690 5236
+7644 2 2 4 8 741 3829 4897
+7645 2 2 4 8 640 4216 5051
+7646 2 2 4 8 1434 3640 3608
+7647 2 2 4 8 1797 5296 4863
+7648 2 2 4 8 2045 3701 3700
+7649 2 2 4 8 1244 3700 3701
+7650 2 2 4 8 1259 2678 4614
+7651 2 2 4 8 1498 4851 5243
+7652 2 2 4 8 1414 3877 4260
+7653 2 2 4 8 1875 4260 3877
+7654 2 2 4 8 1157 4609 2709
+7655 2 2 4 8 1429 2709 4609
+7656 2 2 4 8 1158 2710 4610
+7657 2 2 4 8 1428 4610 2710
+7658 2 2 4 8 2222 4044 4789
+7659 2 2 4 8 1058 3934 2814
+7660 2 2 4 8 1057 2813 3933
+7661 2 2 4 8 819 3765 3515
+7662 2 2 4 8 1558 5084 4587
+7663 2 2 4 8 718 4994 3820
+7664 2 2 4 8 1409 3044 3901
+7665 2 2 4 8 150 3901 3044
+7666 2 2 4 8 371 3902 3045
+7667 2 2 4 8 1410 3045 3902
+7668 2 2 4 8 678 2705 5344
+7669 2 2 4 8 1484 3408 3680
+7670 2 2 4 8 1421 3680 3408
+7671 2 2 4 8 1792 4854 2676
+7672 2 2 4 8 1659 3078 4435
+7673 2 2 4 8 1516 3433 3349
+7674 2 2 4 8 1248 3349 3433
+7675 2 2 4 8 1059 2815 3952
+7676 2 2 4 8 1396 4165 2861
+7677 2 2 4 8 500 2861 4165
+7678 2 2 4 8 1692 4272 4864
+7679 2 2 4 8 2426 4864 4272
+7680 2 2 4 8 1432 4539 2688
+7681 2 2 4 8 1433 4540 2689
+7682 2 2 4 8 1238 3750 3168
+7683 2 2 4 8 455 2821 4348
+7684 2 2 4 8 1421 4348 2821
+7685 2 2 4 8 1604 4985 2845
+7686 2 2 4 8 751 2845 4985
+7687 2 2 4 8 1997 4698 3995
+7688 2 2 4 8 1340 4892 3764
+7689 2 2 4 8 513 3450 4287
+7690 2 2 4 8 1171 4411 2704
+7691 2 2 4 8 799 3379 4929
+7692 2 2 4 8 1853 4929 3379
+7693 2 2 4 8 798 3378 4928
+7694 2 2 4 8 1852 4928 3378
+7695 2 2 4 8 813 5200 3731
+7696 2 2 4 8 2193 3731 5200
+7697 2 2 4 8 1426 4625 3691
+7698 2 2 4 8 1929 3691 4625
+7699 2 2 4 8 9 10 5208
+7700 2 2 4 8 1409 2718 4360
+7701 2 2 4 8 1410 2719 4361
+7702 2 2 4 8 1346 2768 4283
+7703 2 2 4 8 1079 3825 2887
+7704 2 2 4 8 2931 3469 4681
+7705 2 2 4 8 1373 3885 3013
+7706 2 2 4 8 382 3013 3885
+7707 2 2 4 8 1487 4481 3829
+7708 2 2 4 8 725 2684 4914
+7709 2 2 4 8 1017 2683 4913
+7710 2 2 4 8 1019 4915 2685
+7711 2 2 4 8 1566 3279 4633
+7712 2 2 4 8 1107 3066 4537
+7713 2 2 4 8 1358 3178 4142
+7714 2 2 4 8 1018 5050 2684
+7715 2 2 4 8 723 2685 5049
+7716 2 2 4 8 1117 3022 3871
+7717 2 2 4 8 1368 3871 3022
+7718 2 2 4 8 521 2771 5130
+7719 2 2 4 8 2451 4966 3780
+7720 2 2 4 8 245 3346 4953
+7721 2 2 4 8 1106 3118 4811
+7722 2 2 4 8 1775 3793 4568
+7723 2 2 4 8 1275 3271 4598
+7724 2 2 4 8 2964 5239 4097
+7725 2 2 4 8 1315 3682 3740
+7726 2 2 4 8 1589 3740 3682
+7727 2 2 4 8 1679 2739 4276
+7728 2 2 4 8 1068 4891 2692
+7729 2 2 4 8 1911 5149 5251
+7730 2 2 4 8 1372 2998 4298
+7731 2 2 4 8 816 4110 4532
+7732 2 2 4 8 4110 2132 4532
+7733 2 2 4 8 824 4111 4533
+7734 2 2 4 8 4111 2131 4533
+7735 2 2 4 8 485 2856 5140
+7736 2 2 4 8 375 5362 3358
+7737 2 2 4 8 154 5363 3359
+7738 2 2 4 8 1223 3195 3472
+7739 2 2 4 8 1333 2808 4008
+7740 2 2 4 8 1335 2809 4010
+7741 2 2 4 8 1334 2810 4009
+7742 2 2 4 8 749 5039 4725
+7743 2 2 4 8 750 4726 5038
+7744 2 2 4 8 792 3936 4496
+7745 2 2 4 8 2020 4496 3936
+7746 2 2 4 8 2183 3772 4301
+7747 2 2 4 8 153 3359 5145
+7748 2 2 4 8 374 3358 5146
+7749 2 2 4 8 3324 3767 5268
+7750 2 2 4 8 1921 3829 4481
+7751 2 2 4 8 1034 2781 4142
+7752 2 2 4 8 1422 2915 3795
+7753 2 2 4 8 1604 2845 3910
+7754 2 2 4 8 1422 3428 3520
+7755 2 2 4 8 1375 2839 4434
+7756 2 2 4 8 1212 4665 4967
+7757 2 2 4 8 2653 4967 4665
+7758 2 2 4 8 743 2736 4343
+7759 2 2 4 8 1920 3828 4415
+7760 2 2 4 8 1490 4415 3828
+7761 2 2 4 8 1517 3870 4566
+7762 2 2 4 8 1500 4052 4241
+7763 2 2 4 8 748 3972 4818
+7764 2 2 4 8 466 5301 3391
+7765 2 2 4 8 1374 4199 2766
+7766 2 2 4 8 1373 4198 2767
+7767 2 2 4 8 3008 5244 3365
+7768 2 2 4 8 968 3377 4450
+7769 2 2 4 8 673 3212 4027
+7770 2 2 4 8 674 3213 4029
+7771 2 2 4 8 1746 3648 4244
+7772 2 2 4 8 697 4244 3648
+7773 2 2 4 8 1747 3649 4242
+7774 2 2 4 8 699 4242 3649
+7775 2 2 4 8 702 3650 4246
+7776 2 2 4 8 1745 4246 3650
+7777 2 2 4 8 1247 2729 4443
+7778 2 2 4 8 1220 3040 3716
+7779 2 2 4 8 314 315 4854
+7780 2 2 4 8 1125 4846 4440
+7781 2 2 4 8 2512 4440 4846
+7782 2 2 4 8 1251 3293 3711
+7783 2 2 4 8 716 4248 2761
+7784 2 2 4 8 80 4523 79
+7785 2 2 4 8 1546 3365 3963
+7786 2 2 4 8 1189 3963 3365
+7787 2 2 4 8 325 326 3921
+7788 2 2 4 8 94 4416 93
+7789 2 2 4 8 856 2998 3772
+7790 2 2 4 8 1913 4688 4407
+7791 2 2 4 8 526 4281 4603
+7792 2 2 4 8 1100 2728 4554
+7793 2 2 4 8 3131 5413 4713
+7794 2 2 4 8 1150 4257 2987
+7795 2 2 4 8 1734 5291 4046
+7796 2 2 4 8 1469 3789 3240
+7797 2 2 4 8 1615 3240 3789
+7798 2 2 4 8 1468 3790 3241
+7799 2 2 4 8 1614 3241 3790
+7800 2 2 4 8 1613 3242 3788
+7801 2 2 4 8 1467 3788 3242
+7802 2 2 4 8 1612 3243 3787
+7803 2 2 4 8 1465 3787 3243
+7804 2 2 4 8 1609 3784 3245
+7805 2 2 4 8 1463 3244 3785
+7806 2 2 4 8 1611 3785 3244
+7807 2 2 4 8 1610 3786 3246
+7808 2 2 4 8 1461 3245 3784
+7809 2 2 4 8 1462 3246 3786
+7810 2 2 4 8 874 4066 4120
+7811 2 2 4 8 1070 3710 4675
+7812 2 2 4 8 2085 4484 4106
+7813 2 2 4 8 949 4106 4484
+7814 2 2 4 8 1523 2956 4513
+7815 2 2 4 8 1193 4513 2956
+7816 2 2 4 8 1524 2957 4514
+7817 2 2 4 8 1192 4514 2957
+7818 2 2 4 8 4238 5247 1634
+7819 2 2 4 8 1720 3498 4786
+7820 2 2 4 8 1389 3687 4234
+7821 2 2 4 8 817 4335 2910
+7822 2 2 4 8 1462 2910 4335
+7823 2 2 4 8 1572 2725 5074
+7824 2 2 4 8 1616 3890 3596
+7825 2 2 4 8 770 3596 3890
+7826 2 2 4 8 754 4894 4015
+7827 2 2 4 8 1602 2996 4913
+7828 2 2 4 8 316 4604 315
+7829 2 2 4 8 120 2955 4384
+7830 2 2 4 8 1522 4384 2955
+7831 2 2 4 8 131 2956 4383
+7832 2 2 4 8 1523 4383 2956
+7833 2 2 4 8 176 2957 4382
+7834 2 2 4 8 1524 4382 2957
+7835 2 2 4 8 1525 2958 4381
+7836 2 2 4 8 1526 2959 4380
+7837 2 2 4 8 307 4380 2959
+7838 2 2 4 8 296 4381 2958
+7839 2 2 4 8 204 2 4882
+7840 2 2 4 8 2 205 4882
+7841 2 2 4 8 1 4885 440
+7842 2 2 4 8 5 422 4884
+7843 2 2 4 8 4 4883 222
+7844 2 2 4 8 4 223 4883
+7845 2 2 4 8 1 6 4885
+7846 2 2 4 8 5 4884 421
+7847 2 2 4 8 1049 3281 5210
+7848 2 2 4 8 572 2731 5235
+7849 2 2 4 8 1567 5235 2731
+7850 2 2 4 8 1035 2778 5006
+7851 2 2 4 8 2778 1545 5006
+7852 2 2 4 8 806 2803 4361
+7853 2 2 4 8 1410 4361 2803
+7854 2 2 4 8 1409 4360 2804
+7855 2 2 4 8 805 2804 4360
+7856 2 2 4 8 735 4612 2732
+7857 2 2 4 8 1503 2983 4387
+7858 2 2 4 8 1069 4387 2983
+7859 2 2 4 8 562 4413 4851
+7860 2 2 4 8 2478 4851 4413
+7861 2 2 4 8 1774 4398 3247
+7862 2 2 4 8 1456 3247 4398
+7863 2 2 4 8 2197 4603 4281
+7864 2 2 4 8 1659 3451 3519
+7865 2 2 4 8 653 3519 3451
+7866 2 2 4 8 654 2950 4488
+7867 2 2 4 8 1333 4523 2808
+7868 2 2 4 8 27 28 3814
+7869 2 2 4 8 1412 4013 4081
+7870 2 2 4 8 1837 4081 4013
+7871 2 2 4 8 1413 4014 4082
+7872 2 2 4 8 1838 4082 4014
+7873 2 2 4 8 1476 3568 3904
+7874 2 2 4 8 2988 5193 3369
+7875 2 2 4 8 19 3816 18
+7876 2 2 4 8 1157 3305 4433
+7877 2 2 4 8 1158 4432 3306
+7878 2 2 4 8 1774 3916 4398
+7879 2 2 4 8 1006 4922 4112
+7880 2 2 4 8 56 3109 3945
+7881 2 2 4 8 1432 3945 3109
+7882 2 2 4 8 1433 3946 3110
+7883 2 2 4 8 277 3110 3946
+7884 2 2 4 8 104 105 4395
+7885 2 2 4 8 478 5164 5275
+7886 2 2 4 8 567 5029 3093
+7887 2 2 4 8 1316 4521 3807
+7888 2 2 4 8 1317 4522 3808
+7889 2 2 4 8 1482 4178 2891
+7890 2 2 4 8 323 2891 4178
+7891 2 2 4 8 39 5103 3445
+7892 2 2 4 8 1789 3411 4764
+7893 2 2 4 8 755 4764 3411
+7894 2 2 4 8 1039 3392 3528
+7895 2 2 4 8 1557 3528 3392
+7896 2 2 4 8 1458 5387 3418
+7897 2 2 4 8 1341 3421 3422
+7898 2 2 4 8 1391 3422 3421
+7899 2 2 4 8 3423 3424 1392
+7900 2 2 4 8 3423 1342 3424
+7901 2 2 4 8 1343 3425 3426
+7902 2 2 4 8 1393 3426 3425
+7903 2 2 4 8 160 4347 2766
+7904 2 2 4 8 463 3950 4579
+7905 2 2 4 8 2030 4579 3950
+7906 2 2 4 8 997 2738 4669
+7907 2 2 4 8 4167 1573 4900
+7908 2 2 4 8 238 4605 2744
+7909 2 2 4 8 772 4349 3768
+7910 2 2 4 8 1826 3768 4349
+7911 2 2 4 8 1174 3402 4899
+7912 2 2 4 8 1830 4899 3402
+7913 2 2 4 8 430 431 3868
+7914 2 2 4 8 212 213 3867
+7915 2 2 4 8 1509 4596 3220
+7916 2 2 4 8 1436 4651 2832
+7917 2 2 4 8 567 2735 5029
+7918 2 2 4 8 1372 3772 2998
+7919 2 2 4 8 1600 4915 3031
+7920 2 2 4 8 1909 4573 3095
+7921 2 2 4 8 1910 4574 3096
+7922 2 2 4 8 1908 3097 4572
+7923 2 2 4 8 1907 3098 4571
+7924 2 2 4 8 1906 3099 4570
+7925 2 2 4 8 1905 3100 4569
+7926 2 2 4 8 961 4058 4083
+7927 2 2 4 8 1862 4083 4058
+7928 2 2 4 8 1411 3852 3133
+7929 2 2 4 8 678 3133 3852
+7930 2 2 4 8 2343 3744 4757
+7931 2 2 4 8 3745 2344 4758
+7932 2 2 4 8 805 5101 3211
+7933 2 2 4 8 806 5100 3210
+7934 2 2 4 8 3147 4493 1555
+7935 2 2 4 8 1770 4959 5231
+7936 2 2 4 8 1771 4960 5232
+7937 2 2 4 8 2092 4514 3383
+7938 2 2 4 8 2091 4513 3384
+7939 2 2 4 8 1163 3309 4392
+7940 2 2 4 8 2631 4876 4743
+7941 2 2 4 8 617 4743 4876
+7942 2 2 4 8 2226 4333 3487
+7943 2 2 4 8 2227 4334 3486
+7944 2 2 4 8 2228 4337 3485
+7945 2 2 4 8 2229 3483 4335
+7946 2 2 4 8 2230 3484 4336
+7947 2 2 4 8 495 3132 3982
+7948 2 2 4 8 784 4422 4008
+7949 2 2 4 8 1230 3063 3679
+7950 2 2 4 8 2080 4565 5302
+7951 2 2 4 8 45 3886 2975
+7952 2 2 4 8 1335 2975 3886
+7953 2 2 4 8 266 3887 2974
+7954 2 2 4 8 1334 2974 3887
+7955 2 2 4 8 1551 5240 2765
+7956 2 2 4 8 997 4886 2738
+7957 2 2 4 8 695 4451 2755
+7958 2 2 4 8 696 4452 2754
+7959 2 2 4 8 1432 2797 4539
+7960 2 2 4 8 843 4539 2797
+7961 2 2 4 8 1433 2798 4540
+7962 2 2 4 8 844 4540 2798
+7963 2 2 4 8 53 5253 3478
+7964 2 2 4 8 274 5254 3479
+7965 2 2 4 8 492 2893 3930
+7966 2 2 4 8 466 3584 5301
+7967 2 2 4 8 694 5170 2741
+7968 2 2 4 8 1549 3007 4597
+7969 2 2 4 8 1071 4597 3007
+7970 2 2 4 8 93 4416 3004
+7971 2 2 4 8 1340 5239 4892
+7972 2 2 4 8 1598 4273 2941
+7973 2 2 4 8 1599 2940 4274
+7974 2 2 4 8 1849 3752 3386
+7975 2 2 4 8 1925 2744 4605
+7976 2 2 4 8 676 5404 2750
+7977 2 2 4 8 1439 2741 5170
+7978 2 2 4 8 110 3831 2970
+7979 2 2 4 8 1118 4868 4448
+7980 2 2 4 8 2490 4448 4868
+7981 2 2 4 8 1239 3621 3136
+7982 2 2 4 8 1242 3622 3138
+7983 2 2 4 8 248 249 4749
+7984 2 2 4 8 711 4870 2742
+7985 2 2 4 8 106 107 3870
+7986 2 2 4 8 693 4909 2784
+7987 2 2 4 8 2009 2898 4675
+7988 2 2 4 8 1610 3111 4942
+7989 2 2 4 8 686 5059 2806
+7990 2 2 4 8 4172 5117 3259
+7991 2 2 4 8 1661 4450 3377
+7992 2 2 4 8 961 2740 4972
+7993 2 2 4 8 1023 2742 4816
+7994 2 2 4 8 2016 3750 4857
+7995 2 2 4 8 1238 4857 3750
+7996 2 2 4 8 496 3176 3595
+7997 2 2 4 8 4237 1289 5128
+7998 2 2 4 8 1860 4125 5281
+7999 2 2 4 8 1859 4126 5280
+8000 2 2 4 8 1071 2753 4597
+8001 2 2 4 8 1260 3563 5018
+8002 2 2 4 8 1659 4435 5196
+8003 2 2 4 8 1481 3495 3838
+8004 2 2 4 8 1540 3838 3495
+8005 2 2 4 8 1480 3496 3837
+8006 2 2 4 8 1539 3837 3496
+8007 2 2 4 8 713 3313 4057
+8008 2 2 4 8 823 4710 4837
+8009 2 2 4 8 814 4708 4835
+8010 2 2 4 8 815 4709 4836
+8011 2 2 4 8 1469 3487 4333
+8012 2 2 4 8 1468 3486 4334
+8013 2 2 4 8 1466 3485 4337
+8014 2 2 4 8 1463 4336 3484
+8015 2 2 4 8 1462 4335 3483
+8016 2 2 4 8 1107 4537 3030
+8017 2 2 4 8 382 3885 381
+8018 2 2 4 8 1060 5106 2999
+8019 2 2 4 8 2293 2999 5106
+8020 2 2 4 8 46 3886 45
+8021 2 2 4 8 266 267 3887
+8022 2 2 4 8 2314 3459 5010
+8023 2 2 4 8 757 4006 5277
+8024 2 2 4 8 525 3780 4966
+8025 2 2 4 8 714 4971 2914
+8026 2 2 4 8 1596 2914 4971
+8027 2 2 4 8 1283 4351 2863
+8028 2 2 4 8 2864 4350 1282
+8029 2 2 4 8 1026 4425 2812
+8030 2 2 4 8 1025 2811 4426
+8031 2 2 4 8 1224 3594 3593
+8032 2 2 4 8 2220 3593 3594
+8033 2 2 4 8 1667 4940 2744
+8034 2 2 4 8 237 4940 4017
+8035 2 2 4 8 954 3400 4282
+8036 2 2 4 8 336 337 4386
+8037 2 2 4 8 150 151 3901
+8038 2 2 4 8 372 3902 371
+8039 2 2 4 8 693 2792 4909
+8040 2 2 4 8 695 2755 4696
+8041 2 2 4 8 449 5249 4252
+8042 2 2 4 8 2547 5288 3701
+8043 2 2 4 8 511 3036 5227
+8044 2 2 4 8 446 3327 3956
+8045 2 2 4 8 1511 3956 3327
+8046 2 2 4 8 931 3971 2903
+8047 2 2 4 8 1449 2785 4462
+8048 2 2 4 8 1456 5037 2979
+8049 2 2 4 8 833 4195 3076
+8050 2 2 4 8 1749 5214 5206
+8051 2 2 4 8 1748 5213 5205
+8052 2 2 4 8 1184 2756 4697
+8053 2 2 4 8 478 5275 3556
+8054 2 2 4 8 1351 3139 4093
+8055 2 2 4 8 160 161 4347
+8056 2 2 4 8 1136 5319 2848
+8057 2 2 4 8 416 417 4556
+8058 2 2 4 8 2443 3447 4471
+8059 2 2 4 8 978 5411 2775
+8060 2 2 4 8 1434 3506 3640
+8061 2 2 4 8 590 5355 2757
+8062 2 2 4 8 591 5356 2758
+8063 2 2 4 8 589 5357 2759
+8064 2 2 4 8 960 2966 3928
+8065 2 2 4 8 1338 3928 2966
+8066 2 2 4 8 1026 2820 4425
+8067 2 2 4 8 1025 4426 2819
+8068 2 2 4 8 590 2757 5213
+8069 2 2 4 8 591 2758 5214
+8070 2 2 4 8 2677 3761 4186
+8071 2 2 4 8 618 4644 3544
+8072 2 2 4 8 1541 3466 4179
+8073 2 2 4 8 1739 4179 3466
+8074 2 2 4 8 1375 4185 2839
+8075 2 2 4 8 240 241 4092
+8076 2 2 4 8 1795 3364 4317
+8077 2 2 4 8 756 4317 3364
+8078 2 2 4 8 1904 2991 3875
+8079 2 2 4 8 1292 3107 5221
+8080 2 2 4 8 1293 5222 3108
+8081 2 2 4 8 474 5159 2820
+8082 2 2 4 8 472 2819 5160
+8083 2 2 4 8 350 351 4183
+8084 2 2 4 8 163 164 4182
+8085 2 2 4 8 1098 4989 2759
+8086 2 2 4 8 1343 3103 4807
+8087 2 2 4 8 1307 3268 3580
+8088 2 2 4 8 1604 3983 3734
+8089 2 2 4 8 1383 4235 3742
+8090 2 2 4 8 1642 5181 2937
+8091 2 2 4 8 1643 5180 2936
+8092 2 2 4 8 1644 2938 5179
+8093 2 2 4 8 1645 2939 5178
+8094 2 2 4 8 2139 4804 4825
+8095 2 2 4 8 2140 4805 4826
+8096 2 2 4 8 408 409 4032
+8097 2 2 4 8 1270 3768 3767
+8098 2 2 4 8 1826 3767 3768
+8099 2 2 4 8 43 44 4642
+8100 2 2 4 8 2340 4045 3702
+8101 2 2 4 8 4237 5128 2337
+8102 2 2 4 8 682 3385 5115
+8103 2 2 4 8 804 4536 4114
+8104 2 2 4 8 803 4535 4113
+8105 2 2 4 8 4164 4373 2034
+8106 2 2 4 8 4164 1417 4373
+8107 2 2 4 8 56 3945 55
+8108 2 2 4 8 276 277 3946
+8109 2 2 4 8 1590 3170 4444
+8110 2 2 4 8 539 3169 4445
+8111 2 2 4 8 1591 4445 3169
+8112 2 2 4 8 540 4444 3170
+8113 2 2 4 8 1321 5130 2771
+8114 2 2 4 8 3039 1246 3796
+8115 2 2 4 8 2424 4262 3223
+8116 2 2 4 8 527 3504 5013
+8117 2 2 4 8 1962 2879 4397
+8118 2 2 4 8 405 406 3953
+8119 2 2 4 8 1152 5251 2779
+8120 2 2 4 8 1829 5272 4375
+8121 2 2 4 8 1034 5282 2781
+8122 2 2 4 8 1661 5143 4450
+8123 2 2 4 8 193 194 4906
+8124 2 2 4 8 707 3273 4196
+8125 2 2 4 8 706 3272 4197
+8126 2 2 4 8 748 4818 3805
+8127 2 2 4 8 871 4896 5374
+8128 2 2 4 8 529 3193 4904
+8129 2 2 4 8 1072 2916 4476
+8130 2 2 4 8 1532 3197 4181
+8131 2 2 4 8 704 4181 3197
+8132 2 2 4 8 1116 2787 5386
+8133 2 2 4 8 1621 5386 2787
+8134 2 2 4 8 1663 5150 4354
+8135 2 2 4 8 1459 5057 3419
+8136 2 2 4 8 278 279 4593
+8137 2 2 4 8 58 4591 57
+8138 2 2 4 8 264 265 4592
+8139 2 2 4 8 518 3608 3640
+8140 2 2 4 8 1869 3505 4953
+8141 2 2 4 8 244 4953 3505
+8142 2 2 4 8 754 3861 4894
+8143 2 2 4 8 1266 3982 3132
+8144 2 2 4 8 980 4330 3381
+8145 2 2 4 8 1631 3381 4330
+8146 2 2 4 8 943 4022 3766
+8147 2 2 4 8 1673 3766 4022
+8148 2 2 4 8 1199 2780 4887
+8149 2 2 4 8 1051 2802 4503
+8150 2 2 4 8 1640 5151 3326
+8151 2 2 4 8 537 5046 3937
+8152 2 2 4 8 2189 3937 5046
+8153 2 2 4 8 1806 3993 3208
+8154 2 2 4 8 890 3208 3993
+8155 2 2 4 8 1533 3071 4374
+8156 2 2 4 8 705 4374 3071
+8157 2 2 4 8 1642 3067 3971
+8158 2 2 4 8 1603 5050 2995
+8159 2 2 4 8 693 2918 5002
+8160 2 2 4 8 464 3915 3757
+8161 2 2 4 8 1636 3757 3915
+8162 2 2 4 8 1369 2784 4909
+8163 2 2 4 8 1371 3492 4331
+8164 2 2 4 8 1458 3770 5387
+8165 2 2 4 8 1207 3275 3603
+8166 2 2 4 8 546 2833 4820
+8167 2 2 4 8 1506 4820 2833
+8168 2 2 4 8 728 2896 4087
+8169 2 2 4 8 731 4088 2897
+8170 2 2 4 8 1979 3396 5402
+8171 2 2 4 8 534 5402 3396
+8172 2 2 4 8 1336 3520 3428
+8173 2 2 4 8 1422 4188 2915
+8174 2 2 4 8 186 187 4038
+8175 2 2 4 8 77 4041 76
+8176 2 2 4 8 1312 3727 4282
+8177 2 2 4 8 1275 2962 5211
+8178 2 2 4 8 749 3803 5039
+8179 2 2 4 8 750 5038 3804
+8180 2 2 4 8 863 2832 4827
+8181 2 2 4 8 1505 4827 2832
+8182 2 2 4 8 1355 2819 4426
+8183 2 2 4 8 1356 4425 2820
+8184 2 2 4 8 80 2808 4523
+8185 2 2 4 8 1404 4767 2858
+8186 2 2 4 8 1405 4769 2857
+8187 2 2 4 8 1406 4768 2859
+8188 2 2 4 8 1401 2850 4422
+8189 2 2 4 8 1300 3077 5053
+8190 2 2 4 8 1301 3075 5052
+8191 2 2 4 8 1418 3085 4163
+8192 2 2 4 8 1844 4931 4140
+8193 2 2 4 8 1846 4139 4929
+8194 2 2 4 8 1845 4137 4928
+8195 2 2 4 8 1847 4138 4930
+8196 2 2 4 8 1377 3863 5137
+8197 2 2 4 8 753 3862 5136
+8198 2 2 4 8 782 3669 4359
+8199 2 2 4 8 2079 4359 3669
+8200 2 2 4 8 455 4348 2841
+8201 2 2 4 8 1319 3142 4428
+8202 2 2 4 8 1320 3141 4430
+8203 2 2 4 8 1321 3140 4429
+8204 2 2 4 8 1300 5053 3082
+8205 2 2 4 8 1301 5052 3083
+8206 2 2 4 8 1339 3964 4888
+8207 2 2 4 8 1420 3811 3297
+8208 2 2 4 8 533 3297 3811
+8209 2 2 4 8 1132 3762 5278
+8210 2 2 4 8 582 3083 5079
+8211 2 2 4 8 1688 5079 3083
+8212 2 2 4 8 1683 5078 3082
+8213 2 2 4 8 587 3082 5078
+8214 2 2 4 8 1738 5238 2792
+8215 2 2 4 8 285 286 4035
+8216 2 2 4 8 257 258 4036
+8217 2 2 4 8 65 4037 64
+8218 2 2 4 8 1658 3350 4923
+8219 2 2 4 8 1263 4800 3264
+8220 2 2 4 8 1141 5056 3713
+8221 2 2 4 8 1142 3712 5055
+8222 2 2 4 8 347 348 4434
+8223 2 2 4 8 58 2994 4591
+8224 2 2 4 8 279 2996 4593
+8225 2 2 4 8 264 4592 2995
+8226 2 2 4 8 1213 3188 5030
+8227 2 2 4 8 1216 3191 5031
+8228 2 2 4 8 201 4054 2946
+8229 2 2 4 8 226 2945 4055
+8230 2 2 4 8 710 2986 4673
+8231 2 2 4 8 855 5048 5166
+8232 2 2 4 8 1131 2865 4258
+8233 2 2 4 8 1586 3924 4551
+8234 2 2 4 8 693 5002 2965
+8235 2 2 4 8 1111 5379 3994
+8236 2 2 4 8 2359 3994 5379
+8237 2 2 4 8 1114 5292 2799
+8238 2 2 4 8 1579 2799 5292
+8239 2 2 4 8 1449 2990 4516
+8240 2 2 4 8 1448 2989 4515
+8241 2 2 4 8 1388 4631 3688
+8242 2 2 4 8 1451 4452 3280
+8243 2 2 4 8 1141 4758 3145
+8244 2 2 4 8 1142 3146 4757
+8245 2 2 4 8 845 4634 2880
+8246 2 2 4 8 1483 2880 4634
+8247 2 2 4 8 347 4434 2839
+8248 2 2 4 8 2042 4143 2916
+8249 2 2 4 8 1281 4034 2969
+8250 2 2 4 8 540 2835 4444
+8251 2 2 4 8 539 4445 2836
+8252 2 2 4 8 1518 4084 3988
+8253 2 2 4 8 92 4996 3620
+8254 2 2 4 8 392 393 4056
+8255 2 2 4 8 1676 3199 4085
+8256 2 2 4 8 359 3409 4729
+8257 2 2 4 8 1729 4729 3409
+8258 2 2 4 8 172 3410 4730
+8259 2 2 4 8 1728 4730 3410
+8260 2 2 4 8 1594 3550 3956
+8261 2 2 4 8 446 3956 3550
+8262 2 2 4 8 550 5109 2800
+8263 2 2 4 8 1540 2800 5109
+8264 2 2 4 8 549 5108 2801
+8265 2 2 4 8 1539 2801 5108
+8266 2 2 4 8 1131 4284 2865
+8267 2 2 4 8 619 4446 3545
+8268 2 2 4 8 2198 3736 5229
+8269 2 2 4 8 1129 5229 3736
+8270 2 2 4 8 1792 4040 4854
+8271 2 2 4 8 456 5394 4298
+8272 2 2 4 8 1677 2950 4067
+8273 2 2 4 8 1795 4317 3836
+8274 2 2 4 8 1620 3836 4317
+8275 2 2 4 8 1051 4941 2802
+8276 2 2 4 8 369 370 4528
+8277 2 2 4 8 148 149 4527
+8278 2 2 4 8 383 384 4526
+8279 2 2 4 8 630 5236 3283
+8280 2 2 4 8 142 4071 141
+8281 2 2 4 8 362 363 4072
+8282 2 2 4 8 400 3739 3181
+8283 2 2 4 8 445 4848 2840
+8284 2 2 4 8 475 3081 3849
+8285 2 2 4 8 1754 3643 3644
+8286 2 2 4 8 1265 3644 3643
+8287 2 2 4 8 43 4642 3031
+8288 2 2 4 8 568 4209 3577
+8289 2 2 4 8 1648 3577 4209
+8290 2 2 4 8 2394 5267 3900
+8291 2 2 4 8 2353 4649 3064
+8292 2 2 4 8 696 4263 2882
+8293 2 2 4 8 1136 2949 5319
+8294 2 2 4 8 2000 2913 4247
+8295 2 2 4 8 2350 3453 4777
+8296 2 2 4 8 972 2930 4157
+8297 2 2 4 8 2576 5306 4984
+8298 2 2 4 8 697 4521 3136
+8299 2 2 4 8 699 4522 3138
+8300 2 2 4 8 1416 2976 4057
+8301 2 2 4 8 68 4713 3405
+8302 2 2 4 8 1719 3405 4713
+8303 2 2 4 8 848 3734 3983
+8304 2 2 4 8 2372 4623 3756
+8305 2 2 4 8 1273 4821 3196
+8306 2 2 4 8 304 305 5400
+8307 2 2 4 8 293 294 5399
+8308 2 2 4 8 178 179 5398
+8309 2 2 4 8 133 134 5397
+8310 2 2 4 8 122 123 5396
+8311 2 2 4 8 112 5395 111
+8312 2 2 4 8 1626 3143 5042
+8313 2 2 4 8 798 4602 3378
+8314 2 2 4 8 1529 4079 4834
+8315 2 2 4 8 1528 4080 4833
+8316 2 2 4 8 1399 4184 2918
+8317 2 2 4 8 1438 2833 4666
+8318 2 2 4 8 700 3959 5289
+8319 2 2 4 8 1645 5178 3800
+8320 2 2 4 8 1643 3798 5180
+8321 2 2 4 8 1644 5179 3799
+8322 2 2 4 8 1642 3797 5181
+8323 2 2 4 8 462 5286 3965
+8324 2 2 4 8 2281 3965 5286
+8325 2 2 4 8 801 3482 5406
+8326 2 2 4 8 2003 5406 3482
+8327 2 2 4 8 546 4666 2833
+8328 2 2 4 8 86 4147 85
+8329 2 2 4 8 1663 4879 5150
+8330 2 2 4 8 1241 4156 3220
+8331 2 2 4 8 1518 3988 5037
+8332 2 2 4 8 418 419 4255
+8333 2 2 4 8 1371 4331 3687
+8334 2 2 4 8 542 4372 2870
+8335 2 2 4 8 1339 3642 5354
+8336 2 2 4 8 931 3797 3971
+8337 2 2 4 8 1642 3971 3797
+8338 2 2 4 8 2489 4618 2927
+8339 2 2 4 8 40 3329 5103
+8340 2 2 4 8 1786 5103 3329
+8341 2 2 4 8 1698 4091 5144
+8342 2 2 4 8 1673 4181 4000
+8343 2 2 4 8 1278 3072 4503
+8344 2 2 4 8 1651 5036 3068
+8345 2 2 4 8 1180 3068 5036
+8346 2 2 4 8 1181 3069 5035
+8347 2 2 4 8 3069 1650 5035
+8348 2 2 4 8 799 4766 3379
+8349 2 2 4 8 1355 5160 2819
+8350 2 2 4 8 1356 2820 5159
+8351 2 2 4 8 3086 2658 4699
+8352 2 2 4 8 445 3416 4102
+8353 2 2 4 8 1351 4093 3389
+8354 2 2 4 8 2104 3186 5220
+8355 2 2 4 8 1923 2972 4156
+8356 2 2 4 8 322 323 4178
+8357 2 2 4 8 1137 4623 2923
+8358 2 2 4 8 524 3605 4207
+8359 2 2 4 8 445 2840 4772
+8360 2 2 4 8 4237 2337 5060
+8361 2 2 4 8 912 4237 5060
+8362 2 2 4 8 464 3757 5360
+8363 2 2 4 8 1717 4839 2834
+8364 2 2 4 8 816 5031 3191
+8365 2 2 4 8 824 5030 3188
+8366 2 2 4 8 712 3051 4777
+8367 2 2 4 8 1849 3054 4248
+8368 2 2 4 8 739 3787 3454
+8369 2 2 4 8 1465 3454 3787
+8370 2 2 4 8 1071 5279 2840
+8371 2 2 4 8 1701 4924 3233
+8372 2 2 4 8 538 3233 4924
+8373 2 2 4 8 1371 3687 3340
+8374 2 2 4 8 1370 3339 3688
+8375 2 2 4 8 683 3127 4844
+8376 2 2 4 8 455 2895 5177
+8377 2 2 4 8 1588 5177 2895
+8378 2 2 4 8 73 74 4201
+8379 2 2 4 8 90 5171 89
+8380 2 2 4 8 1980 4802 2841
+8381 2 2 4 8 1265 4216 2951
+8382 2 2 4 8 1655 4901 3331
+8383 2 2 4 8 765 4627 5283
+8384 2 2 4 8 369 4528 3017
+8385 2 2 4 8 148 4527 3018
+8386 2 2 4 8 384 3016 4526
+8387 2 2 4 8 1258 2882 4410
+8388 2 2 4 8 1363 2952 4588
+8389 2 2 4 8 1476 4525 4585
+8390 2 2 4 8 2109 3513 4393
+8391 2 2 4 8 1006 3354 3949
+8392 2 2 4 8 1479 3949 3354
+8393 2 2 4 8 713 4057 4130
+8394 2 2 4 8 1790 3490 4876
+8395 2 2 4 8 617 4876 3490
+8396 2 2 4 8 2396 4701 3053
+8397 2 2 4 8 680 4316 2916
+8398 2 2 4 8 2443 3258 4984
+8399 2 2 4 8 1805 4234 4926
+8400 2 2 4 8 1930 4460 5001
+8401 2 2 4 8 12 4254 11
+8402 2 2 4 8 631 4984 5306
+8403 2 2 4 8 1660 4720 3380
+8404 2 2 4 8 497 4116 3053
+8405 2 2 4 8 1403 3053 4116
+8406 2 2 4 8 1767 5366 3052
+8407 2 2 4 8 403 3052 5366
+8408 2 2 4 8 2356 4656 5297
+8409 2 2 4 8 506 4163 3085
+8410 2 2 4 8 946 3322 4210
+8411 2 2 4 8 1542 4210 3322
+8412 2 2 4 8 1442 3095 4573
+8413 2 2 4 8 1443 3096 4574
+8414 2 2 4 8 1444 4572 3097
+8415 2 2 4 8 1445 4571 3098
+8416 2 2 4 8 1446 4570 3099
+8417 2 2 4 8 1447 4569 3100
+8418 2 2 4 8 1115 3144 4427
+8419 2 2 4 8 730 4439 2888
+8420 2 2 4 8 1549 3634 4965
+8421 2 2 4 8 1581 3882 3676
+8422 2 2 4 8 714 4305 2929
+8423 2 2 4 8 1609 4737 3112
+8424 2 2 4 8 301 3111 4739
+8425 2 2 4 8 1610 4739 3111
+8426 2 2 4 8 290 3112 4737
+8427 2 2 4 8 1612 3113 4736
+8428 2 2 4 8 182 4736 3113
+8429 2 2 4 8 1613 3114 4735
+8430 2 2 4 8 137 4735 3114
+8431 2 2 4 8 126 4734 3115
+8432 2 2 4 8 1614 3115 4734
+8433 2 2 4 8 115 4733 3116
+8434 2 2 4 8 1615 3116 4733
+8435 2 2 4 8 1055 2841 5157
+8436 2 2 4 8 1338 2966 4917
+8437 2 2 4 8 1240 4364 3360
+8438 2 2 4 8 876 4048 3624
+8439 2 2 4 8 1508 4242 3622
+8440 2 2 4 8 1507 4244 3621
+8441 2 2 4 8 96 4275 95
+8442 2 2 4 8 1696 2931 4681
+8443 2 2 4 8 214 2925 4486
+8444 2 2 4 8 432 2926 4485
+8445 2 2 4 8 1737 3297 4617
+8446 2 2 4 8 390 391 4279
+8447 2 2 4 8 451 2904 5337
+8448 2 2 4 8 442 5335 2906
+8449 2 2 4 8 450 5336 2905
+8450 2 2 4 8 1721 3918 3463
+8451 2 2 4 8 1722 3464 3919
+8452 2 2 4 8 1370 4388 3525
+8453 2 2 4 8 1484 4843 2851
+8454 2 2 4 8 1585 4686 3833
+8455 2 2 4 8 1848 5152 4377
+8456 2 2 4 8 2869 5389 3876
+8457 2 2 4 8 1168 2978 4230
+8458 2 2 4 8 1343 4807 3425
+8459 2 2 4 8 901 5381 3850
+8460 2 2 4 8 441 4652 3025
+8461 2 2 4 8 560 2851 4843
+8462 2 2 4 8 1678 3209 5382
+8463 2 2 4 8 1238 4611 3455
+8464 2 2 4 8 1264 4407 2911
+8465 2 2 4 8 1701 5165 2844
+8466 2 2 4 8 536 3748 3677
+8467 2 2 4 8 1518 3677 3748
+8468 2 2 4 8 1472 3647 3792
+8469 2 2 4 8 1390 3640 3506
+8470 2 2 4 8 1694 3909 4018
+8471 2 2 4 8 722 4018 3909
+8472 2 2 4 8 922 3499 5420
+8473 2 2 4 8 1347 4281 2968
+8474 2 2 4 8 1605 5376 2896
+8475 2 2 4 8 1606 2897 5377
+8476 2 2 4 8 1207 5227 3036
+8477 2 2 4 8 1313 4133 4134
+8478 2 2 4 8 4133 2407 4134
+8479 2 2 4 8 1314 4136 4135
+8480 2 2 4 8 4135 4136 2408
+8481 2 2 4 8 734 2943 4620
+8482 2 2 4 8 1905 3831 5395
+8483 2 2 4 8 694 4241 2987
+8484 2 2 4 8 1339 5354 3926
+8485 2 2 4 8 1402 3882 5019
+8486 2 2 4 8 1708 5039 3633
+8487 2 2 4 8 1709 3632 5038
+8488 2 2 4 8 1326 2848 5319
+8489 2 2 4 8 774 4184 4132
+8490 2 2 4 8 2092 4837 4710
+8491 2 2 4 8 2090 4835 4708
+8492 2 2 4 8 2091 4836 4709
+8493 2 2 4 8 2852 5077 1800
+8494 2 2 4 8 1267 3875 3205
+8495 2 2 4 8 495 3982 3607
+8496 2 2 4 8 213 214 4486
+8497 2 2 4 8 431 432 4485
+8498 2 2 4 8 771 4004 4101
+8499 2 2 4 8 1763 4101 4004
+8500 2 2 4 8 209 210 4830
+8501 2 2 4 8 427 428 4829
+8502 2 2 4 8 1279 2987 4257
+8503 2 2 4 8 1801 3972 4286
+8504 2 2 4 8 1477 4286 3972
+8505 2 2 4 8 1457 2874 5005
+8506 2 2 4 8 900 3038 4290
+8507 2 2 4 8 1270 3324 5166
+8508 2 2 4 8 702 4246 3220
+8509 2 2 4 8 1509 3220 4246
+8510 2 2 4 8 1510 4547 4765
+8511 2 2 4 8 767 3437 4079
+8512 2 2 4 8 1772 4079 3437
+8513 2 2 4 8 1773 4080 3438
+8514 2 2 4 8 766 3438 4080
+8515 2 2 4 8 1229 4974 2861
+8516 2 2 4 8 1231 4975 2860
+8517 2 2 4 8 2242 4790 5066
+8518 2 2 4 8 1307 4635 3268
+8519 2 2 4 8 1367 4132 3033
+8520 2 2 4 8 3513 1264 4393
+8521 2 2 4 8 398 399 4367
+8522 2 2 4 8 1995 5317 5293
+8523 2 2 4 8 1465 4599 2900
+8524 2 2 4 8 4152 4965 2219
+8525 2 2 4 8 1302 4814 3289
+8526 2 2 4 8 1213 5030 3473
+8527 2 2 4 8 1216 5031 3474
+8528 2 2 4 8 1292 5221 3527
+8529 2 2 4 8 1293 3526 5222
+8530 2 2 4 8 476 3386 3752
+8531 2 2 4 8 1483 2928 5262
+8532 2 2 4 8 656 4235 3105
+8533 2 2 4 8 77 3101 4041
+8534 2 2 4 8 2016 4823 3750
+8535 2 2 4 8 825 3750 4823
+8536 2 2 4 8 678 4100 3046
+8537 2 2 4 8 1963 3898 4762
+8538 2 2 4 8 831 4762 3898
+8539 2 2 4 8 621 2872 4838
+8540 2 2 4 8 1691 3613 5148
+8541 2 2 4 8 858 4206 5382
+8542 2 2 4 8 395 3014 4208
+8543 2 2 4 8 1541 4056 3466
+8544 2 2 4 8 393 3466 4056
+8545 2 2 4 8 1596 5008 3284
+8546 2 2 4 8 1156 4616 3304
+8547 2 2 4 8 1449 4462 2990
+8548 2 2 4 8 947 2990 4462
+8549 2 2 4 8 1590 5043 3170
+8550 2 2 4 8 1592 5044 3171
+8551 2 2 4 8 236 4017 3090
+8552 2 2 4 8 1271 3989 3124
+8553 2 2 4 8 1177 4394 2951
+8554 2 2 4 8 307 308 4380
+8555 2 2 4 8 296 297 4381
+8556 2 2 4 8 175 176 4382
+8557 2 2 4 8 130 131 4383
+8558 2 2 4 8 119 120 4384
+8559 2 2 4 8 1453 4352 4128
+8560 2 2 4 8 1899 4128 4352
+8561 2 2 4 8 1898 4353 4129
+8562 2 2 4 8 1454 4129 4353
+8563 2 2 4 8 1781 5325 3404
+8564 2 2 4 8 1993 3212 4779
+8565 2 2 4 8 1992 3213 4778
+8566 2 2 4 8 2116 4668 4832
+8567 2 2 4 8 2096 4585 4525
+8568 2 2 4 8 1401 3065 4171
+8569 2 2 4 8 431 4485 3868
+8570 2 2 4 8 1813 3868 4485
+8571 2 2 4 8 213 4486 3867
+8572 2 2 4 8 1814 3867 4486
+8573 2 2 4 8 1559 4825 4804
+8574 2 2 4 8 1560 4826 4805
+8575 2 2 4 8 1178 5022 3394
+8576 2 2 4 8 941 3380 4720
+8577 2 2 4 8 1654 2964 4375
+8578 2 2 4 8 1434 4467 2934
+8579 2 2 4 8 1500 3239 4761
+8580 2 2 4 8 569 3157 5131
+8581 2 2 4 8 1250 4150 3336
+8582 2 2 4 8 3086 4478 2314
+8583 2 2 4 8 1924 2971 4364
+8584 2 2 4 8 186 4038 4791
+8585 2 2 4 8 2046 4791 4038
+8586 2 2 4 8 2759 5357 3557
+8587 2 2 4 8 2758 5356 3559
+8588 2 2 4 8 2757 5355 3558
+8589 2 2 4 8 1459 4066 5057
+8590 2 2 4 8 1287 4886 3155
+8591 2 2 4 8 1075 3042 5064
+8592 2 2 4 8 1313 3434 4023
+8593 2 2 4 8 1314 3435 4024
+8594 2 2 4 8 471 3587 3978
+8595 2 2 4 8 579 5389 2869
+8596 2 2 4 8 2103 3194 5226
+8597 2 2 4 8 1741 4679 3091
+8598 2 2 4 8 1742 4680 3092
+8599 2 2 4 8 350 4183 3185
+8600 2 2 4 8 163 4182 3184
+8601 2 2 4 8 1531 4263 5346
+8602 2 2 4 8 1593 4483 4453
+8603 2 2 4 8 2130 4453 4483
+8604 2 2 4 8 803 4113 4472
+8605 2 2 4 8 1955 4472 4113
+8606 2 2 4 8 804 4114 4474
+8607 2 2 4 8 1956 4474 4114
+8608 2 2 4 8 613 4679 5172
+8609 2 2 4 8 1089 2877 4942
+8610 2 2 4 8 1746 4536 3648
+8611 2 2 4 8 1745 3650 4534
+8612 2 2 4 8 1747 4535 3649
+8613 2 2 4 8 1587 5127 4982
+8614 2 2 4 8 970 5005 2874
+8615 2 2 4 8 41 4402 3329
+8616 2 2 4 8 497 4171 3065
+8617 2 2 4 8 1285 4488 2950
+8618 2 2 4 8 1370 3688 4388
+8619 2 2 4 8 1996 4743 3706
+8620 2 2 4 8 617 3706 4743
+8621 2 2 4 8 238 239 4605
+8622 2 2 4 8 1365 2923 4623
+8623 2 2 4 8 2093 4530 4785
+8624 2 2 4 8 73 4201 5361
+8625 2 2 4 8 1303 3084 4200
+8626 2 2 4 8 842 5133 3350
+8627 2 2 4 8 1767 3350 5133
+8628 2 2 4 8 1186 5132 3005
+8629 2 2 4 8 1608 3005 5132
+8630 2 2 4 8 2342 5166 5048
+8631 2 2 4 8 2232 4765 4547
+8632 2 2 4 8 1476 3904 4525
+8633 2 2 4 8 1494 4015 4342
+8634 2 2 4 8 1828 4342 4015
+8635 2 2 4 8 1330 4099 3611
+8636 2 2 4 8 1653 3657 4278
+8637 2 2 4 8 530 4278 3657
+8638 2 2 4 8 11 4254 3041
+8639 2 2 4 8 1512 3041 4254
+8640 2 2 4 8 2638 3620 5058
+8641 2 2 4 8 230 231 4520
+8642 2 2 4 8 1402 5019 5289
+8643 2 2 4 8 1284 3126 4400
+8644 2 2 4 8 1263 3685 4800
+8645 2 2 4 8 330 331 4531
+8646 2 2 4 8 185 4791 2900
+8647 2 2 4 8 2410 3599 3943
+8648 2 2 4 8 2046 2900 4791
+8649 2 2 4 8 1483 4634 2928
+8650 2 2 4 8 1382 3488 4568
+8651 2 2 4 8 1479 5337 2904
+8652 2 2 4 8 1481 2905 5336
+8653 2 2 4 8 1480 2906 5335
+8654 2 2 4 8 1131 2892 5296
+8655 2 2 4 8 1357 3397 4628
+8656 2 2 4 8 781 3658 4525
+8657 2 2 4 8 2096 4525 3658
+8658 2 2 4 8 1228 3616 4141
+8659 2 2 4 8 1875 3877 4716
+8660 2 2 4 8 1913 5303 4688
+8661 2 2 4 8 974 3348 4355
+8662 2 2 4 8 1567 4355 3348
+8663 2 2 4 8 1509 4064 4596
+8664 2 2 4 8 830 4809 3873
+8665 2 2 4 8 1942 3873 4809
+8666 2 2 4 8 1527 2986 4831
+8667 2 2 4 8 710 4831 2986
+8668 2 2 4 8 645 4588 2952
+8669 2 2 4 8 1324 3723 3722
+8670 2 2 4 8 1644 3722 3723
+8671 2 2 4 8 1325 3721 3720
+8672 2 2 4 8 1645 3720 3721
+8673 2 2 4 8 2998 5391 4298
+8674 2 2 4 8 242 2928 4998
+8675 2 2 4 8 2076 4998 2928
+8676 2 2 4 8 1393 3650 4470
+8677 2 2 4 8 696 2882 5326
+8678 2 2 4 8 1557 5197 3461
+8679 2 2 4 8 783 3944 3742
+8680 2 2 4 8 1202 3278 4144
+8681 2 2 4 8 943 3766 4578
+8682 2 2 4 8 1782 4578 3766
+8683 2 2 4 8 1844 4140 3857
+8684 2 2 4 8 1846 3858 4139
+8685 2 2 4 8 1845 3859 4137
+8686 2 2 4 8 1847 3860 4138
+8687 2 2 4 8 1874 3064 4649
+8688 2 2 4 8 1399 4368 3033
+8689 2 2 4 8 510 3406 3903
+8690 2 2 4 8 1703 3903 3406
+8691 2 2 4 8 304 5400 3096
+8692 2 2 4 8 293 5399 3095
+8693 2 2 4 8 179 3097 5398
+8694 2 2 4 8 134 3098 5397
+8695 2 2 4 8 123 3099 5396
+8696 2 2 4 8 112 3100 5395
+8697 2 2 4 8 1126 3223 4262
+8698 2 2 4 8 773 3651 4731
+8699 2 2 4 8 1984 4731 3651
+8700 2 2 4 8 411 412 4751
+8701 2 2 4 8 1028 2896 5376
+8702 2 2 4 8 1029 5377 2897
+8703 2 2 4 8 1535 3741 4723
+8704 2 2 4 8 1030 5365 2888
+8705 2 2 4 8 2014 4379 4332
+8706 2 2 4 8 1622 4332 4379
+8707 2 2 4 8 521 4415 3583
+8708 2 2 4 8 1367 3325 4132
+8709 2 2 4 8 1922 2963 4611
+8710 2 2 4 8 1065 4871 2914
+8711 2 2 4 8 936 3896 3301
+8712 2 2 4 8 937 3300 3897
+8713 2 2 4 8 1612 5228 3113
+8714 2 2 4 8 1474 4359 4564
+8715 2 2 4 8 2079 4564 4359
+8716 2 2 4 8 2276 5222 3526
+8717 2 2 4 8 2277 3527 5221
+8718 2 2 4 8 1687 5069 2899
+8719 2 2 4 8 940 5042 3143
+8720 2 2 4 8 612 2937 4732
+8721 2 2 4 8 341 342 5107
+8722 2 2 4 8 704 4000 4181
+8723 2 2 4 8 1634 3152 4973
+8724 2 2 4 8 1179 4973 3152
+8725 2 2 4 8 1364 4174 3221
+8726 2 2 4 8 1365 3222 4175
+8727 2 2 4 8 1805 3801 4234
+8728 2 2 4 8 1359 4290 3038
+8729 2 2 4 8 1667 5297 4656
+8730 2 2 4 8 100 101 4689
+8731 2 2 4 8 1497 3903 4168
+8732 2 2 4 8 1703 4168 3903
+8733 2 2 4 8 108 109 4690
+8734 2 2 4 8 602 4968 2912
+8735 2 2 4 8 1496 4427 3144
+8736 2 2 4 8 2222 3158 4044
+8737 2 2 4 8 576 4044 3158
+8738 2 2 4 8 2272 5283 4627
+8739 2 2 4 8 732 4824 2942
+8740 2 2 4 8 1553 4062 4339
+8741 2 2 4 8 1138 5231 2901
+8742 2 2 4 8 1140 5232 2902
+8743 2 2 4 8 1329 3515 3765
+8744 2 2 4 8 1302 3076 4195
+8745 2 2 4 8 69 4713 68
+8746 2 2 4 8 704 3197 4671
+8747 2 2 4 8 2837 5158 5323
+8748 2 2 4 8 541 5323 5158
+8749 2 2 4 8 811 4170 3774
+8750 2 2 4 8 551 3331 4901
+8751 2 2 4 8 1403 4101 4109
+8752 2 2 4 8 1763 4109 4101
+8753 2 2 4 8 605 4784 2939
+8754 2 2 4 8 611 2936 4785
+8755 2 2 4 8 495 3501 3891
+8756 2 2 4 8 1478 3891 3501
+8757 2 2 4 8 358 359 4729
+8758 2 2 4 8 171 172 4730
+8759 2 2 4 8 2139 3172 4804
+8760 2 2 4 8 2140 3173 4805
+8761 2 2 4 8 116 4733 115
+8762 2 2 4 8 126 127 4734
+8763 2 2 4 8 138 4735 137
+8764 2 2 4 8 182 183 4736
+8765 2 2 4 8 300 301 4739
+8766 2 2 4 8 311 312 4738
+8767 2 2 4 8 290 4737 289
+8768 2 2 4 8 471 3106 4329
+8769 2 2 4 8 2284 5188 4303
+8770 2 2 4 8 2285 5187 4304
+8771 2 2 4 8 335 3925 3302
+8772 2 2 4 8 1401 4422 3056
+8773 2 2 4 8 261 3252 5161
+8774 2 2 4 8 1714 5161 3252
+8775 2 2 4 8 282 5162 3253
+8776 2 2 4 8 1715 3253 5162
+8777 2 2 4 8 1716 3254 5163
+8778 2 2 4 8 61 5163 3254
+8779 2 2 4 8 1318 5002 2918
+8780 2 2 4 8 1635 3455 3869
+8781 2 2 4 8 701 3869 3455
+8782 2 2 4 8 1230 4715 2961
+8783 2 2 4 8 1552 4589 4108
+8784 2 2 4 8 331 3120 4531
+8785 2 2 4 8 1574 4531 3120
+8786 2 2 4 8 1654 4375 3610
+8787 2 2 4 8 793 3610 4375
+8788 2 2 4 8 1303 4200 3151
+8789 2 2 4 8 2625 3706 4745
+8790 2 2 4 8 1390 3506 4365
+8791 2 2 4 8 1738 2965 5076
+8792 2 2 4 8 689 3546 3888
+8793 2 2 4 8 1510 3888 3546
+8794 2 2 4 8 523 2932 4893
+8795 2 2 4 8 1594 3985 3771
+8796 2 2 4 8 763 3771 3985
+8797 2 2 4 8 1537 4877 4436
+8798 2 2 4 8 2279 4436 4877
+8799 2 2 4 8 529 5047 3193
+8800 2 2 4 8 1658 3193 5047
+8801 2 2 4 8 4180 1832 4492
+8802 2 2 4 8 1068 2986 4891
+8803 2 2 4 8 1527 4891 2986
+8804 2 2 4 8 185 186 4791
+8805 2 2 4 8 1423 5375 3001
+8806 2 2 4 8 1601 4591 2994
+8807 2 2 4 8 1603 2995 4592
+8808 2 2 4 8 1602 4593 2996
+8809 2 2 4 8 1593 2948 4906
+8810 2 2 4 8 193 4906 2948
+8811 2 2 4 8 772 3430 3995
+8812 2 2 4 8 1997 3995 3430
+8813 2 2 4 8 1531 3704 4748
+8814 2 2 4 8 1367 4461 3325
+8815 2 2 4 8 823 4837 3192
+8816 2 2 4 8 814 4835 3189
+8817 2 2 4 8 815 4836 3190
+8818 2 2 4 8 789 4185 4767
+8819 2 2 4 8 1382 3884 3387
+8820 2 2 4 8 534 3033 4368
+8821 2 2 4 8 1448 5017 2989
+8822 2 2 4 8 1796 3523 5051
+8823 2 2 4 8 1471 3207 4207
+8824 2 2 4 8 524 4207 3207
+8825 2 2 4 8 1110 2917 5353
+8826 2 2 4 8 757 5141 3458
+8827 2 2 4 8 1790 3458 5141
+8828 2 2 4 8 79 4523 3598
+8829 2 2 4 8 1200 2932 5001
+8830 2 2 4 8 503 3353 4161
+8831 2 2 4 8 1225 3210 5100
+8832 2 2 4 8 1226 3211 5101
+8833 2 2 4 8 1431 3895 4577
+8834 2 2 4 8 710 4673 2988
+8835 2 2 4 8 1605 4526 3016
+8836 2 2 4 8 1606 3018 4527
+8837 2 2 4 8 1607 3017 4528
+8838 2 2 4 8 604 4986 2938
+8839 2 2 4 8 441 2991 4652
+8840 2 2 4 8 1041 4804 3172
+8841 2 2 4 8 1040 4805 3173
+8842 2 2 4 8 921 2924 5304
+8843 2 2 4 8 1554 3543 4153
+8844 2 2 4 8 661 4153 3543
+8845 2 2 4 8 1380 4121 3159
+8846 2 2 4 8 1381 4120 3160
+8847 2 2 4 8 1742 3987 4259
+8848 2 2 4 8 1423 3001 4794
+8849 2 2 4 8 918 3548 5173
+8850 2 2 4 8 1422 3520 4188
+8851 2 2 4 8 1331 3627 4228
+8852 2 2 4 8 1368 4479 3871
+8853 2 2 4 8 396 397 4921
+8854 2 2 4 8 792 4496 4315
+8855 2 2 4 8 2021 4315 4496
+8856 2 2 4 8 338 339 4933
+8857 2 2 4 8 579 5194 4232
+8858 2 2 4 8 328 329 4939
+8859 2 2 4 8 244 245 4953
+8860 2 2 4 8 1552 4108 4340
+8861 2 2 4 8 1630 5313 3782
+8862 2 2 4 8 1174 4899 3652
+8863 2 2 4 8 1685 2947 5072
+8864 2 2 4 8 4241 5237 1500
+8865 2 2 4 8 1538 3236 4905
+8866 2 2 4 8 614 2941 5176
+8867 2 2 4 8 1615 4733 3240
+8868 2 2 4 8 116 3240 4733
+8869 2 2 4 8 127 3241 4734
+8870 2 2 4 8 1614 4734 3241
+8871 2 2 4 8 1613 4735 3242
+8872 2 2 4 8 138 3242 4735
+8873 2 2 4 8 1612 4736 3243
+8874 2 2 4 8 183 3243 4736
+8875 2 2 4 8 1609 3245 4737
+8876 2 2 4 8 289 4737 3245
+8877 2 2 4 8 311 4738 3244
+8878 2 2 4 8 300 4739 3246
+8879 2 2 4 8 1611 3244 4738
+8880 2 2 4 8 1610 3246 4739
+8881 2 2 4 8 241 242 4998
+8882 2 2 4 8 630 3661 5236
+8883 2 2 4 8 1932 5236 3661
+8884 2 2 4 8 409 3366 4032
+8885 2 2 4 8 1514 4259 3987
+8886 2 2 4 8 611 4785 4530
+8887 2 2 4 8 2463 5014 3085
+8888 2 2 4 8 790 4198 4769
+8889 2 2 4 8 791 4199 4768
+8890 2 2 4 8 1510 4765 4480
+8891 2 2 4 8 1366 4345 3624
+8892 2 2 4 8 1880 3427 4327
+8893 2 2 4 8 764 4327 3427
+8894 2 2 4 8 1366 3415 4603
+8895 2 2 4 8 1034 4142 3178
+8896 2 2 4 8 1404 4307 3163
+8897 2 2 4 8 694 3000 5170
+8898 2 2 4 8 1152 3055 5041
+8899 2 2 4 8 240 4092 3401
+8900 2 2 4 8 830 3077 4754
+8901 2 2 4 8 787 4980 3835
+8902 2 2 4 8 1953 3835 4980
+8903 2 2 4 8 1155 5327 2942
+8904 2 2 4 8 16 5080 15
+8905 2 2 4 8 854 4865 4658
+8906 2 2 4 8 2357 4658 4865
+8907 2 2 4 8 1472 3025 4652
+8908 2 2 4 8 158 159 5087
+8909 2 2 4 8 379 380 5088
+8910 2 2 4 8 1473 2997 5125
+8911 2 2 4 8 48 5092 47
+8912 2 2 4 8 268 269 5093
+8913 2 2 4 8 81 82 5094
+8914 2 2 4 8 40 5103 39
+8915 2 2 4 8 880 5280 3368
+8916 2 2 4 8 881 5281 3367
+8917 2 2 4 8 851 4033 3268
+8918 2 2 4 8 1415 3268 4033
+8919 2 2 4 8 402 403 5366
+8920 2 2 4 8 203 204 5112
+8921 2 2 4 8 223 224 5113
+8922 2 2 4 8 616 3894 3910
+8923 2 2 4 8 1604 3910 3894
+8924 2 2 4 8 1512 5316 3041
+8925 2 2 4 8 106 3870 3692
+8926 2 2 4 8 1517 3692 3870
+8927 2 2 4 8 1664 2954 5102
+8928 2 2 4 8 893 4429 3140
+8929 2 2 4 8 892 4430 3141
+8930 2 2 4 8 891 4428 3142
+8931 2 2 4 8 152 153 5145
+8932 2 2 4 8 373 374 5146
+8933 2 2 4 8 234 235 5147
+8934 2 2 4 8 282 283 5162
+8935 2 2 4 8 260 261 5161
+8936 2 2 4 8 61 62 5163
+8937 2 2 4 8 1259 4753 2992
+8938 2 2 4 8 83 84 5190
+8939 2 2 4 8 49 50 5191
+8940 2 2 4 8 270 271 5192
+8941 2 2 4 8 1475 3388 3944
+8942 2 2 4 8 3422 1391 4536
+8943 2 2 4 8 3423 1392 4535
+8944 2 2 4 8 1393 3425 4534
+8945 2 2 4 8 1880 4327 4231
+8946 2 2 4 8 4231 4327 1637
+8947 2 2 4 8 1068 4898 4512
+8948 2 2 4 8 2300 4512 4898
+8949 2 2 4 8 1357 3935 3397
+8950 2 2 4 8 387 388 5216
+8951 2 2 4 8 144 145 5217
+8952 2 2 4 8 365 366 5218
+8953 2 2 4 8 1675 2960 5209
+8954 2 2 4 8 474 3107 5159
+8955 2 2 4 8 472 5160 3108
+8956 2 2 4 8 53 54 5253
+8957 2 2 4 8 275 5254 274
+8958 2 2 4 8 377 378 5265
+8959 2 2 4 8 156 157 5266
+8960 2 2 4 8 200 5271 199
+8961 2 2 4 8 227 228 5270
+8962 2 2 4 8 2887 3825 4712
+8963 2 2 4 8 1745 4112 4922
+8964 2 2 4 8 876 5066 4790
+8965 2 2 4 8 187 3332 4038
+8966 2 2 4 8 413 414 5308
+8967 2 2 4 8 1562 4832 4668
+8968 2 2 4 8 1953 4980 4556
+8969 2 2 4 8 2345 4556 4980
+8970 2 2 4 8 73 5361 72
+8971 2 2 4 8 375 376 5362
+8972 2 2 4 8 154 155 5363
+8973 2 2 4 8 784 3056 4422
+8974 2 2 4 8 1230 3679 4822
+8975 2 2 4 8 1789 4822 3679
+8976 2 2 4 8 511 4551 3036
+8977 2 2 4 8 427 4829 3287
+8978 2 2 4 8 1632 3287 4829
+8979 2 2 4 8 1633 3288 4830
+8980 2 2 4 8 209 4830 3288
+8981 2 2 4 8 1405 4509 3162
+8982 2 2 4 8 1406 4508 3166
+8983 2 2 4 8 1434 3608 4467
+8984 2 2 4 8 711 3475 4870
+8985 2 2 4 8 1732 5218 3316
+8986 2 2 4 8 366 3316 5218
+8987 2 2 4 8 145 3317 5217
+8988 2 2 4 8 3317 1731 5217
+8989 2 2 4 8 1730 3318 5216
+8990 2 2 4 8 387 5216 3318
+8991 2 2 4 8 1654 5239 2964
+8992 2 2 4 8 1473 3792 3647
+8993 2 2 4 8 4134 3023 4999
+8994 2 2 4 8 3024 5000 4135
+8995 2 2 4 8 1534 4385 3360
+8996 2 2 4 8 4238 5307 2321
+8997 2 2 4 8 535 5307 4238
+8998 2 2 4 8 1700 4202 3436
+8999 2 2 4 8 1273 3812 4821
+9000 2 2 4 8 1359 3038 4562
+9001 2 2 4 8 2132 4110 3448
+9002 2 2 4 8 1467 3448 4110
+9003 2 2 4 8 1470 3449 4111
+9004 2 2 4 8 2131 4111 3449
+9005 2 2 4 8 1175 3127 4285
+9006 2 2 4 8 241 4998 4092
+9007 2 2 4 8 2076 4092 4998
+9008 2 2 4 8 1809 4408 4517
+9009 2 2 4 8 812 4162 5269
+9010 2 2 4 8 1270 5166 3754
+9011 2 2 4 8 835 3203 4860
+9012 2 2 4 8 1600 3031 4642
+9013 2 2 4 8 480 4676 3028
+9014 2 2 4 8 479 4677 3027
+9015 2 2 4 8 1340 4097 5239
+9016 2 2 4 8 1404 3165 4767
+9017 2 2 4 8 1405 3164 4769
+9018 2 2 4 8 1406 3167 4768
+9019 2 2 4 8 727 3980 4030
+9020 2 2 4 8 1736 4030 3980
+9021 2 2 4 8 1158 3073 4432
+9022 2 2 4 8 1157 4433 3074
+9023 2 2 4 8 1681 3755 4151
+9024 2 2 4 8 711 4151 3755
+9025 2 2 4 8 2188 5353 3289
+9026 2 2 4 8 948 2989 5017
+9027 2 2 4 8 1114 4867 3003
+9028 2 2 4 8 1974 4860 3006
+9029 2 2 4 8 1773 4833 4080
+9030 2 2 4 8 1772 4834 4079
+9031 2 2 4 8 1607 5365 3017
+9032 2 2 4 8 1965 4763 4043
+9033 2 2 4 8 836 4043 4763
+9034 2 2 4 8 1220 3716 5144
+9035 2 2 4 8 1581 4469 3882
+9036 2 2 4 8 1496 3456 4964
+9037 2 2 4 8 1673 4000 4001
+9038 2 2 4 8 1418 4001 4000
+9039 2 2 4 8 1280 4537 3066
+9040 2 2 4 8 1573 3811 3773
+9041 2 2 4 8 712 4777 3453
+9042 2 2 4 8 801 4140 4931
+9043 2 2 4 8 799 4929 4139
+9044 2 2 4 8 798 4928 4137
+9045 2 2 4 8 800 4930 4138
+9046 2 2 4 8 1460 4070 3439
+9047 2 2 4 8 2112 3439 4070
+9048 2 2 4 8 2111 4068 3441
+9049 2 2 4 8 1464 3441 4068
+9050 2 2 4 8 2110 3440 4069
+9051 2 2 4 8 1461 4069 3440
+9052 2 2 4 8 2398 5193 2988
+9053 2 2 4 8 810 3520 4937
+9054 2 2 4 8 763 4624 3771
+9055 2 2 4 8 1244 3701 5288
+9056 2 2 4 8 836 4916 4043
+9057 2 2 4 8 1570 3431 4978
+9058 2 2 4 8 664 3853 3660
+9059 2 2 4 8 2081 3660 3853
+9060 2 2 4 8 1163 4392 3102
+9061 2 2 4 8 953 3398 5033
+9062 2 2 4 8 1705 5033 3398
+9063 2 2 4 8 1706 5034 3399
+9064 2 2 4 8 955 3399 5034
+9065 2 2 4 8 1704 3400 5032
+9066 2 2 4 8 954 5032 3400
+9067 2 2 4 8 1555 5064 3042
+9068 2 2 4 8 1075 5064 2997
+9069 2 2 4 8 4232 5194 2136
+9070 2 2 4 8 1382 4568 3884
+9071 2 2 4 8 1537 3255 4972
+9072 2 2 4 8 2208 3518 4896
+9073 2 2 4 8 1531 4477 4263
+9074 2 2 4 8 861 4352 5378
+9075 2 2 4 8 1760 3759 3954
+9076 2 2 4 8 716 3954 3759
+9077 2 2 4 8 717 3955 3758
+9078 2 2 4 8 1759 3758 3955
+9079 2 2 4 8 1109 3325 4461
+9080 2 2 4 8 4180 4492 1582
+9081 2 2 4 8 1357 4628 3753
+9082 2 2 4 8 1621 4996 3004
+9083 2 2 4 8 715 3960 3760
+9084 2 2 4 8 1758 3760 3960
+9085 2 2 4 8 555 5125 2997
+9086 2 2 4 8 593 4174 4117
+9087 2 2 4 8 2099 4117 4174
+9088 2 2 4 8 2100 4175 4118
+9089 2 2 4 8 594 4118 4175
+9090 2 2 4 8 1670 4478 3086
+9091 2 2 4 8 1561 4144 3278
+9092 2 2 4 8 1183 3056 4817
+9093 2 2 4 8 1456 3677 5037
+9094 2 2 4 8 337 3117 4386
+9095 2 2 4 8 1394 3508 5329
+9096 2 2 4 8 1395 3509 5328
+9097 2 2 4 8 1701 4076 5242
+9098 2 2 4 8 2937 5181 3537
+9099 2 2 4 8 2936 5180 3536
+9100 2 2 4 8 2939 3538 5178
+9101 2 2 4 8 2938 3539 5179
+9102 2 2 4 8 1627 4100 3852
+9103 2 2 4 8 678 3852 4100
+9104 2 2 4 8 735 3326 5151
+9105 2 2 4 8 710 3026 4831
+9106 2 2 4 8 858 5382 3209
+9107 2 2 4 8 1203 5086 3164
+9108 2 2 4 8 1205 5085 3167
+9109 2 2 4 8 860 4438 5358
+9110 2 2 4 8 3832 2942 5327
+9111 2 2 4 8 1411 3851 3852
+9112 2 2 4 8 1627 3852 3851
+9113 2 2 4 8 503 3163 4307
+9114 2 2 4 8 511 5227 4005
+9115 2 2 4 8 1457 3904 3568
+9116 2 2 4 8 898 3341 4084
+9117 2 2 4 8 4162 2158 5269
+9118 2 2 4 8 1443 4454 3096
+9119 2 2 4 8 1442 4455 3095
+9120 2 2 4 8 1444 3097 4456
+9121 2 2 4 8 1445 3098 4457
+9122 2 2 4 8 1446 3099 4458
+9123 2 2 4 8 1447 3100 4459
+9124 2 2 4 8 1493 4372 3234
+9125 2 2 4 8 542 3234 4372
+9126 2 2 4 8 1465 3243 4599
+9127 2 2 4 8 1390 4365 3802
+9128 2 2 4 8 1597 3128 5284
+9129 2 2 4 8 1477 3037 4806
+9130 2 2 4 8 795 3506 4119
+9131 2 2 4 8 2162 4983 4288
+9132 2 2 4 8 1623 4288 4983
+9133 2 2 4 8 22 3343 4091
+9134 2 2 4 8 553 4902 4064
+9135 2 2 4 8 2017 4064 4902
+9136 2 2 4 8 1116 5386 3004
+9137 2 2 4 8 1621 3004 5386
+9138 2 2 4 8 1158 4610 3073
+9139 2 2 4 8 1157 3074 4609
+9140 2 2 4 8 418 4255 3311
+9141 2 2 4 8 548 5153 3007
+9142 2 2 4 8 714 3022 4971
+9143 2 2 4 8 1360 4215 3254
+9144 2 2 4 8 1362 4214 3253
+9145 2 2 4 8 1361 3252 4213
+9146 2 2 4 8 1289 4237 3391
+9147 2 2 4 8 1436 3737 5189
+9148 2 2 4 8 1901 5189 3737
+9149 2 2 4 8 1931 3053 4701
+9150 2 2 4 8 1693 5391 2998
+9151 2 2 4 8 973 3001 5375
+9152 2 2 4 8 1609 3112 5320
+9153 2 2 4 8 1420 3773 3811
+9154 2 2 4 8 1632 3023 4943
+9155 2 2 4 8 1633 3024 4944
+9156 2 2 4 8 2117 4887 3205
+9157 2 2 4 8 1114 3003 5292
+9158 2 2 4 8 1579 5292 3003
+9159 2 2 4 8 1801 3775 4818
+9160 2 2 4 8 1360 4818 3775
+9161 2 2 4 8 1519 3415 4048
+9162 2 2 4 8 1613 5322 3114
+9163 2 2 4 8 1832 4180 3481
+9164 2 2 4 8 577 3562 4063
+9165 2 2 4 8 1808 3942 4323
+9166 2 2 4 8 901 3850 5385
+9167 2 2 4 8 2055 5385 3850
+9168 2 2 4 8 2217 5244 3008
+9169 2 2 4 8 1015 3704 5346
+9170 2 2 4 8 1570 4446 3431
+9171 2 2 4 8 619 3431 4446
+9172 2 2 4 8 4216 1796 5051
+9173 2 2 4 8 1086 5228 3010
+9174 2 2 4 8 1577 4145 3714
+9175 2 2 4 8 504 3714 4145
+9176 2 2 4 8 1578 4146 3715
+9177 2 2 4 8 505 3715 4146
+9178 2 2 4 8 1632 4999 3023
+9179 2 2 4 8 1633 5000 3024
+9180 2 2 4 8 740 4740 3058
+9181 2 2 4 8 742 4741 3059
+9182 2 2 4 8 1310 4197 3272
+9183 2 2 4 8 1311 4196 3273
+9184 2 2 4 8 161 3631 4347
+9185 2 2 4 8 1437 3738 5202
+9186 2 2 4 8 1900 5202 3738
+9187 2 2 4 8 720 5264 3060
+9188 2 2 4 8 489 5057 4670
+9189 2 2 4 8 1274 4357 3565
+9190 2 2 4 8 1326 4777 3051
+9191 2 2 4 8 2136 3257 4232
+9192 2 2 4 8 828 3389 4093
+9193 2 2 4 8 787 3700 4980
+9194 2 2 4 8 1427 3277 4376
+9195 2 2 4 8 1531 4748 4477
+9196 2 2 4 8 2134 4477 4748
+9197 2 2 4 8 1402 3676 3882
+9198 2 2 4 8 1424 4698 3218
+9199 2 2 4 8 1627 3699 4100
+9200 2 2 4 8 1327 3618 3922
+9201 2 2 4 8 1328 3923 3619
+9202 2 2 4 8 834 3075 4695
+9203 2 2 4 8 833 3076 4694
+9204 2 2 4 8 4142 2781 4329
+9205 2 2 4 8 2438 5120 4725
+9206 2 2 4 8 749 4725 5120
+9207 2 2 4 8 1742 3566 3987
+9208 2 2 4 8 1741 3567 3986
+9209 2 2 4 8 1605 3016 5376
+9210 2 2 4 8 1606 5377 3018
+9211 2 2 4 8 2370 3512 4563
+9212 2 2 4 8 1130 4563 3512
+9213 2 2 4 8 2009 4025 3906
+9214 2 2 4 8 1088 3021 5241
+9215 2 2 4 8 831 3898 5009
+9216 2 2 4 8 2592 5144 3716
+9217 2 2 4 8 1299 3943 3599
+9218 2 2 4 8 2474 3313 5330
+9219 2 2 4 8 2356 3361 4656
+9220 2 2 4 8 1258 4410 3974
+9221 2 2 4 8 1822 3974 4410
+9222 2 2 4 8 1391 3648 4536
+9223 2 2 4 8 1392 3649 4535
+9224 2 2 4 8 1393 4534 3650
+9225 2 2 4 8 1307 3866 4635
+9226 2 2 4 8 1959 4073 4783
+9227 2 2 4 8 835 4783 4073
+9228 2 2 4 8 1991 4256 4683
+9229 2 2 4 8 838 4683 4256
+9230 2 2 4 8 1163 3102 4619
+9231 2 2 4 8 2932 3610 5001
+9232 2 2 4 8 1353 4102 3416
+9233 2 2 4 8 1398 3329 4402
+9234 2 2 4 8 1614 5342 3115
+9235 2 2 4 8 1615 5343 3116
+9236 2 2 4 8 1851 4866 3179
+9237 2 2 4 8 1316 3136 4521
+9238 2 2 4 8 1317 3138 4522
+9239 2 2 4 8 4227 4752 2236
+9240 2 2 4 8 1271 3690 3989
+9241 2 2 4 8 2546 4838 3462
+9242 2 2 4 8 889 3942 4957
+9243 2 2 4 8 1931 4957 3942
+9244 2 2 4 8 1107 3030 5127
+9245 2 2 4 8 932 3986 3567
+9246 2 2 4 8 933 3987 3566
+9247 2 2 4 8 1682 3664 4624
+9248 2 2 4 8 1425 4624 3664
+9249 2 2 4 8 1375 4434 3630
+9250 2 2 4 8 720 5150 3029
+9251 2 2 4 8 1670 3086 4699
+9252 2 2 4 8 1243 5028 3120
+9253 2 2 4 8 1574 3120 5028
+9254 2 2 4 8 906 3063 4849
+9255 2 2 4 8 850 3264 4800
+9256 2 2 4 8 741 4897 3050
+9257 2 2 4 8 507 4625 3276
+9258 2 2 4 8 1361 3633 5039
+9259 2 2 4 8 1362 5038 3632
+9260 2 2 4 8 1473 5125 3088
+9261 2 2 4 8 2607 5345 4841
+9262 2 2 4 8 1836 4841 5345
+9263 2 2 4 8 1949 4479 5388
+9264 2 2 4 8 2296 4670 5057
+9265 2 2 4 8 1442 4573 3693
+9266 2 2 4 8 1443 4574 3694
+9267 2 2 4 8 1444 3695 4572
+9268 2 2 4 8 1445 3696 4571
+9269 2 2 4 8 1447 3698 4569
+9270 2 2 4 8 1446 3697 4570
+9271 2 2 4 8 2732 4612 5320
+9272 2 2 4 8 1854 3180 4646
+9273 2 2 4 8 1504 4438 4280
+9274 2 2 4 8 1889 4280 4438
+9275 2 2 4 8 1496 4558 4427
+9276 2 2 4 8 2011 4427 4558
+9277 2 2 4 8 720 3029 5264
+9278 2 2 4 8 1378 3316 4293
+9279 2 2 4 8 3317 4294 1379
+9280 2 2 4 8 1377 4295 3318
+9281 2 2 4 8 855 5166 3324
+9282 2 2 4 8 1681 3607 3982
+9283 2 2 4 8 712 4993 3051
+9284 2 2 4 8 2193 4039 3731
+9285 2 2 4 8 1251 3731 4039
+9286 2 2 4 8 826 3899 4955
+9287 2 2 4 8 2017 4955 3899
+9288 2 2 4 8 1603 3522 4914
+9289 2 2 4 8 752 3307 4273
+9290 2 2 4 8 753 4274 3308
+9291 2 2 4 8 2084 3652 4899
+9292 2 2 4 8 505 3166 4508
+9293 2 2 4 8 504 3162 4509
+9294 2 2 4 8 721 3433 4555
+9295 2 2 4 8 1225 5100 3544
+9296 2 2 4 8 1226 5101 3545
+9297 2 2 4 8 1553 4339 3250
+9298 2 2 4 8 1552 4340 3251
+9299 2 2 4 8 831 4310 4762
+9300 2 2 4 8 522 3196 4821
+9301 2 2 4 8 536 3677 4398
+9302 2 2 4 8 1242 5003 3683
+9303 2 2 4 8 1159 5065 3049
+9304 2 2 4 8 1174 4934 3402
+9305 2 2 4 8 851 3268 4635
+9306 2 2 4 8 1378 3826 4894
+9307 2 2 4 8 1828 4894 3826
+9308 2 2 4 8 443 3235 4562
+9309 2 2 4 8 828 4093 3975
+9310 2 2 4 8 1374 4347 3631
+9311 2 2 4 8 613 5172 4227
+9312 2 2 4 8 763 3985 3699
+9313 2 2 4 8 1511 3699 3985
+9314 2 2 4 8 1599 4988 3897
+9315 2 2 4 8 1598 3896 4987
+9316 2 2 4 8 1604 3894 3983
+9317 2 2 4 8 1668 4731 4251
+9318 2 2 4 8 1984 4251 4731
+9319 2 2 4 8 493 4176 4839
+9320 2 2 4 8 542 5419 3234
+9321 2 2 4 8 1702 3234 5419
+9322 2 2 4 8 1478 3489 4362
+9323 2 2 4 8 2093 3515 4530
+9324 2 2 4 8 1995 5293 4371
+9325 2 2 4 8 837 4990 3068
+9326 2 2 4 8 836 4991 3069
+9327 2 2 4 8 854 3198 4979
+9328 2 2 4 8 1580 3060 5264
+9329 2 2 4 8 1475 3944 5302
+9330 2 2 4 8 1576 3822 4059
+9331 2 2 4 8 499 4059 3822
+9332 2 2 4 8 1575 3823 4060
+9333 2 2 4 8 501 4060 3823
+9334 2 2 4 8 1379 3464 5136
+9335 2 2 4 8 1722 5136 3464
+9336 2 2 4 8 2238 5008 4511
+9337 2 2 4 8 1596 4511 5008
+9338 2 2 4 8 831 3393 4310
+9339 2 2 4 8 1421 3408 5157
+9340 2 2 4 8 1241 3220 4596
+9341 2 2 4 8 1594 3956 3985
+9342 2 2 4 8 1511 3985 3956
+9343 2 2 4 8 523 3932 3764
+9344 2 2 4 8 1156 4529 3204
+9345 2 2 4 8 746 4302 3457
+9346 2 2 4 8 1517 3457 4302
+9347 2 2 4 8 1434 4119 3506
+9348 2 2 4 8 1986 4063 3562
+9349 2 2 4 8 1665 3764 3932
+9350 2 2 4 8 929 3078 5018
+9351 2 2 4 8 850 4393 3264
+9352 2 2 4 8 834 5052 3075
+9353 2 2 4 8 830 5053 3077
+9354 2 2 4 8 1781 4862 5325
+9355 2 2 4 8 1085 5322 3050
+9356 2 2 4 8 2272 3757 5283
+9357 2 2 4 8 1636 5283 3757
+9358 2 2 4 8 537 3767 5046
+9359 2 2 4 8 1826 5046 3767
+9360 2 2 4 8 506 4376 3277
+9361 2 2 4 8 1988 4762 4310
+9362 2 2 4 8 1618 4554 4981
+9363 2 2 4 8 1620 4719 3836
+9364 2 2 4 8 1699 4108 4589
+9365 2 2 4 8 809 5149 3948
+9366 2 2 4 8 348 3630 4434
+9367 2 2 4 8 2002 3085 5014
+9368 2 2 4 8 729 3314 4363
+9369 2 2 4 8 4195 4814 1302
+9370 2 2 4 8 1083 5343 3058
+9371 2 2 4 8 1084 5342 3059
+9372 2 2 4 8 1616 3891 3890
+9373 2 2 4 8 1478 3890 3891
+9374 2 2 4 8 1204 5135 3165
+9375 2 2 4 8 797 4926 4234
+9376 2 2 4 8 1628 3490 5311
+9377 2 2 4 8 1312 4282 3400
+9378 2 2 4 8 1156 3204 4616
+9379 2 2 4 8 617 3490 4745
+9380 2 2 4 8 1628 4745 3490
+9381 2 2 4 8 457 3223 5384
+9382 2 2 4 8 1674 5384 3223
+9383 2 2 4 8 1706 4270 4046
+9384 2 2 4 8 864 4046 4270
+9385 2 2 4 8 1170 4471 3447
+9386 2 2 4 8 763 3104 4956
+9387 2 2 4 8 762 3481 4180
+9388 2 2 4 8 1631 5305 4746
+9389 2 2 4 8 2492 4746 5305
+9390 2 2 4 8 1503 3161 4789
+9391 2 2 4 8 1291 3979 3978
+9392 2 2 4 8 2622 3978 3979
+9393 2 2 4 8 1333 3598 4523
+9394 2 2 4 8 1359 4671 3197
+9395 2 2 4 8 1591 4517 4408
+9396 2 2 4 8 1186 5352 3342
+9397 2 2 4 8 1600 3521 5049
+9398 2 2 4 8 1185 3203 4691
+9399 2 2 4 8 1583 4310 3393
+9400 2 2 4 8 4793 3461 5197
+9401 2 2 4 8 1680 3294 5306
+9402 2 2 4 8 631 5306 3294
+9403 2 2 4 8 770 5250 4154
+9404 2 2 4 8 1938 3578 4974
+9405 2 2 4 8 3579 4975 1939
+9406 2 2 4 8 1218 3257 4538
+9407 2 2 4 8 1638 3844 4324
+9408 2 2 4 8 517 4324 3844
+9409 2 2 4 8 1639 4325 3845
+9410 2 2 4 8 520 3845 4325
+9411 2 2 4 8 789 4767 3165
+9412 2 2 4 8 791 4768 3167
+9413 2 2 4 8 790 4769 3164
+9414 2 2 4 8 766 4080 4423
+9415 2 2 4 8 767 4079 4424
+9416 2 2 4 8 1946 3753 4628
+9417 2 2 4 8 2117 5381 4074
+9418 2 2 4 8 901 4074 5381
+9419 2 2 4 8 751 4789 3161
+9420 2 2 4 8 522 4714 3196
+9421 2 2 4 8 583 3289 4814
+9422 2 2 4 8 1487 3335 4481
+9423 2 2 4 8 1144 4581 5369
+9424 2 2 4 8 2403 5369 4581
+9425 2 2 4 8 2081 4154 5250
+9426 2 2 4 8 1635 4857 3455
+9427 2 2 4 8 1238 3455 4857
+9428 2 2 4 8 249 4169 4749
+9429 2 2 4 8 1240 3360 4385
+9430 2 2 4 8 203 5112 3129
+9431 2 2 4 8 2066 3129 5112
+9432 2 2 4 8 224 3130 5113
+9433 2 2 4 8 2067 5113 3130
+9434 2 2 4 8 4307 1815 4346
+9435 2 2 4 8 503 4307 4346
+9436 2 2 4 8 1697 4062 4236
+9437 2 2 4 8 1553 4236 4062
+9438 2 2 4 8 810 4188 3520
+9439 2 2 4 8 913 5148 3613
+9440 2 2 4 8 1006 4065 4922
+9441 2 2 4 8 1308 3702 4045
+9442 2 2 4 8 617 4745 3706
+9443 2 2 4 8 1498 3665 4851
+9444 2 2 4 8 541 5158 3171
+9445 2 2 4 8 1592 3171 5158
+9446 2 2 4 8 1305 3761 4287
+9447 2 2 4 8 879 5195 5063
+9448 2 2 4 8 1793 4141 3616
+9449 2 2 4 8 1366 4603 4002
+9450 2 2 4 8 1305 4287 3450
+9451 2 2 4 8 1367 3931 4461
+9452 2 2 4 8 1489 3334 4607
+9453 2 2 4 8 1838 4576 4662
+9454 2 2 4 8 1837 4575 4661
+9455 2 2 4 8 713 3218 4698
+9456 2 2 4 8 1485 4747 3743
+9457 2 2 4 8 758 4598 3271
+9458 2 2 4 8 757 4786 5141
+9459 2 2 4 8 2397 5141 4786
+9460 2 2 4 8 1393 4470 5102
+9461 2 2 4 8 2330 5070 4019
+9462 2 2 4 8 1242 3137 5003
+9463 2 2 4 8 2216 5233 4358
+9464 2 2 4 8 1173 4358 5233
+9465 2 2 4 8 966 4700 3219
+9466 2 2 4 8 2273 5285 3549
+9467 2 2 4 8 516 4481 3335
+9468 2 2 4 8 1647 3575 5338
+9469 2 2 4 8 1648 5339 3577
+9470 2 2 4 8 1852 3378 4677
+9471 2 2 4 8 1853 3379 4676
+9472 2 2 4 8 1545 3667 4218
+9473 2 2 4 8 894 4218 3667
+9474 2 2 4 8 1186 3411 5352
+9475 2 2 4 8 474 5221 3107
+9476 2 2 4 8 472 3108 5222
+9477 2 2 4 8 210 3435 4830
+9478 2 2 4 8 428 3434 4829
+9479 2 2 4 8 452 5169 4917
+9480 2 2 4 8 2472 4917 5169
+9481 2 2 4 8 758 3271 4900
+9482 2 2 4 8 1673 4022 4181
+9483 2 2 4 8 763 4956 4624
+9484 2 2 4 8 2113 4250 3856
+9485 2 2 4 8 1758 4448 5412
+9486 2 2 4 8 1484 3206 4843
+9487 2 2 4 8 1426 3276 4625
+9488 2 2 4 8 1499 3983 3894
+9489 2 2 4 8 2337 5417 5078
+9490 2 2 4 8 1909 3095 5399
+9491 2 2 4 8 1908 5398 3097
+9492 2 2 4 8 1910 3096 5400
+9493 2 2 4 8 1907 5397 3098
+9494 2 2 4 8 1906 5396 3099
+9495 2 2 4 8 1905 5395 3100
+9496 2 2 4 8 718 4702 3247
+9497 2 2 4 8 538 4924 4761
+9498 2 2 4 8 2274 4761 4924
+9499 2 2 4 8 1636 3915 5139
+9500 2 2 4 8 1799 4779 3212
+9501 2 2 4 8 1798 4778 3213
+9502 2 2 4 8 1702 5420 3499
+9503 2 2 4 8 2335 5412 5062
+9504 2 2 4 8 2018 4277 4903
+9505 2 2 4 8 552 4903 4277
+9506 2 2 4 8 1154 5070 3417
+9507 2 2 4 8 2502 5018 3563
+9508 2 2 4 8 2036 4728 4493
+9509 2 2 4 8 1555 4493 4728
+9510 2 2 4 8 1203 3510 5086
+9511 2 2 4 8 1205 3511 5085
+9512 2 2 4 8 1542 3322 5123
+9513 2 2 4 8 3492 1878 4331
+9514 2 2 4 8 2441 5063 5195
+9515 2 2 4 8 1298 4904 3193
+9516 2 2 4 8 1389 4234 3801
+9517 2 2 4 8 1629 3285 5185
+9518 2 2 4 8 649 5185 3285
+9519 2 2 4 8 456 4298 5391
+9520 2 2 4 8 1250 3780 5273
+9521 2 2 4 8 1867 5273 3780
+9522 2 2 4 8 1802 3802 4365
+9523 2 2 4 8 1759 4440 5417
+9524 2 2 4 8 1305 4186 3761
+9525 2 2 4 8 2496 3661 4587
+9526 2 2 4 8 512 4607 3334
+9527 2 2 4 8 846 4788 3232
+9528 2 2 4 8 1193 3384 4513
+9529 2 2 4 8 1192 3383 4514
+9530 2 2 4 8 691 3542 4292
+9531 2 2 4 8 796 3688 4631
+9532 2 2 4 8 345 5015 3177
+9533 2 2 4 8 1584 4538 4256
+9534 2 2 4 8 782 3884 4568
+9535 2 2 4 8 1147 5225 4403
+9536 2 2 4 8 2206 4403 5225
+9537 2 2 4 8 1516 4555 3433
+9538 2 2 4 8 104 4395 3443
+9539 2 2 4 8 1547 4203 4151
+9540 2 2 4 8 1681 4151 4203
+9541 2 2 4 8 526 4603 3415
+9542 2 2 4 8 1699 4589 3824
+9543 2 2 4 8 491 3824 4589
+9544 2 2 4 8 1346 3906 4025
+9545 2 2 4 8 1155 5413 3131
+9546 2 2 4 8 719 4362 3489
+9547 2 2 4 8 1746 4244 4245
+9548 2 2 4 8 1507 4245 4244
+9549 2 2 4 8 4242 4243 1747
+9550 2 2 4 8 1508 4243 4242
+9551 2 2 4 8 449 4771 5249
+9552 2 2 4 8 1619 5201 4968
+9553 2 2 4 8 2401 5249 4771
+9554 2 2 4 8 905 3152 5247
+9555 2 2 4 8 2475 5351 3380
+9556 2 2 4 8 2164 4973 5263
+9557 2 2 4 8 2088 4322 4861
+9558 2 2 4 8 1332 4249 3626
+9559 2 2 4 8 718 3395 4702
+9560 2 2 4 8 1535 4258 4696
+9561 2 2 4 8 1632 3434 4999
+9562 2 2 4 8 1313 4999 3434
+9563 2 2 4 8 1314 5000 3435
+9564 2 2 4 8 1633 3435 5000
+9565 2 2 4 8 1324 3378 4602
+9566 2 2 4 8 904 4103 4442
+9567 2 2 4 8 795 4365 3506
+9568 2 2 4 8 1488 3582 4970
+9569 2 2 4 8 1491 3581 4969
+9570 2 2 4 8 864 3738 5393
+9571 2 2 4 8 1261 3258 4847
+9572 2 2 4 8 1972 4707 4694
+9573 2 2 4 8 1809 3941 4408
+9574 2 2 4 8 804 3422 4536
+9575 2 2 4 8 802 4534 3425
+9576 2 2 4 8 3423 4535 803
+9577 2 2 4 8 745 5220 3186
+9578 2 2 4 8 1667 4017 4940
+9579 2 2 4 8 2478 4413 4905
+9580 2 2 4 8 793 4375 5272
+9581 2 2 4 8 1151 4656 3361
+9582 2 2 4 8 1516 3349 4966
+9583 2 2 4 8 1202 4815 3278
+9584 2 2 4 8 1800 5077 3830
+9585 2 2 4 8 840 3830 5077
+9586 2 2 4 8 1537 4436 3542
+9587 2 2 4 8 1294 3542 4436
+9588 2 2 4 8 1293 3541 4437
+9589 2 2 4 8 1538 4437 3541
+9590 2 2 4 8 1510 3546 4547
+9591 2 2 4 8 774 5084 3371
+9592 2 2 4 8 1621 3620 4996
+9593 2 2 4 8 531 4825 3351
+9594 2 2 4 8 1559 3351 4825
+9595 2 2 4 8 532 4826 3352
+9596 2 2 4 8 1560 3352 4826
+9597 2 2 4 8 1388 4268 4631
+9598 2 2 4 8 2063 4631 4268
+9599 2 2 4 8 2566 5407 4962
+9600 2 2 4 8 1181 4962 5407
+9601 2 2 4 8 797 4234 3687
+9602 2 2 4 8 1711 3779 4801
+9603 2 2 4 8 793 4801 3779
+9604 2 2 4 8 841 4628 3397
+9605 2 2 4 8 1567 3348 5235
+9606 2 2 4 8 1536 3310 5287
+9607 2 2 4 8 1533 4374 4399
+9608 2 2 4 8 1832 4399 4374
+9609 2 2 4 8 1912 3525 4388
+9610 2 2 4 8 1483 5262 3505
+9611 2 2 4 8 744 5226 3194
+9612 2 2 4 8 1372 4298 3636
+9613 2 2 4 8 1423 3774 4170
+9614 2 2 4 8 1490 3583 4415
+9615 2 2 4 8 1184 4697 3468
+9616 2 2 4 8 1891 3468 4697
+9617 2 2 4 8 1384 3857 4140
+9618 2 2 4 8 1385 4137 3859
+9619 2 2 4 8 1387 4138 3860
+9620 2 2 4 8 1386 4139 3858
+9621 2 2 4 8 613 3383 4679
+9622 2 2 4 8 606 3384 4680
+9623 2 2 4 8 1802 4365 4855
+9624 2 2 4 8 1465 4552 3454
+9625 2 2 4 8 1973 4695 3516
+9626 2 2 4 8 1972 4694 3517
+9627 2 2 4 8 592 4686 4750
+9628 2 2 4 8 2075 4750 4686
+9629 2 2 4 8 796 4388 3688
+9630 2 2 4 8 1262 3199 5276
+9631 2 2 4 8 1336 4937 3520
+9632 2 2 4 8 1513 5312 3606
+9633 2 2 4 8 1776 3742 4235
+9634 2 2 4 8 760 3882 4469
+9635 2 2 4 8 1528 4833 3965
+9636 2 2 4 8 1529 4834 3966
+9637 2 2 4 8 1345 3681 4326
+9638 2 2 4 8 445 4772 3416
+9639 2 2 4 8 1556 3416 4772
+9640 2 2 4 8 1344 3710 4643
+9641 2 2 4 8 1720 5323 3498
+9642 2 2 4 8 541 3498 5323
+9643 2 2 4 8 1189 3365 5244
+9644 2 2 4 8 1479 3354 5337
+9645 2 2 4 8 1481 5336 3355
+9646 2 2 4 8 1480 5335 3356
+9647 2 2 4 8 2586 3353 5011
+9648 2 2 4 8 2259 4488 3968
+9649 2 2 4 8 1285 3968 4488
+9650 2 2 4 8 1713 4693 3938
+9651 2 2 4 8 1918 3938 4693
+9652 2 2 4 8 253 4813 3347
+9653 2 2 4 8 1185 4691 3429
+9654 2 2 4 8 415 5324 3202
+9655 2 2 4 8 2008 5041 3265
+9656 2 2 4 8 1757 5117 3729
+9657 2 2 4 8 1354 3729 5117
+9658 2 2 4 8 1137 3756 4623
+9659 2 2 4 8 1671 5378 3200
+9660 2 2 4 8 1338 3623 5243
+9661 2 2 4 8 1775 4568 3488
+9662 2 2 4 8 1552 4075 4589
+9663 2 2 4 8 1659 5196 3451
+9664 2 2 4 8 1233 3451 5196
+9665 2 2 4 8 2379 5301 3584
+9666 2 2 4 8 1325 3379 4766
+9667 2 2 4 8 1557 5153 3528
+9668 2 2 4 8 782 4359 3884
+9669 2 2 4 8 194 4483 4906
+9670 2 2 4 8 1757 3259 5117
+9671 2 2 4 8 543 5122 3601
+9672 2 2 4 8 738 4239 4095
+9673 2 2 4 8 1729 4095 4239
+9674 2 2 4 8 2665 5071 3407
+9675 2 2 4 8 1941 3407 5071
+9676 2 2 4 8 725 4914 3522
+9677 2 2 4 8 1552 3251 5154
+9678 2 2 4 8 1528 3965 4945
+9679 2 2 4 8 1529 3966 4946
+9680 2 2 4 8 1973 4782 4695
+9681 2 2 4 8 1183 4817 3469
+9682 2 2 4 8 1513 3642 4888
+9683 2 2 4 8 1539 5108 3269
+9684 2 2 4 8 1540 5109 3270
+9685 2 2 4 8 575 3769 4306
+9686 2 2 4 8 1398 3569 5277
+9687 2 2 4 8 1720 5277 3569
+9688 2 2 4 8 481 3713 4447
+9689 2 2 4 8 1584 4447 3713
+9690 2 2 4 8 2087 5387 3770
+9691 2 2 4 8 2035 4949 4396
+9692 2 2 4 8 811 4396 4949
+9693 2 2 4 8 1534 4277 4385
+9694 2 2 4 8 1500 5237 3239
+9695 2 2 4 8 797 3687 4331
+9696 2 2 4 8 1458 3418 4932
+9697 2 2 4 8 1459 3419 4925
+9698 2 2 4 8 1536 5287 3397
+9699 2 2 4 8 578 5062 5412
+9700 2 2 4 8 587 5078 5417
+9701 2 2 4 8 4240 2619 4982
+9702 2 2 4 8 620 4240 4982
+9703 2 2 4 8 1795 3836 5147
+9704 2 2 4 8 234 5147 3836
+9705 2 2 4 8 847 3275 5121
+9706 2 2 4 8 1616 3596 4742
+9707 2 2 4 8 1254 4742 3596
+9708 2 2 4 8 1290 4547 3546
+9709 2 2 4 8 2286 4979 3328
+9710 2 2 4 8 1869 4078 4194
+9711 2 2 4 8 566 3279 5367
+9712 2 2 4 8 1877 4502 5318
+9713 2 2 4 8 801 4646 3482
+9714 2 2 4 8 1289 3758 5128
+9715 2 2 4 8 1759 5128 3758
+9716 2 2 4 8 1760 5129 3759
+9717 2 2 4 8 1295 3759 5129
+9718 2 2 4 8 1291 3760 5124
+9719 2 2 4 8 1758 5124 3760
+9720 2 2 4 8 1319 4428 4027
+9721 2 2 4 8 1321 4429 4028
+9722 2 2 4 8 1320 4430 4029
+9723 2 2 4 8 589 4681 3469
+9724 2 2 4 8 833 4694 4707
+9725 2 2 4 8 1250 5273 4150
+9726 2 2 4 8 1583 3712 4482
+9727 2 2 4 8 470 4482 3712
+9728 2 2 4 8 1860 4908 4125
+9729 2 2 4 8 826 4125 4908
+9730 2 2 4 8 1859 4907 4126
+9731 2 2 4 8 827 4126 4907
+9732 2 2 4 8 1372 4301 3772
+9733 2 2 4 8 1780 4893 5321
+9734 2 2 4 8 566 5367 3291
+9735 2 2 4 8 1678 5382 3228
+9736 2 2 4 8 2274 5242 5304
+9737 2 2 4 8 1545 3333 5006
+9738 2 2 4 8 1544 4306 3769
+9739 2 2 4 8 1649 4662 4576
+9740 2 2 4 8 1646 4661 4575
+9741 2 2 4 8 525 4966 3349
+9742 2 2 4 8 513 3856 4250
+9743 2 2 4 8 612 4732 4981
+9744 2 2 4 8 2178 4981 4732
+9745 2 2 4 8 2090 3412 4835
+9746 2 2 4 8 2091 3413 4836
+9747 2 2 4 8 2092 3414 4837
+9748 2 2 4 8 1041 4148 4804
+9749 2 2 4 8 1040 4149 4805
+9750 2 2 4 8 2916 4316 4476
+9751 2 2 4 8 802 3425 4807
+9752 2 2 4 8 1278 5210 3281
+9753 2 2 4 8 1582 4492 3727
+9754 2 2 4 8 705 3727 4492
+9755 2 2 4 8 1512 3666 5316
+9756 2 2 4 8 1719 4713 5413
+9757 2 2 4 8 1569 4487 3689
+9758 2 2 4 8 571 3689 4487
+9759 2 2 4 8 1456 4398 3677
+9760 2 2 4 8 2001 5011 3353
+9761 2 2 4 8 1708 4725 5039
+9762 2 2 4 8 1709 5038 4726
+9763 2 2 4 8 1784 3947 4939
+9764 2 2 4 8 328 4939 3947
+9765 2 2 4 8 1520 4472 4473
+9766 2 2 4 8 1955 4473 4472
+9767 2 2 4 8 1521 4474 4475
+9768 2 2 4 8 1956 4475 4474
+9769 2 2 4 8 702 4470 3650
+9770 2 2 4 8 509 3628 4515
+9771 2 2 4 8 514 3629 4516
+9772 2 2 4 8 489 3419 5057
+9773 2 2 4 8 1838 4014 4576
+9774 2 2 4 8 1837 4013 4575
+9775 2 2 4 8 1632 4829 3434
+9776 2 2 4 8 1633 4830 3435
+9777 2 2 4 8 1944 4754 3470
+9778 2 2 4 8 877 4704 3558
+9779 2 2 4 8 1564 3558 4704
+9780 2 2 4 8 878 4703 3559
+9781 2 2 4 8 1563 3559 4703
+9782 2 2 4 8 1186 3342 5132
+9783 2 2 4 8 1556 3461 4793
+9784 2 2 4 8 1219 5054 3393
+9785 2 2 4 8 1583 3393 5054
+9786 2 2 4 8 2232 4547 3962
+9787 2 2 4 8 1290 3962 4547
+9788 2 2 4 8 1568 4586 4047
+9789 2 2 4 8 1710 4520 4098
+9790 2 2 4 8 231 4098 4520
+9791 2 2 4 8 507 3276 5383
+9792 2 2 4 8 1532 4181 4022
+9793 2 2 4 8 1566 5367 3279
+9794 2 2 4 8 1495 4859 3444
+9795 2 2 4 8 1588 3341 5177
+9796 2 2 4 8 1755 5013 3389
+9797 2 2 4 8 1204 3547 5135
+9798 2 2 4 8 341 5107 3565
+9799 2 2 4 8 1720 4786 5277
+9800 2 2 4 8 2261 3867 5091
+9801 2 2 4 8 1814 5091 3867
+9802 2 2 4 8 2260 3868 5090
+9803 2 2 4 8 1813 5090 3868
+9804 2 2 4 8 4170 2143 5184
+9805 2 2 4 8 1621 3662 5058
+9806 2 2 4 8 2033 3469 4817
+9807 2 2 4 8 507 5096 4625
+9808 2 2 4 8 783 3670 5302
+9809 2 2 4 8 2080 5302 3670
+9810 2 2 4 8 2050 3324 5268
+9811 2 2 4 8 1184 3369 5193
+9812 2 2 4 8 1477 4806 3507
+9813 2 2 4 8 1801 4818 3972
+9814 2 2 4 8 1471 5115 3385
+9815 2 2 4 8 2478 3928 5243
+9816 2 2 4 8 1997 5330 3313
+9817 2 2 4 8 2115 4320 4756
+9818 2 2 4 8 2114 4321 4755
+9819 2 2 4 8 723 5049 3521
+9820 2 2 4 8 834 4695 4782
+9821 2 2 4 8 630 4587 3661
+9822 2 2 4 8 1556 5279 3461
+9823 2 2 4 8 743 4343 4094
+9824 2 2 4 8 1728 4094 4343
+9825 2 2 4 8 765 4096 5111
+9826 2 2 4 8 1871 5111 4096
+9827 2 2 4 8 733 4194 4078
+9828 2 2 4 8 1832 4374 4492
+9829 2 2 4 8 705 4492 4374
+9830 2 2 4 8 1485 3417 5070
+9831 2 2 4 8 1958 4910 3585
+9832 2 2 4 8 2295 3585 4910
+9833 2 2 4 8 1179 5263 4973
+9834 2 2 4 8 796 5004 4388
+9835 2 2 4 8 1292 4964 3456
+9836 2 2 4 8 780 4569 3698
+9837 2 2 4 8 778 4571 3696
+9838 2 2 4 8 779 4570 3697
+9839 2 2 4 8 777 4572 3695
+9840 2 2 4 8 776 3694 4574
+9841 2 2 4 8 775 3693 4573
+9842 2 2 4 8 1458 4932 3573
+9843 2 2 4 8 1459 4925 3574
+9844 2 2 4 8 896 5293 5317
+9845 2 2 4 8 724 4601 3678
+9846 2 2 4 8 1672 5358 3337
+9847 2 2 4 8 4192 2381 5295
+9848 2 2 4 8 564 4557 3806
+9849 2 2 4 8 1719 5413 4824
+9850 2 2 4 8 1557 3392 5197
+9851 2 2 4 8 1055 5157 3408
+9852 2 2 4 8 2258 5327 4667
+9853 2 2 4 8 1155 4667 5327
+9854 2 2 4 8 722 3674 4615
+9855 2 2 4 8 1313 4134 4999
+9856 2 2 4 8 1314 4135 5000
+9857 2 2 4 8 889 4323 3942
+9858 2 2 4 8 1115 4427 4561
+9859 2 2 4 8 2011 4561 4427
+9860 2 2 4 8 2320 5055 5054
+9861 2 2 4 8 1583 5054 5055
+9862 2 2 4 8 2215 3683 4908
+9863 2 2 4 8 2214 3684 4907
+9864 2 2 4 8 1143 5010 3459
+9865 2 2 4 8 4223 1450 4647
+9866 2 2 4 8 4224 1451 4648
+9867 2 2 4 8 4205 4668 2116
+9868 2 2 4 8 1618 4981 4852
+9869 2 2 4 8 2178 4852 4981
+9870 2 2 4 8 1286 4994 3476
+9871 2 2 4 8 1571 3571 4938
+9872 2 2 4 8 879 5063 3557
+9873 2 2 4 8 2093 4785 3878
+9874 2 2 4 8 2090 3879 4784
+9875 2 2 4 8 1698 4896 3518
+9876 2 2 4 8 1609 4612 3784
+9877 2 2 4 8 735 3784 4612
+9878 2 2 4 8 1338 5243 3928
+9879 2 2 4 8 727 4626 3705
+9880 2 2 4 8 1551 3921 5240
+9881 2 2 4 8 243 3505 5262
+9882 2 2 4 8 841 3397 5287
+9883 2 2 4 8 1289 3391 5301
+9884 2 2 4 8 2147 3473 5030
+9885 2 2 4 8 2146 3474 5031
+9886 2 2 4 8 1011 3914 4744
+9887 2 2 4 8 1912 4744 3914
+9888 2 2 4 8 795 4855 4365
+9889 2 2 4 8 2143 3380 5351
+9890 2 2 4 8 746 3924 4550
+9891 2 2 4 8 1583 5055 3712
+9892 2 2 4 8 1584 3713 5056
+9893 2 2 4 8 2274 5304 4052
+9894 2 2 4 8 1807 5275 5164
+9895 2 2 4 8 752 4273 4987
+9896 2 2 4 8 753 4988 4274
+9897 2 2 4 8 2130 5276 4453
+9898 2 2 4 8 3572 5168 1570
+9899 2 2 4 8 800 3570 4866
+9900 2 2 4 8 1565 3806 4557
+9901 2 2 4 8 1222 3404 5325
+9902 2 2 4 8 1949 3871 4479
+9903 2 2 4 8 478 4799 4105
+9904 2 2 4 8 2043 4105 4799
+9905 2 2 4 8 1828 4015 4894
+9906 2 2 4 8 881 5415 5281
+9907 2 2 4 8 880 5414 5280
+9908 2 2 4 8 1243 3500 5028
+9909 2 2 4 8 1344 4675 3710
+9910 2 2 4 8 1741 5172 4679
+9911 2 2 4 8 817 3653 4852
+9912 2 2 4 8 1618 4852 3653
+9913 2 2 4 8 89 5171 4379
+9914 2 2 4 8 1635 5278 3762
+9915 2 2 4 8 1233 5196 3453
+9916 2 2 4 8 4233 4394 1177
+9917 2 2 4 8 4233 1950 4394
+9918 2 2 4 8 1789 5352 3411
+9919 2 2 4 8 726 4408 3941
+9920 2 2 4 8 1421 5157 4348
+9921 2 2 4 8 758 4900 3773
+9922 2 2 4 8 1425 3771 4624
+9923 2 2 4 8 9 5208 3460
+9924 2 2 4 8 761 4938 3571
+9925 2 2 4 8 488 3418 5387
+9926 2 2 4 8 2071 5085 3511
+9927 2 2 4 8 2070 5086 3510
+9928 2 2 4 8 1912 4388 5004
+9929 2 2 4 8 1002 3663 4792
+9930 2 2 4 8 1661 4795 5143
+9931 2 2 4 8 2190 5143 4795
+9932 2 2 4 8 921 5304 5242
+9933 2 2 4 8 1969 4461 3931
+9934 2 2 4 8 509 4969 3581
+9935 2 2 4 8 514 4970 3582
+9936 2 2 4 8 1895 4600 4705
+9937 2 2 4 8 1626 4705 4600
+9938 2 2 4 8 1680 4792 3663
+9939 2 2 4 8 821 3654 4889
+9940 2 2 4 8 1619 4889 3654
+9941 2 2 4 8 1279 4257 4377
+9942 2 2 4 8 1848 4377 4257
+9943 2 2 4 8 596 5390 4253
+9944 2 2 4 8 2317 4253 5390
+9945 2 2 4 8 1635 3762 4858
+9946 2 2 4 8 551 4858 3762
+9947 2 2 4 8 1071 3461 5279
+9948 2 2 4 8 1711 4801 4799
+9949 2 2 4 8 2043 4799 4801
+9950 2 2 4 8 1358 4142 4329
+9951 2 2 4 8 781 4525 3904
+9952 2 2 4 8 1336 3992 4937
+9953 2 2 4 8 734 4620 4131
+9954 2 2 4 8 1562 3557 5063
+9955 2 2 4 8 2380 3898 5309
+9956 2 2 4 8 1963 5309 3898
+9957 2 2 4 8 2254 4800 3685
+9958 2 2 4 8 1339 4888 3642
+9959 2 2 4 8 2128 3544 5100
+9960 2 2 4 8 2127 3545 5101
+9961 2 2 4 8 1674 5252 3646
+9962 2 2 4 8 1306 3646 5252
+9963 2 2 4 8 2242 4491 4790
+9964 2 2 4 8 701 4577 3895
+9965 2 2 4 8 1586 4550 3924
+9966 2 2 4 8 2054 3820 4994
+9967 2 2 4 8 2535 4027 4428
+9968 2 2 4 8 2537 4028 4429
+9969 2 2 4 8 2536 4029 4430
+9970 2 2 4 8 1930 5001 3610
+9971 2 2 4 8 2237 4635 3866
+9972 2 2 4 8 2094 5135 3547
+9973 2 2 4 8 1142 4757 3744
+9974 2 2 4 8 1141 3745 4758
+9975 2 2 4 8 1740 3565 5107
+9976 2 2 4 8 2060 3895 4788
+9977 2 2 4 8 2374 5246 3874
+9978 2 2 4 8 1943 3874 5246
+9979 2 2 4 8 2373 3873 5245
+9980 2 2 4 8 1942 5245 3873
+9981 2 2 4 8 776 3536 5180
+9982 2 2 4 8 775 3537 5181
+9983 2 2 4 8 779 5178 3538
+9984 2 2 4 8 780 5179 3539
+9985 2 2 4 8 2402 3613 5194
+9986 2 2 4 8 993 3810 4760
+9987 2 2 4 8 1624 4760 3810
+9988 2 2 4 8 1528 4423 4080
+9989 2 2 4 8 1529 4424 4079
+9990 2 2 4 8 1154 4019 5070
+9991 2 2 4 8 858 4664 5392
+9992 2 2 4 8 1043 4812 3967
+9993 2 2 4 8 547 4342 4810
+9994 2 2 4 8 1828 4810 4342
+9995 2 2 4 8 2507 3793 4935
+9996 2 2 4 8 1775 4935 3793
+9997 2 2 4 8 1776 4936 3794
+9998 2 2 4 8 2508 3794 4936
+9999 2 2 4 8 2322 4465 4889
+10000 2 2 4 8 821 4889 4465
+10001 2 2 4 8 216 3818 4721
+10002 2 2 4 8 434 3817 4722
+10003 2 2 4 8 527 5305 3504
+10004 2 2 4 8 1631 3504 5305
+10005 2 2 4 8 1482 4712 3825
+10006 2 2 4 8 762 5168 3572
+10007 2 2 4 8 1621 5058 3620
+10008 2 2 4 8 827 4907 3684
+10009 2 2 4 8 826 4908 3683
+10010 2 2 4 8 1027 5058 3662
+10011 2 2 4 8 2852 3652 5077
+10012 2 2 4 8 1501 3601 5122
+10013 2 2 4 8 2162 4288 4986
+10014 2 2 4 8 1742 4259 4680
+10015 2 2 4 8 606 4680 4259
+10016 2 2 4 8 785 5328 3509
+10017 2 2 4 8 786 5329 3508
+10018 2 2 4 8 1666 3734 5134
+10019 2 2 4 8 848 5134 3734
+10020 2 2 4 8 2084 5299 4555
+10021 2 2 4 8 721 4555 5299
+10022 2 2 4 8 1833 4442 4103
+10023 2 2 4 8 765 4164 4627
+10024 2 2 4 8 1929 4625 5096
+10025 2 2 4 8 921 5242 4076
+10026 2 2 4 8 732 4575 4013
+10027 2 2 4 8 737 4576 4014
+10028 2 2 4 8 1109 3549 5285
+10029 2 2 4 8 1322 3556 5275
+10030 2 2 4 8 1870 4058 4727
+10031 2 2 4 8 961 4727 4058
+10032 2 2 4 8 1602 5219 3747
+10033 2 2 4 8 2197 4002 4603
+10034 2 2 4 8 1656 4955 4902
+10035 2 2 4 8 1657 4954 4903
+10036 2 2 4 8 1990 4123 4991
+10037 2 2 4 8 1989 4122 4990
+10038 2 2 4 8 733 4716 3877
+10039 2 2 4 8 1669 5067 4811
+10040 2 2 4 8 2102 4811 5067
+10041 2 2 4 8 28 4787 3814
+10042 2 2 4 8 1482 4285 4712
+10043 2 2 4 8 840 5077 3652
+10044 2 2 4 8 1256 5408 3663
+10045 2 2 4 8 1360 3805 4818
+10046 2 2 4 8 1513 4370 5312
+10047 2 2 4 8 817 4852 4672
+10048 2 2 4 8 2178 4672 4852
+10049 2 2 4 8 2035 4759 4949
+10050 2 2 4 8 1660 4949 4759
+10051 2 2 4 8 2500 4821 3812
+10052 2 2 4 8 2136 5194 3613
+10053 2 2 4 8 523 3764 4892
+10054 2 2 4 8 1518 5037 3677
+10055 2 2 4 8 2018 4385 4277
+10056 2 2 4 8 739 4047 4586
+10057 2 2 4 8 2178 4732 4020
+10058 2 2 4 8 1991 4447 4256
+10059 2 2 4 8 1584 4256 4447
+10060 2 2 4 8 2206 3557 5357
+10061 2 2 4 8 2205 3558 5355
+10062 2 2 4 8 2207 3559 5356
+10063 2 2 4 8 1060 4678 5106
+10064 2 2 4 8 2044 5106 4678
+10065 2 2 4 8 2017 4596 4064
+10066 2 2 4 8 1604 3734 4985
+10067 2 2 4 8 491 4589 4075
+10068 2 2 4 8 1573 3773 4900
+10069 2 2 4 8 1178 3709 5022
+10070 2 2 4 8 1498 5243 3623
+10071 2 2 4 8 1435 3976 4685
+10072 2 2 4 8 1436 5189 4087
+10073 2 2 4 8 1741 3986 5172
+10074 2 2 4 8 1552 5154 4075
+10075 2 2 4 8 1680 3663 5408
+10076 2 2 4 8 601 3606 5312
+10077 2 2 4 8 4150 5273 2571
+10078 2 2 4 8 504 4509 4950
+10079 2 2 4 8 1901 4950 4509
+10080 2 2 4 8 505 4508 4951
+10081 2 2 4 8 1900 4951 4508
+10082 2 2 4 8 537 5268 3767
+10083 2 2 4 8 1988 4310 4482
+10084 2 2 4 8 2158 4583 5269
+10085 2 2 4 8 1788 5269 4583
+10086 2 2 4 8 2032 4421 4498
+10087 2 2 4 8 956 5354 3642
+10088 2 2 4 8 1985 4608 5073
+10089 2 2 4 8 1787 5073 4608
+10090 2 2 4 8 1515 5172 3986
+10091 2 2 4 8 837 4684 4990
+10092 2 2 4 8 1989 4990 4684
+10093 2 2 4 8 1843 4131 4620
+10094 2 2 4 8 1378 4894 3861
+10095 2 2 4 8 2017 4902 4955
+10096 2 2 4 8 2018 4903 4954
+10097 2 2 4 8 4172 1354 5117
+10098 2 2 4 8 1583 4482 4310
+10099 2 2 4 8 2016 4901 4823
+10100 2 2 4 8 1655 4823 4901
+10101 2 2 4 8 1408 4476 4316
+10102 2 2 4 8 738 3839 4927
+10103 2 2 4 8 2200 3876 5389
+10104 2 2 4 8 1437 5393 3738
+10105 2 2 4 8 2016 4857 4858
+10106 2 2 4 8 1635 4858 4857
+10107 2 2 4 8 1502 5298 4103
+10108 2 2 4 8 1833 4103 5298
+10109 2 2 4 8 950 3782 5313
+10110 2 2 4 8 1900 3724 5202
+10111 2 2 4 8 1756 5019 3958
+10112 2 2 4 8 760 3958 5019
+10113 2 2 4 8 882 4622 5416
+10114 2 2 4 8 2171 5416 4622
+10115 2 2 4 8 1901 3725 5189
+10116 2 2 4 8 4164 2034 4627
+10117 2 2 4 8 1362 3804 5038
+10118 2 2 4 8 1361 5039 3803
+10119 2 2 4 8 830 4754 4809
+10120 2 2 4 8 1944 4809 4754
+10121 2 2 4 8 743 3828 4992
+10122 2 2 4 8 4225 4815 1695
+10123 2 2 4 8 1879 3967 4812
+10124 2 2 4 8 2342 3754 5166
+10125 2 2 4 8 493 4839 4160
+10126 2 2 4 8 1717 4160 4839
+10127 2 2 4 8 1833 5298 3671
+10128 2 2 4 8 2016 4858 4901
+10129 2 2 4 8 551 4901 4858
+10130 2 2 4 8 1134 4477 4468
+10131 2 2 4 8 2134 4468 4477
+10132 2 2 4 8 849 5316 3666
+10133 2 2 4 8 4105 2280 5164
+10134 2 2 4 8 835 4860 4783
+10135 2 2 4 8 1974 4783 4860
+10136 2 2 4 8 2286 5176 3957
+10137 2 2 4 8 462 3965 4833
+10138 2 2 4 8 463 3966 4834
+10139 2 2 4 8 1858 4124 5416
+10140 2 2 4 8 882 5416 4124
+10141 2 2 4 8 726 3747 5219
+10142 2 2 4 8 518 3846 5110
+10143 2 2 4 8 411 4751 4251
+10144 2 2 4 8 2043 5272 5234
+10145 2 2 4 8 1550 4498 4421
+10146 2 2 4 8 4225 4878 2283
+10147 2 2 4 8 4225 1695 4878
+10148 2 2 4 8 1080 4504 4493
+10149 2 2 4 8 2036 4493 4504
+10150 2 2 4 8 732 4086 4824
+10151 2 2 4 8 1098 4668 4205
+10152 2 2 4 8 765 5283 4096
+10153 2 2 4 8 2164 4687 4973
+10154 2 2 4 8 1690 4958 4856
+10155 2 2 4 8 1531 5346 3704
+10156 2 2 4 8 760 5019 3882
+10157 2 2 4 8 223 5113 4883
+10158 2 2 4 8 2067 4883 5113
+10159 2 2 4 8 2066 5112 4882
+10160 2 2 4 8 204 4882 5112
+10161 2 2 4 8 2198 5229 5045
+10162 2 2 4 8 1725 5045 5229
+10163 2 2 4 8 1640 5110 3846
+10164 2 2 4 8 2006 4856 4958
+10165 2 2 4 8 1990 4991 4763
+10166 2 2 4 8 836 4763 4991
+10167 2 2 4 8 2417 5321 4309
+10168 2 2 4 8 744 3781 5226
+10169 2 2 4 8 1034 5349 5282
+10170 2 2 4 8 2382 5282 5349
+10171 2 2 4 8 745 3783 5220
+10172 2 2 4 8 1656 4125 4955
+10173 2 2 4 8 1657 4126 4954
+10174 2 2 4 8 1975 4663 4664
+10175 2 2 4 8 1625 4664 4663
+10176 2 2 4 8 1275 5211 3809
+10177 2 2 4 8 1379 5136 3862
+10178 2 2 4 8 752 5137 3863
+10179 2 2 4 8 1666 5134 5105
+10180 2 2 4 8 2167 5105 5134
+10181 2 2 4 8 2065 4937 3992
+10182 2 2 4 8 4169 1530 4749
+10183 2 2 4 8 1719 4824 4086
+10184 2 2 4 8 985 4873 4418
+10185 2 2 4 8 1852 4418 4873
+10186 2 2 4 8 987 4874 4419
+10187 2 2 4 8 1853 4420 4875
+10188 2 2 4 8 984 4417 4872
+10189 2 2 4 8 1854 4872 4417
+10190 2 2 4 8 986 4875 4420
+10191 2 2 4 8 1851 4419 4874
+10192 2 2 4 8 1755 4590 4660
+10193 2 2 4 8 1559 4804 4148
+10194 2 2 4 8 1560 4805 4149
+10195 2 2 4 8 1502 4439 5298
+10196 2 2 4 8 1977 4607 5198
+10197 2 2 4 8 512 5198 4607
+10198 2 2 4 8 4227 1515 4752
+10199 2 2 4 8 2007 4683 4850
+10200 2 2 4 8 838 4850 4683
+10201 2 2 4 8 1668 4251 4751
+10202 2 2 4 8 837 4856 4684
+10203 2 2 4 8 2006 4684 4856
+10204 2 2 4 8 4193 5299 1830
+10205 2 2 4 8 721 5299 4193
+10206 2 2 4 8 456 5391 3809
+10207 2 2 4 8 1693 3809 5391
+10208 2 2 4 8 4166 1690 4856
+10209 2 2 4 8 1509 4922 4065
+10210 2 2 4 8 1767 5133 4567
+10211 2 2 4 8 2173 4567 5133
+10212 2 2 4 8 4707 1998 4840
+10213 2 2 4 8 833 4707 4840
+10214 2 2 4 8 4195 2137 4814
+10215 2 2 4 8 837 4166 4856
+10216 2 2 4 8 458 5310 4204
+10217 2 2 4 8 1635 3869 5278
+10218 2 2 4 8 469 4524 5248
+10219 2 2 4 8 1948 5248 4524
+10220 2 2 4 8 3832 5327 2258
+10221 2 2 4 8 1682 4624 4956
+10222 2 2 4 8 1895 4853 4855
+10223 2 2 4 8 1745 4922 4246
+10224 2 2 4 8 1509 4246 4922
+10225 2 2 4 8 1097 4756 4320
+10226 2 2 4 8 1096 4755 4321
+10227 2 2 4 8 826 4955 4125
+10228 2 2 4 8 827 4954 4126
+10229 2 2 4 8 1112 3900 5267
+10230 2 2 4 8 1675 5209 3959
+10231 2 2 4 8 1878 5364 4331
+10232 2 2 4 8 1793 4822 4764
+10233 2 2 4 8 4098 2670 4995
+10234 2 2 4 8 1710 4098 4995
+10235 2 2 4 8 326 5240 3921
+10236 2 2 4 8 2566 5312 4370
+10237 2 2 4 8 1549 4965 4152
+10238 2 2 4 8 1854 4646 4931
+10239 2 2 4 8 801 4931 4646
+10240 2 2 4 8 1127 4659 4632
+10241 2 2 4 8 1766 4632 4659
+10242 2 2 4 8 1738 4660 4590
+10243 2 2 4 8 1035 5315 5418
+10244 2 2 4 8 2363 5418 5315
+10245 2 2 4 8 1402 3959 5209
+10246 2 2 4 8 1802 4855 4853
+10247 2 2 4 8 4238 2321 5247
+10248 2 2 4 8 797 4331 5364
+10249 2 2 4 8 2296 5057 4066
+10250 2 2 4 8 1756 5289 5019
+10251 2 2 4 8 1256 5410 5408
+10252 2 2 4 8 2454 5408 5410
+10253 2 2 4 8 2064 5068 4780
+10254 2 2 4 8 2083 5230 4312
+10255 2 2 4 8 871 5374 4674
+10256 2 2 4 8 2024 4674 5374
+10257 2 2 4 8 1870 4727 4926
+10258 2 2 4 8 1805 4926 4727
+10259 2 2 4 8 2292 4005 5227
+10260 2 2 4 8 1572 4861 4322
+10261 2 2 4 8 783 5302 3944
+10262 2 2 4 8 1402 5289 3959
+10263 2 2 4 8 1827 4744 5004
+10264 2 2 4 8 1912 5004 4744
+10265 2 2 4 8 1131 5296 4284
+10266 2 2 4 8 1830 5299 4899
+10267 2 2 4 8 2084 4899 5299
+10268 2 2 4 8 2591 3926 5354
+10269 2 2 4 8 1774 5392 3916
+10270 2 2 4 8 1793 4715 4822
+10271 2 2 4 8 1597 5284 3999
+10272 2 2 4 8 2074 5401 4920
+10273 2 2 4 8 1398 5277 4006
+10274 2 2 4 8 1738 5076 4660
+10275 2 2 4 8 2339 4718 4703
+10276 2 2 4 8 2338 4717 4704
+10277 2 2 4 8 1561 4790 4491
+10278 2 2 4 8 928 5021 4808
+10279 2 2 4 8 1945 4808 5021
+10280 2 2 4 8 2576 4792 5306
+10281 2 2 4 8 478 4105 5164
+10282 2 2 4 8 1664 5102 4470
+10283 2 2 4 8 1598 4987 4273
+10284 2 2 4 8 1599 4274 4988
+10285 2 2 4 8 1564 4704 4717
+10286 2 2 4 8 1563 4703 4718
+10287 2 2 4 8 2256 4881 5182
+10288 2 2 4 8 1789 4764 4822
+10289 2 2 4 8 1943 5246 4654
+10290 2 2 4 8 556 4654 5246
+10291 2 2 4 8 554 5245 4655
+10292 2 2 4 8 1942 4655 5245
+10293 2 2 4 8 1829 5234 5272
+10294 2 2 4 8 1895 4855 4600
+10295 2 2 4 8 2262 5173 4890
+10296 2 2 4 8 1706 4046 5291
+10297 2 2 4 8 860 5350 4438
+10298 2 2 4 8 1889 4438 5350
+10299 2 2 4 8 1538 4905 4413
+10300 2 2 4 8 1636 4096 5283
+10301 2 2 4 8 1630 4053 5313
+10302 2 2 4 8 1726 4559 5333
+10303 2 2 4 8 1727 5334 4560
+10304 2 2 4 8 2300 4879 5097
+10305 2 2 4 8 1738 4590 5238
+10306 2 2 4 8 2274 4924 5242
+10307 2 2 4 8 795 4600 4855
+10308 2 2 4 8 1593 4906 4483
+10309 2 2 4 8 1737 4617 5317
+10310 2 2 4 8 1656 5281 4125
+10311 2 2 4 8 1657 5280 4126
+10312 2 2 4 8 449 4759 4771
+10313 2 2 4 8 2742 4870 4816
+10314 2 2 4 8 2035 4771 4759
+10315 2 2 4 8 4227 5172 1515
+10316 2 2 4 8 2043 4801 5272
+10317 2 2 4 8 2840 5279 4772
+10318 2 2 4 8 1471 4315 5115
+10319 2 2 4 8 2001 5082 5011
+10320 2 2 4 8 1044 5011 5082
+10321 2 2 4 8 1230 4822 4715
+10322 2 2 4 8 1043 5083 5014
+10323 2 2 4 8 2002 5014 5083
+10324 2 2 4 8 1654 4892 5239
+10325 2 2 4 8 2021 5115 4315
+10326 2 2 4 8 2841 4348 5157
+10327 2 2 4 8 2278 4918 5148
+10328 2 2 4 8 725 4303 5188
+10329 2 2 4 8 723 4304 5187
+10330 2 2 4 8 2418 5331 5032
+10331 2 2 4 8 2419 5033 5332
+10332 2 2 4 8 2684 5050 4914
+10333 2 2 4 8 2685 4915 5049
+10334 2 2 4 8 4192 5295 1121
+10335 2 2 4 8 4206 5392 1774
+10336 2 2 4 8 858 5392 4206
+10337 2 2 4 8 4204 5310 2040
+10338 2 2 4 8 1437 4391 5393
+10339 2 2 4 8 899 4312 5230
+10340 2 2 4 8 800 4866 4930
+10341 2 2 4 8 1851 4930 4866
+10342 2 2 4 8 1551 4816 4870
+10343 2 2 4 8 1556 4772 5279
+10344 2 2 4 8 2143 5351 5184
+10345 2 2 4 8 628 5184 5351
+10346 2 2 4 8 1622 4379 5171
+10347 2 2 4 8 1634 4973 4687
+10348 2 2 4 8 1844 4872 4931
+10349 2 2 4 8 1854 4931 4872
+10350 2 2 4 8 1846 4929 4875
+10351 2 2 4 8 1845 4928 4873
+10352 2 2 4 8 1852 4873 4928
+10353 2 2 4 8 1847 4930 4874
+10354 2 2 4 8 1853 4875 4929
+10355 2 2 4 8 1851 4874 4930
+10356 2 2 4 8 1437 5202 4363
+10357 2 2 4 8 15 5080 4583
+10358 2 2 4 8 1788 4583 5080
+10359 2 2 4 8 2390 4962 5035
+10360 2 2 4 8 1181 5035 4962
+10361 2 2 4 8 2391 4963 5036
+10362 2 2 4 8 1180 5036 4963
+10363 2 2 4 8 1797 4284 5296
+10364 2 2 4 8 1726 5333 4911
+10365 2 2 4 8 1727 4912 5334
+10366 2 2 4 8 402 5366 4567
+10367 2 2 4 8 1602 4913 5219
+10368 2 2 4 8 2518 5420 5419
+10369 2 2 4 8 1702 5419 5420
+10370 2 2 4 8 1200 4309 5321
+10371 2 2 4 8 841 4660 5076
+10372 2 2 4 8 2335 5124 5412
+10373 2 2 4 8 1678 4371 5293
+10374 2 2 4 8 2337 5128 5417
+10375 2 2 4 8 2394 5274 5075
+10376 2 2 4 8 1700 4780 5068
+10377 2 2 4 8 828 5238 4590
+10378 2 2 4 8 708 4793 5197
+10379 2 2 4 8 2387 5393 4391
+10380 2 2 4 8 1762 5318 4502
+10381 2 2 4 8 1600 5049 4915
+10382 2 2 4 8 1603 4914 5050
+10383 2 2 4 8 1663 5097 4879
+10384 2 2 4 8 638 5333 4559
+10385 2 2 4 8 637 4560 5334
+10386 2 2 4 8 2337 5078 5060
+10387 2 2 4 8 2336 5079 5061
+10388 2 2 4 8 882 5359 4622
+10389 2 2 4 8 1842 4622 5359
+10390 2 2 4 8 896 5317 4617
+10391 2 2 4 8 1767 4567 5366
+10392 2 2 4 8 1609 5320 4612
+10393 2 2 4 8 2472 5169 5294
+10394 2 2 4 8 1683 5060 5078
+10395 2 2 4 8 1688 5061 5079
+10396 2 2 4 8 1689 5182 4881
+10397 2 2 4 8 1686 4890 5173
+10398 2 2 4 8 1691 5148 4918
+10399 2 2 4 8 1979 5385 5167
+10400 2 2 4 8 2055 5167 5385
+10401 2 2 4 8 2440 5325 4862
+10402 2 2 4 8 644 5186 5405
+10403 2 2 4 8 2061 5405 5186
+10404 2 2 4 8 2683 5219 4913
+10405 2 2 4 8 793 5272 4801
+10406 2 2 4 8 2176 5334 4912
+10407 2 2 4 8 2177 4911 5333
+10408 2 2 4 8 2135 5360 5359
+10409 2 2 4 8 1842 5359 5360
+10410 2 2 4 8 1680 5306 4792
+10411 2 2 4 8 1701 5242 4924
+10412 2 2 4 8 1707 5075 5274
+10413 2 2 4 8 1792 4920 5401
+10414 2 2 4 8 1704 5032 5331
+10415 2 2 4 8 1705 5332 5033
+10416 2 2 4 8 1712 5294 5169
+10417 2 2 4 8 2117 5380 5381
+10418 2 2 4 8 1896 5381 5380
+10419 2 2 4 8 1758 5412 5124
+10420 2 2 4 8 1759 5417 5128
+$EndElements
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_mesh_prestress_reinforcement.msh b/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_mesh_prestress_reinforcement.msh
new file mode 100644
index 000000000..5dd1487ce
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/embedded_mesh_prestress_reinforcement.msh
@@ -0,0 +1,414 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$PhysicalNames
+1
+1 1 "reinforcement"
+$EndPhysicalNames
+$Nodes
+201
+1 10 0.25 0
+2 0 0.25 0
+3 0.04999999999996232 0.25 0
+4 0.09999999999992584 0.25 0
+5 0.1499999999998909 0.25 0
+6 0.199999999999856 0.25 0
+7 0.249999999999819 0.25 0
+8 0.2999999999997771 0.25 0
+9 0.3499999999997248 0.25 0
+10 0.3999999999996677 0.25 0
+11 0.4499999999996051 0.25 0
+12 0.4999999999995511 0.25 0
+13 0.5499999999995031 0.25 0
+14 0.5999999999994683 0.25 0
+15 0.6499999999994334 0.25 0
+16 0.6999999999993983 0.25 0
+17 0.7499999999993634 0.25 0
+18 0.7999999999993286 0.25 0
+19 0.8499999999992935 0.25 0
+20 0.8999999999992587 0.25 0
+21 0.9499999999992237 0.25 0
+22 0.9999999999991888 0.25 0
+23 1.049999999999154 0.25 0
+24 1.099999999999119 0.25 0
+25 1.149999999999084 0.25 0
+26 1.199999999999033 0.25 0
+27 1.24999999999897 0.25 0
+28 1.299999999998852 0.25 0
+29 1.349999999998722 0.25 0
+30 1.399999999998576 0.25 0
+31 1.44999999999843 0.25 0
+32 1.499999999998284 0.25 0
+33 1.549999999998138 0.25 0
+34 1.599999999997992 0.25 0
+35 1.649999999997846 0.25 0
+36 1.6999999999977 0.25 0
+37 1.749999999997554 0.25 0
+38 1.799999999997408 0.25 0
+39 1.849999999997263 0.25 0
+40 1.899999999997116 0.25 0
+41 1.949999999996971 0.25 0
+42 1.999999999996825 0.25 0
+43 2.049999999996679 0.25 0
+44 2.099999999996533 0.25 0
+45 2.149999999996387 0.25 0
+46 2.199999999996241 0.25 0
+47 2.249999999996095 0.25 0
+48 2.299999999995949 0.25 0
+49 2.349999999995803 0.25 0
+50 2.399999999995657 0.25 0
+51 2.449999999995511 0.25 0
+52 2.499999999995365 0.25 0
+53 2.54999999999522 0.25 0
+54 2.599999999995073 0.25 0
+55 2.649999999994928 0.25 0
+56 2.699999999994782 0.25 0
+57 2.749999999994635 0.25 0
+58 2.79999999999449 0.25 0
+59 2.849999999994344 0.25 0
+60 2.899999999994198 0.25 0
+61 2.949999999994052 0.25 0
+62 2.999999999993906 0.25 0
+63 3.04999999999376 0.25 0
+64 3.099999999993614 0.25 0
+65 3.149999999993468 0.25 0
+66 3.199999999993322 0.25 0
+67 3.249999999993176 0.25 0
+68 3.299999999993029 0.25 0
+69 3.349999999992884 0.25 0
+70 3.399999999992738 0.25 0
+71 3.449999999992592 0.25 0
+72 3.499999999992446 0.25 0
+73 3.5499999999923 0.25 0
+74 3.599999999992154 0.25 0
+75 3.649999999992009 0.25 0
+76 3.699999999991863 0.25 0
+77 3.749999999991717 0.25 0
+78 3.799999999991571 0.25 0
+79 3.849999999991425 0.25 0
+80 3.899999999991278 0.25 0
+81 3.949999999991132 0.25 0
+82 3.999999999991022 0.25 0
+83 4.049999999990987 0.25 0
+84 4.099999999991035 0.25 0
+85 4.149999999991111 0.25 0
+86 4.199999999991187 0.25 0
+87 4.249999999991263 0.25 0
+88 4.299999999991338 0.25 0
+89 4.349999999991415 0.25 0
+90 4.399999999991491 0.25 0
+91 4.449999999991566 0.25 0
+92 4.499999999991642 0.25 0
+93 4.549999999991719 0.25 0
+94 4.599999999991795 0.25 0
+95 4.649999999991871 0.25 0
+96 4.699999999991947 0.25 0
+97 4.749999999992022 0.25 0
+98 4.799999999992099 0.25 0
+99 4.849999999992175 0.25 0
+100 4.89999999999225 0.25 0
+101 4.949999999992326 0.25 0
+102 4.999999999992403 0.25 0
+103 5.049999999992478 0.25 0
+104 5.099999999992555 0.25 0
+105 5.14999999999263 0.25 0
+106 5.199999999992706 0.25 0
+107 5.249999999992783 0.25 0
+108 5.299999999992858 0.25 0
+109 5.349999999992933 0.25 0
+110 5.39999999999301 0.25 0
+111 5.449999999993086 0.25 0
+112 5.499999999993161 0.25 0
+113 5.549999999993238 0.25 0
+114 5.599999999993313 0.25 0
+115 5.649999999993391 0.25 0
+116 5.699999999993466 0.25 0
+117 5.749999999993543 0.25 0
+118 5.799999999993618 0.25 0
+119 5.849999999993694 0.25 0
+120 5.899999999993771 0.25 0
+121 5.949999999993846 0.25 0
+122 5.999999999993922 0.25 0
+123 6.049999999993998 0.25 0
+124 6.099999999994074 0.25 0
+125 6.14999999999415 0.25 0
+126 6.199999999994227 0.25 0
+127 6.249999999994302 0.25 0
+128 6.299999999994378 0.25 0
+129 6.349999999994455 0.25 0
+130 6.39999999999453 0.25 0
+131 6.449999999994606 0.25 0
+132 6.499999999994682 0.25 0
+133 6.549999999994759 0.25 0
+134 6.599999999994833 0.25 0
+135 6.64999999999491 0.25 0
+136 6.699999999994986 0.25 0
+137 6.749999999995062 0.25 0
+138 6.799999999995138 0.25 0
+139 6.849999999995214 0.25 0
+140 6.899999999995289 0.25 0
+141 6.949999999995366 0.25 0
+142 6.999999999995442 0.25 0
+143 7.049999999995517 0.25 0
+144 7.099999999995594 0.25 0
+145 7.14999999999567 0.25 0
+146 7.199999999995747 0.25 0
+147 7.249999999995821 0.25 0
+148 7.299999999995897 0.25 0
+149 7.349999999995973 0.25 0
+150 7.39999999999605 0.25 0
+151 7.449999999996125 0.25 0
+152 7.499999999996202 0.25 0
+153 7.549999999996278 0.25 0
+154 7.599999999996353 0.25 0
+155 7.64999999999643 0.25 0
+156 7.699999999996505 0.25 0
+157 7.749999999996582 0.25 0
+158 7.799999999996658 0.25 0
+159 7.849999999996734 0.25 0
+160 7.899999999996808 0.25 0
+161 7.949999999996885 0.25 0
+162 7.999999999996962 0.25 0
+163 8.049999999997038 0.25 0
+164 8.099999999997113 0.25 0
+165 8.14999999999719 0.25 0
+166 8.199999999997265 0.25 0
+167 8.249999999997341 0.25 0
+168 8.299999999997418 0.25 0
+169 8.349999999997493 0.25 0
+170 8.399999999997569 0.25 0
+171 8.449999999997646 0.25 0
+172 8.499999999997721 0.25 0
+173 8.549999999997798 0.25 0
+174 8.599999999997873 0.25 0
+175 8.649999999997949 0.25 0
+176 8.699999999998024 0.25 0
+177 8.749999999998101 0.25 0
+178 8.799999999998176 0.25 0
+179 8.849999999998253 0.25 0
+180 8.899999999998329 0.25 0
+181 8.949999999998404 0.25 0
+182 8.999999999998479 0.25 0
+183 9.049999999998557 0.25 0
+184 9.099999999998634 0.25 0
+185 9.149999999998709 0.25 0
+186 9.199999999998786 0.25 0
+187 9.24999999999886 0.25 0
+188 9.299999999998937 0.25 0
+189 9.349999999999012 0.25 0
+190 9.399999999999089 0.25 0
+191 9.449999999999164 0.25 0
+192 9.499999999999241 0.25 0
+193 9.549999999999315 0.25 0
+194 9.599999999999392 0.25 0
+195 9.649999999999469 0.25 0
+196 9.699999999999545 0.25 0
+197 9.749999999999622 0.25 0
+198 9.799999999999697 0.25 0
+199 9.849999999999774 0.25 0
+200 9.899999999999848 0.25 0
+201 9.949999999999925 0.25 0
+$EndNodes
+$Elements
+200
+1 1 2 1 6 2 3
+2 1 2 1 6 3 4
+3 1 2 1 6 4 5
+4 1 2 1 6 5 6
+5 1 2 1 6 6 7
+6 1 2 1 6 7 8
+7 1 2 1 6 8 9
+8 1 2 1 6 9 10
+9 1 2 1 6 10 11
+10 1 2 1 6 11 12
+11 1 2 1 6 12 13
+12 1 2 1 6 13 14
+13 1 2 1 6 14 15
+14 1 2 1 6 15 16
+15 1 2 1 6 16 17
+16 1 2 1 6 17 18
+17 1 2 1 6 18 19
+18 1 2 1 6 19 20
+19 1 2 1 6 20 21
+20 1 2 1 6 21 22
+21 1 2 1 6 22 23
+22 1 2 1 6 23 24
+23 1 2 1 6 24 25
+24 1 2 1 6 25 26
+25 1 2 1 6 26 27
+26 1 2 1 6 27 28
+27 1 2 1 6 28 29
+28 1 2 1 6 29 30
+29 1 2 1 6 30 31
+30 1 2 1 6 31 32
+31 1 2 1 6 32 33
+32 1 2 1 6 33 34
+33 1 2 1 6 34 35
+34 1 2 1 6 35 36
+35 1 2 1 6 36 37
+36 1 2 1 6 37 38
+37 1 2 1 6 38 39
+38 1 2 1 6 39 40
+39 1 2 1 6 40 41
+40 1 2 1 6 41 42
+41 1 2 1 6 42 43
+42 1 2 1 6 43 44
+43 1 2 1 6 44 45
+44 1 2 1 6 45 46
+45 1 2 1 6 46 47
+46 1 2 1 6 47 48
+47 1 2 1 6 48 49
+48 1 2 1 6 49 50
+49 1 2 1 6 50 51
+50 1 2 1 6 51 52
+51 1 2 1 6 52 53
+52 1 2 1 6 53 54
+53 1 2 1 6 54 55
+54 1 2 1 6 55 56
+55 1 2 1 6 56 57
+56 1 2 1 6 57 58
+57 1 2 1 6 58 59
+58 1 2 1 6 59 60
+59 1 2 1 6 60 61
+60 1 2 1 6 61 62
+61 1 2 1 6 62 63
+62 1 2 1 6 63 64
+63 1 2 1 6 64 65
+64 1 2 1 6 65 66
+65 1 2 1 6 66 67
+66 1 2 1 6 67 68
+67 1 2 1 6 68 69
+68 1 2 1 6 69 70
+69 1 2 1 6 70 71
+70 1 2 1 6 71 72
+71 1 2 1 6 72 73
+72 1 2 1 6 73 74
+73 1 2 1 6 74 75
+74 1 2 1 6 75 76
+75 1 2 1 6 76 77
+76 1 2 1 6 77 78
+77 1 2 1 6 78 79
+78 1 2 1 6 79 80
+79 1 2 1 6 80 81
+80 1 2 1 6 81 82
+81 1 2 1 6 82 83
+82 1 2 1 6 83 84
+83 1 2 1 6 84 85
+84 1 2 1 6 85 86
+85 1 2 1 6 86 87
+86 1 2 1 6 87 88
+87 1 2 1 6 88 89
+88 1 2 1 6 89 90
+89 1 2 1 6 90 91
+90 1 2 1 6 91 92
+91 1 2 1 6 92 93
+92 1 2 1 6 93 94
+93 1 2 1 6 94 95
+94 1 2 1 6 95 96
+95 1 2 1 6 96 97
+96 1 2 1 6 97 98
+97 1 2 1 6 98 99
+98 1 2 1 6 99 100
+99 1 2 1 6 100 101
+100 1 2 1 6 101 102
+101 1 2 1 6 102 103
+102 1 2 1 6 103 104
+103 1 2 1 6 104 105
+104 1 2 1 6 105 106
+105 1 2 1 6 106 107
+106 1 2 1 6 107 108
+107 1 2 1 6 108 109
+108 1 2 1 6 109 110
+109 1 2 1 6 110 111
+110 1 2 1 6 111 112
+111 1 2 1 6 112 113
+112 1 2 1 6 113 114
+113 1 2 1 6 114 115
+114 1 2 1 6 115 116
+115 1 2 1 6 116 117
+116 1 2 1 6 117 118
+117 1 2 1 6 118 119
+118 1 2 1 6 119 120
+119 1 2 1 6 120 121
+120 1 2 1 6 121 122
+121 1 2 1 6 122 123
+122 1 2 1 6 123 124
+123 1 2 1 6 124 125
+124 1 2 1 6 125 126
+125 1 2 1 6 126 127
+126 1 2 1 6 127 128
+127 1 2 1 6 128 129
+128 1 2 1 6 129 130
+129 1 2 1 6 130 131
+130 1 2 1 6 131 132
+131 1 2 1 6 132 133
+132 1 2 1 6 133 134
+133 1 2 1 6 134 135
+134 1 2 1 6 135 136
+135 1 2 1 6 136 137
+136 1 2 1 6 137 138
+137 1 2 1 6 138 139
+138 1 2 1 6 139 140
+139 1 2 1 6 140 141
+140 1 2 1 6 141 142
+141 1 2 1 6 142 143
+142 1 2 1 6 143 144
+143 1 2 1 6 144 145
+144 1 2 1 6 145 146
+145 1 2 1 6 146 147
+146 1 2 1 6 147 148
+147 1 2 1 6 148 149
+148 1 2 1 6 149 150
+149 1 2 1 6 150 151
+150 1 2 1 6 151 152
+151 1 2 1 6 152 153
+152 1 2 1 6 153 154
+153 1 2 1 6 154 155
+154 1 2 1 6 155 156
+155 1 2 1 6 156 157
+156 1 2 1 6 157 158
+157 1 2 1 6 158 159
+158 1 2 1 6 159 160
+159 1 2 1 6 160 161
+160 1 2 1 6 161 162
+161 1 2 1 6 162 163
+162 1 2 1 6 163 164
+163 1 2 1 6 164 165
+164 1 2 1 6 165 166
+165 1 2 1 6 166 167
+166 1 2 1 6 167 168
+167 1 2 1 6 168 169
+168 1 2 1 6 169 170
+169 1 2 1 6 170 171
+170 1 2 1 6 171 172
+171 1 2 1 6 172 173
+172 1 2 1 6 173 174
+173 1 2 1 6 174 175
+174 1 2 1 6 175 176
+175 1 2 1 6 176 177
+176 1 2 1 6 177 178
+177 1 2 1 6 178 179
+178 1 2 1 6 179 180
+179 1 2 1 6 180 181
+180 1 2 1 6 181 182
+181 1 2 1 6 182 183
+182 1 2 1 6 183 184
+183 1 2 1 6 184 185
+184 1 2 1 6 185 186
+185 1 2 1 6 186 187
+186 1 2 1 6 187 188
+187 1 2 1 6 188 189
+188 1 2 1 6 189 190
+189 1 2 1 6 190 191
+190 1 2 1 6 191 192
+191 1 2 1 6 192 193
+192 1 2 1 6 193 194
+193 1 2 1 6 194 195
+194 1 2 1 6 195 196
+195 1 2 1 6 196 197
+196 1 2 1 6 197 198
+197 1 2 1 6 198 199
+198 1 2 1 6 199 200
+199 1 2 1 6 200 201
+200 1 2 1 6 201 1
+$EndElements
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/material.dat b/test/test_model/test_solid_mechanics_model/test_embedded_interface/material.dat
new file mode 100644
index 000000000..23e677b42
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/material.dat
@@ -0,0 +1,13 @@
+material reinforcement elastic [
+ name = reinforcement
+ E = 210e9
+ area = 0.1
+]
+
+material elastic [
+ name = concrete
+ rho = 2500 # density
+ E = 30e9 # young's modulus
+ nu = 0.0 # poisson's ratio
+ Plane_Stress = true
+]
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/matrix b/test/test_model/test_solid_mechanics_model/test_embedded_interface/matrix
new file mode 100644
index 000000000..8688d2a9c
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/matrix
@@ -0,0 +1,93 @@
+%%MatrixMarket matrix coordinate real symmetric
+18 18 91
+1 1 22500000000
+1 2 0
+1 3 -15000000000
+1 4 0
+1 9 0
+1 10 -7500000000
+2 2 22500000000
+2 3 7500000000
+2 4 -7500000000
+2 9 -7500000000
+2 10 0
+3 3 45000000000
+3 4 -7500000000
+3 9 -15000000000
+3 10 7500000000
+4 4 45000000000
+4 9 7500000000
+4 10 -30000000000
+9 9 174000000000
+9 10 -15000000000
+10 10 90000000000
+3 5 -15000000000
+3 6 0
+3 11 0
+3 12 -7500000000
+4 5 7500000000
+4 6 -7500000000
+4 11 -7500000000
+4 12 0
+5 5 22500000000
+5 6 -7500000000
+5 11 -7500000000
+5 12 0
+6 6 22500000000
+6 11 7500000000
+6 12 -15000000000
+11 11 87000000000
+11 12 -7500000000
+12 12 45000000000
+1 7 -7500000000
+1 8 7500000000
+2 7 0
+2 8 -15000000000
+9 7 -72000000000
+9 8 7500000000
+10 7 7500000000
+10 8 -15000000000
+7 7 87000000000
+7 8 -7500000000
+8 8 45000000000
+11 9 -72000000000
+11 10 7500000000
+12 9 7500000000
+12 10 -15000000000
+7 15 0
+7 16 -7500000000
+8 15 -7500000000
+8 16 0
+9 15 -15000000000
+9 16 7500000000
+10 15 7500000000
+10 16 -30000000000
+15 15 45000000000
+15 16 -7500000000
+16 16 45000000000
+9 17 0
+9 18 -7500000000
+10 17 -7500000000
+10 18 0
+11 17 -7500000000
+11 18 0
+12 17 7500000000
+12 18 -15000000000
+17 17 22500000000
+17 18 0
+18 18 22500000000
+7 13 -7500000000
+7 14 7500000000
+8 13 0
+8 14 -15000000000
+15 13 -15000000000
+15 14 0
+16 13 7500000000
+16 14 -7500000000
+13 13 22500000000
+13 14 -7500000000
+14 14 22500000000
+17 15 -15000000000
+17 16 0
+18 15 7500000000
+18 16 -7500000000
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/prestress.dat b/test/test_model/test_solid_mechanics_model/test_embedded_interface/prestress.dat
new file mode 100644
index 000000000..55f8b64d2
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/prestress.dat
@@ -0,0 +1,14 @@
+material reinforcement elastic [
+ name = reinforcement
+ E = 210e9
+ area = 1e-2
+ pre_stress = 1e6
+]
+
+material elastic [
+ name = concrete
+ rho = 2500 # density
+ E = 30e9 # young's modulus
+ nu = 0.0 # poisson's ratio
+ Plane_Stress = true
+]
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
new file mode 100644
index 000000000..a292d29b2
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_element_matrix.cc
@@ -0,0 +1,89 @@
+/**
+ * @file test_embedded_interface_model.cc
+ *
+ * @author Lucas Frérot <lucas.frerot@epfl.ch>
+ *
+ * @date Thu 19 Mar 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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
new file mode 100644
index 000000000..befd92f17
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.cc
@@ -0,0 +1,105 @@
+/**
+ * @file test_embedded_interface_model.cc
+ *
+ * @author Lucas Frerot <lucas.frerot@epfl.ch>
+ *
+ * @date lun. 09 29 16:03:10 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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.sh b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.sh
new file mode 100755
index 000000000..e9cc69c6b
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+./test_embedded_interface_model && diff matrix matrix_test >/dev/null 2>&1
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
new file mode 100644
index 000000000..f9eb3e1e2
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
@@ -0,0 +1,225 @@
+/**
+ * @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
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "aka_common.hh"
+#include "embedded_interface_model.hh"
+
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+
+#define YG 0.483644859
+#define I_eq 0.012488874
+#define A_eq (1e-2 + 1. / 7. * 1.)
+
+/* -------------------------------------------------------------------------- */
+
+struct StressSolution : public BC::Neumann::FromHigherDim {
+ Real M;
+ Real I;
+ Real yg;
+ Real pre_stress;
+
+ StressSolution(UInt dim, Real M, Real I, Real yg = 0, Real pre_stress = 0) :
+ BC::Neumann::FromHigherDim(Matrix<Real>(dim, dim)),
+ M(M), I(I), yg(yg), pre_stress(pre_stress)
+ {}
+
+ virtual ~StressSolution() {}
+
+ void operator()(const IntegrationPoint & quad_point,
+ Vector<Real> & dual,
+ const Vector<Real> & coord,
+ const Vector<Real> & normals) const {
+ UInt dim = coord.size();
+
+ if (dim < 2) AKANTU_DEBUG_ERROR("Solution not valid for 1D");
+
+ Matrix<Real> stress(dim, dim); stress.clear();
+ stress(0, 0) = this->stress(coord(1));
+ dual.mul<false>(stress, normals);
+ }
+
+ inline Real stress(Real height) const {
+ return -M / I * (height - yg) + pre_stress;
+ }
+
+ inline Real neutral_axis() const {
+ return -I * pre_stress / M + yg;
+ }
+};
+
+/* -------------------------------------------------------------------------- */
+
+int main (int argc, char * argv[]) {
+ initialize("prestress.dat", argc, argv);
+ debug::setDebugLevel(dblError);
+
+ Math::setTolerance(1e-6);
+
+ const UInt dim = 2;
+
+/* -------------------------------------------------------------------------- */
+
+ Mesh mesh(dim);
+ mesh.read("embedded_mesh_prestress.msh");
+ mesh.createGroupsFromMeshData<std::string>("physical_names");
+
+ Mesh reinforcement_mesh(dim, "reinforcement_mesh");
+ try {
+ reinforcement_mesh.read("embedded_mesh_prestress_reinforcement.msh");
+ } catch(debug::Exception & e) {}
+
+ reinforcement_mesh.createGroupsFromMeshData<std::string>("physical_names");
+
+ EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
+ model.initFull(EmbeddedInterfaceModelOptions(_static));
+
+/* -------------------------------------------------------------------------- */
+/* Computation of analytical residual */
+/* -------------------------------------------------------------------------- */
+
+ /*
+ * q = 1000 N/m
+ * L = 20 m
+ * a = 1 m
+ */
+
+ Real steel_area = model.getMaterial("reinforcement").getParam<Real>("area");
+ Real pre_stress = 1e6;
+ Real stress_norm = 0.;
+
+ StressSolution * concrete_stress = NULL, * steel_stress = NULL;
+
+ Real pre_force = pre_stress * steel_area;
+ Real pre_moment = -pre_force * (YG - 0.25);
+ Real neutral_axis = YG - I_eq / A_eq * pre_force / pre_moment;
+
+ concrete_stress = new StressSolution(dim, pre_moment, 7. * I_eq, YG, -pre_force / (7. * A_eq));
+ steel_stress = new StressSolution(dim, pre_moment, I_eq, YG, pre_stress - pre_force / A_eq);
+
+ stress_norm = std::abs(concrete_stress->stress(1)) * (1 - neutral_axis) * 0.5
+ + std::abs(concrete_stress->stress(0)) * neutral_axis * 0.5
+ + std::abs(steel_stress->stress(0.25)) * steel_area;
+
+ model.applyBC(*concrete_stress, "XBlocked");
+ ElementGroup & end_node = mesh.getElementGroup("EndNode");
+ NodeGroup & end_node_group = end_node.getNodeGroup();
+ NodeGroup::const_node_iterator end_node_it = end_node_group.begin();
+
+ Vector<Real> end_node_force = model.getForce().begin(dim)[*end_node_it];
+ end_node_force(0) += steel_stress->stress(0.25) * steel_area;
+
+ Array<Real> analytical_residual(mesh.getNbNodes(), dim, "analytical_residual");
+ analytical_residual.copy(model.getForce());
+ model.getForce().clear();
+
+ delete concrete_stress;
+ delete steel_stress;
+
+/* -------------------------------------------------------------------------- */
+
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "XBlocked");
+ model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "YBlocked");
+
+ // Assemble the global stiffness matrix
+ model.assembleStiffnessMatrix();
+
+ model.updateResidual();
+
+ if (!model.solveStatic<_scm_newton_raphson_tangent_not_computed, _scc_residual>(1e-6, 1))
+ return EXIT_FAILURE;
+
+ model.updateResidual();
+
+/* -------------------------------------------------------------------------- */
+/* Computation of FEM residual norm */
+/* -------------------------------------------------------------------------- */
+
+ ElementGroup & xblocked = mesh.getElementGroup("XBlocked");
+ NodeGroup & boundary_nodes = xblocked.getNodeGroup();
+ NodeGroup::const_node_iterator
+ nodes_it = boundary_nodes.begin(),
+ nodes_end = boundary_nodes.end();
+ Array<Real>::vector_iterator com_res = model.getResidual().begin(dim);
+ Array<Real>::vector_iterator ana_res = analytical_residual.begin(dim);
+ Array<Real>::vector_iterator position = mesh.getNodes().begin(dim);
+
+ Real res_sum = 0.;
+ UInt lower_node = -1;
+ UInt upper_node = -1;
+ Real lower_dist = 1;
+ Real upper_dist = 1;
+
+ for (; nodes_it != nodes_end ; ++nodes_it) {
+ UInt node_number = *nodes_it;
+ const Vector<Real> res = com_res[node_number];
+ const Vector<Real> ana = ana_res[node_number];
+ const Vector<Real> pos = position[node_number];
+
+ if (!Math::are_float_equal(pos(1), 0.25)) {
+ if ((std::abs(pos(1) - 0.25) < lower_dist) && (pos(1) < 0.25)) {
+ lower_dist = std::abs(pos(1) - 0.25);
+ lower_node = node_number;
+ }
+
+ if ((std::abs(pos(1) - 0.25) < upper_dist) && (pos(1) > 0.25)) {
+ upper_dist = std::abs(pos(1) - 0.25);
+ upper_node = node_number;
+ }
+ }
+
+ for (UInt i = 0 ; i < dim ; i++) {
+ if (!Math::are_float_equal(pos(1), 0.25)) {
+ res_sum += std::abs(res(i));
+ }
+ }
+ }
+
+ const Vector<Real> upper_res = com_res[upper_node], lower_res = com_res[lower_node];
+ const Vector<Real> end_node_res = com_res[*end_node_it];
+ Vector<Real> delta = upper_res - lower_res;
+ delta *= lower_dist / (upper_dist + lower_dist);
+ Vector<Real> concrete_residual = lower_res + delta;
+ Vector<Real> steel_residual = end_node_res - concrete_residual;
+
+ for (UInt i = 0 ; i < dim ; i++) {
+ res_sum += std::abs(concrete_residual(i));
+ res_sum += std::abs(steel_residual(i));
+ }
+
+ Real relative_error = std::abs(res_sum - stress_norm) / stress_norm;
+
+ if (relative_error > 1e-3)
+ return EXIT_FAILURE;
+
+ finalize();
+ return 0;
+}
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/triangle.msh b/test/test_model/test_solid_mechanics_model/test_embedded_interface/triangle.msh
new file mode 100644
index 000000000..94ac34b28
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/triangle.msh
@@ -0,0 +1,17 @@
+$MeshFormat
+2.2 0 8
+$EndMeshFormat
+$PhysicalNames
+1
+2 1 "null"
+$EndPhysicalNames
+$Nodes
+3
+1 0 0 0
+2 1 0 0
+3 0 1 0
+$EndNodes
+$Elements
+1
+2 2 2 1 6 1 2 3
+$EndElements
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
new file mode 100644
index 000000000..c082e2ef7
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_material_selector.cc
@@ -0,0 +1,64 @@
+/**
+ * @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
+ *
+ * @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 "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 8cb966363..cabf83ffb 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,63 +1,81 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Fri Nov 26 2010
# @date last modification: Fri Feb 14 2014
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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 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
- DIRECTORIES_TO_CREATE paraview)
-#===============================================================================
+ DEPENDS test_interpolate_stress_mesh
+ DIRECTORIES_TO_CREATE paraview
+ PACKAGE lapack core
+ )
-add_akantu_test(test_material_plasticity "test material plasticity"
- PACKAGE extra_materials)
+#===============================================================================
+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
+ )
-add_akantu_test(test_material_viscoelastic "test the visco elastic materials"
- PACKAGE extra_materials)
+#===============================================================================
+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_non_local "test the non-local materials"
- PACKAGE damage_non_local)
+# ==============================================================================
+add_akantu_test(test_material_viscoelastic "test the visco elastic materials")
+add_akantu_test(test_material_non_local "test the non-local materials")
+add_akantu_test(test_material_elasto_plastic_linear_isotropic_hardening "test the elasto plastic with linear isotropic hardening materials")
\ No newline at end of file
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/barre_trou.geo b/test/test_model/test_solid_mechanics_model/test_materials/barre_trou.geo
index 02f154f7c..fbf64aa7e 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/barre_trou.geo
+++ b/test/test_model/test_solid_mechanics_model/test_materials/barre_trou.geo
@@ -1,25 +1,25 @@
-cl1 = 0.1;
+cl1 = 0.25;
Point(1) = {0, 0, 0, cl1};
Point(2) = {10, 0, 0, cl1};
Point(3) = {10, 4, 0, cl1};
Point(4) = {0, 4, 0, cl1};
Point(5) = {5, 2, 0, cl1};
Point(6) = {3.5, 2, 0, cl1};
Point(8) = {6.5, 2, 0, cl1};
Point(9) = {5, 0.5, 0, cl1};
Point(11) = {5, 3.5, 0, cl1};
Point(12) = {5, 3.5, 0, cl1};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Circle(7) = {6, 5, 11};
Circle(8) = {11, 5, 8};
Circle(9) = {8, 5, 9};
Circle(10) = {9, 5, 6};
Line Loop(11) = {1, 2, 3, 4, -9, -8, -7, -10};
Plane Surface(11) = {11};
Physical Surface("Interior") = {11};
Physical Line("Traction") = {2};
Physical Line("Fixed") = {1, 3, 4};
Physical Line("Free") = {7, 8, 9, 10};
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/material.dat b/test/test_model/test_solid_mechanics_model/test_materials/material.dat
index 662bae263..1bf4e1fbf 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/material.dat
+++ b/test/test_model/test_solid_mechanics_model/test_materials/material.dat
@@ -1,6 +1,8 @@
material local_damage [
name = concrete
rho = 3000 # density
E = 40e9 # young's modulus
- nu = 0.2 # poisson's ratio
+ nu = 0.3 # poisson's ratio
+ Yd = 1e5 # material strenght
+ Sd = 2.748e6
]
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/test_materials/mesh_section_gap.geo b/test/test_model/test_solid_mechanics_model/test_materials/mesh_section_gap.geo
new file mode 100644
index 000000000..118c5e6fa
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/mesh_section_gap.geo
@@ -0,0 +1,39 @@
+// Mesh size
+h = 0.05;
+
+// Dimensions of thin part
+Lx = 1;
+Ly = 0.2;
+
+
+// ------------------------------------------
+// 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, 2*Ly, 0.0, h};
+Point(104) = { Lx/2, 2*Ly, 0.0, h};
+Point(105) = { Lx/2, Ly, 0.0, h};
+Point(106) = { 0.0, Ly, 0.0, h};
+
+// Base Cube
+Line(101) = {101,102}; // Bottom Face
+Line(102) = {102,103};
+Line(103) = {103,104};
+Line(104) = {104,105};
+Line(105) = {105,106};
+Line(106) = {106,101};
+
+// Base Cube
+Line Loop(101) = {101:106};
+
+Plane Surface(101) = {101};
+
+Physical Line("Fixed") = {101, 106};
+Physical Line("Traction") = {102};
+Physical Surface("Interior") = {101};
+
+//Transfinite Surface "*";
+//Recombine Surface "*";
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/orthotropic.dat b/test/test_model/test_solid_mechanics_model/test_materials/orthotropic.dat
new file mode 100644
index 000000000..bd9d2876a
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/orthotropic.dat
@@ -0,0 +1,10 @@
+
+
+material elastic_orthotropic [
+ name = aluminum-film-0K-LJ-orthotropic
+ rho = 3.8328782866680342684 # density in g/mol/A^2
+ E1 = 9.7874197348334701168 # young's in kcal/mol/A^3
+ E2 = 9.7874197348334701168 # young's in kcal/mol/A^3
+ nu12 = 0.33333333333333333333 # poisson's ratio
+ G12 = 3.6702824005625512938 # shear modulus in kcal/mol/A^3
+]
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..6e9b1861f 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,183 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 384796347..cc6850bdd 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,89 +1,138 @@
/**
* @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>
*
* @date creation: Fri Nov 26 2010
* @date last modification: Fri Sep 19 2014
*
- * @brief test of the class SolidMechanicsModel
+ * @brief test of the class SolidMechanicsModel with custom local damage on a
+ * 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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 = 200;
- Real epot, ekin;
-
+ UInt max_steps = 1100;
+
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
- mesh.read("barre_trou.msh");
+ 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/10.);
+ 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");
+ // model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "Fixed");
// Boundary condition (Neumann)
Matrix<Real> stress(2,2);
- stress.eye(3e6);
+ 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();
+ /*epot = model.getPotentialEnergy();
ekin = model.getKineticEnergy();
- std::cout << s << " " << epot << " " << ekin << " " << epot + ekin
+ if(s % 10 == 0) std::cout << s << " " << epot << " " << ekin << " " << epot + ekin
<< std::endl;
+
+ if(s % 10 == 0) std::cout << "Step " << s+1 << "/" << max_steps <<std::endl;
+ if(s % 10 == 0) model.dump();*/
+ }
+
+ const Vector<Real> & lower_bounds = mesh.getLowerBounds();
+ const Vector<Real> & upper_bounds = mesh.getUpperBounds();
+ Real L = upper_bounds(0) - lower_bounds(0);
+
+ const ElementTypeMapArray<UInt> & filter = model.getMaterial(0).getElementFilter();
+ ElementTypeMapArray<UInt>::type_iterator it = filter.firstType(spatial_dimension);
+ ElementTypeMapArray<UInt>::type_iterator end = filter.lastType(spatial_dimension);
+ Vector<Real> barycenter(spatial_dimension);
+ bool is_fully_damaged = false;
+ for(; it != end; ++it) {
+ UInt nb_elem = mesh.getNbElement(*it);
+ const UInt nb_gp = model.getFEEngine().getNbIntegrationPoints(*it);
+ Array<Real> & material_damage_array = model.getMaterial(0).getArray<Real>("damage", *it);
+ UInt cpt = 0;
+ for(UInt nel = 0; nel < nb_elem ; ++nel){
+ if (material_damage_array(cpt,0) > 0.9){
+ is_fully_damaged = true;
+ mesh.getBarycenter(nel,*it,barycenter.storage());
+ if( (std::abs(barycenter(0)-(L/2)) < (L/10) ) ) {
+ return EXIT_FAILURE;
+ }
+ }
+ cpt += nb_gp;
+ }
}
+ if(!is_fully_damaged)
+ return EXIT_FAILURE;
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/CMakeLists.txt
new file mode 100644
index 000000000..53d6d8db0
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/CMakeLists.txt
@@ -0,0 +1,45 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Jaehyun Cho <jaehyun.cho@epfl.ch>
+#
+# @date creation: Fri Aug 3 2015
+#
+# @brief test for material type elasto plastic linear isotropic hardening using
+# tension-compression test
+#
+# @section LICENSE
+#
+# Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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..ac16544f3
--- /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: Fri Aug 3 2015
+ *
+ # @brief test for material type elasto plastic linear isotropic hardening using
+ # tension-compression test
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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..a74ad2b74
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_mazars.cc
@@ -0,0 +1,304 @@
+/**
+ * @file tes_material_mazars.cc
+ * @author Clement Roux-Langlois <clement.roux@epfl.ch>
+ * @date Fri Sep 11 20151
+ *
+ * @brief test for material mazars, dissymmetric
+ *
+ * @section LICENSE
+ *
+ * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+ * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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 c7b02c9a6..6302ed999 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,41 +1,50 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Mon Jan 20 2014
# @date last modification: Mon Jan 20 2014
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
#
# @section DESCRIPTION
#
#===============================================================================
-add_mesh(test_material_non_local_mesh mesh.geo 2 2 OUTPUT mesh.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)
+
register_test(test_material_damage_non_local
SOURCES test_material_damage_non_local.cc
- DEPENDENCIES test_material_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_non_local
+ SOURCES test_material_non_local.cc custom_non_local_test_material.cc
+ DEPENDS test_material_non_local_mesh
+ FILES_TO_COPY material.dat
+ PACKAGE damage_non_local
+ )
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc
new file mode 100644
index 000000000..11e8811b6
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc
@@ -0,0 +1,88 @@
+/**
+ * @file custom_non_local_test_material.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date Sun Mar 1 15:57:50 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+
+#include "custom_non_local_test_material.hh"
+
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+CustomNonLocalTestMaterial<dim>::CustomNonLocalTestMaterial(SolidMechanicsModel & model, const ID & id) :
+ Material(model, id),
+ MyElasticParent(model, id),
+ MyNonLocalParent(model, id),
+ local_damage("local_damage", *this),
+ damage("damage", *this)
+{
+ // Initialize the internal field by specifying the number of components
+ this->local_damage.initialize(1);
+ this->damage.initialize(1);
+ /// register the non-local variable in the manager
+ this->model->getNonLocalManager().registerNonLocalVariable(this->local_damage.getName(), this->damage.getName(), 1);
+
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+void CustomNonLocalTestMaterial<dim>::initMaterial() {
+ MyElasticParent::initMaterial();
+ MyNonLocalParent::initMaterial();
+ this->model->getNonLocalManager().nonLocalVariableToNeighborhood(damage.getName(), this->name);
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+void CustomNonLocalTestMaterial<dim>::computeStress(ElementType el_type, GhostType ghost_type) {
+ MyElasticParent::computeStress(el_type, ghost_type);
+}
+
+/* -------------------------------------------------------------------------- */
+template<UInt dim>
+void CustomNonLocalTestMaterial<dim>::computeNonLocalStress(ElementType el_type, GhostType ghost_type) {
+ Array<Real>::const_scalar_iterator dam = this->damage(el_type, ghost_type).begin();
+ Array<Real>::matrix_iterator stress = this->stress(el_type, ghost_type).begin(dim, dim);
+ Array<Real>::matrix_iterator stress_end = this->stress(el_type, ghost_type).end(dim, dim);
+
+ // compute the damage and update the stresses
+ for (; stress != stress_end; ++stress, ++dam) {
+ *stress *= (1. - *dam);
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+// Instantiate the material for the 3 dimensions
+INSTANTIATE_MATERIAL(CustomNonLocalTestMaterial);
+/* -------------------------------------------------------------------------- */
+
+
+__END_AKANTU__
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
new file mode 100644
index 000000000..073cb5f37
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
@@ -0,0 +1,101 @@
+/**
+ * @file custom_non_local_test_material.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ *
+ * @date Sun Mar 1 15:57:50 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "material_non_local.hh"
+#include "material_elastic.hh"
+
+#ifndef __CUSTOM_NON_LOCAL_TEST_MATERIAL_HH__
+#define __CUSTOM_NON_LOCAL_TEST_MATERIAL_HH__
+
+__BEGIN_AKANTU__
+
+template<UInt dim>
+class CustomNonLocalTestMaterial : public MaterialElastic<dim>,
+ public MaterialNonLocal<dim> {
+public:
+ typedef MaterialNonLocal<dim> MyNonLocalParent;
+ typedef MaterialElastic<dim> MyElasticParent;
+
+ CustomNonLocalTestMaterial(SolidMechanicsModel & model, const ID & id);
+
+ /* ------------------------------------------------------------------------ */
+ virtual void initMaterial();
+
+ void computeNonLocalStress(ElementType el_type, GhostType ghost_type);
+ void computeStress(ElementType el_type, GhostType ghost_type);
+
+protected:
+
+ /* ------------------------------------------------------------------------ */
+ void computeNonLocalStresses(GhostType ghost_type) {
+ AKANTU_DEBUG_IN();
+
+ Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(dim, ghost_type);
+ Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(dim, ghost_type);
+ for(; it != last_type; ++it) {
+ computeNonLocalStress(*it, ghost_type);
+ }
+
+ AKANTU_DEBUG_OUT();
+ }
+
+public:
+ /* ------------------------------------------------------------------------ */
+ virtual inline UInt getNbDataForElements(const Array<Element> & elements,
+ SynchronizationTag tag) const {
+ return MyNonLocalParent::getNbDataForElements(elements, tag) +
+ MyElasticParent::getNbDataForElements(elements, tag);
+ }
+ virtual inline void packElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag) const {
+ MyNonLocalParent::packElementData(buffer, elements, tag);
+ MyElasticParent::packElementData(buffer, elements, tag);
+ }
+
+ virtual inline void unpackElementData(CommunicationBuffer & buffer,
+ const Array<Element> & elements,
+ SynchronizationTag tag) {
+ MyNonLocalParent::unpackElementData(buffer, elements, tag);
+ MyElasticParent::unpackElementData(buffer, elements, tag);
+ }
+
+
+ void setDamage(Real dam) {
+ this->local_damage.setDefaultValue(dam);
+ }
+protected:
+ InternalField<Real> local_damage;
+ InternalField<Real> damage;
+};
+
+__END_AKANTU__
+
+#endif /* __CUSTOM_NON_LOCAL_TEST_MATERIAL_HH__ */
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material.dat b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material.dat
new file mode 100644
index 000000000..401f2491c
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/material.dat
@@ -0,0 +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 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 d7dabd2da..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 = 1e-3
- 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/mesh.geo b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/mesh.geo
index aef4af475..47df6e2c2 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/mesh.geo
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/mesh.geo
@@ -1,32 +1,35 @@
// Mesh size
-h = 0.1; // Top cube
+h = 0.05; // 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};
Plane Surface(101) = {101};
Physical Line("Fixed") = {101, 103, 104};
Physical Line("Traction") = {102};
Physical Surface("Interior") = {101};
+
+//Transfinite Surface "*";
+//Recombine Surface "*";
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/mesh_section_gap.geo b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/mesh_section_gap.geo
new file mode 100644
index 000000000..118c5e6fa
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/mesh_section_gap.geo
@@ -0,0 +1,39 @@
+// Mesh size
+h = 0.05;
+
+// Dimensions of thin part
+Lx = 1;
+Ly = 0.2;
+
+
+// ------------------------------------------
+// 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, 2*Ly, 0.0, h};
+Point(104) = { Lx/2, 2*Ly, 0.0, h};
+Point(105) = { Lx/2, Ly, 0.0, h};
+Point(106) = { 0.0, Ly, 0.0, h};
+
+// Base Cube
+Line(101) = {101,102}; // Bottom Face
+Line(102) = {102,103};
+Line(103) = {103,104};
+Line(104) = {104,105};
+Line(105) = {105,106};
+Line(106) = {106,101};
+
+// Base Cube
+Line Loop(101) = {101:106};
+
+Plane Surface(101) = {101};
+
+Physical Line("Fixed") = {101, 106};
+Physical Line("Traction") = {102};
+Physical Surface("Interior") = {101};
+
+//Transfinite Surface "*";
+//Recombine Surface "*";
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 13e302956..7e3f92d06 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,96 +1,125 @@
/**
* @file test_material_damage_non_local.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
+ * @author Clément Roux-Langlois <clement.roux@epfl.ch>
*
* @date creation: Tue Sep 13 2011
* @date last modification: Thu Apr 03 2014
*
- * @brief test for non-local damage materials
+ * @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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 = 40000;
+ UInt max_steps = 1100;
const UInt spatial_dimension = 2;
Mesh mesh(spatial_dimension);
- mesh.read("mesh.msh");
+ 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/10.);
+ 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(3e6);
+ stress.eye(5e8);
model.applyBC(BC::Neumann::FromHigherDim(stress), "Traction");
- model.setBaseName("damage_non_local");
- model.addDumpField("displacement");
+ /*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();
+ 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();
+ //if(s % 100 == 0) std::cout << "Step " << s+1 << "/" << max_steps <<std::endl;
+ //if(s % 100 == 0) model.dump();
+ }
+
+ const Vector<Real> & lower_bounds = mesh.getLowerBounds();
+ const Vector<Real> & upper_bounds = mesh.getUpperBounds();
+ Real L = upper_bounds(0) - lower_bounds(0);
+ Real H = upper_bounds(1) - lower_bounds(1);
+
+ const ElementTypeMapArray<UInt> & filter = model.getMaterial(0).getElementFilter();
+ ElementTypeMapArray<UInt>::type_iterator it = filter.firstType(spatial_dimension);
+ ElementTypeMapArray<UInt>::type_iterator end = filter.lastType(spatial_dimension);
+ Vector<Real> barycenter(spatial_dimension);
+ for(; it != end; ++it) {
+ UInt nb_elem = mesh.getNbElement(*it);
+ const UInt nb_gp = model.getFEEngine().getNbIntegrationPoints(*it);
+ Array<Real> & material_damage_array = model.getMaterial(0).getArray<Real>("damage", *it);
+ UInt cpt = 0;
+ for(UInt nel = 0; nel < nb_elem ; ++nel){
+ mesh.getBarycenter(nel,*it,barycenter.storage());
+ if( (std::abs(barycenter(0)-(L/2)+0.025)<0.025)
+ && (std::abs(barycenter(1)-(H/2)+0.025)<0.025) ) {
+ if (material_damage_array(cpt,0) < 0.9){
+ // std::cout << "barycenter(0) = " << barycenter(0) << ", barycenter(1) = "
+ // << barycenter(1) <<std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+ cpt += nb_gp;
+ }
}
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_non_local.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_non_local.cc
new file mode 100644
index 000000000..366c3cf11
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/test_material_non_local.cc
@@ -0,0 +1,107 @@
+/**
+ * @file test_material_non_local.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date Wed Aug 31 11:09:48 2011
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include "solid_mechanics_model.hh"
+#include "custom_non_local_test_material.hh"
+/* -------------------------------------------------------------------------- */
+#include <iostream>
+/* -------------------------------------------------------------------------- */
+
+using namespace akantu;
+/* -------------------------------------------------------------------------- */
+int main(int argc, char *argv[]) {
+ akantu::initialize("material.dat", argc, argv);
+
+ // some configuration variables
+ const UInt spatial_dimension = 2;
+
+ Mesh mesh(spatial_dimension);
+
+ StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ Int psize = comm.getNbProc();
+ Int prank = comm.whoAmI();
+
+ // mesh creation and read
+ MeshPartition * partition;
+ if(prank == 0) {
+ mesh.read("mesh.msh");
+
+ /// partition the mesh
+ partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ partition->partitionate(psize);
+ } else {
+ partition = NULL;
+ }
+
+ /// model creation
+ SolidMechanicsModel model(mesh);
+ model.initParallel(partition);
+ delete partition;
+
+ /// model initialization changed to use our material
+ model.initFull(SolidMechanicsModelOptions(_explicit_lumped_mass, true));
+ model.registerNewCustomMaterials< CustomNonLocalTestMaterial<spatial_dimension> >("custom_non_local_test_material");
+ model.initMaterials();
+
+ CustomNonLocalTestMaterial<spatial_dimension> & mat = dynamic_cast<CustomNonLocalTestMaterial<spatial_dimension> &>(model.getMaterial("test"));
+
+ if(prank == 0) std::cout << mat << std::endl;
+
+ // Setting up the dumpers + first dump
+ model.setBaseName("non_local_material");
+ model.addDumpFieldVector("displacement");
+ model.addDumpFieldVector("force" );
+ model.addDumpField("partitions" );
+ model.addDumpField("stress" );
+ model.addDumpField("stress" );
+ model.addDumpField("local_damage");
+ model.addDumpField("damage" );
+
+ model.updateResidual();
+ model.dump();
+
+
+ //Array<Real> & damage = mat.getArray("local_damage", _quadrangle_4);
+ Array<Real> & damage = mat.getArray<Real>("local_damage", _triangle_3);
+
+ RandGenerator<UInt> gen;
+
+ for (UInt i = 0; i < 1; ++i) {
+ UInt g = (gen() / Real(RandGenerator<UInt>::max() - RandGenerator<UInt>::min())) * damage.getSize();
+ std::cout << prank << " -> " << g << std::endl;
+ damage(g) = 1.;
+ }
+
+ model.updateResidual();
+ model.dump();
+
+ akantu::finalize();
+ return EXIT_SUCCESS;
+}
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc
new file mode 100644
index 000000000..5f53d0d36
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_orthotropic.cc
@@ -0,0 +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
+ *
+ * @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_materials/test_material_viscoelastic/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/CMakeLists.txt
new file mode 100644
index 000000000..c826a0ffa
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/CMakeLists.txt
@@ -0,0 +1,45 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Nicolas Richart <nicolas.richart@epfl.ch>
+#
+# @date Thu Aug 09 21:06:34 2012
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+add_mesh(test_material_standard_linear_solid_deviatoric_relaxation_mesh
+ test_material_standard_linear_solid_deviatoric_relaxation.geo 2 1)
+
+register_test(test_material_standard_linear_solid_deviatoric_relaxation
+ SOURCES test_material_standard_linear_solid_deviatoric_relaxation.cc
+ DEPENDS test_material_standard_linear_solid_deviatoric_relaxation_mesh
+ FILES_TO_COPY material_standard_linear_solid_deviatoric_relaxation.dat
+ PACKAGE core
+ )
+
+register_test(test_material_standard_linear_solid_deviatoric_relaxation_tension
+ SOURCES test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
+ DEPENDS test_material_standard_linear_solid_deviatoric_relaxation_mesh
+ FILES_TO_COPY material_standard_linear_solid_deviatoric_relaxation.dat
+ PACKAGE core
+ )
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_standard_linear_solid_deviatoric_relaxation.dat b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_standard_linear_solid_deviatoric_relaxation.dat
new file mode 100644
index 000000000..9a487b03e
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/material_standard_linear_solid_deviatoric_relaxation.dat
@@ -0,0 +1,9 @@
+material sls_deviatoric [
+ name = anything
+ rho = 7800 # density
+ E = 15 # young's modulus
+ nu = 0.25 # poisson's ratio
+ Eta = 10 # viscosity
+ Ev = 5 # viscous stiffness
+ Plane_Stress = 0
+]
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
new file mode 100644
index 000000000..87f690e2e
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.cc
@@ -0,0 +1,165 @@
+/**
+ * @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
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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.geo b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.geo
new file mode 100644
index 000000000..173c1f300
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation.geo
@@ -0,0 +1,33 @@
+// Mesh size
+h = 1; // Top cube
+
+// Dimensions of top cube
+Lx = 0.001;
+Ly = 0.001;
+
+
+// ------------------------------------------
+// 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};
+
+Plane Surface(101) = {101};
+
+Physical Surface(1) = {101};
+
+Transfinite Surface "*";
+Recombine Surface "*";
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
new file mode 100644
index 000000000..58dedfc77
--- /dev/null
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_viscoelastic/test_material_standard_linear_solid_deviatoric_relaxation_tension.cc
@@ -0,0 +1,172 @@
+/**
+ * @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
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <limits>
+#include <fstream>
+#include <sstream>
+#include <iostream>
+/* -------------------------------------------------------------------------- */
+#include "solid_mechanics_model.hh"
+
+using namespace akantu;
+
+int main(int argc, char *argv[])
+{
+ akantu::initialize("material_standard_linear_solid_deviatoric_relaxation.dat", argc, argv);
+
+ // sim data
+ Real T = 10.;
+ Real eps = 0.001;
+
+ // const UInt dim = 3;
+ const UInt dim = 2;
+ Real sim_time = 25.;
+ //Real sim_time = 250.;
+ Real time_factor = 0.1;
+
+ Real tolerance = 1e-5;
+
+ Mesh mesh(dim);
+ mesh.read("test_material_standard_linear_solid_deviatoric_relaxation.msh");
+ // mesh_io.read("hexa_structured.msh",mesh);
+ //const ElementType element_type = _hexahedron_8;
+ const ElementType element_type = _quadrangle_4;
+ SolidMechanicsModel model(mesh);
+
+ /* ------------------------------------------------------------------------ */
+ /* Initialization */
+ /* ------------------------------------------------------------------------ */
+ model.initFull();
+ std::cout << model.getMaterial(0) << std::endl;
+
+ model.assembleMassLumped();
+
+ model.updateResidual();
+ model.getMaterial(0).setToSteadyState();
+
+ std::stringstream filename_sstr;
+ filename_sstr << "test_material_standard_linear_solid_deviatoric_relaxation_tension.out";
+ std::ofstream output_data;
+ output_data.open(filename_sstr.str().c_str());
+ output_data << "#[1]-time [2]-sigma_analytic [3+]-sigma_measurements" << std::endl;
+
+ Material & mat = model.getMaterial(0);
+ const Array<Real> & stress = mat.getStress(element_type);
+
+ Real Eta = mat.getParam<Real>("Eta");
+ Real EV = mat.getParam<Real>("Ev");
+ Real Einf = mat.getParam<Real>("Einf");
+ Real E0 = mat.getParam<Real>("E");
+
+ Real kpa = mat.getParam<Real>("kapa");
+ Real mu = mat.getParam<Real>("mu");
+
+ Real gamma = EV/E0;
+ Real gammainf = Einf/E0;
+
+ Real tau = Eta / EV;
+ std::cout << "relaxation time = " << tau << std::endl;
+
+ UInt nb_nodes = mesh.getNbNodes();
+ const Array<Real> & coordinate = mesh.getNodes();
+ Array<Real> & displacement = model.getDisplacement();
+
+ /// Setting time step
+ Real time_step = model.getStableTimeStep() * time_factor;
+ std::cout << "Time Step = " << time_step << "s" << std::endl;
+ model.setTimeStep(time_step);
+
+ UInt max_steps = sim_time / time_step;
+ UInt out_interval = 1;
+
+ Real time = 0.;
+
+ /* ------------------------------------------------------------------------ */
+ /* Main loop */
+ /* ------------------------------------------------------------------------ */
+ for(UInt s = 0; s <= max_steps; ++s) {
+
+ if(s % 1000 == 0)
+ std::cerr << "passing step " << s << "/" << max_steps << std::endl;
+
+ time = s * time_step;
+ // impose displacement
+ Real epsilon = 0.;
+ if (time < T) {
+ epsilon = eps * time / T;
+ }
+ else {
+ epsilon = eps;
+ }
+
+ for (UInt n=0; n<nb_nodes; ++n) {
+ for (UInt d=0; d<dim; ++d)
+ displacement(n,d) = epsilon * coordinate(n,d);
+ }
+
+ // compute stress
+ model.updateResidual();
+
+ // print output
+ if(s % out_interval == 0) {
+ // analytical solution
+ Real epskk = dim * eps;
+ Real solution= 0.;
+ if (time < T) {
+ solution = 2 * mu * (eps - epskk/3.) / T * (gammainf * time + gamma * tau * (1 - exp(-time/tau))) + gammainf * kpa * epskk * time / T;
+ }
+ else {
+ solution = 2 * mu * (eps - epskk/3.) * (gammainf + gamma * tau / T *(exp((T-time)/tau) - exp(-time/tau))) + gammainf * kpa * epskk;
+ }
+ output_data << s*time_step << " " << solution;
+
+ // data output
+ Array<Real>::const_matrix_iterator stress_it = stress.begin(dim, dim);
+ Array<Real>::const_matrix_iterator stress_end = stress.end(dim, dim);
+ for(;stress_it != stress_end; ++stress_it) {
+ output_data << " " << (*stress_it)(1,1);
+
+ // test error
+ Real rel_error_1 = std::abs(((*stress_it)(1,1) - solution) / solution);
+ if (rel_error_1 > tolerance) {
+ std::cerr << "Relative error: " << rel_error_1 << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+ output_data << std::endl;
+ }
+ }
+
+ finalize();
+
+ std::cout << "Test successful!" << std::endl;
+ return EXIT_SUCCESS;
+}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d.cc
index 9033a1895..be47ae8d2 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,197 @@
/**
* @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
*
* @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 <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.getPotentialEnergy();
- akantu::Real ekin = model.getKineticEnergy();
+ akantu::Real epot = model.getEnergy("potential");
+ akantu::Real ekin = model.getEnergy("kinetic");
energy << s << "," << (s-1)*time_step << "," << epot << "," << ekin << "," << epot + ekin
<< std::endl;
#ifdef CHECK_STRESS
/// search the position of the maximum of stress to determine the wave speed
akantu::Real max_stress = std::numeric_limits<akantu::Real>::min();
akantu::Real * stress = model.getMaterial(0).getStress(type).storage();
for (akantu::UInt i = 0; i < nb_element; ++i) {
if(max_stress < stress[i*spatial_dimension*spatial_dimension]) {
max_stress = stress[i*spatial_dimension*spatial_dimension];
}
}
akantu::Real * coord = model.getFEEngine().getMesh().getNodes().storage();
akantu::Real * disp_val = model.getDisplacement().storage();
akantu::UInt * conn = model.getFEEngine().getMesh().getConnectivity(type).storage();
akantu::UInt nb_nodes_per_element = model.getFEEngine().getMesh().getNbNodesPerElement(type);
akantu::Real * coords = new akantu::Real[spatial_dimension];
akantu::Real min_x = std::numeric_limits<akantu::Real>::max();
akantu::Real max_x = std::numeric_limits<akantu::Real>::min();
akantu::Real stress_range = 5e7;
for (akantu::UInt el = 0; el < nb_element; ++el) {
if(stress[el*spatial_dimension*spatial_dimension] > max_stress - stress_range) {
akantu::UInt el_offset = el * nb_nodes_per_element;
memset(coords, 0, spatial_dimension*sizeof(akantu::Real));
for (akantu::UInt n = 0; n < nb_nodes_per_element; ++n) {
for (akantu::UInt i = 0; i < spatial_dimension; ++i) {
akantu::UInt node = conn[el_offset + n] * spatial_dimension;
coords[i] += (coord[node + i] + disp_val[node + i])
/ ((akantu::Real) nb_nodes_per_element);
}
}
min_x = min_x < coords[0] ? min_x : coords[0];
max_x = max_x > coords[0] ? max_x : coords[0];
}
}
outfile << s << " " << .5 * (min_x + max_x) << " " << min_x << " " << max_x << " " << max_x - min_x << " " << max_stress << std::endl;
delete [] coords;
#endif // CHECK_STRESS
#ifdef AKANTU_USE_IOHELPER
if(s % 100 == 0) {
model.dump();
model.dumpGroup();
}
#endif //AKANTU_USE_IOHELPER
if(s % 100 == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl;
}
energy.close();
#ifdef CHECK_STRESS
outfile.close();
#endif // CHECK_STRESS
akantu::finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_parallel.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_bar_traction2d_parallel.cc
index 985194f2e..b2f6b18b8 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,161 @@
/**
* @file test_solid_mechanics_model_bar_traction2d_parallel.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Sun Sep 12 2010
* @date last modification: Thu Jun 05 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 <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.getPotentialEnergy();
- akantu::Real ekin = model.getKineticEnergy();
+ 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 58e1823d0..a93decdbd 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,100 @@
/**
* @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
*
* @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 <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->getPotentialEnergy();
- ekin = model->getKineticEnergy();
+ 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 7fcedb574..c83ad0bdc 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,126 @@
/**
* @file test_solid_mechanics_model_bar_traction2d_structured_pbc.cc
*
* @author David Simon Kammer <david.kammer@epfl.ch>
*
* @date creation: Thu Dec 22 2011
* @date last modification: Mon Jun 23 2014
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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.getPotentialEnergy();
- ekin = model.getKineticEnergy();
+ 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_circle_2.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_circle_2.cc
index 476bb4ed3..118a15ff4 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,98 @@
/**
* @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
*
* @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("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(1e3);
+ 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 256346394..9d174da36 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,111 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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.getPotentialEnergy();
- ekin = model.getKineticEnergy();
+ 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 2c8747547..51bb61113 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,111 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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.getPotentialEnergy();
- ekin = model.getKineticEnergy();
+ 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 6603996fa..b94addff5 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,113 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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.getPotentialEnergy();
- ekin = model.getKineticEnergy();
+ 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_material_eigenstrain.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
index bdfa9fb8d..09baf71cf 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,209 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You 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_eigenstrain) {
+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_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_eigenstrain(dim, dim);
- prescribed_eigenstrain.clear();
+ Matrix<Real> prescribed_eigengradu(dim, dim);
+ prescribed_eigengradu.clear();
for (UInt i = 0; i < dim; ++i) {
for (UInt j = 0; j < dim; ++j)
- prescribed_eigenstrain(i,j) += 0.1;
+ 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> & eigenstrain_vect = const_cast<Array<Real> &>(my_model.getMaterial(0).getInternal("eigenstrain")(element_type));
- Array<Real>::iterator< Matrix<Real> > eigenstrain_it = eigenstrain_vect.begin(dim, dim);
- Array<Real>::iterator< Matrix<Real> > eigenstrain_end = eigenstrain_vect.end(dim, dim);
+ 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 (; eigenstrain_it != eigenstrain_end; ++eigenstrain_it) {
+ for (; eigengradu_it != eigengradu_end; ++eigengradu_it) {
for (UInt i = 0; i < dim; ++i)
for (UInt j = 0; j < dim; ++j)
- (*eigenstrain_it)(i,j) += prescribed_eigenstrain(i,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_eigenstrain);
+ presc_stress = prescribed_stress<element_type, plane_strain>(prescribed_eigengradu);
Real stress_tolerance = 1e-13;
for (; stress_it != stress_end; ++stress_it) {
Matrix<Real> & stress = *stress_it;
Matrix<Real> diff(dim, dim);
diff = stress;
diff -= presc_stress;
Real stress_error = diff.norm<L_inf>() / stress.norm<L_inf>();
if(stress_error > stress_tolerance) {
std::cerr << "stress error: " << stress_error << " > " << stress_tolerance << std::endl;
std::cerr << "stress: " << stress << std::endl
<< "prescribed stress: " << presc_stress << std::endl;
return EXIT_FAILURE;
} else {
std::cerr << "stress error: " << stress_error << " < " << stress_tolerance << std::endl;
}
}
finalize();
return EXIT_SUCCESS;
}
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_reassign_material.cc
index 3af8a370c..02480414b 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
*
* @brief test the function reassign material
*
* @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 "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> & el_idx_by_mat = model.getElementIndexByMaterial(*it, ghost_type);
+ 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 (el_idx_by_mat(elem,0) != mat_index)
+ 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 b24c63aae..72afecf70 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,116 @@
/**
* @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
*
* @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 <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.getPotentialEnergy();
- akantu::Real ekin = model.getKineticEnergy();
+ 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 20dc8b4fa..d2c5050a2 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,102 @@
/**
* @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("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(1e3);
+ 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.getPotentialEnergy();
- ekin = model.getKineticEnergy();
+ 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 3c13a5441..efcd140bd 100644
--- a/test/test_model/test_structural_mechanics_model/CMakeLists.txt
+++ b/test/test_model/test_structural_mechanics_model/CMakeLists.txt
@@ -1,57 +1,72 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Fabian Barras <fabian.barras@epfl.ch>
#
# @date creation: Fri Jul 15 2011
# @date last modification: Mon Jul 07 2014
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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
+ )
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview)
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
new file mode 100644
index 000000000..39ab9d611
--- /dev/null
+++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_bernoulli_beam_12_10_13.cc
@@ -0,0 +1,28 @@
+/**
+ * @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
+ *
+ * @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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
diff --git a/test/test_python_interface/CMakeLists.txt b/test/test_python_interface/CMakeLists.txt
new file mode 100644
index 000000000..47fe8922b
--- /dev/null
+++ b/test/test_python_interface/CMakeLists.txt
@@ -0,0 +1,34 @@
+#===============================================================================
+# @file CMakeLists.txt
+#
+# @author Fabian Barras <fabian.barras@epfl.ch>
+#
+# @date creation: Tue Jan 5 2016
+#
+# @brief Python Interface tests
+#
+# @section LICENSE
+#
+# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
+# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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/1D_bar.geo b/test/test_solver/1D_bar.geo
new file mode 100644
index 000000000..235f16da2
--- /dev/null
+++ b/test/test_solver/1D_bar.geo
@@ -0,0 +1,4 @@
+Point(1) = {0, 0, 0, 1};
+Point(2) = {10, 0, 0, 1};
+Line(1) = {1, 2};
+Physical Line(2) = {1};
diff --git a/test/test_solver/CMakeCache.txt b/test/test_solver/CMakeCache.txt
new file mode 100644
index 000000000..44fc15c46
--- /dev/null
+++ b/test/test_solver/CMakeCache.txt
@@ -0,0 +1,40 @@
+# This is the CMakeCache file.
+# For build in directory: /home/cubaramo/akantu/test/test_solver
+# It was generated by CMake: /usr/bin/cmake
+# You can edit this file to change values found and used by cmake.
+# If you do not want to change any of the values, simply exit the editor.
+# If you do want to change a value, simply edit, save, and exit the editor.
+# The syntax for the file is as follows:
+# KEY:TYPE=VALUE
+# KEY is the name of a variable in the cache.
+# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
+# VALUE is the current value for the KEY.
+
+########################
+# EXTERNAL cache entries
+########################
+
+
+########################
+# INTERNAL cache entries
+########################
+
+//This is the directory where this CMakeCache.txt was created
+CMAKE_CACHEFILE_DIR:INTERNAL=/home/cubaramo/akantu/test/test_solver
+//Major version of cmake used to create the current loaded cache
+CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2
+//Minor version of cmake used to create the current loaded cache
+CMAKE_CACHE_MINOR_VERSION:INTERNAL=8
+//Patch version of cmake used to create the current loaded cache
+CMAKE_CACHE_PATCH_VERSION:INTERNAL=12
+//Path to CMake executable.
+CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
+//Path to cpack program executable.
+CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
+//Path to ctest program executable.
+CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
+//Path to cache edit program executable.
+CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/ccmake
+//Path to CMake installation.
+CMAKE_ROOT:INTERNAL=/usr/share/cmake-2.8
+
diff --git a/test/test_solver/CMakeLists.txt b/test/test_solver/CMakeLists.txt
index 42f17633c..130c89133 100644
--- a/test/test_solver/CMakeLists.txt
+++ b/test/test_solver/CMakeLists.txt
@@ -1,54 +1,90 @@
#===============================================================================
# @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
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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_solver_mesh
- )
\ No newline at end of file
+ DEPENDS test_matrix_mesh
+ PACKAGE petsc
+ )
+
+register_test(test_petsc_matrix_profile_parallel
+ SOURCES test_petsc_matrix_profile_parallel.cc
+ DEPENDS test_matrix_mesh
+ PACKAGE petsc
+ )
+
+register_test(test_petsc_matrix_diagonal
+ SOURCES test_petsc_matrix_diagonal.cc
+ DEPENDS test_solver_mesh
+ PACKAGE petsc
+ )
+
+register_test(test_petsc_matrix_apply_boundary
+ SOURCES test_petsc_matrix_apply_boundary.cc
+ DEPENDS test_solver_mesh
+ PACKAGE petsc
+ )
+
+register_test(test_solver_petsc
+ SOURCES test_solver_petsc.cc
+ DEPENDS test_solver_petsc_mesh
+ PACKAGE petsc
+ )
+
+register_test(test_solver_petsc_parallel
+ SOURCES test_solver_petsc.cc
+ DEPENDS test_solver_petsc_mesh
+ PACKAGE petsc
+ )
diff --git a/test/test_solver/square.geo b/test/test_solver/square.geo
new file mode 100644
index 000000000..67df205f8
--- /dev/null
+++ b/test/test_solver/square.geo
@@ -0,0 +1,28 @@
+// Mesh size
+h = 1.0; // 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};
diff --git a/test/test_solver/test_petsc_matrix_apply_boundary.cc b/test/test_solver/test_petsc_matrix_apply_boundary.cc
new file mode 100644
index 000000000..54cb37117
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_apply_boundary.cc
@@ -0,0 +1,141 @@
+/**
+ * @file test_petsc_matrix_profile.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Jul 30 12:34:08 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <cstdlib>
+/* -------------------------------------------------------------------------- */
+#include "static_communicator.hh"
+#include "aka_common.hh"
+#include "aka_csr.hh"
+#include "mesh.hh"
+#include "mesh_io.hh"
+#include "mesh_utils.hh"
+#include "distributed_synchronizer.hh"
+#include "petsc_matrix.hh"
+#include "fe_engine.hh"
+#include "dof_synchronizer.hh"
+
+#include "mesh_partition_scotch.hh"
+
+using namespace akantu;
+int main(int argc, char *argv[]) {
+
+ initialize(argc, argv);
+ const ElementType element_type = _triangle_3;
+ const GhostType ghost_type = _not_ghost;
+ UInt spatial_dimension = 2;
+
+
+ StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ Int psize = comm.getNbProc();
+ Int prank = comm.whoAmI();
+
+ /// read the mesh and partition it
+ Mesh mesh(spatial_dimension);
+
+ /* ------------------------------------------------------------------------ */
+ /* Parallel initialization */
+ /* ------------------------------------------------------------------------ */
+ DistributedSynchronizer * communicator = NULL;
+ if(prank == 0) {
+ /// creation mesh
+ mesh.read("triangle.msh");
+ MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ partition->partitionate(psize);
+ communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
+ delete partition;
+ } else {
+ communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ }
+
+
+ FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
+
+ DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
+ UInt nb_global_nodes = mesh.getNbGlobalNodes();
+
+ dof_synchronizer.initGlobalDOFEquationNumbers();
+
+ // fill the matrix with
+ UInt nb_element = mesh.getNbElement(element_type);
+ UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
+ UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
+ SparseMatrix K(nb_global_nodes * spatial_dimension, _symmetric);
+ K.buildProfile(mesh, dof_synchronizer, spatial_dimension);
+ Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1);
+ Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
+ Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
+ Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
+
+ for(; K_e_it != K_e_end; ++K_e_it)
+ *K_e_it = element_input;
+
+ // assemble the test matrix
+ fem->assembleMatrix(K_e, K, spatial_dimension, element_type, ghost_type);
+
+ // create petsc matrix
+ PETScMatrix petsc_matrix(nb_global_nodes * spatial_dimension, _symmetric);
+
+ petsc_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
+
+ // add stiffness matrix to petsc matrix
+ petsc_matrix.add(K, 1);
+
+ // create boundary array: block all dofs
+ UInt nb_nodes = mesh.getNbNodes();
+ Array<bool> boundary = Array<bool>(nb_nodes, spatial_dimension, true);
+
+ // apply boundary
+ petsc_matrix.applyBoundary(boundary);
+
+ // test if all entries except the diagonal ones have been zeroed
+ Real test_passed = 0;
+
+ for (UInt i = 0; i < nb_nodes * spatial_dimension; ++i) {
+ if (dof_synchronizer.isLocalOrMasterDOF(i)) {
+ for (UInt j = 0; j < nb_nodes * spatial_dimension; ++j) {
+ if (dof_synchronizer.isLocalOrMasterDOF(j)) {
+ if (i == j)
+ test_passed += petsc_matrix(i, j) - 1;
+ else
+ test_passed += petsc_matrix(i, j) - 0;
+ }
+ }
+ }
+ }
+
+ if (std::abs(test_passed) > Math::getTolerance()) {
+ finalize();
+ return EXIT_FAILURE;
+ }
+ delete communicator;
+
+ finalize();
+
+ return EXIT_SUCCESS;
+
+}
diff --git a/test/test_solver/test_petsc_matrix_apply_boundary.sh b/test/test_solver/test_petsc_matrix_apply_boundary.sh
new file mode 100755
index 000000000..f053c4da0
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_apply_boundary.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+mpirun -np 4 ./test_petsc_matrix_apply_boundary
diff --git a/test/test_solver/test_petsc_matrix_diagonal.cc b/test/test_solver/test_petsc_matrix_diagonal.cc
new file mode 100644
index 000000000..dd3eed87d
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_diagonal.cc
@@ -0,0 +1,147 @@
+/**
+ * @file test_petsc_matrix_diagonal.cc
+ * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Apr 22 09:41:14 2015
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <cstdlib>
+/* -------------------------------------------------------------------------- */
+#include "static_communicator.hh"
+#include "aka_common.hh"
+#include "aka_csr.hh"
+#include "mesh.hh"
+#include "mesh_io.hh"
+#include "mesh_utils.hh"
+#include "distributed_synchronizer.hh"
+#include "petsc_matrix.hh"
+#include "fe_engine.hh"
+#include "dof_synchronizer.hh"
+#include "dumper_paraview.hh"
+#include "mesh_partition_scotch.hh"
+
+using namespace akantu;
+int main(int argc, char *argv[]) {
+
+ initialize(argc, argv);
+ const ElementType element_type = _triangle_3;
+ const GhostType ghost_type = _not_ghost;
+ UInt spatial_dimension = 2;
+
+
+ StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+ Int psize = comm.getNbProc();
+ Int prank = comm.whoAmI();
+
+ /// read the mesh and partition it
+ Mesh mesh(spatial_dimension);
+
+ /* ------------------------------------------------------------------------ */
+ /* Parallel initialization */
+ /* ------------------------------------------------------------------------ */
+ DistributedSynchronizer * communicator = NULL;
+ if(prank == 0) {
+ /// creation mesh
+ mesh.read("triangle.msh");
+ MeshPartitionScotch * partition = new MeshPartitionScotch(mesh, spatial_dimension);
+ partition->partitionate(psize);
+ communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, partition);
+ delete partition;
+ } else {
+ communicator = DistributedSynchronizer::createDistributedSynchronizerMesh(mesh, NULL);
+ }
+
+ // DumperParaview mesh_dumper("mesh_dumper");
+ // mesh_dumper.registerMesh(mesh, spatial_dimension, _not_ghost);
+ // mesh_dumper.dump();
+
+ /// initialize the FEEngine and the dof_synchronizer
+ FEEngine *fem = new FEEngineTemplate<IntegratorGauss,ShapeLagrange,_ek_regular>(mesh, spatial_dimension, "my_fem");
+
+ DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
+ UInt nb_global_nodes = mesh.getNbGlobalNodes();
+
+ dof_synchronizer.initGlobalDOFEquationNumbers();
+
+ // construct an Akantu sparse matrix, build the profile and fill the matrix for the given mesh
+ UInt nb_element = mesh.getNbElement(element_type);
+ UInt nb_nodes_per_element = mesh.getNbNodesPerElement(element_type);
+ UInt nb_dofs_per_element = spatial_dimension * nb_nodes_per_element;
+ SparseMatrix K_akantu(nb_global_nodes * spatial_dimension, _unsymmetric);
+ K_akantu.buildProfile(mesh, dof_synchronizer, spatial_dimension);
+ /// use as elemental matrices a matrix with values equal to 1 every where
+ Matrix<Real> element_input(nb_dofs_per_element, nb_dofs_per_element, 1.);
+ Array<Real> K_e = Array<Real>(nb_element, nb_dofs_per_element * nb_dofs_per_element, "K_e");
+ Array<Real>::matrix_iterator K_e_it = K_e.begin(nb_dofs_per_element, nb_dofs_per_element);
+ Array<Real>::matrix_iterator K_e_end = K_e.end(nb_dofs_per_element, nb_dofs_per_element);
+
+ for(; K_e_it != K_e_end; ++K_e_it)
+ *K_e_it = element_input;
+
+ // assemble the test matrix
+ fem->assembleMatrix(K_e, K_akantu, spatial_dimension, element_type, ghost_type);
+
+ /// construct a PETSc matrix
+ PETScMatrix K_petsc(nb_global_nodes * spatial_dimension, _unsymmetric);
+ /// build the profile of the PETSc matrix for the mesh of this example
+ K_petsc.buildProfile(mesh, dof_synchronizer, spatial_dimension);
+ /// add an Akantu sparse matrix to a PETSc sparse matrix
+ K_petsc.add(K_akantu, 1);
+
+ /// check to how many elements each node is connected
+ CSR<Element> node_to_elem;
+
+ MeshUtils::buildNode2Elements(mesh, node_to_elem, spatial_dimension);
+
+ /// test the diagonal of the PETSc matrix: the diagonal entries
+ /// of the PETSc matrix correspond to the number of elements
+ /// connected to the node of the dof. Note: for an Akantu matrix this is only true for the serial case
+ Real error = 0.;
+ /// loop over all diagonal values of the matrix
+ for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
+ for (UInt j = 0; j < spatial_dimension; ++j) {
+ UInt dof = i * spatial_dimension + j;
+ /// for PETSc matrix only DOFs on the processor and be accessed
+ if (dof_synchronizer.isLocalOrMasterDOF(dof)) {
+ UInt global_dof = dof_synchronizer.getDOFGlobalID(dof);
+ std::cout << "Number of elements connected: " << node_to_elem.getNbCols(i) << std::endl;
+ std::cout << "K_petsc(" << global_dof << "," << global_dof << ")=" << K_petsc(dof,dof) << std::endl;
+ error += std::abs(K_petsc(dof, dof) - node_to_elem.getNbCols(i));
+ }
+ }
+ }
+
+ if(error > Math::getTolerance() ) {
+ std::cout << "error in the stiffness matrix!!!" << std::cout;
+ finalize();
+ return EXIT_FAILURE;
+ }
+
+ delete communicator;
+
+ finalize();
+
+ return EXIT_SUCCESS;
+
+}
diff --git a/test/test_solver/test_petsc_matrix_diagonal.sh b/test/test_solver/test_petsc_matrix_diagonal.sh
new file mode 100755
index 000000000..5f592e4b2
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_diagonal.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+mpirun -np 4 ./test_petsc_matrix_diagonal
diff --git a/test/test_solver/test_petsc_matrix_profile.cc b/test/test_solver/test_petsc_matrix_profile.cc
new file mode 100644
index 000000000..bff41dcfd
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_profile.cc
@@ -0,0 +1,131 @@
+/**
+ * @file test_petsc_matrix_profile.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Jul 30 12:34:08 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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.verified b/test/test_solver/test_petsc_matrix_profile.verified
new file mode 100644
index 000000000..4213dba00
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_profile.verified
@@ -0,0 +1,12 @@
+Matrix Object: 1 MPI processes
+ type: seqaij
+row 0: (0, 2) (1, 2) (2, 1) (3, 1) (6, 1) (7, 1) (8, 2) (9, 2)
+row 1: (0, 2) (1, 2) (2, 1) (3, 1) (6, 1) (7, 1) (8, 2) (9, 2)
+row 2: (0, 1) (1, 1) (2, 2) (3, 2) (4, 1) (5, 1) (8, 2) (9, 2)
+row 3: (0, 1) (1, 1) (2, 2) (3, 2) (4, 1) (5, 1) (8, 2) (9, 2)
+row 4: (2, 1) (3, 1) (4, 2) (5, 2) (6, 1) (7, 1) (8, 2) (9, 2)
+row 5: (2, 1) (3, 1) (4, 2) (5, 2) (6, 1) (7, 1) (8, 2) (9, 2)
+row 6: (0, 1) (1, 1) (4, 1) (5, 1) (6, 2) (7, 2) (8, 2) (9, 2)
+row 7: (0, 1) (1, 1) (4, 1) (5, 1) (6, 2) (7, 2) (8, 2) (9, 2)
+row 8: (0, 2) (1, 2) (2, 2) (3, 2) (4, 2) (5, 2) (6, 2) (7, 2) (8, 4) (9, 4)
+row 9: (0, 2) (1, 2) (2, 2) (3, 2) (4, 2) (5, 2) (6, 2) (7, 2) (8, 4) (9, 4)
diff --git a/test/test_solver/test_petsc_matrix_profile_parallel.cc b/test/test_solver/test_petsc_matrix_profile_parallel.cc
new file mode 100644
index 000000000..2ec40523c
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_profile_parallel.cc
@@ -0,0 +1,130 @@
+/**
+ * @file test_petsc_matrix_profile.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Wed Jul 30 12:34:08 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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_petsc_matrix_profile_parallel.sh b/test/test_solver/test_petsc_matrix_profile_parallel.sh
new file mode 100755
index 000000000..2dd775687
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_profile_parallel.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+mpirun -np 2 ./test_petsc_matrix_profile_parallel
diff --git a/test/test_solver/test_petsc_matrix_profile_parallel.verified b/test/test_solver/test_petsc_matrix_profile_parallel.verified
new file mode 100644
index 000000000..662687ada
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_profile_parallel.verified
@@ -0,0 +1,12 @@
+Matrix Object: 1 MPI processes
+ type: mpiaij
+row 0: (0, 2) (1, 2) (2, 1) (3, 1) (4, 1) (5, 1) (6, 2) (7, 2)
+row 1: (0, 2) (1, 2) (2, 1) (3, 1) (4, 1) (5, 1) (6, 2) (7, 2)
+row 2: (0, 1) (1, 1) (2, 2) (3, 2) (6, 2) (7, 2) (8, 1) (9, 1)
+row 3: (0, 1) (1, 1) (2, 2) (3, 2) (6, 2) (7, 2) (8, 1) (9, 1)
+row 4: (0, 1) (1, 1) (4, 2) (5, 2) (6, 2) (7, 2) (8, 1) (9, 1)
+row 5: (0, 1) (1, 1) (4, 2) (5, 2) (6, 2) (7, 2) (8, 1) (9, 1)
+row 6: (0, 2) (1, 2) (2, 2) (3, 2) (4, 2) (5, 2) (6, 4) (7, 4) (8, 2) (9, 2)
+row 7: (0, 2) (1, 2) (2, 2) (3, 2) (4, 2) (5, 2) (6, 4) (7, 4) (8, 2) (9, 2)
+row 8: (2, 1) (3, 1) (4, 1) (5, 1) (6, 2) (7, 2) (8, 2) (9, 2)
+row 9: (2, 1) (3, 1) (4, 1) (5, 1) (6, 2) (7, 2) (8, 2) (9, 2)
diff --git a/test/test_solver/test_solver_petsc.cc b/test/test_solver/test_solver_petsc.cc
new file mode 100644
index 000000000..2ad17899c
--- /dev/null
+++ b/test/test_solver/test_solver_petsc.cc
@@ -0,0 +1,162 @@
+/**
+ * @file test_solver_petsc.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Tue Dec 2 17:17:34 2014
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You 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
new file mode 100755
index 000000000..af7d892a6
--- /dev/null
+++ b/test/test_solver/test_solver_petsc.sh
@@ -0,0 +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
+
+
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_profile_parallel.cc b/test/test_solver/test_sparse_matrix_profile_parallel.cc
new file mode 100644
index 000000000..492735e37
--- /dev/null
+++ b/test/test_solver/test_sparse_matrix_profile_parallel.cc
@@ -0,0 +1,112 @@
+/**
+ * @file test_sparse_matrix_profile_parallel.cc
+ *
+ * @author Nicolas Richart <nicolas.richart@epfl.ch>
+ *
+ * @date Mon Feb 07 17:33:51 2011
+ *
+ * @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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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 7d3f3bb84..7d84dfc79 100644
--- a/test/test_static_memory/CMakeLists.txt
+++ b/test/test_static_memory/CMakeLists.txt
@@ -1,33 +1,33 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
#
# @date creation: Fri Sep 03 2010
# @date last modification: Tue Nov 06 2012
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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)
+register_test(test_static_memory SOURCES test_static_memory.cc PACKAGE core)
diff --git a/test/test_surface_extraction/CMakeLists.txt b/test/test_surface_extraction/CMakeLists.txt
deleted file mode 100644
index 0f26d6f24..000000000
--- a/test/test_surface_extraction/CMakeLists.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-#===============================================================================
-# @file CMakeLists.txt
-#
-# @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
-#
-# @date creation: Tue Oct 26 2010
-# @date last modification: Tue Nov 06 2012
-#
-# @brief configuration for surface extraction 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)
-#
-# Akantu is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option) any
-# later version.
-#
-# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# 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_surface_extraction_2d_mesh squares.geo 2 1)
-register_test(test_surface_extraction_triangle_3
- SOURCES test_surface_extraction_triangle_3.cc
- DEPENDENCIES test_surface_extraction_2d_mesh
- DIRECTORIES_TO_CREATE paraview
- )
-
-#===============================================================================
-add_mesh(test_surface_extraction_3d_mesh cubes.geo 3 1)
-register_test(test_surface_extraction_tetrahedron_4
- SOURCES test_surface_extraction_tetrahedron_4.cc
- DEPENDENCIES test_surface_extraction_3d_mesh
- DIRECTORIES_TO_CREATE paraview
-)
diff --git a/test/test_surface_extraction/cubes.geo b/test/test_surface_extraction/cubes.geo
deleted file mode 100644
index cdd2e3788..000000000
--- a/test/test_surface_extraction/cubes.geo
+++ /dev/null
@@ -1,74 +0,0 @@
-h = 1;
-
-Point(1) = {0, 0, 0, h};
-Point(2) = {1, 0, 0, h};
-Point(3) = {1, 1, 0, h};
-Point(4) = {0, 1, 0, h};
-Point(5) = {0, 0, 1, h};
-Point(6) = {1, 0, 1, h};
-Point(7) = {1, 1, 1, h};
-Point(8) = {0, 1, 1, h};
-
-Point(9) = {2+0, 0, 0, h};
-Point(10) = {2+1, 0, 0, h};
-Point(11) = {2+1, 1, 0, h};
-Point(12) = {2+0, 1, 0, h};
-Point(13) = {2+0, 0, 1, h};
-Point(14) = {2+1, 0, 1, h};
-Point(15) = {2+1, 1, 1, h};
-Point(16) = {2+0, 1, 1, h};
-
-Line(1) = {5, 6};
-Line(2) = {6, 7};
-Line(3) = {7, 8};
-Line(4) = {8, 5};
-Line(5) = {1, 2};
-Line(6) = {2, 3};
-Line(7) = {3, 4};
-Line(8) = {4, 1};
-Line(9) = {5, 1};
-Line(10) = {6, 2};
-Line(11) = {7, 3};
-Line(12) = {8, 4};
-Line(13) = {13, 14};
-Line(14) = {14, 15};
-Line(15) = {15, 16};
-Line(16) = {16, 13};
-Line(17) = {9, 10};
-Line(18) = {10, 11};
-Line(19) = {11, 12};
-Line(20) = {12, 9};
-Line(21) = {13, 9};
-Line(22) = {14, 10};
-Line(23) = {15, 11};
-Line(24) = {16, 12};
-
-
-Line Loop(25) = {4, 1, 2, 3};
-Plane Surface(26) = {25};
-Line Loop(27) = {7, 8, 5, 6};
-Plane Surface(28) = {27};
-Line Loop(29) = {12, -7, -11, 3};
-Plane Surface(30) = {29};
-Line Loop(31) = {12, 8, -9, -4};
-Plane Surface(32) = {31};
-Line Loop(33) = {1, 10, -5, -9};
-Plane Surface(34) = {33};
-Line Loop(35) = {2, 11, -6, -10};
-Plane Surface(36) = {35};
-Line Loop(37) = {16, 13, 14, 15};
-Plane Surface(38) = {37};
-Line Loop(39) = {20, 17, 18, 19};
-Plane Surface(40) = {39};
-Line Loop(41) = {24, 20, -21, -16};
-Plane Surface(42) = {41};
-Line Loop(43) = {13, 22, -17, -21};
-Plane Surface(44) = {43};
-Line Loop(45) = {14, 23, -18, -22};
-Plane Surface(46) = {45};
-Line Loop(47) = {15, 24, -19, -23};
-Plane Surface(48) = {47};
-Surface Loop(49) = {32, 30, 28, 34, 26, 36};
-Volume(50) = {49};
-Surface Loop(51) = {42, 48, 38, 44, 46, 40};
-Volume(52) = {51};
diff --git a/test/test_surface_extraction/squares.geo b/test/test_surface_extraction/squares.geo
deleted file mode 100644
index d2e389681..000000000
--- a/test/test_surface_extraction/squares.geo
+++ /dev/null
@@ -1,37 +0,0 @@
-// Element size
-h = 0.5;
-
-// Dimension of square
-L = 1;
-
-// ------------------------------------------
-// Geometry
-// ------------------------------------------
-
-// Points
-Point(1) = {0, 0, 0, h};
-Point(2) = {L, 0, 0, h};
-Point(3) = {L, L, 0, h};
-Point(4) = {0, L, 0, h};
-
-Point(5) = {1.5*L, 0, 0, h};
-Point(6) = {2.5*L, 0, 0, h};
-Point(7) = {2.5*L, L, 0, h};
-Point(8) = {1.5*L, L, 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};
-Line Loop(2) = {5, 6, 7, 8};
-Plane Surface(1) = {1};
-Plane Surface(2) = {2};
diff --git a/test/test_surface_extraction/test_surface_extraction_tetrahedron_4.cc b/test/test_surface_extraction/test_surface_extraction_tetrahedron_4.cc
deleted file mode 100644
index d667b447d..000000000
--- a/test/test_surface_extraction/test_surface_extraction_tetrahedron_4.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * @file test_surface_extraction_tetrahedron_4.cc
- *
- * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date creation: Tue Oct 26 2010
- * @date last modification: Thu Mar 27 2014
- *
- * @brief 3d surface extraction 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)
- *
- * Akantu is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option) any
- * later version.
- *
- * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should 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 "mesh_utils.hh"
-#include "solid_mechanics_model.hh"
-#include "material.hh"
-#include <cstdio>
-
-#ifdef AKANTU_USE_IOHELPER
-# include "io_helper.hh"
-
-#endif //AKANTU_USE_IOHELPER
-
-using namespace akantu;
-
-int main(int argc, char *argv[])
-{
- int dim = 3;
-
- akantu::initialize(argc, argv);
-
- Mesh mesh(dim);
- MeshIOMSH mesh_io;
- mesh_io.read("cubes.msh", mesh);
-
- MeshUtils::buildFacets(mesh);
-
- mesh.createBoundaryGroupFromGeometry();
-// MeshUtils::buildSurfaceID(mesh);
-
- unsigned int nb_nodes = mesh.getNbNodes();
-#ifdef AKANTU_USE_IOHELPER
- iohelper::DumperParaview dumper;
- dumper.setMode(iohelper::TEXT);
-
- dumper.setPoints(mesh.getNodes().storage(), dim, nb_nodes, "test-surface-extraction");
- dumper.setConnectivity((int*)mesh.getConnectivity(_tetrahedron_4).storage(),
- iohelper::TETRA1, mesh.getNbElement(_tetrahedron_4), iohelper::C_MODE);
- dumper.setPrefix("paraview/");
- dumper.init();
- dumper.dump();
-
- iohelper::DumperParaview dumper_surface;
- dumper_surface.setMode(iohelper::TEXT);
-
- dumper_surface.setPoints(mesh.getNodes().storage(), dim, nb_nodes, "test-surface-extraction_boundary");
-
- dumper_surface.setConnectivity((int *)mesh.getConnectivity(_triangle_3).storage(),
- iohelper::TRIANGLE1, mesh.getNbElement(_triangle_3), iohelper::C_MODE);
-
- UInt * surf_id = new UInt[mesh.getNbElement(_triangle_3)];
-
- for(Mesh::const_element_group_iterator it(mesh.element_group_begin());
- it != mesh.element_group_end(); ++it) {
- const Array<UInt> & element_ids = it->second->getElements(_triangle_3);
- for(UInt i(0); i << element_ids.getSize(); ++i) {
- UInt elem_idx = element_ids(i);
- surf_id[elem_idx] = atoi((it->first.c_str()));
- }
- }
-
-// for (UInt i = 0; i < mesh.getSurfaceID(_triangle_3).getSize(); ++i)
-// surf_id[i] = (double)mesh.getSurfaceID(_triangle_3).storage()[i];
-
- dumper_surface.addElemDataField("surface_id", surf_id, 1, mesh.getNbElement(_triangle_3));
- dumper_surface.setPrefix("paraview/");
- dumper_surface.init();
- dumper_surface.dump();
-
- delete [] surf_id;
-#endif //AKANTU_USE_IOHELPER
-
- finalize();
- return EXIT_SUCCESS;
-}
diff --git a/test/test_surface_extraction/test_surface_extraction_triangle_3.cc b/test/test_surface_extraction/test_surface_extraction_triangle_3.cc
deleted file mode 100644
index 2b7a57d8e..000000000
--- a/test/test_surface_extraction/test_surface_extraction_triangle_3.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * @file test_surface_extraction_triangle_3.cc
- *
- * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
- * @author Marco Vocialta <marco.vocialta@epfl.ch>
- *
- * @date creation: Tue Oct 26 2010
- * @date last modification: Thu Mar 27 2014
- *
- * @brief test for surface extractions
- *
- * @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 "mesh.hh"
-#include "mesh_io.hh"
-#include "mesh_io_msh.hh"
-#include "mesh_utils.hh"
-#include "solid_mechanics_model.hh"
-#include "material.hh"
-#include <cstdlib>
-
-#ifdef AKANTU_USE_IOHELPER
-# include "io_helper.hh"
-
-#endif //AKANTU_USE_IOHELPER
-
-using namespace akantu;
-
-int main(int argc, char *argv[])
-{
- int dim = 2;
-
- akantu::initialize(argc, argv);
-
- Mesh mesh(dim);
- MeshIOMSH mesh_io;
- mesh_io.read("squares.msh", mesh);
-
- MeshUtils::buildFacets(mesh);
- mesh.createBoundaryGroupFromGeometry();
-
- unsigned int nb_nodes = mesh.getNbNodes();
-#ifdef AKANTU_USE_IOHELPER
- iohelper::DumperParaview dumper;
- dumper.setMode(iohelper::TEXT);
-
- dumper.setPoints(mesh.getNodes().storage(), dim, nb_nodes, "test-surface-extraction");
- dumper.setConnectivity((int*)mesh.getConnectivity(_triangle_3).storage(),
- iohelper::TRIANGLE1, mesh.getNbElement(_triangle_3), iohelper::C_MODE);
- dumper.setPrefix("paraview/");
- dumper.init();
- dumper.dump();
-
- iohelper::DumperParaview dumper_surface;
- dumper_surface.setMode(iohelper::TEXT);
-
- dumper_surface.setPoints(mesh.getNodes().storage(), dim, nb_nodes, "test-surface-extraction_boundary");
-
- dumper_surface.setConnectivity((int *)mesh.getConnectivity(_segment_2).storage(),
- iohelper::LINE1, mesh.getNbElement(_segment_2), iohelper::C_MODE);
- UInt * surf_id = new UInt [mesh.getNbElement(_segment_2)];
-
- for(Mesh::const_element_group_iterator it(mesh.element_group_begin());
- it != mesh.element_group_end(); ++it) {
- const Array<UInt> & element_ids = it->second->getElements(_segment_2);
- for(UInt i(0); i << element_ids.getSize(); ++i) {
- UInt elem_idx = element_ids(i);
- surf_id[elem_idx] = atoi((it->first.c_str()));
- }
- }
- //for (UInt i = 0; i < mesh.getSurfaceID(_segment_2).getSize(); ++i)
- // surf_id[i] = (double)mesh.getSurfaceID(_segment_2).storage()[i];
-
- dumper_surface.addElemDataField("surface_id", surf_id, 1, mesh.getNbElement(_segment_2));
- dumper_surface.setPrefix("paraview/");
- dumper_surface.init();
- dumper_surface.dump();
-
- delete [] surf_id;
-#endif //AKANTU_USE_IOHELPER
-
- finalize();
- return EXIT_SUCCESS;
-}
diff --git a/test/test_synchronizer/CMakeLists.txt b/test/test_synchronizer/CMakeLists.txt
index 52a6c6b31..62bd1f74c 100644
--- a/test/test_synchronizer/CMakeLists.txt
+++ b/test/test_synchronizer/CMakeLists.txt
@@ -1,62 +1,70 @@
#===============================================================================
# @file CMakeLists.txt
#
# @author Nicolas Richart <nicolas.richart@epfl.ch>
#
# @date creation: Sun Sep 12 2010
# @date last modification: Fri Sep 05 2014
#
# @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)
#
# Akantu is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# 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)
target_link_libraries(test_grid_synchronizer_check_neighbors akantu)
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)
+ FILES_TO_COPY bar.msh
+ PACKAGE parallel
+ )
+
+register_test(test_dof_synchronizer_communication
+ SOURCES test_dof_synchronizer_communication.cc test_dof_data_accessor.hh
+ DEPENDS test_synchronizer_communication_mesh
+ PACKAGE parallel
+ )
register_test(test_data_distribution
SOURCES test_data_distribution.cc
FILES_TO_COPY data_split.msh
PACKAGE parallel
)
diff --git a/test/test_synchronizer/test_dof_data_accessor.hh b/test/test_synchronizer/test_dof_data_accessor.hh
new file mode 100644
index 000000000..9288d4360
--- /dev/null
+++ b/test/test_synchronizer/test_dof_data_accessor.hh
@@ -0,0 +1,115 @@
+/**
+ * @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
+ *
+ * @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 "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_communication.cc b/test/test_synchronizer/test_dof_synchronizer_communication.cc
new file mode 100644
index 000000000..b1eb23333
--- /dev/null
+++ b/test/test_synchronizer/test_dof_synchronizer_communication.cc
@@ -0,0 +1,100 @@
+/**
+ * @file test_dof_synchronizer_communication.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date Thu Nov 20 13:40:33 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)
+ *
+ * Akantu is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should 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_dof_synchronizer_communication.sh b/test/test_synchronizer/test_dof_synchronizer_communication.sh
new file mode 100755
index 000000000..962e73c1a
--- /dev/null
+++ b/test/test_synchronizer/test_dof_synchronizer_communication.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+mpirun -np 2 ./test_dof_synchronizer_communication
diff --git a/test/test_synchronizer/test_grid_synchronizer.cc b/test/test_synchronizer/test_grid_synchronizer.cc
index 8807881d1..5563f76ea 100644
--- a/test/test_synchronizer/test_grid_synchronizer.cc
+++ b/test/test_synchronizer/test_grid_synchronizer.cc
@@ -1,296 +1,297 @@
/**
* @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
*
* @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)
*
* Akantu is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should 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.2;
+ 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("bar3d.msh");
+ 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();
- AKANTU_DEBUG_INFO("Creating TestAccessor");
- TestAccessor test_accessor(mesh, barycenters);
- SynchronizerRegistry synch_registry(test_accessor);
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 64b4119f7..685623463 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
*
* @brief Test the generation of neighbors list based on a akaentu::Grid
*
* @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 <fstream>
#include <iostream>
#include <string>
#include "aka_common.hh"
#include "static_communicator.hh"
using namespace akantu;
-const UInt spatial_dimension = 2;
+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/third-party/MUMPS_4.10.0_make.inc.cmake b/third-party/MUMPS_4.10.0_make.inc.cmake
index 539c84cd8..a0fe5bd71 100644
--- a/third-party/MUMPS_4.10.0_make.inc.cmake
+++ b/third-party/MUMPS_4.10.0_make.inc.cmake
@@ -1,168 +1,84 @@
-#
-# 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@
-
-# PLAT : use it to add a default suffix to the generated libraries
-PLAT = @MUMPS_PREFIX@
+PLAT = @MUMPS_PREFIX@
LIBEXT = @CMAKE_STATIC_LIBRARY_SUFFIX@
SHLIBEXT = @CMAKE_SHARED_LIBRARY_SUFFIX@
OUTC = -o
OUTF = -o
-
-
-########################################################################
-#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 = @MUMPS_SCOTCH_LIBRARIES@
-
LPORDDIR = $(topdir)/PORD/lib/
IPORD = -I$(topdir)/PORD/include/
LPORD = -L$(LPORDDIR) -lpord$(PLAT)
-
-#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...
-
-# RM : remove files
-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
-# (optionnal use "RANLIB = echo" in case of problem)
-RANLIB = @CMAKE_RANLIB@
-
+RANLIB = '@CMAKE_RANLIB@'
# SCALAP should define the SCALAPACK and BLACS libraries.
-SCALAP = @SCALAPACK_LIBRARIES@
+SCALAP = '@SCALAPACK_LIBRARIES@'
-# INCLUDE DIRECTORY FOR MPI
INCPAR =
-
-# LIBRARIES USED BY THE PARALLEL VERSION OF MUMPS: $(SCALAP) and MPI
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)
-
-# DEFINE HERE YOUR BLAS LIBRARY
LIBBLAS = @MUMPS_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)
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/MUMPS_5.0.0.patch b/third-party/MUMPS_5.0.0.patch
new file mode 100644
index 000000000..52469cd54
--- /dev/null
+++ b/third-party/MUMPS_5.0.0.patch
@@ -0,0 +1,154 @@
+diff -Naur MUMPS_5.0.0/libseq/Makefile MUMPS_5.0.0.shared/libseq/Makefile
+--- MUMPS_5.0.0/libseq/Makefile 2015-02-20 09:20:00.000000000 +0100
++++ MUMPS_5.0.0.shared/libseq/Makefile 2015-03-06 14:23:37.293877000 +0100
+@@ -8,11 +8,15 @@
+
+ include ../Makefile.inc
+
+-libmpiseq: libmpiseq$(PLAT)$(LIBEXT)
++libmpiseq: libmpiseq$(PLAT)$(LIBEXT) libmpiseq$(PLAT)$(SHLIBEXT)
+
+ libmpiseq$(PLAT)$(LIBEXT): mpi.o mpic.o elapse.o
+ $(AR)$@ mpi.o mpic.o elapse.o
+ $(RANLIB) $@
++
++libmpiseq$(PLAT)$(SHLIBEXT): mpi.o mpic.o elapse.o
++ $(FC) -shared $^ -o libmpiseq$(PLAT)$(SHLIBEXT)
++
+ .f.o:
+ $(FC) $(OPTF) -c $*.f $(OUTF)$*.o
+ .c.o:
+diff -Naur MUMPS_5.0.0/Makefile MUMPS_5.0.0.shared/Makefile
+--- MUMPS_5.0.0/Makefile 2015-02-20 09:19:56.000000000 +0100
++++ MUMPS_5.0.0.shared/Makefile 2015-03-06 14:24:13.083854000 +0100
+@@ -2,14 +2,15 @@
+ # This file is part of MUMPS 5.0.0, released
+ # on Fri Feb 20 08:19:56 UTC 2015
+ #
+-topdir = .
+-libdir = $(topdir)/lib
++topdir = .
++libdir = $(topdir)/lib
++prefix ?= /usr/local
+
+ default: dexamples
+
+ .PHONY: default alllib all c z s d \
+ sexamples dexamples cexamples zexamples \
+- mumps_lib requiredobj libseqneeded clean
++ mumps_lib requiredobj libseqneeded install clean
+
+ alllib: c z s d
+ all: cexamples zexamples sexamples dexamples
+@@ -51,29 +52,46 @@
+ dexamples: d
+ (cd examples ; $(MAKE) d)
+
+-requiredobj: Makefile.inc $(LIBSEQNEEDED) $(libdir)/libpord$(PLAT)$(LIBEXT)
++requiredobj: Makefile.inc $(LIBSEQNEEDED) $(libdir)/libpord$(PLAT)$(LIBEXT) $(libdir)/libpord$(PLAT)$(SHLIBEXT)
+
+ # dummy MPI library (sequential version)
+
+ libseqneeded:
+ (cd libseq; $(MAKE))
++ cp libseq/lib* $(libdir)
+
+ # Build the libpord.a library and copy it into $(topdir)/lib
+ $(libdir)/libpord$(PLAT)$(LIBEXT):
+ if [ "$(LPORDDIR)" != "" ] ; then \
+ cd $(LPORDDIR); \
+- $(MAKE) CC="$(CC)" CFLAGS="$(OPTC)" AR="$(AR)" RANLIB="$(RANLIB)" OUTC="$(OUTC)" LIBEXT=$(LIBEXT); \
++ $(MAKE) CC="$(CC)" CFLAGS="$(OPTC)" AR="$(AR)" RANLIB="$(RANLIB)" OUTC="$(OUTC)" LIBEXT=$(LIBEXT) PLAT=$(PLAT) SHLIBEXT=$(SHLIBEXT); \
+ fi;
+ if [ "$(LPORDDIR)" != "" ] ; then \
+ cp $(LPORDDIR)/libpord$(LIBEXT) $@; \
+ fi;
+
++$(libdir)/libpord$(PLAT)$(SHLIBEXT):
++ if [ "$(LPORDDIR)" != "" ] ; then \
++ cd $(LPORDDIR); \
++ $(MAKE) CC="$(CC)" CFLAGS="$(OPTC)" AR="$(AR)" RANLIB="$(RANLIB)" OUTC="$(OUTC)" LIBEXT=$(LIBEXT) PLAT=$(PLAT) SHLIBEXT=$(SHLIBEXT) libpord$(PLAT)$(SHLIBEXT); \
++ fi;
++ if [ "$(LPORDDIR)" != "" ] ; then \
++ cp $(LPORDDIR)/libpord$(PLAT)$(SHLIBEXT) $@; \
++ fi;
++
++install: alllib
++ -$(MKDIR) $(prefix)/include/
++ -$(MKDIR) $(prefix)/lib/
++ -$(CP) include/* $(prefix)/include/
++ -$(CP) lib/* $(prefix)/lib/
++
+ clean:
+ (cd src; $(MAKE) clean)
+ (cd examples; $(MAKE) clean)
+- (cd $(libdir); $(RM) *$(PLAT)$(LIBEXT))
++ (cd $(libdir); $(RM) *$(PLAT)$(LIBEXT) *$(PLAT)$(SHLIBEXT))
+ (cd libseq; $(MAKE) clean)
+ if [ "$(LPORDDIR)" != "" ] ; then \
+ cd $(LPORDDIR); $(MAKE) realclean; \
++ cd $(LPORDDIR); $(MAKE) LIBEXT=$(LIBEXT) PLAT=$(PLAT) SHLIBEXT=$(SHLIBEXT) realclean; \
+ fi;
+
+diff -Naur MUMPS_5.0.0/PORD/lib/Makefile MUMPS_5.0.0.shared/PORD/lib/Makefile
+--- MUMPS_5.0.0/PORD/lib/Makefile 2015-02-20 09:19:56.000000000 +0100
++++ MUMPS_5.0.0.shared/PORD/lib/Makefile 2015-03-06 14:23:37.272190000 +0100
+@@ -13,7 +13,7 @@
+
+ OBJS = graph.o gbipart.o gbisect.o ddcreate.o ddbisect.o nestdiss.o \
+ multisector.o gelim.o bucket.o tree.o \
+- symbfac.o interface.o sort.o minpriority.o
++ symbfac.o interface.o sort.o minpriority.o
+
+ # Note: numfac.c read.c mapping.c triangular.c matrix.c kernel.c
+ # were not direcly used by MUMPS and have been removed from the
+@@ -24,12 +24,15 @@
+ .c.o:
+ $(CC) $(COPTIONS) -c $*.c $(OUTC)$*.o
+
+-libpord$(LIBEXT):$(OBJS)
++libpord$(PLAT)$(LIBEXT):$(OBJS)
+ $(AR)$@ $(OBJS)
+ $(RANLIB) $@
+
++libpord$(PLAT)$(SHLIBEXT): $(OBJS)
++ $(CC) -shared $(OBJS) -o libpord$(PLAT)$(SHLIBEXT)
++
+ clean:
+ rm -f *.o
+
+ realclean:
+- rm -f *.o libpord.a
++ rm -f *.o libpord$(PLAT)$(SHLIBEXT) libpord$(PLAT)$(LIBEXT)
+diff -Naur MUMPS_5.0.0/src/Makefile MUMPS_5.0.0.shared/src/Makefile
+--- MUMPS_5.0.0/src/Makefile 2015-02-20 09:19:56.000000000 +0100
++++ MUMPS_5.0.0.shared/src/Makefile 2015-03-06 14:24:22.568979000 +0100
+@@ -24,7 +24,10 @@
+ include $(topdir)/Makefile.inc
+
+ mumps_lib: $(libdir)/libmumps_common$(PLAT)$(LIBEXT) \
+- $(libdir)/lib$(ARITH)mumps$(PLAT)$(LIBEXT)
++ $(libdir)/libmumps_common$(PLAT)$(SHLIBEXT) \
++ $(libdir)/lib$(ARITH)mumps$(PLAT)$(LIBEXT) \
++ $(libdir)/lib$(ARITH)mumps$(PLAT)$(SHLIBEXT)
++
+
+ OBJS_COMMON_MOD = \
+ ana_omp_m.o\
+@@ -161,6 +164,16 @@
+ $(AR)$@ $?
+ $(RANLIB) $@
+
++$(libdir)/libmumps_common$(PLAT)$(SHLIBEXT): $(OBJS_COMMON_MOD) $(OBJS_COMMON_OTHER)
++ $(FC) -shared $^ -L$(libdir) $(LORDERINGS) $(LIBS) $(LIBBLAS) $(LIBOTHERS) -o $(libdir)/libmumps_common$(PLAT)$(SHLIBEXT)
++
++
++$(libdir)/lib$(ARITH)mumps$(PLAT)$(SHLIBEXT): $(OBJS_MOD) $(OBJS_OTHER)
++ $(FC) -shared $^ -L$(libdir) -lmumps_common$(PLAT) $(LORDERINGS) $(LIBS) $(LIBBLAS) $(LIBOTHERS) -o $(libdir)/lib$(ARITH)mumps$(PLAT)$(SHLIBEXT)
++
++
++
++
+ # Dependencies between modules:
+ $(ARITH)mumps_load.o: $(ARITH)mumps_comm_buffer.o \
+ $(ARITH)mumps_struc_def.o \
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
new file mode 100644
index 000000000..e37bcdaa6
--- /dev/null
+++ b/third-party/cmake/blackdynamite.cmake
@@ -0,0 +1,41 @@
+if(${PROJECT_SOURCE_DIR}/third-party/${BLACKDYNAMITE_ARCHIVE})
+ set(_blackdynamite_download_command
+ URL ${PROJECT_SOURCE_DIR}/third-party/${BLACKDYNAMITE_ARCHIVE})
+else()
+ set(_blackdynamite_download_command
+ GIT_REPOSITORY ${BLACKDYNAMITE_GIT}
+ GIT_TAG ${BLACKDYNAMITE_VERSION}
+ )
+endif()
+
+if(CMAKE_VERSION VERSION_GREATER 3.1)
+ set(_extra_options
+ UPDATE_DISCONNECTED 1
+ DOWNLOAD_NO_PROGRESS 1
+ EXCLUDE_FROM_ALL 1
+ )
+endif()
+
+ExternalProject_Add(blackdynamite
+ PREFIX ${PROJECT_BINARY_DIR}/third-party
+ ${_blackdynamite_download_command}
+ ${_extra_options}
+ CMAKE_ARGS <SOURCE_DIR>/
+ CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER}
+ BUILD_COMMAND make
+ INSTALL_COMMAND make install
+ LOG_DOWNLOAD 1
+ LOG_CONFIGURE 1
+ LOG_BUILD 1
+ LOG_INSTALL 1
+ )
+
+
+set_third_party_shared_libirary_name(BLACKDYNAMITE_LIBRARIES blackdynamite)
+set(BLACKDYNAMITE_INCLUDE_DIR "${PROJECT_BINARY_DIR}/third-party/include/blackdynamite" CACHE PATH "")
+mark_as_advanced(
+ BLACKDYNAMITE_LIBRARIES
+ BLACKDYNAMITE_INCLUDE_DIR
+ )
+
+package_add_extra_dependency(BlackDynamite blackdynamite)
diff --git a/third-party/cmake/blas.cmake b/third-party/cmake/blas.cmake
new file mode 100644
index 000000000..62288c4f3
--- /dev/null
+++ b/third-party/cmake/blas.cmake
@@ -0,0 +1,24 @@
+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
new file mode 100644
index 000000000..507973371
--- /dev/null
+++ b/third-party/cmake/iohelper.cmake
@@ -0,0 +1,45 @@
+if(NOT EXISTS ${PROJECT_SOURCE_DIR}/third-party/${IOHELPER_ARCHIVE})
+ set(_iohelper_download_command
+ GIT_REPOSITORY ${IOHELPER_GIT}
+ GIT_TAG ${IOHELPER_VERSION}
+ )
+else()
+ set(_iohelper_download_command
+ URL ${PROJECT_SOURCE_DIR}/third-party/${IOHELPER_ARCHIVE}
+ )
+endif()
+
+if(CMAKE_VERSION VERSION_GREATER 3.1)
+ set(_extra_options
+ UPDATE_DISCONNECTED 1
+ DOWNLOAD_NO_PROGRESS 1
+ EXCLUDE_FROM_ALL 1
+ )
+endif()
+
+ExternalProject_Add(iohelper
+ PREFIX ${PROJECT_BINARY_DIR}/third-party
+ ${_iohelper_download_command}
+ ${_extra_options}
+ CMAKE_ARGS <SOURCE_DIR>/
+ CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER}
+ LOG_DOWNLOAD 1
+ LOG_CONFIGURE 1
+ LOG_BUILD 1
+ LOG_INSTALL 1
+ )
+
+set_third_party_shared_libirary_name(IOHELPER_LIBRARIES iohelper)
+if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ set(_tmp ${IOHELPER_LIBRARIES})
+ set(IOHELPER_LIBRARIES "${_tmp}.a" CACHE FILEPATH "" FORCE)
+endif()
+
+set(IOHELPER_INCLUDE_DIR "${PROJECT_BINARY_DIR}/third-party/include/iohelper" CACHE PATH "IOHelper include directory")
+
+mark_as_advanced(
+ IOHELPER_LIBRARIES
+ IOHELPER_INCLUDE_DIR
+ )
+
+package_add_extra_dependency(IOHelper iohelper)
diff --git a/third-party/cmake/mumps.cmake b/third-party/cmake/mumps.cmake
new file mode 100644
index 000000000..2153aa534
--- /dev/null
+++ b/third-party/cmake/mumps.cmake
@@ -0,0 +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
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Akantu. If not, see <http://www.gnu.org/licenses/>.
+#
+#===============================================================================
+
+enable_language(Fortran)
+
+set(MUMPS_VERSION ${AKANTU_USE_MUMPS_VERSION})
+set(MUMPS_ARCHIVE "${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}.tar.gz")
+set(MUMPS_ARCHIVE_HASH_4.9.2 "MD5=d0b8f139a4acf29b76dbae69ade8ac54")
+set(MUMPS_ARCHIVE_HASH_4.10.0 "MD5=959e9981b606cd574f713b8422ef0d9f")
+set(MUMPS_ARCHIVE_HASH_5.0.0 "MD5=3c6aeab847e9d775ca160194a9db2b75")
+
+if(NOT EXISTS ${MUMPS_ARCHIVE})
+ message(FATAL_ERROR "To be able to compile MUMPS please download it from "
+ "http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS and place it "
+ "in the directory: ${PROJECT_SOURCE_DIR}/third-party and in cmake set the "
+ "variable AKANTU_MUMPS_VERSION to the corresponding version "
+ "\n"
+ "Supported version for automated compilation in Akantu are 4.9.2, 4.10.0 "
+ "and 5.0.0")
+endif()
+
+package_get_option_name(MPI _mpi_option)
+if(${_mpi_option})
+ unset(MUMPS_PREFIX)
+else()
+ set(MUMPS_PREFIX _seq)
+endif()
+
+package_use_system(Scotch _scotch_use_system)
+if(NOT _scotch_use_system)
+ list(APPEND MUMPS_DEPENDS Scotch)
+endif()
+
+package_get_option_name(ScaLAPACK _scalapack_option)
+package_use_system(ScaLAPACK _scalapack_use_system)
+if(NOT _scalapack_use_system AND ${_scalapack_option})
+ list(APPEND MUMPS_DEPENDS ScaLAPACK)
+endif()
+
+include(AkantuMacros)
+
+package_get_libraries(Scotch _scotch_libraries)
+string(REPLACE ";" " " MUMPS_SCOTCH_LIBRARIES
+ "${_scotch_libraries};${SCOTCH_LIBRARY_ESMUMPS}")
+
+package_get_libraries(BLAS _blas_libraries)
+foreach(_blas_lib ${_blas_libraries})
+ if("${_blas_lib}" MATCHES ".*\\.framework")
+ get_filename_component(_blas_framework "${_blas_lib}" NAME_WE)
+ set(MUMPS_BLAS_LIBRARIES "${MUMPS_BLAS_LIBRARIES} -framework ${_blas_framework}")
+ else()
+ set(MUMPS_BLAS_LIBRARIES "${MUMPS_BLAS_LIBRARIES} ${_blas_lib}")
+ endif()
+endforeach()
+
+if("${MUMPS_TYPE}" STREQUAL "seq")
+ set_third_party_shared_libirary_name(MUMPS_LIBRARY_MPI mpiseq${MUMPS_PREFIX})
+ mark_as_advanced(MUMPS_LIBRARY_MPI)
+else()
+ set(MUMPS_LIBRARY_MPI "")
+endif()
+
+if(CMAKE_C_COMPILER_ID STREQUAL "Intel")
+ set(MUMPS_EXTRA_Fortran_FLAGS "-nofor_main")
+else()
+ set(MUMPS_EXTRA_Fortran_FLAGS "")
+endif()
+
+if(CMAKE_VERSION VERSION_GREATER 3.1)
+ set(_extra_options
+ DOWNLOAD_NO_PROGRESS 1
+ EXCLUDE_FROM_ALL 1
+ )
+endif()
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ set(AKANTU_MUMPS_CDEFS "-DAdd_ -DWITHOUT_PTHREAD")
+else()
+ set(AKANTU_MUMPS_CDEFS "-DAdd_")
+ set(AKANTU_MUMPS_PTHREAD "-lpthread")
+endif()
+
+configure_file(${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}_make.inc.cmake
+ ${PROJECT_BINARY_DIR}/third-party/MUMPS_make.inc @ONLY)
+
+ExternalProject_Add(MUMPS
+ DEPENDS ${MUMPS_DEPENDS}
+ PREFIX ${PROJECT_BINARY_DIR}/third-party
+ URL ${MUMPS_ARCHIVE}
+ URL_HASH ${MUMPS_ARCHIVE_HASH_${MUMPS_VERSION}}
+ ${_extra_options}
+ BUILD_IN_SOURCE 1
+ PATCH_COMMAND ${PATCH_COMMAND} -p2 < ${PROJECT_SOURCE_DIR}/third-party/MUMPS_${MUMPS_VERSION}.patch
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/third-party/MUMPS_make.inc Makefile.inc
+ BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} d
+ INSTALL_COMMAND "${CMAKE_MAKE_PROGRAM}" prefix=<INSTALL_DIR> install
+ LOG_DOWNLOAD 1
+ LOG_CONFIGURE 1
+ LOG_BUILD 1
+ LOG_INSTALL 1
+ )
+
+set_third_party_shared_libirary_name(MUMPS_LIBRARY_DMUMPS dmumps${MUMPS_PREFIX})
+set_third_party_shared_libirary_name(MUMPS_LIBRARY_COMMON mumps_common${MUMPS_PREFIX})
+set_third_party_shared_libirary_name(MUMPS_LIBRARY_PORD pord${MUMPS_PREFIX})
+
+mark_as_advanced(
+ MUMPS_LIBRARY_COMMON
+ MUMPS_LIBRARY_DMUMPS
+ MUMPS_LIBRARY_PORD
+ MUMPS_LIBRARY_MPI
+ MUMPS_INCLUDE_DIR
+ )
+
+set(MUMPS_LIBRARIES_ALL
+ ${MPI_Fortran_LIBRARIES}
+ ${MUMPS_LIBRARY_COMMON}
+ ${MUMPS_LIBRARY_DMUMPS}
+ ${MUMPS_LIBRARY_PORD}
+ ${MUMPS_LIBRARY_MPI})
+
+set(MUMPS_INCLUDE_DIR ${PROJECT_BINARY_DIR}/third-party/include CACHE PATH "" FORCE)
+set(MUMPS_LIBRARIES ${MUMPS_LIBRARIES_ALL} CACHE INTERNAL "Libraries for MUMPS" FORCE)
+
+package_add_extra_dependency(Mumps MUMPS)
diff --git a/third-party/cmake/scalapack.cmake b/third-party/cmake/scalapack.cmake
new file mode 100644
index 000000000..0ad66a21f
--- /dev/null
+++ b/third-party/cmake/scalapack.cmake
@@ -0,0 +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
+#
+# @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)
+#
+# Akantu is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# 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
new file mode 100644
index 000000000..31e9ddc1e
--- /dev/null
+++ b/third-party/cmake/scotch.cmake
@@ -0,0 +1,98 @@
+if(TARGET Scotch)
+ return()
+endif()
+
+if(NOT EXISTS ${PROJECT_SOURCE_DIR}/third-party/${SCOTCH_ARCHIVE})
+ set(_scotch_download_command
+ URL ${SCOTCH_URL}
+# URL_HASH ${SCOTCH_ARCHIVE_HASH}
+ TLS_VERIFY FALSE
+ )
+else()
+ set(_scotch_download_command
+ URL ${PROJECT_SOURCE_DIR}/third-party/${SCOTCH_ARCHIVE}
+ URL_HASH ${SCOTCH_ARCHIVE_HASH})
+endif()
+
+if(CMAKE_VERSION VERSION_GREATER 3.1)
+ set(_extra_options
+ DOWNLOAD_NO_PROGRESS 1
+ EXCLUDE_FROM_ALL 1
+ )
+endif()
+
+find_package(BISON REQUIRED)
+find_package(FLEX REQUIRED)
+find_package(ZLIB)
+
+#if(ZLIB_FOUND)
+# set(_zlib_cflags "-DCOMMON_FILE_COMPRESS_GZ -I${ZLIB_INCLUDE_DIR}")
+# set(_zlib_ldflags "${ZLIB_LIBRARY}")
+#endif()
+
+if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ if (AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
+ set(_timing_cflags -DCOMMON_TIMING_OLD)
+ endif()
+ set(_system_cflags "-DCOMMON_PTHREAD -DSCOTCH_PTHREAD ${_timing_cflags}")
+ set(_system_ldflags "-lpthread")
+else()
+ set(_system_cflags "-DCOMMON_RANDOM_RAND -DCOMMON_WINDOWS -DCOMMON_STUB_FORK -D'pipe(pfds)=_pipe(pfds,1024,0x8000)'")
+endif()
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(_architecture_cflags -DIDXSIZE64)
+endif()
+
+math(EXPR _n "${AKANTU_INTEGER_SIZE} * 8")
+if(NOT _n EQUAL 32)
+ set(_num_size_cflags "-DINTSIZE${_n}")
+endif()
+
+if(HAVE_STDINT_H)
+ set(_stdint -DHAVE_STDINT_H)
+endif()
+
+set(AKANTU_SCOTCH_CFLAGS "-O3 -w -fPIC -Drestrict=__restrict -DCOMMON_RANDOM_FIXED_SEED -DSCOTCH_RENAME -DSCOTCH_RENAME_PARSER ${_zlib_cflags} ${_system_cflags} ${_architecture_cflags} ${_num_size_cflags} ${_stdint}")
+set(AKANTU_SCOTCH_LDFLAGS "${_zlib_ldflags} ${_system_ldflags} -lm")
+
+set(SCOTCH_DIR ${PROJECT_BINARY_DIR}/third-party)
+configure_file(
+ ${PROJECT_SOURCE_DIR}/third-party/scotch_${SCOTCH_VERSION}_make.inc.cmake
+ ${SCOTCH_DIR}/scotch_make.inc)
+
+include(ExternalProject)
+
+ExternalProject_Add(Scotch
+ PREFIX ${SCOTCH_DIR}
+ ${_scotch_download_command}
+ ${_extra_options}
+ PATCH_COMMAND ${PATCH_COMMAND} -p1 < ${PROJECT_SOURCE_DIR}/third-party/scotch_${SCOTCH_VERSION}.patch
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy ${SCOTCH_DIR}/scotch_make.inc src/Makefile.inc
+ BUILD_IN_SOURCE 1
+ BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} -C src
+ INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} prefix=<INSTALL_DIR> -C src install
+ LOG_DOWNLOAD 1
+ LOG_CONFIGURE 1
+ LOG_BUILD 1
+ LOG_INSTALL 1
+ )
+
+set_third_party_shared_libirary_name(SCOTCH_LIBRARY scotch)
+set_third_party_shared_libirary_name(SCOTCH_LIBRARY_ERR scotcherr)
+set_third_party_shared_libirary_name(SCOTCH_LIBRARY_ERREXIT scotcherrexit)
+set_third_party_shared_libirary_name(SCOTCH_LIBRARY_ESMUMPS esmumps)
+
+set(SCOTCH_INCLUDE_DIR ${SCOTCH_DIR}/include CACHE PATH "" FORCE)
+
+mark_as_advanced(
+ SCOTCH_LIBRARY
+ SCOTCH_LIBRARY_ERR
+ SCOTCH_LIBRARY_ERREXIT
+ SCOTCH_LIBRARY_ESMUMPS
+ SCOTCH_INCLUDE_DIR)
+
+set(SCOTCH_LIBRARIES_ALL ${SCOTCH_LIBRARY} ${SCOTCH_LIBRARY_ERR})
+set(SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES_ALL} CACHE INTERNAL "Libraries for scotch" FORCE)
+
+package_add_extra_dependency(Scotch Scotch)
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 fae13b448..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@
+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