diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0446abb71..3ca043942 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,348 +1,349 @@ stages: - configure - build - check-warnings - test - deploy .docker_build: image: 'docker:19.03.11' stage: .pre services: - docker:19.03.11-dind variables: # Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: "/certs" before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - cd test/ci/${IMAGE_NAME}/ - docker build -t registry.gitlab.com/akantu/akantu/${IMAGE_NAME} . - docker push registry.gitlab.com/akantu/akantu/${IMAGE_NAME} docker build:debian-testing: variables: IMAGE_NAME: debian:testing extends: .docker_build rules: - changes: - test/ci/debian:testing/Dockerfile docker build:ubuntu-lts: variables: IMAGE_NAME: ubuntu:lts extends: .docker_build rules: - changes: - test/ci/ubuntu:lts/Dockerfile .configure: stage: configure except: - tags variables: BLA_VENDOR: 'Generic' script: - cmake -E make_directory build - cd build - cmake -DAKANTU_COHESIVE_ELEMENT:BOOL=TRUE -DAKANTU_IMPLICIT:BOOL=TRUE -DAKANTU_PARALLEL:BOOL=TRUE -DAKANTU_STRUCTURAL_MECHANICS:BOOL=TRUE -DAKANTU_HEAT_TRANSFER:BOOL=TRUE -DAKANTU_DAMAGE_NON_LOCAL:BOOL=TRUE + -DAKANTU_PHASE_FIELD:BOOL=TRUE -DAKANTU_PYTHON_INTERFACE:BOOL=TRUE -DAKANTU_EXAMPLES:BOOL=TRUE -DAKANTU_BUILD_ALL_EXAMPLES:BOOL=TRUE -DAKANTU_TEST_EXAMPLES:BOOL=TRUE -DAKANTU_TESTS:BOOL=TRUE -DAKANTU_RUN_IN_DOCKER:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Coverage .. - cp compile_commmands.json .. artifacts: when: on_success paths: - build - compile_commands.json expire_in: 10h .build: stage: build script: - cmake --build build/src > >(tee -a ${output}-out.log) 2> >(tee -a ${output}-err.log >&2) - cmake --build build/python > >(tee -a ${output}-out.log) 2> >(tee -a ${output}-err.log >&2) - cmake --build build/test/ > >(tee -a ${output}-out.log) 2> >(tee -a ${output}-err.log >&2) - cmake --build build/examples > >(tee -a ${output}-out.log) 2> >(tee -a ${output}-err.log >&2) artifacts: when: on_success paths: - build/ #- ${output}-out.log - ${output}-err.log - compile_commands.json expire_in: 10h .tests: stage: test script: - cd build - ctest -T test --no-compress-output --timeout 1800 after_script: - cd build - tag=$(head -n 1 < Testing/TAG) - if [ -e Testing/${tag}/Test.xml ]; then - xsltproc -o ./juint.xml ${CI_PROJECT_DIR}/test/ci/ctest2junit.xsl Testing/${tag}/Test.xml; - fi - gcovr --xml --gcov-executable "${GCOV_EXECUTABLE}" --output coverage.xml --object-directory ${CI_PROJECT_DIR}/build --root ${CI_PROJECT_DIR} -s || true artifacts: when: always paths: - build/juint.xml - build/coverage.xml reports: junit: - build/juint.xml cobertura: - build/coverage.xml .analyse_build: stage: check-warnings script: - if [[ $(cat ${output}-err.log | grep warning -i) ]]; then - cat ${output}-err.log; - exit 1; - fi allow_failure: true artifacts: when: on_failure paths: - "$output-err.log" # ------------------------------------------------------------------------------ .cache_build: variables: CCACHE_BASEDIR: ${CI_PROJECT_DIR}/build CCACHE_DIR: ${CI_PROJECT_DIR}/.ccache CCACHE_NOHASHDIR: 1 CCACHE_COMPILERCHECK: content cache: key: ${output} policy: pull-push paths: - .ccache/ - third-party/google-test - third-party/pybind11 before_script: - ccache --zero-stats || true after_script: - ccache --show-stats || true # ------------------------------------------------------------------------------ .image_debian_testing: image: registry.gitlab.com/akantu/akantu/debian:testing .image_ubuntu_lts: image: registry.gitlab.com/akantu/akantu/ubuntu:lts # ------------------------------------------------------------------------------ .compiler_gcc: variables: CC: /usr/lib/ccache/gcc CXX: /usr/lib/ccache/g++ FC: gfortran GCOV_EXECUTABLE: gcov .compiler_clang: variables: CC: /usr/lib/ccache/clang CXX: /usr/lib/ccache/clang++ FC: gfortran GCOV_EXECUTABLE: llvm-cov gcov # ------------------------------------------------------------------------------ .debian_testing_gcc: variables: output: debian_testing_gcc extends: - .compiler_gcc - .image_debian_testing - .cache_build .debian_testing_clang: variables: output: debian_testing_clang extends: - .compiler_clang - .image_debian_testing - .cache_build .ubuntu_lts_gcc: variables: output: ubuntu_lts_gcc extends: - .compiler_gcc - .image_ubuntu_lts - .cache_build # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ configure:debian_testing_gcc: extends: - .debian_testing_gcc - .configure cache: policy: pull-push build:debian_testing_gcc: extends: - .debian_testing_gcc - .build dependencies: - configure:debian_testing_gcc test:debian_testing_gcc: extends: - .debian_testing_gcc - .tests dependencies: - build:debian_testing_gcc analyse_build:debian_testing_gcc: extends: - .debian_testing_gcc - .analyse_build dependencies: - build:debian_testing_gcc # ------------------------------------------------------------------------------ configure:debian_testing_clang: extends: - .debian_testing_clang - .configure cache: policy: pull-push build:debian_testing_clang: extends: - .debian_testing_clang - .build dependencies: - configure:debian_testing_clang test:debian_testing_clang: extends: - .debian_testing_clang - .tests dependencies: - build:debian_testing_clang analyse_build:debian_testing_clang: extends: - .debian_testing_clang - .analyse_build dependencies: - build:debian_testing_clang # ------------------------------------------------------------------------------ configure:ubuntu_lts_gcc: extends: - .ubuntu_lts_gcc - .configure cache: policy: pull-push build:ubuntu_lts_gcc: extends: - .ubuntu_lts_gcc - .build dependencies: - configure:ubuntu_lts_gcc analyse_build:ubuntu_lts_gcc: extends: - .ubuntu_lts_gcc - .analyse_build dependencies: - build:ubuntu_lts_gcc test:ubuntu_lts_gcc: extends: - .ubuntu_lts_gcc - .tests dependencies: - build:ubuntu_lts_gcc # ------------------------------------------------------------------------------ code_quality: stage: test image: docker:19.03.12 allow_failure: true services: - docker:19.03.12-dind variables: DOCKER_DRIVER: overlay2 DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: "/certs" CODECLIMATE_DEV: 1 CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.22" needs: [] script: - export SOURCE_CODE=$PWD - | # this is required to avoid undesirable reset of Docker image ENV variables being set on build stage function propagate_env_vars() { CURRENT_ENV=$(printenv) for VAR_NAME; do echo $CURRENT_ENV | grep "${VAR_NAME}=" > /dev/null && echo "--env $VAR_NAME " done } - docker pull --quiet "$CODE_QUALITY_IMAGE" - | - docker build -t codeclimate/codeclimate-clang-tidy test/ci/codeclimate/codeclimate-clang-tidy - | docker run \ $(propagate_env_vars \ SOURCE_CODE \ TIMEOUT_SECONDS \ CODECLIMATE_DEBUG \ CODECLIMATE_DEV \ REPORT_STDOUT \ REPORT_FORMAT \ ENGINE_MEMORY_LIMIT_BYTES \ ) \ --volume "$PWD":/code \ --volume /var/run/docker.sock:/var/run/docker.sock \ "$CODE_QUALITY_IMAGE" /code artifacts: paths: - gl-code-quality-report.json reports: codequality: gl-code-quality-report.json expire_in: 1 week dependencies: [] rules: - if: '$CODE_QUALITY_DISABLED' when: never - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH' # ------------------------------------------------------------------------------ pages: stage: deploy extends: - .debian_testing_gcc script: - cd build - cmake -DAKANTU_DOCUMENTATION=ON .. - cmake --build . -t sphinx-doc - mv doc/dev-doc/html ../public dependencies: - build:debian_testing_gcc artifacts: paths: - public only: - master diff --git a/doc/dev-doc/index.rst b/doc/dev-doc/index.rst index c7116d93f..34de864af 100644 --- a/doc/dev-doc/index.rst +++ b/doc/dev-doc/index.rst @@ -1,49 +1,50 @@ .. 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/heattransfermodel.rst + ./manual/phasefieldmodel.rst ./manual/structuralmechanicsmodel.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/figures/phasefield-dynamic.png b/doc/dev-doc/manual/figures/phasefield-dynamic.png new file mode 100644 index 000000000..248867548 Binary files /dev/null and b/doc/dev-doc/manual/figures/phasefield-dynamic.png differ diff --git a/doc/dev-doc/manual/phasefieldmodel.rst b/doc/dev-doc/manual/phasefieldmodel.rst new file mode 100644 index 000000000..45bc01472 --- /dev/null +++ b/doc/dev-doc/manual/phasefieldmodel.rst @@ -0,0 +1,263 @@ +PhaseField Model +================ + +The phasefield model is a specific implementation of +:cpp:class:`Model ` interface to handle brittle fracture +for infinitesimal strains. + +Theory +------ + +The variational formulation of brittle fracture was first proposed by +Francfort and Marigo:cite:`franc` so as to overcome the shortcomings +of Griffith's criteria. The approach used by Francfort and Margio for +variational formulation is based on the principle of global minimality +of total energy. Similar to Griffith's work, they define a surface +energy corresponding to the discontinuity :math:`\Gamma` as + + +.. math:: + \Phi_{s}(\Gamma) = \int\limits_{\Gamma}\mathcal{G}_cd\mathcal{H}^{d-1}(\Gamma) + + +where :math:`\mathcal{H}^{d-1}` is d-1 dimensional Hausdroff measure +which is surface measure for smooth hypersurfaces. the material +behavior is considered to be linearly elastic with small strains +throughout the body. Based on these assumptions the elastic energy of +the body is defined as + +.. math:: + \Phi_e(\Gamma,u) = \int\limits_{\Omega_{p}}\psi(\boldsymbol{\epsilon}(u))d\Omega + +where :math:`\psi` is elastic energy density and it is given as a +function of strain as + +.. math:: + \psi_e(\boldsymbol{\epsilon}) = \dfrac{1}{2}\lambda(\text{tr}(\boldsymbol{\epsilon}))^{2}+\mu\boldsymbol{\epsilon}:\boldsymbol{\epsilon} + + +Exponential phasefield law +'''''''''''''''''''''''''' + +Bourdin et. al.:cite:`bourdin` in their work proposed a regularized +version of variational formulation where a scalar field variable +:math:`d(\vec{x},t)` is used to represent crack. This scalar field +variable approximates the sharp crack topology by taking value 1 at +crack location and smoothly diffusing into value 0 away from the +crack. \figref{fig:diffusive_topology} shows both sharp crack topology +and an approximated regularized crack topology for one-dimensional +case. + + +The strong form of the phasefield can be expressed as + +.. math:: + 2(1-d)\mathcal{H} - \dfrac{G_c}{l_0}(d-l_0^2d) = 0 + \nabla d . \boldsymbol n = 0 + + + +Using the PhaseField Model +-------------------------- + +The :cpp:class:`PhaseFieldModel ` object +solves the strong form using an inplicit solver. An instance of the +class can be created like this:: + + PhaseFieldModel phase(mesh, spatial_dimension); + +while ans existing mesh has been used (see \ref{sect:common:mesh}). To +intialize the model object:: + + phase.initFull(); + +Currently, implicit solver is defined for the phasefield model and no +explicit solver is implemented in Akantu. Furthermore, By default, the +implicit solver defined is of linear type. One can change the linear +solver to a non-linear by initiating a new solver type. + +The phasefield model contains :cpp:class:`Arrays `: + +:cpp:func:`damage `: + contains the nodal damage :math:`d` (zero by default after the + initialization) + +:cpp:func:`blocked_dofs ` + contains a Boolean value specifying whether the damage at a node + is to be blocked or not. A Dirichlet boundary condition can be + prescribed by setting the **blocked_dofs** value of damage to + ``true``. The **damage** ais computed for all nodes where the + **blocked_dofs** value is set to ``false``. For the remaining + nodes, the imposed values (zero by default after initialization) + are kept. + +:cpp:func:`internal_force ` + contains the driving force responsible for the crack to nucelate + or propagate. + + Currently, the phasefield model uses a exponential shaped scalar + field variable :math:`d(\vec{x}, t)` to approximate the sharp crack + topology. A Phasefield variable thus requires a length scale + parameter :math:`l_0` to control the width of the diffusive crack + topology along with the material parameters such as elastic modulus, + poisson's ratio, critical energy release rate. + + The data input file provides the parameters for the exponential + phasefield law as follows: + +.. code-block:: + + phasefield exponential [ + name = plate + E = 210.0 + nu = 0.3 + gc = 5e-3 + l0 = 0.1 + ] + +:cpp:class:`PhaseFieldModel` can handle + phasefield laws for multiple materials. To define so: + +.. code-block:: + + phasefield exponential [ + name = hard + E = 210.0 + nu = 0.3 + gc = 5e-3 + l0 = 0.1 + ] + + phasefield exponential [ + name = soft + E = 21.0 + nu = 0.3 + gc = 5e-5 + l0 = 0.1 + ] + +In order to assign correct phasefield variable properties based on the +names of region as defined in mesh file, +:cpp:class:`MeshDataPhaseFieldSelector +` must be set as phasefield +selector:: + + auto && selector = std::make_shared>( + "physical_names", phase); + phase.setPhaseFieldSelector(selector); + +For the crack to nucleate or propagate, phasefield model requires +strain measure at each quadrature point. The strain measure computed +from solid mechanics model is provided to the phasefield +model. Similarly, damage value computed at each quadrature point by +the phasefield model is provided to the solid mechanics model. This +damage is thus used to degrade the the elastic strain energy. To do +so, a new material which is a specific implementation of +:cpp:class:`MaterialDamage ` is defined for +solid mechanics model. The governing equation is given as + +.. math:: + \boldsymbol \sigma = ((1-d)^2 + \eta)\dfrac{\psi}{\boldsymbol \epsilon} + +where :math:`\psi` is the elastic energy and :math:`\eta` is a +numerical parmaeter avoid numerical difficulties due to full +degradation of elastic energy for fully broken state. The material +properties are thus provided in the input data filled as: + +.. code-block:: + + material phasefield [ + name = hard + rho = 1. + E = 210.0 + nu = 0.3 + eta = 0.0 + Plane_Stress = false + ] + + material phasefield [ + name = soft + rho = 1. + E = 21.0 + nu = 0.3 + eta = 0.0 + Plane_Stress = false + ] + + + +To simplify the execution of phasefield model coupled with +solidmechanis model, a special class +:cpp:class:`CouplerSolidPhaseField` is +provided. + +Coupling Phase Field Model and Solid Mechanics Model +'''''''''''''''''''''''''''''''''''''''''''''''''''' + +A dedicated coupler class :cpp:class:`CouplerSolidPhaseField +` is defined in Akantu to ease the +coupling of the two models. + +When an instance of a Coupler class is created, it automatically +creates the instances of solid mechanics model and phasefield +model. The two objects can be retrived from the coupler class. + +.. code-block:: c++ + + CouplerSolidPhaseField coupler(mesh); + auto & phase = coupler.getPhaseFieldModel(); + auto & solid = coupler.getSolidMechanicsModel(); + +The two objects must be used to define the solver type and apply +boundary conditions. + +.. code-block:: c++ + solid.initFull(_analysis_method = _explicit_lumped_mass); + phase.initFull(_analysis_method = _static); + + +The whole proces of coupling the two models at a given time step is +made easy by the :cpp:`solve` function of coupler class. + +.. code-block:: c++ + + coupler.solve(, ); + + +Staggered scheme +---------------- + +To solve the solid mechanics model and phasefield model, staggered +scheme is implemented. In staggered scheme, at current time step first +solid mechanics model is solved assuming the damage values from the +previous time step. The strain thus computed are passed to the +phasefield model and now, phasefield model is solved for the damage +variable. At each iteration step, convergence in displacement and +damage is checked for. If convergence is not reached, the combined +newton-raphson iteration continues. + +To illustrate the staggered scheme solution of phasefield model, one +can refere to the examples provided for the phasefield model. Two +examples provided are for static `phasefield-static.py` and dynamic +crack propgation `phasefield-dynamic.py`. + +For the static problem, both the solid mechanics model and the +phsefield model are solved using alinear implicit solver. Convergence +in value of both displacement as well as damage is checked at each +loading step. + +In case of the dynamic problem, solid mechanics model is solved +dynamically using an explicit solver and the phasefield model is +solved using a linear implcit solver. In this sceanrio, the staggered +scheme doesnot check for any convergence. Below is the crack +propagation observed for the dyanmic problem. + +.. _fig-phasefieldmodel-dynamic: + +.. figure:: figures/phasefield-dynamic.png + :align: center + + Dynamic crack propagation using phasefield model + + +.. LocalWords: phasefield SolidMechanics PhaseField akantu cpp diff --git a/doc/dev-doc/reference.rst b/doc/dev-doc/reference.rst index 0550062f5..20f199e39 100644 --- a/doc/dev-doc/reference.rst +++ b/doc/dev-doc/reference.rst @@ -1,101 +1,114 @@ .. _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 Heat Transfer Model ................... .. doxygenclass:: akantu::HeatTransferModel +Phase Field Model +................... + +.. doxygenclass:: akantu::PhaseFieldModel +.. doxygenclass:: akantu::PhaseField + Structural Mechanics Model .......................... .. doxygenclass:: akantu::StructuralMaterial .. doxygenclass:: akantu::StructuralMechanicsModel + +Coupler Solid PhaseField +................... + +.. doxygenclass:: akantu::CouplerSolidPhaseField + + 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 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f7d2fdb07..bcdace931 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,53 +1,55 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Fri Oct 22 2010 # @date last modification: Fri Jan 22 2016 # # @brief List of examples # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # # @section DESCRIPTION # #=============================================================================== add_example(new_material "Example on how to add a new material in Akantu" PACKAGE core) add_example(boundary_conditions "Example on hoy to set boundary conditions" PACKAGE core) add_example(explicit "Example on how to run an explicit simulation" PACKAGE core) add_example(io "Example on how to perform Input/Output operations" PACKAGE core) add_example(implicit "Example on how to run an implicit simulation" PACKAGE implicit) add_example(static "Example on how to run a static simulation" PACKAGE implicit) add_example(parallel "Example of how to write a parallel code with Akantu" PACKAGE parallel) add_example(cohesive_element "Cohesive element examples" PACKAGE cohesive_element) add_example(structural_mechanics "Structural mechanics model examples" PACKAGE structural_mechanics) add_example(heat_transfer "Example on how to run heat transfer simulation" PACKAGE heat_transfer) add_example(python "Example on how to use the python interface" PACKAGE python_interface) add_example(embedded "Example on how to run embedded model simulation" PACKAGE embedded) +add_example(phase_field "Example on how to run phase field model simulation" PACKAGE phase_field) + package_add_files_to_package( examples/README.rst cmake/AkantuExampleMacros.cmake ) diff --git a/examples/phase_field/CMakeLists.txt b/examples/phase_field/CMakeLists.txt new file mode 100644 index 000000000..e12c9ba1d --- /dev/null +++ b/examples/phase_field/CMakeLists.txt @@ -0,0 +1,40 @@ +#=============================================================================== +# @file CMakeLists.txt +# +# @author Mohit Pundir +# +# @date creation: Tue Oct 2 2018 +# +# @brief configuration for phase field example +# +# @section LICENSE +# +# Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de +# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des +# Solides) +# +# Akantu is free software: you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Akantu. If not, see . +# +# @section DESCRIPTION +# +#=============================================================================== + +add_mesh(square_notch square_notch.geo 2 1) + +register_example(phase_field_notch + SOURCES phase_field_notch.cc + DEPENDS square_notch + FILES_TO_COPY material_notch.dat + ) + diff --git a/examples/phase_field/material_notch.dat b/examples/phase_field/material_notch.dat new file mode 100644 index 000000000..5ce8d9c68 --- /dev/null +++ b/examples/phase_field/material_notch.dat @@ -0,0 +1,20 @@ +model solid_mechanics_model [ +material phasefield [ + name = plate + rho = 1. + E = 210.0 + nu = 0.3 + eta = 0 + Plane_Stress = false +] +] + +model phase_field_model [ +phasefield exponential [ + name = plate + l0 = 0.0075 + gc = 2.7e-3 + E = 210.0 + nu = 0.3 +] +] \ No newline at end of file diff --git a/examples/phase_field/phase_field_notch.cc b/examples/phase_field/phase_field_notch.cc new file mode 100644 index 000000000..a57212bd8 --- /dev/null +++ b/examples/phase_field/phase_field_notch.cc @@ -0,0 +1,92 @@ +/* -------------------------------------------------------------------------- */ +#include "non_linear_solver.hh" +#include "phase_field_model.hh" +#include "solid_mechanics_model.hh" +#include "coupler_solid_phasefield.hh" +/* -------------------------------------------------------------------------- */ +#include +#include +#include +/* -------------------------------------------------------------------------- */ + +using namespace akantu; +using clk = std::chrono::high_resolution_clock; +using second = std::chrono::duration; +using millisecond = std::chrono::duration; + +const UInt spatial_dimension = 2; + +/* -------------------------------------------------------------------------- */ + +int main(int argc, char *argv[]){ + + initialize("material_notch.dat", argc, argv); + + // create mesh + Mesh mesh(spatial_dimension); + mesh.read("square_notch.msh"); + + CouplerSolidPhaseField coupler(mesh); + auto & model = coupler.getSolidMechanicsModel(); + auto & phase = coupler.getPhaseFieldModel(); + + model.initFull(_analysis_method = _static); + auto && mat_selector = std::make_shared>( + "physical_names", model); + model.setMaterialSelector(mat_selector); + + auto && selector = std::make_shared>( + "physical_names", phase); + phase.setPhaseFieldSelector(selector); + + phase.initFull(_analysis_method = _static); + + model.applyBC(BC::Dirichlet::FixedValue(0., _y), "bottom"); + model.applyBC(BC::Dirichlet::FixedValue(0., _x), "left"); + + model.setBaseName("phase_notch"); + model.addDumpField("stress"); + model.addDumpField("grad_u"); + model.addDumpFieldVector("displacement"); + model.addDumpField("damage"); + model.dump(); + + UInt nbSteps = 1500; + Real increment = 1e-5; + + auto start_time = clk::now(); + + + for (UInt s = 1; s < nbSteps; ++s) { + + if (s >= 500) { + increment = 1.e-6; + } + + if (s % 10 == 0 ) { + constexpr char wheel[] = "/-\\|"; + auto elapsed = clk::now() - start_time; + auto time_per_step = elapsed / s; + std::cout << "\r[" << wheel[(s / 10) % 4] << "] " << std::setw(5) << s + << "/" << nbSteps << " (" << std::setprecision(2) + << std::fixed << std::setw(8) + << millisecond(time_per_step).count() + << "ms/step - elapsed: " << std::setw(8) + << second(elapsed).count() << "s - ETA: " << std::setw(8) + << second((nbSteps - s) * time_per_step).count() << "s)" + << std::string(' ', 20) << std::flush; + } + model.applyBC(BC::Dirichlet::IncrementValue(increment, _y), "top"); + + coupler.solve(); + + if ( s % 100 == 0) { + model.dump(); + } + + } + + + finalize(); + return EXIT_SUCCESS; +} diff --git a/examples/phase_field/square_notch.geo b/examples/phase_field/square_notch.geo new file mode 100644 index 000000000..d9ab8b202 --- /dev/null +++ b/examples/phase_field/square_notch.geo @@ -0,0 +1,30 @@ +element_size = 0.050; + +Point(1) = {0.5, 0.5, 0, element_size}; +Point(2) = {-0.5, 0.5, 0, element_size}; +Point(3) = {-0.5, -0.5, 0, element_size}; +Point(4) = {0.5, -0.5, 0, element_size}; +Point(5) = {-0.5, 0.001, 0, element_size}; +Point(6) = {0., 0.0, 0, element_size}; +Point(7) = {0.5, 0.0, 0, element_size}; +Point(8) = {-0.5, -0.001, 0, element_size}; + +Line(1) = {3, 4}; +Line(2) = {4, 7}; +Line(3) = {7, 1}; +Line(4) = {1, 2}; +Line(5) = {2, 5}; +Line(6) = {5, 6}; +Line(7) = {6, 8}; +Line(8) = {8, 3}; + +Line Loop(1) = {1, 2, 3, 4, 5, 6, 7, 8}; + +Plane Surface(1) = {1}; + +Physical Surface("plate") = {1}; + +Physical Line("bottom") = {1}; +Physical Line("right") = {2, 3}; +Physical Line("top") = {4}; +Physical Line("left") = {5,8}; diff --git a/examples/python/phase-field/phasefield-dynamic.py b/examples/python/phase-field/phasefield-dynamic.py new file mode 100644 index 000000000..9b7b822d9 --- /dev/null +++ b/examples/python/phase-field/phasefield-dynamic.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# coding: utf-8 + +import py11_akantu as aka +import subprocess + +geometry_file = """ +h1 = 1e-4; +h2 = 1e-3; +L = 32e-3; +H = 16e-3; +l = 4e-3; +Point(1) = {0, 0, 0, h1}; +Point(2) = {L, 0, 0, h1}; +Point(3) = {L, H/2, 0, h2}; +Point(4) = {0, H/2, 0, h2}; +Point(5) = {l, 0, 0, h1}; + +Point(6) = {0, 0, 0, h1}; +Point(7) = {L, -H/2, 0, h2}; +Point(8) = {0, -H/2, 0, h2}; + + +Line(1) = {1, 5}; +Line(2) = {4, 1}; +Line(3) = {3, 4}; +Line(4) = {2, 3}; +Line(5) = {5, 2}; + +Line Loop(1) = {2, 3, 4, 5, 1}; +Plane Surface(1) = {1}; + +Line(6) = {5, 6}; +Line(7) = {6, 8}; +Line(8) = {8, 7}; +Line(9) = {7, 2}; +Line Loop(2) = {6, 7, 8, 9, -5}; +Plane Surface(2) = {2}; + + +Physical Surface(8) = {1,2}; +Physical Line("left") = {2,7}; +Physical Line("bottom") = {8}; +Physical Line("top") = {3}; +Physical Line("right") = {4,9}; + +""" + +with open('plate.geo', 'w') as f: + f.write(geometry_file) + +ret = subprocess.run("gmsh -2 -order 1 -o plate.msh plate.geo", shell=True) +if ret.returncode: + print("Beware, gmsh could not run: mesh is not regenerated") +else: + print("Mesh generated") + +material_file = """ +material phasefield [ + name = virtual + rho = 1180. # density + E = 3.09e9 # young's modulus + nu = 0.35 # poisson's ratio + eta = 0.0 + finite_deformation = false +] + +phasefield exponential [ + name = virtual + E = 3.09e9 + nu = 0.35 + gc = 300. + l0 = 0.1e-3 +] + +""" + +with open('material.dat', 'w') as f: + f.write(material_file) + + +# reading material file +aka.parseInput('material.dat') +# creating mesh +spatial_dimension = 2 +mesh = aka.Mesh(spatial_dimension) +mesh.read('plate.msh') + + +model = aka.CouplerSolidPhaseField(mesh) + +solid = model.getSolidMechanicsModel() +phase = model.getPhaseFieldModel() + +# initializing the Solid Mechanics Model with implicit solver for static resolution +solid.initFull(_analysis_method=aka._static) +solver = solid.getNonLinearSolver('static') +solver.set('max_iterations', 100) +solver.set('threshold', 1e-10) +solver.set("convergence_type", aka.SolveConvergenceCriteria.residual) + +# adding another solver dynamic/quasi-static resolution (explicit Newmark with lumped mass) +solid.initNewSolver(aka._explicit_lumped_mass) + +# initializing the PhaseField Model with linear implicit solver for static resolution +phase.initFull(_analysis_method=aka._static) + +# initializing the PhaseField Model with Newton Raphson implicit solver for static resolution +phase.getNewSolver("nonlinear_static", aka.TimeStepSolverType.static, + aka.NonLinearSolverType.newton_raphson) +phase.setIntegrationScheme("nonlinear_static", "damage", + aka.IntegrationSchemeType.pseudo_time) + +solver = phase.getNonLinearSolver('nonlinear_static') +solver.set('max_iterations', 100) +solver.set('threshold', 1e-3) +solver.set("convergence_type", aka.SolveConvergenceCriteria.solution) + + +# Initialization for bulk vizualisation +solid.setBaseName('plate') +solid.addDumpFieldVector('displacement') +solid.addDumpFieldVector('external_force') +solid.addDumpFieldVector('velocity') +solid.addDumpField('strain') +solid.addDumpField('stress') +solid.addDumpField('damage') +solid.addDumpField('blocked_dofs') + + +class FixedDamage (aka.DirichletFunctor): + ''' + Fix the damage to 0 + ''' + def __init__(self, axis): + super().__init__(axis) + self.axis = axis + + def __call__(self, node, flags, dam, coord): + # sets the blocked dofs vector to true in the desired axis + flags[int(self.axis)] = True + dam[int(self.axis)] = 0.0 + + +# Dirichlet +solid.applyBC(aka.FixedValue(0., aka._x), 'top') +solid.applyBC(aka.FixedValue(0., aka._x), 'bottom') + +solid.applyBC(aka.FixedValue(0., aka._x), 'left') +solid.applyBC(aka.FixedValue(0., aka._x), 'right') + + +solid.applyBC(aka.FixedValue(0.06e-3, aka._y), 'top') +solid.applyBC(aka.FixedValue(-0.06e-3, aka._y), 'bottom') + + +solid.solveStep('static') +solid.dump() + + +# #### **Damped dynamics resolution** +solid.setTimeStep(solid.getStableTimeStep()*0.8) + +# set maximum number of iteration +maxsteps = 1000 +# solve using staggered scheme +for i in range(0, maxsteps): + if i % 100 == 0: + print('step {0}/{1}'.format(i, maxsteps)) + model.solve('explicit_lumped', '') + if i % 100 == 0: + model.dump() diff --git a/examples/python/phase-field/phasefield-static.py b/examples/python/phase-field/phasefield-static.py new file mode 100644 index 000000000..524a55d87 --- /dev/null +++ b/examples/python/phase-field/phasefield-static.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python +# coding: utf-8 + +import numpy as np +import py11_akantu as aka + + +import subprocess + +geometry_file = """ +element_size = 0.1; +fine_element_size = element_size; + +Point(1) = {0.5, 0.5, 0, element_size}; +Point(2) = {-0.5, 0.5, 0, element_size}; +Point(3) = {-0.5, -0.5, 0, element_size}; +Point(4) = {0.5, -0.5, 0, element_size}; +Point(5) = {-0.5, 0.001, 0, element_size}; +Point(6) = {0., 0.0, 0, fine_element_size}; +Point(7) = {0.5, 0.0, 0, fine_element_size}; +Point(8) = {-0.5, -0.001, 0, element_size}; + +Line(1) = {3, 4}; +Line(2) = {4, 7}; +Line(3) = {7, 1}; +Line(4) = {1, 2}; +Line(5) = {2, 5}; +Line(6) = {5, 6}; +Line(7) = {6, 8}; +Line(8) = {8, 3}; + +Line Loop(1) = {1, 2, 3, 4, 5, 6, 7, 8}; + +Plane Surface(1) = {1}; + +Physical Surface("plate") = {1}; + +Physical Line("bottom") = {1}; +Physical Line("right") = {2, 3}; +Physical Line("top") = {4}; +Physical Line("left") = {5,8}; + +""" + +with open('plate.geo', 'w') as f: + f.write(geometry_file) + +ret = subprocess.run("gmsh -2 -order 1 -o plate.msh plate.geo", shell=True) +if ret.returncode: + print("Beware, gmsh could not run: mesh is not regenerated") +else: + print("Mesh generated") + +material_file = """ +material phasefield [ +name = plate + rho = 1. + E = 210.0 + nu = 0.3 + eta = 0.0 + Plane_Stress = false +] + +phasefield exponential [ + name = plate + l0 = 0.0075 + gc = 2.7e-3 + E = 210.0 + nu = 0.3 +] +""" + +with open('material.dat', 'w') as f: + f.write(material_file) + +aka.parseInput("material.dat") + +dim = 2 +mesh = aka.Mesh(dim) +mesh.read("plate.msh") + +model = aka.CouplerSolidPhaseField(mesh) + +solid = model.getSolidMechanicsModel() +phase = model.getPhaseFieldModel() + +solid.initFull(_analysis_method=aka._static) +solver = solid.getNonLinearSolver('static') +solver.set('max_iterations', 100) +solver.set('threshold', 1e-8) +solver.set("convergence_type", aka.SolveConvergenceCriteria.solution) + + +solid.getNewSolver("linear_static", aka.TimeStepSolverType.static, + aka.NonLinearSolverType.linear) +solid.setIntegrationScheme("linear_static", "displacement", + aka.IntegrationSchemeType.pseudo_time) + + +phase.initFull(_analysis_method=aka._static) +phase.getNewSolver("nonlinear_static", aka.TimeStepSolverType.static, + aka.NonLinearSolverType.newton_raphson) +phase.setIntegrationScheme("nonlinear_static", "damage", + aka.IntegrationSchemeType.pseudo_time) +solver = phase.getNonLinearSolver('nonlinear_static') +solver.set('max_iterations', 100) +solver.set('threshold', 1e-4) +solver.set("convergence_type", aka.SolveConvergenceCriteria.solution) + + +solid.applyBC(aka.FixedValue(0, aka._y), "bottom") +solid.applyBC(aka.FixedValue(0, aka._x), "left") + +# Initialization for bulk vizualisation +solid.setBaseName('phasefield-static') +solid.addDumpFieldVector('displacement') +solid.addDumpFieldVector('external_force') +solid.addDumpField('strain') +solid.addDumpField('stress') +solid.addDumpField('damage') +solid.addDumpField('blocked_dofs') + + +nb_dofs = solid.getMesh().getNbNodes() * dim + +increment = solid.getIncrement() +displacement = solid.getDisplacement() +displacement = displacement.reshape(nb_dofs) + +blocked_dofs = solid.getBlockedDOFs() +blocked_dofs = blocked_dofs.reshape(nb_dofs) + +damage = phase.getDamage() + +tolerance = 1e-8 + +steps = 1500 +increment = 1e-5 + +for n in range(steps): + print("Computing iteration " + str(n + 1) + "/" + str(steps)) + + solid.applyBC(aka.IncrementValue(increment, aka._y), 'top') + + mask = blocked_dofs == False + + iiter = 0 + error_disp = 1 + error_dam = 1 + + displacement_prev = displacement[mask].copy() + + damage_prev = damage.copy() + damage_prev = damage_prev + + # solve using staggered scheme + while (error_disp > tolerance or error_dam > tolerance): + model.solve("linear_static", "") + + displacement_new = displacement[mask] + damage_new = damage + + delta_disp = displacement_new - displacement_prev + delta_dam = damage_new - damage_prev + + error_disp = np.linalg.norm(delta_disp) + error_dam = np.linalg.norm(delta_dam) + + iiter += 1 + + displacement_prev = displacement_new.copy() + damage_prev = damage_new.copy() + + print(error_dam, error_disp) + if iiter > 500: + raise Exception('Convergence not reached') + + if n % 50 == 0: + solid.dump() + +solid.dump() diff --git a/packages/model_couplers.cmake b/packages/model_couplers.cmake new file mode 100644 index 000000000..47c375b8c --- /dev/null +++ b/packages/model_couplers.cmake @@ -0,0 +1,47 @@ +#=============================================================================== +# @file model_couplers.cmake +# +# @author Mohit Pundir +# +# @date creation: Sun Sep 30 2018 +# @date last modification: Sun Sep 28 2018 +# +# @brief package description for model couplers +# +# @section LICENSE +# +# Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de +# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des +# Solides) +# +# Akantu is free software: you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Akantu. If not, see . +# +#=============================================================================== + +package_declare(model_couplers ADVANCED + DESCRIPTION "Use Model Couplers package of Akantu") + +package_declare_sources(model_couplers + model/model_couplers/coupler_solid_phasefield.hh + model/model_couplers/coupler_solid_phasefield.cc + ) + +package_declare_documentation_files(model_couplers + # + ) + +package_declare_documentation(model_couplers + "This package activates the modle couplers within Akantu. " + "It has no additional dependencies." + ) diff --git a/packages/phase_field.cmake b/packages/phase_field.cmake new file mode 100644 index 000000000..01ab95a37 --- /dev/null +++ b/packages/phase_field.cmake @@ -0,0 +1,57 @@ +#=============================================================================== +# @file phase_field.cmake +# +# @author Mohit Pundir +# +# @date creation: Sun Sep 30 2018 +# @date last modification: Sun Sep 30 2018 +# +# @brief package description for phase field model +# +# @section LICENSE +# +# Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de +# Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des +# Solides) +# +# Akantu is free software: you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# Akantu is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Akantu. If not, see . +# +#=============================================================================== + +package_declare(phase_field + DEPENDS model_couplers + DESCRIPTION "Use Phase Field package of Akantu") + +package_declare_sources(phase_field + model/phase_field/phasefield.cc + model/phase_field/phasefield.hh + model/phase_field/phasefield_inline_impl.cc + model/phase_field/phasefield_selector.hh + model/phase_field/phasefield_selector_tmpl.hh + + model/phase_field/phasefields/phasefield_exponential.hh + model/phase_field/phasefields/phasefield_exponential.cc + + model/phase_field/phase_field_model.cc + model/phase_field/phase_field_model.hh + model/phase_field/phase_field_model_inline_impl.cc + ) + +package_declare_documentation_files(phase_field + # + ) + +package_declare_documentation(phase_field + "This package activates the phase field model within Akantu. " + ) diff --git a/packages/solid_mechanics.cmake b/packages/solid_mechanics.cmake index 0ea58434b..ae2d6ed5c 100644 --- a/packages/solid_mechanics.cmake +++ b/packages/solid_mechanics.cmake @@ -1,134 +1,137 @@ #=============================================================================== # @file solid_mechanics.cmake # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Mon Nov 21 2011 # @date last modification: Mon Jan 18 2016 # # @brief package description for core # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== package_declare(solid_mechanics DEFAULT ON DESCRIPTION "Solid mechanics model" DEPENDS core lapack ) package_declare_sources(solid_mechanics model/solid_mechanics/material.cc model/solid_mechanics/material.hh model/solid_mechanics/material_inline_impl.hh model/solid_mechanics/material_selector.hh model/solid_mechanics/material_selector_tmpl.hh model/solid_mechanics/materials/internal_field.hh model/solid_mechanics/materials/internal_field_tmpl.hh model/solid_mechanics/materials/random_internal_field.hh model/solid_mechanics/materials/random_internal_field_tmpl.hh model/solid_mechanics/solid_mechanics_model.cc model/solid_mechanics/solid_mechanics_model.hh model/solid_mechanics/solid_mechanics_model_inline_impl.hh model/solid_mechanics/solid_mechanics_model_io.cc model/solid_mechanics/solid_mechanics_model_mass.cc model/solid_mechanics/solid_mechanics_model_material.cc model/solid_mechanics/solid_mechanics_model_tmpl.hh model/solid_mechanics/solid_mechanics_model_event_handler.hh model/solid_mechanics/materials/plane_stress_toolbox.hh model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh model/solid_mechanics/materials/material_core_includes.hh model/solid_mechanics/materials/material_elastic.cc model/solid_mechanics/materials/material_elastic.hh model/solid_mechanics/materials/material_elastic_inline_impl.hh model/solid_mechanics/materials/material_thermal.cc model/solid_mechanics/materials/material_thermal.hh model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.hh model/solid_mechanics/materials/material_elastic_orthotropic.cc model/solid_mechanics/materials/material_elastic_orthotropic.hh model/solid_mechanics/materials/material_damage/material_anisotropic_damage.hh model/solid_mechanics/materials/material_damage/material_anisotropic_damage.cc model/solid_mechanics/materials/material_damage/material_anisotropic_damage_tmpl.hh model/solid_mechanics/materials/material_damage/material_damage.hh model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh model/solid_mechanics/materials/material_damage/material_marigo.cc model/solid_mechanics/materials/material_damage/material_marigo.hh model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.hh model/solid_mechanics/materials/material_damage/material_mazars.cc model/solid_mechanics/materials/material_damage/material_mazars.hh + model/solid_mechanics/materials/material_damage/material_phasefield.cc + model/solid_mechanics/materials/material_damage/material_phasefield.hh + model/solid_mechanics/materials/material_damage/material_phasefield_inline_impl.cc model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.hh model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.hh model/solid_mechanics/materials/material_plastic/material_plastic.cc model/solid_mechanics/materials/material_plastic/material_plastic.hh model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.hh model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.hh model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.cc model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.hh model/solid_mechanics/materials/material_non_local.hh model/solid_mechanics/materials/material_non_local_tmpl.hh model/solid_mechanics/materials/material_non_local_includes.hh ) package_declare_material_infos(solid_mechanics LIST AKANTU_CORE_MATERIAL_LIST INCLUDE material_core_includes.hh ) package_declare_documentation_files(solid_mechanics manual-solidmechanicsmodel.tex manual-constitutive-laws.tex manual-lumping.tex manual-appendix-materials.tex figures/dynamic_analysis.png figures/explicit_dynamic.pdf figures/explicit_dynamic.svg figures/static.pdf figures/static.svg figures/hooke_law.pdf figures/implicit_dynamic.pdf figures/implicit_dynamic.svg figures/problemDomain.pdf_tex figures/problemDomain.pdf figures/static_analysis.png figures/stress_strain_el.pdf figures/tangent.pdf figures/tangent.svg figures/stress_strain_neo.pdf figures/visco_elastic_law.pdf figures/isotropic_hardening_plasticity.pdf figures/stress_strain_visco.pdf ) package_declare_extra_files_to_package(solid_mechanics SOURCES model/solid_mechanics/material_list.hh.in ) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index f629f08f9..b734d35e0 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,124 +1,132 @@ #=============================================================================== # @file CMakeLists.txt # # @author Nicolas Richart # # @date creation: Fri Dec 12 2014 # @date last modification: Mon Jan 18 2016 # # @brief CMake file for the python wrapping of akantu # # @section LICENSE # # Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory # (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== if(NOT SKBUILD) package_get_all_include_directories( AKANTU_LIBRARY_INCLUDE_DIRS ) package_get_all_external_informations( PRIVATE_INCLUDE AKANTU_PRIVATE_EXTERNAL_INCLUDE_DIR INTERFACE_INCLUDE AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR LIBRARIES AKANTU_EXTERNAL_LIBRARIES ) endif() set(PYAKANTU_SRCS py_aka_common.cc py_aka_error.cc py_akantu.cc py_boundary_conditions.cc py_fe_engine.cc py_group_manager.cc py_mesh.cc py_model.cc py_parser.cc py_solver.cc ) package_is_activated(iohelper _is_activated) if (_is_activated) list(APPEND PYAKANTU_SRCS py_dumpable.cc ) endif() package_is_activated(solid_mechanics _is_activated) if (_is_activated) list(APPEND PYAKANTU_SRCS py_solid_mechanics_model.cc py_material.cc ) endif() package_is_activated(cohesive_element _is_activated) if (_is_activated) list(APPEND PYAKANTU_SRCS py_solid_mechanics_model_cohesive.cc py_fragment_manager.cc ) endif() package_is_activated(heat_transfer _is_activated) if (_is_activated) list(APPEND PYAKANTU_SRCS py_heat_transfer_model.cc ) endif() +package_is_activated(phase_field _is_activated) +if (_is_activated) + list(APPEND PYAKANTU_SRCS + py_phase_field_model.cc + ) +endif() + + package_is_activated(structural_mechanics _is_activated) if (_is_activated) list(APPEND PYAKANTU_SRCS py_structural_mechanics_model.cc ) endif() pybind11_add_module(py11_akantu ${PYAKANTU_SRCS}) # to avoid compilation warnings from pybind11 target_include_directories(py11_akantu SYSTEM BEFORE PRIVATE ${PYBIND11_INCLUDE_DIR} PRIVATE ${pybind11_INCLUDE_DIR} PRIVATE ${PYTHON_INCLUDE_DIRS}) target_link_libraries(py11_akantu PUBLIC akantu) set_target_properties(py11_akantu PROPERTIES DEBUG_POSTFIX "" LIBRARY_OUTPUT_DIRECTORY akantu) file(COPY akantu DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) if(NOT SKBUILD) set(_python_install_dir ${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages) else() set(_python_install_dir .) endif() install(TARGETS py11_akantu LIBRARY DESTINATION ${_python_install_dir}) if(NOT SKBUILD) install(DIRECTORY akantu DESTINATION ${_python_install_dir} FILES_MATCHING PATTERN "*.py") endif() diff --git a/python/py_aka_common.cc b/python/py_aka_common.cc index 7a5ef2c77..07fbcc881 100644 --- a/python/py_aka_common.cc +++ b/python/py_aka_common.cc @@ -1,111 +1,112 @@ /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ namespace py = pybind11; namespace akantu { /* -------------------------------------------------------------------------- */ #define PY_AKANTU_PP_VALUE(s, data, elem) \ .value(BOOST_PP_STRINGIZE(elem), BOOST_PP_CAT(data, elem)) #define PY_AKANTU_REGISTER_ENUM_(type_name, list, prefix, mod) \ py::enum_(mod, BOOST_PP_STRINGIZE(type_name)) \ BOOST_PP_SEQ_FOR_EACH(PY_AKANTU_PP_VALUE, prefix, list) \ .export_values() #define PY_AKANTU_REGISTER_CLASS_ENUM(type_name, list, mod) \ PY_AKANTU_REGISTER_ENUM_(type_name, list, type_name::_, mod) #define PY_AKANTU_REGISTER_ENUM(type_name, list, mod) \ PY_AKANTU_REGISTER_ENUM_(type_name, list, , mod) /* -------------------------------------------------------------------------- */ void register_initialize(py::module & mod) { mod.def("__initialize", []() { int nb_args = 0; char ** null = nullptr; initialize(nb_args, null); }); } void register_enums(py::module & mod) { py::enum_(mod, "SpatialDirection") .value("_x", _x) .value("_y", _y) .value("_z", _z) .export_values(); py::enum_(mod, "AnalysisMethod") .value("_static", _static) .value("_implicit_dynamic", _implicit_dynamic) .value("_explicit_lumped_mass", _explicit_lumped_mass) .value("_explicit_lumped_capacity", _explicit_lumped_capacity) .value("_explicit_consistent_mass", _explicit_consistent_mass) .export_values(); + PY_AKANTU_REGISTER_CLASS_ENUM(ModelType, AKANTU_MODEL_TYPES, mod); PY_AKANTU_REGISTER_CLASS_ENUM(NonLinearSolverType, AKANTU_NON_LINEAR_SOLVER_TYPES, mod); PY_AKANTU_REGISTER_CLASS_ENUM(TimeStepSolverType, AKANTU_TIME_STEP_SOLVER_TYPE, mod); PY_AKANTU_REGISTER_CLASS_ENUM(IntegrationSchemeType, AKANTU_INTEGRATION_SCHEME_TYPE, mod); PY_AKANTU_REGISTER_CLASS_ENUM(SolveConvergenceCriteria, AKANTU_SOLVE_CONVERGENCE_CRITERIA, mod); py::enum_(mod, "CohesiveMethod") .value("_intrinsic", _intrinsic) .value("_extrinsic", _extrinsic) .export_values(); py::enum_(mod, "GhostType") .value("_not_ghost", _not_ghost) .value("_ghost", _ghost) .value("_casper", _casper) .export_values(); py::enum_(mod, "MeshIOType") .value("_miot_auto", _miot_auto) .value("_miot_gmsh", _miot_gmsh) .value("_miot_gmsh_struct", _miot_gmsh_struct) .value("_miot_diana", _miot_diana) .value("_miot_abaqus", _miot_abaqus) .export_values(); py::enum_(mod, "MatrixType") .value("_unsymmetric", _unsymmetric) .value("_symmetric", _symmetric) .export_values(); PY_AKANTU_REGISTER_ENUM(ElementType, AKANTU_ALL_ELEMENT_TYPE(_not_defined), mod); PY_AKANTU_REGISTER_ENUM(ElementKind, AKANTU_ELEMENT_KIND(_ek_not_defined), mod); } /* -------------------------------------------------------------------------- */ #define AKANTU_PP_STR_TO_TYPE2(s, data, elem) ({BOOST_PP_STRINGIZE(elem), elem}) void register_functions(py::module & mod) { mod.def("getElementTypes", []() { std::map element_types{ BOOST_PP_SEQ_FOR_EACH_I( AKANTU_PP_ENUM, BOOST_PP_SEQ_SIZE(AKANTU_ek_regular_ELEMENT_TYPE), BOOST_PP_SEQ_TRANSFORM(AKANTU_PP_STR_TO_TYPE2, akantu, AKANTU_ek_regular_ELEMENT_TYPE))}; return element_types; }); } #undef AKANTU_PP_STR_TO_TYPE2 } // namespace akantu diff --git a/python/py_akantu.cc b/python/py_akantu.cc index 8c27c27d0..cf425a9d9 100644 --- a/python/py_akantu.cc +++ b/python/py_akantu.cc @@ -1,115 +1,125 @@ /* -------------------------------------------------------------------------- */ #include "aka_config.hh" /* -------------------------------------------------------------------------- */ #include "py_aka_common.hh" #include "py_aka_error.hh" #include "py_boundary_conditions.hh" #include "py_fe_engine.hh" #include "py_group_manager.hh" #include "py_mesh.hh" #include "py_model.hh" #include "py_parser.hh" #include "py_solver.hh" #if defined(AKANTU_USE_IOHELPER) #include "py_dumpable.hh" #endif #if defined(AKANTU_SOLID_MECHANICS) #include "py_material.hh" #include "py_solid_mechanics_model.hh" #endif #if defined(AKANTU_HEAT_TRANSFER) #include "py_heat_transfer_model.hh" #endif #if defined(AKANTU_COHESIVE_ELEMENT) #include "py_fragment_manager.hh" #include "py_solid_mechanics_model_cohesive.hh" #endif +#if defined(AKANTU_PHASE_FIELD) +#include "py_phase_field_model.hh" +#endif + #if defined(AKANTU_STRUCTURAL_MECHANICS) #include "py_structural_mechanics_model.hh" #endif + /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ namespace py = pybind11; namespace akantu { void register_all(pybind11::module & mod) { register_initialize(mod); register_enums(mod); register_error(mod); register_functions(mod); register_parser(mod); register_solvers(mod); register_group_manager(mod); #if defined(AKANTU_USE_IOHELPER) register_dumpable(mod); #endif register_mesh(mod); register_fe_engine(mod); register_boundary_conditions(mod); register_model(mod); #if defined(AKANTU_HEAT_TRANSFER) register_heat_transfer_model(mod); #endif #if defined(AKANTU_SOLID_MECHANICS) register_solid_mechanics_model(mod); register_material(mod); #endif #if defined(AKANTU_COHESIVE_ELEMENT) register_solid_mechanics_model_cohesive(mod); register_fragment_manager(mod); #endif #if defined(AKANTU_STRUCTURAL_MECHANICS) register_structural_mechanics_model(mod); #endif + +#if defined(AKANTU_PHASE_FIELD) + register_phase_field_model(mod); + register_phase_field_coupler(mod); +#endif } } // namespace akantu /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ PYBIND11_MODULE(py11_akantu, mod) { mod.doc() = "Akantu python interface"; static py::exception akantu_exception(mod, "Exception"); py::register_exception_translator([](std::exception_ptr ptr) { try { if (ptr) { std::rethrow_exception(ptr); } } catch (akantu::debug::Exception & e) { if (akantu::debug::debugger.printBacktrace()) { akantu::debug::printBacktrace(); } akantu_exception(e.info().c_str()); } }); akantu::register_all(mod); mod.def("has_mpi", []() { #if defined(AKANTU_USE_MPI) return true; #else return false; #endif }); } // Module akantu diff --git a/python/py_model.cc b/python/py_model.cc index f688183b9..1373cf9dc 100644 --- a/python/py_model.cc +++ b/python/py_model.cc @@ -1,93 +1,102 @@ /* -------------------------------------------------------------------------- */ #include "py_aka_array.hh" /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ namespace py = pybind11; /* -------------------------------------------------------------------------- */ namespace akantu { /* -------------------------------------------------------------------------- */ void register_model(py::module & mod) { py::class_(mod, "DOFManager") .def("getMatrix", &DOFManager::getMatrix, py::return_value_policy::reference) .def( "getNewMatrix", [](DOFManager & self, const std::string & name, const std::string & matrix_to_copy_id) -> decltype(auto) { return self.getNewMatrix(name, matrix_to_copy_id); }, py::return_value_policy::reference) .def( "getResidual", [](DOFManager & self) -> decltype(auto) { return self.getResidual(); }, py::return_value_policy::reference) .def("getArrayPerDOFs", &DOFManager::getArrayPerDOFs) .def( "hasMatrix", [](DOFManager & self, const ID & name) -> bool { return self.hasMatrix(name); }, py::arg("name")) .def("assembleToResidual", &DOFManager::assembleToResidual); py::class_(mod, "NonLinearSolver") .def( "set", [](NonLinearSolver & self, const std::string & id, const Real & val) { if (id == "max_iterations") { self.set(id, int(val)); } else { self.set(id, val); } }) .def("set", [](NonLinearSolver & self, const std::string & id, const SolveConvergenceCriteria & val) { self.set(id, val); }); py::class_(mod, "ModelSolver", py::multiple_inheritance()) .def("getNonLinearSolver", (NonLinearSolver & (ModelSolver::*)(const ID &)) & ModelSolver::getNonLinearSolver, py::arg("solver_id") = "", py::return_value_policy::reference) .def("solveStep", [](ModelSolver & self) { self.solveStep(); }) .def("solveStep", [](ModelSolver & self, const ID & solver_id) { self.solveStep(solver_id); }); py::class_(mod, "Model", py::multiple_inheritance()) .def("setBaseName", &Model::setBaseName) + .def("setDirectory", &Model::setDirectory) .def("getFEEngine", &Model::getFEEngine, py::arg("name") = "", py::return_value_policy::reference) .def("getFEEngineBoundary", &Model::getFEEngine, py::arg("name") = "", py::return_value_policy::reference) .def("addDumpFieldVector", &Model::addDumpFieldVector) .def("addDumpField", &Model::addDumpField) .def("setBaseNameToDumper", &Model::setBaseNameToDumper) .def("addDumpFieldVectorToDumper", &Model::addDumpFieldVectorToDumper) .def("addDumpFieldToDumper", &Model::addDumpFieldToDumper) .def("dump", py::overload_cast<>(&Model::dump)) .def("dump", py::overload_cast(&Model::dump)) .def("dump", py::overload_cast(&Model::dump)) .def("dump", py::overload_cast(&Model::dump)) .def("dump", py::overload_cast(&Model::dump)) .def("dump", py::overload_cast(&Model::dump)) .def("initNewSolver", &Model::initNewSolver) + .def("getNewSolver", [](Model & self, const std::string id, const TimeStepSolverType & time, + const NonLinearSolverType & type) { + self.getNewSolver(id, time, type); + }, py::return_value_policy::reference) + .def("setIntegrationScheme", [](Model & self, const std::string id, const std::string primal, + const IntegrationSchemeType & scheme) { + self.setIntegrationScheme(id, primal, scheme); + }) .def("getDOFManager", &Model::getDOFManager, py::return_value_policy::reference) .def("assembleMatrix", &Model::assembleMatrix); } } // namespace akantu diff --git a/python/py_parser.cc b/python/py_parser.cc index bb0720ec0..2c8fc9dbf 100644 --- a/python/py_parser.cc +++ b/python/py_parser.cc @@ -1,69 +1,70 @@ /* -------------------------------------------------------------------------- */ #include "py_aka_array.hh" /* -------------------------------------------------------------------------- */ #include #include #include #include /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ namespace py = pybind11; /* -------------------------------------------------------------------------- */ namespace akantu { std::map> map_params; void register_parser(py::module & mod) { py::enum_(mod, "ParameterAccessType", py::arithmetic()) .value("_pat_internal", _pat_internal) .value("_pat_writable", _pat_writable) .value("_pat_readable", _pat_readable) .value("_pat_modifiable", _pat_modifiable) .value("_pat_parsable", _pat_parsable) .value("_pat_parsmod", _pat_parsmod) .export_values(); py::class_(mod, "ParameterRegistry", py::multiple_inheritance()) .def("registerParamReal", [](ParameterRegistry & self, const std::string & name, UInt type, const std::string & description) { Real * p = new Real; map_params[&self][name] = p; self.registerParam(name, *p, ParameterAccessType(type), description); }) .def("registerParamReal", [](ParameterRegistry & self, const Real & _default, const std::string & name, UInt type, const std::string & description) { Real * p = new Real; map_params[&self][name] = p; self.registerParam(name, *p, _default, ParameterAccessType(type), description); }) .def("getReal", [](ParameterRegistry & self, const std::string & name) { return Real(self.get(name)); }) .def("getMatrix", [](ParameterRegistry & self, const std::string & name) { const Matrix & res = static_cast &>(self.get(name)); return res; }, py::return_value_policy::copy); py::class_(mod, "Parsable", py::multiple_inheritance()) .def(py::init()); mod.def("parseInput", [](const std::string & input_file) { getStaticParser().parse(input_file); }, "Parse an Akantu input file"); + } } // namespace akantu diff --git a/python/py_phase_field_model.cc b/python/py_phase_field_model.cc new file mode 100644 index 000000000..77a3da1e7 --- /dev/null +++ b/python/py_phase_field_model.cc @@ -0,0 +1,123 @@ +/* -------------------------------------------------------------------------- */ +#include "py_aka_array.hh" +/* -------------------------------------------------------------------------- */ +#include +#include +#include +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ +namespace py = pybind11; +/* -------------------------------------------------------------------------- */ + +namespace akantu { + +/* -------------------------------------------------------------------------- */ +#define def_deprecated(func_name, mesg) \ + def(func_name, [](py::args, py::kwargs) { AKANTU_ERROR(mesg); }) + +#define def_function_nocopy(func_name) \ + def(#func_name, \ + [](PhaseFieldModel & self) -> decltype(auto) { \ + return self.func_name(); \ + }, \ + py::return_value_policy::reference) + +#define def_function(func_name) \ + def(#func_name, [](PhaseFieldModel & self) -> decltype(auto) { \ + return self.func_name(); \ + }) +/* -------------------------------------------------------------------------- */ + + +[[gnu::visibility("default")]] void +register_phase_field_model(py::module & mod) { + + py::class_(mod, "PhaseFieldModelOptions") + .def(py::init(), + py::arg("analysis_method") = _static); + + + py::class_(mod, "PhaseFieldModel", + py::multiple_inheritance()) + .def(py::init(), + py::arg("mesh"), py::arg("spatial_dimension") = _all_dimensions, + py::arg("id") = "phase_field_model", + py::arg("model_type") = ModelType::_phase_field_model) + .def("initFull", + [](PhaseFieldModel & self, + const PhaseFieldModelOptions & options) { + self.initFull(options); + }, + py::arg("_analysis_method") = PhaseFieldModelOptions()) + .def("initFull", + [](PhaseFieldModel & self, + const AnalysisMethod & analysis_method) { + self.initFull(_analysis_method = analysis_method); + }, + py::arg("_analysis_method")) + .def_deprecated("applyDirichletBC", "Deprecated: use applyBC") + .def("applyBC", + [](PhaseFieldModel & self, + BC::Dirichlet::DirichletFunctor & func, + const std::string & element_group) { + self.applyBC(func, element_group); + }) + .def("applyBC", + [](PhaseFieldModel & self, BC::Neumann::NeumannFunctor & func, + const std::string & element_group) { + self.applyBC(func, element_group); + }) + .def("setTimeStep", &PhaseFieldModel::setTimeStep, + py::arg("time_step"), py::arg("solver_id") = "") + .def_function(assembleStiffnessMatrix) + .def_function(assembleInternalForces) + .def_function_nocopy(getDamage) + .def_function_nocopy(getInternalForce) + .def_function_nocopy(getBlockedDOFs) + .def_function_nocopy(getMesh) + .def("dump", py::overload_cast<>(&PhaseFieldModel::dump)) + .def("dump", + py::overload_cast(&PhaseFieldModel::dump)) + .def("dump", py::overload_cast( + &PhaseFieldModel::dump)) + .def("dump", py::overload_cast( + &PhaseFieldModel::dump)) + .def("getPhaseField", + py::overload_cast(&PhaseFieldModel::getPhaseField), + py::return_value_policy::reference) + .def("getPhaseField", + py::overload_cast( + &PhaseFieldModel::getPhaseField), + py::return_value_policy::reference) + .def("getPhaseFieldIndex", &PhaseFieldModel::getPhaseFieldIndex) + .def("setPhaseFieldSelector", &PhaseFieldModel::setPhaseFieldSelector); + +} + + +[[gnu::visibility("default")]] void +register_phase_field_coupler(py::module & mod) { + + py::class_(mod, "CouplerSolidPhaseField") + .def(py::init(), + py::arg("mesh"), py::arg("spatial_dimension") = _all_dimensions, + py::arg("id") = "coupler_solid_phasefield", + py::arg("model_type") = ModelType::_coupler_solid_phasefield) + .def("solve", [](CouplerSolidPhaseField & self, const ID & solid_solver_id, + const ID & phase_solver_id) { + self.solve(solid_solver_id, phase_solver_id); + }) + .def("getSolidMechanicsModel", + &CouplerSolidPhaseField::getSolidMechanicsModel, + py::return_value_policy::reference) + .def("getPhaseFieldModel", + &CouplerSolidPhaseField::getPhaseFieldModel, + py::return_value_policy::reference); + +} + + + +} diff --git a/python/py_phase_field_model.hh b/python/py_phase_field_model.hh new file mode 100644 index 000000000..541f2a10a --- /dev/null +++ b/python/py_phase_field_model.hh @@ -0,0 +1,11 @@ +#include + +#ifndef __AKANTU_PY_PHASE_FIELD_MODEL_HH__ +#define __AKANTU_PY_PHASE_FIELD_MODEL_HH__ + +namespace akantu { + void register_phase_field_model(pybind11::module & mod); + void register_phase_field_coupler(pybind11::module & mod); +} // namespace akantu + +#endif // __AKANTU_PY_PHASE_FIELD_MODEL_HH__ diff --git a/src/common/aka_array_tmpl.hh b/src/common/aka_array_tmpl.hh index 50788d2ae..cd716dab0 100644 --- a/src/common/aka_array_tmpl.hh +++ b/src/common/aka_array_tmpl.hh @@ -1,1361 +1,1361 @@ /** * @file aka_array_tmpl.hh * * @author Guillaume Anciaux * @author Nicolas Richart * * @date creation: Thu Jul 15 2010 * @date last modification: Tue Feb 20 2018 * * @brief Inline functions of the classes Array and ArrayBase * * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ /* Inline Functions Array */ /* -------------------------------------------------------------------------- */ #include "aka_array.hh" // NOLINT /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #ifndef AKANTU_AKA_ARRAY_TMPL_HH_ #define AKANTU_AKA_ARRAY_TMPL_HH_ namespace akantu { namespace debug { struct ArrayException : public Exception {}; } // namespace debug /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ template ArrayDataLayer::ArrayDataLayer(UInt size, UInt nb_component, const ID & id) : ArrayBase(id) { allocate(size, nb_component); } /* -------------------------------------------------------------------------- */ template ArrayDataLayer::ArrayDataLayer(UInt size, UInt nb_component, const_reference value, const ID & id) : ArrayBase(id) { allocate(size, nb_component, value); } /* -------------------------------------------------------------------------- */ template ArrayDataLayer::ArrayDataLayer(const ArrayDataLayer & vect, const ID & id) : ArrayBase(vect, id) { this->data_storage = vect.data_storage; this->size_ = vect.size_; this->nb_component = vect.nb_component; this->values = this->data_storage.data(); } /* -------------------------------------------------------------------------- */ template ArrayDataLayer::ArrayDataLayer( const std::vector & vect) { this->data_storage = vect; this->size_ = vect.size(); this->nb_component = 1; this->values = this->data_storage.data(); } /* -------------------------------------------------------------------------- */ template ArrayDataLayer & ArrayDataLayer::operator=(const ArrayDataLayer & other) { if (this != &other) { this->data_storage = other.data_storage; this->nb_component = other.nb_component; this->size_ = other.size_; this->values = this->data_storage.data(); } return *this; } /* -------------------------------------------------------------------------- */ template void ArrayDataLayer::allocate(UInt new_size, UInt nb_component) { this->nb_component = nb_component; this->resize(new_size); } /* -------------------------------------------------------------------------- */ template void ArrayDataLayer::allocate(UInt new_size, UInt nb_component, const T & val) { this->nb_component = nb_component; this->resize(new_size, val); } /* -------------------------------------------------------------------------- */ template void ArrayDataLayer::resize(UInt new_size) { this->data_storage.resize(new_size * this->nb_component); this->values = this->data_storage.data(); this->size_ = new_size; } /* -------------------------------------------------------------------------- */ template void ArrayDataLayer::resize(UInt new_size, const T & value) { this->data_storage.resize(new_size * this->nb_component, value); this->values = this->data_storage.data(); this->size_ = new_size; } /* -------------------------------------------------------------------------- */ template void ArrayDataLayer::reserve(UInt size, UInt new_size) { if (new_size != UInt(-1)) { this->data_storage.resize(new_size * this->nb_component); } this->data_storage.reserve(size * this->nb_component); this->values = this->data_storage.data(); } /* -------------------------------------------------------------------------- */ /** * append a tuple to the array with the value value for all components * @param value the new last tuple or the array will contain nb_component copies * of value */ template inline void ArrayDataLayer::push_back(const T & value) { this->data_storage.push_back(value); this->values = this->data_storage.data(); this->size_ += 1; } /* -------------------------------------------------------------------------- */ /** * append a matrix or a vector to the array * @param new_elem a reference to a Matrix or Vector */ template template