diff --git a/cmake/akantu_test_driver.sh b/cmake/akantu_test_driver.sh index 939ea448b..9bc6e86b4 100755 --- a/cmake/akantu_test_driver.sh +++ b/cmake/akantu_test_driver.sh @@ -1,110 +1,111 @@ #!/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 -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= while getopts ":n: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" ;; 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 [ -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/doc/manual/CMakeLists.txt b/doc/manual/CMakeLists.txt index a169945f5..5348490e2 100644 --- a/doc/manual/CMakeLists.txt +++ b/doc/manual/CMakeLists.txt @@ -1,154 +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_name label) string(REPLACE "_" "-" _pkg_tex_label_dash ${pkg_name}) string(TOLOWER "${_pkg_tex_label_dash}" _pkg_tex_label) set(TOLOWER "${_pkg_tex_label_dash}" _pkg_tex_label) set(${label} "pkg:${_pkg_tex_label}" PARENT_SCOPE) endfunction() function(get_doc_package_name pkg_name pkg_tex) _package_get_option_name(${pkg_name} _opt_name) string(REPLACE "_" "\\_" _pkg_tex "${_opt_name}") set(${pkg_tex} ${_pkg_tex} PARENT_SCOPE) endfunction() #------------------------------------------------------------------------------# function(generate_package_dependency_tex_doc pkg_name FILENAME LEVEL) _package_get_option_name(${pkg_name} _opt_name) string(REPLACE "_" "\\_" _pkg_tex "${_opt_name}") get_doc_label(${pkg_name} _pkg_tex_label) file(APPEND ${FILENAME} "\\AkantuPackageNameWithLabel{${_pkg_tex}}{${_pkg_tex_label}}{${LEVEL}}\\xspace") math(EXPR _sub_level "${LEVEL}+1") _package_get_dependencies(${pkg_name} _dependencies) foreach(_dep_pkg_name ${_dependencies}) generate_package_dependency_tex_doc(${_dep_pkg_name} ${FILENAME} ${_sub_level}) endforeach() endfunction() #------------------------------------------------------------------------------# function(generate_package_tex_doc pkg_name FILENAME) get_doc_package_name(${pkg_name} _pkg_tex) get_doc_label(${pkg_name} _pkg_tex_label) file(APPEND ${FILENAME} "\n\\begin{AkantuPackage}{${_pkg_tex}}{${_pkg_tex_label}}") _package_get_documentation(${pkg_name} _doc) if (_doc) file(APPEND ${FILENAME} "${_doc}") else() _package_get_filename(${pkg_name} _file_path) _package_get_real_name(${pkg_name} _pkg) get_filename_component(_file ${_file_path} NAME) + string(REPLACE "_" "\\_" _escaped_file "${_file}") string(REPLACE "_" "\\_" _escaped_pkg "${_pkg}") set(_missing_doc - "{\\color{red} TODO}: No Documentation in {\\color{blue} \\href{${_file_path}}{${_file}}}" + "{\\color{red} TODO}: No Documentation in {\\color{blue} \\href{${_file_path}}{${_escaped_file}}}" "" "looking for the sequence: " "\\begin{cmake}" "\\package_declare_documentation(" " ${_escaped_pkg}" " \"documentation text\"" " )" "\\end{cmake}") set(_missing_doc_str "") foreach(_str ${_missing_doc}) set(_missing_doc_str "${_missing_doc_str}\n${_str}") endforeach() file(APPEND ${FILENAME} "${_missing_doc_str}") endif() _package_get_dependencies(${pkg_name} _dependencies) if(_dependencies) file(APPEND ${FILENAME} "\n\\begin{AkantuPackageDependencies}") foreach(_dep_pkg_name ${_dependencies}) generate_package_dependency_tex_doc(${_dep_pkg_name} ${FILENAME} 1) endforeach() file(APPEND ${FILENAME} "\n\\end{AkantuPackageDependencies}") endif() file(APPEND ${FILENAME} "\n\\end{AkantuPackage} ") endfunction() #------------------------------------------------------------------------------# #------------------------------------------------------------------------------# set(DOC_DEPS_TEX_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/manual-packages-doc.tex") file(WRITE ${DOC_DEPS_TEX_FILENAME} "") find_program(RUBBER_EXECUTABLE rubber) if (NOT RUBBER_EXECUTABLE) message(ERROR "Manual cannot be built without rubber latex compiler") endif() mark_as_advanced(RUBBER_EXECUTABLE) package_get_all_documentation_files(_manual_files) set(AKANTU_MANUAL_FILES_DEPEND) set(AKANTU_MANUAL_FILES_COPY_COMMAND) foreach(_f ${_manual_files}) file(RELATIVE_PATH _rel_f ${CMAKE_CURRENT_SOURCE_DIR} "${_f}") list(APPEND AKANTU_MANUAL_FILES_DEPEND ${_f}) list(APPEND AKANTU_MANUAL_FILES_COPY_COMMAND COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${_rel_f} ${_rel_f}) endforeach() set(MANUAL_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/manual.pdf) add_custom_command( OUTPUT ${MANUAL_OUTPUT} DEPENDS ${AKANTU_MANUAL_FILES_DEPEND} ${DOC_DEPS_TEX_FILENAME} ${AKANTU_MANUAL_FILES_COPY_COMMAND} COMMAND ${RUBBER_EXECUTABLE} -dfq -Wall manual WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Compiling the user's manual" ) add_custom_target(manual ALL DEPENDS ${MANUAL_OUTPUT}) install(FILES ${MANUAL_OUTPUT} DESTINATION share/akantu/doc) package_get_all_activated_packages(_package_list) foreach (_pkg_name ${_package_list}) generate_package_tex_doc(${_pkg_name} ${DOC_DEPS_TEX_FILENAME}) endforeach() configure_file(version-definition.tex.in "${CMAKE_CURRENT_BINARY_DIR}/version-definition.tex" @ONLY) \ No newline at end of file diff --git a/doc/manual/manual-appendix-elements.tex b/doc/manual/manual-appendix-elements.tex index 65a2f356f..1bfd5b593 100644 --- a/doc/manual/manual-appendix-elements.tex +++ b/doc/manual/manual-appendix-elements.tex @@ -1,608 +1,608 @@ \chapter{Shape Functions\index{Elements}} \label{app:elements} -Schmatic overview of all the element types defined in \akantu is described in Chapter~\ref{chap:elements}. In this appendix, more detailed information (shape function, location of Gaussian quadrature points, and so on) of each of these types is listed. For each element type, the coordinates of the nodes are given in the isoparametric frame of reference, together with the shape functions (and their derivatives) on these respective nodes. Also all the Gaussian quadrature points within each element are assigned (together with the weight that is applied on these points). The graphical representations of all the element types can be found in Chapter~\ref{chap:elements}. +Schmatic overview of all the element types defined in \akantu is described in Section~\ref{sec:elements}. In this appendix, more detailed information (shape function, location of Gaussian quadrature points, and so on) of each of these types is listed. For each element type, the coordinates of the nodes are given in the isoparametric frame of reference, together with the shape functions (and their derivatives) on these respective nodes. Also all the Gaussian quadrature points within each element are assigned (together with the weight that is applied on these points). The graphical representations of all the element types can be found in Section~\ref{sec:elements}. %%%%%%%%%% 1D %%%%%%%%% %\section{Isoparametric Elements in 1D\index{Elements!1D}} \section{1D-Shape Functions\index{Elements!1D}} \subsection{Segment 2\index{Elements!1D!Segment 2}} \begin{Element}{1D} 1 & \inelemone{-1} & $\half\left(1-\xi\right)$ & \inelemone{-\half} \\ \elemline 2 & \inelemone{1} & $\half\left(1+\xi\right)$ & \inelemone{\half} \\ \end{Element} \begin{QuadPoints}{lc} Coord. \elemcooroned & 0 \\ \elemline Weight & 2 \\ \end{QuadPoints} \subsection{Segment 3\index{Elements!1D!Segment 3}} \begin{Element}{1D} 1 & \inelemone{-1} & $\half\xi\left(\xi-1\right)$ & \inelemone{\xi-\half} \\ \elemline 2 & \inelemone{1} & $\half\xi\left(\xi+1\right)$ & \inelemone{\xi+\half} \\ \elemline 3 & \inelemone{0} & $1-\xi^{2}$ & \inelemone{-2\xi} \\ \end{Element} \begin{QuadPoints}{lcc} Coord. \elemcooroned & $-1/\sqrt{3}$ & $1/\sqrt{3}$ \\ \elemline Weight & 1 & 1 \\ \end{QuadPoints} %%%%%%%%%% 2D %%%%%%%%% %\section{Isoparametric Elements in 2D\index{Elements!2D}} \section{2D-Shape Functions\index{Elements!2D}} \subsection{Triangle 3\index{Elements!2D!Triangle 3}} \begin{Element}{2D} 1 & \inelemtwo{0}{0} & $1-\xi-\eta$ & \inelemtwo{-1}{-1} \\ \elemline 2 & \inelemtwo{1}{0} & $\xi$ & \inelemtwo{1}{0} \\ \elemline 3 & \inelemtwo{0}{1} & $\eta$ & \inelemtwo{0}{1} \\ \end{Element} \begin{QuadPoints}{lc} Coord. \elemcoortwod & \inquadtwo{\third}{\third} \\ \elemline Weight & 1 \\ \end{QuadPoints} \subsection{Triangle 6\index{Elements!2D!Triangle 6}} \begin{Element}{2D} 1 & \inelemtwo{0}{0} & $-\left(1-\xi-\eta\right)\left(1-2\left(1-\xi-\eta\right)\right)$ & \inelemtwo{1-4\left(1-\xi-\eta\right)}{1-4\left(1-\xi-\eta\right)} \\ \elemline 2 & \inelemtwo{1}{0} & $-\xi\left(1-2\xi\right)$ & \inelemtwo{4\xi-1}{0} \\ \elemline 3 & \inelemtwo{0}{1} & $-\eta\left(1-2\eta\right)$ & \inelemtwo{0}{4\eta-1} \\ \elemline 4 & \inelemtwo{\half}{0} & $4\xi\left(1-\xi-\eta\right)$ & \inelemtwo{4\left(1-2\xi-\eta\right)}{-4\xi} \\ \elemline 5 & \inelemtwo{\half}{\half} & $4\xi\eta$ & \inelemtwo{4\eta}{4\xi} \\ \elemline 6 & \inelemtwo{0}{\half} & $4\eta\left(1-\xi-\eta\right)$ & \inelemtwo{-4\eta}{4\left(1-\xi-2\eta\right)} \\ \elemline \end{Element} \begin{QuadPoints}{lccc} Coord. \elemcoortwod & \inquadtwo{\sixth}{\sixth} & \inquadtwo{\twothird}{\sixth} & \inquadtwo{\sixth}{\twothird} \\ \elemline Weight & \sixth & \sixth & \sixth \\ \end{QuadPoints} \clearpage \subsection{Quadrangle 4\index{Elements!2D!Quadrangle 4}} \begin{Element}{2D} 1 & \inelemtwo{-1}{-1} & $\quart\left(1-\xi\right)\left(1-\eta\right)$ & \inelemtwo{-\quart\left(1-\eta\right)}{-\quart\left(1-\xi\right)} \\ \elemline 2 & \inelemtwo{1}{-1} & $\quart\left(1+\xi\right)\left(1-\eta\right)$ & \inelemtwo{\quart\left(1-\eta\right)}{-\quart\left(1+\xi\right)} \\ \elemline 3 & \inelemtwo{1}{1} & $\quart\left(1+\xi\right)\left(1+\eta\right)$ & \inelemtwo{\quart\left(1+\eta\right)}{\quart\left(1+\xi\right)} \\ \elemline 4 & \inelemtwo{-1}{1} & $\quart\left(1-\xi\right)\left(1+\eta\right)$ & \inelemtwo{-\quart\left(1+\eta\right)}{\quart\left(1-\xi\right)} \\ \end{Element} \begin{QuadPoints}{lcccc} \elemcoortwod & \inquadtwo{-\invsqrtthree}{-\invsqrtthree} & \inquadtwo{\invsqrtthree}{-\invsqrtthree} & \inquadtwo{\invsqrtthree}{\invsqrtthree} & \inquadtwo{-\invsqrtthree}{\invsqrtthree} \\ \elemline Weight & 1 & 1 & 1 & 1 \\ \end{QuadPoints} \subsection{Quadrangle 8\index{Elements!2D!Quadrangle 8}} \begin{Element}{2D} 1 & \inelemtwo{-1}{-1} & $\quart\left(1-\xi\right)\left(1-\eta\right)\left(-1-\xi-\eta\right)$ & \inelemtwo{\quart\left(1-\eta\right)\left(2\xi+\eta\right)} {\quart\left(1-\xi\right)\left(\xi+2\eta\right)} \\ \elemline 2 & \inelemtwo{1}{-1} & $\quart\left(1+\xi\right)\left(1-\eta\right)\left(-1+\xi-\eta\right)$ & \inelemtwo{\quart\left(1-\eta\right)\left(2\xi-\eta\right)} {-\quart\left(1+\xi\right)\left(\xi-2\eta\right)} \\ \elemline 3 & \inelemtwo{1}{1} & $\quart\left(1+\xi\right)\left(1+\eta\right)\left(-1+\xi+\eta\right)$ & \inelemtwo{\quart\left(1+\eta\right)\left(2\xi+\eta\right)} {\quart\left(1+\xi\right)\left(\xi+2\eta\right)} \\ \elemline 4 & \inelemtwo{-1}{1} & $\quart\left(1-\xi\right)\left(1+\eta\right)\left(-1-\xi+\eta\right)$ & \inelemtwo{\quart\left(1+\eta\right)\left(2\xi-\eta\right)} {-\quart\left(1-\xi\right)\left(\xi-2\eta\right)} \\ \elemline 5 & \inelemtwo{0}{-1} & $\half\left(1-\xi^{2}\right)\left(1-\eta\right)$ & \inelemtwo{-\xi\left(1-\eta\right)} {-\half\left(1-\xi^{2}\right)} \\ \elemline 6 & \inelemtwo{1}{0} & $\half\left(1+\xi\right)\left(1-\eta^{2}\right)$ & \inelemtwo{\half\left(1-\eta^{2}\right)} {-\eta\left(1+\xi\right)} \\ \elemline 7 & \inelemtwo{0}{1} & $\half\left(1-\xi^{2}\right)\left(1+\eta\right)$ & \inelemtwo{-\xi\left(1+\eta\right)} {\half\left(1-\xi^{2}\right)} \\ \elemline 8 & \inelemtwo{-1}{0} & $\half\left(1-\xi\right)\left(1-\eta^{2}\right)$ & \inelemtwo{-\half\left(1-\eta^{2}\right)} {-\eta\left(1-\xi\right)} \\ \end{Element} \begin{QuadPoints}{lccccc} Coord. \elemcoortwod & \inquadtwo{0}{0} & \inquadtwo{\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}} & \inquadtwo{-\sqrt{\tfrac{3}{5}}}{\sqrt{\tfrac{3}{5}}} & \inquadtwo{-\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} & \inquadtwo{\sqrt{\tfrac{3}{5}}}{-\sqrt{\tfrac{3}{5}}} \\ \elemline Weight & 64/81 & 25/81 & 25/81 & 25/81 & 25/81 \\ \elemline Coord. \elemcoortwod & \inquadtwo{0}{\sqrt{\tfrac{3}{5}}} & \inquadtwo{-\sqrt{\tfrac{3}{5}}}{0} & \inquadtwo{0}{-\sqrt{\tfrac{3}{5}}} & \inquadtwo{\sqrt{\tfrac{3}{5}}}{0} & \\ \elemline Weight & 40/81 & 40/81 & 40/81 & 40/81 & \\ \end{QuadPoints} \clearpage %%%%%%%%%% 3D %%%%%%%%% \section{3D-Shape Functions\index{Elements!3D}} %\section{Isoparametric Elements in 3D\index{Elements!3D}} \subsection{Tetrahedron 4\index{Elements!3D!Tetrahedron 4}} \begin{Element}{3D} 1 & \inelemthree{0}{0}{0} & $1-\xi-\eta-\zeta$ & \inelemthree{-1}{-1}{-1} \\ \elemline 2 & \inelemthree{1}{0}{0} & $\xi$ & \inelemthree{1}{0}{0} \\ \elemline 3 & \inelemthree{0}{1}{0} & $\eta$ & \inelemthree{0}{1}{0} \\ \elemline 4 & \inelemthree{0}{0}{1} & $\zeta$ & \inelemthree{0}{0}{1} \\ \end{Element} \begin{QuadPoints}{lc} Coord. \elemcoorthreed & \inquadthree{\quart}{\quart}{\quart} \\ \elemline Weight & \sixth \\ \end{QuadPoints} \subsection{Tetrahedron 10\index{Elements!3D!Tetrahedron 10}} \begin{Element}{3D} 1 & \inelemthree{0}{0}{0} & $\left(1-\xi-\eta-\zeta\right)\left(1-2\xi-2\eta-2\zeta\right)$ & \inelemthreecolumn{4\xi+4\eta+4\zeta-3}{4\xi+4\eta+4\zeta-3}{4\xi+4\eta+4\zeta-3}\\ \elemline 2 & \inelemthree{1}{0}{0} & $\xi\left(2\xi-1\right)$ & \inelemthree{4\xi-1}{0}{0} \\ \elemline 3 & \inelemthree{0}{1}{0} & $\eta\left(2\eta-1\right)$ & \inelemthree{0}{4\eta-1}{0} \\ \elemline 4 & \inelemthree{0}{0}{1} & $\zeta\left(2\zeta-1\right)$ & \inelemthree{0}{0}{4\zeta-1} \\ \elemline 5 & \inelemthree{\half}{0}{0} & $4\xi\left(1-\xi-\eta-\zeta\right)$ & \inelemthree{4-8\xi-4\eta-4\zeta}{-4\xi}{-4\xi} \\ \elemline 6 & \inelemthree{\half}{\half}{0} & $4\xi\eta$ & \inelemthree{4\eta}{4\xi}{0} \\ \elemline 7 & \inelemthree{0}{\half}{0} & $4\eta\left(1-\xi-\eta-\zeta\right)$ & \inelemthree{-4\eta}{4-4\xi-8\eta-4\zeta}{-4\eta} \\ \elemline 8 & \inelemthree{0}{0}{\half} & $4\zeta\left(1-\xi-\eta-\zeta\right)$ & \inelemthree{-4\zeta}{-4\zeta}{4-4\xi-4\eta-8\zeta} \\ \elemline 9 & \inelemthree{\half}{0}{\half} & $4\xi\zeta$ & \inelemthree{4\zeta}{0}{4\xi} \\ \elemline 10 & \inelemthree{0}{\half}{\half} & $4\eta\zeta$ & \inelemthree{0}{4\zeta}{4\eta} \\ \end{Element} \begin{QuadPoints}{lcc} Coord. \elemcoorthreed & \inquadthree{\quada}{\quada}{\quada} & \inquadthree{\quadb}{\quada}{\quada} \\ \elemline Weight & 1/24 & 1/24 \\ \elemline Coord. \elemcoorthreed & \inquadthree{\quada}{\quadb}{\quada} & \inquadthree{\quada}{\quada}{\quadb} \\ \elemline Weight & 1/24 & 1/24 \\ \end{QuadPoints} \clearpage \subsection{Hexahedron 8\index{Elements!3D!Hexahedron 8}} \begin{Element}{3D} 1 & \inelemthree{-1}{-1}{-1} & $\eighth\left(1-\xi\right)\left(1-\eta\right)\left(1-\zeta\right)$ & \inelemthree{-\eighth\left(1-\eta\right)\left(1-\zeta\right)} {-\eighth\left(1-\xi\right)\left(1-\zeta\right)} {-\eighth\left(1-\xi\right)\left(1-\eta\right)} \\ \elemline 2 & \inelemthree{1}{-1}{-1} & $\eighth\left(1+\xi\right)\left(1-\eta\right)\left(1-\zeta\right)$ & \inelemthree{ \eighth\left(1-\eta\right)\left(1-\zeta\right)} {-\eighth\left(1+\xi\right)\left(1-\zeta\right)} {-\eighth\left(1+\xi\right)\left(1-\eta\right)} \\ \elemline 3 & \inelemthree{1}{1}{-1} & $\eighth\left(1+\xi\right)\left(1+\eta\right)\left(1-\zeta\right)$ & \inelemthree{ \eighth\left(1+\eta\right)\left(1-\zeta\right)} { \eighth\left(1+\xi\right)\left(1-\zeta\right)} {-\eighth\left(1+\xi\right)\left(1+\eta\right)} \\ \elemline 4 & \inelemthree{-1}{1}{-1} & $\eighth\left(1-\xi\right)\left(1+\eta\right)\left(1-\zeta\right)$ & \inelemthree{-\eighth\left(1+\eta\right)\left(1-\zeta\right)} { \eighth\left(1-\xi\right)\left(1-\zeta\right)} {-\eighth\left(1-\xi\right)\left(1+\eta\right)} \\ \elemline 5 & \inelemthree{-1}{-1}{1} & $\eighth\left(1-\xi\right)\left(1-\eta\right)\left(1+\zeta\right)$ & \inelemthree{-\eighth\left(1-\eta\right)\left(1+\zeta\right)} {-\eighth\left(1-\xi\right)\left(1+\zeta\right)} { \eighth\left(1-\xi\right)\left(1-\eta\right)} \\ \elemline 6 & \inelemthree{1}{-1}{1} & $\eighth\left(1+\xi\right)\left(1-\eta\right)\left(1+\zeta\right)$ & \inelemthree{ \eighth\left(1-\eta\right)\left(1+\zeta\right)} {-\eighth\left(1+\xi\right)\left(1+\zeta\right)} { \eighth\left(1+\xi\right)\left(1-\eta\right)} \\ \elemline 7 & \inelemthree{1}{1}{1} & $\eighth\left(1+\xi\right)\left(1+\eta\right)\left(1+\zeta\right)$ & \inelemthree{ \eighth\left(1+\eta\right)\left(1+\zeta\right)} { \eighth\left(1+\xi\right)\left(1+\zeta\right)} { \eighth\left(1+\xi\right)\left(1+\eta\right)} \\ \elemline 8 & \inelemthree{-1}{1}{1} & $\eighth\left(1-\xi\right)\left(1+\eta\right)\left(1+\zeta\right)$ & \inelemthree{-\eighth\left(1+\eta\right)\left(1+\zeta\right)} { \eighth\left(1-\xi\right)\left(1+\zeta\right)} { \eighth\left(1-\xi\right)\left(1+\eta\right)} \\ \end{Element} \begin{QuadPoints}{lcccc} \elemcoorthreed & \inquadthree{-\invsqrtthree}{-\invsqrtthree}{-\invsqrtthree} & \inquadthree{\invsqrtthree}{-\invsqrtthree}{-\invsqrtthree} & \inquadthree{\invsqrtthree}{\invsqrtthree}{-\invsqrtthree} & \inquadthree{-\invsqrtthree}{\invsqrtthree}{-\invsqrtthree} \\ \elemline Weight & 1 & 1 & 1 & 1 \\ \elemline \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-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-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-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.tex b/doc/manual/manual.tex index b27df2847..956881ab4 100644 --- a/doc/manual/manual.tex +++ b/doc/manual/manual.tex @@ -1,52 +1,52 @@ \documentclass[openright,a4paper,11pt,fleqn]{manual} \usepackage{manual} \usepackage{manual-macros} \IfFileExists{version-definition.tex}{ \input{version-definition} }{ \newcommand{\version}{2.2} } \graphicspath{ {./figures/} } %%% For references \todo check the coherency %% section 3.5 -> Section 3.5 %% figure 3.5 -> Figure 3.5 %% equation 3.5 -> Equation (3.5) % Title pages and Table of Contents (includes \begin{document}) \input{manual-titlepages} % Introduction chapter \input{manual-introduction} % The planning to write the documentation %\input{manual-planning} % The documentation chapter (split in parts) \input{manual-gettingstarted} -\input{manual-elements} +\input{manual-feengine} %\IfFileExists{manual-lumping.tex}{}{\input{manual-lumping}} \input{manual-solidmechanicsmodel} \IfFileExists{manual-structuralmechanicsmodel.tex}{\input{manual-structuralmechanicsmodel}}{} \IfFileExists{manual-heattransfermodel.tex}{\input{manual-heattransfermodel}}{} \input{manual-io} \IfFileExists{manual-parallel.tex}{\input{manual-parallel}}{} \IfFileExists{manual-contact.tex}{\input{manual-contact}}{} % 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/extra_packages/extra-materials b/extra_packages/extra-materials index 413cd3016..dea972981 160000 --- a/extra_packages/extra-materials +++ b/extra_packages/extra-materials @@ -1 +1 @@ -Subproject commit 413cd301657897dbf57f36e0250da810fd81eb7a +Subproject commit dea9729814e7967a4088ac100749be7f3e0ca6cd diff --git a/extra_packages/igfem b/extra_packages/igfem index fcacdece3..078a747c6 160000 --- a/extra_packages/igfem +++ b/extra_packages/igfem @@ -1 +1 @@ -Subproject commit fcacdece31fc1c406208b3780b50b623939e8656 +Subproject commit 078a747c6f453ab4e35def4a195d98ec34d7a57b diff --git a/packages/core.cmake b/packages/core.cmake index 09a4e3c11..3cb5a046e 100644 --- a/packages/core.cmake +++ b/packages/core.cmake @@ -1,483 +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/python/CMakeLists.txt b/python/CMakeLists.txt index 188f2c9ee..122e8ae1b 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,238 +1,237 @@ #=============================================================================== # @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 #=============================================================================== find_package(SWIG 3.0) 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 "Scannong dependencies for swig module ${_module_we}" + COMMENT "Scanning dependencies for swig module ${_module_we}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} MAIN_DEPENDENCY ${_module_absolute} DEPENDS ${_swig_${_module_we}_depends} ) set(${_depedencies} ${_dependencies_file} PARENT_SCOPE) endfunction() function(swig_generate_wrappers project _wrappers_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 in order to generate them") 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_common.i b/python/swig/aka_common.i index 556f916d8..8a98d0748 100644 --- a/python/swig/aka_common.i +++ b/python/swig/aka_common.i @@ -1,91 +1,80 @@ %{ #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 { - void initialize(const std::string & input_file) { - int argc = 0; - char ** argv = NULL; - initialize(input_file, argc, argv); - } - void initialize() { - int argc = 0; - char ** argv = NULL; - initialize(argc, argv); - } - void _initializeWithArgv(const std::string & input_file, int argc, char *argv[]) { initialize(input_file, argc, argv); } } %} %pythoncode %{ - import sys as _aka_sys - def initializeWithArgv(input_file): - _initializeWithArgv(input_file, _aka_sys.argv) +import sys as _aka_sys +def initialize(input_file="", argv=_aka_sys.argv): + _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/mesh.i b/python/swig/mesh.i index b446c8933..d29a38ac3 100644 --- a/python/swig/mesh.i +++ b/python/swig/mesh.i @@ -1,127 +1,141 @@ %{ #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); - - } + Array<Real> & getCohesiveBarycenter(SpacialDirection dir) { + + UInt spatial_dimension = $self->getSpatialDimension(); + ElementTypeMapArray<Real> & barycenter = $self->registerData<Real>("barycenter"); + $self->initElementTypeMapArray(barycenter, 1, spatial_dimension, false, akantu::_ek_cohesive, true); + akantu::ElementType type = *($self->firstType(spatial_dimension, akantu::_not_ghost, akantu::_ek_cohesive)); + std::cout << "Nb_cohesives : " << $self->getNbElement(type) << std::endl; + 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; + } } %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/solid_mechanics_model.i b/python/swig/solid_mechanics_model.i index c4e2b0600..c9ed3632b 100644 --- a/python/swig/solid_mechanics_model.i +++ b/python/swig/solid_mechanics_model.i @@ -1,172 +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_residual>(tolerance, max_iteration); + akantu::_scc_increment>(tolerance, max_iteration); + } + + /* ------------------------------------------------------------------------ */ + void solveStep_TgIncr(Real tolerance, Real & error, UInt max_iteration) { + + $self->solveStep<akantu::_scm_newton_raphson_tangent, + akantu::_scc_increment>(tolerance, error, max_iteration); } /* ------------------------------------------------------------------------ */ void clearDisplVeloAcc() { akantu::Array<akantu::Real> & displ = $self->getDisplacement(); akantu::Array<akantu::Real> & velo = $self->getVelocity(); akantu::Array<akantu::Real> & acc = $self->getAcceleration(); displ.clear(); velo.clear(); acc.clear(); } /* ------------------------------------------------------------------------ */ void applyUniformPressure(Real pressure, const std::string surface_name) { UInt spatial_dimension = $self->getSpatialDimension(); akantu::Matrix<akantu::Real> surface_stress(spatial_dimension, spatial_dimension, 0.0); for (UInt i = 0; i < spatial_dimension; ++i) { surface_stress(i, i) = -pressure; } $self->applyBC(akantu::BC::Neumann::FromStress(surface_stress), surface_name); } /* ------------------------------------------------------------------------ */ void blockDOF(const std::string surface_name, SpacialDirection direction) { $self->applyBC(akantu::BC::Dirichlet::FixedValue(0.0, direction), surface_name); } } diff --git a/python/swig/solid_mechanics_model_cohesive.i b/python/swig/solid_mechanics_model_cohesive.i index 8693a41bf..bc95c9d96 100644 --- a/python/swig/solid_mechanics_model_cohesive.i +++ b/python/swig/solid_mechanics_model_cohesive.i @@ -1,14 +1,25 @@ %{ #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/src/common/aka_common.cc b/src/common/aka_common.cc index 089584f08..f72e4815f 100644 --- a/src/common/aka_common.cc +++ b/src/common/aka_common.cc @@ -1,148 +1,162 @@ /** * @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) { AKANTU_DEBUG_IN(); initialize("", argc, argv); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void initialize(const std::string & input_file, int & argc, char ** & argv) { AKANTU_DEBUG_IN(); StaticMemory::getStaticMemory(); StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator(argc, argv); debug::debugger.setParallelContext(comm.whoAmI(), comm.getNbProc()); debug::initSignalHandler(); static_argparser.setParallelContext(comm.whoAmI(), comm.getNbProc()); static_argparser.setExternalExitFunction(debug::exit); static_argparser.addArgument("--aka_input_file", "Akantu's input file", 1, cppargparse::_string, std::string()); static_argparser.addArgument("--aka_debug_level", std::string("Akantu's overall debug level") + std::string(" (0: error, 1: exceptions, 4: warnings, 5: info, ..., 100: dump,") + std::string(" more info on levels can be foind in aka_error.hh)"), 1, cppargparse::_integer, int(dblWarning)); static_argparser.addArgument("--aka_print_backtrace", "Should Akantu print a backtrace in case of error", 0, cppargparse::_boolean, false, true); static_argparser.parse(argc, argv, cppargparse::_remove_parsed); std::string infile = static_argparser["aka_input_file"]; if(infile == "") infile = input_file; debug::setDebugLevel(dblError); if ("" != infile) { static_parser.parse(infile); } long int seed; try { seed = static_parser.getParameter("seed", _ppsc_current_scope); } catch (debug::Exception &) { seed = time(NULL); } int dbl_level = static_argparser["aka_debug_level"]; debug::setDebugLevel(DebugLevel(dbl_level)); debug::debugger.printBacktrace(static_argparser["aka_print_backtrace"]); seed *= (comm.whoAmI() + 1); #if not defined(_WIN32) Rand48Generator<Real>::seed(seed); #endif RandGenerator<Real>::seed(seed); AKANTU_DEBUG_INFO("Random seed set to " << seed); /// initialize external solvers StaticSolver::getStaticSolver().initialize(argc,argv); AKANTU_DEBUG_OUT(); } - /* -------------------------------------------------------------------------- */ -void finalize() { +void clear() { AKANTU_DEBUG_IN(); /// finalize external solvers StaticSolver::getStaticSolver().finalize(); if(StaticMemory::isInstantiated()) delete &(StaticMemory::getStaticMemory()); if(StaticCommunicator::isInstantiated()) { StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator(); comm.barrier(); delete &comm; } + static_parser.clear(); + + AKANTU_DEBUG_OUT(); +} +/* -------------------------------------------------------------------------- */ +void finalize() { + AKANTU_DEBUG_IN(); + + if(StaticCommunicator::isInstantiated()) { + StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator(); + comm.barrier(); + comm.finalize(); + } + + clear(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ cppargparse::ArgumentParser & getStaticArgumentParser() { return static_argparser; } /* -------------------------------------------------------------------------- */ Parser & getStaticParser() { return static_parser; } /* -------------------------------------------------------------------------- */ const ParserSection & getUserParser() { return *(static_parser.getSubSections(_st_user).first); } __END_AKANTU__ diff --git a/src/common/aka_common.hh b/src/common/aka_common.hh index 65de285ae..869684cc0 100644 --- a/src/common/aka_common.hh +++ b/src/common/aka_common.hh @@ -1,485 +1,488 @@ /** * @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> /* -------------------------------------------------------------------------- */ #define __BEGIN_AKANTU__ namespace akantu { #define __END_AKANTU__ }; /* -------------------------------------------------------------------------- */ #define __BEGIN_AKANTU_DUMPER__ namespace dumper { #define __END_AKANTU_DUMPER__ } /* -------------------------------------------------------------------------- */ #if defined(WIN32) # define __attribute__(x) #endif /* -------------------------------------------------------------------------- */ #include "aka_config.hh" #include "aka_error.hh" #include "aka_safe_enum.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ /* Common types */ /* -------------------------------------------------------------------------- */ typedef std::string ID; static const Real UINT_INIT_VALUE = Real(0.); #ifdef AKANTU_NDEBUG static const Real REAL_INIT_VALUE = Real(0.); #else static const Real REAL_INIT_VALUE = std::numeric_limits<Real>::quiet_NaN(); #endif /* -------------------------------------------------------------------------- */ /* Memory types */ /* -------------------------------------------------------------------------- */ typedef UInt MemoryID; typedef std::string Surface; typedef std::pair<Surface, Surface> SurfacePair; typedef std::list< SurfacePair > SurfacePairList; /* -------------------------------------------------------------------------- */ extern const UInt _all_dimensions; /* -------------------------------------------------------------------------- */ /* Mesh/FEM/Model types */ /* -------------------------------------------------------------------------- */ __END_AKANTU__ #include "aka_element_classes_info.hh" __BEGIN_AKANTU__ /// small help to use names for directions enum SpacialDirection { _x = 0, _y = 1, _z = 2 }; /// enum MeshIOType type of mesh reader/writer enum MeshIOType { _miot_auto, ///< Auto guess of the reader to use based on the extension _miot_gmsh, ///< Gmsh files _miot_gmsh_struct, ///< Gsmh reader with reintpretation of elements has structures elements _miot_diana, ///< TNO Diana mesh format _miot_abaqus ///< Abaqus mesh format }; /// enum AnalysisMethod type of solving method used to solve the equation of motion enum AnalysisMethod { _static, _implicit_dynamic, _explicit_lumped_mass, _explicit_lumped_capacity, _explicit_consistent_mass }; //! enum ContactResolutionMethod types of solving for the contact enum ContactResolutionMethod { _penalty, _lagrangian, _augmented_lagrangian, _nitsche, _mortar }; //! enum ContactImplementationMethod types for different contact implementations enum ContactImplementationMethod { _none, _uzawa, _generalized_newton }; /// enum SolveConvergenceMethod different resolution algorithms enum SolveConvergenceMethod { _scm_newton_raphson_tangent, ///< Newton-Raphson with tangent matrix _scm_newton_raphson_tangent_modified, ///< Newton-Raphson with constant tangent matrix _scm_newton_raphson_tangent_not_computed ///< Newton-Raphson with constant tangent matrix (user has to assemble it) }; /// enum SolveConvergenceCriteria different convergence criteria enum SolveConvergenceCriteria { _scc_residual, ///< Use residual to test the convergence _scc_increment, ///< Use increment to test the convergence _scc_residual_mass_wgh ///< Use residual weighted by inv. nodal mass to testb }; /// enum CohesiveMethod type of insertion of cohesive elements enum CohesiveMethod { _intrinsic, _extrinsic }; /// myfunction(double * position, double * stress/force, double * normal, unsigned int material_id) typedef void (*BoundaryFunction)(double *,double *, double*, unsigned int); /// @enum BoundaryFunctionType type of function passed for boundary conditions enum BoundaryFunctionType { _bft_stress, _bft_traction, _bft_traction_local }; /// @enum SparseMatrixType type of sparse matrix used enum SparseMatrixType { _unsymmetric, _symmetric }; /* -------------------------------------------------------------------------- */ /* Contact */ /* -------------------------------------------------------------------------- */ typedef ID ContactID; typedef ID ContactSearchID; typedef ID ContactNeighborStructureID; enum ContactType { _ct_not_defined = 0, _ct_2d_expli = 1, _ct_3d_expli = 2, _ct_rigid = 3 }; enum ContactSearchType { _cst_not_defined = 0, _cst_2d_expli = 1, _cst_expli = 2 }; enum ContactNeighborStructureType { _cnst_not_defined = 0, _cnst_regular_grid = 1, _cnst_2d_grid = 2 }; /* -------------------------------------------------------------------------- */ /* Friction */ /* -------------------------------------------------------------------------- */ typedef ID FrictionID; /* -------------------------------------------------------------------------- */ /* Ghosts handling */ /* -------------------------------------------------------------------------- */ typedef ID SynchronizerID; /// @enum CommunicatorType type of communication method to use enum CommunicatorType { _communicator_mpi, _communicator_dummy }; /// @enum SynchronizationTag type of synchronizations enum SynchronizationTag { //--- SolidMechanicsModel tags --- _gst_smm_mass, //< synchronization of the SolidMechanicsModel.mass _gst_smm_for_gradu, //< synchronization of the SolidMechanicsModel.displacement _gst_smm_boundary, //< synchronization of the boundary, forces, velocities and displacement _gst_smm_uv, //< synchronization of the nodal velocities and displacement _gst_smm_res, //< synchronization of the nodal residual _gst_smm_init_mat, //< synchronization of the data to initialize materials _gst_smm_stress, //< synchronization of the stresses to compute the internal forces _gst_smmc_facets, //< synchronization of facet data to setup facet synch _gst_smmc_facets_conn, //< synchronization of facet global connectivity _gst_smmc_facets_stress, //< synchronization of facets' stress to setup facet synch _gst_smmc_damage, //< synchronization of damage //--- GlobalIdsUpdater tags --- _gst_giu_global_conn, //< synchronization of global connectivities //--- CohesiveElementInserter tags --- _gst_ce_groups, //< synchronization of cohesive element insertion depending on facet groups //--- GroupManager tags --- _gst_gm_clusters, //< synchronization of clusters //--- HeatTransfer tags --- _gst_htm_capacity, //< synchronization of the nodal heat capacity _gst_htm_temperature, //< synchronization of the nodal temperature _gst_htm_gradient_temperature, //< synchronization of the element gradient temperature //--- LevelSet tags --- /// synchronization of the nodal level set value phi _gst_htm_phi, /// synchronization of the element gradient phi _gst_htm_gradient_phi, //--- Material non local --- _gst_mnl_for_average, //< synchronization of data to average in non local material _gst_mnl_weight, //< synchronization of data for the weight computations //--- NeighborhoodSynchronization tags --- _gst_nh_criterion, //--- General tags --- _gst_test, //< Test tag _gst_user_1, //< tag for user simulations _gst_user_2, //< tag for user simulations _gst_material_id, //< synchronization of the material ids _gst_for_dump, //< everything that needs to be synch before dump //--- Contact & Friction --- _gst_cf_nodal, //< synchronization of disp, velo, and current position _gst_cf_incr, //< synchronization of increment ///--- Solver tags --- _gst_solver_solution //< synchronization of the solution obained with the PETSc solver }; /// standard output stream operator for SynchronizationTag inline std::ostream & operator <<(std::ostream & stream, SynchronizationTag type); /// @enum GhostType type of ghost enum GhostType { _not_ghost, _ghost, _casper // not used but a real cute ghost }; /* -------------------------------------------------------------------------- */ struct GhostType_def { typedef GhostType type; static const type _begin_ = _not_ghost; static const type _end_ = _casper; }; typedef safe_enum<GhostType_def> ghost_type_t; /// standard output stream operator for GhostType inline std::ostream & operator <<(std::ostream & stream, GhostType type); /// @enum SynchronizerOperation reduce operation that the synchronizer can perform enum SynchronizerOperation { _so_sum, _so_min, _so_max, _so_prod, _so_land, _so_band, _so_lor, _so_bor, _so_lxor, _so_bxor, _so_min_loc, _so_max_loc, _so_null }; /* -------------------------------------------------------------------------- */ /* Global defines */ /* -------------------------------------------------------------------------- */ #define AKANTU_MIN_ALLOCATION 2000 #define AKANTU_INDENT " " #define AKANTU_INCLUDE_INLINE_IMPL /* -------------------------------------------------------------------------- */ // int 2 type construct template <int d> struct Int2Type { enum { result = d }; }; // type 2 type construct template <class T> class Type2Type { typedef T OriginalType; }; /* -------------------------------------------------------------------------- */ template<class T> struct is_scalar { enum{ value = false }; }; #define AKANTU_SPECIFY_IS_SCALAR(type) \ template<> \ struct is_scalar<type> { \ enum { value = true }; \ } AKANTU_SPECIFY_IS_SCALAR(Real); AKANTU_SPECIFY_IS_SCALAR(UInt); AKANTU_SPECIFY_IS_SCALAR(Int); AKANTU_SPECIFY_IS_SCALAR(bool); template < typename T1, typename T2 > struct is_same { enum { value = false }; // is_same represents a bool. }; template < typename T > struct is_same<T, T> { enum { value = true }; }; /* -------------------------------------------------------------------------- */ #define AKANTU_SET_MACRO(name, variable, type) \ inline void set##name (type variable) { \ this->variable = variable; \ } #define AKANTU_GET_MACRO(name, variable, type) \ inline type get##name () const { \ return variable; \ } #define AKANTU_GET_MACRO_NOT_CONST(name, variable, type) \ inline type get##name () { \ return variable; \ } #define AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, \ support, con) \ inline con Array<type> & \ get##name (const support & el_type, \ const GhostType & ghost_type = _not_ghost) con { \ return variable(el_type, ghost_type); \ } #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE(name, variable, type) \ AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType,) #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(name, variable, type) \ AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType, const) #define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE(name, variable, type) \ AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType,) #define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE_CONST(name, variable, type) \ AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType, const) /* -------------------------------------------------------------------------- */ /// initialize the static part of akantu void initialize(int & argc, char ** & argv); /// initialize the static part of akantu and read the global input_file void initialize(const std::string & input_file, int & argc, char ** & argv); /* -------------------------------------------------------------------------- */ +/// Clean akantu memory. Should be used only before a re-initialize of Akantu. +/// Otherwise finalize() should be used. +void clear(); /// finilize correctly akantu and clean the memory void finalize (); /* -------------------------------------------------------------------------- */ /* * For intel compiler annoying remark */ #if defined(__INTEL_COMPILER) /// remark #981: operands are evaluated in unspecified order #pragma warning ( disable : 981 ) /// remark #383: value copied to temporary, reference to temporary used #pragma warning ( disable : 383 ) #endif //defined(__INTEL_COMPILER) /* -------------------------------------------------------------------------- */ /* string manipulation */ /* -------------------------------------------------------------------------- */ inline std::string to_lower(const std::string & str); /* -------------------------------------------------------------------------- */ inline std::string trim(const std::string & to_trim); /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /// give a string representation of the a human readable size in bit template<typename T> std::string printMemorySize(UInt size); /* -------------------------------------------------------------------------- */ __END_AKANTU__ #include "aka_fwd.hh" __BEGIN_AKANTU__ /// get access to the internal argument parser cppargparse::ArgumentParser & getStaticArgumentParser(); /// get access to the internal input file parser Parser & getStaticParser(); /// get access to the user part of the internal input file parser const ParserSection & getUserParser(); __END_AKANTU__ #include "aka_common_inline_impl.cc" /* -------------------------------------------------------------------------- */ #if defined(AKANTU_UNORDERED_MAP_IS_CXX11) __BEGIN_AKANTU_UNORDERED_MAP__ #if AKANTU_INTEGER_SIZE == 4 #define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b9 #elif AKANTU_INTEGER_SIZE == 8 #define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b97f4a7c13LL #endif /** * Hashing function for pairs based on hash_combine from boost The magic number * is coming from the golden number @f[\phi = \frac{1 + \sqrt5}{2}@f] * @f[\frac{2^32}{\phi} = 0x9e3779b9@f] * http://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine * http://burtleburtle.net/bob/hash/doobs.html */ template <typename a, typename b> struct hash< std::pair<a, b> > { public: hash() : ah(), bh() {} size_t operator()(const std::pair<a, b> & p) const { size_t seed = ah(p.first); return bh(p.second) + AKANTU_HASH_COMBINE_MAGIC_NUMBER + (seed << 6) + (seed >> 2); } private: const hash<a> ah; const hash<b> bh; }; __END_AKANTU_UNORDERED_MAP__ #endif #endif /* __AKANTU_COMMON_HH__ */ diff --git a/src/common/aka_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/geometry/mesh_geom_factory_tmpl.hh b/src/geometry/mesh_geom_factory_tmpl.hh index b7b41b3ab..222654b94 100644 --- a/src/geometry/mesh_geom_factory_tmpl.hh +++ b/src/geometry/mesh_geom_factory_tmpl.hh @@ -1,240 +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/io/parser/parser.hh b/src/io/parser/parser.hh index 9317914e0..c66335a46 100644 --- a/src/io/parser/parser.hh +++ b/src/io/parser/parser.hh @@ -1,445 +1,448 @@ /** * @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) \ (embedded_interface) \ (rules) \ (neighborhoods) \ (non_local) \ (weight_function) \ (neighborhood) \ (user) \ (not_defined) #define AKANTU_SECTION_TYPES_PREFIX(elem) BOOST_PP_CAT(_st_, elem) #define AKANTU_SECT_PREFIX(s, data, elem) AKANTU_SECTION_TYPES_PREFIX(elem) /// Defines the possible section types enum SectionType { BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(AKANTU_SECT_PREFIX, _, AKANTU_SECTION_TYPES)) }; #undef AKANTU_SECT_PREFIX #define AKANTU_SECTION_TYPE_PRINT_CASE(r, data, elem) \ case AKANTU_SECTION_TYPES_PREFIX(elem): { \ stream << BOOST_PP_STRINGIZE(AKANTU_SECTION_TYPES_PREFIX(elem)); \ break; \ } inline std::ostream & operator <<(std::ostream & stream, SectionType type) { switch(type) { BOOST_PP_SEQ_FOR_EACH(AKANTU_SECTION_TYPE_PRINT_CASE, _, AKANTU_SECTION_TYPES) default: stream << "not a SectionType"; break; } return stream; } #undef AKANTU_SECTION_TYPE_PRINT_CASE /// Defines the possible search contexts/scopes (for parameter search) enum ParserParameterSearchCxt { _ppsc_current_scope = 0x1, _ppsc_parent_scope = 0x2, _ppsc_current_and_parent_scope = 0x3 }; /* ------------------------------------------------------------------------ */ /* Parameters Class */ /* ------------------------------------------------------------------------ */ class ParserSection; /// @brief The ParserParameter objects represent the end of tree branches as they /// are the different informations contained in the input file. class ParserParameter { public: ParserParameter() : parent_section(NULL), name(std::string()), value(std::string()), dbg_filename(std::string()) {} ParserParameter(const std::string & name, const std::string & value, const ParserSection & parent_section) : parent_section(&parent_section), name(name), value(value), dbg_filename(std::string()) {} ParserParameter(const ParserParameter & param) : parent_section(param.parent_section), name(param.name), value(param.value), dbg_filename(param.dbg_filename), dbg_line(param.dbg_line), dbg_column(param.dbg_column) {} virtual ~ParserParameter() {} /// Get parameter name const std::string & getName() const { return name; } /// Get parameter value const std::string & getValue() const { return value; } /// Set info for debug output void setDebugInfo(const std::string & filename, UInt line, UInt column) { dbg_filename = filename; dbg_line = line; dbg_column = column; } template <typename T> inline operator T() const; // template <typename T> inline operator Vector<T>() const; // template <typename T> inline operator Matrix<T>() const; /// Print parameter info in stream void printself(std::ostream & stream, unsigned int indent = 0) const { stream << name << ": " << value << " (" << dbg_filename << ":" << dbg_line << ":" << dbg_column << ")"; } private: void setParent(const ParserSection & sect) { parent_section = § } friend class ParserSection; private: /// Pointer to the parent section const ParserSection * parent_section; /// Name of the parameter std::string name; /// Value of the parameter std::string value; /// File for debug output std::string dbg_filename; /// Position of parameter in parsed file UInt dbg_line, dbg_column; }; /* ------------------------------------------------------------------------ */ /* Sections Class */ /* ------------------------------------------------------------------------ */ /// ParserSection represents a branch of the parsing tree. class ParserSection { public: typedef std::multimap<SectionType, ParserSection> SubSections; typedef std::map<std::string, ParserParameter> Parameters; private: typedef SubSections::const_iterator const_section_iterator_; public: /* ------------------------------------------------------------------------ */ /* SubSection iterator */ /* ------------------------------------------------------------------------ */ /// Iterator on sections class const_section_iterator { public: const_section_iterator(const const_section_iterator & other) : it(other.it) { } const_section_iterator(const const_section_iterator_ & it) : it(it) { } const_section_iterator & operator=(const const_section_iterator & other) { if(this != &other) { it = other.it; } return *this; } const ParserSection & operator* () const { return it->second; } const ParserSection * operator-> () const { return &(it->second); } bool operator==(const const_section_iterator & other) const { return it == other.it; } bool operator!=(const const_section_iterator & other) const { return it != other.it; } const_section_iterator & operator++() { ++it; return *this; } const_section_iterator operator++(int) { const_section_iterator tmp = *this; operator++(); return tmp; } private: const_section_iterator_ it; }; /* ------------------------------------------------------------------------ */ /* Parameters iterator */ /* ------------------------------------------------------------------------ */ /// Iterator on parameters class const_parameter_iterator { public: const_parameter_iterator(const const_parameter_iterator & other) : it(other.it) { } const_parameter_iterator(const Parameters::const_iterator & it) : it(it) { } const_parameter_iterator & operator=(const const_parameter_iterator & other) { if(this != &other) { it = other.it; } return *this; } const ParserParameter & operator* () const { return it->second; } const ParserParameter * operator->() { return &(it->second); }; bool operator==(const const_parameter_iterator & other) const { return it == other.it; } bool operator!=(const const_parameter_iterator & other) const { return it != other.it; } const_parameter_iterator & operator++() { ++it; return *this; } const_parameter_iterator operator++(int) { const_parameter_iterator tmp = *this; operator++(); return tmp; } private: Parameters::const_iterator it; }; /* ---------------------------------------------------------------------- */ ParserSection() : parent_section(NULL), name(std::string()), type(_st_not_defined){} ParserSection(const std::string & name, SectionType type) : parent_section(NULL), name(name), type(type) {} ParserSection(const std::string & name, SectionType type, const std::string & option, const ParserSection & parent_section) : parent_section(&parent_section), name(name), type(type), option(option) {} ParserSection(const ParserSection & section) : parent_section(section.parent_section), name(section.name), type(section.type), option(section.option), parameters(section.parameters), sub_sections_by_type(section.sub_sections_by_type) { setChldrenPointers(); } ParserSection & operator=(const ParserSection & other) { if(&other != this) { parent_section = other.parent_section; name = other.name; type = other.type; option = other.option; parameters = other.parameters; sub_sections_by_type = other.sub_sections_by_type; setChldrenPointers(); } return *this; } virtual ~ParserSection(); virtual void printself(std::ostream & stream, unsigned int indent = 0) const; /* ---------------------------------------------------------------------- */ /* Creation functions */ /* ---------------------------------------------------------------------- */ public: ParserParameter & addParameter(const ParserParameter & param); ParserSection & addSubSection(const ParserSection & section); + /// Clear ParserSection content + void clear() {parameters.clear(); sub_sections_by_type.clear();} + private: void setChldrenPointers() { Parameters::iterator pit = this->parameters.begin(); for(;pit != this->parameters.end(); ++pit) pit->second.setParent(*this); SubSections::iterator sit = this->sub_sections_by_type.begin(); for (;sit != this->sub_sections_by_type.end(); ++sit) sit->second.setParent(*this); } /* ---------------------------------------------------------------------- */ /* Accessors */ /* ---------------------------------------------------------------------- */ public: /// Get begin and end iterators on subsections of certain type std::pair<const_section_iterator, const_section_iterator> getSubSections(SectionType type = _st_not_defined) const { if(type != _st_not_defined) { std::pair<const_section_iterator_, const_section_iterator_> range = sub_sections_by_type.equal_range(type); return std::pair<const_section_iterator, const_section_iterator>(range.first, range.second); } else { return std::pair<const_section_iterator, const_section_iterator>(sub_sections_by_type.begin(), sub_sections_by_type.end()); } } /// Get begin and end iterators on parameters std::pair<const_parameter_iterator, const_parameter_iterator> getParameters() const { return std::pair<const_parameter_iterator, const_parameter_iterator>(parameters.begin(), parameters.end()); } /* ---------------------------------------------------------------------- */ /// Get parameter within specified context const ParserParameter & getParameter(const std::string & name, ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const { Parameters::const_iterator it; if(search_ctx & _ppsc_current_scope) it = parameters.find(name); if(it == parameters.end()) { if((search_ctx & _ppsc_parent_scope) && parent_section) return parent_section->getParameter(name, search_ctx); else { AKANTU_SILENT_EXCEPTION("The parameter " << name << " has not been found in the specified context"); } } return it->second; } /* ------------------------------------------------------------------------ */ /// Check if parameter exists within specified context bool hasParameter(const std::string & name, ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const { Parameters::const_iterator it; if(search_ctx & _ppsc_current_scope) it = parameters.find(name); if(it == parameters.end()) { if((search_ctx & _ppsc_parent_scope) && parent_section) return parent_section->hasParameter(name, search_ctx); else { return false; } } return true; } /* -------------------------------------------------------------------------- */ /// Get value of given parameter in context template<class T> T getParameterValue(const std::string & name, ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const { const ParserParameter & tmp_param = getParameter(name, search_ctx); T t = tmp_param; return t; } /* -------------------------------------------------------------------------- */ /// Get section name const std::string & getName() const { return name; } /// Get section type const SectionType & getType() const { return type; } /// Get section option const std::string & getOption() const { return option; } protected: void setParent(const ParserSection & sect) { parent_section = § } /* ---------------------------------------------------------------------- */ /* Members */ /* ---------------------------------------------------------------------- */ private: /// Pointer to the parent section const ParserSection * parent_section; /// Name of section std::string name; /// Type of section, see AKANTU_SECTION_TYPES SectionType type; /// Section option std::string option; /// Map of parameters in section Parameters parameters; /// Multi-map of subsections SubSections sub_sections_by_type; }; /* ------------------------------------------------------------------------ */ /* Parser Class */ /* ------------------------------------------------------------------------ */ /// Root of parsing tree, represents the global ParserSection class Parser : public ParserSection { public: Parser() : ParserSection("global", _st_global) {} void parse(const std::string & filename); std::string getLastParsedFile() const; static bool isPermissive() { return permissive_parser; } public: /// Parse real scalar static Real parseReal (const std::string & value, const ParserSection & section); /// Parse real vector static Vector<Real> parseVector(const std::string & value, const ParserSection & section); /// Parse real matrix static Matrix<Real> parseMatrix(const std::string & value, const ParserSection & section); /// Parse real random parameter static RandomParameter<Real> parseRandomParameter(const std::string & value, const ParserSection & section); protected: /// General parse function template <class T, class Grammar> static T parseType(const std::string & value, Grammar & grammar); protected: // friend class Parsable; static bool permissive_parser; std::string last_parsed_file; }; inline std::ostream & operator <<(std::ostream & stream, const ParserParameter &_this) { _this.printself(stream); return stream; } inline std::ostream & operator <<(std::ostream & stream, const ParserSection & section) { section.printself(stream); return stream; } __END_AKANTU__ #include "parser_tmpl.hh" #endif /* __AKANTU_PARSER_HH__ */ diff --git a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc index 17f0b18cf..c8b7fc796 100644 --- a/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc +++ b/src/model/solid_mechanics/solid_mechanics_model_embedded_interface/embedded_interface_intersector.cc @@ -1,160 +1,160 @@ /** * @file embedded_interface_intersector.cc * * @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)); + 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/synchronizer/real_static_communicator.hh b/src/synchronizer/real_static_communicator.hh index aed480b2d..f950fead4 100644 --- a/src/synchronizer/real_static_communicator.hh +++ b/src/synchronizer/real_static_communicator.hh @@ -1,108 +1,109 @@ /** * @file real_static_communicator.hh * * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date creation: Thu Apr 14 2011 * @date last modification: Tue Nov 06 2012 * * @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() { }; - + /// Finalize communication process + virtual void finalize() {}; friend class StaticCommunicator; protected: Int prank; Int psize; }; __END_AKANTU__ #endif /* __AKANTU_REAL_STATIC_COMMUNICATOR_HH__ */ diff --git a/src/synchronizer/static_communicator.cc b/src/synchronizer/static_communicator.cc index f6e3c2e09..1bbf26a87 100644 --- a/src/synchronizer/static_communicator.cc +++ b/src/synchronizer/static_communicator.cc @@ -1,115 +1,120 @@ /** * @file static_communicator.cc * * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date creation: Wed Sep 01 2010 * @date last modification: Mon Jul 21 2014 * * @brief implementation of the common part of the static communicator * * @section LICENSE * * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "static_communicator.hh" #include "static_communicator_dummy.hh" #ifdef AKANTU_USE_MPI # include "static_communicator_mpi.hh" #endif /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ bool StaticCommunicator::is_instantiated = false; StaticCommunicator * StaticCommunicator::static_communicator = NULL; UInt CommunicationRequest::counter = 0; /* -------------------------------------------------------------------------- */ CommunicationRequest::CommunicationRequest(UInt source, UInt dest) : source(source), destination(dest) { this->id = counter++; } /* -------------------------------------------------------------------------- */ CommunicationRequest::~CommunicationRequest() { } /* -------------------------------------------------------------------------- */ void CommunicationRequest::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); stream << space << "CommunicationRequest [" << std::endl; stream << space << " + id : " << id << std::endl; stream << space << " + source : " << source << std::endl; stream << space << " + destination : " << destination << std::endl; stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ StaticCommunicator::StaticCommunicator(int & argc, char ** & argv, CommunicatorType type) { real_type = type; #ifdef AKANTU_USE_MPI if(type == _communicator_mpi) { real_static_communicator = new StaticCommunicatorMPI(argc, argv); } else { #endif real_static_communicator = new StaticCommunicatorDummy(argc, argv); #ifdef AKANTU_USE_MPI } #endif } +/* -------------------------------------------------------------------------- */ +void StaticCommunicator::finalize() { + + real_static_communicator->finalize(); +} /* -------------------------------------------------------------------------- */ StaticCommunicator & StaticCommunicator::getStaticCommunicator(CommunicatorType type) { AKANTU_DEBUG_IN(); if (!static_communicator) { int nb_args = 0; char ** null; static_communicator = new StaticCommunicator(nb_args, null, type); } is_instantiated = true; AKANTU_DEBUG_OUT(); return *static_communicator; } /* -------------------------------------------------------------------------- */ StaticCommunicator & StaticCommunicator::getStaticCommunicator(int & argc, char ** & argv, CommunicatorType type) { if (!static_communicator) static_communicator = new StaticCommunicator(argc, argv, type); return getStaticCommunicator(type); } __END_AKANTU__ diff --git a/src/synchronizer/static_communicator.hh b/src/synchronizer/static_communicator.hh index 6754774be..0fc81efed 100644 --- a/src/synchronizer/static_communicator.hh +++ b/src/synchronizer/static_communicator.hh @@ -1,212 +1,218 @@ /** * @file static_communicator.hh * * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date creation: Wed Sep 01 2010 * @date last modification: Mon Jul 21 2014 * * @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))) #if defined(AKANTU_USE_MPI) # include "static_communicator_mpi.hh" # define AKANTU_COMMUNICATOR_LIST_ALL \ BOOST_PP_SEQ_PUSH_BACK(AKANTU_COMMUNICATOR_LIST_1, \ (_communicator_mpi, (StaticCommunicatorMPI, BOOST_PP_NIL))) #else # define AKANTU_COMMUNICATOR_LIST_ALL AKANTU_COMMUNICATOR_LIST_1 #endif // AKANTU_COMMUNICATOR_LIST #include "real_static_communicator.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ class RealStaticCommunicator; struct FinalizeCommunicatorEvent { FinalizeCommunicatorEvent(const StaticCommunicator & comm) : communicator(comm) {} const StaticCommunicator & communicator; }; class CommunicatorEventHandler { public: virtual ~CommunicatorEventHandler() {} virtual void onCommunicatorFinalize(__attribute__((unused)) const StaticCommunicator & communicator) { } private: inline void sendEvent(const FinalizeCommunicatorEvent & event) { onCommunicatorFinalize(event.communicator); } template<class EventHandler> friend class EventHandlerManager; }; class StaticCommunicator : public EventHandlerManager<CommunicatorEventHandler>{ /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ protected: StaticCommunicator(int & argc, char ** & argv, CommunicatorType type = _communicator_mpi); public: virtual ~StaticCommunicator() { FinalizeCommunicatorEvent *event = new FinalizeCommunicatorEvent(*this); this->sendEvent(*event); - delete event; + delete event; delete real_static_communicator; + is_instantiated = false; + StaticCommunicator::static_communicator = NULL; + }; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: + + /// Finalize the real_static_communicator + void finalize(); /* ------------------------------------------------------------------------ */ /* Point to Point */ /* ------------------------------------------------------------------------ */ template<typename T> inline void send(T * buffer, Int size, Int receiver, Int tag); template<typename T> inline void receive(T * buffer, Int size, Int sender, Int tag); template<typename T> inline CommunicationRequest * asyncSend(T * buffer, Int size, Int receiver, Int tag); template<typename T> inline CommunicationRequest * asyncReceive(T * buffer, Int size, Int sender, Int tag); template<typename T> inline void probe(Int sender, Int tag, CommunicationStatus & status); /* ------------------------------------------------------------------------ */ /* Collectives */ /* ------------------------------------------------------------------------ */ template<typename T> inline void reduce(T * values, int nb_values, const SynchronizerOperation & op, int root = 0); template<typename T> inline void allReduce(T * values, int nb_values, const SynchronizerOperation & op); template<typename T> inline void allGather(T * values, int nb_values); template<typename T> inline void allGatherV(T * values, int * nb_values); template<typename T> inline void gather(T * values, int nb_values, int root = 0); template<typename T> inline void gatherV(T * values, int * nb_values, int root = 0); template<typename T> inline void broadcast(T * values, int nb_values, int root = 0); inline void barrier(); /* ------------------------------------------------------------------------ */ /* Request handling */ /* ------------------------------------------------------------------------ */ inline bool testRequest(CommunicationRequest * request); inline void wait(CommunicationRequest * request); inline void waitAll(std::vector<CommunicationRequest *> & requests); inline void freeCommunicationRequest(CommunicationRequest * request); inline void freeCommunicationRequest(std::vector<CommunicationRequest *> & requests); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: virtual Int getNbProc() const { return real_static_communicator->psize; }; virtual Int whoAmI() const { return real_static_communicator->prank; }; AKANTU_GET_MACRO(RealStaticCommunicator, *real_static_communicator, const RealStaticCommunicator &); AKANTU_GET_MACRO_NOT_CONST(RealStaticCommunicator, *real_static_communicator, RealStaticCommunicator &); template<class Comm> Comm & getRealStaticCommunicator() { return dynamic_cast<Comm &>(*real_static_communicator); } static StaticCommunicator & getStaticCommunicator(CommunicatorType type = _communicator_mpi); static StaticCommunicator & getStaticCommunicator(int & argc, char ** & argv, CommunicatorType type = _communicator_mpi); static bool isInstantiated() { return is_instantiated; }; int getMaxTag(); int getMinTag(); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: static bool is_instantiated; static StaticCommunicator * static_communicator; RealStaticCommunicator * real_static_communicator; CommunicatorType real_type; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #include "static_communicator_inline_impl.hh" /* -------------------------------------------------------------------------- */ /* Inline Functions ArrayBase */ /* -------------------------------------------------------------------------- */ inline std::ostream & operator<<(std::ostream & stream, const CommunicationRequest & _this) { _this.printself(stream); return stream; } __END_AKANTU__ #endif /* __AKANTU_STATIC_COMMUNICATOR_HH__ */ diff --git a/src/synchronizer/static_communicator_dummy.hh b/src/synchronizer/static_communicator_dummy.hh index 37f0a492f..59114ab25 100644 --- a/src/synchronizer/static_communicator_dummy.hh +++ b/src/synchronizer/static_communicator_dummy.hh @@ -1,158 +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) { prank = 0; psize = 1; }; virtual ~StaticCommunicatorDummy(){}; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: template <typename T> void send(__attribute__((unused)) T * buffer, __attribute__((unused)) Int size, __attribute__((unused)) Int receiver, __attribute__((unused)) Int tag) {} template <typename T> void receive(__attribute__((unused)) T * buffer, __attribute__((unused)) Int size, __attribute__((unused)) Int sender, __attribute__((unused)) Int tag) {} template <typename T> CommunicationRequest * asyncSend(__attribute__((unused)) T * buffer, __attribute__((unused)) Int size, __attribute__((unused)) Int receiver, __attribute__((unused)) Int tag) { return new CommunicationRequest(0, 0); } template <typename T> CommunicationRequest * asyncReceive(__attribute__((unused)) T * buffer, __attribute__((unused)) Int size, __attribute__((unused)) Int sender, __attribute__((unused)) Int tag) { return new CommunicationRequest(0, 0); } template <typename T> inline void probe(__attribute__((unused)) Int sender, __attribute__((unused)) Int tag, __attribute__((unused)) CommunicationStatus & status) {} bool testRequest(__attribute__((unused)) CommunicationRequest * request) { return true; }; void wait(__attribute__((unused)) CommunicationRequest * request){}; void waitAll(__attribute__((unused)) std::vector<CommunicationRequest *> & requests){}; void barrier(){}; template <typename T> void reduce(__attribute__ ((unused)) T * values, __attribute__ ((unused)) int nb_values, __attribute__ ((unused)) const SynchronizerOperation & op, __attribute__ ((unused)) int root) {} template <typename T> void allReduce(__attribute__((unused)) T * values, __attribute__((unused)) int nb_values, __attribute__((unused)) const SynchronizerOperation & op) {} template <typename T> inline void allGather(__attribute__((unused)) T * values, __attribute__((unused)) int nb_values) {} template <typename T> inline void allGatherV(__attribute__((unused)) T * values, __attribute__((unused)) int * nb_values) {} template <typename T> inline void gather(__attribute__((unused)) T * values, __attribute__((unused)) int nb_values, __attribute__((unused)) int root = 0) {} template <typename T> inline void gatherV(__attribute__((unused)) T * values, __attribute__((unused)) int * nb_values, __attribute__((unused)) int root = 0) {} template <typename T> inline void broadcast(__attribute__((unused)) T * values, __attribute__((unused)) int nb_values, __attribute__((unused)) int root = 0) {} /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ int getMaxTag() { return std::numeric_limits<int>::max(); } int getMinTag() { return 0; } - + void finalize() {} /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ }; __END_AKANTU__ #endif /* __AKANTU_STATIC_COMMUNICATOR_DUMMY_HH__ */ diff --git a/src/synchronizer/static_communicator_mpi.cc b/src/synchronizer/static_communicator_mpi.cc index f6f25a63f..47ed3732b 100644 --- a/src/synchronizer/static_communicator_mpi.cc +++ b/src/synchronizer/static_communicator_mpi.cc @@ -1,492 +1,498 @@ /** * @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_PROD, MPI_LAND, MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR, MPI_BXOR, MPI_MINLOC, MPI_MAXLOC, MPI_OP_NULL }; class CommunicationRequestMPI : public CommunicationRequest { public: CommunicationRequestMPI(UInt source, UInt dest); ~CommunicationRequestMPI(); MPI_Request * getMPIRequest() { return request; }; private: MPI_Request * request; }; /* -------------------------------------------------------------------------- */ /* Implementation */ /* -------------------------------------------------------------------------- */ CommunicationRequestMPI::CommunicationRequestMPI(UInt source, UInt dest) : CommunicationRequest(source, dest) { request = new MPI_Request; } /* -------------------------------------------------------------------------- */ CommunicationRequestMPI::~CommunicationRequestMPI() { delete request; } /* -------------------------------------------------------------------------- */ StaticCommunicatorMPI::StaticCommunicatorMPI(int & argc, char ** & argv) : RealStaticCommunicator(argc, argv) { - 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() { + +} + +/* -------------------------------------------------------------------------- */ +void StaticCommunicatorMPI::finalize() { MPI_Finalize(); } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::send(T * buffer, Int size, Int receiver, Int tag) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Send(buffer, size, type, receiver, tag, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Send."); } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::receive(T * buffer, Int size, Int sender, Int tag) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Status status; MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Recv(buffer, size, type, sender, tag, communicator, &status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Recv."); } /* -------------------------------------------------------------------------- */ template<typename T> CommunicationRequest * StaticCommunicatorMPI::asyncSend(T * buffer, Int size, Int receiver, Int tag) { MPI_Comm communicator = mpi_data->getMPICommunicator(); CommunicationRequestMPI * request = new CommunicationRequestMPI(prank, receiver); MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Isend(buffer, size, type, receiver, tag, communicator, request->getMPIRequest()); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Isend."); return request; } /* -------------------------------------------------------------------------- */ template<typename T> CommunicationRequest * StaticCommunicatorMPI::asyncReceive(T * buffer, Int size, Int sender, Int tag) { MPI_Comm communicator = mpi_data->getMPICommunicator(); CommunicationRequestMPI * request = new CommunicationRequestMPI(sender, prank); MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Irecv(buffer, size, type, sender, tag, communicator, request->getMPIRequest()); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Irecv."); return request; } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::probe(Int sender, Int tag, CommunicationStatus & status) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Status mpi_status; #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Probe(sender, tag, communicator, &mpi_status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Probe."); MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); int count; MPI_Get_count(&mpi_status, type, &count); status.setSource(mpi_status.MPI_SOURCE); status.setTag(mpi_status.MPI_TAG); status.setSize(count); } /* -------------------------------------------------------------------------- */ bool StaticCommunicatorMPI::testRequest(CommunicationRequest * request) { MPI_Status status; int flag; CommunicationRequestMPI * req_mpi = static_cast<CommunicationRequestMPI *>(request); MPI_Request * req = req_mpi->getMPIRequest(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Test(req, &flag, &status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Test."); return (flag != 0); } /* -------------------------------------------------------------------------- */ void StaticCommunicatorMPI::wait(CommunicationRequest * request) { MPI_Status status; CommunicationRequestMPI * req_mpi = static_cast<CommunicationRequestMPI *>(request); MPI_Request * req = req_mpi->getMPIRequest(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Wait(req, &status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Wait."); } /* -------------------------------------------------------------------------- */ void StaticCommunicatorMPI::waitAll(std::vector<CommunicationRequest *> & requests) { MPI_Status status; std::vector<CommunicationRequest *>::iterator it; for(it = requests.begin(); it != requests.end(); ++it) { MPI_Request * req = static_cast<CommunicationRequestMPI *>(*it)->getMPIRequest(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Wait(req, &status); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Wait."); } } /* -------------------------------------------------------------------------- */ void StaticCommunicatorMPI::barrier() { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Barrier(communicator); } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::reduce(T * values, int nb_values, const SynchronizerOperation & op, int root) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Reduce(MPI_IN_PLACE, values, nb_values, type, MPITypeWrapper::getMPISynchronizerOperation(op), root, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Allreduce."); } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::allReduce(T * values, int nb_values, const SynchronizerOperation & op) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Allreduce(MPI_IN_PLACE, values, nb_values, type, MPITypeWrapper::getMPISynchronizerOperation(op), communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Allreduce."); } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::allGather(T * values, int nb_values) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Allgather(MPI_IN_PLACE, nb_values, type, values, nb_values, type, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Allgather."); } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::allGatherV(T * values, int * nb_values) { MPI_Comm communicator = mpi_data->getMPICommunicator(); int * displs = new int[psize]; displs[0] = 0; for (int i = 1; i < psize; ++i) { displs[i] = displs[i-1] + nb_values[i-1]; } MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Allgatherv(MPI_IN_PLACE, *nb_values, type, values, nb_values, displs, type, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Gather."); delete [] displs; } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::gather(T * values, int nb_values, int root) { MPI_Comm communicator = mpi_data->getMPICommunicator(); T * send_buf = NULL, * recv_buf = NULL; if(prank == root) { send_buf = (T *) MPI_IN_PLACE; recv_buf = values; } else { send_buf = values; } MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Gather(send_buf, nb_values, type, recv_buf, nb_values, type, root, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Gather."); } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::gatherV(T * values, int * nb_values, int root) { MPI_Comm communicator = mpi_data->getMPICommunicator(); int * displs = NULL; if(prank == root) { displs = new int[psize]; displs[0] = 0; for (int i = 1; i < psize; ++i) { displs[i] = displs[i-1] + nb_values[i-1]; } } T * send_buf = NULL, * recv_buf = NULL; if(prank == root) { send_buf = (T *) MPI_IN_PLACE; recv_buf = values; } else send_buf = values; MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Gatherv(send_buf, *nb_values, type, recv_buf, nb_values, displs, type, root, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Gather."); if(prank == root) { delete [] displs; } } /* -------------------------------------------------------------------------- */ template<typename T> void StaticCommunicatorMPI::broadcast(T * values, int nb_values, int root) { MPI_Comm communicator = mpi_data->getMPICommunicator(); MPI_Datatype type = MPITypeWrapper::getMPIDatatype<T>(); #if !defined(AKANTU_NDEBUG) int ret = #endif MPI_Bcast(values, nb_values, type, root, communicator); AKANTU_DEBUG_ASSERT(ret == MPI_SUCCESS, "Error in MPI_Gather."); } /* -------------------------------------------------------------------------- */ int StaticCommunicatorMPI::getMaxTag() { return MPI_TAG_UB; } /* -------------------------------------------------------------------------- */ int StaticCommunicatorMPI::getMinTag() { return 0; } /* -------------------------------------------------------------------------- */ // template<typename T> // MPI_Datatype StaticCommunicatorMPI::getMPIDatatype() { // return MPI_DATATYPE_NULL; // } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<char>() { return MPI_CHAR; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<float>() { return MPI_FLOAT; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<double>() { return MPI_DOUBLE; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<long double>() { return MPI_LONG_DOUBLE; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<signed int>() { return MPI_INT; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned int>() { return MPI_UNSIGNED; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<signed long int>() { return MPI_LONG; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned long int>() { return MPI_UNSIGNED_LONG; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<signed long long int>() { return MPI_LONG_LONG; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype<unsigned long long int>() { return MPI_UNSIGNED_LONG_LONG; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype< SCMinMaxLoc<double, int> >() { return MPI_DOUBLE_INT; } template<> MPI_Datatype MPITypeWrapper::getMPIDatatype< SCMinMaxLoc<float, int> >() { return MPI_FLOAT_INT; } /* -------------------------------------------------------------------------- */ /* Template instantiation */ /* -------------------------------------------------------------------------- */ #define AKANTU_MPI_COMM_INSTANTIATE(T) \ template void StaticCommunicatorMPI::send<T> (T * buffer, Int size, Int receiver, Int tag); \ template void StaticCommunicatorMPI::receive<T>(T * buffer, Int size, Int sender, Int tag); \ template CommunicationRequest * StaticCommunicatorMPI::asyncSend<T> (T * buffer, Int size, Int receiver, Int tag); \ template CommunicationRequest * StaticCommunicatorMPI::asyncReceive<T>(T * buffer, Int size, Int sender, Int tag); \ template void StaticCommunicatorMPI::probe<T>(Int sender, Int tag, CommunicationStatus & status); \ template void StaticCommunicatorMPI::allGather<T> (T * values, int nb_values); \ template void StaticCommunicatorMPI::allGatherV<T>(T * values, int * nb_values); \ template void StaticCommunicatorMPI::gather<T> (T * values, int nb_values, int root); \ template void StaticCommunicatorMPI::gatherV<T>(T * values, int * nb_values, int root); \ template void StaticCommunicatorMPI::broadcast<T>(T * values, int nb_values, int root); \ template void StaticCommunicatorMPI::allReduce<T>(T * values, int nb_values, const SynchronizerOperation & op); AKANTU_MPI_COMM_INSTANTIATE(Real); AKANTU_MPI_COMM_INSTANTIATE(UInt); AKANTU_MPI_COMM_INSTANTIATE(Int); AKANTU_MPI_COMM_INSTANTIATE(char); template void StaticCommunicatorMPI::send<SCMinMaxLoc<Real,int> > (SCMinMaxLoc<Real,int> * buffer, Int size, Int receiver, Int tag); template void StaticCommunicatorMPI::receive<SCMinMaxLoc<Real,int> >(SCMinMaxLoc<Real,int> * buffer, Int size, Int sender, Int tag); template CommunicationRequest * StaticCommunicatorMPI::asyncSend<SCMinMaxLoc<Real,int> > (SCMinMaxLoc<Real,int> * buffer, Int size, Int receiver, Int tag); template CommunicationRequest * StaticCommunicatorMPI::asyncReceive<SCMinMaxLoc<Real,int> >(SCMinMaxLoc<Real,int> * buffer, Int size, Int sender, Int tag); template void StaticCommunicatorMPI::probe<SCMinMaxLoc<Real,int> >(Int sender, Int tag, CommunicationStatus & status); template void StaticCommunicatorMPI::allGather<SCMinMaxLoc<Real,int> > (SCMinMaxLoc<Real,int> * values, int nb_values); template void StaticCommunicatorMPI::allGatherV<SCMinMaxLoc<Real,int> >(SCMinMaxLoc<Real,int> * values, int * nb_values); template void StaticCommunicatorMPI::gather<SCMinMaxLoc<Real,int> > (SCMinMaxLoc<Real,int> * values, int nb_values, int root); template void StaticCommunicatorMPI::gatherV<SCMinMaxLoc<Real,int> >(SCMinMaxLoc<Real,int> * values, int * nb_values, int root); template void StaticCommunicatorMPI::broadcast<SCMinMaxLoc<Real,int> >(SCMinMaxLoc<Real,int> * values, int nb_values, int root); template void StaticCommunicatorMPI::allReduce<SCMinMaxLoc<Real,int> >(SCMinMaxLoc<Real,int> * values, int nb_values, const SynchronizerOperation & op); #if AKANTU_INTEGER_SIZE > 4 AKANTU_MPI_COMM_INSTANTIATE(int); #endif __END_AKANTU__ diff --git a/src/synchronizer/static_communicator_mpi.hh b/src/synchronizer/static_communicator_mpi.hh index 6f93f977a..16df1f879 100644 --- a/src/synchronizer/static_communicator_mpi.hh +++ b/src/synchronizer/static_communicator_mpi.hh @@ -1,128 +1,130 @@ /** * @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 gather (T * values, int nb_values, int root); template<typename T> void gatherV(T * values, int * nb_values, int root); template<typename T> void broadcast(T * values, int nb_values, int root); bool testRequest(CommunicationRequest * request); void wait (CommunicationRequest * request); void waitAll(std::vector<CommunicationRequest *> & requests); void barrier(); template<typename T> void reduce(T * values, int nb_values, const SynchronizerOperation & op, int root); template<typename T> void allReduce(T * values, int nb_values, const SynchronizerOperation & op); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: const MPITypeWrapper & getMPITypeWrapper() const { return *mpi_data; } MPITypeWrapper & getMPITypeWrapper() { return *mpi_data; } int getMinTag(); int getMaxTag(); + /// Finalize MPI + void finalize(); private: void setRank(int prank) { this->prank = prank; } void setSize(int psize) { this->psize = psize; } /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: friend class MPITypeWrapper; MPITypeWrapper * mpi_data; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #include "static_communicator_mpi_inline_impl.hh" __END_AKANTU__ #endif /* __AKANTU_STATIC_COMMUNICATOR_MPI_HH__ */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5ca640c77..ac9efb28a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,87 +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_fe_engine "Test finite element functionalties") add_akantu_test(test_mesh_utils "Test mesh utils") add_akantu_test(test_model "Test model objects") add_akantu_test(test_solver "Test solver function") add_akantu_test(test_io "Test the IO modules") add_akantu_test(test_contact "Test the contact part of Akantu") add_akantu_test(test_geometry "Test the geometry module of Akantu") - add_akantu_test(test_synchronizer "Test synchronizers") - - +add_akantu_test(test_python_interface "Test python interface") file(GLOB_RECURSE __all_files "*.*") set(_all_files) foreach(_file ${__all_files}) if("${_file}" MATCHES "${PROJECT_SOURCE_DIR}/test") file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_file}) list(APPEND _all_files ${__file}) endif() endforeach() file(GLOB_RECURSE __all_files "*CMakeLists.txt") foreach(_file ${__all_files}) if("${_file}" MATCHES "${PROJECT_SOURCE_DIR}/test") file(RELATIVE_PATH __file ${PROJECT_SOURCE_DIR} ${_file}) list(APPEND _cmakes ${__file}) endif() endforeach() list(APPEND AKANTU_TESTS_FILES ${_cmakes}) foreach(_file ${_all_files}) list(FIND AKANTU_TESTS_FILES ${_file} _ret) if(_ret EQUAL -1) list(APPEND AKANTU_TESTS_EXCLUDE_FILES /${_file}) endif() endforeach() set(AKANTU_TESTS_EXCLUDE_FILES ${AKANTU_TESTS_EXCLUDE_FILES} PARENT_SCOPE) #foreach(f ${AKANTU_TESTS_EXCLUDE_FILES}) # message(${f}) #endforeach() diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/.#back b/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/.#back deleted file mode 120000 index a7aa184ec..000000000 --- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_elasto_plastic_linear_isotropic_hardening/.#back +++ /dev/null @@ -1 +0,0 @@ -jcho@lsmspc46.epfl.ch.10152:1440501541 \ No newline at end of file diff --git a/test/test_python_interface/CMakeLists.txt b/test/test_python_interface/CMakeLists.txt new file mode 100644 index 000000000..f268e6b8b --- /dev/null +++ b/test/test_python_interface/CMakeLists.txt @@ -0,0 +1,37 @@ +#=============================================================================== +# @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/>. +# +#=============================================================================== +package_is_activated(python_interface _python_act) +if(_python_act) + add_test(test_multiple_init + python ${CMAKE_CURRENT_SOURCE_DIR}/test_multiple_init.py ${CMAKE_BINARY_DIR}) +endif() + +file(COPY input_test.dat mesh_dcb_2d.geo + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} + ) diff --git a/test/test_python_interface/input_test.dat b/test/test_python_interface/input_test.dat new file mode 100644 index 000000000..7a80374a7 --- /dev/null +++ b/test/test_python_interface/input_test.dat @@ -0,0 +1,23 @@ +material elastic [ + name = bulk + rho = 2500 + nu = 0.22 + E = 71e9 +# finite_deformation = 1 +] + +material cohesive_exponential [ + name = coh + sigma_c = 1.5e6 + beta = 1 + delta_c = 1e-4 + exponential_penalty = true + contact_tangent = 1.0 +] + +mesh parameters [ + + cohesive_surfaces = coh + +] + diff --git a/test/test_python_interface/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 100644 index 000000000..e2231b7a1 --- /dev/null +++ b/test/test_python_interface/test_multiple_init.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# =============================================================================== +# @file test_multiple_init.py +# +# @author Fabian Barras <fabian.barras@epfl.ch> +# +# @date creation: Tue Jan 5 2016 +# +# @brief Testing multiple initialize calls through Python +# +# @section LICENSE +# +# Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) +# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) +# +# Akantu is free software: you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Akantu. If not, see <http://www.gnu.org/licenses/>. +# +# =============================================================================== + +import sys +import os +from mpi4py import MPI + +comm = MPI.COMM_WORLD + +sys.path.append(sys.argv[1]+'/python/') +import akantu as aka +os.system('gmsh -order 2 -2 -o mesh_dcb_2d.msh mesh_dcb_2d.geo') +print('First initialisation') +aka.initialize('input_test.dat') +mesh = aka.Mesh(2) +mesh.read('mesh_dcb_2d.msh') +model = aka.SolidMechanicsModelCohesive(mesh) +model.initFull(aka.SolidMechanicsModelCohesiveOptions(aka._static)) +del model +del mesh +aka.clear() +print('Second initialisation') +aka.initialize('input_test.dat') +mesh = aka.Mesh(2) +mesh.read('mesh_dcb_2d.msh') +model = aka.SolidMechanicsModelCohesive(mesh) +model.initFull(aka.SolidMechanicsModelCohesiveOptions(aka._static)) +del model +del mesh +aka.finalize() +print('All right')