diff --git a/doc/dev-doc/conf.py.in b/doc/dev-doc/conf.py.in index 194a88f4e..92b37ec71 100644 --- a/doc/dev-doc/conf.py.in +++ b/doc/dev-doc/conf.py.in @@ -1,237 +1,238 @@ # -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a # full list see the documentation: # http://www.sphinx-doc.org/en/master/config # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # import os # import subprocess # import sys # sys.path.insert(0, os.path.abspath('.')) # -- Project information ----------------------------------------------------- project = '@PROJECT_NAME@' copyright = '@AKANTU_COPYRING@' author = '@AKANTU_MAINTAINER@' version = '@AKANTU_VERSION_MAJOR@.@AKANTU_VERSION_MINOR@' # The full version, including alpha/beta/rc tags release = '@AKANTU_VERSION@' # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Number figures numfig = True # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', 'sphinx.ext.mathjax', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', 'sphinxcontrib.bibtex', 'breathe', ] read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["CMakeLists.txt"] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' primary_domain = 'cpp' highlight_language = 'cpp' +bibtex_bibfiles = ['manual/manual-bibliography.bib'] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # if read_the_docs_build: html_theme = 'default' else: html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # The default sidebars (for documents that don't match any pattern) are # defined by theme itself. Builtin themes are using these templates by # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', # 'searchbox.html']``. # # html_sidebars = {} html_sidebars = { '**': [ 'relations.html', # needs 'show_related': True theme option to display 'searchbox.html', ]} math_eqref_format = "Eq. {number}" # MathJax configuration mathjax_config = { 'extensions': [ "tex2jax.js", "siunitx.js" ], 'TeX': { 'Macros': { 'st': [r'\mathrm{#1}', 1], 'mat': [r'\mathbf{#1}', 1], 'half': [r'\frac{1}{2}', 0], }, 'extensions': ["AMSmath.js", "AMSsymbols.js", "sinuitx.js"], }, } # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = 'Akantudoc' # -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # 'preamble': r'''\usepackage{amsmath}''', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'Akantu.tex', 'Akantu Documentation', 'Nicolas Richart', 'manual'), ] # -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'akantu', 'Akantu Documentation', [author], 1) ] # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'Akantu', 'Akantu Documentation', author, 'Akantu', 'One line description of project.', 'Miscellaneous'), ] # -- Options for Epub output ------------------------------------------------- # Bibliographic Dublin Core info. epub_title = project epub_author = author epub_publisher = author epub_copyright = copyright # The unique identifier of the text. This can be a ISBN number # or the project homepage. # epub_identifier = '' # A unique identification for the text. # # epub_uid = '' # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] # -- Extension configuration ------------------------------------------------- if read_the_docs_build: akantu_path = "." else: akantu_path = "@CMAKE_CURRENT_BINARY_DIR@" os.makedirs("@CMAKE_CURRENT_BINARY_DIR@/_static", exist_ok=True) # print("akantu_path = '{}'".format(akantu_path)) breathe_projects = {"Akantu": os.path.join(akantu_path, "xml")} breathe_default_project = "Akantu" breathe_default_members = ('members', 'undoc-members') breathe_implementation_filename_extensions = ['.c', '.cc', '.cpp'] breathe_show_enumvalue_initializer = True # -- Options for intersphinx extension --------------------------------------- intersphinx_mapping = { 'numpy': ('https://docs.scipy.org/doc/numpy/', None), 'scipy': ('https://docs.scipy.org/doc/scipy/reference', None), } diff --git a/doc/dev-doc/index.rst b/doc/dev-doc/index.rst index f4e37d8f8..19405e19b 100644 --- a/doc/dev-doc/index.rst +++ b/doc/dev-doc/index.rst @@ -1,46 +1,47 @@ .. Akantu documentation master file, created by sphinx-quickstart on Fri Apr 17 16:35:46 2020. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Akantu: a FEM library ===================== .. toctree:: :maxdepth: 2 :caption: User Manual ./manual/getting_started.rst ./manual/fe_engine.rst ./manual/solidmechanicsmodel.rst + ./manual/io.rst .. toctree:: :maxdepth: 2 :caption: Changelog ./changelog.rst .. toctree:: :maxdepth: 2 :caption: API Reference ./reference.rst .. toctree:: :maxdepth: 2 :caption: Appendix ./manual/appendix.rst .. toctree:: :maxdepth: 2 :caption: Bibliography ./manual/bibliography.rst Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` diff --git a/doc/dev-doc/manual/appendix/elements.rst b/doc/dev-doc/manual/appendix/elements.rst index 0105a39cc..22ce3e818 100644 --- a/doc/dev-doc/manual/appendix/elements.rst +++ b/doc/dev-doc/manual/appendix/elements.rst @@ -1,772 +1,743 @@ .. _app-elements: Shape Functions =============== Schematic 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 iso-parametric 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`. Iso-parametric Elements ----------------------- 1D-Shape Functions `````````````````` Segment 2 ''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`) * - 1 - -1 - :math:`\frac{1}{2}\left(1-\xi\right)` - :math:`-\frac{1}{2}` * - 2 - 1 - :math:`\frac{1}{2}\left(1+\xi\right)` - :math:`\frac{1}{2}` .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`) - - 0 - * - Weight + - Weight + * - 0 - 2 Segment 3 ''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`) * - 1 - -1 - :math:`\frac{1}{2}\xi\left(\xi-1\right)` - :math:`\xi-\frac{1}{2}` * - 2 - 1 - :math:`\frac{1}{2}\xi\left(\xi+1\right)` - :math:`\xi+\frac{1}{2}` * - 3 - 0 - :math:`1-\xi^{2}` - :math:`-2\xi` .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`) - - :math:`-1/\sqrt{3}` - - :math:`1/\sqrt{3}` - * - Weight + - Weight + * - :math:`-1/\sqrt{3}` - 1 + * - :math:`1/\sqrt{3}` - 1 2D-Shape Functions `````````````````` Triangle 3 '''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`) * - 1 - (:math:`0`, :math:`0`) - :math:`1-\xi-\eta` - (:math:`-1`, :math:`-1`) * - 2 - (:math:`1`, :math:`0`) - :math:`\xi` - (:math:`1`, :math:`0`) * - 3 - (:math:`0`, :math:`1`) - :math:`\eta` - (:math:`0`, :math:`1`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`) - - (:math:`\frac{1}{3}`, :math:`\frac{1}{3}`) - * - Weight + - Weight + * - (:math:`\frac{1}{3}`, :math:`\frac{1}{3}`) - :math:`\frac{1}{2}` Triangle 6 '''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`) * - 1 - (:math:`0`, :math:`0`) - :math:`-\left(1-\xi-\eta\right)\left(1-2\left(1-\xi-\eta\right)\right)` - (:math:`1-4\left(1-\xi-\eta\right)`, :math:`1-4\left(1-\xi-\eta\right)`) * - 2 - (:math:`1`, :math:`0`) - :math:`-\xi\left(1-2\xi\right)` - (:math:`4\xi-1`, :math:`0`) * - 3 - (:math:`0`, :math:`1`) - :math:`-\eta\left(1-2\eta\right)` - (:math:`0`, :math:`4\eta-1`) * - 4 - (:math:`\frac{1}{2}`, :math:`0`) - :math:`4\xi\left(1-\xi-\eta\right)` - (:math:`4\left(1-2\xi-\eta\right)`, :math:`-4\xi`) * - 5 - (:math:`\frac{1}{2}`, :math:`\frac{1}{2}`) - :math:`4\xi\eta` - (:math:`4\eta`, :math:`4\xi`) * - 6 - (:math:`0`, :math:`\frac{1}{2}`) - :math:`4\eta\left(1-\xi-\eta\right)` - (:math:`-4\eta`, :math:`4\left(1-\xi-2\eta\right)`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`) - - (:math:`\frac{1}{6}`, :math:`\frac{1}{6}`) - - (:math:`\frac{2}{3}`, :math:`\frac{1}{6}`) - - (:math:`\frac{1}{6}`, :math:`\frac{2}{3}`) - * - Weight + - Weight + * - (:math:`\frac{1}{6}`, :math:`\frac{1}{6}`) - :math:`\frac{1}{6}` + * - (:math:`\frac{2}{3}`, :math:`\frac{1}{6}`) - :math:`\frac{1}{6}` + * - (:math:`\frac{1}{6}`, :math:`\frac{2}{3}`) - :math:`\frac{1}{6}` Quadrangle 4 '''''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`) * - 1 - (:math:`-1`, :math:`-1`) - :math:`\frac{1}{4}\left(1-\xi\right)\left(1-\eta\right)` - (:math:`-\frac{1}{4}\left(1-\eta\right)`, :math:`-\frac{1}{4}\left(1-\xi\right)`) * - 2 - (:math:`1`, :math:`-1`) - :math:`\frac{1}{4}\left(1+\xi\right)\left(1-\eta\right)` - (:math:`\frac{1}{4}\left(1-\eta\right)`, :math:`-\frac{1}{4}\left(1+\xi\right)`) * - 3 - (:math:`1`, :math:`1`) - :math:`\frac{1}{4}\left(1+\xi\right)\left(1+\eta\right)` - (:math:`\frac{1}{4}\left(1+\eta\right)`, :math:`\frac{1}{4}\left(1+\xi\right)`) * - 4 - (:math:`-1`, :math:`1`) - :math:`\frac{1}{4}\left(1-\xi\right)\left(1+\eta\right)` - (:math:`-\frac{1}{4}\left(1+\eta\right)`, :math:`\frac{1}{4}\left(1-\xi\right)`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`) - - (:math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - - (:math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - - (:math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - - (:math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - * - Weight + - Weight + * - (:math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - 1 + * - (:math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - 1 + * - (:math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - 1 + * - (:math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - 1 Quadrangle 8 '''''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`) * - 1 - (:math:`-1`, :math:`-1`) - :math:`\frac{1}{4}\left(1-\xi\right)\left(1-\eta\right)\left(-1-\xi-\eta\right)` - (:math:`\frac{1}{4}\left(1-\eta\right)\left(2\xi+\eta\right)`, :math:`\frac{1}{4}\left(1-\xi\right)\left(\xi+2\eta\right)`) * - 2 - (:math:`1`, :math:`-1`) - :math:`\frac{1}{4}\left(1+\xi\right)\left(1-\eta\right)\left(-1+\xi-\eta\right)` - (:math:`\frac{1}{4}\left(1-\eta\right)\left(2\xi-\eta\right)`, :math:`-\frac{1}{4}\left(1+\xi\right)\left(\xi-2\eta\right)`) * - 3 - (:math:`1`, :math:`1`) - :math:`\frac{1}{4}\left(1+\xi\right)\left(1+\eta\right)\left(-1+\xi+\eta\right)` - (:math:`\frac{1}{4}\left(1+\eta\right)\left(2\xi+\eta\right)`, :math:`\frac{1}{4}\left(1+\xi\right)\left(\xi+2\eta\right)`) * - 4 - (:math:`-1`, :math:`1`) - :math:`\frac{1}{4}\left(1-\xi\right)\left(1+\eta\right)\left(-1-\xi+\eta\right)` - (:math:`\frac{1}{4}\left(1+\eta\right)\left(2\xi-\eta\right)`, :math:`-\frac{1}{4}\left(1-\xi\right)\left(\xi-2\eta\right)`) * - 5 - (:math:`0`, :math:`-1`) - :math:`\frac{1}{2}\left(1-\xi^{2}\right)\left(1-\eta\right)` - (:math:`-\xi\left(1-\eta\right)`, :math:`-\frac{1}{2}\left(1-\xi^{2}\right)`) * - 6 - (:math:`1`, :math:`0`) - :math:`\frac{1}{2}\left(1+\xi\right)\left(1-\eta^{2}\right)` - (:math:`\frac{1}{2}\left(1-\eta^{2}\right)`, :math:`-\eta\left(1+\xi\right)`) * - 7 - (:math:`0`, :math:`1`) - :math:`\frac{1}{2}\left(1-\xi^{2}\right)\left(1+\eta\right)` - (:math:`-\xi\left(1+\eta\right)`, :math:`\frac{1}{2}\left(1-\xi^{2}\right)`) * - 8 - (:math:`-1`, :math:`0`) - :math:`\frac{1}{2}\left(1-\xi\right)\left(1-\eta^{2}\right)` - (:math:`-\frac{1}{2}\left(1-\eta^{2}\right)`, :math:`-\eta\left(1-\xi\right)`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`) - - (:math:`0`, :math:`0`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - * - Weight + - Weight + * - (:math:`0`, :math:`0`) - :math:`\frac{64}{81}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{25}{81}` + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{25}{81}` + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{25}{81}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{25}{81}` - * - Coord. (:math:`\xi`, :math:`\eta`) - - (:math:`0`, :math:`\sqrt{\tfrac{3}{5}}`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`) - - (:math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`0`) - - - * - Weight + * - (:math:`0`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{40}{81}` + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`) - :math:`\frac{40}{81}` + * - (:math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{40}{81}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`0`) - :math:`\frac{40}{81}` - - + 3D-Shape Functions `````````````````` Tetrahedron 4 ''''''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`, :math:`\frac{\partial N_i}{\partial \zeta}`) * - 1 - (:math:`0`, :math:`0`, :math:`0`) - :math:`1-\xi-\eta-\zeta` - (:math:`-1`, :math:`-1`, :math:`-1`) * - 2 - (:math:`1`, :math:`0`, :math:`0`) - :math:`\xi` - (:math:`1`, :math:`0`, :math:`0`) * - 3 - (:math:`0`, :math:`1`, :math:`0`) - :math:`\eta` - (:math:`0`, :math:`1`, :math:`0`) * - 4 - (:math:`0`, :math:`0`, :math:`1`) - :math:`\zeta` - (:math:`0`, :math:`0`, :math:`1`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`\frac{1}{4}`, :math:`\frac{1}{4}`, :math:`\frac{1}{4}`) - * - Weight + - Weight + * - (:math:`\frac{1}{4}`, :math:`\frac{1}{4}`, :math:`\frac{1}{4}`) - :math:`\frac{1}{6}` Tetrahedron 10 '''''''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`, :math:`\frac{\partial N_i}{\partial \zeta}`) * - 1 - (:math:`0`, :math:`0`, :math:`0`) - :math:`\left(1-\xi-\eta-\zeta\right)\left(1-2\xi-2\eta-2\zeta\right)` - :math:`4\xi+4\eta+4\zeta-3`, :math:`4\xi+4\eta+4\zeta-3`, :math:`4\xi+4\eta+4\zeta-3` * - 2 - (:math:`1`, :math:`0`, :math:`0`) - :math:`\xi\left(2\xi-1\right)` - (:math:`4\xi-1`, :math:`0`, :math:`0`) * - 3 - (:math:`0`, :math:`1`, :math:`0`) - :math:`\eta\left(2\eta-1\right)` - (:math:`0`, :math:`4\eta-1`, :math:`0`) * - 4 - (:math:`0`, :math:`0`, :math:`1`) - :math:`\zeta\left(2\zeta-1\right)` - (:math:`0`, :math:`0`, :math:`4\zeta-1`) * - 5 - (:math:`\frac{1}{2}`, :math:`0`, :math:`0`) - :math:`4\xi\left(1-\xi-\eta-\zeta\right)` - (:math:`4-8\xi-4\eta-4\zeta`, :math:`-4\xi`, :math:`-4\xi`) * - 6 - (:math:`\frac{1}{2}`, :math:`\frac{1}{2}`, :math:`0`) - :math:`4\xi\eta` - (:math:`4\eta`, :math:`4\xi`, :math:`0`) * - 7 - (:math:`0`, :math:`\frac{1}{2}`, :math:`0`) - :math:`4\eta\left(1-\xi-\eta-\zeta\right)` - (:math:`-4\eta`, :math:`4-4\xi-8\eta-4\zeta`, :math:`-4\eta`) * - 8 - (:math:`0`, :math:`0`, :math:`\frac{1}{2}`) - :math:`4\zeta\left(1-\xi-\eta-\zeta\right)` - (:math:`-4\zeta`, :math:`-4\zeta`, :math:`4-4\xi-4\eta-8\zeta`) * - 9 - (:math:`\frac{1}{2}`, :math:`0`, :math:`\frac{1}{2}`) - :math:`4\xi\zeta` - (:math:`4\zeta`, :math:`0`, :math:`4\xi`) * - 10 - (:math:`0`, :math:`\frac{1}{2}`, :math:`\frac{1}{2}`) - :math:`4\eta\zeta` - (:math:`0`, :math:`4\zeta`, :math:`4\eta`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`) - - (:math:`\frac{5+3\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`) - * - Weight + - Weight + * - (:math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`) - :math:`\frac{1}{24}` + * - (:math:`\frac{5+3\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`) - :math:`\frac{1}{24}` - * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5+3\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`) - - (:math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5+3\sqrt{5}}{20}`) - * - Weight + * - (:math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5+3\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`) - :math:`\frac{1}{24}` + * - (:math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5-\sqrt{5}}{20}`, :math:`\frac{5+3\sqrt{5}}{20}`) - :math:`\frac{1}{24}` Hexahedron 8 '''''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`, :math:`\frac{\partial N_i}{\partial \zeta}`) * - 1 - (:math:`-1`, :math:`-1`, :math:`-1`) - :math:`\frac{1}{8}\left(1-\xi\right)\left(1-\eta\right)\left(1-\zeta\right)` - (:math:`-\frac{1}{8}\left(1-\eta\right)\left(1-\zeta\right)`, :math:`-\frac{1}{8}\left(1-\xi\right)\left(1-\zeta\right)`, :math:`3`) * - 2 - (:math:`1`, :math:`-1`, :math:`-1`) - :math:`\frac{1}{8}\left(1+\xi\right)\left(1-\eta\right)\left(1-\zeta\right)` - (:math:`\frac{1}{8}\left(1-\eta\right)\left(1-\zeta\right)`, :math:`-\frac{1}{8}\left(1+\xi\right)\left(1-\zeta\right)`, :math:`3`) * - 3 - (:math:`1`, :math:`1`, :math:`-1`) - :math:`\frac{1}{8}\left(1+\xi\right)\left(1+\eta\right)\left(1-\zeta\right)` - (:math:`\frac{1}{8}\left(1+\eta\right)\left(1-\zeta\right)`, :math:`\frac{1}{8}\left(1+\xi\right)\left(1-\zeta\right)`, :math:`3`) * - 4 - (:math:`-1`, :math:`1`, :math:`-1`) - :math:`\frac{1}{8}\left(1-\xi\right)\left(1+\eta\right)\left(1-\zeta\right)` - (:math:`-\frac{1}{8}\left(1+\eta\right)\left(1-\zeta\right)`, :math:`\frac{1}{8}\left(1-\xi\right)\left(1-\zeta\right)`, :math:`3`) * - 5 - (:math:`-1`, :math:`-1`, :math:`1`) - :math:`\frac{1}{8}\left(1-\xi\right)\left(1-\eta\right)\left(1+\zeta\right)` - (:math:`-\frac{1}{8}\left(1-\eta\right)\left(1+\zeta\right)`, :math:`-\frac{1}{8}\left(1-\xi\right)\left(1+\zeta\right)`, :math:`3`) * - 6 - (:math:`1`, :math:`-1`, :math:`1`) - :math:`\frac{1}{8}\left(1+\xi\right)\left(1-\eta\right)\left(1+\zeta\right)` - (:math:`\frac{1}{8}\left(1-\eta\right)\left(1+\zeta\right)`, :math:`-\frac{1}{8}\left(1+\xi\right)\left(1+\zeta\right)`, :math:`3`) * - 7 - (:math:`1`, :math:`1`, :math:`1`) - :math:`\frac{1}{8}\left(1+\xi\right)\left(1+\eta\right)\left(1+\zeta\right)` - (:math:`\frac{1}{8}\left(1+\eta\right)\left(1+\zeta\right)`, :math:`\frac{1}{8}\left(1+\xi\right)\left(1+\zeta\right)`, :math:`3`) * - 8 - (:math:`-1`, :math:`1`, :math:`1`) - :math:`\frac{1}{8}\left(1-\xi\right)\left(1+\eta\right)\left(1+\zeta\right)` - (:math:`-\frac{1}{8}\left(1+\eta\right)\left(1+\zeta\right)`, :math:`\frac{1}{8}\left(1-\xi\right)\left(1+\zeta\right)`, :math:`3`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - - (:math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - - (:math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - - (:math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - * - Weight + - Weight + * - (:math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - 1 + * - (:math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - 1 + * - (:math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - 1 + * - (:math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`) - 1 - * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - - (:math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - - (:math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - - (:math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - * - Weight + * - (:math:`-\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - 1 + * - (:math:`\frac{1}{\sqrt{3}}`, :math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - 1 + * - (:math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - 1 + * - (:math:`-\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`, :math:`\frac{1}{\sqrt{3}}`) - 1 Pentahedron 6 ''''''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`, :math:`\frac{\partial N_i}{\partial \zeta}`) * - 1 - (:math:`-1`, :math:`1`, :math:`0`) - :math:`\frac{1}{2}\left(1-\xi\right)\eta` - (:math:`-\frac{1}{2}\eta`, :math:`\frac{1}{2}\left(1-\xi\right)`, :math:`3`) * - 2 - (:math:`-1`, :math:`0`, :math:`1`) - :math:`\frac{1}{2}\left(1-\xi\right)\zeta` - (:math:`-\frac{1}{2}\zeta`, :math:`0.0`, :math:`3`) * - 3 - (:math:`-1`, :math:`0`, :math:`0`) - :math:`\frac{1}{2}\left(1-\xi\right)\left(1-\eta-\zeta\right)` - (:math:`-\frac{1}{2}\left(1-\eta-\zeta\right)`, :math:`-\frac{1}{2}\left(1-\xi\right)`, :math:`3`) * - 4 - (:math:`1`, :math:`1`, :math:`0`) - :math:`\frac{1}{2}\left(1+\xi\right)\eta` - (:math:`\frac{1}{2}\eta`, :math:`\frac{1}{2}\left(1+\xi\right)`, :math:`3`) * - 5 - (:math:`1`, :math:`0`, :math:`1`) - :math:`\frac{1}{2}\left(1+\xi\right)\zeta` - (:math:`\frac{1}{2}\zeta`, :math:`0.0`, :math:`3`) * - 6 - (:math:`1`, :math:`0`, :math:`0`) - :math:`\frac{1}{2}\left(1+\xi\right)\left(1-\eta-\zeta\right)` - (:math:`\frac{1}{2}\left(1-\eta-\zeta\right)`, :math:`-\frac{1}{2}\left(1+\xi\right)`, :math:`3`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`-\frac{1}{\sqrt{3}}`, :math:`0.5`, :math:`0.5`) - - - (:math:`-\frac{1}{\sqrt{3}}`, :math:`0.0`, :math:`0.5`) - - - (:math:`-\frac{1}{\sqrt{3}}`, :math:`0.5`, :math:`0.0`) - - - (:math:`\frac{1}{\sqrt{3}}`, :math:`0.5`, :math:`0.5`) - - - (:math:`\frac{1}{\sqrt{3}}`, :math:`0.0`, :math:`0.5`) - - - (:math:`\frac{1}{\sqrt{3}}`, :math:`0.5`, :math:`0.0`) - * - Weight + - Weight + * - (:math:`-\frac{1}{\sqrt{3}}`, :math:`0.5`, :math:`0.5`) - :math:`\frac{1}{6}` + * - (:math:`-\frac{1}{\sqrt{3}}`, :math:`0.0`, :math:`0.5`) - :math:`\frac{1}{6}` + * - (:math:`-\frac{1}{\sqrt{3}}`, :math:`0.5`, :math:`0.0`) - :math:`\frac{1}{6}` + * - (:math:`\frac{1}{\sqrt{3}}`, :math:`0.5`, :math:`0.5`) - :math:`\frac{1}{6}` + * - (:math:`\frac{1}{\sqrt{3}}`, :math:`0.0`, :math:`0.5`) - :math:`\frac{1}{6}` + * - (:math:`\frac{1}{\sqrt{3}}`, :math:`0.5`, :math:`0.0`) - :math:`\frac{1}{6}` Hexahedron 20 ''''''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`, :math:`\frac{\partial N_i}{\partial \zeta}`) * - 1 - (:math:`-1`, :math:`-1`, :math:`-1`) - :math:`\frac{1}{8}\left(1-\xi\right)\left(1-\eta\right)\left(1-\zeta\right)\left(-2-\xi-\eta-\zeta\right)` - (:math:`\frac{1}{4}\left(\xi+\frac{1}{2}\left(\eta+\zeta+1\right)\right)\left(\eta-1\right)\left(\zeta-1\right)`, :math:`\frac{1}{4}\left(\eta+\frac{1}{2}\left(\xi+\zeta+1\right)\right)\left(\xi-1\right)\left(\zeta-1\right)`, :math:`3`) * - 2 - (:math:`1`, :math:`-1`, :math:`-1`) - :math:`\frac{1}{8}\left(1+\xi\right)\left(1-\eta\right)\left(1-\zeta\right)\left(-2+\xi-\eta-\zeta\right)` - (:math:`\frac{1}{4}\left(\xi-\frac{1}{2}\left(\eta+\zeta+1\right)\right)\left(\eta-1\right)\left(\zeta-1\right)`, :math:`-\frac{1}{4}\left(\eta-\frac{1}{2}\left(\xi-\zeta-1\right)\right)\left(\xi+1\right)\left(\zeta-1\right)`, :math:`3`) * - 3 - (:math:`1`, :math:`1`, :math:`-1`) - :math:`\frac{1}{8}\left(1+\xi\right)\left(1+\eta\right)\left(1-\zeta\right)\left(-2+\xi+\eta-\zeta\right)` - (:math:`-\frac{1}{4}\left(\xi+\frac{1}{2}\left(\eta-\zeta-1\right)\right)\left(\eta+1\right)\left(\zeta-1\right)`, :math:`-\frac{1}{4}\left(\eta+\frac{1}{2}\left(\xi-\zeta-1\right)\right)\left(\xi+1\right)\left(\zeta-1\right)`, :math:`3`) * - 4 - (:math:`-1`, :math:`1`, :math:`-1`) - :math:`\frac{1}{8}\left(1-\xi\right)\left(1+\eta\right)\left(1-\zeta\right)\left(-2-\xi+\eta-\zeta\right)` - (:math:`-\frac{1}{4}\left(\xi-\frac{1}{2}\left(\eta-\zeta-1\right)\right)\left(\eta+1\right)\left(\zeta-1\right)`, :math:`\frac{1}{4}\left(\eta-\frac{1}{2}\left(\xi+\zeta+1\right)\right)\left(\xi-1\right)\left(\zeta-1\right)`, :math:`3`) * - 5 - (:math:`-1`, :math:`-1`, :math:`1`) - :math:`\frac{1}{8}\left(1-\xi\right)\left(1-\eta\right)\left(1+\zeta\right)\left(-2-\xi-\eta+\zeta\right)` - (:math:`-\frac{1}{4}\left(\xi+\frac{1}{2}\left(\eta-\zeta+1\right)\right)\left(\eta-1\right)\left(\zeta+1\right)`, :math:`-\frac{1}{4}\left(\eta+\frac{1}{2}\left(\xi-\zeta+1\right)\right)\left(\xi-1\right)\left(\zeta+1\right)`, :math:`3`) * - 6 - (:math:`1`, :math:`-1`, :math:`1`) - :math:`\frac{1}{8}\left(1+\xi\right)\left(1-\eta\right)\left(1+\zeta\right)\left(-2+\xi-\eta+\zeta\right)` - (:math:`-\frac{1}{4}\left(\xi-\frac{1}{2}\left(\eta-\zeta+1\right)\right)\left(\eta-1\right)\left(\zeta+1\right)`, :math:`\frac{1}{4}\left(\eta-\frac{1}{2}\left(\xi+\zeta-1\right)\right)\left(\xi+1\right)\left(\zeta+1\right)`, :math:`3`) * - 7 - (:math:`1`, :math:`1`, :math:`1`) - :math:`\frac{1}{8}\left(1+\xi\right)\left(1+\eta\right)\left(1+\zeta\right)\left(-2+\xi+\eta+\zeta\right)` - (:math:`\frac{1}{4}\left(\xi+\frac{1}{2}\left(\eta+\zeta-1\right)\right)\left(\eta+1\right)\left(\zeta+1\right)`, :math:`\frac{1}{4}\left(\eta+\frac{1}{2}\left(\xi+\zeta-1\right)\right)\left(\xi+1\right)\left(\zeta+1\right)`, :math:`3`) * - 8 - (:math:`-1`, :math:`1`, :math:`1`) - :math:`\frac{1}{8}\left(1-\xi\right)\left(1+\eta\right)\left(1+\zeta\right)\left(-2-\xi+\eta+\zeta\right)` - (:math:`\frac{1}{4}\left(\xi-\frac{1}{2}\left(\eta+\zeta-1\right)\right)\left(\eta+1\right)\left(\zeta+1\right)`, :math:`-\frac{1}{4}\left(\eta-\frac{1}{2}\left(\xi-\zeta+1\right)\right)\left(\xi-1\right)\left(\zeta+1\right)`, :math:`3`) * - 9 - (:math:`0`, :math:`-1`, :math:`-1`) - :math:`\frac{1}{4}\left(1-\xi^{2}\right)\left(1-\eta\right)\left(1-\zeta\right)` - (:math:`-\frac{1}{2}\xi\left(\eta-1\right)\left(\zeta-1\right)`, :math:`-\frac{1}{4}\left(\xi^{2}-1\right)\left(\zeta-1\right)`, :math:`3`) * - 10 - (:math:`1`, :math:`0`, :math:`-1`) - :math:`\frac{1}{4}\left(1+\xi\right)\left(1-\eta^{2}\right)\left(1-\zeta\right)` - (:math:`\frac{1}{4}\left(\eta^{2}-1\right)\left(\zeta-1\right)`, :math:`\frac{1}{2}\eta\left(\xi+1\right)\left(\zeta-1\right)`, :math:`3`) * - 11 - (:math:`0`, :math:`1`, :math:`-1`) - :math:`\frac{1}{4}\left(1-\xi^{2}\right)\left(1+\eta\right)\left(1-\zeta\right)` - (:math:`\frac{1}{2}\xi\left(\eta+1\right)\left(\zeta-1\right)`, :math:`\frac{1}{4}\left(\xi^{2}-1\right)\left(\zeta-1\right)`, :math:`3`) * - 12 - (:math:`-1`, :math:`0`, :math:`-1`) - :math:`\frac{1}{4}\left(1-\xi\right)\left(1-\eta^{2}\right)\left(1-\zeta\right)` - (:math:`-\frac{1}{4}\left(\eta^{2}-1\right)\left(\zeta-1\right)`, :math:`-\frac{1}{2}\eta\left(\xi-1\right)\left(\zeta-1\right)`, :math:`3`) * - 13 - (:math:`-1`, :math:`-1`, :math:`0`) - :math:`\frac{1}{4}\left(1-\xi\right)\left(1-\eta\right)\left(1-\zeta^{2}\right)` - (:math:`-\frac{1}{4}\left(\eta-1\right)\left(\zeta^{2}-1\right)`, :math:`-\frac{1}{4}\left(\xi-1\right)\left(\zeta^{2}-1\right)`, :math:`3`) * - 14 - (:math:`1`, :math:`-1`, :math:`0`) - :math:`\frac{1}{4}\left(1+\xi\right)\left(1-\eta\right)\left(1-\zeta^{2}\right)` - (:math:`\frac{1}{4}\left(\eta-1\right)\left(\zeta^{2}-1\right)`, :math:`\frac{1}{4}\left(\xi+1\right)\left(\zeta^{2}-1\right)`, :math:`3`) * - 15 - (:math:`1`, :math:`1`, :math:`0`) - :math:`\frac{1}{4}\left(1+\xi\right)\left(1+\eta\right)\left(1-\zeta^{2}\right)` - (:math:`-\frac{1}{4}\left(\eta+1\right)\left(\zeta^{2}-1\right)`, :math:`-\frac{1}{4}\left(\xi+1\right)\left(\zeta^{2}-1\right)`, :math:`3`) * - 16 - (:math:`-1`, :math:`1`, :math:`0`) - :math:`\frac{1}{4}\left(1-\xi\right)\left(1+\eta\right)\left(1-\zeta^{2}\right)` - (:math:`\frac{1}{4}\left(\eta+1\right)\left(\zeta^{2}-1\right)`, :math:`\frac{1}{4}\left(\xi-1\right)\left(\zeta^{2}-1\right)`, :math:`3`) * - 17 - (:math:`0`, :math:`-1`, :math:`1`) - :math:`\frac{1}{4}\left(1-\xi^{2}\right)\left(1-\eta\right)\left(1+\zeta\right)` - (:math:`\frac{1}{2}\xi\left(\eta-1\right)\left(\zeta+1\right)`, :math:`\frac{1}{4}\left(\xi^{2}-1\right)\left(\zeta+1\right)`, :math:`3`) * - 18 - (:math:`1`, :math:`0`, :math:`1`) - :math:`\frac{1}{4}\left(1+\xi\right)\left(1-\eta^{2}\right)\left(1+\zeta\right)` - (:math:`-\frac{1}{4}\left(\eta^{2}-1\right)\left(\zeta+1\right)`, :math:`-\frac{1}{2}\eta\left(\xi+1\right)\left(\zeta+1\right)`, :math:`3`) * - 19 - (:math:`0`, :math:`1`, :math:`1`) - :math:`\frac{1}{4}\left(1-\xi^{2}\right)\left(1+\eta\right)\left(1+\zeta\right)` - (:math:`-\frac{1}{2}\xi\left(\eta+1\right)\left(\zeta+1\right)`, :math:`-\frac{1}{4}\left(\xi^{2}-1\right)\left(\zeta+1\right)`, :math:`3`) * - 20 - (:math:`-1`, :math:`0`, :math:`1`) - :math:`\frac{1}{4}\left(1-\xi\right)\left(1-\eta^{2}\right)\left(1+\zeta\right)` - (:math:`\frac{1}{4}\left(\eta^{2}-1\right)\left(\zeta+1\right)`, :math:`\frac{1}{2}\eta\left(\xi-1\right)\left(\zeta+1\right)`, :math:`3`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`) - * - Weight + - Weight + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{125}{729}` + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`) - :math:`\frac{200}{729}` + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{125}{729}` + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{200}{729}` - * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`0`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`\sqrt{\tfrac{3}{5}}`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`0`) - * - Weight + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`0`) - :math:`\frac{320}{729}` + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{200}{729}` + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{125}{729}` + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`0`) - :math:`\frac{200}{729}` - * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - - (:math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - - (:math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`) - - (:math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - * - Weight + * - (:math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{125}{729}` + * - (:math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{200}{729}` + * - (:math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`) - :math:`\frac{320}{729}` + * - (:math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{200}{729}` - * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`0`, :math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`) - - (:math:`0`, :math:`0`, :math:`0`) - - (:math:`0`, :math:`0`, :math:`\sqrt{\tfrac{3}{5}}`) - - (:math:`0`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - * - Weight + * - (:math:`0`, :math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{320}{729}` + * - (:math:`0`, :math:`0`, :math:`0`) - :math:`\frac{512}{729}` + * - (:math:`0`, :math:`0`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{320}{729}` + * - (:math:`0`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{200}{729}` - * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`0`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`0`) - - (:math:`0`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`) - * - Weight + * - (:math:`0`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`0`) - :math:`\frac{320}{729}` + * - (:math:`0`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{200}{729}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{125}{729}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`0`) - :math:`\frac{200}{729}` - * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`0`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`\sqrt{\tfrac{3}{5}}`) - * - Weight + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{125}{729}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{200}{729}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`0`) - :math:`\frac{320}{729}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`0`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{200}{729}` - * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`0`) - - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - - - * - Weight + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`-\sqrt{\tfrac{3}{5}}`) - :math:`\frac{125}{729}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`0`) - :math:`\frac{200}{729}` + * - (:math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`, :math:`\sqrt{\tfrac{3}{5}}`) - :math:`\frac{125}{729}` - - Pentahedron 15 '''''''''''''' .. list-table:: Elements properties :header-rows: 1 * - Node (:math:`i`) - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - Shape function (:math:`N_i`) - Derivative (:math:`\frac{\partial N_i}{\partial \xi}`, :math:`\frac{\partial N_i}{\partial \eta}`, :math:`\frac{\partial N_i}{\partial \zeta}`) * - 1 - (:math:`-1`, :math:`1`, :math:`0`) - :math:`\frac{1}{2}\eta\left(1-\xi\right)\left(2\eta-2-\xi\right)` - (:math:`\frac{1}{2}\eta\left(2\xi-2\eta+1\right)`, :math:`-\frac{1}{2}\left(\xi-1\right)\left(4\eta-\xi-2\right)`, :math:`3`) * - 2 - (:math:`-1`, :math:`0`, :math:`1`) - :math:`\frac{1}{2}\zeta\left(1-\xi\right)\left(2\zeta-2-\xi\right)` - (:math:`\frac{1}{2}\zeta\left(2\xi-2\zeta+1\right)`, :math:`0.0`, :math:`3`) * - 3 - (:math:`-1`, :math:`0`, :math:`0`) - :math:`\frac{1}{2}\left(\xi-1\right)\left(1-\eta-\zeta\right)\left(\xi+2\eta+2\zeta\right)` - (:math:`-\frac{1}{2}\left(2\xi+2\eta+2\zeta-1\right)\left(\eta+\zeta-1\right)`, :math:`-\frac{1}{2}\left(\xi-1\right)\left(4\eta+\xi+2\left(2\zeta-1\right)\right)`, :math:`3`) * - 4 - (:math:`1`, :math:`1`, :math:`0`) - :math:`\frac{1}{2}\eta\left(1+\xi\right)\left(2\eta-2+\xi\right)` - (:math:`\frac{1}{2}\eta\left(2\xi+2\eta-1\right)`, :math:`\frac{1}{2}\left(\xi+1\right)\left(4\eta+\xi-2\right)`, :math:`3`) * - 5 - (:math:`1`, :math:`0`, :math:`1`) - :math:`\frac{1}{2}\zeta\left(1+\xi\right)\left(2\zeta-2+\xi\right)` - (:math:`\frac{1}{2}\zeta\left(2\xi+2\zeta-1\right)`, :math:`0.0`, :math:`3`) * - 6 - (:math:`1`, :math:`0`, :math:`0`) - :math:`\frac{1}{2}\left(-\xi-1\right)\left(1-\eta-\zeta\right)\left(-\xi+2\eta+2\zeta\right)` - (:math:`-\frac{1}{2}\left(\eta+\zeta-1\right)\left(2\xi-2\eta-2\zeta+1\right)`, :math:`\frac{1}{2}\left(\xi+1\right)\left(4\eta-\xi+2\left(2\zeta-1\right)\right)`, :math:`3`) * - 7 - (:math:`-1`, :math:`0.5`, :math:`0.5`) - :math:`2\eta\zeta\left(1-\xi\right)` - (:math:`-2\eta\zeta`, :math:`-2\left(\xi-1\right)\zeta`, :math:`3`) * - 8 - (:math:`-1`, :math:`0`, :math:`0.5`) - :math:`2\zeta\left(1-\eta-\zeta\right)\left(1-\xi\right)` - (:math:`2\zeta\left(\eta+\zeta-1\right)`, :math:`2\zeta-\left(\xi-1\right)`, :math:`3`) * - 9 - (:math:`-1`, :math:`0.5`, :math:`0`) - :math:`2\eta\left(1-\xi\right)\left(1-\eta-\zeta\right)` - (:math:`2\eta\left(\eta+\zeta-1\right)`, :math:`2\left(2\eta+\zeta-1\right)\left(\xi-1\right)`, :math:`3`) * - 10 - (:math:`0`, :math:`1`, :math:`0`) - :math:`\eta\left(1-\xi^{2}\right)` - (:math:`-2\xi\eta`, :math:`-\left(\xi^{2}-1\right)`, :math:`3`) * - 11 - (:math:`0`, :math:`0`, :math:`1`) - :math:`\zeta\left(1-\xi^{2}\right)` - (:math:`-2\xi\zeta`, :math:`0.0`, :math:`3`) * - 12 - (:math:`0`, :math:`0`, :math:`0`) - :math:`\left(1-\xi^{2}\right)\left(1-\eta-\zeta\right)` - (:math:`2\xi\left(\eta+\zeta-1\right)`, :math:`\left(\xi^{2}-1\right)`, :math:`3`) * - 13 - (:math:`1`, :math:`0.5`, :math:`0.5`) - :math:`2\eta\zeta\left(1+\xi\right)` - (:math:`2\eta\zeta`, :math:`2\zeta\left(\xi+1\right)`, :math:`3`) * - 14 - (:math:`1`, :math:`0`, :math:`0.5`) - :math:`2\zeta\left(1+\xi\right)\left(1-\eta-\zeta\right)` - (:math:`-2\zeta\left(\eta+\zeta-1\right)`, :math:`-2\zeta\left(\xi+1\right)`, :math:`3`) * - 15 - (:math:`1`, :math:`0.5`, :math:`0`) - :math:`2\eta\left(1+\xi\right)\left(1-\eta-\zeta\right)` - (:math:`-2\eta\left(\eta+\zeta-1\right)`, :math:`-2\left(2\eta+\zeta-1\right)\left(\xi+1\right)`, :math:`3`) .. list-table:: Gaussian quadrature points :align: center * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`-{\tfrac{1}{\sqrt{3}}}`, :math:`\tfrac{1}{3}`, :math:`\tfrac{1}{3}`) - - (:math:`-{\tfrac{1}{\sqrt{3}}}`, :math:`0.6`, :math:`0.2`) - - - (:math:`-{\tfrac{1}{\sqrt{3}}}`, :math:`0.2`, :math:`0.6`) - - (:math:`-{\tfrac{1}{\sqrt{3}}}`, :math:`0.2`, :math:`0.2`) - * - Weight + - Weight + * - (:math:`-{\tfrac{1}{\sqrt{3}}}`, :math:`\tfrac{1}{3}`, :math:`\tfrac{1}{3}`) - -:math:`\frac{27}{96}` + * - (:math:`-{\tfrac{1}{\sqrt{3}}}`, :math:`0.6`, :math:`0.2`) - :math:`\frac{25}{96}` + * - (:math:`-{\tfrac{1}{\sqrt{3}}}`, :math:`0.2`, :math:`0.6`) - :math:`\frac{25}{96}` + * - (:math:`-{\tfrac{1}{\sqrt{3}}}`, :math:`0.2`, :math:`0.2`) - :math:`\frac{25}{96}` - * - Coord. (:math:`\xi`, :math:`\eta`, :math:`\zeta`) - - (:math:`{\tfrac{1}{\sqrt{3}}}`, :math:`\tfrac{1}{3}`, :math:`\tfrac{1}{3}`) - - (:math:`{\tfrac{1}{\sqrt{3}}}`, :math:`0.6`, :math:`0.2`) - - (:math:`{\tfrac{1}{\sqrt{3}}}`, :math:`0.2`, :math:`0.6`) - - (:math:`{\tfrac{1}{\sqrt{3}}}`, :math:`0.2`, :math:`0.2`) - * - Weight + * - (:math:`{\tfrac{1}{\sqrt{3}}}`, :math:`\tfrac{1}{3}`, :math:`\tfrac{1}{3}`) - -:math:`\frac{27}{96}` + * - (:math:`{\tfrac{1}{\sqrt{3}}}`, :math:`0.6`, :math:`0.2`) - :math:`\frac{25}{96}` + * - (:math:`{\tfrac{1}{\sqrt{3}}}`, :math:`0.2`, :math:`0.6`) - :math:`\frac{25}{96}` + * - (:math:`{\tfrac{1}{\sqrt{3}}}`, :math:`0.2`, :math:`0.2`) - :math:`\frac{25}{96}` diff --git a/doc/dev-doc/manual/constitutive-laws.rst b/doc/dev-doc/manual/constitutive-laws.rst index 2f9c0771a..c171c0584 100644 --- a/doc/dev-doc/manual/constitutive-laws.rst +++ b/doc/dev-doc/manual/constitutive-laws.rst @@ -1,572 +1,917 @@ .. _sect-smm-cl: Constitutive Laws ----------------- In order to compute an element’s response to deformation, one needs to use an appropriate constitutive relationship. The constitutive law is used to compute the element’s stresses from the element’s strains. In the finite-element discretization, the constitutive formulation is applied to every quadrature point of each element. When the implicit formulation is used, the tangent matrix has to be computed. | The chosen materials for the simulation have to be specified in the mesh file or, as an alternative, they can be assigned using the at ``element_material`` vector. For every material assigned to the problem one has to specify the material characteristics (constitutive behavior and material properties) using - the text input file (see `[sect:io:material] <#sect:io:material>`__). + the text input file (see :ref:`sect-io-material`). | In order to conveniently store values at each quadrature in a material point ``Akantu`` provides a special data structure, the at :cpp:class:`InternalField `. The internal fields are inheriting from the at :cpp:class:`ElementTypeMapArray `. Furthermore, it provides several functions for initialization, auto-resizing and auto removal of quadrature points. Sometimes it is also desired to generate random distributions of internal parameters. An example might be the critical stress at which the material fails. To generate such a field, in the text input file, a random quantity needs be added to the base value: All parameters are real numbers. For the uniform distribution, minimum and maximum values have to be specified. Random parameters are defined as a :math:`base` value to which we add a random number that follows the chosen distribution. The `Uniform `__ distribution is gives a random values between in :math:`[min, max)`. The `Weibull `__ distribution is characterized by the following cumulative distribution function: .. math:: F(x) = 1- e^{-\left({x/\lambda}\right)^m} which depends on :math:`m` and :math:`\lambda`, which are the shape parameter and the scale parameter. These random distributions are different each time the code is executed. In order to obtain always the same one, it possible to manually set the *seed* that is the number from which these pseudo-random distributions are created. This can be done by adding the following line to the input file *outside* the material parameters environments: .. code-block:: seed = 1.0 where the value 1.0 can be substituted with any number. Currently ``Akantu`` can reproduce always the same distribution when the seed is specified *only* in serial. The value of the *seed* can be also specified directly in the code (for instance in the main file) with the command: .. code-block:: RandGenerator::seed(1.0) The same command, with empty brackets, can be used to check the value of the *seed* used in the simulation. The following sections describe the constitutive models implemented in ``Akantu``. In Appendix `7 <#app:material-parameters>`__ a summary of the parameters for all materials of ``Akantu`` is provided. -Elasticity -`````````` +Elastic +``````` The elastic law is a commonly used constitutive relationship that can be used for a wide range of engineering materials (*e.g.*, metals, concrete, rock, wood, glass, rubber, etc.) provided that the strains remain small (*i.e.*, small deformation and stress lower than yield strength). The elastic laws are often expressed as :math:`\boldsymbol{\sigma} = \boldsymbol{C}:\boldsymbol{\varepsilon}` with where :math:`\boldsymbol{\sigma}` is the Cauchy stress tensor, :math:`\boldsymbol{\varepsilon}` represents the infinitesimal strain tensor and :math:`\boldsymbol{C}` is the elastic modulus tensor. .. _sect-smm-linear-elastic-isotropic: Linear isotropic '''''''''''''''' The linear isotropic elastic behavior is described by Hooke’s law, which states that the stress is linearly proportional to the applied strain (material behaves like an ideal spring), as illustrated in Figure `[fig:smm:cl:elastic] <#fig:smm:cl:elastic>`__. The equation that relates the strains to the displacements is: point) from the displacements as follows: .. math:: \label{eqn:smm:strain_inf} \boldsymbol{\varepsilon} = \frac{1}{2} \left[ \nabla_0 \boldsymbol{u}+\nabla_0 \boldsymbol{u}^T \right] where :math:`\boldsymbol{\varepsilon}` represents the infinitesimal strain tensor, :math:`\nabla_{0}\boldsymbol{u}` the displacement gradient tensor according to the initial configuration. The constitutive equation for isotropic homogeneous media can be expressed as: .. math:: \label{eqn:smm:material:constitutive_elastic} \boldsymbol{\sigma } =\lambda\mathrm{tr}(\boldsymbol{\varepsilon})\boldsymbol{I}+2 \mu\boldsymbol{\varepsilon} where :math:`\boldsymbol{\sigma}` is the Cauchy stress tensor (:math:`\lambda` and :math:`\mu` are the the first and second Lame’s coefficients). In Voigt notation this correspond to .. math:: \begin{aligned} \left[\begin{array}{c} \sigma_{11}\\ \sigma_{22}\\ \sigma_{33}\\ \sigma_{23}\\ \sigma_{13}\\ \sigma_{12}\\ \end{array}\right] &= \frac{E}{(1+\nu)(1-2\nu)}\left[ \begin{array}{cccccc} 1-\nu & \nu & \nu & 0 & 0 & 0\\ \nu & 1-\nu & \nu & 0 & 0 & 0\\ \nu & \nu & 1-\nu & 0 & 0 & 0\\ 0 & 0 & 0 & \frac{1-2\nu}{2} & 0 & 0 \\ 0 & 0 & 0 & 0 & \frac{1-2\nu}{2} & 0 \\ 0 & 0 & 0 & 0 & 0 & \frac{1-2\nu}{2} \\ \end{array}\right] \left[\begin{array}{c} \varepsilon_{11}\\ \varepsilon_{22}\\ \varepsilon_{33}\\ 2\varepsilon_{23}\\ 2\varepsilon_{13}\\ 2\varepsilon_{12}\\ \end{array}\right]\end{aligned} .. _sect-smm-linear-elastic-anisotropic: Linear anisotropic '''''''''''''''''' This formulation is not sufficient to represent all elastic material behavior. Some materials have characteristic orientation that have to be taken into account. To represent this anisotropy a more general stress-strain law has to be used. For this we define the elastic modulus tensor as follow: .. math:: \begin{aligned} \left[\begin{array}{c} \sigma_{11}\\ \sigma_{22}\\ \sigma_{33}\\ \sigma_{23}\\ \sigma_{13}\\ \sigma_{12}\\ \end{array}\right] &= \left[ \begin{array}{cccccc} c_{11} & c_{12} & c_{13} & c_{14} & c_{15} & c_{16}\\ c_{21} & c_{22} & c_{23} & c_{24} & c_{25} & c_{26}\\ c_{31} & c_{32} & c_{33} & c_{34} & c_{35} & c_{36}\\ c_{41} & c_{42} & c_{43} & c_{44} & c_{45} & c_{46}\\ c_{51} & c_{52} & c_{53} & c_{54} & c_{55} & c_{56}\\ c_{61} & c_{62} & c_{63} & c_{64} & c_{65} & c_{66}\\ \end{array}\right] \left[\begin{array}{c} \varepsilon_{11}\\ \varepsilon_{22}\\ \varepsilon_{33}\\ 2\varepsilon_{23}\\ 2\varepsilon_{13}\\ 2\varepsilon_{12}\\ \end{array}\right]\end{aligned} To simplify the writing of input files the :math:`\boldsymbol{C}` tensor is expressed in the material basis. And this basis as to be given too. This basis :math:`\Omega_{{\mathrm{mat}}} = \{\boldsymbol{n_1}, \boldsymbol{n_2}, \boldsymbol{n_3}\}` is used to define the rotation :math:`R_{ij} = \boldsymbol{n_j} . \boldsymbol{e_i}`. And :math:`\boldsymbol{C}` can be rotated in the global basis :math:`\Omega = \{\boldsymbol{e_1}, \boldsymbol{e_2}, \boldsymbol{e_3}\}` as follow: .. math:: \begin{aligned} \boldsymbol{C}_{\Omega} &= \boldsymbol{R}_1 \boldsymbol{C}_{\Omega_{{\mathrm{mat}}}} \boldsymbol{R}_2\\ \boldsymbol{R}_1 &= \left[ \begin{array}{cccccc} R_{11} R_{11} & R_{12} R_{12} & R_{13} R_{13} & R_{12} R_{13} & R_{11} R_{13} & R_{11} R_{12}\\ R_{21} R_{21} & R_{22} R_{22} & R_{23} R_{23} & R_{22} R_{23} & R_{21} R_{23} & R_{21} R_{22}\\ R_{31} R_{31} & R_{32} R_{32} & R_{33} R_{33} & R_{32} R_{33} & R_{31} R_{33} & R_{31} R_{32}\\ R_{21} R_{31} & R_{22} R_{32} & R_{23} R_{33} & R_{22} R_{33} & R_{21} R_{33} & R_{21} R_{32}\\ R_{11} R_{31} & R_{12} R_{32} & R_{13} R_{33} & R_{12} R_{33} & R_{11} R_{33} & R_{11} R_{32}\\ R_{11} R_{21} & R_{12} R_{22} & R_{13} R_{23} & R_{12} R_{23} & R_{11} R_{23} & R_{11} R_{22}\\ \end{array}\right]\\ \boldsymbol{R}_2 &= \left[ \begin{array}{cccccc} R_{11} R_{11} & R_{21} R_{21} & R_{31} R_{31} & R_{21} R_{31} & R_{11} R_{31} & R_{11} R_{21}\\ R_{12} R_{12} & R_{22} R_{22} & R_{32} R_{32} & R_{22} R_{32} & R_{12} R_{32} & R_{12} R_{22}\\ R_{13} R_{13} & R_{23} R_{23} & R_{33} R_{33} & R_{23} R_{33} & R_{13} R_{33} & R_{13} R_{23}\\ R_{12} R_{13} & R_{22} R_{23} & R_{32} R_{33} & R_{22} R_{33} & R_{12} R_{33} & R_{12} R_{23}\\ R_{11} R_{13} & R_{21} R_{23} & R_{31} R_{33} & R_{21} R_{33} & R_{11} R_{33} & R_{11} R_{23}\\ R_{11} R_{12} & R_{21} R_{22} & R_{31} R_{32} & R_{21} R_{32} & R_{11} R_{32} & R_{11} R_{22}\\ \end{array}\right]\\\end{aligned} .. _sect-smm-linear-elastic-orthotropic: Linear orthotropic '''''''''''''''''' A particular case of anisotropy is when the material basis is orthogonal in which case the elastic modulus tensor can be simplified and rewritten in terms of 9 independents material parameters. .. math:: \begin{aligned} \left[\begin{array}{c} \sigma_{11}\\ \sigma_{22}\\ \sigma_{33}\\ \sigma_{23}\\ \sigma_{13}\\ \sigma_{12}\\ \end{array}\right] &= \left[ \begin{array}{cccccc} c_{11} & c_{12} & c_{13} & 0 & 0 & 0 \\ & c_{22} & c_{23} & 0 & 0 & 0 \\ & & c_{33} & 0 & 0 & 0 \\ & & & c_{44} & 0 & 0 \\ & \multicolumn{2}{l}{\text{sym.}} & & c_{55} & 0 \\ & & & & & c_{66}\\ \end{array}\right] \left[\begin{array}{c} \varepsilon_{11}\\ \varepsilon_{22}\\ \varepsilon_{33}\\ 2\varepsilon_{23}\\ 2\varepsilon_{13}\\ 2\varepsilon_{12}\\ \end{array}\right]\end{aligned} .. math:: \begin{aligned} c_{11} &= E_1 (1 - \nu_{23}\nu_{32})\Gamma \qquad c_{22} = E_2 (1 - \nu_{13}\nu_{31})\Gamma \qquad c_{33} = E_3 (1 - \nu_{12}\nu_{21})\Gamma\\ c_{12} &= E_1 (\nu_{21} - \nu_{31}\nu_{23})\Gamma = E_2 (\nu_{12} - \nu_{32}\nu_{13})\Gamma\\ c_{13} &= E_1 (\nu_{31} - \nu_{21}\nu_{32})\Gamma = E_2 (\nu_{13} - \nu_{21}\nu_{23})\Gamma\\ c_{23} &= E_2 (\nu_{32} - \nu_{12}\nu_{31})\Gamma = E_3 (\nu_{23} - \nu_{21}\nu_{13})\Gamma\\ c_{44} &= \mu_{23} \qquad c_{55} = \mu_{13} \qquad c_{66} = \mu_{12} \\ \Gamma &= \frac{1}{1 - \nu_{12} \nu_{21} - \nu_{13} \nu_{31} - \nu_{32} \nu_{23} - 2 \nu_{21} \nu_{32} \nu_{13}}\end{aligned} The Poisson ratios follow the rule :math:`\nu_{ij} = \nu_{ji} E_i / E_j`. .. _sect-smm-cl-neohookean: Neo-Hookean ''''''''''' The hyperelastic Neo-Hookean constitutive law results from an extension of the linear elastic relationship (Hooke’s Law) for large deformation. Thus, the model predicts nonlinear stress-strain behavior for bodies undergoing large deformations. -.. figure:: figures/stress_strain_neo.pdf +.. figure:: figures/cl/stress_strain_neo.svg :alt: Neo-hookean Stress-strain curve. :name: fig:smm:cl:neo_hookean :width: 40.0% Neo-hookean Stress-strain curve. -As illustrated in Figure `4.6 <#fig:smm:cl:neo_hookean>`__, the behavior +As illustrated in :numref:`fig:smm:cl:neo_hookean`, the behavior is initially linear and the mechanical behavior is very close to the corresponding linear elastic material. This constitutive relationship, which accounts for compressibility, is a modified version of the one proposed by Ronald Rivlin :cite:`Belytschko:2000`. The strain energy stored in the material is given by: .. math:: \label{eqn:smm:constitutive:neohookean_potential} \Psi(\boldsymbol{C}) = \frac{1}{2}\lambda_0\left(\ln J\right)^2-\mu_0\ln J+\frac{1}{2} \mu_0\left(\mathrm{tr}(\boldsymbol{C})-3\right) where :math:`\lambda_0` and :math:`\mu_0` are, respectively, Lamé’s first parameter and the shear modulus at the initial configuration. :math:`J` is the jacobian of the deformation gradient (:math:`\boldsymbol{F}=\nabla_{\!\!\boldsymbol{X}}\boldsymbol{x}`): :math:`J=\text{det}(\boldsymbol{F})`. Finally :math:`\boldsymbol{C}` is the right Cauchy-Green deformation tensor. Since this kind of material is used for large deformation problems, a finite deformation framework should be used. Therefore, the Cauchy stress (:math:`\boldsymbol{\sigma}`) should be computed through the second Piola-Kirchhoff stress tensor :math:`\boldsymbol{S}`: .. math:: \boldsymbol{\sigma } = \frac{1}{J}\boldsymbol{F}\boldsymbol{S}\boldsymbol{F}^T Finally the second Piola-Kirchhoff stress tensor is given by: .. math:: \boldsymbol{S} = 2\frac{\partial\Psi}{\partial\boldsymbol{C}} = \lambda_0\ln J \boldsymbol{C}^{-1}+\mu_0\left(\boldsymbol{I}-\boldsymbol{C}^{-1}\right) The parameters to indicate in the material file are the same as those for the elastic case: ``E`` (Young’s modulus), ``nu`` (Poisson’s ratio). .. _sect-smm-cl-sls: Visco-Elasticity '''''''''''''''' Visco-elasticity is characterized by strain rate dependent behavior. Moreover, when such a material undergoes a deformation it dissipates energy. This dissipation results in a hysteresis loop in the stress-strain curve at every loading cycle (see -Figure `[fig:smm:cl:visco-elastic:hyst] <#fig:smm:cl:visco-elastic:hyst>`__). +:numref:`fig:smm:cl:visco-elastic:hyst`). In principle, it can be applied to many materials, since all materials exhibit a visco-elastic behavior if subjected to particular conditions (such as high temperatures). +.. figure:: figures/cl/stress_strain_visco.svg + :name: fig:smm:cl:visco-elastic:hyst + :align: center + :width: 40.0% + + Characteristic stress-strain behavior of a visco-elastic material with hysteresis loop + +.. figure:: figures/cl/visco_elastic_law.svg + :name: fig:smm:cl:visco-elastic:model + :align: center + :width: 40.0% + + Schematic representation of the standard rheological linear solid visco-elastic model + The standard rheological linear solid model (see Sections 10.2 and 10.3 of :cite:`simo92`) has been implemented in ``Akantu``. This model results from the combination of a spring mounted in parallel with a spring and a dashpot connected in series, as illustrated in -Figure `[fig:smm:cl:visco-elastic:model] <#fig:smm:cl:visco-elastic:model>`__. +:numref:`fig:smm:cl:visco-elastic:model`. The advantage of this model is that it allows to account for creep or stress relaxation. The equation that relates the stress to the strain is (in 1D): .. math:: \frac{d\varepsilon(t)}{dt} = \left ( E + E_V \right ) ^ {-1} \cdot \left [ \frac{d\sigma(t)}{dt} + \frac{E_V}{\eta}\sigma(t) - \frac{EE_V}{\eta}\varepsilon(t) \right ] where :math:`\eta` is the viscosity. The equilibrium condition is unique and is attained in the limit, as :math:`t \to \infty`. At this stage, the response is elastic and depends on the Young’s modulus :math:`E`. The mandatory parameters for the material file are the following: ``rho`` (density), ``E`` (Young’s modulus), ``nu`` (Poisson’s ratio), ``Plane_Stress`` (if set to zero plane strain, otherwise plane stress), ``eta`` (dashpot viscosity) and ``Ev`` (stiffness of the viscous element). Note that the current standard linear solid model is applied only on the deviatoric part of the strain tensor. The spheric part of the strain tensor affects the stress tensor like an linear elastic material. .. _sect-smm-cl-plastic: +Plastic +``````` + Small-Deformation Plasticity '''''''''''''''''''''''''''' The small-deformation plasticity is a simple plasticity material formulation which accounts for the additive decomposition of strain into elastic and plastic strain components. This formulation is applicable to infinitesimal deformation where the additive decomposition of the strain is a valid approximation. In this formulation, plastic strain is a shearing process where hydrostatic stress has no contribution to plasticity and consequently plasticity does not lead to volume change. -Figure `4.7 <#fig:smm:cl:Lin-strain-hard>`__ shows the linear strain +:numref:`fig:smm:cl:Lin-strain-hard` shows the linear strain hardening elasto-plastic behavior according to the additive decomposition of strain into the elastic and plastic parts in infinitesimal deformation as .. math:: \boldsymbol{\varepsilon} &= \boldsymbol{\varepsilon}^e +\boldsymbol{\varepsilon}^p\\ \boldsymbol{\sigma} &= 2G(\boldsymbol{\varepsilon}^e) + \lambda \mathrm{tr}(\boldsymbol{\varepsilon}^e)\boldsymbol{I} +.. figure:: figures/cl/isotropic_hardening_plasticity.svg + :name: fig:smm:cl:Lin-strain-hard + :align: center + + Stress-strain curve for the small-deformation plasticity with linear isotropic hardening. In this class, the von Mises yield criterion is used. In the von Mises yield criterion, the yield is independent of the hydrostatic stress. Other yielding criteria such as Tresca and Gurson can be easily implemented in this class as well. In the von Mises yield criterion, the hydrostatic stresses have no effect on the plasticity and consequently the yielding occurs when a critical elastic shear energy is achieved. .. math:: \label{eqn:smm:constitutive:von Mises} f = \sigma_{{\mathrm{eff}}} - \sigma_y = \left(\frac{3}{2} {\boldsymbol{\sigma}}^{{\mathrm{tr}}} : {\boldsymbol{\sigma}}^{{\mathrm{tr}}}\right)^\frac{1}{2}-\sigma_y (\boldsymbol{\varepsilon}^p) .. math:: \label{eqn:smm:constitutive:yielding} f < 0 \quad \textrm{Elastic deformation,} \qquad f = 0 \quad \textrm{Plastic deformation} where :math:`\sigma_y` is the yield strength of the material which can be function of plastic strain in case of hardening type of materials and :math:`{\boldsymbol{\sigma}}^{{\mathrm{tr}}}` is the deviatoric part of stress given by .. math:: \label{eqn:smm:constitutive:deviatoric stress} {\boldsymbol{\sigma}}^{{\mathrm{tr}}}=\boldsymbol{\sigma} - \frac{1}{3} \mathrm{tr}(\boldsymbol{\sigma}) \boldsymbol{I} After yielding :math:`(f = 0)`, the normality hypothesis of plasticity determines the direction of plastic flow which is normal to the tangent to the yielding surface at the load point. Then, the tensorial form of the plastic constitutive equation using the von Mises yielding criterion (see equation 4.34) may be written as .. math:: \label{eqn:smm:constitutive:plastic contitutive equation} \Delta {\boldsymbol{\varepsilon}}^p = \Delta p \frac {\partial{f}}{\partial{\boldsymbol{\sigma}}}=\frac{3}{2} \Delta p \frac{{\boldsymbol{\sigma}}^{{\mathrm{tr}}}}{\sigma_{{\mathrm{eff}}}} In these expressions, the direction of the plastic strain increment (or equivalently, plastic strain rate) is given by :math:`\frac{{\boldsymbol{\sigma}}^{{\mathrm{tr}}}}{\sigma_{{\mathrm{eff}}}}` while the magnitude is defined by the plastic multiplier :math:`\Delta p`. This can be obtained using the *consistency condition* which impose the requirement for the load point to remain on the yielding surface in the plastic regime. Here, we summarize the implementation procedures for the small-deformation plasticity with linear isotropic hardening: #. Compute the trial stress: .. math:: {\boldsymbol{\sigma}}^{{\mathrm{tr}}} = {\boldsymbol{\sigma}}_t + 2G\Delta \boldsymbol{\varepsilon} + \lambda \mathrm{tr}(\Delta \boldsymbol{\varepsilon})\boldsymbol{I} #. Check the Yielding criteria: .. math:: f = (\frac{3}{2} {\boldsymbol{\sigma}}^{{\mathrm{tr}}} : {\boldsymbol{\sigma}}^{{\mathrm{tr}}})^{1/2}-\sigma_y (\boldsymbol{\varepsilon}^p) #. Compute the Plastic multiplier: .. math:: \begin{aligned} d \Delta p &= \frac{\sigma^{tr}_{eff} - 3G \Delta P^{(k)}- \sigma_y^{(k)}}{3G + h}\\ \Delta p^{(k+1)} &= \Delta p^{(k)}+ d\Delta p\\ \sigma_y^{(k+1)} &= (\sigma_y)_t+ h\Delta p \end{aligned} #. Compute the plastic strain increment: .. math:: \Delta {\boldsymbol{\varepsilon}}^p = \frac{3}{2} \Delta p \frac{{\boldsymbol{\sigma}}^{{\mathrm{tr}}}}{\sigma_{{\mathrm{eff}}}} #. Compute the stress increment: .. math:: {\Delta \boldsymbol{\sigma}} = 2G(\Delta \boldsymbol{\varepsilon}-\Delta \boldsymbol{\varepsilon}^p) + \lambda \mathrm{tr}(\Delta \boldsymbol{\varepsilon}-\Delta \boldsymbol{\varepsilon}^p)\boldsymbol{I} #. Update the variables: .. math:: \begin{aligned} {\boldsymbol{\varepsilon^p}} &= {\boldsymbol{\varepsilon}}^p_t+{\Delta {\boldsymbol{\varepsilon}}^p}\\ {\boldsymbol{\sigma}} &= {\boldsymbol{\sigma}}_t+{\Delta \boldsymbol{\sigma}} \end{aligned} We use an implicit integration technique called *the radial return method* to obtain the plastic multiplier. This method has the advantage of being unconditionally stable, however, the accuracy remains dependent on the step size. The plastic parameters to indicate in the material file are: :math:`\sigma_y` (Yield stress) and ``h`` (Hardening modulus). In addition, the elastic parameters need to be defined as previously mentioned: ``E`` (Young’s modulus), ``nu`` (Poisson’s ratio). Damage `````` In the simplified case of a linear elastic and brittle material, isotropic damage can be represented by a scalar variable :math:`d`, which varies from :math:`0` to :math:`1` for no damage to fully broken material respectively. The stress-strain relationship then becomes: .. math:: \boldsymbol{\sigma} = (1-d)\, \boldsymbol{C}:\boldsymbol{\varepsilon} where :math:`\boldsymbol{\sigma}`, :math:`\boldsymbol{\varepsilon}` are the Cauchy stress and strain tensors, and :math:`\boldsymbol{C}` is the elastic stiffness tensor. This formulation relies on the definition of an evolution law for the damage variable. In ``Akantu``, many possibilities exist and they are listed below. -.. _sect-smm-cl-damage: +.. _sect-smm-cl-damage-marigo: Marigo '''''' This damage evolution law is energy based as defined by Marigo -:cite:`marigo81a, lemaitre96a`. It is an isotropic damage law. +:cite:`marigo81a`, :cite:`lemaitre96a`. It is an isotropic damage law. .. math:: \begin{aligned} Y &= \frac{1}{2}\boldsymbol{\varepsilon}:\boldsymbol{C}:\boldsymbol{\varepsilon}\\ F &= Y - Y_d - S d\\ d &= \left\{ \begin{array}{l l} \mathrm{min}\left(\frac{Y-Y_d}{S},\;1\right) & \mathrm{if}\; F > 0\\ \mathrm{unchanged} & \mathrm{otherwise} \end{array} \right.\end{aligned} In this formulation, :math:`Y` is the strain energy release rate, :math:`Y_d` the rupture criterion and :math:`S` the damage energy. The non-local version of this damage evolution law is constructed by averaging the energy :math:`Y`. .. _sect-smm-cl-damage-mazars: Mazars '''''' This law introduced by Mazars :cite:`mazars84a` is a behavioral model to represent damage evolution in concrete. This model does not rely on the computation of the tangent stiffness, the damage is directly evaluated from the strain. The governing variable in this damage law is the equivalent strain :math:`\varepsilon_{{\mathrm{eq}}} = \sqrt{<\boldsymbol{\varepsilon}>_+:<\boldsymbol{\varepsilon}>_+}`, with :math:`<.>_+` the positive part of the tensor. This part is defined in the principal coordinates (I, II, III) as :math:`\varepsilon_{{\mathrm{eq}}} = \sqrt{<\boldsymbol{\varepsilon_I}>_+^2 + <\boldsymbol{\varepsilon_{II}}>_+^2 + <\boldsymbol{\varepsilon_{III}}>_+^2}`. The damage is defined as: .. math:: \begin{aligned} D &= \alpha_t^\beta D_t + (1-\alpha_t)^\beta D_c\\ D_t &= 1 - \frac{\kappa_0 (1- A_t)}{\varepsilon_{{\mathrm{eq}}}} - A_t \exp^{-B_t(\varepsilon_{{\mathrm{eq}}}-\kappa_0)}\\ D_c &= 1 - \frac{\kappa_0 (1- A_c)}{\varepsilon_{{\mathrm{eq}}}} - A_c \exp^{-B_c(\varepsilon_{{\mathrm{eq}}}-\kappa_0)}\\ \alpha_t &= \frac{\sum_{i=1}^3<\varepsilon_i>_+\varepsilon_{{\mathrm{nd}}\;i}}{\varepsilon_{{\mathrm{eq}}}^2}\end{aligned} With :math:`\kappa_0` the damage threshold, :math:`A_t` and :math:`B_t` the damage parameter in traction, :math:`A_c` and :math:`B_c` the damage parameter in compression, :math:`\beta` is the shear parameter. :math:`\alpha_t` is the coupling parameter between traction and compression, the :math:`\varepsilon_i` are the eigenstrain and the :math:`\varepsilon_{{\mathrm{nd}}\;i}` are the eigenvalues of the strain if the material were undamaged. The coefficients :math:`A` and :math:`B` are the post-peak asymptotic value and the decay shape parameters. + +.. _sect:smm:CLNL: + +Non-Local Constitutive Laws +``````````````````````````` + +Continuum damage modeling of quasi-brittle materials undergo significant +softening after the onset of damage. This fast growth of damage causes a loss of +ellipticity of partial differential equations of equilibrium. Therefore, the +numerical simulation results won't be objective anymore, because the dissipated +energy will depend on mesh size used in the simulation. One way to avoid this +effect is the use of non-local damage formulations. In this approach a local +quantity such as the strain is replaced by its non-local average, where the size +of the domain, over which the quantitiy is averaged, depends on the underlying +material microstructure. ``Akantu`` provides non-local versions of many +constitutive laws for damage. Examples are for instance the material +:ref:`sect-smm-cl-damage-mazars` and the material +:ref:`sect-smm-cl-damage-marigo`, that can be used in a non-local context. In +order to use the corresponding non-local formulation the user has to define the +non-local material he wishes to use in the text input file: + +.. code-block:: + + material constitutive_law_non_local [ + name = material_name + rho = $value$ + ... + ] + +where ``constitutive_law_non_local`` is the name of the non-local constitutive law, *e.g.* `marigo_non_local`. +In addition to the material the non-local neighborhood, that should be used for the averaging process needs to be defined in the material file as well: + +.. code-block:: + + non_local neighborhood_name weight_function_type [ + radius = $value$ + ... + weight_function weight_parameter [ + damage_limit = $value$ + ... + ] + ] + +for the non-local averaging, *e.g.* ``base_wf``, followed by the properties of the non-local neighborhood, such as the radius, and the weight function parameters. It is important to notice that the non-local neighborhood must have the same name as the material to which the neighborhood belongs! +The following two sections list the non-local constitutive laws and different type of weight functions available in ``Akantu``. +\subsection{Non-local constitutive laws} +Let us consider a body having a volume :math:`V` and a boundary :math:`\Gamma`. The stress-strain relation for a non-local damage model can be described as follows: + +.. _eq:non-local-const: + .. math:: \vec{\sigma} = (1-\bar{d}) \vec{D}:\epsilon + +with :math:`\vec{D}` the elastic moduli tensor, :math:`\sigma` the stress tensor, :math:`\epsilon` the strain tensor and :math:`\bar{d}` the non-local damage variable. Note that this stres-strain relationship is similar to the relationship defined in Damage model except :math:`\bar{d}`. The non-local damage model can be extended to the damage constitutive laws: :ref:`sect-smm-cl-damage-marigo` and :ref:`sect-smm-cl-damage-mazars`. + +The non-local damage variable :math:`\bar{d}` is defined as follows: + +.. _eq:non-local-const: + .. math:: \bar{d}(\vec{x}) = \int_{V}W(\vec{x}, \vec{y}) d(\vec{y}) dV(\vec{y}) + +with :math:`W(\vec{x},\vec{y})` the weight function which averages local damage variables to describe the non-local interactions. A list of available weight functions and its functionalities in \akantu are explained in the next section. + +Non-local weight functions +'''''''''''''''''''''''''' + +The available weight functions in ``Akantu`` are follows: + + - ``base_weight_function``: This weight function averages local damage variables by using a bell-shape function on spatial dimensions. + - ``damaged_weight_function``: A linear-shape weight function is applied to average local damage variables. Its slope is determined by damage variables. For example, the damage variables for an element which is highly damaged are averaged over large spatial dimension (linear function including a small slope). + - ``remove_damaged_weight_function``: This weight function averages damage values by using a bell-shape function as ``base_weight_function``, but excludes elements which are fully damaged. + - ``remove_damaged_with_damage_rate_weight_function``: A bell-shape function is applied to average local damage variables for elements having small damage rates. + - ``stress_based_weight_function``: Non local integral takes stress states, and use the states to construct weight function: an ellipsoid shape. Detailed explanations of this weight function are given in Giry et al. :cite:`giry13a`. + + + +.. _sec-cohesive-laws: + +Cohesive Constitutive laws +`````````````````````````` + +.. _ssect-smm-cl-coh-snozzi: + +Linear Irreversible Law +''''''''''''''''''''''' + +.. figure:: figures/cl/linear_cohesive_law.svg + :alt: Irreversible cohesive laws for explicit simulations. + :name: fig:smm:coh:linear_cohesive_law + :align: center + :width: 60.0% + + Irreversible cohesive laws for explicit simulations. + + +`Akantu` includes the Snozzi-Molinari :cite:`snozzi_cohesive_2013` +linear irreversible cohesive law (see +:numref:`fig:smm:coh:linear_cohesive_law`). It is an extension to +the Camacho-Ortiz :cite:`camacho_computational_1996` cohesive law in +order to make dissipated fracture energy path-dependent. The concept +of free potential energy is dropped and a new independent parameter +:math:`\kappa` is introduced: + +.. math:: + \kappa = \frac{G_\mathrm{c, II}}{G_\mathrm{c, I}} + + +where :math:`G_\mathrm{c, I}` and :math:`G_\mathrm{c, II}` are the +necessary works of separation per unit area to open completely a +cohesive zone under mode I and mode II, respectively. Their model yields to the +following equation for cohesive tractions :math:`\vec{T}` in case of crack +opening :math:`{\delta}`: + +.. math:: + \vec{T} = \left( \frac{\beta^2}{\kappa} \Delta_\mathrm{t} \vec{t} + + \Delta_\mathrm{n} \vec{n} \right) + \frac{\sigma_\mathrm{c}}{\delta} + \left( 1- \frac{\delta}{\delta_\mathrm{c}} \right) + = \hat{\vec T}\, + \frac{\sigma_\mathrm{c}}{\delta} + \left( 1- \frac{\delta}{\delta_\mathrm{c}} \right) + :label: eq-smm-coh-tractions + +where :math:`\sigma_\mathrm{c}` is the material strength along the fracture, +:math:`\delta_\mathrm{c}` the critical effective displacement after which +cohesive tractions are zero (complete decohesion), :math:`\Delta_\mathrm{t}` +and :math:`\Delta_\mathrm{n}` are the tangential and normal components of +the opening displacement vector :math:`\vec{\Delta}`, respectively. The +parameter :math:`\beta` is a weight that indicates how big the tangential +opening contribution is. The effective opening displacement is: + +.. math:: + \delta = \sqrt{\frac{\beta^2}{\kappa^2} \Delta_\mathrm{t}^2 + \Delta_\mathrm{n}^2} + +In case of unloading or reloading :math:`\delta < \delta_\mathrm{max}`, +tractions are calculated as: + +.. math:: + \begin{eqnarray} + T_\mathrm{n} &= \Delta_\mathrm{n}\, \frac{\sigma_\mathrm{c}}{\delta_\mathrm{max}} \left( 1- \frac{\delta_\mathrm{max}}{\delta_\mathrm{c}} \right) \\ + T_\mathrm{t} &= \frac{\beta^2}{\kappa}\, \Delta_\mathrm{t}\, \frac{\sigma_\mathrm{c}}{\delta_\mathrm{max}} \left( 1- \frac{\delta_\mathrm{max}}{\delta_\mathrm{c}} \right) + \end{eqnarray} + +so that they vary linearly between the origin and the maximum attained +tractions. As shown in :numref:`fig:smm:coh:linear_cohesive_law`, +in this law, the dissipated and reversible energies are: + +.. math:: + \begin{eqnarray} + E_\mathrm{diss} &= \frac{1}{2} \sigma_\mathrm{c}\, \delta_\mathrm{max}\\[1ex] + E_\mathrm{rev} &= \frac{1}{2} T\, \delta + \end{eqnarray} + +Moreover, a damage parameter :math:`D` can be defined as: + +.. math:: + D = \min \left( + \frac{\delta_\mathrm{max}}{\delta_\mathrm{c}},1 \right) + +which varies from 0 (undamaged condition) and 1 (fully +damaged condition). This variable can only increase because damage is +an irreversible process. A simple penalty contact model has been incorporated +in the cohesive law so that normal tractions can be returned in +case of compression: + +.. math:: + T_\mathrm{n} = \alpha \Delta_\mathrm{n} \quad\text{if}\quad + \Delta_\mathrm{n}\quad <\quad 0 + +where :math:`\alpha` is a stiffness parameter that defaults to zero. The +relative contact energy is equivalent to reversible energy but in +compression. + +The material name of the linear decreasing cohesive law is +``material_cohesive_linear`` and its parameters with their respective default +values are: + +- sigma_c: 0 +- delta_c: 0 +- beta: 0 +- G_c: 0 +- kappa: 1 +- penalty: 0 + +where ``G_c`` corresponds to :math:`G_\mathrm{c, I}`. A random number +generator can be used to assign a random :math:`\sigma_\mathrm{c}` to each +facet following a given distribution (see +Section :ref:`sect-smm-cl`). Only one parameter between ``delta_c`` +and ``G_c`` has to be specified. For random :math:`\sigma_\mathrm{c}` +distributions, the chosen parameter of these two is kept fixed and the +other one is varied. + +The bi-linear constitutive law works exactly the same way as the linear +one, except for the additional parameter ``delta_0`` that by +default is zero. Two examples for the extrinsic and intrinsic cohesive +elements and also an example to assign different properties to +inter-granular and trans-granular cohesive elements can be found in +the folder ``examples/cohesive_element/``. + +.. _ssect:smm:cl:coh-friction: + +Linear Cohesive Law with Friction +''''''''''''''''''''''''''''''''' + +This law represents a variation of the linear irreversible cohesive of +the previous section, which adds friction. The friction behavior is +approximated with an elasto-plastic law, which relates the friction +force to the relative sliding between the two faces of the cohesive +element. The slope of the elastic branch is called +``penalty_for_friction``, and is defined by the user, together +with the friction coefficient, as a material property. The friction +contribution evolves with the damage of the cohesive law: it is null +when the damage is zero, and it becomes maximum when the damage is +equal to one. This is done by defining a current value of the +friction coefficient (mu) that increases linearly with the damage, up +to the value of the friction coefficient defined by the user. The +yielding plateau of the friction law is given by the product of the +current friction coefficient and the local compression stress acting +in the cohesive element. Such an approach is equivalent to a +node-to-node contact friction. Its accuracy is acceptable only for +small displacements. + +The material name of the linear cohesive law with friction is +``material_cohesive_linear_friction``. Its additional parameters +with respect to those of the linear cohesive law without friction, +with the respective default values, are: + +-mu: 0 +-penalty_for_friction: 0 + +.. _ssect:smm:cl:coh-fatigue: + +Linear Cohesive Law with Fatigue +'''''''''''''''''''''''''''''''' + +This law represents a variation of the linear irreversible cohesive +law of the previous section, that removes the hypothesis of elastic +unloading-reloading cycles. With this law, some energy is dissipated +also during unloading and reloading with hysteresis. The +implementation follows the work of :cite:`nguyen2001`. During the +unloading-reloading cycle, the traction increment is computed as + +.. math:: + \dot{T} = + \begin{cases} + K^- \, \dot{\delta} & \text{if $\dot{\delta} < 0$} \\ + K^+ \, \dot{\delta} & \text{if $\dot{\delta} > 0$} \\ + \end{cases} + +where :math:`\dot{\delta}` and :math:`\dot{T}` are respectively the effective +opening displacement and the cohesive traction increments with respect +to time, while :math:`K^-` and :math:`K^+` are respectively the unloading and +reloading incremental stiffness. The unloading path is linear and +results in an unloading stiffness + +.. math:: + K^- = \frac{T_\mathrm{max}}{\delta_\mathrm{max}} + +where :math:`T_\mathrm{max}` and :math:`\delta_\mathrm{max}` are the maximum +cohesive traction and the effective opening displacement reached +during the precedent loading phase. The unloading stiffness remains +constant during the unloading phase. On the other hand the reloading +stiffness increment :math:`\dot{K}^+` is calculated as + +.. math:: + \dot{K}^+ = + \begin{cases} + - K^+ \, \dot{\delta} / \delta_\mathrm{f} & \text{if $\dot{\delta} + > 0$} \\ + \left( K^+ - K^- \right) \, \dot{\delta} / \delta_\mathrm{f} & + \text{if $\dot{\delta}$ < $0$} + \end{cases} + +where :math:`\delta_\mathrm{f}` is a material parameter (refer +to :cite:`vocialta15` for more details). During unloading the stiffness +:math:`K^+` tends to :math:`K^-`, while during reloading :math:`K^+` gets decreased at +every time step. If the cohesive traction during reloading exceeds the +upper limit given by equation :eq:`eq-smm-coh-tractions`, it is +recomputed following the behavior of the linear decreasing cohesive +law for crack opening. + +.. _ssect:smm:cl:coh-exponential: + +Exponential Cohesive Law +''''''''''''''''''''''''' + +Ortiz and Pandolfi proposed this cohesive law in 1999 :cite:`ortiz1999`. The +traction-opening equation for this law is as follows: + +.. math:: + T = e \sigma_c \frac{\delta}{\delta_c}e^{-\delta/ \delta_c} + :label: eq:exponential_law + +This equation is plotted in Figure :numref:`fig:smm:cl:ecl`. The term +:math:`\partial{\vec{T}}/ \partial{\delta}` after the necessary derivation +can expressed as + +.. math:: + \frac{\partial{\vec{T}}} {\partial{\delta}} = \hat{\vec{T}} \otimes + \frac {\partial{(T/\delta)}}{\partial{\delta}} + \frac{\hat{\vec{T}}}{\delta}+ \frac{T}{\delta} \left[ \beta^2 \mat{I} + + \left(1-\beta^2\right) \left(\vec{n} \otimes \vec{n}\right)\right] + :label: eq:tangent_cohesive + +where + +.. math:: + \frac{\partial{(T/ \delta)}}{\partial{\delta}} = \left\{\begin{array} {l l} + -e \frac{\sigma_c}{\delta_c^2 }e^{-\delta / \delta_c} & \quad \text{if} + \delta \geq \delta_{max}\\ + 0 & \quad \text{if} \delta < \delta_{max}, \delta_n > 0 + \end{array} \right. + + +As regards the behavior in compression, two options are available: +a contact penalty approach with stiffness following the formulation of +the exponential law and a contact penalty approach with constant +stiffness. In the second case, the stiffness is defined as a function +of the tangent of the exponential law at the origin. + +.. figure:: figures/cl/cohesive_exponential.png + :alt: Exponential cohesive law + :name: fig:smm:cl:ecl + :align: center + + Exponential cohesive law diff --git a/doc/dev-doc/manual/fe_engine.rst b/doc/dev-doc/manual/fe_engine.rst index 12efe833b..072e1c550 100644 --- a/doc/dev-doc/manual/fe_engine.rst +++ b/doc/dev-doc/manual/fe_engine.rst @@ -1,310 +1,233 @@ FEEngine ======== The :cpp:class:`FEEngine` interface is dedicated to handle the finite-element approximations and the numerical integration of the weak form. As we will see in Chapter :doc:`./solidmechanicsmodel`, :cpp:class:`Model` creates its own :cpp:class:`FEEngine` object so the explicit creation of the object is not required. Mathematical Operations ----------------------- Using the :cpp:class:`FEEngine` object, one can compute a interpolation, an integration or a gradient.A simple example is given below: .. code-block:: c++ // having a FEEngine object auto fem = std::make_unique>(my_mesh, dim, "my_fem"); // instead of this, a FEEngine object can be get using the model: // model.getFEEngine() // compute the gradient Array u; // append the values you want Array nablauq; // gradient array to be computed // compute the gradient fem->gradientOnIntegrationPoints(const Array & u, Array & nablauq, const UInt nb_degree_of_freedom, ElementType type); // interpolate Array uq; // interpolated array to be computed // compute the interpolation fem->interpolateOnIntegrationPoints(const Array & u, Array & uq, UInt nb_degree_of_freedom, ElementType type); // interpolated function can be integrated over the elements Array int_val_on_elem; // integrate fem->integrate(const Array & uq, Array & int_uq, UInt nb_degree_of_freedom, ElementType type); Another example below shows how to integrate stress and strain fields over elements assigned to a particular material: .. code-block:: c++ UInt sp_dim{3}; // spatial dimension UInt m{1}; // material index of interest const auto type{_tetrahedron_4}; // element type // get the stress and strain arrays associated to the material index m const auto & strain_vec = model.getMaterial(m).getGradU(type); const auto & stress_vec = model.getMaterial(m).getStress(type); // get the element filter for the material index const auto & elem_filter = model.getMaterial(m).getElementFilter(type); // initialize the integrated stress and strain arrays Array int_strain_vec(elem_filter.getSize(), sp_dim * sp_dim, "int_of_strain"); Array 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); .. _sec-elements: 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 iso-parametric 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 app:elements. Iso-parametric Elements ....................... 1D ```` There are two types of iso-parametric elements defined in 1D. These element types are called :cpp:enumerator:`_segment_2 ` and :cpp:enumerator:`_segment_3 `, and are depicted schematically in :numref:`fig-elements-1D`. Some of the basic properties of these elements are listed in :numref:`tab-elements-1D`. .. _fig-elements-1D: .. figure:: figures/elements/segments.svg :align: center 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). .. _tab-elements-1D: .. csv-table:: Some basic properties of the two 1D iso-parametric elements in ``Akantu`` :header: "Element type", "Order", "#nodes", "#quad points" ":cpp:enumerator:`_segment_2 `", "linear", 2, 1 ":cpp:enumerator:`_segment_3 `", "quadratic", 3, 2 2D ```` There are four types of iso-parametric elements defined in 2D. These element types are called :cpp:enumerator:`_triangle_3 `, :cpp:enumerator:`_triangle_6 `, :cpp:enumerator:`_quadrangle_4 ` and :cpp:enumerator:`_quadrangle_8 `, and all of them are depicted in :numref:`fig-elements-2D`. As with the 1D elements, some of the most basic properties of these elements are listed in :numref:`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 (``_quadrangle_8``) is not a Lagrangian but a serendipity element. .. _fig-elements-2D: .. figure:: figures/elements/elements_2d.svg :align: center 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). .. _tab-elements-2D: .. csv-table:: Some basic properties of the 2D iso-parametric elements in ``Akantu`` :header: "Element type", "Order", "#nodes", "#quad points" ":cpp:enumerator:`_triangle_3 `", "linear", 3, 1 ":cpp:enumerator:`_triangle_6 `", "quadratic", 6, 3 ":cpp:enumerator:`_quadrangle_4 `", "linear", 4, 4 ":cpp:enumerator:`_quadrangle_8 `", "quadratic", 8, 9 3D ```` In ``Akantu``, there are three types of iso-parametric elements defined in 3D. These element types are called :cpp:enumerator:`_tetrahedron_4 `, :cpp:enumerator:`_tetrahedron_10 ` and :cpp:enumerator:`_hexadedron_8 `, and all of them are depicted schematically in :numref:`fig-elements-3D`. As with the 1D and 2D elements some of the most basic properties of these elements are listed in :numref:`tab-elements-3D`. .. _fig-elements-3D: .. figure:: figures/elements/elements_3d.svg :align: center 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 circles). .. _tab-elements-3D: .. csv-table:: Some basic properties of the 3D iso-parametric elements in ``Akantu`` :header: "Element type", "Order", "#nodes", "#quad points" ":cpp:enumerator:`_tetrahedron_4 `", "linear", 4, 1 ":cpp:enumerator:`_tetrahedron_10 `", "quadratic", 10, 4 ":cpp:enumerator:`_hexadedron_8 `", "cubic", 8, 8 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 :numref:`tab-coh-cohesive_elements`. .. _fig-smm-coh-cohesive2d: .. figure:: figures/elements/cohesive_2d_6.svg :align: center Cohesive element in 2D for quadratic triangular elements T6. .. _tab-coh-cohesive_elements: .. csv-table:: Some basic properties of the cohesive elements in ``Akantu``. :header: "Element type", "Facet type", "Order", "#nodes", "#quad points" ":cpp:enumerator:`_cohesive_1d_2 <_cohesive_1d_2>`", ":cpp:enumerator:`_point_1 `", "linear", 2, 1 ":cpp:enumerator:`_cohesive_2d_4 `", ":cpp:enumerator:`_segment_2 `", "linear", 4, 1 ":cpp:enumerator:`_cohesive_2d_6 `", ":cpp:enumerator:`_segment_3 `", "quadratic", 6, 2 ":cpp:enumerator:`_cohesive_3d_6 `", ":cpp:enumerator:`_triangle_3 `","linear", 6, 1 ":cpp:enumerator:`_cohesive_3d_12 `", ":cpp:enumerator:`_triangle_6 `", "quadratic", 12, 3 -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 ``intrinsic``, the second -one ``extrinsic``. When an element is present from the beginning, a -bi-linear or exponential cohesive law should be used instead of a -linear one. A bi-linear law works exactly like a linear one except for -an additional parameter :math:`\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}. - -.. _fig-smm-coh-insertion: -.. figure:: figures/insertion.svg - :align: center - - Insertion of a cohesive element. - -Extrinsic cohesive elements are dynamically inserted between two -standard elements when - -.. math:: - \sigma_\mathrm{eff} > \sigma_\mathrm{c} \quad\text {with} \quad \sigma_\mathrm{eff} = \sqrt{\sigma_\mathrm{n} ^ 2 + \frac{\tau ^ 2} {\beta ^ 2 }} - -in which :math:`\sigma_\mathrm { n } -` is the tensile normal traction and $\tau$ the resulting tangential one( :numref:`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 -:numref:`fig-smm-coh-cohesive2d`, the opening displacement along the mid-surface -can be written as: - -.. _eq-coh-opening: -.. math:: - \begin{align} - \vec{\Delta}(s) &= \left[\!\!\left[ \mat{u}\right]\!\!\right] \,\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{align} - -The :math:`\mat{U}`, :math:`\mat{A}` and :math:`\mat{N}^\mathrm{k}` are as following : - -.. math:: - \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]\\ - \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]\\ - \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 - -.. _eq-cohesive_stiffness: -.. math:: - \mat{K}=\int_{S_0}\mat{P}^\mathrm{T} \, \frac{\partial{\vec{T}}}{\partial{\delta}}\mat{P}\,\mathrm{d} S_0 - -where :math:`\vec{T}` is the cohesive traction and :math:`\delta` the opening -displacement (for more details check :numref:`tab-coh-cohesive_elements`). - Structural Elements ................... Bernoulli Beam Elements ``````````````````````` 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 :cpp:enumerator:`_bernoulli_beam_2 ` and :cpp:enumerator:`_bernoulli_beam_3 `. A schematic depiction of a beam element is shown in :numref:`fig-elements-bernoulli` and some of its properties are listed in :numref:`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. .. _fig-elements-bernoulli: .. figure:: figures/elements/bernoulli_2.svg :align: center 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). .. _tab-elements-bernoulli: .. csv-table:: Some basic properties of the beam elements in ``Akantu`` :header: "Element type", "Dimension", "# nodes", "# quad. points", "# d.o.f." ":cpp:enumerator:`_bernoulli_beam_2 `", "2D", 2, 3, 6 ":cpp:enumerator:`_bernoulli_beam_3 `", "3D", 2, 3, 12 diff --git a/doc/dev-doc/manual/figures/cl/cohesive_exponential.png b/doc/dev-doc/manual/figures/cl/cohesive_exponential.png new file mode 100644 index 000000000..d3d0ad6a6 Binary files /dev/null and b/doc/dev-doc/manual/figures/cl/cohesive_exponential.png differ diff --git a/doc/dev-doc/manual/figures/cl/linear_cohesive_law.svg b/doc/dev-doc/manual/figures/cl/linear_cohesive_law.svg new file mode 100644 index 000000000..96390ca87 --- /dev/null +++ b/doc/dev-doc/manual/figures/cl/linear_cohesive_law.svg @@ -0,0 +1,553 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/dev-doc/manual/figures/cl/stress_strain_visco.svg b/doc/dev-doc/manual/figures/cl/stress_strain_visco.svg index 0de647977..28aa90e1d 100644 --- a/doc/dev-doc/manual/figures/cl/stress_strain_visco.svg +++ b/doc/dev-doc/manual/figures/cl/stress_strain_visco.svg @@ -1,616 +1,633 @@ image/svg+xml + + + + image/svg+xml + + + + + + εσ + id="namedview280" + showgrid="false" + inkscape:zoom="1.5116523" + inkscape:cx="302.362" + inkscape:cy="283.46466" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg278" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/dev-doc/manual/figures/cl/visco_elastic_law.svg b/doc/dev-doc/manual/figures/cl/visco_elastic_law.svg new file mode 100644 index 000000000..c1fbc8cee --- /dev/null +++ b/doc/dev-doc/manual/figures/cl/visco_elastic_law.svg @@ -0,0 +1,238 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/dev-doc/manual/io.rst b/doc/dev-doc/manual/io.rst new file mode 100644 index 000000000..8103067e8 --- /dev/null +++ b/doc/dev-doc/manual/io.rst @@ -0,0 +1,273 @@ +.. _sect-io: + +Input/Output +============ + +Input file +---------- + +The text input file of a simulation should be precised using the method +:cpp:func:`initialize ` which will instantiate the static +:cpp:class:`Parser ` object of ``Akantu``. This section +explains how to manipulate at :cpp:class:`Parser ` objects to +input data in ``Akantu``. + +Akantu Parser +~~~~~~~~~~~~~ + +``Akantu`` file parser has a tree organization. + +- :cpp:class:`Parser `, the root of the tree, can be accessed + using:: + + auto & parser = getStaticParser(); + +- :cpp:class:`ParserSection `, branch of the tree, + contains map a of sub-sections (:cpp:enum:`SectionType + `, :cpp:class:`ParserSection `) + and a :cpp:class:`ParserSection * ` pointing to the + parent section. The user section of the input file can directly be accessed + by:: + + const auto & usersect = getUserParser(); + +- :cpp:class:`ParserParameter `, the leaf of the tree, + carries data of the input file which can be cast to the correct type with the + assignment operator:: + + Real mass = usersect.getParameter("mass"); + + or used directly within an expression + +Grammar +~~~~~~~ + +The structure of text input files consists of different sections +containing a list of parameters. As example, the file parsed in the +previous section will look like:: + + user parameters [ + mass = 10.5 + ] + +Basically every standard arithmetic operations can be used inside of input files +as well as the constant ``pi`` and ``e`` and the exponent operator ``^``. +Operations between :cpp:class:`ParserParameter ` are +also possible with the convention that only parameters of the current and the +parent sections are available. :cpp:class:`Vector ` and +:cpp:class:`Matrix ` can also be read according to the ``NumPy`` +:cite:`numpy` writing convention (a.e. cauchy_stress_tensor = [[:math:`\sigma_{xx}`, +:math:`\sigma_{xy}`],[:math:`\sigma_{yx}`,\ :math:`\sigma_{yy}`]]). An example +illustrating how to parse the following input file can be found in +``example\io\parser\example_parser.cc``:: + + user parameters [ + spatial_dimension = 2 + mesh_file = swiss_cheese.msh + inner_holes = holes + outter_crust = crust + lactostatic_p = 30e3 + stress = [[lactostatic_p, 0 ], + [0, lactostatic_p]] + max_nb_iterations = 100 + precision = 1e-9 + ] + +.. _sect-io-material: + +Material section +~~~~~~~~~~~~~~~~ + +The input file should also be used to specify material characteristics +(constitutive behavior and material properties). The dedicated material section +is then read by :cpp:func:`initFull ` +method of :cpp:class:`SolidMechanicsModel ` which +initializes the different materials specified with the following convention:: + + material constitutive_law [ + name = value + rho = value + ... + ] + +where *constitutive_law* is the adopted constitutive law, followed by +the material properties listed one by line in the bracket (*e.g.*, +``name`` and density :math:``rho``. Some constitutive laws can also +have an *optional flavor*. More information can be found in sections +relative to material :ref:`sect-smm-cl` +or in Appendix :ref:`app-material-parameters`. + +Output data +----------- + +Generic data +~~~~~~~~~~~~ + +In this section, we address ways to get the internal data in human-readable +formats. The models in ``Akantu`` handle data associated to the mesh, but this +data can be split into several :cpp:class:`Arrays `. For example, +the data stored per element type in a :cpp:class:`ElementTypeMapArray +` is composed of as many :cpp:class:`Arrays +` as types in the mesh. + +In order to get this data in a visualization software, the models contain a +object to dump ``VTK`` files. These files can be visualized in software such +as ``ParaView`` :cite:`paraview`, ``ViSit`` :cite:`visit` or ``Mayavi`` +:cite:`mayavi`. + +The internal dumper of the model can be configured to specify which data +fields are to be written. This is done with the :cpp:func:`addDumpField ` method. By default all the +files are generated in a folder called ``paraview/``:: + + model.setBaseName("output"); // prefix for all generated files + model.addDumpField("displacement"); model.addDumpField("stress"); ... + model.dump() + +The fields are dumped with the number of components of the memory. For example, +in 2D, the memory has :cpp:class:`Vectors ` of 2 components, or +the :math:`2^{nd}` order tensors with :math:`2\times2` components. This memory +can be dealt with :cpp:func:`addDumpFieldVector +` which always dumps :cpp:class:`Vectors +` with 3 components or :cpp:func:`addDumpFieldTensor +` which dumps :math:`2^{nd}` order tensors +with :math:`3\times3` components respectively. The routines :cpp:func:`addDumpFieldVector ` and +:cpp:func:`addDumpFieldTensor ` were +introduced because of ``ParaView`` which mostly manipulate 3D data. + +Those fields which are stored by quadrature point are modified to be seen in the +``VTK`` file as elemental data. To do this, the default is to average the +values of all the quadrature points. + +The list of fields depends on the models (for :cpp:class:`SolidMechanicsModel +` see table :ref:`tab-io-smm-field-list`. + +.. container:: + :name: tab-io-smm-field-list + + .. table:: List of dumpable fields for :cpp:class:`SolidMechanicsModel `. + + ====================== ============ ================= + key type support + ====================== ============ ================= + displacement Vector nodes + mass Vector nodes + velocity Vector nodes + acceleration Vector nodes + force Vector nodes + residual Vector nodes + increment Vector nodes + blocked_dofs Vector nodes + partitions Real elements + material_index variable elements + strain Matrix quadrature points + Green strain Matrix quadrature points + principal strain Vector quadrature points + principal Green strain Vector quadrature points + grad_u Matrix quadrature points + stress Matrix quadrature points + Von Mises stress Real quadrature points + material_index variable quadrature points + ====================== ============ ================= + +Cohesive elements’ data +~~~~~~~~~~~~~~~~~~~~~~~ + +Cohesive elements and their relative data can be easily dumped thanks to +a specific dumper contained in :cpp:class:`SolidMechanicsModelCohesive `. In order to use it, one has +just to add the string ``cohesive elements`` when calling each method already +illustrated. Here is an example on how to dump displacement and damage:: + + model.addDumpFieldVectorToDumper("cohesive elements", "displacement"); + model.addDumpFieldToDumper("cohesive elements", "damage"); + model.dump("cohesive elements"); + + +Fragmentation data +^^^^^^^^^^^^^^^^^^ + +Whenever the :cpp:class:`SolidMechanicsModelCohesive +` is used, it is possible to dump +additional data about the fragments that get formed in the simulation both in +serial and parallel. This task is carried out by the +:cpp:class:`FragmentManager ` class, that takes care of +computing the following quantities for each fragment: + +- index; + +- mass; + +- moments of inertia; + +- velocity; + +- number of elements. + +These computations can be realized at once by calling the function +:cpp:class:`computeAllData `, or +individually by calling the other public functions of the class. The data can be +dumped to be visualized in ``ParaView``, or can be accessed within the +simulation. An example of usage is: + +At the end of this example the velocities of the fragments are accessed with a +reference to a :cpp:class:`const Array\ `. The size of this +array is the number of fragments, and its number of components is the spatial +dimension in this case. + +Advanced dumping +~~~~~~~~~~~~~~~~ + +Arbitrary fields +^^^^^^^^^^^^^^^^ + +In addition to the predetermined fields from the models and materials, +the user can add any data to a dumper as long as the support is the +same. That is to say data that have the size of the full mesh on if the +dumper is dumping the mesh, or of the size of an element group if it is +a filtered dumper. + +For this the easiest is to use the “external” fields register functions + +The simple case force nodal and elemental data are to pass directly the +data container itself if it as the good size. + +- For nodal fields: + + It is assumed that the array as the same size as the number of nodes + in the mesh + +- For elemental fields: + + It is assumed that the arrays in the map have the same sizes as the element + numbers in the mesh for element types of dimension ``spatial_dimension``. + +If some changes have to be applied on the data as for example a padding for +``ParaView`` vectors, this can be done by using the field interface. + +All these functions use the default dumper registered in the mesh but also have +the ``ToDumper`` variation with the dumper name specified. For example: + +An example of code presenting this interface is present in the +``examples/io/dumper``. This interface is part of the :cpp:class:`Dumpable +` class from which the :cpp:class:`Mesh ` +inherits. + +Creating a new dumper +^^^^^^^^^^^^^^^^^^^^^ + +You can also create you own dumpers, ``Akantu`` uses a third-party library in +order to write the output files, ``IOHelper``. ``Akantu`` supports the +``ParaView`` format and a Text format defined by ``IOHelper``. + +This two files format are handled by the classes :cpp:class:`DumperParaview +` and :cpp:class:`DumperText `. + +In order to use them you can instantiate on of this object in your code. This +dumper have a simple interface. You can register a mesh :cpp:func:`registerMesh +`, :cpp:func:`registerFilteredMesh +` or a field, +:cpp:class:`registerField `. + +An example of code presenting this low level interface is present in the +``examples/io/dumper``. The different types of :cpp:class:`Field +` that can be created are present in the source folder +``src/io/dumper``. diff --git a/doc/dev-doc/manual/manual-bibliography.bib b/doc/dev-doc/manual/manual-bibliography.bib index 4ebe2f8ff..7913a9f6e 100644 --- a/doc/dev-doc/manual/manual-bibliography.bib +++ b/doc/dev-doc/manual/manual-bibliography.bib @@ -1,582 +1,594 @@ % This file was created with JabRef 2.10b2. % Encoding: UTF-8 @Article{aifantis84a, Title = {On the microstructural origin of certain inelastic models}, Author = {E. C. Aifantis}, Journal = {Journal of Engineering Materials and Technology}, Year = {1984}, Pages = {326 - 330}, Volume = {106} } @Article{Aragon:2013d, Title = {A hierarchical detection framework for computational contact mechanics}, Author = {Alejandro M. Arag{\'o}n and Jean-Fran{\c c}ois Molinari}, Journal = {Computer Methods in Applied Mechanics and Engineering}, Year = {2014}, Number = {0}, Pages = {574 - 588}, Volume = {268}, Bdsk-url-1 = {http://www.sciencedirect.com/science/article/pii/S0045782513002533}, Bdsk-url-2 = {http://dx.doi.org/10.1016/j.cma.2013.10.001}, Date-added = {2014-05-22 09:14:48 +0000}, Date-modified = {2014-05-22 09:14:48 +0000}, Doi = {10.1016/j.cma.2013.10.001}, ISSN = {0045-7825}, Url = {http://dx.doi.org/10.1016/j.cma.2013.10.001} } @Article{bazant86a, Title = {Mechanics of distributed cracking}, Author = {Zden\v{e}k P. Ba\v{z}ant}, Journal = {Applied Mechanics Reviews}, Year = {1986}, Number = {5}, Pages = {675 - 705}, Volume = {39} } @Article{bazant76a, Title = {Instability, Ductility, and Size Effect in Strain-Softening Concrete}, Author = {Zden\v{e}k P. Ba\v{z}ant}, Journal = {Journal of the Engineering Mechanics Division}, Year = {1976}, Number = {5}, Pages = {331 - 344}, Volume = {102} } @Article{bazant85a, Title = {Wave Propagation in a Strain-Softening Bar: Exact Solution}, Author = {Zden\v{e}k P. Ba\v{z}ant and Ted Belytschko}, Journal = {Journal of Engineering Mechanics}, Year = {1985}, Number = {3}, Pages = {381 - 389}, Volume = {111} } @Article{bazant88a, Title = {{Nonlocal Continuum Damage, Localization Instability and Convergence}}, Author = {Zden\v{e}k P. Ba\v{z}ant and Gilles Pijaudier-Cabot}, Journal = {Journal of Applied Mechanics}, Year = {1988}, Number = {2}, Pages = {287-293}, Volume = {55}, Optdoi = {10.1115/1.3173674}, Publisher = {ASME} } @Article{belytschko03a, Title = {Dynamic crack propagation based on loss of hyperbolicity and a new discontinuous enrichment}, Author = {T Belytschko and H Chen and J Xu and G Zi}, Journal = {International Journal for Numerical Methods in Engineering}, Year = {2003}, Pages = {1875-1905}, Volume = {58} } @Article{camacho_computational_1996, Title = {Computational modelling of impact damage in brittle materials}, Author = {Camacho, {G.T.} and Ortiz, M.}, Journal = {International Journal of Solids and Structures}, Year = {1996}, Month = aug, Number = {20{\textendash}22}, Pages = {2899--2938}, Volume = {33}, Urldate = {2012-01-17} } @Article{caughey1960, Title = {Classical normal modes in damped linear dynamic systems}, Author = {Caughey, TK}, Journal = {Journal of Applied Mechanics}, Year = {1960}, Number = {2}, Pages = {269--271}, Volume = {27}, Publisher = {American Society of Mechanical Engineers} } @Book{courant56a, Title = {On the partial difference equations of mathematical physics}, Author = {Courant, Richard and Friedrichs, Kurt Otto and Lewy, H.}, Publisher = {Courant Institute of Mathematical Sciences, New York University}, Year = {1956}, Address = {New York} } @Book{curnier92a, Title = {M{\'e}thodes num{\'e}riques en m{\'e}canique des solides}, Author = {Curnier, A.}, Publisher = {EPFL}, Year = {1992}, Bdsk-url-1 = {http://books.google.ch/books?id=-Z2zygAACAAJ}, Url = {http://books.google.ch/books?id=-Z2zygAACAAJ} } +@incollection{giry13a, + title = {{Stress-based Non-local Damage Model}}, + author = {GIRY, C{\'e}dric and Dufour, Fr{\'e}d{\'e}ric}, + url = {https://hal.archives-ouvertes.fr/hal-02535143}, + booktitle = {{Damage Mechanics of Cementitious Materials and Structures}}, + publisher = {{John Wiley \& Sons, Inc.}}, + pages = {51-88}, + year = {2013}, + month = Mar, + doi = {10.1002/9781118562086.ch3}, +} + @Article{youn10a, Title = {Studies of dynamic crack propagation and crack branching with peridynamics}, Author = {Youn Doh-Ha and Florin Bobaru}, Journal = {International Journal of Fracture}, Year = {2010}, Pages = {229-1244}, Volume = {162} } @Book{frey2009, Title = {M{\'e}thodes des {\'e}l{\'e}ments finis: Analyse des structures et milieux continus}, Author = {Frey, F. and Jirousek, J.}, Publisher = {PPUR}, Year = {2009}, Series = {Trait{\'e} de g{\'e}nie civil de l'Ecole Polytechnique F{\'e}d{\'e}rale de Lausanne}, Bdsk-url-1 = {http://books.google.fr/books?id=bCBtQgAACAAJ}, ISBN = {9782880748524}, Url = {http://books.google.fr/books?id=bCBtQgAACAAJ} } @Article{gmsh, Title = {Gmsh: A 3-D finite element mesh generator with built-in pre- and post-processing facilities}, Author = {Geuzaine, Christophe and Remacle, Jean-Fran{\c c}ois}, Journal = {International Journal for Numerical Methods in Engineering}, Year = {2009}, Number = {11}, Pages = {1309--1331}, Volume = {79}, Bdsk-url-1 = {http://dx.doi.org/10.1002/nme.2579}, Doi = {10.1002/nme.2579}, ISSN = {1097-0207}, Keywords = {computer-aided design, mesh generation, post-processing, finite element method, open-source software}, Publisher = {John Wiley \& Sons, Ltd.}, Url = {http://dx.doi.org/10.1002/nme.2579} } @Article{giry11a, Title = {Stress-based nonlocal damage model}, Author = {C. Giry and F. Dufour and J. Mazars}, Journal = {International Journal of Solids and Structures}, Year = {2011}, Pages = {3431 - 3443}, Volume = {48} } @Article{hughes-83a, Title = {A precis of developments in computational methods for transient analysis}, Author = {Hughes, T.J.R. and Belytschko, T.}, Journal = {Journal. of Applied Mechanics (ASME)}, Year = {1983}, Pages = {1033-1041}, Volume = {50} } @Article{hughes83a, Title = {{A Pr{\'e}cis of Developments in Computational Methods for Transient Analysis}}, Author = {{Hughes}, T.~J.~R. and {Belytschko}, T.}, Journal = {Journal of Applied Mechanics}, Year = {1983}, Month = {December}, Pages = {1033}, Volume = {50}, Optdoi = {10.1115/1.3167186} } @Article{jirasek07a, Title = {Mathematical analysis of strain localization}, Author = {Milan Jir\'asek}, Journal = {Revue Europeenne de Genie Civil}, Year = {2007}, Pages = {977 - 991}, Volume = {11} } @Article{jirasek07b, Title = {Nonlocal damage mechanics}, Author = {Milan Jir\'asek}, Journal = {Revue Europeenne de Genie Civil}, Year = {2007}, Pages = {993 - 1021}, Volume = {11} } @Article{jirasek98a, Title = {Nonlocal models for damage and fracture: comparison of approaches}, Author = {Milan Jir\'asek}, Journal = {International Journal of Solids and Structures}, Year = {1998}, Pages = {4133 - 4145}, Volume = {35} } @Article{jirasek03a, Title = {Comparison of integral-type nonlocal plasticity models for strain-softening materials}, Author = {Milan Jir\'asek and Simon Rolshoven}, Journal = {International Journal of Engineering Science}, Year = {2003}, Pages = {1553-1602}, Volume = {41} } @Article{jirasek04a, Title = {Size effect on fracture energy induced by non-locality}, Author = {Milan Jir\'asek and S Rolshoven and P Grassl}, Journal = {International Journal for numerical and analytical methods in geomechanics}, Year = {2004}, Pages = {653 - 670}, Volume = {28} } @Article{ladeveze92a, Title = {A damage computational method for composite structures}, Author = {P. Ladeveze}, Journal = {Computational \& Structures}, Year = {1992}, Pages = {79-87}, Volume = {44} } @Book{Laursen:2002, Title = {Computational Contact and Impact Mechanics: Fundamentals of Modeling Interfacial Phenomena in Nonlinear Finite Element Analysis}, Author = {Laursen, T.A.}, Publisher = {Springer}, Year = {2002}, Series = {Engineering online library}, Bdsk-url-1 = {http://books.google.ch/books?id=umzsErNuyFgC}, Date-added = {2014-03-21 13:24:56 +0000}, Date-modified = {2014-03-21 13:24:56 +0000}, ISBN = {9783540429067}, Lccn = {2002511027} } @Book{lemaitre96a, Title = {A Course on Damage Mechanics}, Author = {Lemaitre, Jean}, Publisher = {Springer Berlin Heidelberg}, Year = {1996}, ISBN = {978-3-540-60980-3} } @PhdThesis{levy10a, Title = {Exploring the {P}hysics behind {D}ynamic {F}ragmentation through {P}arallel {S}imulations}, Author = {Levy, Sarah}, School = {ENAC}, Year = {2010}, Address = {Lausanne}, Affiliation = {EPFL}, Doctoral = {EDME}, Institute = {IIC}, Original-unit = {LSMS}, Publisher = {EPFL}, Unit = {LSMS} } @Article{marigo81a, Title = {{Formulation d'une loi d'endommagement d'un mat\'eriau \'elastique}}, Author = {Marigo, Jean-Jacques}, Journal = {{C. R. Acad. Sci., Paris, S\'er. II}}, Year = {1981}, Number = {19}, Pages = {1309-1312}, Volume = {292}, ISSN = {0249-6305} } @PhdThesis{mazars84a, Title = {{Application de la m\'ecanique de l'endommagement au comportement non lin\'eaire et \`a la rupture du b\'eton de structure}}, Author = {Mazars, Jacky}, School = {Universit\'e Paris 6}, Year = {1984} } @Article{needleman88a, Title = {Material rate dependence and mesh sensitivity in localization problems}, Author = {A. Needleman}, Journal = {Computer Methods in Applied Mechanics and Engineering}, Year = {1988}, Number = {1}, Pages = {69 - 85}, Volume = {67}, ISSN = {0045-7825}, Optdoi = {10.1016/0045-7825(88)90069-2} } @Article{newmark59a, Title = {{A Method of Computation for Structural Dynamics}}, Author = {Nathan M. Newmark}, Journal = {Journal of the Engineering Mechanics Division}, Year = {1959}, Month = {July}, Number = {3}, Pages = {67-94}, Volume = {85}, Editor = {ASCE} } @Article{nguyen2001, Title = {A cohesive model of fatigue crack growth}, Author = {Nguyen, O. and Repetto, E. A. and Ortiz, M. and Radovitzky, R. A.}, Journal = {International Journal of Fracture}, Year = {2001}, Month = aug, Number = {4}, Pages = {351--369}, Volume = {110}, Doi = {10.1023/A:1010839522926}, ISSN = {0376-9429, 1573-2673}, Language = {en}, Urldate = {2015-02-17} } @TechReport{Omohundro:1989, Title = {Five Balltree Construction Algorithms}, Author = {Stephen M. Omohundro}, Institution = {International Computer Science Institute, University of California at Berkeley}, Year = {1989}, Number = {TR-89-063}, Type = {Technical Report}, Bdsk-url-1 = {http://ftp.icsi.berkeley.edu/ftp/pub/techreports/1989/tr-89-063.pdf}, Date-added = {2014-05-22 09:47:58 +0000}, Date-modified = {2014-05-22 09:47:58 +0000}, Url = {http://ftp.icsi.berkeley.edu/ftp/pub/techreports/1989/tr-89-063.pdf} } @Article{ortiz1999, Title = {Finite-deformation irreversible cohesive elements for three-dimensional crack-propagation analysis}, Author = {Ortiz, M. and Pandolfi, A.}, Journal = {International Journal for Numerical Methods in Engineering (IJNME)}, Year = {1999}, Pages = {1267-1282}, Volume = {44} } @Article{ortiz99a, Title = {Finite-deformation irreversible cohesive elements for three-dimensional crack-propagation analysis}, Author = {M Ortiz and A Pandolfi}, Journal = {International Journal for Numerical Methods in Engineering}, Year = {1999}, Pages = {1267-1282}, Volume = {44} } @Article{pandolfi12a, Title = {An eigenerosion approach to brittle fracture}, Author = {A Pandolfi and M Ortiz}, Journal = {International Journal for Numerical Methods in Engineering}, Year = {2012}, Pages = {694-714}, Volume = {92} } @Article{patzak01a, Title = {Parallel explicit finite element dynamics with nonlocal constitutive models}, Author = {B. Patz{\'a}k and D. Rypl and Z. Bittnar}, Journal = {{Computers \& Structures}}, Year = {2001}, Number = {26--28}, Pages = {2287 - 2297}, Volume = {79}, ISSN = {0045-7949} } @PhdThesis{Pietrzak:1997, Title = {Continuum mechanics modelling and augmented Lagrangian formulation of large deformation frictional contact problems}, Author = {Pietrzak, Grzegorz}, School = {{\'E}cole {P}olytechnique {F}{\'e}d{\'e}rale de {L}ausanne}, Year = {1997}, Date-added = {2014-09-16 12:23:01 +0000}, Date-modified = {2014-09-16 12:41:09 +0000}, Doi = {10.5075/epfl-thesis-1656} } @Article{pijaudier87a, Title = {Nonlocal damage theory}, Author = {Gilles Pijaudier-Cabot and Zden\v{e}k P. Ba\v{z}ant}, Journal = {Journal of Engineering Mechanics}, Year = {1987}, Number = {10}, Pages = {1512 - 1533}, Volume = {113} } @Article{rice76a, Title = {The Localisation of Plastic Deformation}, Author = {James R. Rice}, Journal = {Theoretical and Applied Mechanics (14th International Congress on Theoretical and Applied Mechanics, Delft, 1976, ed. W.T. Koiter)}, Year = {1976}, Pages = {207 - 220}, Volume = {1} } @Article{sharon96a, Title = {Microbranching instability and the dynamic fracture of brittle materials}, Author = {Eran Sharon and Jay Fineberg}, Journal = {Physical Review B}, Year = {1996}, Number = {10}, Pages = {7128 - 7139}, Volume = {54} } @Article{silling00a, Title = {Reformulation of elasticity theory for discontinuities and long-range forces}, Author = {S A Silling}, Journal = {Journal of the Mechanics and Physics of Solids}, Year = {2000}, Pages = {175-209}, Volume = {48} } @Book{simo92, Title = {Computational Inelasticity}, Author = {Simo, J.C. and Hughes, T.J.R.}, Publisher = {Springer}, Year = {1992} } @Article{snozzi_cohesive_2013, Title = {A cohesive element model for mixed mode loading with frictional contact capability}, Author = {Snozzi, Leonardo and Molinari, Jean-Francois}, Journal = {International Journal for Numerical Methods in Engineering}, Year = {2013}, Month = feb, Number = {5}, Pages = {510--526}, Volume = {93} } @Book{Belytschko:2000, Title = {Nonlinear Finite Elements for Continua and Structures}, Author = {Ted Belytschko, Wing Kam Liu, Brian Moran}, Publisher = {Wiley}, Year = {2000} } @Article{devree95, Title = {Comparison of nonlocal approaches in continuum damage mechanics}, Author = {J.H.P. de Vree and W.A.M. Brekelmans and M.A.J. van Gils}, Journal = {Computers \&; Structures}, Year = {1995}, Number = {4}, Pages = {581 - 588}, Volume = {55}, ISSN = {0045-7949}, Optdoi = {10.1016/0045-7949(94)00501-S} } @Unpublished{vocialta15, Title = {3D dynamic fragmentation with parallel dynamic insertion of cohesive elements}, Author = {M. Vocialta and N. Richart and J.-F. Molinari}, Note = {Submitted to IJNME}, Year = {2015} } @Unpublished{wolff14a, Title = {A non-local continuum damage approach to model dynamic crack branching}, Author = {C. Wolff and N. Richart and J.-F. Molinari}, Note = {Submitted to IJNME}, Year = {2014} } @Article{Zhou_Molinari_2004, Title = {Dynamic crack propagation with cohesive elements: a methodology to address mesh dependency}, Author = {F. Zhou and J. F. Molinari}, Journal = {International Journal for Numerical Methods in Engineering}, Year = {2004}, Timestamp = {2015.07.30} } @Misc{abaqus, Title = {Simulia ABAQUS FEA}, Bdsk-url-1 = {http://www.3ds.com/products-services/simulia/portfolio/abaqus/}, Key = {Unified FEA}, Url = {\url{http://www.3ds.com/products-services/simulia/portfolio/abaqus/}} } @Misc{cmake, Title = {CMake - Cross Platform Make}, Bdsk-url-1 = {http://www.cmake.org/}, Url = {\url{http://www.cmake.org/}} } @Misc{diana, Title = {TNO DIANA}, Bdsk-url-1 = {http://tnodiana.com/content/DIANA}, Key = {FEM}, Url = {\url{http://tnodiana.com/content/DIANA}} } @Misc{mayavi, Title = {The MayaVi Data Visualizer}, Bdsk-url-1 = {http://mayavi.sourceforge.net/}, Url = {\url{http://mayavi.sourceforge.net/}} } @Misc{mumps, Title = {MUMPS : a parallel sparse direct solver}, Bdsk-url-1 = {http://graal.ens-lyon.fr/MUMPS/}, Key = {sparse matrix, direct solver, parallelisme}, Url = {\url{http://graal.ens-lyon.fr/MUMPS/}} } @Misc{numpy, Title = {NumPy - Fundamental package for scientific computing with Python}, Bdsk-url-1 = {http://www.numpy.org/}, Url = {\url{http://www.numpy.org/}} } @Misc{paraview, Title = {ParaView - Open Source Scientific Visualization}, Bdsk-url-1 = {http://www.paraview.org/}, Url = {\url{http://www.paraview.org/}} } @Misc{scotch, Title = {SCOTCH: Static Mapping, Graph, Mesh and Hypergraph Partitioning}, Bdsk-url-1 = {http://www.labri.fr/perso/pelegrin/scotch/}, Url = {\url{http://www.labri.fr/perso/pelegrin/scotch/}} } @Misc{visit, Title = {VisIt Visualization Tool}, Bdsk-url-1 = {http://wci.llnl.gov/codes/visit/}, Url = {\url{http://wci.llnl.gov/codes/visit/}} } diff --git a/doc/dev-doc/manual/solidmechanicsmodel.rst b/doc/dev-doc/manual/solidmechanicsmodel.rst index b1ce6e401..4268d46e3 100644 --- a/doc/dev-doc/manual/solidmechanicsmodel.rst +++ b/doc/dev-doc/manual/solidmechanicsmodel.rst @@ -1,848 +1,877 @@ Solid Mechanics Model ===================== The solid mechanics model is a specific implementation of the :cpp:class:`Model ` interface dedicated to handle the equations of motion or equations of equilibrium. The model is created for a given mesh. It will create its own :cpp:class:`FEEngine ` object to compute the interpolation, gradient, integration and assembly operations. A :cpp:class:`SolidMechanicsModel ` object can simply be created like this:: SolidMechanicsModel model(mesh); where ``mesh`` is the mesh for which the equations are to be solved. A second parameter called ``spatial_dimension`` can be added after ``mesh`` if the spatial dimension of the problem is different than that of the mesh. This model contains at least the following six ``Arrays``: :cpp:func:`blocked_dofs `: contains a Boolean value for each degree of freedom specifying whether that degree is blocked or not. A Dirichlet boundary condition can be prescribed by setting the **blocked_dofs** value of a degree of freedom to ``true``. A Neumann boundary condition can be applied by setting the **blocked_dofs** value of a degree of freedom to ``false``. The **displacement**, **velocity** and **acceleration** are computed for all degrees of freedom for which the **blocked_dofs** value is set to ``false``. For the remaining degrees of freedom, the imposed values (zero by default after initialization) are kept. :cpp:func:`displacement `: contains the displacements of all degrees of freedom. It can be either a computed displacement for free degrees of freedom or an imposed displacement in case of blocked ones (:math:`\vec{u}` in the following). :cpp:func:`velocity `: contains the velocities of all degrees of freedom. As **displacement**, it contains computed or imposed velocities depending on the nature of the degrees of freedom (:math:`\dot{\vec{u}}` in the following). :cpp:func:`acceleration `: contains the accelerations of all degrees of freedom. As **displacement**, it contains computed or imposed accelerations depending on the nature of the degrees of freedom (:math:`\ddot{\vec{u}}` in the following). :cpp:func:`external_force `: contains the external forces applied on the nodes (:math:`\vec{f}_{\st{ext}}` in the following). :cpp:func:`internal_force `: contains the internal forces on the nodes (:math:`\vec{f}_{\mathrm{int}}` in the following). Some examples to help to understand how to use this model will be presented in the next sections. Model Setup ----------- Setting Initial Conditions `````````````````````````` For a unique solution of the equations of motion, initial displacements and velocities for all degrees of freedom must be specified: .. math:: \vec{u}(t=0) & = \vec{u}_0\\ \dot{\vec u}(t=0) & = \vec{v}_0 The solid mechanics model can be initialized as follows:: model.initFull() -This function initializes the internal arrays and sets them to -zero. Initial displacements and velocities that are not equal to zero -can be prescribed by running a loop over the total number of -nodes. Here, the initial displacement in :math:`x`-direction and the -initial velocity in :math:`y`-direction for all nodes is set to :math:`0.1` and :math:`1`, -respectively:: +This function initializes the internal arrays and sets them to zero. Initial +displacements and velocities that are not equal to zero can be prescribed by +running a loop over the total number of nodes. Here, the initial displacement in +:math:`x`-direction and the initial velocity in :math:`y`-direction for all +nodes is set to :math:`0.1` and :math:`1`, respectively:: auto & disp = model.getDisplacement(); auto & velo = model.getVelocity(); for (UInt node = 0; node < mesh.getNbNodes(); ++node) { disp(node, 0) = 0.1; velo(node, 1) = 1.; } .. _sect-smm-boundary: Setting Boundary Conditions ``````````````````````````` This section explains how to impose Dirichlet or Neumann boundary conditions. A Dirichlet boundary condition specifies the values that the displacement needs to take for every point :math:`x` at the boundary -(:math:`\Gamma_u`) of the problem domain (:numref:`fig:smm:boundaries`): +(:math:`\Gamma_u`) of the problem domain (:numref:`fig-smm-boundaries`): .. math:: \vec{u} = \bar{\vec u} \quad \forall \vec{x}\in \Gamma_{u} A Neumann boundary condition imposes the value of the gradient of the solution at the boundary :math:`\Gamma_t` of the problem domain -(:numref:`fig:smm:boundaries`): +(:numref:`fig-smm-boundaries`): .. math:: \vec{t} = \mat{\sigma} \vec{n} = \bar{\vec t} \quad \forall \vec{x}\in \Gamma_{t} .. _fig-smm-boundaries: .. figure:: figures/problem_domain.svg :align: center Problem domain :math:`\Omega` with boundary in three dimensions. The Dirchelet and the Neumann regions of the boundary are denoted with :math:`\Gamma_u` and :math:`\Gamma_t`, respecitvely. Different ways of imposing these boundary conditions exist. A basic way is to loop over nodes or elements at the boundary and apply local values. A more advanced method consists of using the notion of the boundary of the mesh. In the following both ways are presented. Starting with the basic approach, as mentioned, the Dirichlet boundary conditions can be applied by looping over the nodes and assigning the required values. :numref:`fig-smm-dirichlet_bc` shows a beam with a fixed support on the left side. On the right end of the beam, a load is applied. At the fixed support, the displacement has a given value. For this example, the displacements in both the :math:`x` and the :math:`y`-direction are set to zero. Implementing this displacement boundary condition is similar to the implementation of initial displacement conditions described above. However, in order to impose a displacement boundary condition for all time steps, the corresponding nodes need to be marked as boundary nodes using the function ``blocked``. While, in order to impose a load on the right side, the nodes are not marked. The detail codes are shown as follows .. code-block:: c++ auto & blocked = model.getBlockedDOFs(); const auto & pos = mesh.getNodes(); UInt nb_nodes = mesh.getNbNodes(); for (UInt node = 0; node < nb_nodes; ++node) { if(Math::are_float_equal(pos(node, _x), 0)) { blocked(node, _x) = true; // block dof in x-direction blocked(node, _y) = true; // block dof in y-direction disp(node, _x) = 0.; // fixed displacement in x-direction disp(node, _y) = 0.; // fixed displacement in y-direction } else if (Math::are_float_equal(pos(node, _y), 0)) { blocked(node, _x) = false; // unblock dof in x-direction forces(node, _x) = 10.; // force in x-direction } } .. _fig-smm-dirichlet_bc: .. figure:: figures/dirichlet.svg :align: center Beam with fixed support and load. For the more advanced approach, one needs the notion of a boundary in the mesh. Therefore, the boundary should be created before boundary condition functors can be applied. Generally the boundary can be specified from the mesh file or the geometry. For the first case, the function ``createGroupsFromMeshData`` is called. This function can read any types of mesh data which are provided in the mesh file. If the mesh file is created with Gmsh, the function takes one input strings which is either ``tag_0``, ``tag_1`` or ``physical_names``. The first two tags are assigned by Gmsh to each element which shows the physical group that they belong to. In Gmsh, it is also possible to consider strings for different groups of elements. These elements can be separated by giving a string ``physical_names`` to the function ``createGroupsFromMeshData`` .. code-block:: c++ mesh.createGroupsFromMeshData("physical_names"). Boundary conditions support can also be created from the geometry by calling ``createBoundaryGroupFromGeometry``. This function gathers all the elements on the boundary of the geometry. To apply the required boundary conditions, the function :cpp:func:`applyBC ` needs to be called on a :cpp:class:`SolidMechanicsModel `. This function gets a Dirichlet or Neumann functor and a string which specifies the desired boundary on which the boundary conditions is to be applied. The functors specify the type of conditions to apply. Three built-in functors for Dirichlet exist: :cpp:class:`FlagOnly `, :cpp:class:`FixedValue ` and :cpp:class:`IncrementValue `. The functor ``FlagOnly`` is used if a point is fixed in a given direction. Therefore, the input parameter to this functor is only the fixed direction. The ``FixedValue`` functor is used when a displacement value is applied in a fixed direction. The ``IncrementValue`` applies an increment to the displacement in a given direction. The following code shows the utilization of three functors for the top, bottom and side surface of the mesh which were already defined in the Gmsh .. code-block:: c++ model.applyBC(BC::Dirichlet::FixedValue(13.0, _y), "Top"); model.applyBC(BC::Dirichlet::FlagOnly(_x), "Bottom"); model.applyBC(BC::Dirichlet::IncrementValue(13.0, _x), "Side"); To apply a Neumann boundary condition, the applied traction or stress should be specified before. In case of specifying the traction on the surface, the functor :cpp:class:`FromTraction ` of Neumann boundary conditions is called. Otherwise, the functor :cpp:class:`FromStress ` should be called which gets the stress tensor as an input parameter .. code-block:: c++ Vector surface_traction{0., 0., 1.}; auto surface_stress(3, 3) = Matrix::eye(3); model.applyBC(BC::Neumann::FromTraction(surface_traction), "Bottom"); model.applyBC(BC::Neumann::FromStress(surface_stress), "Top"); If the boundary conditions need to be removed during the simulation, a functor is called from the Neumann boundary condition to free those boundary conditions from the desired boundary .. code-block:: c++ model.applyBC(BC::Neumann::FreeBoundary(), "Side"); User specified functors can also be implemented. A full example for setting both initial and boundary conditions can be found in ``examples/boundary_conditions.cc``. The problem solved -in this example is shown in :numref:`fig-smm-bc_and_id`. It consists +in this example is shown in :numref:`fig-smm-bc_and_ic`. It consists of a plate that is fixed with movable supports on the left and bottom side. On the right side, a traction, which increases linearly with the number of time steps, is applied. The initial displacement and velocity in :math:`x`-direction at all free nodes is zero and two respectively. .. _fig-smm-bc_and_ic: .. figure:: figures/bc_and_ic_example.svg :align: center :width: 75% Plate on movable supports. .. \begin{figure}[!htb] \centering \includegraphics[scale=0.8]{figures/bc_and_ic_example} \caption{Plate on movable supports.\label{fig-smm-bc_and_ic}} \end{figure} As it is mentioned in Section \ref{sect:common:groups}, node and element groups can be used to assign the boundary conditions. A generic example is given below with a Dirichlet boundary condition:: // create a node group NodeGroup & node_group = mesh.createNodeGroup("nodes_fix"); /* fill the node group with the nodes you want */ // create an element group using the existing node group mesh.createElementGroupFromNodeGroup("el_fix", "nodes_fix", spatial_dimension-1); // boundary condition can be applied using the element group name model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "el_fix"); Material Selector ````````````````` If the user wants to assign different materials to different finite elements groups in ``Akantu``, a material selector has to be used. By default, ``Akantu`` assigns the first valid material in the material file to all elements present in the model (regular continuum materials are assigned to the regular elements and cohesive materials are assigned to cohesive elements or element facets). To assign different materials to specific elements, mesh data information such as tag information or specified physical names can be used. :cpp:class:`MeshDataMaterialSelector ` class uses this information to assign different materials. With the proper physical name or tag name and index, different materials can be assigned as demonstrated in the examples below:: auto mat_selector = std::make_shared>("physical_names", model); model.setMaterialSelector(mat_selector); In this example the physical names specified in a GMSH geometry file will by used to match the material names in the input file. Another example would be to use the first (``tag_0``) or the second (``tag_1``) tag associated to each elements in the mesh:: auto mat_selector = std::make_shared>( "tag_1", model, first_index); model.setMaterialSelector(*mat_selector); where ``first_index`` (default is 1) is the value of ``tag_1`` that will be associated to the first material in the material input file. The following values of the tag will be associated with the following materials. There are four different material selectors pre-defined in ``Akantu``. :cpp:class:`MaterialSelector ` and :cpp:class:`DefaultMaterialSelector ` is used to assign a material to regular elements by default. For the regular elements, as in the example above, :cpp:class:`MeshDataMaterialSelector ` can be used to assign different materials to different elements. Apart from the ``Akantu``'s default material selectors, users can always develop their own classes in the main code to tackle various multi-material assignment situations. +For cohesive material, ``Akantu`` has a pre-defined material selector to assign +the first cohesive material by default to the cohesive elements which is called +:cpp:class:`DefaultMaterialCohesiveSelector +` and it inherits its properties from +:cpp:class:`DefaultMaterialSelector `. Multiple +cohesive materials can be assigned using mesh data information (for more +details, see :ref:`sect-smm-intrinsic-insertion`). + + +Insertion of Cohesive Elements +`````````````````````````````` +Cohesive elements are currently compatible only with static simulation +and dynamic simulation with an explicit time integration scheme (see +section :ref:`ssect-smm-expl-time-integration`). They do not have to be +inserted when the mesh is generated (intrinsic) but can be added +during the simulation (extrinsic). At any time during the simulation, +it is possible to access the following energies with the relative +function: + +.. code-block:: c++ + + Real Ed = model.getEnergy("dissipated"); + Real Er = model.getEnergy("reversible"); + Real Ec = model.getEnergy("contact"); + +A new model have to be call in a very similar way that the solid +mechanics model: + +.. code-block:: c++ + + SolidMechanicsModelCohesive model(mesh); + model.initFull(_analysis_method = _explicit_lumped_mass, + _is_extrinsic = true); + +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 ``intrinsic``, the second +one ``extrinsic``. When an element is present from the beginning, a +bi-linear or exponential cohesive law should be used instead of a +linear one. A bi-linear law works exactly like a linear one except for +an additional parameter :math:`\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}. + +.. _fig-smm-coh-insertion: +.. figure:: figures/insertion.svg + :align: center + + Insertion of a cohesive element. + +Extrinsic cohesive elements are dynamically inserted between two +standard elements when + +.. math:: + \sigma_\mathrm{eff} > \sigma_\mathrm{c} \quad\text {with} \quad \sigma_\mathrm{eff} = \sqrt{\sigma_\mathrm{n} ^ 2 + \frac{\tau ^ 2} {\beta ^ 2 }} + +in which :math:`\sigma_\mathrm { n } +` is the tensile normal traction and $\tau$ the resulting tangential one( :numref:`fig-smm-coh-insertion`). + +Extrinsic approach +'''''''''''''''''' + +During the simulation, stress has to be checked along each facet in order to +insert cohesive elements where the stress criterion is reached. This check is +performed by calling the method :cpp:func:`checkCohesiveStress +`, as example before +each step resolution: + +.. code-block:: c++ + + model.checkCohesiveStress(); + model.solveStep(); + +The area where stresses are checked and cohesive elements inserted can be +limited using the method :cpp:func:`setLimit +` on the :cpp:class:`CohesiveInserter +` during initialization. As example, to limit +insertion in the range :math:`[-1.5, 1.5]` in the $x$ direction: + +.. code-block:: c++ + + auto & inserter = model.getElementInserter(); + inserter.setLimit(_x, -1.5, 1.5); + +Additional restrictions with respect to :math:`_y` and :math:`_z` directions can +be added as well. + +.. _sect-smm-intrinsic-insertion: + +Intrinsic approach +'''''''''''''''''' + +Intrinsic cohesive elements are inserted in the mesh with the method +:cpp:func:`initFull `. +Similarly, the range of insertion can be limited with :cpp:func:`setLimit +` before the :cpp:func:`initFull +` call. + +In both cases extrinsic and intrinsic the insertion can be restricted to +surfaces or element groups. To do so the list of groups should be specified in +the input file. + +.. code-block:: + + model solid_mechanics_model_cohesive [ + cohesive_inserter [ + cohesive_surfaces = [surface1, surface2, ...] + cohesive_zones = [group1, group2, ...] + ] + + material cohesive_linear [ + name = insertion + beta = 1 + G_c = 10 + sigma_c = 1e6 + ] + ] + + + Static Analysis --------------- The :cpp:class:`SolidMechanicsModel ` class can handle different analysis methods, the first one being presented is the static case. In this case, the equation to solve is .. math:: \mat{K} \vec{u} = \vec{f}_{\mathrm{ext}} :label: eqn-smm-static where :math:`\mat{K}` is the global stiffness matrix, :math:`\vec{u}` the displacement vector and :math:`\vec{f}_{\st{ext}}` the vector of external forces applied to the system. To solve such a problem, the static solver of the :cpp:class:`SolidMechanicsModel ` object is used. First, a model has to be created and initialized. To create the model, a mesh (which can be read from a file) is needed, as explained in Section~\ref{sect:common:mesh}. Once an instance of a :cpp:class:`SolidMechanicsModel ` is obtained, the easiest way to initialize it is to use the :cpp:func:`initFull ` method by giving the :cpp:class:`SolidMechanicsModelOptions `. These options specify the type of analysis to be performed and whether the materials should be initialized with :cpp:func:`initMaterials ` or not .. code-block:: c++ SolidMechanicsModel model(mesh); model.initFull(_analysis_method = _static); Here, a static analysis is chosen by passing the argument :cpp:enumerator:`_static ` to the method. By default, the Boolean for no initialization of the materials is set to false, so that they are initialized during the ``initFull``. The method ``initFull`` also initializes all appropriate vectors to zero. Once the model is created and initialized, the boundary conditions can be set as explained in Section :ref:`sect-smm-boundary`. Boundary conditions will prescribe the external forces for some free degrees of freedom :math:`\vec{f}_{\st{ext}}` and displacements for some others. At this point of the analysis, the function :cpp:func:`solveStep ` can be called .. code-block:: c++ auto & solver = model.getNonLinearSolver(); solver.set("max_iterations", 1); solver.set("threshold", 1e-4); solver.set("convergence_type", SolveConvergenceCriteria::_residual); model.solveStep(); This function is templated by the solving method and the convergence criterion and takes two arguments: the tolerance and the maximum number of iterations (100 by default), which are :math:`10^{-4}` and :math:`1` for this example. The modified Newton-Raphson method is chosen to solve the system. In this method, the equilibrium equation (:eq:`eqn-smm-static`) is modified in order to apply a Newton-Raphson convergence algorithm: .. math:: \mat{K}^{i+1}\delta\vec{u}^{i+1} &= \vec{r} \\ &= \vec{f}_{\st{ext}} -\vec{f}_{\st{int}}\\ &= \vec{f}_{\st{ext}} - \mat{K}^{i} \vec{u}^{i}\\ \vec{u}^{i+1} &= \vec{u}^{i} + \delta\vec{u}^{i+1}~, where :math:`\delta\vec{u}` is the increment of displacement to be added from one iteration to the other, and :math:`i` is the Newton-Raphson iteration counter. By invoking the ``solveStep`` method in the first step, the global stiffness matrix :math:`\mat{K}` from (:eq:`eqn-smm-static`) is automatically assembled. A Newton-Raphson iteration is subsequently started, :math:`\mat{K}` is updated according to the displacement computed at the previous iteration and one loops until the forces are balanced (:cpp:enumerator:`SolveConvergenceCriteria::_residual `), i.e. :math:`||\vec{r}|| <` :cpp:member:`threshold `. One can also iterate until the increment of displacement is zero (:cpp:enumerator:`SolveConvergenceCriteria::_solution `) which also means that the equilibrium is found. For a linear elastic problem, the solution is obtained in one iteration and therefore the maximum number of iterations can be set to one. But for a non-linear case, one needs to iterate as long as the norm of the residual exceeds the tolerance threshold and therefore the maximum number of iterations has to be higher, e.g. :math:`100` .. code-block:: c++ solver.set("max_iterations", 100); model.solveStep(); At the end of the analysis, the final solution is stored in the **displacement** vector. A full example of how to solve a static problem is presented in the code ``examples/static/static.cc``. This example is composed of a 2D plate of steel, blocked with rollers on the left and bottom sides as shown in :numref:`fig-smm-static`. The nodes from the right side of the sample are displaced by :math:`0.01\%` of the length of the plate. .. _fig-smm-static: .. figure:: figures/static.svg :align: center :width: 75% Numerical setup. The results of this analysis is depicted in :numref:`fig-smm-implicit:static_solution`. -.. - \begin{figure}[!htb] - \centering - \includegraphics[width=.7\linewidth]{figures/static_analysis} - \caption{Solution of the static analysis. Left: the initial - condition, right: the solution (deformation magnified 50 times)} - \label{fig-smm-implicit:static_solution} - \end{figure} - .. _fig-smm-implicit:static_solution: .. figure:: figures/static_analysis.png :align: center :width: 75% Solution of the static analysis. Left: the initial condition, right: the solution (deformation magnified 50 times). -.. - Static implicit analysis with dynamic insertion of cohesive elements - ```````````````````````````````````````````````````````````````````` - - In order to solve problems with the extrinsic cohesive method in the - static implicit solution scheme, the function ``solveStepCohesive`` - has to be used:: - - model.solveStepCohesive<_scm_newton_raphson_tangent, - SolveConvergenceCriteria::_increment>(1e-13, error, - 25, false, 1e5, - true); - - - in which the arguments are: tolerance, error, max_iteration, - load_reduction, tol_increase_factor, do_not_factorize. This - function, first applies the Newton-Raphson procedure to solve the - problem. Then, it calls the method ``checkCohesiveStress`` to - check if cohesive elements have to be inserted. Since the approach is - implicit, only one element is added, the most stressed one (see - Section \ref{extrinsic_insertion}). After insertion, the - Newton-Raphson procedure is applied again to solve the same - incremental loading step, with the new inserted cohesive element. The - procedure loops in this way since no new cohesive elements have to be - inserted. At that point, the solution is saved, and the simulation - can advance to the next incremental loading step. In case the - convergence is not reached, the obtained solution is not saved and the - simulation return to the main file with the error given by the - solution saved in the argument of the function *error*. In this - way, the user can intervene in the simulation in order to find anyhow - convergence. A possibility is, for instance, to reduce the last - incremental loading step. The variable *load_reduction* can be - used to identify if the load has been already reduced or not. At the - same time, with the variable *tol_increase_factor* it is - possible to increase the tolerance by a factor defined by the user in - the main file, in order to accept a solution even with an error bigger - than the tolerance set at the beginning. It is possible to increase - the tolerance only in the phase of loading reduction, i.e., when - load_reduction = true. A not converged solution is never saved. In - case the convergence is not reached even after the loading reduction - procedure, the displacement field is not updated and remains the one - of the last converged incremental steps. Also, cohesive elements are - inserted only if convergence is reached. An example of the extrinsic - cohesive method in the static implicit solution scheme is presented in - ``examples/cohesive_element/cohesive_extrinsic_implicit``. Dynamic Methods --------------- Different ways to solve the equations of motion are implemented in the solid mechanics model. The complete equations that should be solved are: .. math:: \mat{M}\ddot{\vec{u}} + \mat{C}\dot{\vec{u}} + \mat{K}\vec{u} = \vec{f}_{\mathrm{ext}} :label: eqn-equation-motion where :math:`\mat{M}`, :math:`\mat{C}` and :math:`\mat{K}` are the mass, damping and stiffness matrices, respectively. In the previous section, it has already been discussed how to solve this equation in the static case, where :math:`\ddot{\vec{u}} = \dot{\vec{u}} = 0`. Here the method to solve this equation in the general case will be presented. For this purpose, a time discretization has to be specified. The most common discretization method in solid mechanics is the Newmark-:math:`\beta` method, which is also the default in ``Akantu``. For the Newmark-:math:`\beta` method, (:eq:`eqn-equation-motion`) becomes a system of three equations (see :cite:`curnier92a,hughes-83a` for more details): .. math:: \begin{eqnarray} \mat{M} \ddot{\vec{u}}_{n+1} + \mat{C}\dot{\vec{u}}_{n+1} + \mat{K} \vec{u}_{n+1} &={\vec{f}_{\st{ext}}}_{\, n+1}\\ \vec{u}_{n+1} &= \vec{u}_{n} + \left(1 - \alpha\right) \Delta t \dot{\vec{u}}_{n} + \alpha \Delta t \dot{\vec{u}}_{n+1} + \left(\frac{1}{2} - \alpha\right) \Delta t^2 \ddot{\vec{u}}_{n}\\ \dot{\vec{u}}_{n+1} &= \dot{\vec{u}}_{n} + \left(1 - \beta\right) \Delta t \ddot{\vec{u}}_{n} + \beta \Delta t \ddot{\vec{u}}_{n+1} \end{eqnarray} :label: eqn-equation-motion-discret In these new equations, :math:`\ddot{\vec{u}}_{n}`, :math:`\dot{\vec{u}}_{n}` and :math:`\vec{u}_{n}` are the approximations of :math:`\ddot{\vec{u}}(t_n)`, :math:`\dot{\vec{u}}(t_n)` and :math:`\vec{u}(t_n)`. -Equation~(\ref{eqn:equation-motion-discret}) is the equation of motion +Equation~(:eq:`eqn-equation-motion-discret`) is the equation of motion discretized in space (finite-element discretization), and the equations above are discretized in both space and time (Newmark discretization). The :math:`\alpha` and :math:`\beta` parameters determine the stability and the accuracy of the algorithm. Classical values for :math:`\alpha` and :math:`\beta` are usually :math:`\beta = 1/2` for no numerical damping and :math:`0 < \alpha < 1/2`. .. csv-table:: :header: ":math:`\alpha`", "Method (:math:`\beta= 1/2`)", "Type" ":math:`0`", "central difference", "explicit" ":math:`\frac{1}{6}`", "Fox-Goodwin(royal road)", "implicit" ":math:`\frac{1}{3}`", "Linear acceleration", "implicit" ":math:`\frac{1}{2}`", "Average acceleration (trapeziodal rule)", "implicit" The solution of this system of equations, -(:eq:`eqn-equation-motion-discret`)) is +(:eq:`eqn-equation-motion-discret`) is split into a predictor and a corrector system of equations. Moreover, in the case of a non-linear equations, an iterative algorithm such as the Newton-Raphson method is applied. The system of equations can be written as: - *Predictor*: .. math:: \vec{u}_{n+1}^{0} &= \vec{u}_{n} + \Delta t \dot{\vec{u}}_{n} + \frac{\Delta t^2}{2} \ddot{\vec{u}}_{n} \\ \dot{\vec{u}}_{n+1}^{0} &= \dot{\vec{u}}_{n} + \Delta t \ddot{\vec{u}}_{n} \\ \ddot{\vec{u}}_{n+1}^{0} &= \ddot{\vec{u}}_{n} - *Solve*: .. math:: \left(c \mat{M} + d \mat{C} + e \mat{K}_{n+1}^i\right) \vec{w} &= {\vec{f}_{\st{ext}}}_{\,n+1} - {\vec{f}_{\st{int}}}_{\,n+1}^i - \mat{C} \dot{\vec{u}}_{n+1}^i - \mat{M} \ddot{\vec{u}}_{n+1}^i\\ &= \vec{r}_{n+1}^i - *Corrector*: .. math:: \ddot{\vec{u}}_{n+1}^{i+1} &= \ddot{\vec{u}}_{n+1}^{i} +c \vec{w} \\ \dot{\vec{u}}_{n+1}^{i+1} &= \dot{\vec{u}}_{n+1}^{i} + d\vec{w} \\ \vec{u}_{n+1}^{i+1} &= \vec{u}_{n+1}^{i} + e \vec{w} where :math:`i` is the Newton-Raphson iteration counter and :math:`c`, :math:`d` and :math:`e` are parameters depending on the method used to solve the equations .. csv-table:: :header: "", ":math:`\vec{w}`", ":math:`e`", ":math:`d`", ":math:`c`" "in acceleration", ":math:`\delta\ddot{\vec{u}}`", ":math:`\alpha\beta\Delta t^2`", ":math:`\beta\Delta t`", ":math:`1`" "in velocity", ":math:`\delta\dot{\vec{u}}`", ":math:`\alpha\Delta t`", ":math:`1`", ":math:`\frac{1}{\beta\Delta t}`" "in displacement", ":math:`\delta\vec{u}`", ":math:`1`", ":math:`\frac{1}{\alpha\Delta t}`", ":math:`\frac{1}{\alpha\beta \Delta t^2}`" .. note:: If you want to use the implicit solver ``Akantu`` should be compiled at least with one sparse matrix solver such as Mumps :cite:`mumps`. Implicit Time Integration ````````````````````````` To solve a problem with an implicit time integration scheme, first a :cpp:class:`SolidMechanicsModel ` object has to be created and initialized. Then the initial and boundary conditions have to be set. Everything is similar to the example in the static case (Section~\ref{sect:smm:static}), however, in this case the implicit dynamic scheme is selected at the initialization of the model:: SolidMechanicsModel model(mesh); model.initFull(_analysis_method = _implicit_dynamic); Because a dynamic simulation is conducted, an integration time step :math:`\Delta t` has to be specified. In the case of implicit simulations, ``Akantu`` implements a trapezoidal rule by default. That is to say :math:`\alpha = 1/2` and :math:`\beta = 1/2` which is unconditionally stable. Therefore the value of the time step can be chosen arbitrarily within reason:: model.setTimeStep(time_step); Since the system has to be solved for a given amount of time steps, the method ``solveStep()``, (which has already been used in the static example in Section~\ref{sect:smm:static}), is called inside a time loop:: /// time loop Real time = 0.; auto & solver = model.getNonLinearSolver(); solver.set("max_iterations", 100); solver.set("threshold", 1e-12); solver.set("convergence_type", SolveConvergenceCriteria::_solution); for (UInt s = 1; time ` class. In the initialization, the explicit -scheme is selected using the ``_explicit_lumped_mass`` constant:: +The initialization of the simulation is similar to the static and implicit +dynamic version. The model is created from the :cpp:class:`SolidMechanicsModel +` class. In the initialization, the explicit scheme +is selected using the ``_explicit_lumped_mass`` constant:: SolidMechanicsModel model(mesh); model.initFull(_analysis_method = _explicit_lumped_mass); .. note:: Writing ``model.initFull()`` or ``model.initFull();`` is equivalent to use the ``_explicit_lumped_mass`` keyword, as this is the default case. The explicit time integration scheme implemented in ``Akantu`` uses a lumped mass matrix :math:`\mat{M}` (reducing the computational cost). This matrix is assembled by distributing the mass of each element onto its nodes. The resulting :math:`\mat{M}` is therefore a diagonal matrix stored in the **mass** vector of the model. The explicit integration scheme is conditionally stable. The time step has to be smaller than the stable time step which is obtained in Akantu as follows:: critical_time_step = model.getStableTimeStep(); The stable time step corresponds to the time the fastest wave (the compressive wave) needs to travel the characteristic length of the mesh: .. math:: \Delta t_{\st{crit}} = \frac{\Delta x}{c} where :math:`\Delta x` is a characteristic length (\eg the inradius in the case of linear triangle element) and :math:`c` is the celerity of the fastest wave in the material. It is generally the compressive wave of celerity :math:`c = \sqrt{\frac{2 \mu + \lambda}{\rho}}`, :math:`\mu` and :math:`\lambda` are the first and second Lame's coefficients and :math:`\rho` is the density. However, it is recommended to impose a time step that is smaller than the stable time step, for instance, by multiplying the stable time step by a safety factor smaller than one:: const Real safety_time_factor = 0.8; Real applied_time_step = critical_time_step * safety_time_factor; model.setTimeStep(applied_time_step); The initial displacement and velocity fields are, by default, equal to zero if not given specifically by the user (see \ref{sect:smm:initial_condition}). Like in implicit dynamics, a time loop is used in which the displacement, velocity and acceleration fields are updated at each time step. The values of these fields are obtained from the Newmark:math:`-\beta` equations with :math:`\beta=1/2` and :math:`\alpha=0`. In ``Akantu`` these computations at each time step are invoked by calling the function ``solveStep``:: for (UInt s = 1; (s-1)*applied_time_step < total_time; ++s) { model.solveStep(); } The method ``solveStep`` wraps the four following functions: - ``model.explicitPred()`` allows to compute the displacement field at :math:`t+1` and a part of the velocity field at :math:`t+1`, denoted by :math:`\vec{\dot{u}^{\st{p}}}_{n+1}`, which will be used later in the method ``model.explicitCorr()``. The equations are: .. math:: \vec{u}_{n+1} &= \vec{u}_{n} + \Delta t \vec{\dot{u}}_{n} + \frac{\Delta t^2}{2} \vec{\ddot{u}}_{n}\\ \vec{\dot{u}^{\st{p}}}_{n+1} &= \vec{\dot{u}}_{n} + \Delta t \vec{\ddot{u}}_{n} - ``model.updateResidual()`` and ``model.updateAcceleration()`` compute the acceleration increment :math:`\delta \vec{\ddot{u}}`: .. math:: \left(\mat{M} + \frac{1}{2} \Delta t \mat{C}\right) \delta \vec{\ddot{u}} = \vec{f_{\st{ext}}} - \vec{f}_{\st{int}\, n+1} - \mat{C} \vec{\dot{u}^{\st{p}}}_{n+1} - \mat{M} \vec{\ddot{u}}_{n} The internal force :math:`\vec{f}_{\st{int}\, n+1}` is computed from the displacement :math:`\vec{u}_{n+1}` based on the constitutive law. - ``model.explicitCorr()`` computes the velocity and acceleration fields at :math:`t+1`: .. math:: \vec{\dot{u}}_{n+1} &= \vec{\dot{u}^{\st{p}}}_{n+1} + \frac{\Delta t}{2} \delta \vec{\ddot{u}} \\ \vec{\ddot{u}}_{n+1} &= \vec{\ddot{u}}_{n} + \delta \vec{\ddot{u}} The use of an explicit time integration scheme is illustrated by the example: ``examples/explicit/explicit_dynamic.cc``. This example models the propagation of a wave in a steel beam. The beam and the applied displacement in the :math:`x` direction are shown in :numref:`fig-smm-explicit`. .. _fig-smm-explicit: .. figure:: figures/explicit.svg :align: center :width: 90% Numerical setup. -.. - \begin{figure}[!htb] \centering - \begin{tikzpicture} - \coordinate (c) at (0,2); - \draw[shift={(c)},thick, color=blue] plot [id=x, domain=-5:5, samples=50] ({\x, {(40 * sin(0.1*pi*3*\x) * exp(- (0.1*pi*3*\x)*(0.1*pi*3*\x) / 4))}}); - \draw[shift={(c)},-latex] (-6,0) -- (6,0) node[right, below] {:math:`x`}; - \draw[shift={(c)},-latex] (0,-0.7) -- (0,1) node[right] {:math:`u`}; - \draw[shift={(c)}] (-0.1,0.6) node[left] {:math:`A`}-- (1.5,0.6); - - \coordinate (l) at (0,0.6); - \draw[shift={(0,-0.7)}] (-5, 0) -- (5,0) -- (5, 1) -- (-5, 1) -- cycle; - \draw[shift={(l)}, latex-latex] (-5,0)-- (5,0) node [midway, above] {:math:`L`}; - \draw[shift={(l)}] (5,0.2)-- (5,-0.2); - \draw[shift={(l)}] (-5,0.2)-- (-5,-0.2); - - \coordinate (h) at (5.3,-0.7); - \draw[shift={(h)}, latex-latex] (0,0)-- (0,1) node [midway, right] {:math:`h`}; - \draw[shift={(h)}] (-0.2,1)-- (0.2,1); - \draw[shift={(h)}] (-0.2,0)-- (0.2,0); - \end{tikzpicture} - - \caption{Numerical setup \label{fig-smm-explicit}} - \end{figure} The length and height of the beam are :math:`L={10}\textrm{m}` and :math:`h = {1}\textrm{m}`, respectively. The material is linear elastic, homogeneous and isotropic (density: \SI{7800}{\kilo\gram\per\cubic\metre}, Young's modulus: \SI{210}{\giga\pascal} and Poisson's ratio: :math:`0.3`). The imposed displacement follow a Gaussian function with a maximum amplitude of :math:`A = {0.01}\textrm{m}`. The potential, kinetic and total energies are computed. The safety factor is equal to :math:`0.8`. .. include:: ./constitutive-laws.rst .. include:: ./new-constitutive-laws.rst diff --git a/doc/dev-doc/reference.rst b/doc/dev-doc/reference.rst index 8be6066c0..dc8255a21 100644 --- a/doc/dev-doc/reference.rst +++ b/doc/dev-doc/reference.rst @@ -1,72 +1,90 @@ .. _reference: Reference --------- Common `````` .. doxygenfunction:: akantu::initialize(const std::string &input_file, int &argc, char **&argv) .. doxygenfunction:: akantu::initialize(int &argc, char **&argv) .. doxygentypedef:: akantu::UInt .. doxygentypedef:: akantu::Int .. doxygentypedef:: akantu::Real .. doxygenenum:: akantu::ElementType .. doxygenenum:: akantu::ModelType .. doxygenenum:: akantu::AnalysisMethod .. doxygenenum:: akantu::SolveConvergenceCriteria .. doxygenclass:: akantu::ArrayBase .. doxygenclass:: akantu::ArrayDataLayer .. doxygenclass:: akantu::Array .. doxygenclass:: akantu::ElementTypeMapArray .. doxygenclass:: akantu::Vector .. doxygenclass:: akantu::Matrix Mesh ```` .. doxygenclass:: akantu::Mesh .. doxygenclass:: akantu::FEEngine Models `````` Common ...... .. doxygenclass:: akantu::BC::Dirichlet::FixedValue .. doxygenclass:: akantu::BC::Dirichlet::FlagOnly .. doxygenclass:: akantu::BC::Dirichlet::IncrementValue .. doxygenclass:: akantu::BC::Neumann::FromStress .. doxygenclass:: akantu::BC::Neumann::FromTraction .. doxygenclass:: akantu::BoundaryCondition .. doxygenclass:: akantu::BoundaryConditionFunctor .. doxygenclass:: akantu::EventHandlerManager .. doxygenclass:: akantu::Model .. doxygenclass:: akantu::NonLocalManagerCallback Solvers ....... .. doxygenclass:: akantu::ModelSolver .. doxygenclass:: akantu::DOFManager .. doxygenclass:: akantu::NonLinearSolver .. doxygenclass:: akantu::NonLinearSolverNewtonRaphson Solid Mechanics Model ..................... .. doxygenclass:: akantu::SolidMechanicsModel .. doxygenclass:: akantu::SolidMechanicsModelOptions .. doxygenclass:: akantu::MaterialSelector .. doxygenclass:: akantu::MeshDataMaterialSelector .. doxygenclass:: akantu::Material .. doxygenclass:: akantu::InternalField +Solid Mechanics Model Cohesive +.............................. + +.. doxygenclass:: akantu::SolidMechanicsModelCohesive +.. doxygenclass:: akantu::FragmentManager + Synchronizers ````````````` .. doxygenclass:: akantu::DataAccessor + +Input/Output +```````````` +.. doxygenclass:: akantu::Dumpable +.. doxygenclass:: akantu::DumperIOHelper +.. doxygenclass:: akantu::DumperParaview +.. doxygenclass:: akantu::DumperText +.. doxygenclass:: akantu::Field +.. doxygenclass:: akantu::Parser +.. doxygenclass:: akantu::ParserParameter +.. doxygenclass:: akantu::ParserSection +.. doxygenenum:: akantu::SectionType