diff --git a/packages/core.cmake b/packages/core.cmake index 786549ef9..d57a5ef5a 100644 --- a/packages/core.cmake +++ b/packages/core.cmake @@ -1,596 +1,593 @@ #=============================================================================== # @file core.cmake # # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch> # @author Nicolas Richart <nicolas.richart@epfl.ch> # # @date creation: Mon Nov 21 2011 # @date last modification: 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 <http://www.gnu.org/licenses/>. # #=============================================================================== package_declare(core NOT_OPTIONAL DESCRIPTION "core package for Akantu" FEATURES_PUBLIC cxx_strong_enums cxx_defaulted_functions cxx_deleted_functions cxx_auto_type cxx_decltype_auto FEATURES_PRIVATE cxx_lambdas cxx_nullptr cxx_delegated_constructors cxx_range_for ) package_declare_sources(core common/aka_array.cc common/aka_array.hh common/aka_array_tmpl.hh common/aka_blas_lapack.hh common/aka_circular_array.hh common/aka_circular_array_inline_impl.cc common/aka_common.cc common/aka_common.hh common/aka_common_inline_impl.cc common/aka_csr.hh common/aka_element_classes_info_inline_impl.cc common/aka_error.cc common/aka_error.hh common/aka_event_handler_manager.hh common/aka_extern.cc common/aka_factory.hh common/aka_fwd.hh common/aka_grid_dynamic.hh common/aka_math.cc common/aka_math.hh common/aka_math_tmpl.hh common/aka_memory.cc common/aka_memory.hh common/aka_memory_inline_impl.cc common/aka_named_argument.hh common/aka_random_generator.hh common/aka_safe_enum.hh common/aka_static_memory.cc common/aka_static_memory.hh common/aka_static_memory_inline_impl.cc common/aka_static_memory_tmpl.hh common/aka_typelist.hh common/aka_types.hh common/aka_visitor.hh common/aka_voigthelper.hh common/aka_voigthelper_tmpl.hh common/aka_voigthelper.cc common/aka_warning.hh common/aka_warning_restore.hh common/aka_iterators.hh common/aka_static_if.hh fe_engine/element_class.cc fe_engine/element_class.hh fe_engine/element_class_tmpl.hh fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc fe_engine/element_classes/element_class_point_1_inline_impl.cc fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc fe_engine/element_classes/element_class_segment_2_inline_impl.cc fe_engine/element_classes/element_class_segment_3_inline_impl.cc fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc fe_engine/element_classes/element_class_triangle_3_inline_impl.cc fe_engine/element_classes/element_class_triangle_6_inline_impl.cc fe_engine/element_type_conversion.hh fe_engine/fe_engine.cc fe_engine/fe_engine.hh fe_engine/fe_engine_inline_impl.cc fe_engine/fe_engine_template.hh fe_engine/fe_engine_template_tmpl_field.hh fe_engine/fe_engine_template_tmpl.hh fe_engine/geometrical_element.cc fe_engine/gauss_integration.cc fe_engine/gauss_integration_tmpl.hh fe_engine/integrator.hh fe_engine/integrator_gauss.hh fe_engine/integrator_gauss_inline_impl.cc fe_engine/interpolation_element.cc fe_engine/interpolation_element_tmpl.hh fe_engine/integration_point.hh fe_engine/shape_functions.hh fe_engine/shape_functions.cc fe_engine/shape_functions_inline_impl.cc fe_engine/shape_lagrange_base.cc fe_engine/shape_lagrange_base.hh fe_engine/shape_lagrange_base_inline_impl.cc fe_engine/shape_lagrange.cc fe_engine/shape_lagrange.hh fe_engine/shape_lagrange_inline_impl.cc - fe_engine/shape_linked.cc - fe_engine/shape_linked.hh - fe_engine/shape_linked_inline_impl.cc fe_engine/element.hh io/dumper/dumpable.hh io/dumper/dumpable.cc io/dumper/dumpable_dummy.hh io/dumper/dumpable_inline_impl.hh io/dumper/dumper_field.hh io/dumper/dumper_material_padders.hh io/dumper/dumper_filtered_connectivity.hh io/dumper/dumper_element_partition.hh io/mesh_io.cc io/mesh_io.hh io/mesh_io/mesh_io_abaqus.cc io/mesh_io/mesh_io_abaqus.hh io/mesh_io/mesh_io_diana.cc io/mesh_io/mesh_io_diana.hh io/mesh_io/mesh_io_msh.cc io/mesh_io/mesh_io_msh.hh - io/model_io.cc - io/model_io.hh + #io/model_io.cc + #io/model_io.hh io/parser/algebraic_parser.hh io/parser/input_file_parser.hh io/parser/parsable.cc io/parser/parsable.hh io/parser/parsable_tmpl.hh io/parser/parser.cc io/parser/parser_real.cc io/parser/parser_random.cc io/parser/parser_types.cc io/parser/parser_input_files.cc io/parser/parser.hh io/parser/parser_tmpl.hh io/parser/parser_grammar_tmpl.hh io/parser/cppargparse/cppargparse.hh io/parser/cppargparse/cppargparse.cc io/parser/cppargparse/cppargparse_tmpl.hh io/parser/parameter_registry.cc io/parser/parameter_registry.hh io/parser/parameter_registry_tmpl.hh mesh/element_group.cc mesh/element_group.hh mesh/element_group_inline_impl.cc mesh/element_type_map.cc mesh/element_type_map.hh mesh/element_type_map_tmpl.hh mesh/element_type_map_filter.hh mesh/group_manager.cc mesh/group_manager.hh mesh/group_manager_inline_impl.cc mesh/mesh.cc mesh/mesh.hh mesh/mesh_accessor.hh mesh/mesh_accessor.cc mesh/mesh_events.hh mesh/mesh_filter.hh mesh/mesh_data.cc mesh/mesh_data.hh mesh/mesh_data_tmpl.hh mesh/mesh_inline_impl.cc mesh/node_group.cc mesh/node_group.hh mesh/node_group_inline_impl.cc mesh/mesh_iterators.hh mesh_utils/mesh_partition.cc mesh_utils/mesh_partition.hh mesh_utils/mesh_partition/mesh_partition_mesh_data.cc mesh_utils/mesh_partition/mesh_partition_mesh_data.hh mesh_utils/mesh_partition/mesh_partition_scotch.hh mesh_utils/mesh_utils_pbc.cc mesh_utils/mesh_utils.cc mesh_utils/mesh_utils.hh mesh_utils/mesh_utils_distribution.cc mesh_utils/mesh_utils_distribution.hh mesh_utils/mesh_utils.hh mesh_utils/mesh_utils_inline_impl.cc mesh_utils/global_ids_updater.hh mesh_utils/global_ids_updater.cc mesh_utils/global_ids_updater_inline_impl.cc model/boundary_condition.hh model/boundary_condition_functor.hh model/boundary_condition_functor_inline_impl.cc model/boundary_condition_tmpl.hh model/common/neighborhood_base.hh model/common/neighborhood_base.cc model/common/neighborhood_base_inline_impl.cc model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc model/common/non_local_toolbox/non_local_manager.hh model/common/non_local_toolbox/non_local_manager.cc model/common/non_local_toolbox/non_local_manager_inline_impl.cc model/common/non_local_toolbox/non_local_manager_callback.hh model/common/non_local_toolbox/non_local_neighborhood_base.hh model/common/non_local_toolbox/non_local_neighborhood_base.cc model/common/non_local_toolbox/non_local_neighborhood.hh model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc model/common/non_local_toolbox/base_weight_function.hh model/common/non_local_toolbox/base_weight_function_inline_impl.cc model/dof_manager.cc model/dof_manager.hh model/dof_manager_default.cc model/dof_manager_default.hh model/dof_manager_default_inline_impl.cc model/dof_manager_inline_impl.cc model/model_solver.cc model/model_solver.hh model/model_solver_tmpl.hh model/non_linear_solver.cc model/non_linear_solver.hh model/non_linear_solver_default.hh model/non_linear_solver_lumped.cc model/non_linear_solver_lumped.hh model/solver_callback.hh model/solver_callback.cc model/time_step_solver.hh model/time_step_solvers/time_step_solver.cc model/time_step_solvers/time_step_solver_default.cc model/time_step_solvers/time_step_solver_default.hh model/time_step_solvers/time_step_solver_default_explicit.hh model/non_linear_solver_callback.hh model/time_step_solvers/time_step_solver_default_solver_callback.hh model/integration_scheme/generalized_trapezoidal.cc model/integration_scheme/generalized_trapezoidal.hh model/integration_scheme/integration_scheme.cc model/integration_scheme/integration_scheme.hh model/integration_scheme/integration_scheme_1st_order.cc model/integration_scheme/integration_scheme_1st_order.hh model/integration_scheme/integration_scheme_2nd_order.cc model/integration_scheme/integration_scheme_2nd_order.hh model/integration_scheme/newmark-beta.cc model/integration_scheme/newmark-beta.hh model/integration_scheme/pseudo_time.cc model/integration_scheme/pseudo_time.hh model/model.cc model/model.hh model/model_inline_impl.cc model/solid_mechanics/material.cc model/solid_mechanics/material.hh model/solid_mechanics/material_inline_impl.cc model/solid_mechanics/material_selector.hh model/solid_mechanics/material_selector_tmpl.hh model/solid_mechanics/materials/internal_field.hh model/solid_mechanics/materials/internal_field_tmpl.hh model/solid_mechanics/materials/random_internal_field.hh model/solid_mechanics/materials/random_internal_field_tmpl.hh model/solid_mechanics/solid_mechanics_model.cc model/solid_mechanics/solid_mechanics_model.hh model/solid_mechanics/solid_mechanics_model_inline_impl.cc model/solid_mechanics/solid_mechanics_model_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.cc model/solid_mechanics/materials/material_thermal.cc model/solid_mechanics/materials/material_thermal.hh model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh model/solid_mechanics/materials/material_elastic_orthotropic.cc model/solid_mechanics/materials/material_elastic_orthotropic.hh model/solid_mechanics/materials/material_damage/material_damage.hh model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh model/solid_mechanics/materials/material_damage/material_marigo.cc model/solid_mechanics/materials/material_damage/material_marigo.hh model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc model/solid_mechanics/materials/material_damage/material_mazars.cc model/solid_mechanics/materials/material_damage/material_mazars.hh model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc model/solid_mechanics/materials/material_plastic/material_plastic.cc model/solid_mechanics/materials/material_plastic/material_plastic.hh model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh model/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 model/solid_mechanics/materials/material_non_local_inline_impl.cc solver/sparse_solver.cc solver/sparse_solver.hh solver/sparse_solver_inline_impl.cc solver/sparse_matrix.cc solver/sparse_matrix.hh solver/sparse_matrix_inline_impl.cc solver/sparse_matrix_aij.cc solver/sparse_matrix_aij.hh solver/sparse_matrix_aij_inline_impl.cc solver/terms_to_assemble.hh synchronizer/communication_descriptor_tmpl.hh synchronizer/communications_tmpl.hh synchronizer/communication_buffer.hh synchronizer/communication_buffer_inline_impl.cc synchronizer/communication_descriptor.hh synchronizer/communication_tag.hh synchronizer/communications.hh synchronizer/data_accessor.cc synchronizer/data_accessor.hh synchronizer/element_synchronizer.cc synchronizer/element_synchronizer.hh synchronizer/node_synchronizer.cc synchronizer/node_synchronizer.hh synchronizer/dof_synchronizer.cc synchronizer/dof_synchronizer.hh synchronizer/dof_synchronizer_inline_impl.cc synchronizer/element_info_per_processor.cc synchronizer/element_info_per_processor.hh synchronizer/element_info_per_processor_tmpl.hh synchronizer/filtered_synchronizer.cc synchronizer/filtered_synchronizer.hh synchronizer/grid_synchronizer.cc synchronizer/grid_synchronizer.hh synchronizer/grid_synchronizer_tmpl.hh synchronizer/master_element_info_per_processor.cc synchronizer/node_info_per_processor.cc synchronizer/node_info_per_processor.hh synchronizer/real_static_communicator.hh synchronizer/slave_element_info_per_processor.cc synchronizer/static_communicator.cc synchronizer/static_communicator.hh synchronizer/static_communicator_dummy.hh synchronizer/static_communicator_inline_impl.hh synchronizer/synchronizer.cc synchronizer/synchronizer.hh synchronizer/synchronizer_impl.hh synchronizer/synchronizer_impl_tmpl.hh synchronizer/synchronizer_registry.cc synchronizer/synchronizer_registry.hh synchronizer/synchronizer_tmpl.hh ) package_declare_elements(core ELEMENT_TYPES _point_1 _segment_2 _segment_3 _triangle_3 _triangle_6 _quadrangle_4 _quadrangle_8 _tetrahedron_4 _tetrahedron_10 _pentahedron_6 _pentahedron_15 _hexahedron_8 _hexahedron_20 KIND regular GEOMETRICAL_TYPES _gt_point _gt_segment_2 _gt_segment_3 _gt_triangle_3 _gt_triangle_6 _gt_quadrangle_4 _gt_quadrangle_8 _gt_tetrahedron_4 _gt_tetrahedron_10 _gt_hexahedron_8 _gt_hexahedron_20 _gt_pentahedron_6 _gt_pentahedron_15 INTERPOLATION_TYPES _itp_lagrange_point_1 _itp_lagrange_segment_2 _itp_lagrange_segment_3 _itp_lagrange_triangle_3 _itp_lagrange_triangle_6 _itp_lagrange_quadrangle_4 _itp_serendip_quadrangle_8 _itp_lagrange_tetrahedron_4 _itp_lagrange_tetrahedron_10 _itp_lagrange_hexahedron_8 _itp_serendip_hexahedron_20 _itp_lagrange_pentahedron_6 _itp_lagrange_pentahedron_15 GEOMETRICAL_SHAPES _gst_point _gst_triangle _gst_square _gst_prism GAUSS_INTEGRATION_TYPES _git_point _git_segment _git_triangle _git_tetrahedron _git_pentahedron INTERPOLATION_KIND _itk_lagrangian FE_ENGINE_LISTS gradient_on_integration_points interpolate_on_integration_points interpolate compute_normals_on_integration_points inverse_map contains compute_shapes compute_shapes_derivatives get_shapes_derivatives lagrange_base ) package_declare_material_infos(core LIST AKANTU_CORE_MATERIAL_LIST INCLUDE material_core_includes.hh ) package_declare_documentation_files(core manual.sty manual.cls manual.tex manual-macros.sty manual-titlepages.tex manual-authors.tex manual-introduction.tex manual-gettingstarted.tex manual-io.tex manual-feengine.tex manual-solidmechanicsmodel.tex manual-constitutive-laws.tex manual-lumping.tex manual-elements.tex manual-appendix-elements.tex manual-appendix-materials.tex manual-appendix-packages.tex manual-backmatter.tex manual-bibliography.bib manual-bibliographystyle.bst figures/bc_and_ic_example.pdf figures/boundary.pdf figures/boundary.svg figures/dirichlet.pdf figures/dirichlet.svg figures/doc_wheel.pdf figures/doc_wheel.svg figures/dynamic_analysis.png figures/explicit_dynamic.pdf figures/explicit_dynamic.svg figures/static.pdf figures/static.svg figures/hooke_law.pdf figures/hot-point-1.png figures/hot-point-2.png figures/implicit_dynamic.pdf figures/implicit_dynamic.svg figures/insertion.pdf figures/interpolate.pdf figures/interpolate.svg figures/problemDomain.pdf_tex figures/problemDomain.pdf figures/static_analysis.png figures/stress_strain_el.pdf figures/tangent.pdf figures/tangent.svg figures/vectors.pdf figures/vectors.svg figures/stress_strain_neo.pdf figures/visco_elastic_law.pdf figures/isotropic_hardening_plasticity.pdf figures/stress_strain_visco.pdf figures/elements/hexahedron_8.pdf figures/elements/hexahedron_8.svg figures/elements/quadrangle_4.pdf figures/elements/quadrangle_4.svg figures/elements/quadrangle_8.pdf figures/elements/quadrangle_8.svg figures/elements/segment_2.pdf figures/elements/segment_2.svg figures/elements/segment_3.pdf figures/elements/segment_3.svg figures/elements/tetrahedron_10.pdf figures/elements/tetrahedron_10.svg figures/elements/tetrahedron_4.pdf figures/elements/tetrahedron_4.svg figures/elements/triangle_3.pdf figures/elements/triangle_3.svg figures/elements/triangle_6.pdf figures/elements/triangle_6.svg figures/elements/xtemp.pdf ) package_declare_documentation(core "This package is the core engine of \\akantu. It depends on:" "\\begin{itemize}" "\\item A C++ compiler (\\href{http://gcc.gnu.org/}{GCC} >= 4, or \\href{https://software.intel.com/en-us/intel-compilers}{Intel})." "\\item The cross-platform, open-source \\href{http://www.cmake.org/}{CMake} build system." "\\item The \\href{http://www.boost.org/}{Boost} C++ portable libraries." "\\item The \\href{http://www.zlib.net/}{zlib} compression library." "\\end{itemize}" "" "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:" "\\begin{command}" " > sudo apt-get install cmake libboost-dev zlib1g-dev g++" "\\end{command}" "" "Under Mac OS X the installation requires the following steps:" "\\begin{itemize}" "\\item Install Xcode" "\\item Install the command line tools." "\\item Install the MacPorts project which allows to automatically" "download and install opensource packages." "\\end{itemize}" "Then the following commands should be typed in a terminal:" "\\begin{command}" " > sudo port install cmake gcc48 boost" "\\end{command}" ) find_program(READLINK_COMMAND readlink) find_program(ADDR2LINE_COMMAND addr2line) find_program(PATCH_COMMAND patch) mark_as_advanced(READLINK_COMMAND) mark_as_advanced(ADDR2LINE_COMMAND) package_declare_extra_files_to_package(core SOURCES common/aka_element_classes_info.hh.in common/aka_config.hh.in model/solid_mechanics/material_list.hh.in ) if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9)) package_set_compile_flags(core CXX "-Wno-undefined-var-template") endif() if(DEFINED AKANTU_CXX11_FLAGS) package_declare(core_cxx11 NOT_OPTIONAL DESCRIPTION "C++ 11 additions for Akantu core" COMPILE_FLAGS CXX "${AKANTU_CXX11_FLAGS}") if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.6") set(AKANTU_CORE_CXX11 OFF CACHE BOOL "C++ 11 additions for Akantu core - not supported by the selected compiler" FORCE) endif() endif() package_declare_documentation(core_cxx11 "This option activates some features of the C++11 standard. This is usable with GCC>=4.7 or Intel>=13.") else() if(CMAKE_VERSION VERSION_LESS 3.1) message(FATAL_ERROR "Since version 3.0 Akantu requires at least c++11 capable compiler") endif() endif() diff --git a/packages/structural_mechanics.cmake b/packages/structural_mechanics.cmake index bcf32ff94..3090ea633 100644 --- a/packages/structural_mechanics.cmake +++ b/packages/structural_mechanics.cmake @@ -1,76 +1,81 @@ #=============================================================================== # @file structural_mechanics.cmake # # @author Nicolas Richart <nicolas.richart@epfl.ch> # # @date creation: Mon Nov 21 2011 # @date last modification: Sun Jul 19 2015 # # @brief package description for structural mechanics # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see <http://www.gnu.org/licenses/>. # #=============================================================================== package_declare(structural_mechanics DESCRIPTION "Use Structural mechanics model package of Akantu" DEPENDS implicit) package_declare_sources(structural_mechanics fe_engine/element_class_structural.hh fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc - fe_engine/fe_engine_template_tmpl_struct.hh fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc + fe_engine/fe_engine_template_tmpl_struct.hh + fe_engine/shape_structural.cc + fe_engine/shape_structural.hh + fe_engine/shape_structural_inline_impl.cc io/mesh_io/mesh_io_msh_struct.cc io/mesh_io/mesh_io_msh_struct.hh - io/model_io/model_io_ibarras.cc - io/model_io/model_io_ibarras.hh + model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh + model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh + model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_kirchhoff_shell.hh model/structural_mechanics/structural_mechanics_model.cc model/structural_mechanics/structural_mechanics_model.hh model/structural_mechanics/structural_mechanics_model_boundary.cc model/structural_mechanics/structural_mechanics_model_inline_impl.cc model/structural_mechanics/structural_mechanics_model_mass.cc ) package_declare_elements(structural_mechanics ELEMENT_TYPES _bernoulli_beam_2 _bernoulli_beam_3 _kirchhoff_shell KIND structural INTERPOLATION_TYPES - _itp_bernoulli_beam + _itp_bernoulli_beam_2 + _itp_bernoulli_beam_3 _itp_kirchhoff_shell INTERPOLATION_KIND _itk_structural ) package_declare_documentation_files(structural_mechanics manual-structuralmechanicsmodel.tex manual-structuralmechanicsmodel-elements.tex figures/beam_example.pdf figures/elements/bernoulli_2.pdf figures/elements/bernoulli_2.svg ) package_declare_documentation(structural_mechanics "This package activates the compilation for the Structural Mechanics engine of Akantu" ) diff --git a/src/fe_engine/element_class_structural.hh b/src/fe_engine/element_class_structural.hh index 4ef4c017c..a3d13ab6e 100644 --- a/src/fe_engine/element_class_structural.hh +++ b/src/fe_engine/element_class_structural.hh @@ -1,260 +1,197 @@ /** * @file element_class_structural.hh * * @author Fabian Barras <fabian.barras@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * @author Damien Spielmann <damien.spielmann@epfl.ch> * * @date creation: Thu Feb 21 2013 * @date last modification: Thu Oct 22 2015 * * @brief Specialization of the element classes for structural elements * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ +/* -------------------------------------------------------------------------- */ +#include "element_class.hh" +/* -------------------------------------------------------------------------- */ + +#ifndef __AKANTU_ELEMENT_CLASS_STRUCTURAL_HH__ +#define __AKANTU_ELEMENT_CLASS_STRUCTURAL_HH__ namespace akantu { +/// Macro to generate the InterpolationProperty structures for different +/// interpolation types +#define AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY( \ + itp_type, parent_type, ndim, ndof) \ + template <> struct InterpolationProperty<itp_type> { \ + static const InterpolationKind kind{_itk_structural}; \ + static const UInt nb_nodes_per_element{ \ + InterpolationProperty<parent_type>::nb_nodes_per_element}; \ + static const InterpolationType parent_element_type{parent_type}; \ + static const UInt natural_space_dimension{ndim}; \ + static const UInt nb_degree_of_freedom{ndof}; \ + } + /* -------------------------------------------------------------------------- */ template <InterpolationType interpolation_type> class InterpolationElement<interpolation_type, _itk_structural> { public: - typedef InterpolationPorperty<interpolation_type> interpolation_property; + using interpolation_property = InterpolationProperty<interpolation_type>; /// compute the shape values for a given set of points in natural coordinates static inline void computeShapes(const Matrix<Real> & natural_coord, - Matrix<Real> & N, - const Matrix<Real> & real_nodal_coord, - UInt n = 0) { + Tensor3<Real> & N, + const Matrix<Real> & real_nodal_coord) { UInt nb_points = natural_coord.cols(); for (UInt p = 0; p < nb_points; ++p) { - Vector<Real> Np = N(p); - computeShapes(natural_coord(p), Np, real_nodal_coord, n); + Matrix<Real> Np = N(p); + computeShapes(natural_coord(p), Np, real_nodal_coord); } } /// compute the shape values for a given point in natural coordinates static inline void computeShapes(const Vector<Real> & natural_coord, - Vector<Real> & N, - const Matrix<Real> & real_nodal_coord, - UInt n = 0); + Matrix<Real> & N, + const Matrix<Real> & real_nodal_coord); /** * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of * shape functions along with variation of natural coordinates on a given set * of points in natural coordinates */ static inline void computeDNDS(const Matrix<Real> & natural_coord, Tensor3<Real> & dnds, - const Matrix<Real> & real_nodal_coord, - UInt n = 0) { + const Matrix<Real> & real_nodal_coord) { for (UInt i = 0; i < natural_coord.cols(); ++i) { Matrix<Real> dnds_t = dnds(i); - computeDNDS(natural_coord(i), dnds_t, real_nodal_coord, n); + computeDNDS(natural_coord(i), dnds_t, real_nodal_coord); } } /** * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of * shape functions along with * variation of natural coordinates on a given point in natural * coordinates */ static inline void computeDNDS(const Vector<Real> & natural_coord, Matrix<Real> & dnds, - const Matrix<Real> & real_nodal_coord, - UInt n = 0); + const Matrix<Real> & real_nodal_coord); public: - static AKANTU_GET_MACRO_NOT_CONST(NbShapeFunctions, nb_shape_functions, UInt); - static AKANTU_GET_MACRO_NOT_CONST(NbShapeDerivatives, nb_shape_derivatives, - UInt); static AKANTU_GET_MACRO_NOT_CONST( - ShapeSize, interpolation_property::nb_nodes_per_element, UInt); + NbNodesPerInterpolationElement, + interpolation_property::nb_nodes_per_element, UInt); + static AKANTU_GET_MACRO_NOT_CONST( - ShapeDerivativesSize, (interpolation_property::nb_nodes_per_element * - interpolation_property::natural_space_dimension), + ShapeSize, + (interpolation_property::nb_nodes_per_element * + interpolation_property::nb_degree_of_freedom * + interpolation_property::nb_degree_of_freedom), + UInt); + static AKANTU_GET_MACRO_NOT_CONST( + ShapeDerivativesSize, + (interpolation_property::nb_nodes_per_element * + interpolation_property::nb_degree_of_freedom * + interpolation_property::natural_space_dimension), UInt); static AKANTU_GET_MACRO_NOT_CONST( NaturalSpaceDimension, interpolation_property::natural_space_dimension, UInt); + static AKANTU_GET_MACRO_NOT_CONST( + NbDegreeOfFreedom, + interpolation_property::nb_degree_of_freedom, UInt); -protected: - /// nb shape functions - static const UInt nb_shape_functions; - static const UInt nb_shape_derivatives; }; /// Macro to generate the element class structures for different structural /// element types /* -------------------------------------------------------------------------- */ #define AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY( \ elem_type, geom_type, interp_type, parent_el_type, elem_kind, sp, \ gauss_int_type, min_int_order) \ template <> struct ElementClassProperty<elem_type> { \ - static const GeometricalType geometrical_type = geom_type; \ - static const InterpolationType interpolation_type = interp_type; \ - static const ElementType parent_element_type = parent_el_type; \ - static const ElementKind element_kind = elem_kind; \ - static const UInt spatial_dimension = sp; \ - static const GaussIntegrationType gauss_integration_type = gauss_int_type; \ - static const UInt polynomial_degree = min_int_order; \ + static const GeometricalType geometrical_type{geom_type}; \ + static const InterpolationType interpolation_type{interp_type}; \ + static const ElementType parent_element_type{parent_el_type}; \ + static const ElementKind element_kind{elem_kind}; \ + static const UInt spatial_dimension{sp}; \ + static const GaussIntegrationType gauss_integration_type{gauss_int_type}; \ + static const UInt polynomial_degree{min_int_order}; \ } /* -------------------------------------------------------------------------- */ /* ElementClass for structural elements */ /* -------------------------------------------------------------------------- */ template <ElementType element_type> class ElementClass<element_type, _ek_structural> : public GeometricalElement< ElementClassProperty<element_type>::geometrical_type>, public InterpolationElement< ElementClassProperty<element_type>::interpolation_type> { protected: - typedef GeometricalElement< - ElementClassProperty<element_type>::geometrical_type> - geometrical_element; - typedef InterpolationElement< - ElementClassProperty<element_type>::interpolation_type> - interpolation_element; - typedef ElementClass<ElementClassProperty<element_type>::parent_element_type> - parent_element; + using geometrical_element = + GeometricalElement<ElementClassProperty<element_type>::geometrical_type>; + using interpolation_element = InterpolationElement< + ElementClassProperty<element_type>::interpolation_type>; + using parent_element = + ElementClass<ElementClassProperty<element_type>::parent_element_type>; public: /// compute shape derivatives (input is dxds) for a set of points static inline void computeShapeDerivatives(const Matrix<Real> & natural_coord, Tensor3<Real> & shape_deriv, - const Matrix<Real> & real_nodal_coord, UInt n = 0) { + const Matrix<Real> & real_nodal_coord) { UInt nb_points = natural_coord.cols(); - - if (element_type == _kirchhoff_shell) { - /// TO BE CONTINUED and moved in a _tmpl.hh - - UInt spatial_dimension = real_nodal_coord.cols(); - UInt nb_nodes = real_nodal_coord.rows(); - - const UInt projected_dim = natural_coord.rows(); - Matrix<Real> rotation_matrix(real_nodal_coord); - Matrix<Real> rotated_nodal_coord(real_nodal_coord); - Matrix<Real> projected_nodal_coord(natural_coord); - /* -------------------------------------------------------------------------- - */ - /* -------------------------------------------------------------------------- - */ - - Matrix<Real> Pe(real_nodal_coord); - Matrix<Real> Pg(real_nodal_coord); - Matrix<Real> inv_Pg(real_nodal_coord); - - /// compute matrix Pe - Pe.eye(); - - /// compute matrix Pg - Vector<Real> Pg_col_1(spatial_dimension); - Pg_col_1(0) = real_nodal_coord(0, 1) - real_nodal_coord(0, 0); - Pg_col_1(1) = real_nodal_coord(1, 1) - real_nodal_coord(1, 0); - Pg_col_1(2) = real_nodal_coord(2, 1) - real_nodal_coord(2, 0); - - Vector<Real> Pg_col_2(spatial_dimension); - Pg_col_2(0) = real_nodal_coord(0, 2) - real_nodal_coord(0, 0); - Pg_col_2(1) = real_nodal_coord(1, 2) - real_nodal_coord(1, 0); - Pg_col_2(2) = real_nodal_coord(2, 2) - real_nodal_coord(2, 0); - - Vector<Real> Pg_col_3(spatial_dimension); - Pg_col_3.crossProduct(Pg_col_1, Pg_col_2); - - for (UInt i = 0; i < nb_points; ++i) { - Pg(i, 0) = Pg_col_1(i); - Pg(i, 1) = Pg_col_2(i); - Pg(i, 2) = Pg_col_3(i); - } - - /// compute inverse of Pg - inv_Pg.inverse(Pg); - - /// compute rotation matrix - // rotation_matrix=Pe*inv_Pg; - rotation_matrix.eye(); - /* -------------------------------------------------------------------------- - */ - /* -------------------------------------------------------------------------- - */ - - rotated_nodal_coord.mul<false, false>(rotation_matrix, real_nodal_coord); - - for (UInt i = 0; i < projected_dim; ++i) { - for (UInt j = 0; j < nb_points; ++j) { - projected_nodal_coord(i, j) = rotated_nodal_coord(i, j); - } - } - - Tensor3<Real> dnds(projected_dim, nb_nodes, natural_coord.cols()); - Tensor3<Real> J(projected_dim, projected_dim, natural_coord.cols()); - - parent_element::computeDNDS(natural_coord, dnds); - - parent_element::computeJMat(dnds, projected_nodal_coord, J); - - for (UInt p = 0; p < nb_points; ++p) { - - Matrix<Real> shape_deriv_p = shape_deriv(p); - - interpolation_element::computeDNDS(natural_coord(p), shape_deriv_p, - projected_nodal_coord, n); - - Matrix<Real> dNdS = shape_deriv_p; - Matrix<Real> inv_J(projected_dim, projected_dim); - inv_J.inverse(J(p)); - shape_deriv_p.mul<false, false>(inv_J, dNdS); - } - } else { - - for (UInt p = 0; p < nb_points; ++p) { - Matrix<Real> shape_deriv_p = shape_deriv(p); - interpolation_element::computeDNDS(natural_coord(p), shape_deriv_p, - real_nodal_coord, n); - } + for (UInt p = 0; p < nb_points; ++p) { + Matrix<Real> shape_deriv_p = shape_deriv(p); + interpolation_element::computeDNDS(natural_coord(p), shape_deriv_p, + real_nodal_coord); } } /// compute jacobian (or integration variable change factor) for a given point static inline void computeJacobian(const Matrix<Real> & natural_coords, const Matrix<Real> & nodal_coords, Vector<Real> & jacobians) { parent_element::computeJacobian(natural_coords, nodal_coords, jacobians); } public: static AKANTU_GET_MACRO_NOT_CONST(Kind, _ek_structural, ElementKind); static AKANTU_GET_MACRO_NOT_CONST(P1ElementType, _not_defined, ElementType); static AKANTU_GET_MACRO_NOT_CONST(FacetType, _not_defined, ElementType); static ElementType getFacetType(__attribute__((unused)) UInt t = 0) { return _not_defined; } static AKANTU_GET_MACRO_NOT_CONST( SpatialDimension, ElementClassProperty<element_type>::spatial_dimension, UInt); static ElementType * getFacetTypeInternal() { return NULL; } }; +} // namespace akantu + #include "element_classes/element_class_bernoulli_beam_inline_impl.cc" #include "element_classes/element_class_kirchhoff_shell_inline_impl.cc" -} // akantu +#endif /* __AKANTU_ELEMENT_CLASS_STRUCTURAL_HH__ */ diff --git a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc index 1b38affd4..f3ba7f621 100644 --- a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc +++ b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.cc @@ -1,195 +1,270 @@ /** * @file element_class_bernoulli_beam_inline_impl.cc * * @author Fabian Barras <fabian.barras@epfl.ch> * * @date creation: Fri Jul 15 2011 * @date last modification: Sun Oct 19 2014 * - * @brief Specialization of the element_class class for the type _bernoulli_beam_2 + * @brief Specialization of the element_class class for the type + _bernoulli_beam_2 * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * * @section DESCRIPTION * * @verbatim --x-----q1----|----q2-----x---> x -a 0 a @endverbatim * * @subsection coords Nodes coordinates * * @f[ * \begin{array}{ll} * x_{1} = -a & x_{2} = a * \end{array} * @f] * * @subsection shapes Shape functions * @f[ * \begin{array}{ll} * N_1(x) &= \frac{1-x}{2a}\\ * N_2(x) &= \frac{1+x}{2a} * \end{array} * * \begin{array}{ll} * M_1(x) &= 1/4(x^{3}/a^{3}-3x/a+2)\\ * M_2(x) &= -1/4(x^{3}/a^{3}-3x/a-2) * \end{array} * * \begin{array}{ll} * L_1(x) &= a/4(x^{3}/a^{3}-x^{2}/a^{2}-x/a+1)\\ * L_2(x) &= a/4(x^{3}/a^{3}+x^{2}/a^{2}-x/a-1) * \end{array} * * \begin{array}{ll} * M'_1(x) &= 3/4a(x^{2}/a^{2}-1)\\ * M'_2(x) &= -3/4a(x^{2}/a^{2}-1) * \end{array} * * \begin{array}{ll} * L'_1(x) &= 1/4(3x^{2}/a^{2}-2x/a-1)\\ * L'_2(x) &= 1/4(3x^{2}/a^{2}+2x/a-1) * \end{array} *@f] * * @subsection dnds Shape derivatives * *@f[ * \begin{array}{ll} * N'_1(x) &= -1/2a\\ * N'_2(x) &= 1/2a * \end{array}] * * \begin{array}{ll} * -M''_1(x) &= -3x/(2a^{3})\\ * -M''_2(x) &= 3x/(2a^{3})\\ * \end{array} * * \begin{array}{ll} * -L''_1(x) &= -1/2a(3x/a-1)\\ * -L''_2(x) &= -1/2a(3x/a+1) * \end{array} *@f] * * @subsection quad_points Position of quadrature points * * @f[ * \begin{array}{ll} * x_{q1} = -a/\sqrt{3} & x_{q2} = a/\sqrt{3} * \end{array} * @f] */ +/* -------------------------------------------------------------------------- */ +#include "aka_static_if.hh" +#include "element_class_structural.hh" +/* -------------------------------------------------------------------------- */ +#ifndef __AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_CC__ +#define __AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_CC__ + +namespace akantu { /* -------------------------------------------------------------------------- */ +AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam_2, + _itp_lagrange_segment_2, 2, + 3); +AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam_3, + _itp_lagrange_segment_2, 3, + 6); + AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_2, - _gt_segment_2, - _itp_bernoulli_beam, - _segment_2, - _ek_structural, - 2, - _git_segment, 4); + _gt_segment_2, + _itp_bernoulli_beam_2, + _segment_2, _ek_structural, 2, + _git_segment, 5); AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_3, - _gt_segment_2, - _itp_bernoulli_beam, - _segment_2, - _ek_structural, - 3, - _git_segment, 4); + _gt_segment_2, + _itp_bernoulli_beam_3, + _segment_2, _ek_structural, 3, + _git_segment, 5); + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +namespace { + namespace details { + template <InterpolationType type> + void computeShapes(const Vector<Real> & natural_coords, Matrix<Real> & N, + const Matrix<Real> & real_coord) { + /// Compute the dimension of the beam + Vector<Real> x1 = real_coord(0); + Vector<Real> x2 = real_coord(1); + + Real a = x1.distance(x2) / 2.; + /// natural coordinate + Real c = natural_coords(0); + + auto N0 = (1 - c) / 2.; + auto N1 = (1 + c) / 2.; + + auto M0 = (c * c * c - 3. * c + 2.) / 4.; + auto M1 = -(c * c * c - 3. * c - 2.) / 4.; + + auto L0 = a * (c * c * c - c * c - c + 1.) / 4.; + auto L1 = a * (c * c * c + c * c - c - 1.) / 4.; + + auto Mp0 = 3. / a * (c * c - 1.) / 4.; + auto Mp1 = -3. / a * (c * c - 1.) / 4.; + + auto Lp0 = (3. * c * c - 2. * c - 1.) / 4.; + auto Lp1 = (3. * c * c + 2. * c - 1.) / 4.; + + static_if(type == _itp_bernoulli_beam_2) + .then([&](auto && N) { + // clang-format off + // 0 1 2 3 4 5 + N = {{N0, 0., 0., N1, 0., 0.}, + {0., M0, L0, 0., M1, L1}, + {0., Mp0, Lp0, 0., Mp1, Lp1}}; + // clang-format on + }) + .else_if(type == _itp_bernoulli_beam_3) + .then([&](auto && N) { + // clang-format off + // 0 1 2 3 4 5 6 7 8 9 10 11 + N = {{N0, 0., 0., 0., 0., 0., N1, 0., 0., 0., 0., 0.}, + { 0., M0, 0., 0., 0., L0, 0., M1, 0., 0., 0., L1}, + { 0., 0., M0, 0., -L0, 0., 0., 0., M1, 0., -L1, 0.}, + { 0., 0., 0., N0, 0., 0., 0., 0., 0., N1, 0., 0.}, + { 0., 0., Mp0, 0., -Lp0, 0., 0., 0., Mp1, 0., -Lp1, 0.}, + { 0., Mp0, 0., 0., 0., Lp0, 0., Mp1, 0., 0., 0., Lp1}}; + // clang-format on + }) + .else_([](auto && /*unused*/) { + AKANTU_EXCEPTION("Should not be in this part of the code"); + })(std::forward<decltype(N)>(N)); + } + + /* ---------------------------------------------------------------------- */ + + template <InterpolationType type> + void computeDNDS(const Vector<Real> & natural_coords, Matrix<Real> & B, + const Matrix<Real> & real_nodes_coord) { + /// Compute the dimension of the beam + Vector<Real> x1 = real_nodes_coord(0); + Vector<Real> x2 = real_nodes_coord(1); + + Real a = .5 * x1.distance(x2); + /// natural coordinate + Real c = natural_coords(0) * a; + + auto Np0 = -1. / (2. * a); + auto Np1 = 1. / (2. * a); + + auto Mpp0 = -3. * c / (2. * pow(a, 3.)); + auto Mpp1 = 3. * c / (2. * pow(a, 3.)); + + auto Lpp0 = -1. / (2. * a) * (3. * c / a - 1.); + auto Lpp1 = -1. / (2. * a) * (3. * c / a + 1.); + + static_if(type == _itp_bernoulli_beam_2) + .then([&](auto && B) { + // clang-format off + // 0 1 2 3 4 5 + B = {{Np0, 0., 0., Np1, 0., 0.}, + { 0., Mpp0, Lpp0, 0., Mpp1, Lpp1}}; + // clang-format on + }) + .else_if(type == _itp_bernoulli_beam_3) + .then([&](auto && B) { + // clang-format off + // 0 1 2 3 4 5 6 7 8 9 10 11 + B = {{Np0, 0., 0., 0., 0., 0., Np1, 0., 0., 0., 0., 0.}, + { 0., Mpp0, 0., 0., 0., Lpp0, 0., Mpp1, 0., 0., 0., Lpp1}, + { 0., 0., Mpp0, 0., -Lpp0, 0., 0., 0., Mpp1, 0., -Lpp1, 0.}, + { 0., 0., 0., Np0, 0., 0., 0., 0., 0., Np1, 0., 0.}}; + // clang-format on + }) + .else_([](auto && /*unused*/) { + AKANTU_EXCEPTION("Should not be in this part of the code"); + })(std::forward<decltype(B)>(B)); + } + } // namespace details +} // namespace /* -------------------------------------------------------------------------- */ template <> inline void -InterpolationElement<_itp_bernoulli_beam>::computeShapes(const Vector<Real> & natural_coords, - Vector<Real> & N, - const Matrix<Real> & real_coord, - UInt id) { - /// Compute the dimension of the beam - Vector<Real> x1 = real_coord(0); - Vector<Real> x2 = real_coord(1); - - Real a = .5 * x1.distance(x2); - /// natural coordinate - Real c = natural_coords(0); - - switch (id) { - case 0: { // N - N(0) = 0.5*(1 - c); - N(1) = 0.5*(1 + c); - break; - } - case 1: { // M - N(0) = 0.25 * (c*c*c - 3*c + 2); - N(1) = -0.25 * (c*c*c - 3*c - 2); - break; - } - case 2: { // L - N(0) = 0.25*a * (c*c*c - c*c - c + 1); - N(1) = 0.25*a * (c*c*c + c*c - c - 1); - break; - } - case 3: { // M' - N(0) = 0.75/a * (c*c - 1); - N(1) = -0.75/a * (c*c - 1); - break; - } - case 4: { // L' - N(0) = 0.25 * (3*c*c - 2*c - 1); - N(1) = 0.25 * (3*c*c + 2*c - 1); - break; - } - } - } +InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeShapes( + const Vector<Real> & natural_coords, Matrix<Real> & N, + const Matrix<Real> & real_coord) { + details::computeShapes<_itp_bernoulli_beam_2>(natural_coords, N, real_coord); +} + +template <> +inline void +InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::computeShapes( + const Vector<Real> & natural_coords, Matrix<Real> & N, + const Matrix<Real> & real_coord) { + details::computeShapes<_itp_bernoulli_beam_3>(natural_coords, N, real_coord); +} /* -------------------------------------------------------------------------- */ template <> inline void -InterpolationElement<_itp_bernoulli_beam>::computeDNDS(const Vector<Real> & natural_coords, - Matrix<Real> & dnds, - const Matrix<Real> & real_nodes_coord, - UInt id) { - /// Compute the dimension of the beam - Vector<Real> x1 = real_nodes_coord(0); - Vector<Real> x2 = real_nodes_coord(1); - - Real a = .5 * x1.distance(x2); - /// natural coordinate - Real c = natural_coords(0)*a; - - - switch (id) { - case 0: { // N' - dnds(0, 0) = -0.5/a; - dnds(0, 1) = 0.5/a; - break; - } - case 1: { // M'' - dnds(0, 0) = -3.*c/(2.*pow(a,3)); - dnds(0, 1) = 3.*c/(2.*pow(a,3)); - break; - } - case 2: { // L'' - dnds(0, 0) = -0.5/a * (3*c/a - 1); - dnds(0, 1) =- 0.5/a * (3*c/a + 1); - break; - } - } +InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeDNDS( + const Vector<Real> & natural_coords, Matrix<Real> & B, + const Matrix<Real> & real_nodes_coord) { + details::computeDNDS<_itp_bernoulli_beam_2>(natural_coords, B, + real_nodes_coord); } + +template <> +inline void +InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::computeDNDS( + const Vector<Real> & natural_coords, Matrix<Real> & B, + const Matrix<Real> & real_nodes_coord) { + details::computeDNDS<_itp_bernoulli_beam_3>(natural_coords, B, + real_nodes_coord); +} + +} // namespace akantu +#endif /* __AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_CC__ */ diff --git a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc index f033f8184..299a36112 100644 --- a/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc +++ b/src/fe_engine/element_classes/element_class_kirchhoff_shell_inline_impl.cc @@ -1,289 +1,368 @@ /** * @file element_class_kirchhoff_shell_inline_impl.cc * * @author Damien Spielmann <damien.spielmann@epfl.ch> * * @date creation: Fri Jul 04 2014 * @date last modification: Sun Oct 19 2014 * * @brief Element class Kirchhoff Shell * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ +/* -------------------------------------------------------------------------- */ +#include "element_class_structural.hh" +/* -------------------------------------------------------------------------- */ + +#ifndef __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__ +#define __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__ + +namespace akantu { /* -------------------------------------------------------------------------- */ +AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_kirchhoff_shell, + _itp_lagrange_triangle_3, 3, 6); AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_kirchhoff_shell, _gt_triangle_3, _itp_kirchhoff_shell, _triangle_3, _ek_structural, 3, _git_triangle, 2); /* -------------------------------------------------------------------------- */ // cf. element_class_bernoulli... // element_class_triangle_3_inline... (pour compute Jacobian) template <> inline void InterpolationElement<_itp_kirchhoff_shell>::computeShapes( - const Vector<Real> & natural_coords, Vector<Real> & N, - const Matrix<Real> & projected_coord, UInt id) { - // projected_coord (x1 x2 x3) (y1 y2 y3) - - // natural coordinate - Real xi = natural_coords(0); - Real eta = natural_coords(1); - - Real x21 = projected_coord(0, 0) - projected_coord(0, 1); // x1-x2 - Real x32 = projected_coord(0, 1) - projected_coord(0, 2); - Real x13 = projected_coord(0, 2) - projected_coord(0, 0); - - Real y21 = projected_coord(1, 0) - projected_coord(1, 1); // y1-y2 - Real y32 = projected_coord(1, 1) - projected_coord(1, 2); - Real y13 = projected_coord(1, 2) - projected_coord(1, 0); - - /* Real x21=projected_coord(0,1)-projected_coord(0,0); - Real x32=projected_coord(0,2)-projected_coord(0,1); - Real x13=projected_coord(0,0)-projected_coord(0,2); - - Real y21=projected_coord(1,1)-projected_coord(1,0); - Real y32=projected_coord(1,2)-projected_coord(1,1); - Real y13=projected_coord(1,0)-projected_coord(1,2);*/ - - // natural triangle side length - Real L4 = sqrt(x21 * x21 + y21 * y21); - Real L5 = sqrt(x32 * x32 + y32 * y32); - Real L6 = sqrt(x13 * x13 + y13 * y13); - - // sinus and cosinus - Real C4 = x21 / L4; // 1 - Real C5 = x32 / L5; //-1/sqrt(2); - Real C6 = x13 / L6; // 0 - Real S4 = y21 / L4; // 0; - Real S5 = y32 / L5; // 1/sqrt(2); - Real S6 = y13 / L6; //-1; - - Real N1 = 1 - xi - eta; - Real N2 = xi; - Real N3 = eta; - - Real P4 = 4 * xi * (1 - xi - eta); - Real P5 = 4 * xi * eta; - Real P6 = 4 * eta * (1 - xi - eta); - - switch (id) { - case 0: { // N - N(0) = N1; - N(1) = N2; - N(2) = N3; - break; - } - case 1: { // Nwi2 - N(0) = -(1 / 8) * P4 * L4 * C4 + (1 / 8) * P6 * L6 * C6; - N(1) = -(1 / 8) * P5 * L5 * C5 + (1 / 8) * P4 * L4 * C4; - N(2) = -(1 / 8) * P6 * L6 * C6 + (1 / 8) * P5 * L5 * C5; - break; - } - case 2: { // Nwi3 - N(0) = -(1 / 8) * P4 * L4 * S4 + (1 / 8) * P6 * L6 * S6; - N(1) = -(1 / 8) * P5 * L5 * S5 + (1 / 8) * P4 * L4 * S4; - N(2) = -(1 / 8) * P6 * L6 * S6 + (1 / 8) * P5 * L5 * S5; - break; - } - case 3: { // Nxi1 - N(0) = 3 / (2 * L4) * P4 * C4 - 3 / (2 * L6) * P6 * C6; - N(1) = 3 / (2 * L5) * P5 * C5 - 3 / (2 * L4) * P4 * C4; - N(2) = 3 / (2 * L6) * P6 * C6 - 3 / (2 * L5) * P5 * C5; - break; - } - case 4: { // Nxi2 - N(0) = N1 - (3. / 4.) * P4 * C4 * C4 - (3. / 4.) * P6 * C6 * C6; - N(1) = N2 - (3. / 4.) * P5 * C5 * C5 - (3. / 4.) * P4 * C4 * C4; - N(2) = N3 - (3. / 4.) * P6 * C6 * C6 - (3. / 4.) * P5 * C5 * C5; - break; - } - case 5: { // Nxi3 - N(0) = -(3. / 4.) * P4 * C4 * S4 - (3. / 4.) * P6 * C6 * S6; - N(1) = -(3. / 4.) * P5 * C5 * S5 - (3. / 4.) * P4 * C4 * S4; - N(2) = -(3. / 4.) * P6 * C6 * S6 - (3. / 4.) * P5 * C5 * S5; - break; - } - case 6: { // Nyi1 - N(0) = 3 / (2 * L4) * P4 * S4 - 3 / (2 * L6) * P6 * S6; - N(1) = 3 / (2 * L5) * P5 * S5 - 3 / (2 * L4) * P4 * S4; - N(2) = 3 / (2 * L6) * P6 * S6 - 3 / (2 * L5) * P5 * S5; - break; - } - case 7: { // Nyi2 - N(0) = -(3. / 4.) * P4 * C4 * S4 - (3. / 4.) * P6 * C6 * S6; - N(1) = -(3. / 4.) * P5 * C5 * S5 - (3. / 4.) * P4 * C4 * S4; - N(2) = -(3. / 4.) * P6 * C6 * S6 - (3. / 4.) * P5 * C5 * S5; - break; - } - case 8: { // Nyi3 - N(0) = N1 - (3. / 4.) * P4 * S4 * S4 - (3. / 4.) * P6 * S6 * S6; - N(1) = N2 - (3. / 4.) * P5 * S5 * S5 - (3. / 4.) * P4 * S4 * S4; - N(2) = N3 - (3. / 4.) * P6 * S6 * S6 - (3. / 4.) * P5 * S5 * S5; - break; - } - } + const Vector<Real> & /*natural_coords*/, Matrix<Real> & /*N*/, + const Matrix<Real> & /*projected_coord*/) { +// // projected_coord (x1 x2 x3) (y1 y2 y3) + +// // natural coordinate +// Real xi = natural_coords(0); +// Real eta = natural_coords(1); + +// Real x21 = projected_coord(0, 0) - projected_coord(0, 1); // x1-x2 +// Real x32 = projected_coord(0, 1) - projected_coord(0, 2); +// Real x13 = projected_coord(0, 2) - projected_coord(0, 0); + +// Real y21 = projected_coord(1, 0) - projected_coord(1, 1); // y1-y2 +// Real y32 = projected_coord(1, 1) - projected_coord(1, 2); +// Real y13 = projected_coord(1, 2) - projected_coord(1, 0); + +// /* Real x21=projected_coord(0,1)-projected_coord(0,0); +// Real x32=projected_coord(0,2)-projected_coord(0,1); +// Real x13=projected_coord(0,0)-projected_coord(0,2); + +// Real y21=projected_coord(1,1)-projected_coord(1,0); +// Real y32=projected_coord(1,2)-projected_coord(1,1); +// Real y13=projected_coord(1,0)-projected_coord(1,2);*/ + +// // natural triangle side length +// Real L4 = sqrt(x21 * x21 + y21 * y21); +// Real L5 = sqrt(x32 * x32 + y32 * y32); +// Real L6 = sqrt(x13 * x13 + y13 * y13); + +// // sinus and cosinus +// Real C4 = x21 / L4; // 1 +// Real C5 = x32 / L5; //-1/sqrt(2); +// Real C6 = x13 / L6; // 0 +// Real S4 = y21 / L4; // 0; +// Real S5 = y32 / L5; // 1/sqrt(2); +// Real S6 = y13 / L6; //-1; + +// Real N1 = 1 - xi - eta; +// Real N2 = xi; +// Real N3 = eta; + +// Real P4 = 4 * xi * (1 - xi - eta); +// Real P5 = 4 * xi * eta; +// Real P6 = 4 * eta * (1 - xi - eta); + +// // switch (id) { +// // case 0: { // N +// // N(0) = N1; +// // N(1) = N2; +// // N(2) = N3; +// // break; +// // } +// // case 1: { // Nwi2 +// // N(0) = -(1 / 8) * P4 * L4 * C4 + (1 / 8) * P6 * L6 * C6; +// // N(1) = -(1 / 8) * P5 * L5 * C5 + (1 / 8) * P4 * L4 * C4; +// // N(2) = -(1 / 8) * P6 * L6 * C6 + (1 / 8) * P5 * L5 * C5; +// // break; +// // } +// // case 2: { // Nwi3 +// // N(0) = -(1 / 8) * P4 * L4 * S4 + (1 / 8) * P6 * L6 * S6; +// // N(1) = -(1 / 8) * P5 * L5 * S5 + (1 / 8) * P4 * L4 * S4; +// // N(2) = -(1 / 8) * P6 * L6 * S6 + (1 / 8) * P5 * L5 * S5; +// // break; +// // } +// // case 3: { // Nxi1 +// // N(0) = 3 / (2 * L4) * P4 * C4 - 3 / (2 * L6) * P6 * C6; +// // N(1) = 3 / (2 * L5) * P5 * C5 - 3 / (2 * L4) * P4 * C4; +// // N(2) = 3 / (2 * L6) * P6 * C6 - 3 / (2 * L5) * P5 * C5; +// // break; +// // } +// // case 4: { // Nxi2 +// // N(0) = N1 - (3. / 4.) * P4 * C4 * C4 - (3. / 4.) * P6 * C6 * C6; +// // N(1) = N2 - (3. / 4.) * P5 * C5 * C5 - (3. / 4.) * P4 * C4 * C4; +// // N(2) = N3 - (3. / 4.) * P6 * C6 * C6 - (3. / 4.) * P5 * C5 * C5; +// // break; +// // } +// // case 5: { // Nxi3 +// // N(0) = -(3. / 4.) * P4 * C4 * S4 - (3. / 4.) * P6 * C6 * S6; +// // N(1) = -(3. / 4.) * P5 * C5 * S5 - (3. / 4.) * P4 * C4 * S4; +// // N(2) = -(3. / 4.) * P6 * C6 * S6 - (3. / 4.) * P5 * C5 * S5; +// // break; +// // } +// // case 6: { // Nyi1 +// // N(0) = 3 / (2 * L4) * P4 * S4 - 3 / (2 * L6) * P6 * S6; +// // N(1) = 3 / (2 * L5) * P5 * S5 - 3 / (2 * L4) * P4 * S4; +// // N(2) = 3 / (2 * L6) * P6 * S6 - 3 / (2 * L5) * P5 * S5; +// // break; +// // } +// // case 7: { // Nyi2 +// // N(0) = -(3. / 4.) * P4 * C4 * S4 - (3. / 4.) * P6 * C6 * S6; +// // N(1) = -(3. / 4.) * P5 * C5 * S5 - (3. / 4.) * P4 * C4 * S4; +// // N(2) = -(3. / 4.) * P6 * C6 * S6 - (3. / 4.) * P5 * C5 * S5; +// // break; +// // } +// // case 8: { // Nyi3 +// // N(0) = N1 - (3. / 4.) * P4 * S4 * S4 - (3. / 4.) * P6 * S6 * S6; +// // N(1) = N2 - (3. / 4.) * P5 * S5 * S5 - (3. / 4.) * P4 * S4 * S4; +// // N(2) = N3 - (3. / 4.) * P6 * S6 * S6 - (3. / 4.) * P5 * S5 * S5; +// // break; +// // } +// // } } /* -------------------------------------------------------------------------- */ template <> -inline void InterpolationElement<_itp_kirchhoff_shell>::computeDNDS( - const Vector<Real> & natural_coords, Matrix<Real> & dnds, - const Matrix<Real> & projected_coord, UInt id) { +inline void +InterpolationElement<_itp_kirchhoff_shell, _itk_structural>::computeDNDS( + const Vector<Real> & natural_coords, Matrix<Real> & B, + const Matrix<Real> & projected_coord) { // natural coordinate Real xi = natural_coords(0); Real eta = natural_coords(1); // projected_coord (x1 x2 x3) (y1 y2 y3) // donne juste pour pour le patch test 4_5_5 mais donne quelque changement de // signe dans la matrice de rotation Real x21 = projected_coord(0, 0) - projected_coord(0, 1); // x1-x2 Real x32 = projected_coord(0, 1) - projected_coord(0, 2); Real x13 = projected_coord(0, 2) - projected_coord(0, 0); Real y21 = projected_coord(1, 0) - projected_coord(1, 1); // y1-y2 Real y32 = projected_coord(1, 1) - projected_coord(1, 2); Real y13 = projected_coord(1, 2) - projected_coord(1, 0); // donne juste pour la matrice de rigidité... mais pas pour le patch test // 4_5_5 /* Real x21=projected_coord(0,1)-projected_coord(0,0); Real x32=projected_coord(0,2)-projected_coord(0,1); Real x13=projected_coord(0,0)-projected_coord(0,2); Real y21=projected_coord(1,1)-projected_coord(1,0); Real y32=projected_coord(1,2)-projected_coord(1,1); Real y13=projected_coord(1,0)-projected_coord(1,2);*/ // natural triangle side length Real L4 = sqrt(x21 * x21 + y21 * y21); Real L5 = sqrt(x32 * x32 + y32 * y32); Real L6 = sqrt(x13 * x13 + y13 * y13); // sinus and cosinus Real C4 = x21 / L4; Real C5 = x32 / L5; Real C6 = x13 / L6; Real S4 = y21 / L4; Real S5 = y32 / L5; Real S6 = y13 / L6; Real dN1xi = -1; Real dN2xi = 1; Real dN3xi = 0; Real dN1eta = -1; Real dN2eta = 0; Real dN3eta = 1; Real dP4xi = 4 - 8 * xi - 4 * eta; Real dP5xi = 4 * eta; Real dP6xi = -4 * eta; Real dP4eta = -4 * xi; Real dP5eta = 4 * xi; Real dP6eta = 4 - 4 * xi - 8 * eta; - switch (id) { - case 0: { // N'xi N'eta - dnds(0, 0) = dN1xi; - dnds(0, 1) = dN2xi; - dnds(0, 2) = dN3xi; - - dnds(1, 0) = dN1eta; - dnds(1, 1) = dN2eta; - dnds(1, 2) = dN3eta; - break; - } - case 1: { // Nxi1'xi Nxi1'eta - dnds(0, 0) = 3 / (2 * L4) * dP4xi * C4 - 3 / (2 * L6) * dP6xi * C6; - dnds(0, 1) = 3 / (2 * L5) * dP5xi * C5 - 3 / (2 * L4) * dP4xi * C4; - dnds(0, 2) = 3 / (2 * L6) * dP6xi * C6 - 3 / (2 * L5) * dP5xi * C5; - - dnds(1, 0) = 3 / (2 * L4) * dP4eta * C4 - 3 / (2 * L6) * dP6eta * C6; - dnds(1, 1) = 3 / (2 * L5) * dP5eta * C5 - 3 / (2 * L4) * dP4eta * C4; - dnds(1, 2) = 3 / (2 * L6) * dP6eta * C6 - 3 / (2 * L5) * dP5eta * C5; - break; - } - case 2: { // Nxi2'xi Nxi2'eta - dnds(0, 0) = -1 - (3. / 4.) * dP4xi * C4 * C4 - (3. / 4.) * dP6xi * C6 * C6; - dnds(0, 1) = 1 - (3. / 4.) * dP5xi * C5 * C5 - (3. / 4.) * dP4xi * C4 * C4; - dnds(0, 2) = -(3. / 4.) * dP6xi * C6 * C6 - (3. / 4.) * dP5xi * C5 * C5; - - dnds(1, 0) = - -1 - (3. / 4.) * dP4eta * C4 * C4 - (3. / 4.) * dP6eta * C6 * C6; - dnds(1, 1) = -(3. / 4.) * dP5eta * C5 * C5 - (3. / 4.) * dP4eta * C4 * C4; - dnds(1, 2) = - 1 - (3. / 4.) * dP6eta * C6 * C6 - (3. / 4.) * dP5eta * C5 * C5; - break; - } - case 3: { // Nxi3'xi Nxi3'eta - dnds(0, 0) = -(3. / 4.) * dP4xi * C4 * S4 - (3. / 4.) * dP6xi * C6 * S6; - dnds(0, 1) = -(3. / 4.) * dP5xi * C5 * S5 - (3. / 4.) * dP4xi * C4 * S4; - dnds(0, 2) = -(3. / 4.) * dP6xi * C6 * S6 - (3. / 4.) * dP5xi * C5 * S5; - - dnds(1, 0) = -(3. / 4.) * dP4eta * C4 * S4 - (3. / 4.) * dP6eta * C6 * S6; - dnds(1, 1) = -(3. / 4.) * dP5eta * C5 * S5 - (3. / 4.) * dP4eta * C4 * S4; - dnds(1, 2) = -(3. / 4.) * dP6eta * C6 * S6 - (3. / 4.) * dP5eta * C5 * S5; - break; - } - case 4: { // Nyi1'xi Nyi1'eta - dnds(0, 0) = 3 / (2 * L4) * dP4xi * S4 - 3 / (2 * L6) * dP6xi * S6; - dnds(0, 1) = 3 / (2 * L5) * dP5xi * S5 - 3 / (2 * L4) * dP4xi * S4; - dnds(0, 2) = 3 / (2 * L6) * dP6xi * S6 - 3 / (2 * L5) * dP5xi * S5; - - dnds(1, 0) = 3 / (2 * L4) * dP4eta * S4 - 3 / (2 * L6) * dP6eta * S6; - dnds(1, 1) = 3 / (2 * L5) * dP5eta * S5 - 3 / (2 * L4) * dP4eta * S4; - dnds(1, 2) = 3 / (2 * L6) * dP6eta * S6 - 3 / (2 * L5) * dP5eta * S5; - break; - } - case 5: { // Nyi2'xi Nyi2'eta - dnds(0, 0) = -(3. / 4.) * dP4xi * C4 * S4 - (3. / 4.) * dP6xi * C6 * S6; - dnds(0, 1) = -(3. / 4.) * dP5xi * C5 * S5 - (3. / 4.) * dP4xi * C4 * S4; - dnds(0, 2) = -(3. / 4.) * dP6xi * C6 * S6 - (3. / 4.) * dP5xi * C5 * S5; - - dnds(1, 0) = -(3. / 4.) * dP4eta * C4 * S4 - (3. / 4.) * dP6eta * C6 * S6; - dnds(1, 1) = -(3. / 4.) * dP5eta * C5 * S5 - (3. / 4.) * dP4eta * C4 * S4; - dnds(1, 2) = -(3. / 4.) * dP6eta * C6 * S6 - (3. / 4.) * dP5eta * C5 * S5; - break; - } - case 6: { // Nyi3'xi Nyi3'eta - dnds(0, 0) = - dN1xi - (3. / 4.) * dP4xi * S4 * S4 - (3. / 4.) * dP6xi * S6 * S6; - dnds(0, 1) = - dN2xi - (3. / 4.) * dP5xi * S5 * S5 - (3. / 4.) * dP4xi * S4 * S4; - dnds(0, 2) = - dN3xi - (3. / 4.) * dP6xi * S6 * S6 - (3. / 4.) * dP5xi * S5 * S5; - - dnds(1, 0) = - dN1eta - (3. / 4.) * dP4eta * S4 * S4 - (3. / 4.) * dP6eta * S6 * S6; - dnds(1, 1) = - dN2eta - (3. / 4.) * dP5eta * S5 * S5 - (3. / 4.) * dP4eta * S4 * S4; - dnds(1, 2) = - dN3eta - (3. / 4.) * dP6eta * S6 * S6 - (3. / 4.) * dP5eta * S5 * S5; - break; - } - } + // N'xi + auto Np00 = dN1xi; + auto Np01 = dN2xi; + auto Np02 = dN3xi; + // N'eta + auto Np10 = dN1eta; + auto Np11 = dN2eta; + auto Np12 = dN3eta; + + // Nxi1'xi + auto Nx1p00 = 3. / (2 * L4) * dP4xi * C4 - 3. / (2. * L6) * dP6xi * C6; + auto Nx1p01 = 3. / (2 * L5) * dP5xi * C5 - 3. / (2. * L4) * dP4xi * C4; + auto Nx1p02 = 3. / (2 * L6) * dP6xi * C6 - 3. / (2. * L5) * dP5xi * C5; + // Nxi1'eta + auto Nx1p10 = 3. / (2 * L4) * dP4eta * C4 - 3. / (2. * L6) * dP6eta * C6; + auto Nx1p11 = 3. / (2 * L5) * dP5eta * C5 - 3. / (2. * L4) * dP4eta * C4; + auto Nx1p12 = 3. / (2 * L6) * dP6eta * C6 - 3. / (2. * L5) * dP5eta * C5; + + // Nxi2'xi + auto Nx2p00 = -1 - (3. / 4.) * dP4xi * C4 * C4 - (3. / 4.) * dP6xi * C6 * C6; + auto Nx2p01 = 1 - (3. / 4.) * dP5xi * C5 * C5 - (3. / 4.) * dP4xi * C4 * C4; + auto Nx2p02 = -(3. / 4.) * dP6xi * C6 * C6 - (3. / 4.) * dP5xi * C5 * C5; + // Nxi2'eta + auto Nx2p10 = + -1 - (3. / 4.) * dP4eta * C4 * C4 - (3. / 4.) * dP6eta * C6 * C6; + auto Nx2p11 = -(3. / 4.) * dP5eta * C5 * C5 - (3. / 4.) * dP4eta * C4 * C4; + auto Nx2p12 = 1 - (3. / 4.) * dP6eta * C6 * C6 - (3. / 4.) * dP5eta * C5 * C5; + + // Nxi3'xi + auto Nx3p00 = -(3. / 4.) * dP4xi * C4 * S4 - (3. / 4.) * dP6xi * C6 * S6; + auto Nx3p01 = -(3. / 4.) * dP5xi * C5 * S5 - (3. / 4.) * dP4xi * C4 * S4; + auto Nx3p02 = -(3. / 4.) * dP6xi * C6 * S6 - (3. / 4.) * dP5xi * C5 * S5; + // Nxi3'eta + auto Nx3p10 = -(3. / 4.) * dP4eta * C4 * S4 - (3. / 4.) * dP6eta * C6 * S6; + auto Nx3p11 = -(3. / 4.) * dP5eta * C5 * S5 - (3. / 4.) * dP4eta * C4 * S4; + auto Nx3p12 = -(3. / 4.) * dP6eta * C6 * S6 - (3. / 4.) * dP5eta * C5 * S5; + + // Nyi1'xi + auto Ny1p00 = 3 / (2 * L4) * dP4xi * S4 - 3 / (2 * L6) * dP6xi * S6; + auto Ny1p01 = 3 / (2 * L5) * dP5xi * S5 - 3 / (2 * L4) * dP4xi * S4; + auto Ny1p02 = 3 / (2 * L6) * dP6xi * S6 - 3 / (2 * L5) * dP5xi * S5; + // Nyi1'eta + auto Ny1p10 = 3 / (2 * L4) * dP4eta * S4 - 3 / (2 * L6) * dP6eta * S6; + auto Ny1p11 = 3 / (2 * L5) * dP5eta * S5 - 3 / (2 * L4) * dP4eta * S4; + auto Ny1p12 = 3 / (2 * L6) * dP6eta * S6 - 3 / (2 * L5) * dP5eta * S5; + + // Nyi2'xi + auto Ny2p00 = -(3. / 4.) * dP4xi * C4 * S4 - (3. / 4.) * dP6xi * C6 * S6; + auto Ny2p01 = -(3. / 4.) * dP5xi * C5 * S5 - (3. / 4.) * dP4xi * C4 * S4; + auto Ny2p02 = -(3. / 4.) * dP6xi * C6 * S6 - (3. / 4.) * dP5xi * C5 * S5; + // Nyi2'eta + auto Ny2p10 = -(3. / 4.) * dP4eta * C4 * S4 - (3. / 4.) * dP6eta * C6 * S6; + auto Ny2p11 = -(3. / 4.) * dP5eta * C5 * S5 - (3. / 4.) * dP4eta * C4 * S4; + auto Ny2p12 = -(3. / 4.) * dP6eta * C6 * S6 - (3. / 4.) * dP5eta * C5 * S5; + + // Nyi3'xi + auto Ny3p00 = + dN1xi - (3. / 4.) * dP4xi * S4 * S4 - (3. / 4.) * dP6xi * S6 * S6; + auto Ny3p01 = + dN2xi - (3. / 4.) * dP5xi * S5 * S5 - (3. / 4.) * dP4xi * S4 * S4; + auto Ny3p02 = + dN3xi - (3. / 4.) * dP6xi * S6 * S6 - (3. / 4.) * dP5xi * S5 * S5; + // Nyi3'eta + auto Ny3p10 = + dN1eta - (3. / 4.) * dP4eta * S4 * S4 - (3. / 4.) * dP6eta * S6 * S6; + auto Ny3p11 = + dN2eta - (3. / 4.) * dP5eta * S5 * S5 - (3. / 4.) * dP4eta * S4 * S4; + auto Ny3p12 = + dN3eta - (3. / 4.) * dP6eta * S6 * S6 - (3. / 4.) * dP5eta * S5 * S5; + + // clang-format off + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + B = {{Np00, 0., 0., 0., 0., 0., Np01, 0., 0., 0., 0., 0., Np02, 0., 0., 0., 0., 0.}, // 0 + { 0., Np10, 0., 0., 0., 0., 0., Np11, 0., 0., 0., 0., 0., Np12, 0., 0., 0., 0.}, // 1 + {Np10, Np00, 0., 0., 0., 0., Np11, Np01, 0., 0., 0., 0., Np12, Np02, 0., 0., 0., 0.}, // 2 + { 0., 0., Nx1p00, Nx2p00, Nx3p00, 0., 0., 0., Nx1p01, Nx2p01, Nx3p01, 0., 0., 0., Nx1p02, Nx2p02, Nx3p02, 0.}, // 3 + { 0., 0., Ny1p10, Ny2p10, Ny3p10, 0., 0., 0., Ny1p11, Ny2p11, Ny3p11, 0., 0., 0., Ny1p12, Ny2p12, Ny3p12, 0.}, // 4 + { 0., 0., Nx1p10 + Ny1p00, Nx2p10 + Ny2p00, Nx3p10 + Ny3p00, 0., 0., 0., Nx1p11 + Ny1p01, Nx2p11 + Ny2p01, Nx3p11 + Ny3p01, 0., 0., 0., Nx1p12 + Ny1p02, Nx2p12 + Ny2p02, Nx3p12 + Ny3p02, 0.}}; // 5 + // clang-format on +} + + +/* -------------------------------------------------------------------------- */ +template <> +inline void ElementClass<_kirchhoff_shell,_ek_structural>::computeShapeDerivatives( + const Matrix<Real> & /*natural_coord*/, Tensor3<Real> & /*shape_deriv*/, + const Matrix<Real> & /*real_nodal_coord*/) { + + /// TO BE CONTINUED and moved in a _tmpl.hh + //UInt spatial_dimension = real_nodal_coord.cols(); +// UInt nb_nodes = real_nodal_coord.rows(); + +// const UInt projected_dim = natural_coord.rows(); +// Matrix<Real> rotation_matrix(real_nodal_coord); +// Matrix<Real> rotated_nodal_coord(real_nodal_coord); +// Matrix<Real> projected_nodal_coord(natural_coord); +// /* ------------------------------------------------------------------------ */ +// Matrix<Real> Pe(real_nodal_coord); +// Matrix<Real> Pg(real_nodal_coord); +// Matrix<Real> inv_Pg(real_nodal_coord); + +// /// compute matrix Pe +// Pe.eye(); + +// // /// compute matrix Pg +// // Pg(0) = real_nodal_coord(1) - real_nodal_coord(0); +// // Pg(1) = real_nodal_coord(2) - real_nodal_coord(0); +// // Pg(2).crossProduct(Pg(0), Pg(1)); + +// // /// compute inverse of Pg +// // inv_Pg.inverse(Pg); + +// /// compute rotation matrix +// // rotation_matrix=Pe*inv_Pg; +// rotation_matrix.eye(); + +// /* ------------------------------------------------------------------------ */ +// rotated_nodal_coord.mul<false, false>(rotation_matrix, real_nodal_coord); + +// UInt nb_points = shape_deriv.size(2); + +// for (UInt i = 0; i < projected_dim; ++i) { +// for (UInt j = 0; j < nb_points; ++j) { +// projected_nodal_coord(i, j) = rotated_nodal_coord(i, j); +// } +// } + +// Tensor3<Real> dnds(projected_dim, nb_nodes, natural_coord.cols()); +// Tensor3<Real> J(projected_dim, projected_dim, natural_coord.cols()); + +// parent_element::computeDNDS(natural_coord, dnds); +// parent_element::computeJMat(dnds, projected_nodal_coord, J); + +// for (UInt p = 0; p < nb_points; ++p) { +// Matrix<Real> shape_deriv_p = shape_deriv(p); + +// interpolation_element::computeDNDS(natural_coord(p), shape_deriv_p, +// projected_nodal_coord); + +// Matrix<Real> dNdS = shape_deriv_p; +// Matrix<Real> inv_J(projected_dim, projected_dim); +// inv_J.inverse(J(p)); +// shape_deriv_p.mul<false, false>(inv_J, dNdS); +// } } + +} // akantu + +#endif /* __AKANTU_ELEMENT_CLASS_KIRCHHOFF_SHELL_INLINE_IMPL_CC__ */ diff --git a/src/fe_engine/fe_engine_template_tmpl_struct.hh b/src/fe_engine/fe_engine_template_tmpl_struct.hh index 3f1396218..8ffdd516f 100644 --- a/src/fe_engine/fe_engine_template_tmpl_struct.hh +++ b/src/fe_engine/fe_engine_template_tmpl_struct.hh @@ -1,246 +1,101 @@ /** * @file fe_engine_template_tmpl_struct.hh * * @author Fabian Barras <fabian.barras@epfl.ch> * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date creation: Mon Jul 07 2014 * @date last modification: Thu Oct 15 2015 * * @brief Template implementation of FEEngineTemplate for Structural Element * Kinds * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ -#include "shape_linked.hh" +#include "shape_structural.hh" namespace akantu { -/* -------------------------------------------------------------------------- */ -template <> -inline const Array<Real> & -FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural, - DefaultIntegrationOrderFunctor>:: - getShapesDerivatives(const ElementType & type, const GhostType & ghost_type, - UInt id) const { - - AKANTU_DEBUG_IN(); - const Array<Real> * ret = NULL; - -#define GET_SHAPES(type) \ - ret = &(shape_functions.getShapesDerivatives(type, ghost_type, id)); - - AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_SHAPES); -#undef GET_SHAPES - - AKANTU_DEBUG_OUT(); - return *ret; -} - -/* -------------------------------------------------------------------------- */ -template <> -inline const Array<Real> & FEEngineTemplate< - IntegratorGauss, ShapeLinked, _ek_structural, - DefaultIntegrationOrderFunctor>::getShapes(const ElementType & type, - const GhostType & ghost_type, - UInt id) const { - AKANTU_DEBUG_IN(); - const Array<Real> * ret = NULL; - -#define GET_SHAPES(type) \ - ret = &(shape_functions.getShapes(type, ghost_type, id)); - - AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_SHAPES); -#undef GET_SHAPES - - AKANTU_DEBUG_OUT(); - return *ret; -} - /* -------------------------------------------------------------------------- */ template <ElementKind kind, typename = void> struct AssembleFieldMatrixStructHelper {}; template <ElementKind kind> struct AssembleFieldMatrixStructHelper< kind, typename std::enable_if<kind == _ek_structural>::type> { template <template <ElementKind, class> class I, template <ElementKind> class S, ElementKind k, class IOF> static void call(const FEEngineTemplate<I, S, k, IOF> & fem, const Array<Real> & field_1, UInt nb_degree_of_freedom, SparseMatrix & M, Array<Real> * n, ElementTypeMapArray<Real> & rotation_mat, const ElementType & type, const GhostType & ghost_type) { #define ASSEMBLE_MATRIX(type) \ fem.template assembleFieldMatrix<type>(field_1, nb_degree_of_freedom, M, n, \ rotation_mat, ghost_type) AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_MATRIX, _ek_structural); #undef ASSEMBLE_MATRIX } }; template <template <ElementKind, class> class I, template <ElementKind> class S, ElementKind kind, class IntegrationOrderFunctor> inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldMatrix( const Array<Real> & field_1, UInt nb_degree_of_freedom, SparseMatrix & M, Array<Real> * n, ElementTypeMapArray<Real> & rotation_mat, const ElementType & type, const GhostType & ghost_type) const { AKANTU_DEBUG_IN(); AssembleFieldMatrixStructHelper<kind>::template call( *this, field_1, nb_degree_of_freedom, M, n, rotation_mat, type, ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template <template <ElementKind, class> class I, template <ElementKind> class S, ElementKind kind, class IntegrationOrderFunctor> inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeShapesMatrix( const ElementType &, UInt, UInt, Array<Real> *, - __attribute__((unused)) UInt, UInt, UInt, const bool, + UInt, UInt, UInt, const bool, const GhostType &) const { AKANTU_DEBUG_TO_IMPLEMENT(); } -/* -------------------------------------------------------------------------- */ -template <> -inline void FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural, - DefaultIntegrationOrderFunctor>:: - computeShapesMatrix(const ElementType & type, UInt nb_degree_of_freedom, - UInt nb_nodes_per_element, Array<Real> * n, UInt id, - UInt degree_to_interpolate, UInt degree_interpolated, - const bool sign, // true +, false - - const GhostType & ghost_type) const { - AKANTU_DEBUG_IN(); - - UInt nb_element = mesh.getNbElement(type); - UInt nb_quadrature_points = getNbIntegrationPoints(type); - - UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element; - UInt n_size = n->getNbComponent() / nt_n_field_size; - - Array<Real>::const_vector_iterator shape = - getShapes(type, ghost_type, id).begin(nb_nodes_per_element); - Array<Real>::matrix_iterator N_it = n->begin(n_size, nt_n_field_size); - - int c; - if (sign == true) { - c = 1; - } else { - c = -1; - } - - UInt line = degree_interpolated; - UInt coll = degree_to_interpolate; - - for (UInt e = 0; e < nb_element; ++e) { - for (UInt q = 0; q < nb_quadrature_points; ++q, ++N_it, ++shape) { - const Vector<Real> & shapes = *shape; - Matrix<Real> & N = *N_it; - N(line, coll) = shapes(0) * c; - N(line, coll + nb_degree_of_freedom) = shapes(1) * c; - } - } - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template <> -template <ElementType type> -inline void FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural, - DefaultIntegrationOrderFunctor>:: - assembleFieldMatrix(const Array<Real> & field_1, UInt nb_degree_of_freedom, - SparseMatrix & M, Array<Real> * n, - ElementTypeMapArray<Real> & rotation_mat, - const GhostType & ghost_type) const { - AKANTU_DEBUG_IN(); - - UInt nb_element = mesh.getNbElement(type); - UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type); - UInt nb_quadrature_points = getNbIntegrationPoints(type); - - UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element; - UInt n_size = n->getNbComponent() / nt_n_field_size; - - Array<Real> * nt_n_field = new Array<Real>( - nb_element * nb_quadrature_points, // nt_n_size * nt_n_size, nb_elem * - // nb_quad_points? - nt_n_field_size * nt_n_field_size, "NT*N*field"); - Array<Real> * nt = new Array<Real>(nb_element * nb_quadrature_points, - n_size * nt_n_field_size, "N*T"); - Array<Real> t = rotation_mat(type); - nt_n_field->clear(); - nt->clear(); - - Array<Real>::matrix_iterator N = n->begin(n_size, nt_n_field_size); - Array<Real>::matrix_iterator Nt_N_field = - nt_n_field->begin(nt_n_field_size, nt_n_field_size); - Array<Real>::matrix_iterator T = - rotation_mat(type).begin(nt_n_field_size, nt_n_field_size); - Array<Real>::matrix_iterator NT = nt->begin(n_size, nt_n_field_size); - Real * field_val = field_1.storage(); - - for (UInt e = 0; e < nb_element; ++e, ++T) { - for (UInt q = 0; q < nb_quadrature_points; - ++q, ++N, ++NT, ++Nt_N_field, /*++T,*/ ++field_val) { - NT->mul<false, false>(*N, *T); - Nt_N_field->mul<true, false>(*NT, *NT, *field_val); - } - } - - Array<Real> * int_nt_n_field = new Array<Real>( - nb_element, nt_n_field_size * nt_n_field_size, "NT*N*field"); - int_nt_n_field->clear(); - - integrate(*nt_n_field, *int_nt_n_field, nt_n_field_size * nt_n_field_size, - type); - // integrate(*nt_n_field, *int_nt_n_field, nb_degree_of_freedom, type); - - assembleMatrix(*int_nt_n_field, M, nb_degree_of_freedom, type); - - delete nt; - delete nt_n_field; - delete int_nt_n_field; - - AKANTU_DEBUG_OUT(); -} - /* -------------------------------------------------------------------------- */ template <template <ElementKind, class> class I, template <ElementKind> class S, ElementKind kind, class IntegrationOrderFunctor> template <ElementType type> inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldMatrix( - const Array<Real> & field_1, UInt nb_degree_of_freedom, SparseMatrix & M, - Array<Real> * n, ElementTypeMapArray<Real> & rotation_mat, - const GhostType & ghost_type) const { + const Array<Real> & , UInt , SparseMatrix &, + Array<Real> * , ElementTypeMapArray<Real> & , + const GhostType & ) const { AKANTU_DEBUG_TO_IMPLEMENT(); } } // akantu diff --git a/src/fe_engine/interpolation_element.cc b/src/fe_engine/interpolation_element.cc index cf5b90ed8..0cc6d7d54 100644 --- a/src/fe_engine/interpolation_element.cc +++ b/src/fe_engine/interpolation_element.cc @@ -1,48 +1,44 @@ /** * @file interpolation_element.cc * * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date creation: Thu Feb 21 2013 * @date last modification: Sun Oct 19 2014 * * @brief Common part of element_classes * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "element_class.hh" /* -------------------------------------------------------------------------- */ namespace akantu { /* -------------------------------------------------------------------------- */ /* Structural elements */ /* -------------------------------------------------------------------------- */ #if defined(AKANTU_STRUCTURAL_MECHANICS) -template<> const UInt InterpolationElement<_itp_bernoulli_beam>::nb_shape_functions = 5; -template<> const UInt InterpolationElement<_itp_kirchhoff_shell>::nb_shape_functions = 9; -template<> const UInt InterpolationElement<_itp_bernoulli_beam>::nb_shape_derivatives = 3; -template<> const UInt InterpolationElement<_itp_kirchhoff_shell>::nb_shape_derivatives = 7; #endif } // akantu diff --git a/src/fe_engine/shape_functions.cc b/src/fe_engine/shape_functions.cc index 3bb25cffd..15d67f780 100644 --- a/src/fe_engine/shape_functions.cc +++ b/src/fe_engine/shape_functions.cc @@ -1,238 +1,243 @@ /** * @file shape_functions.cc * * @author Nicolas Richart * * @date creation Thu Jul 27 2017 * * @brief implementation of th shape functions interface * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "shape_functions.hh" /* -------------------------------------------------------------------------- */ namespace akantu { /* -------------------------------------------------------------------------- */ +ShapeFunctions::ShapeFunctions(const Mesh & mesh, const ID & id, + const MemoryID & memory_id) + : Memory(id, memory_id), shapes("shapes_generic", id, memory_id), + shapes_derivatives("shapes_derivatives_generic", id, memory_id), + mesh(mesh) {} + /* -------------------------------------------------------------------------- */ template <ElementType type> inline void ShapeFunctions::initElementalFieldInterpolationFromIntegrationPoints( const Array<Real> & interpolation_points_coordinates, ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices, ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices, - const Array<Real> & quadrature_points_coordinates, const GhostType & ghost_type, - const Array<UInt> & element_filter) const { + const Array<Real> & quadrature_points_coordinates, + const GhostType & ghost_type, const Array<UInt> & element_filter) const { AKANTU_DEBUG_IN(); UInt spatial_dimension = this->mesh.getSpatialDimension(); UInt nb_element = this->mesh.getNbElement(type, ghost_type); UInt nb_element_filter; if (element_filter == empty_filter) nb_element_filter = nb_element; else nb_element_filter = element_filter.size(); UInt nb_quad_per_element = GaussIntegrationElement<type>::getNbQuadraturePoints(); UInt nb_interpolation_points_per_elem = interpolation_points_coordinates.size() / nb_element; - AKANTU_DEBUG_ASSERT(interpolation_points_coordinates.size() % nb_element == - 0, + AKANTU_DEBUG_ASSERT(interpolation_points_coordinates.size() % nb_element == 0, "Number of interpolation points should be a multiple of " "total number of elements"); if (!quad_points_coordinates_inv_matrices.exists(type, ghost_type)) quad_points_coordinates_inv_matrices.alloc( nb_element_filter, nb_quad_per_element * nb_quad_per_element, type, ghost_type); else quad_points_coordinates_inv_matrices(type, ghost_type) .resize(nb_element_filter); if (!interpolation_points_coordinates_matrices.exists(type, ghost_type)) interpolation_points_coordinates_matrices.alloc( nb_element_filter, nb_interpolation_points_per_elem * nb_quad_per_element, type, ghost_type); else interpolation_points_coordinates_matrices(type, ghost_type) .resize(nb_element_filter); Array<Real> & quad_inv_mat = quad_points_coordinates_inv_matrices(type, ghost_type); Array<Real> & interp_points_mat = interpolation_points_coordinates_matrices(type, ghost_type); Matrix<Real> quad_coord_matrix(nb_quad_per_element, nb_quad_per_element); Array<Real>::const_matrix_iterator quad_coords_it = quadrature_points_coordinates.begin_reinterpret( spatial_dimension, nb_quad_per_element, nb_element_filter); Array<Real>::const_matrix_iterator points_coords_begin = interpolation_points_coordinates.begin_reinterpret( spatial_dimension, nb_interpolation_points_per_elem, nb_element); Array<Real>::matrix_iterator inv_quad_coord_it = quad_inv_mat.begin(nb_quad_per_element, nb_quad_per_element); Array<Real>::matrix_iterator int_points_mat_it = interp_points_mat.begin( nb_interpolation_points_per_elem, nb_quad_per_element); /// loop over the elements of the current material and element type for (UInt el = 0; el < nb_element_filter; ++el, ++inv_quad_coord_it, ++int_points_mat_it, ++quad_coords_it) { /// matrix containing the quadrature points coordinates const Matrix<Real> & quad_coords = *quad_coords_it; /// matrix to store the matrix inversion result Matrix<Real> & inv_quad_coord_matrix = *inv_quad_coord_it; /// insert the quad coordinates in a matrix compatible with the /// interpolation buildElementalFieldInterpolationMatrix<type>(quad_coords, quad_coord_matrix); /// invert the interpolation matrix inv_quad_coord_matrix.inverse(quad_coord_matrix); /// matrix containing the interpolation points coordinates const Matrix<Real> & points_coords = points_coords_begin[element_filter(el)]; /// matrix to store the interpolation points coordinates /// compatible with these functions Matrix<Real> & inv_points_coord_matrix = *int_points_mat_it; /// insert the quad coordinates in a matrix compatible with the /// interpolation buildElementalFieldInterpolationMatrix<type>(points_coords, inv_points_coord_matrix); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void ShapeFunctions::initElementalFieldInterpolationFromIntegrationPoints( const ElementTypeMapArray<Real> & interpolation_points_coordinates, ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices, ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices, const ElementTypeMapArray<Real> & quadrature_points_coordinates, const ElementTypeMapArray<UInt> * element_filter) const { AKANTU_DEBUG_IN(); UInt spatial_dimension = this->mesh.getSpatialDimension(); for (auto ghost_type : ghost_types) { Mesh::type_iterator it, last; if (element_filter) { it = element_filter->firstType(spatial_dimension, ghost_type); last = element_filter->lastType(spatial_dimension, ghost_type); } else { it = mesh.firstType(spatial_dimension, ghost_type); last = mesh.lastType(spatial_dimension, ghost_type); } for (; it != last; ++it) { ElementType type = *it; UInt nb_element = mesh.getNbElement(type, ghost_type); if (nb_element == 0) continue; const Array<UInt> * elem_filter; if (element_filter) elem_filter = &((*element_filter)(type, ghost_type)); else elem_filter = &(empty_filter); #define AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS(type) \ this->initElementalFieldInterpolationFromIntegrationPoints<type>( \ interpolation_points_coordinates(type, ghost_type), \ interpolation_points_coordinates_matrices, \ quad_points_coordinates_inv_matrices, \ quadrature_points_coordinates(type, ghost_type), ghost_type, \ *elem_filter) AKANTU_BOOST_REGULAR_ELEMENT_SWITCH( AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS); #undef AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void ShapeFunctions::interpolateElementalFieldFromIntegrationPoints( const ElementTypeMapArray<Real> & field, const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices, const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices, ElementTypeMapArray<Real> & result, const GhostType & ghost_type, const ElementTypeMapArray<UInt> * element_filter) const { AKANTU_DEBUG_IN(); UInt spatial_dimension = this->mesh.getSpatialDimension(); Mesh::type_iterator it, last; if (element_filter) { it = element_filter->firstType(spatial_dimension, ghost_type); last = element_filter->lastType(spatial_dimension, ghost_type); } else { it = mesh.firstType(spatial_dimension, ghost_type); last = mesh.lastType(spatial_dimension, ghost_type); } for (; it != last; ++it) { ElementType type = *it; UInt nb_element = mesh.getNbElement(type, ghost_type); if (nb_element == 0) continue; const Array<UInt> * elem_filter; if (element_filter) elem_filter = &((*element_filter)(type, ghost_type)); else elem_filter = &(empty_filter); #define AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS(type) \ interpolateElementalFieldFromIntegrationPoints<type>( \ field(type, ghost_type), \ interpolation_points_coordinates_matrices(type, ghost_type), \ quad_points_coordinates_inv_matrices(type, ghost_type), result, \ ghost_type, *elem_filter) AKANTU_BOOST_REGULAR_ELEMENT_SWITCH( AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS); #undef AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS } AKANTU_DEBUG_OUT(); } } // namespace akantu diff --git a/src/fe_engine/shape_functions.hh b/src/fe_engine/shape_functions.hh index 9158ec11c..4459fbb2b 100644 --- a/src/fe_engine/shape_functions.hh +++ b/src/fe_engine/shape_functions.hh @@ -1,191 +1,213 @@ /** * @file shape_functions.hh * * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date creation: Fri Jun 18 2010 * @date last modification: Thu Oct 22 2015 * * @brief shape function class * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "aka_memory.hh" #include "mesh.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_SHAPE_FUNCTIONS_HH__ #define __AKANTU_SHAPE_FUNCTIONS_HH__ namespace akantu { /* -------------------------------------------------------------------------- */ class ShapeFunctions : protected Memory { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: ShapeFunctions(const Mesh & mesh, const ID & id = "shape", - const MemoryID & memory_id = 0) - : Memory(id, memory_id), mesh(mesh){}; - virtual ~ShapeFunctions(){}; + const MemoryID & memory_id = 0); + virtual ~ShapeFunctions() = default; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const { std::string space; for (Int i = 0; i < indent; i++, space += AKANTU_INDENT) ; stream << space << "Shapes [" << std::endl; integration_points.printself(stream, indent + 1); stream << space << "]" << std::endl; }; /// set the integration points for a given element template <ElementType type> void setIntegrationPointsByType(const Matrix<Real> & integration_points, const GhostType & ghost_type); /// Build pre-computed matrices for interpolation of field form integration /// points at other given positions (interpolation_points) void initElementalFieldInterpolationFromIntegrationPoints( const ElementTypeMapArray<Real> & interpolation_points_coordinates, ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices, ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices, const ElementTypeMapArray<Real> & quadrature_points_coordinates, const ElementTypeMapArray<UInt> * element_filter) const; /// Interpolate field at given position from given values of this field at /// integration points (field) /// using matrices precomputed with /// initElementalFieldInterplationFromIntegrationPoints void interpolateElementalFieldFromIntegrationPoints( const ElementTypeMapArray<Real> & field, const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices, const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices, ElementTypeMapArray<Real> & result, const GhostType & ghost_type, const ElementTypeMapArray<UInt> * element_filter) const; protected: /// interpolate nodal values stored by element on the integration points template <ElementType type> void interpolateElementalFieldOnIntegrationPoints( const Array<Real> & u_el, Array<Real> & uq, const GhostType & ghost_type, const Array<Real> & shapes, const Array<UInt> & filter_elements = empty_filter) const; /// gradient of nodal values stored by element on the control points template <ElementType type> void gradientElementalFieldOnIntegrationPoints( const Array<Real> & u_el, Array<Real> & out_nablauq, const GhostType & ghost_type, const Array<Real> & shapes_derivatives, const Array<UInt> & filter_elements) const; protected: /// By element versions of non-templated eponym methods template <ElementType type> inline void interpolateElementalFieldFromIntegrationPoints( const Array<Real> & field, const Array<Real> & interpolation_points_coordinates_matrices, const Array<Real> & quad_points_coordinates_inv_matrices, ElementTypeMapArray<Real> & result, const GhostType & ghost_type, const Array<UInt> & element_filter) const; /// Interpolate field at given position from given values of this field at /// integration points (field) /// using matrices precomputed with /// initElementalFieldInterplationFromIntegrationPoints template <ElementType type> inline void initElementalFieldInterpolationFromIntegrationPoints( const Array<Real> & interpolation_points_coordinates, ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices, ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices, const Array<Real> & quadrature_points_coordinates, const GhostType & ghost_type, const Array<UInt> & element_filter) const; /// build matrix for the interpolation of field form integration points template <ElementType type> inline void buildElementalFieldInterpolationMatrix( const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order = ElementClassProperty<type>::polynomial_degree) const; /// build the so called interpolation matrix (first collumn is 1, then the /// other collumns are the traansposed coordinates) inline void buildInterpolationMatrix(const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const; public: - virtual void onElementsAdded(const Array<Element> & elements) = 0; - virtual void - onElementsRemoved(const Array<Element> & elements, - const ElementTypeMapArray<UInt> & new_numbering) = 0; + virtual void onElementsAdded(const Array<Element> &) { + AKANTU_DEBUG_TO_IMPLEMENT(); + } + virtual void onElementsRemoved(const Array<Element> &, + const ElementTypeMapArray<UInt> &) { + AKANTU_DEBUG_TO_IMPLEMENT(); + } /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// get the size of the shapes returned by the element class static inline UInt getShapeSize(const ElementType & type); /// get the size of the shapes derivatives returned by the element class static inline UInt getShapeDerivativesSize(const ElementType & type); inline const Matrix<Real> & getIntegrationPoints(const ElementType & type, const GhostType & ghost_type) const { return integration_points(type, ghost_type); } + /* ------------------------------------------------------------------------ */ + /* Accessors */ + /* ------------------------------------------------------------------------ */ +public: + /// get a the shapes vector + inline const Array<Real> & + getShapes(const ElementType & el_type, + const GhostType & ghost_type = _not_ghost) const; + + /// get a the shapes derivatives vector + inline const Array<Real> & + getShapesDerivatives(const ElementType & el_type, + const GhostType & ghost_type = _not_ghost) const; + /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: + /// shape functions for all elements + ElementTypeMapArray<Real, InterpolationType> shapes; + + /// shape functions derivatives for all elements + ElementTypeMapArray<Real, InterpolationType> shapes_derivatives; + /// associated mesh const Mesh & mesh; /// shape functions for all elements ElementTypeMap<Matrix<Real>> integration_points; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ /// standard output stream operator inline std::ostream & operator<<(std::ostream & stream, const ShapeFunctions & _this) { _this.printself(stream); return stream; } } // namespace akantu #include "shape_functions_inline_impl.cc" #endif /* __AKANTU_SHAPE_FUNCTIONS_HH__ */ diff --git a/src/fe_engine/shape_functions_inline_impl.cc b/src/fe_engine/shape_functions_inline_impl.cc index 031f8060c..4b4a8ac43 100644 --- a/src/fe_engine/shape_functions_inline_impl.cc +++ b/src/fe_engine/shape_functions_inline_impl.cc @@ -1,393 +1,398 @@ /** * @file shape_functions_inline_impl.cc * * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch> * @author Fabian Barras <fabian.barras@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * @author Marco Vocialta <marco.vocialta@epfl.ch> * * @date creation: Wed Oct 27 2010 * @date last modification: Thu Oct 15 2015 * * @brief ShapeFunctions inline implementation * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "fe_engine.hh" #include "shape_functions.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_CC__ #define __AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_CC__ namespace akantu { +/* -------------------------------------------------------------------------- */ +inline const Array<Real> & +ShapeFunctions::getShapes(const ElementType & el_type, + const GhostType & ghost_type) const { + return shapes(FEEngine::getInterpolationType(el_type), ghost_type); +} + +/* -------------------------------------------------------------------------- */ +inline const Array<Real> & +ShapeFunctions::getShapesDerivatives(const ElementType & el_type, + const GhostType & ghost_type) const { + return shapes_derivatives(FEEngine::getInterpolationType(el_type), + ghost_type); +} + /* -------------------------------------------------------------------------- */ inline UInt ShapeFunctions::getShapeSize(const ElementType & type) { AKANTU_DEBUG_IN(); UInt shape_size = 0; #define GET_SHAPE_SIZE(type) shape_size = ElementClass<type>::getShapeSize() AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_SIZE); // , #undef GET_SHAPE_SIZE AKANTU_DEBUG_OUT(); return shape_size; } /* -------------------------------------------------------------------------- */ inline UInt ShapeFunctions::getShapeDerivativesSize(const ElementType & type) { AKANTU_DEBUG_IN(); UInt shape_derivatives_size = 0; #define GET_SHAPE_DERIVATIVES_SIZE(type) \ shape_derivatives_size = ElementClass<type>::getShapeDerivativesSize() AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_DERIVATIVES_SIZE); // , #undef GET_SHAPE_DERIVATIVES_SIZE AKANTU_DEBUG_OUT(); return shape_derivatives_size; } /* -------------------------------------------------------------------------- */ template <ElementType type> void ShapeFunctions::setIntegrationPointsByType(const Matrix<Real> & points, const GhostType & ghost_type) { if (not this->integration_points.exists(type, ghost_type)) this->integration_points(type, ghost_type).shallowCopy(points); } /* -------------------------------------------------------------------------- */ inline void ShapeFunctions::buildInterpolationMatrix(const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const { switch (integration_order) { case 1: { for (UInt i = 0; i < coordinates.cols(); ++i) coordMatrix(i, 0) = 1; break; } case 2: { UInt nb_quadrature_points = coordMatrix.cols(); for (UInt i = 0; i < coordinates.cols(); ++i) { coordMatrix(i, 0) = 1; for (UInt j = 1; j < nb_quadrature_points; ++j) coordMatrix(i, j) = coordinates(j - 1, i); } break; } default: { AKANTU_DEBUG_TO_IMPLEMENT(); break; } } } /* -------------------------------------------------------------------------- */ template <ElementType type> inline void ShapeFunctions::buildElementalFieldInterpolationMatrix( const Matrix<Real> &, Matrix<Real> &, UInt) const { AKANTU_DEBUG_TO_IMPLEMENT(); } /* -------------------------------------------------------------------------- */ template <> inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_2>( const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const { buildInterpolationMatrix(coordinates, coordMatrix, integration_order); } /* -------------------------------------------------------------------------- */ template <> inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_3>( const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const { buildInterpolationMatrix(coordinates, coordMatrix, integration_order); } /* -------------------------------------------------------------------------- */ template <> inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_3>( const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const { buildInterpolationMatrix(coordinates, coordMatrix, integration_order); } /* -------------------------------------------------------------------------- */ template <> inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_6>( const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const { buildInterpolationMatrix(coordinates, coordMatrix, integration_order); } /* -------------------------------------------------------------------------- */ template <> inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_4>( const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const { buildInterpolationMatrix(coordinates, coordMatrix, integration_order); } /* -------------------------------------------------------------------------- */ template <> inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_10>( const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const { buildInterpolationMatrix(coordinates, coordMatrix, integration_order); } /** * @todo Write a more efficient interpolation for quadrangles by * dropping unnecessary quadrature points * */ /* -------------------------------------------------------------------------- */ template <> inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_4>( const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const { if (integration_order != ElementClassProperty<_quadrangle_4>::polynomial_degree) { AKANTU_DEBUG_TO_IMPLEMENT(); } else { for (UInt i = 0; i < coordinates.cols(); ++i) { Real x = coordinates(0, i); Real y = coordinates(1, i); coordMatrix(i, 0) = 1; coordMatrix(i, 1) = x; coordMatrix(i, 2) = y; coordMatrix(i, 3) = x * y; } } } /* -------------------------------------------------------------------------- */ template <> inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_8>( const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix, UInt integration_order) const { if (integration_order != ElementClassProperty<_quadrangle_8>::polynomial_degree) { AKANTU_DEBUG_TO_IMPLEMENT(); } else { for (UInt i = 0; i < coordinates.cols(); ++i) { UInt j = 0; Real x = coordinates(0, i); Real y = coordinates(1, i); for (UInt e = 0; e <= 2; ++e) { for (UInt n = 0; n <= 2; ++n) { coordMatrix(i, j) = std::pow(x, e) * std::pow(y, n); ++j; } } } } } /* -------------------------------------------------------------------------- */ template <ElementType type> inline void ShapeFunctions::interpolateElementalFieldFromIntegrationPoints( const Array<Real> & field, const Array<Real> & interpolation_points_coordinates_matrices, const Array<Real> & quad_points_coordinates_inv_matrices, ElementTypeMapArray<Real> & result, const GhostType & ghost_type, const Array<UInt> & element_filter) const { AKANTU_DEBUG_IN(); - UInt nb_element = this->mesh.getNbElement(type, ghost_type); + auto nb_element = this->mesh.getNbElement(type, ghost_type); - UInt nb_quad_per_element = + auto nb_quad_per_element = GaussIntegrationElement<type>::getNbQuadraturePoints(); - UInt nb_interpolation_points_per_elem = + auto nb_interpolation_points_per_elem = interpolation_points_coordinates_matrices.getNbComponent() / nb_quad_per_element; if (!result.exists(type, ghost_type)) result.alloc(nb_element * nb_interpolation_points_per_elem, field.getNbComponent(), type, ghost_type); if (element_filter != empty_filter) nb_element = element_filter.size(); Matrix<Real> coefficients(nb_quad_per_element, field.getNbComponent()); - Array<Real> & result_vec = result(type, ghost_type); + auto & result_vec = result(type, ghost_type); - Array<Real>::const_matrix_iterator field_it = field.begin_reinterpret( - field.getNbComponent(), nb_quad_per_element, nb_element); + auto field_it = field.begin_reinterpret(field.getNbComponent(), + nb_quad_per_element, nb_element); - Array<Real>::const_matrix_iterator interpolation_points_coordinates_it = + auto interpolation_points_coordinates_it = interpolation_points_coordinates_matrices.begin( nb_interpolation_points_per_elem, nb_quad_per_element); - Array<Real>::matrix_iterator result_begin = result_vec.begin_reinterpret( + auto result_begin = result_vec.begin_reinterpret( field.getNbComponent(), nb_interpolation_points_per_elem, result_vec.size() / nb_interpolation_points_per_elem); - Array<Real>::const_matrix_iterator inv_quad_coord_it = - quad_points_coordinates_inv_matrices.begin(nb_quad_per_element, - nb_quad_per_element); + auto inv_quad_coord_it = quad_points_coordinates_inv_matrices.begin( + nb_quad_per_element, nb_quad_per_element); /// loop over the elements of the current filter and element type for (UInt el = 0; el < nb_element; ++el, ++field_it, ++inv_quad_coord_it, ++interpolation_points_coordinates_it) { /** * matrix containing the inversion of the quadrature points' * coordinates */ - const Matrix<Real> & inv_quad_coord_matrix = *inv_quad_coord_it; + const auto & inv_quad_coord_matrix = *inv_quad_coord_it; /** * multiply it by the field values over quadrature points to get * the interpolation coefficients */ coefficients.mul<false, true>(inv_quad_coord_matrix, *field_it); /// matrix containing the points' coordinates - const Matrix<Real> & coord = *interpolation_points_coordinates_it; + const auto & coord = *interpolation_points_coordinates_it; /// multiply the coordinates matrix by the coefficients matrix and store the /// result Matrix<Real> res(result_begin[element_filter(el)]); res.mul<true, true>(coefficients, coord); } AKANTU_DEBUG_OUT(); } + /* -------------------------------------------------------------------------- */ template <ElementType type> inline void ShapeFunctions::interpolateElementalFieldOnIntegrationPoints( const Array<Real> & u_el, Array<Real> & uq, const GhostType & ghost_type, const Array<Real> & shapes, const Array<UInt> & filter_elements) const { - UInt nb_element; - UInt nb_nodes_per_element = ElementClass<type>::getShapeSize(); - - UInt nb_points = shapes.size() / mesh.getNbElement(type, ghost_type); - UInt nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element; + auto nb_element = mesh.getNbElement(type, ghost_type); + auto nb_nodes_per_element = ElementClass<type>::getShapeSize(); + auto nb_points = shapes.size() / mesh.getNbElement(type, ghost_type); + auto nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element; Array<Real>::const_matrix_iterator N_it; - Array<Real>::const_matrix_iterator u_it; - Array<Real>::matrix_iterator inter_u_it; - - Array<Real> * filtered_N = NULL; + Array<Real> * filtered_N = nullptr; if (filter_elements != empty_filter) { nb_element = filter_elements.size(); filtered_N = new Array<Real>(0, shapes.getNbComponent()); FEEngine::filterElementalData(mesh, shapes, *filtered_N, type, ghost_type, filter_elements); N_it = filtered_N->begin_reinterpret(nb_nodes_per_element, nb_points, nb_element); } else { - nb_element = mesh.getNbElement(type, ghost_type); N_it = shapes.begin_reinterpret(nb_nodes_per_element, nb_points, nb_element); } uq.resize(nb_element * nb_points); - u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element); - inter_u_it = + auto u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element); + auto inter_u_it = uq.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element); for (UInt el = 0; el < nb_element; ++el, ++N_it, ++u_it, ++inter_u_it) { - const Matrix<Real> & u = *u_it; - const Matrix<Real> & N = *N_it; - Matrix<Real> & inter_u = *inter_u_it; + const auto & u = *u_it; + const auto & N = *N_it; + auto & inter_u = *inter_u_it; - inter_u.mul<false, false>(u, N); + inter_u.template mul<false, false>(u, N); } delete filtered_N; } /* -------------------------------------------------------------------------- */ template <ElementType type> void ShapeFunctions::gradientElementalFieldOnIntegrationPoints( const Array<Real> & u_el, Array<Real> & out_nablauq, const GhostType & ghost_type, const Array<Real> & shapes_derivatives, const Array<UInt> & filter_elements) const { AKANTU_DEBUG_IN(); - UInt nb_nodes_per_element = + auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerInterpolationElement(); - UInt nb_points = integration_points(type, ghost_type).cols(); - UInt element_dimension = ElementClass<type>::getNaturalSpaceDimension(); - UInt nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element; + auto nb_points = integration_points(type, ghost_type).cols(); + auto element_dimension = ElementClass<type>::getNaturalSpaceDimension(); + auto nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element; + auto nb_element = mesh.getNbElement(type, ghost_type); Array<Real>::const_matrix_iterator B_it; - Array<Real>::const_matrix_iterator u_it; - Array<Real>::matrix_iterator nabla_u_it; - UInt nb_element; - Array<Real> * filtered_B = NULL; + Array<Real> * filtered_B = nullptr; if (filter_elements != empty_filter) { nb_element = filter_elements.size(); filtered_B = new Array<Real>(0, shapes_derivatives.getNbComponent()); FEEngine::filterElementalData(mesh, shapes_derivatives, *filtered_B, type, ghost_type, filter_elements); B_it = filtered_B->begin(element_dimension, nb_nodes_per_element); } else { B_it = shapes_derivatives.begin(element_dimension, nb_nodes_per_element); - nb_element = mesh.getNbElement(type, ghost_type); } out_nablauq.resize(nb_element * nb_points); - - u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element); - nabla_u_it = out_nablauq.begin(nb_degree_of_freedom, element_dimension); + auto u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element); + auto nabla_u_it = out_nablauq.begin(nb_degree_of_freedom, element_dimension); for (UInt el = 0; el < nb_element; ++el, ++u_it) { - const Matrix<Real> & u = *u_it; + const auto & u = *u_it; for (UInt q = 0; q < nb_points; ++q, ++B_it, ++nabla_u_it) { - const Matrix<Real> & B = *B_it; - Matrix<Real> & nabla_u = *nabla_u_it; - - nabla_u.mul<false, true>(u, B); + const auto & B = *B_it; + auto & nabla_u = *nabla_u_it; + nabla_u.template mul<false, true>(u, B); } } delete filtered_B; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ } // namespace akantu #endif /* __AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_CC__ */ diff --git a/src/fe_engine/shape_lagrange_base.cc b/src/fe_engine/shape_lagrange_base.cc index 12c7fb0d8..2d9dcb7b0 100644 --- a/src/fe_engine/shape_lagrange_base.cc +++ b/src/fe_engine/shape_lagrange_base.cc @@ -1,161 +1,159 @@ /** * @file shape_lagrange_base.cc * * @author Nicolas Richart * * @date creation Thu Jul 27 2017 * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "shape_lagrange_base.hh" #include "mesh_iterators.hh" /* -------------------------------------------------------------------------- */ namespace akantu { ShapeLagrangeBase::ShapeLagrangeBase(const Mesh & mesh, const ElementKind & kind, const ID & id, const MemoryID & memory_id) : ShapeFunctions(mesh, id, memory_id), - shapes("shapes_generic", id, memory_id), - shapes_derivatives("shapes_derivatives_generic", id, memory_id), _kind(kind) {} /* -------------------------------------------------------------------------- */ ShapeLagrangeBase::~ShapeLagrangeBase() = default; /* -------------------------------------------------------------------------- */ #define AKANTU_COMPUTE_SHAPES(type) \ _this.template computeShapesOnIntegrationPoints<type>( \ nodes, integration_points, shapes, ghost_type, filter_elements) namespace shape_lagrange { namespace details { template <ElementKind kind> struct Helper { template <class S> static void call(const S &, const Array<Real> &, const Matrix<Real> &, Array<Real> &, const ElementType &, const GhostType &, const Array<UInt> &) { AKANTU_DEBUG_TO_IMPLEMENT(); } }; #define AKANTU_COMPUTE_SHAPES_KIND(kind) \ template <> struct Helper<kind> { \ template <class S> \ static void call(const S & _this, const Array<Real> & nodes, \ const Matrix<Real> & integration_points, \ Array<Real> & shapes, const ElementType & type, \ const GhostType & ghost_type, \ const Array<UInt> & filter_elements) { \ AKANTU_BOOST_KIND_ELEMENT_SWITCH(AKANTU_COMPUTE_SHAPES, kind); \ } \ }; AKANTU_BOOST_ALL_KIND_LIST(AKANTU_COMPUTE_SHAPES_KIND, AKANTU_FE_ENGINE_LIST_LAGRANGE_BASE) } // namespace details } // namespace shape_lagrange /* -------------------------------------------------------------------------- */ void ShapeLagrangeBase::computeShapesOnIntegrationPoints( const Array<Real> & nodes, const Matrix<Real> & integration_points, Array<Real> & shapes, const ElementType & type, const GhostType & ghost_type, const Array<UInt> & filter_elements) const { auto kind = Mesh::getKind(type); #define AKANTU_COMPUTE_SHAPES_KIND_SWITCH(kind) \ shape_lagrange::details::Helper<kind>::call( \ *this, nodes, integration_points, shapes, type, ghost_type, \ filter_elements); AKANTU_BOOST_LIST_SWITCH( AKANTU_COMPUTE_SHAPES_KIND_SWITCH, BOOST_PP_LIST_TO_SEQ(AKANTU_FE_ENGINE_LIST_LAGRANGE_BASE), kind); #undef AKANTU_COMPUTE_SHAPES #undef AKANTU_COMPUTE_SHAPES_KIND #undef AKANTU_COMPUTE_SHAPES_KIND_SWITCH } /* -------------------------------------------------------------------------- */ void ShapeLagrangeBase::onElementsAdded(const Array<Element> & new_elements) { AKANTU_DEBUG_IN(); const auto & nodes = mesh.getNodes(); for (auto elements_range : MeshElementsByTypes(new_elements)) { auto type = elements_range.getType(); auto ghost_type = elements_range.getGhostType(); if (mesh.getKind(type) != _kind) continue; auto & elements = elements_range.getElements(); auto itp_type = FEEngine::getInterpolationType(type); if (not this->shapes_derivatives.exists(itp_type, ghost_type)) { auto size_of_shapesd = this->getShapeDerivativesSize(type); this->shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type); } if (not shapes.exists(itp_type, ghost_type)) { auto size_of_shapes = this->getShapeSize(type); this->shapes.alloc(0, size_of_shapes, itp_type, ghost_type); } const auto & natural_coords = integration_points(type, ghost_type); computeShapesOnIntegrationPoints(nodes, natural_coords, shapes(itp_type, ghost_type), type, ghost_type, elements); computeShapeDerivativesOnIntegrationPoints( nodes, natural_coords, shapes_derivatives(itp_type, ghost_type), type, ghost_type, elements); } #undef INIT_SHAPE_FUNCTIONS AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void ShapeLagrangeBase::onElementsRemoved( const Array<Element> &, const ElementTypeMapArray<UInt> & new_numbering) { this->shapes.onElementsRemoved(new_numbering); this->shapes_derivatives.onElementsRemoved(new_numbering); } /* -------------------------------------------------------------------------- */ void ShapeLagrangeBase::printself(std::ostream & stream, int indent) const { std::string space; for (Int i = 0; i < indent; i++, space += AKANTU_INDENT) ; stream << space << "Shapes Lagrange [" << std::endl; ShapeFunctions::printself(stream, indent + 1); shapes.printself(stream, indent + 1); shapes_derivatives.printself(stream, indent + 1); stream << space << "]" << std::endl; } } // namespace akantu diff --git a/src/fe_engine/shape_lagrange_base.hh b/src/fe_engine/shape_lagrange_base.hh index 675215fb5..2d3a0ab8c 100644 --- a/src/fe_engine/shape_lagrange_base.hh +++ b/src/fe_engine/shape_lagrange_base.hh @@ -1,114 +1,91 @@ /** * @file shape_lagrange_base.hh * * @author Nicolas Richart * * @date creation Thu Jul 27 2017 * * @brief Base class for the shape lagrange * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "shape_functions.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_SHAPE_LAGRANGE_BASE_HH__ #define __AKANTU_SHAPE_LAGRANGE_BASE_HH__ namespace akantu { class ShapeLagrangeBase : public ShapeFunctions { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: ShapeLagrangeBase(const Mesh & mesh, const ElementKind & kind, const ID & id = "shape_lagrange", const MemoryID & memory_id = 0); virtual ~ShapeLagrangeBase(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// computes the shape functions for given interpolation points virtual void computeShapesOnIntegrationPoints( const Array<Real> & nodes, const Matrix<Real> & integration_points, Array<Real> & shapes, const ElementType & type, const GhostType & ghost_type, const Array<UInt> & filter_elements = empty_filter) const; /// computes the shape functions derivatives for given interpolation points virtual void computeShapeDerivativesOnIntegrationPoints( const Array<Real> & nodes, const Matrix<Real> & integration_points, Array<Real> & shape_derivatives, const ElementType & type, const GhostType & ghost_type, const Array<UInt> & filter_elements = empty_filter) const = 0; /// function to print the containt of the class void printself(std::ostream & stream, int indent = 0) const override; template <ElementType type> void computeShapesOnIntegrationPoints( const Array<Real> & nodes, const Matrix<Real> & integration_points, Array<Real> & shapes, const GhostType & ghost_type, const Array<UInt> & filter_elements = empty_filter) const; public: void onElementsAdded(const Array<Element> & elements) override; void onElementsRemoved(const Array<Element> & elements, const ElementTypeMapArray<UInt> & new_numbering) override; - /* ------------------------------------------------------------------------ */ - /* Accessors */ - /* ------------------------------------------------------------------------ */ -public: - /// get a the shapes vector - inline const Array<Real> & - getShapes(const ElementType & el_type, - const GhostType & ghost_type = _not_ghost) const; - - /// get a the shapes derivatives vector - inline const Array<Real> & - getShapesDerivatives(const ElementType & el_type, - const GhostType & ghost_type = _not_ghost) const; - - /* ------------------------------------------------------------------------ */ - /* Class Members */ - /* ------------------------------------------------------------------------ */ protected: - /// shape functions for all elements - ElementTypeMapArray<Real, InterpolationType> shapes; - - /// shape functions derivatives for all elements - ElementTypeMapArray<Real, InterpolationType> shapes_derivatives; - /// The kind to consider ElementKind _kind; }; } // namespace akantu #include "shape_lagrange_base_inline_impl.cc" #endif /* __AKANTU_SHAPE_LAGRANGE_BASE_HH__ */ diff --git a/src/fe_engine/shape_lagrange_base_inline_impl.cc b/src/fe_engine/shape_lagrange_base_inline_impl.cc index 1c09adcef..4b9ebbf08 100644 --- a/src/fe_engine/shape_lagrange_base_inline_impl.cc +++ b/src/fe_engine/shape_lagrange_base_inline_impl.cc @@ -1,97 +1,82 @@ /** * @file shape_lagrange_base_inline_impl.cc * * @author Nicolas Richart * * @date creation Thu Jul 27 2017 * * @brief A Documented file. * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "shape_lagrange_base.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_SHAPE_LAGRANGE_BASE_INLINE_IMPL_CC__ #define __AKANTU_SHAPE_LAGRANGE_BASE_INLINE_IMPL_CC__ namespace akantu { -/* -------------------------------------------------------------------------- */ -inline const Array<Real> & -ShapeLagrangeBase::getShapes(const ElementType & el_type, - const GhostType & ghost_type) const { - return shapes(FEEngine::getInterpolationType(el_type), ghost_type); -} - -/* -------------------------------------------------------------------------- */ -inline const Array<Real> & -ShapeLagrangeBase::getShapesDerivatives(const ElementType & el_type, - const GhostType & ghost_type) const { - return shapes_derivatives(FEEngine::getInterpolationType(el_type), - ghost_type); -} - /* -------------------------------------------------------------------------- */ template <ElementType type> void ShapeLagrangeBase::computeShapesOnIntegrationPoints( const Array<Real> &, const Matrix<Real> & integration_points, Array<Real> & shapes, const GhostType & ghost_type, const Array<UInt> & filter_elements) const { AKANTU_DEBUG_IN(); UInt nb_points = integration_points.cols(); UInt nb_element = mesh.getConnectivity(type, ghost_type).size(); shapes.resize(nb_element * nb_points); #if !defined(AKANTU_NDEBUG) UInt size_of_shapes = ElementClass<type>::getShapeSize(); AKANTU_DEBUG_ASSERT(shapes.getNbComponent() == size_of_shapes, "The shapes array does not have the correct " << "number of component"); #endif auto shapes_it = shapes.begin_reinterpret( ElementClass<type>::getNbNodesPerInterpolationElement(), nb_points, nb_element); auto shapes_begin = shapes_it; if (filter_elements != empty_filter) { nb_element = filter_elements.size(); } for (UInt elem = 0; elem < nb_element; ++elem) { if (filter_elements != empty_filter) shapes_it = shapes_begin + filter_elements(elem); Matrix<Real> & N = *shapes_it; ElementClass<type>::computeShapes(integration_points, N); if (filter_elements == empty_filter) ++shapes_it; } AKANTU_DEBUG_OUT(); } } // namespace akantu #endif /* __AKANTU_SHAPE_LAGRANGE_BASE_INLINE_IMPL_CC__ */ diff --git a/src/fe_engine/shape_linked.cc b/src/fe_engine/shape_linked.cc deleted file mode 100644 index 86392fec7..000000000 --- a/src/fe_engine/shape_linked.cc +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file shape_linked.cc - * - * @author Fabian Barras <fabian.barras@epfl.ch> - * @author Nicolas Richart <nicolas.richart@epfl.ch> - * - * @date creation: Fri Jul 15 2011 - * @date last modification: Sun Oct 19 2014 - * - * @brief ShapeLinked implementation - * - * @section LICENSE - * - * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de - * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des - * Solides) - * - * Akantu is free software: you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Akantu. If not, see <http://www.gnu.org/licenses/>. - * - */ - -/* -------------------------------------------------------------------------- */ -#include "aka_memory.hh" -#include "mesh.hh" -#include "shape_linked.hh" -/* -------------------------------------------------------------------------- */ - -namespace akantu { - -#if defined(AKANTU_STRUCTURAL_MECHANICS) -/* -------------------------------------------------------------------------- */ -template <> -ShapeLinked<_ek_structural>::ShapeLinked(Mesh & mesh, const ID & id, const MemoryID & memory_id) : - ShapeFunctions(mesh, id, memory_id) -{ - -} - - -/* -------------------------------------------------------------------------- */ -template <> -ShapeLinked<_ek_structural>::~ShapeLinked() { - for (ghost_type_t::iterator gt = ghost_type_t::begin(); - gt != ghost_type_t::end(); ++gt) { - GhostType ghost_type = *gt; - - // delete all the shapes id - ElementTypeMapMultiReal::type_iterator s_type_it = - shapes.firstType(_all_dimensions, ghost_type, _ek_structural); - ElementTypeMapMultiReal::type_iterator s_type_end = - shapes.lastType (_all_dimensions, ghost_type, _ek_structural); - - for(; s_type_it != s_type_end; ++s_type_it) { - delete [] shapes(*s_type_it, ghost_type); - } - - - // delete all the shapes derivatives id - ElementTypeMapMultiReal::type_iterator sd_type_it = - shapes_derivatives.firstType(_all_dimensions, ghost_type, _ek_structural); - ElementTypeMapMultiReal::type_iterator sd_type_end = - shapes_derivatives.lastType (_all_dimensions, ghost_type, _ek_structural); - - for(; sd_type_it != sd_type_end; ++sd_type_it) { - delete [] shapes_derivatives(*sd_type_it, ghost_type); - } - } -} -#endif - -} // akantu diff --git a/src/fe_engine/shape_linked_inline_impl.cc b/src/fe_engine/shape_linked_inline_impl.cc deleted file mode 100644 index 2112762e6..000000000 --- a/src/fe_engine/shape_linked_inline_impl.cc +++ /dev/null @@ -1,319 +0,0 @@ -/** - * @file shape_linked_inline_impl.cc - * - * @author Fabian Barras <fabian.barras@epfl.ch> - * @author Nicolas Richart <nicolas.richart@epfl.ch> - * - * @date creation: Mon Dec 13 2010 - * @date last modification: Thu Oct 15 2015 - * - * @brief ShapeLinked inline implementation - * - * @section LICENSE - * - * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de - * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des - * Solides) - * - * Akantu is free software: you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Akantu. If not, see <http://www.gnu.org/licenses/>. - * - */ - -template <ElementKind kind> -inline void ShapeLinked<kind>::initShapeFunctions( - __attribute__((unused)) const Array<Real> & nodes, - __attribute__((unused)) const Matrix<Real> & integration_points, - __attribute__((unused)) const ElementType & type, - __attribute__((unused)) const GhostType & ghost_type) { - AKANTU_DEBUG_TO_IMPLEMENT(); -} - -#undef INIT_SHAPE_FUNCTIONS - -/* -------------------------------------------------------------------------- */ -#define INIT_SHAPE_FUNCTIONS(type) \ - setIntegrationPointsByType<type>(integration_points, ghost_type); \ - precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type); \ - precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type); - -#if defined(AKANTU_STRUCTURAL_MECHANICS) -template <> -inline void ShapeLinked<_ek_structural>::initShapeFunctions( - __attribute__((unused)) const Array<Real> & nodes, - __attribute__((unused)) const Matrix<Real> & integration_points, - __attribute__((unused)) const ElementType & type, - __attribute__((unused)) const GhostType & ghost_type) { - AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS); -} -#endif - -#undef INIT_SHAPE_FUNCTIONS - -/* -------------------------------------------------------------------------- */ -template <ElementKind kind> -inline const Array<Real> & -ShapeLinked<kind>::getShapes(const ElementType & type, - const GhostType & ghost_type, UInt id) const { - AKANTU_DEBUG_IN(); - AKANTU_DEBUG_ASSERT(shapes.exists(type, ghost_type), - "No shapes of type " << type << " in " << this->id); - AKANTU_DEBUG_OUT(); - return *(shapes(type, ghost_type)[id]); -} - -/* -------------------------------------------------------------------------- */ -template <ElementKind kind> -inline const Array<Real> & ShapeLinked<kind>::getShapesDerivatives( - const ElementType & type, const GhostType & ghost_type, UInt id) const { - AKANTU_DEBUG_IN(); - AKANTU_DEBUG_ASSERT(shapes_derivatives.exists(type, ghost_type), - "No shapes_derivatives of type " << type << " in " - << this->id); - AKANTU_DEBUG_OUT(); - return *(shapes_derivatives(type, ghost_type)[id]); -} - -#if defined(AKANTU_STRUCTURAL_MECHANICS) -/* -------------------------------------------------------------------------- */ -template <> -template <ElementType type> -void ShapeLinked<_ek_structural>::precomputeShapesOnIntegrationPoints( - const Array<Real> & nodes, const GhostType & ghost_type) { - AKANTU_DEBUG_IN(); - - // Real * coord = mesh.getNodes().storage(); - UInt spatial_dimension = mesh.getSpatialDimension(); - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); - - Matrix<Real> & natural_coords = integration_points(type, ghost_type); - UInt nb_points = integration_points(type, ghost_type).cols(); - - UInt size_of_shapes = ElementClass<type>::getShapeSize(); - - std::string ghost = ""; - if (ghost_type == _ghost) { - ghost = "ghost_"; - } - - UInt nb_element = mesh.getNbElement(type, ghost_type); - UInt nb_shape_functions = - ElementClass<type, _ek_structural>::getNbShapeFunctions(); - - Array<Real> ** shapes_tmp = new Array<Real> * [nb_shape_functions]; - - Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element); - FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type); - - for (UInt s = 0; s < nb_shape_functions; ++s) { - std::stringstream sstr_shapes; - sstr_shapes << id << ":" << ghost << "shapes:" << type << ":" << s; - shapes_tmp[s] = &(alloc<Real>(sstr_shapes.str(), nb_element * nb_points, - size_of_shapes)); - Array<Real>::matrix_iterator x_it = - x_el.begin(spatial_dimension, nb_nodes_per_element); - Array<Real>::matrix_iterator shapes_it = - shapes_tmp[s]->begin_reinterpret(size_of_shapes, nb_points, nb_element); - - for (UInt elem = 0; elem < nb_element; ++elem, ++shapes_it, ++x_it) { - Matrix<Real> & X = *x_it; - Matrix<Real> & N = *shapes_it; - ElementClass<type>::computeShapes(natural_coords, N, X, s); - } - } - - shapes(type, ghost_type) = shapes_tmp; - - AKANTU_DEBUG_OUT(); -} -#endif - -/* -------------------------------------------------------------------------- */ -template <ElementKind kind> -template <ElementType type> -void ShapeLinked<kind>::precomputeShapeDerivativesOnIntegrationPoints( - const Array<Real> & nodes, const GhostType & ghost_type) { - AKANTU_DEBUG_IN(); - - // Real * coord = mesh.getNodes().storage(); - UInt spatial_dimension = mesh.getSpatialDimension(); - UInt natural_spatial_dimension = - ElementClass<type>::getNaturalSpaceDimension(); - - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); - UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize(); - Matrix<Real> & natural_coords = integration_points(type, ghost_type); - UInt nb_points = natural_coords.cols(); - - UInt nb_element = mesh.getNbElement(type, ghost_type); - std::string ghost = ""; - - if (ghost_type == _ghost) { - ghost = "ghost_"; - } - - Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element); - FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type); - - UInt nb_shape_functions = ElementClass<type>::getNbShapeDerivatives(); - - Array<Real> ** shapes_derivatives_tmp = - new Array<Real> * [nb_shape_functions]; - for (UInt s = 0; s < nb_shape_functions; ++s) { - std::stringstream sstr_shapesd; - sstr_shapesd << id << ":" << ghost << "shapes_derivatives:" << type << ":" - << s; - shapes_derivatives_tmp[s] = &(alloc<Real>( - sstr_shapesd.str(), nb_element * nb_points, size_of_shapesd)); - Real * shapesd_val = shapes_derivatives_tmp[s]->storage(); - - Array<Real>::matrix_iterator x_it = - x_el.begin(spatial_dimension, nb_nodes_per_element); - - for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) { - // compute shape derivatives - Matrix<Real> & X = *x_it; - Tensor3<Real> B(shapesd_val, natural_spatial_dimension, - nb_nodes_per_element, nb_points); - ElementClass<type>::computeShapeDerivatives(natural_coords, B, X, s); - - shapesd_val += size_of_shapesd * nb_points; - } - } - - shapes_derivatives(type, ghost_type) = shapes_derivatives_tmp; - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template <ElementKind kind> -template <ElementType type> -void ShapeLinked<kind>::extractNodalToElementField( - const Array<Real> & nodal_f, Array<Real> & elemental_f, - UInt num_degre_of_freedom_to_extract, const GhostType & ghost_type, - const Array<UInt> & filter_elements) const { - AKANTU_DEBUG_IN(); - - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); - UInt nb_degree_of_freedom = nodal_f.getNbComponent(); - UInt nb_element = mesh.getNbElement(type, ghost_type); - UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage(); - - if (filter_elements != empty_filter) { - nb_element = filter_elements.size(); - } - - elemental_f.resize(nb_element); - - Real * nodal_f_val = nodal_f.storage(); - Real * f_val = elemental_f.storage(); - - UInt * el_conn; - for (UInt el = 0; el < nb_element; ++el) { - if (filter_elements != empty_filter) - el_conn = conn_val + filter_elements(el) * nb_nodes_per_element; - else - el_conn = conn_val + el * nb_nodes_per_element; - - for (UInt n = 0; n < nb_nodes_per_element; ++n) { - UInt node = *(el_conn + n); - *f_val = nodal_f_val[node * nb_degree_of_freedom + - num_degre_of_freedom_to_extract]; - f_val += 1; - } - } - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template <ElementKind kind> -template <ElementType type> -void ShapeLinked<kind>::interpolateOnIntegrationPoints( - const Array<Real> & in_u, Array<Real> & out_uq, - __attribute__((unused)) UInt nb_degree_of_freedom, - const GhostType & ghost_type, const Array<UInt> & filter_elements, - bool accumulate, UInt id_shape, UInt num_degre_of_freedom_to_interpolate, - __attribute__((unused)) UInt num_degre_of_freedom_interpolated) const { - AKANTU_DEBUG_IN(); - - Array<Real> * shapes_loc = shapes(type, ghost_type)[id_shape]; - - AKANTU_DEBUG_ASSERT(shapes_loc != NULL, "No shapes for the type " << type); - - UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement(); - Array<Real> u_el(0, nb_nodes_per_element); - extractNodalToElementField<type>(in_u, u_el, - num_degre_of_freedom_to_interpolate, - ghost_type, filter_elements); - - if (!accumulate) - out_uq.clear(); - - UInt nb_points = integration_points(type, ghost_type).cols() * u_el.size(); - Array<Real> uq(nb_points, 1, 0.); - - this->template interpolateElementalFieldOnIntegrationPoints<type>( - u_el, uq, ghost_type, *shapes_loc, filter_elements); - - for (UInt q = 0; q < nb_points; ++q) { - out_uq(q, num_degre_of_freedom_to_interpolate) += uq(q); - } - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template <ElementKind kind> -template <ElementType type> -void ShapeLinked<kind>::gradientOnIntegrationPoints( - const Array<Real> & in_u, Array<Real> & out_nablauq, - UInt nb_degree_of_freedom, const GhostType & ghost_type, - const Array<UInt> & filter_elements, bool accumulate, UInt id_shape, - UInt num_degre_of_freedom_to_interpolate, - __attribute__((unused)) UInt num_degre_of_freedom_interpolated) const { - AKANTU_DEBUG_IN(); - - Array<Real> * shapesd_loc = shapes_derivatives(type, ghost_type)[id_shape]; - - AKANTU_DEBUG_ASSERT(shapesd_loc != NULL, "No shapes for the type " << type); - - UInt nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement(); - Array<Real> u_el(0, nb_nodes_per_element); - extractNodalToElementField<type>(in_u, u_el, - num_degre_of_freedom_to_interpolate, - ghost_type, filter_elements); - - UInt nb_points = integration_points(type, ghost_type).cols() * u_el.size(); - UInt element_dimension = ElementClass<type>::getSpatialDimension(); - - Array<Real> nablauq(nb_points, element_dimension, 0.); - - if (!accumulate) - out_nablauq.clear(); - this->template gradientElementalFieldOnIntegrationPoints<type>( - u_el, nablauq, ghost_type, *shapesd_loc, filter_elements); - - Array<Real>::matrix_iterator nabla_u_it = nablauq.begin(1, element_dimension); - Array<Real>::matrix_iterator out_nabla_u_it = - out_nablauq.begin(nb_degree_of_freedom, element_dimension); - for (UInt q = 0; q < nb_points; ++q, ++nabla_u_it, ++out_nabla_u_it) { - for (UInt s = 0; s < element_dimension; ++s) { - (*out_nabla_u_it)(num_degre_of_freedom_to_interpolate, s) += - (*nabla_u_it)(0, s); - } - } - - AKANTU_DEBUG_OUT(); -} diff --git a/src/io/model_io.cc b/src/fe_engine/shape_structural.cc similarity index 63% rename from src/io/model_io.cc rename to src/fe_engine/shape_structural.cc index edfd6c372..0bee5ec47 100644 --- a/src/io/model_io.cc +++ b/src/fe_engine/shape_structural.cc @@ -1,50 +1,53 @@ /** - * @file model_io.cc + * @file shape_structural.cc * + * @author Fabian Barras <fabian.barras@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * - * @date creation: Thu Feb 21 2013 + * @date creation: Fri Jul 15 2011 * @date last modification: Sun Oct 19 2014 * - * @brief Reader for models (this is deprecated) + * @brief ShapeStructural implementation * * @section LICENSE * - * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) - * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de + * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des + * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ -#include "aka_common.hh" -#include "model_io.hh" - +#include "shape_structural.hh" +#include "aka_memory.hh" +#include "mesh.hh" /* -------------------------------------------------------------------------- */ - namespace akantu { /* -------------------------------------------------------------------------- */ -ModelIO::ModelIO() { -} +template <> +ShapeStructural<_ek_structural>::ShapeStructural(Mesh & mesh, const ID & id, + const MemoryID & memory_id) + : ShapeFunctions(mesh, id, memory_id) {} /* -------------------------------------------------------------------------- */ -ModelIO::~ModelIO() { +template <> ShapeStructural<_ek_structural>::~ShapeStructural() = default; -} /* -------------------------------------------------------------------------- */ -} // akantu + +} // namespace akantu diff --git a/src/fe_engine/shape_linked.hh b/src/fe_engine/shape_structural.hh similarity index 52% rename from src/fe_engine/shape_linked.hh rename to src/fe_engine/shape_structural.hh index 1e0c6eae5..cd7e368d5 100644 --- a/src/fe_engine/shape_linked.hh +++ b/src/fe_engine/shape_structural.hh @@ -1,161 +1,123 @@ /** - * @file shape_linked.hh + * @file shape_structural.hh * * @author Fabian Barras <fabian.barras@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date creation: Tue Feb 15 2011 * @date last modification: Thu Oct 22 2015 * * @brief shape class for element with different set of shapes functions * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "shape_functions.hh" -#ifndef __AKANTU_SHAPE_LINKED_HH__ -#define __AKANTU_SHAPE_LINKED_HH__ +#ifndef __AKANTU_SHAPE_STRUCTURAL_HH__ +#define __AKANTU_SHAPE_STRUCTURAL_HH__ namespace akantu { -template <ElementKind kind> -class ShapeLinked : public ShapeFunctions { +template <ElementKind kind> class ShapeStructural : public ShapeFunctions { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - typedef ElementTypeMap<Array<Real> **> ElementTypeMapMultiReal; - ShapeLinked(Mesh & mesh, const ID & id = "shape_linked", const MemoryID & memory_id = 0); - virtual ~ShapeLinked(); + ShapeStructural(Mesh & mesh, const ID & id = "shape_structural", + const MemoryID & memory_id = 0); + virtual ~ShapeStructural(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// initialization function for structural elements inline void initShapeFunctions(const Array<Real> & nodes, - const Matrix<Real> & integration_points, - const ElementType & type, - const GhostType & ghost_type); + const Matrix<Real> & integration_points, + const ElementType & type, + const GhostType & ghost_type); - /// pre compute all shapes on the element integration points from natural coordinates + /// pre compute all shapes on the element integration points from natural + /// coordinates template <ElementType type> void precomputeShapesOnIntegrationPoints(const Array<Real> & nodes, - const GhostType & ghost_type); + const GhostType & ghost_type); - /// pre compute all shapes on the element integration points from natural coordinates + /// pre compute all shapes on the element integration points from natural + /// coordinates template <ElementType type> - void precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes, - const GhostType & ghost_type); + void + precomputeShapeDerivativesOnIntegrationPoints(const Array<Real> & nodes, + const GhostType & ghost_type); /// interpolate nodal values on the integration points template <ElementType type> - void interpolateOnIntegrationPoints(const Array<Real> &u, - Array<Real> &uq, - UInt nb_degree_of_freedom, - const GhostType & ghost_type = _not_ghost, - const Array<UInt> & filter_elements = empty_filter, - bool accumulate = false, - UInt id_shape = 0, - UInt num_degre_of_freedom_to_interpolate = 0, - UInt num_degre_of_freedom_interpolated = 0) const; - + void interpolateOnIntegrationPoints( + const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom, + const GhostType & ghost_type = _not_ghost, + const Array<UInt> & filter_elements = empty_filter) const; /// compute the gradient of u on the integration points template <ElementType type> - void gradientOnIntegrationPoints(const Array<Real> &u, - Array<Real> &nablauq, - UInt nb_degree_of_freedom, - const GhostType & ghost_type = _not_ghost, - const Array<UInt> & filter_elements = empty_filter, - bool accumulate = false, - UInt id_shape = 0, - UInt num_degre_of_freedom_to_interpolate = 0, - UInt num_degre_of_freedom_interpolated = 0) const; + void gradientOnIntegrationPoints( + const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom, + const GhostType & ghost_type = _not_ghost, + const Array<UInt> & filter_elements = empty_filter) const; /// multiply a field by shape functions template <ElementType type> - void fieldTimesShapes(__attribute__((unused)) const Array<Real> & field, - __attribute__((unused)) Array<Real> & fiedl_times_shapes, - __attribute__((unused)) const GhostType & ghost_type) const { + void + fieldTimesShapes(__attribute__((unused)) const Array<Real> & field, + __attribute__((unused)) Array<Real> & fiedl_times_shapes, + __attribute__((unused)) const GhostType & ghost_type) const { AKANTU_DEBUG_TO_IMPLEMENT(); } -private: - /// extract the nodal field value to fill an elemental field - template <ElementType type> - void extractNodalToElementField(const Array<Real> & nodal_f, - Array<Real> & elemental_f, - UInt num_degre_of_freedom_to_extract, - const GhostType & ghost_type, - const Array<UInt> & filter_elements) const; - /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: - /// get a the shapes vector inline const Array<Real> & getShapes(const ElementType & type, - const GhostType & ghost_type, - UInt id = 0) const; + const GhostType & ghost_type, + UInt id = 0) const; /// get a the shapes derivatives vector inline const Array<Real> & getShapesDerivatives(const ElementType & type, - const GhostType & ghost_type, - UInt id = 0) const; + const GhostType & ghost_type, + UInt id = 0) const; /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: - /// shape functions for all elements - ElementTypeMapMultiReal shapes; - - /// shape derivatives for all elements - ElementTypeMapMultiReal shapes_derivatives; }; +} // namespace akantu -/* -------------------------------------------------------------------------- */ -/* inline functions */ -/* -------------------------------------------------------------------------- */ - -#if defined (AKANTU_INCLUDE_INLINE_IMPL) -# include "shape_linked_inline_impl.cc" -#endif - -/// standard output stream operator -// inline std::ostream & operator <<(std::ostream & stream, const ShapeLinked & _this) -// { -// _this.printself(stream); -// return stream; -// } - - -} // akantu +#include "shape_structural_inline_impl.cc" -#endif /* __AKANTU_SHAPE_LINKED_HH__ */ +#endif /* __AKANTU_SHAPE_STRUCTURAL_HH__ */ diff --git a/src/fe_engine/shape_structural_inline_impl.cc b/src/fe_engine/shape_structural_inline_impl.cc new file mode 100644 index 000000000..cf22aec85 --- /dev/null +++ b/src/fe_engine/shape_structural_inline_impl.cc @@ -0,0 +1,253 @@ +/** + * @file shape_structural_inline_impl.cc + * + * @author Fabian Barras <fabian.barras@epfl.ch> + * @author Nicolas Richart <nicolas.richart@epfl.ch> + * + * @date creation: Mon Dec 13 2010 + * @date last modification: Thu Oct 15 2015 + * + * @brief ShapeStructural inline implementation + * + * @section LICENSE + * + * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de + * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des + * Solides) + * + * Akantu is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Akantu. If not, see <http://www.gnu.org/licenses/>. + * + */ +/* -------------------------------------------------------------------------- */ +#include "mesh_iterators.hh" +#include "shape_structural.hh" +/* -------------------------------------------------------------------------- */ + +#ifndef __AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_CC__ +#define __AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_CC__ + +namespace akantu { + +template <ElementKind kind> +inline void ShapeStructural<kind>::initShapeFunctions( + const Array<Real> & /* unused */, const Matrix<Real> & /* unused */, + const ElementType & /* unused */, const GhostType & /* unused */) { + AKANTU_DEBUG_TO_IMPLEMENT(); +} + +/* -------------------------------------------------------------------------- */ +#define INIT_SHAPE_FUNCTIONS(type) \ + setIntegrationPointsByType<type>(integration_points, ghost_type); \ + precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type); \ + precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type); + +template <> +inline void ShapeStructural<_ek_structural>::initShapeFunctions( + const Array<Real> & nodes, const Matrix<Real> & integration_points, + const ElementType & type, const GhostType & ghost_type) { + AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS); +} + +#undef INIT_SHAPE_FUNCTIONS + +/* -------------------------------------------------------------------------- */ +template <> +template <ElementType type> +void ShapeStructural<_ek_structural>::precomputeShapesOnIntegrationPoints( + const Array<Real> & nodes, const GhostType & ghost_type) { + AKANTU_DEBUG_IN(); + + const auto & natural_coords = integration_points(type, ghost_type); + auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type); + auto spatial_dimension = mesh.getSpatialDimension(); + auto nb_points = integration_points(type, ghost_type).cols(); + auto nb_element = mesh.getNbElement(type, ghost_type); + auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom(); + + Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element); + FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type); + + auto itp_type = FEEngine::getInterpolationType(type); + if (not shapes.exists(itp_type, ghost_type)) { + auto size_of_shapes = this->getShapeSize(type); + this->shapes.alloc(0, size_of_shapes, itp_type, ghost_type); + } + + auto & shapes_ = this->shapes(itp_type, ghost_type); + shapes_.resize(nb_element * nb_points); + + auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element); + + auto shapes_it = shapes_.begin_reinterpret( + nb_dof, nb_dof * nb_nodes_per_element, nb_points, nb_element); + + for (UInt elem = 0; elem < nb_element; ++elem, ++shapes_it, ++x_it) { + auto & X = *x_it; + auto & N = *shapes_it; + ElementClass<type>::computeShapes(natural_coords, N, X); + } + + AKANTU_DEBUG_OUT(); +} // namespace akantu + +/* -------------------------------------------------------------------------- */ +template <ElementKind kind> +template <ElementType type> +void ShapeStructural<kind>::precomputeShapeDerivativesOnIntegrationPoints( + const Array<Real> & nodes, const GhostType & ghost_type) { + AKANTU_DEBUG_IN(); + + const auto & natural_coords = integration_points(type, ghost_type); + auto spatial_dimension = mesh.getSpatialDimension(); + auto natural_spatial_dimension = + ElementClass<type>::getNaturalSpaceDimension(); + auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type); + auto nb_points = natural_coords.cols(); + auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom(); + auto nb_element = mesh.getNbElement(type, ghost_type); + + auto itp_type = FEEngine::getInterpolationType(type); + if (not this->shapes_derivatives.exists(itp_type, ghost_type)) { + auto size_of_shapesd = this->getShapeDerivativesSize(type); + this->shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type); + } + + Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element); + FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type); + + auto & shapesd = this->shapes_derivatives(itp_type, ghost_type); + shapesd.resize(nb_element * nb_points); + + auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element); + auto shapesd_it = shapesd.begin_reinterpret(natural_spatial_dimension, + nb_nodes_per_element * nb_dof, + nb_points, nb_element); + + for (UInt elem = 0; elem < nb_element; ++elem, ++x_it, ++shapesd_it) { + // compute shape derivatives + auto & X = *x_it; + auto & B = *shapesd_it; + ElementClass<type>::computeShapeDerivatives(natural_coords, B, X); + } + + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +template <ElementKind kind> +template <ElementType type> +void ShapeStructural<kind>::interpolateOnIntegrationPoints( + const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_dof, + const GhostType & ghost_type, const Array<UInt> & filter_elements) const { + AKANTU_DEBUG_IN(); + + AKANTU_DEBUG_ASSERT(out_uq.getNbComponent() == nb_dof, + "The output array shape is not correct"); + + auto itp_type = FEEngine::getInterpolationType(type); + const auto & shapes_ = shapes(itp_type, ghost_type); + + auto nb_element = mesh.getNbElement(type, ghost_type); + auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement(); + auto nb_quad_points_per_element = integration_points(type, ghost_type).cols(); + + Array<Real> u_el(0, nb_nodes_per_element * nb_dof); + FEEngine::extractNodalToElementField<type>(mesh, in_u, u_el, ghost_type, filter_elements); + + auto nb_quad_points = nb_quad_points_per_element * u_el.size(); + out_uq.resize(nb_quad_points); + + auto out_it = out_uq.begin_reinterpret(nb_dof, 1, nb_quad_points_per_element, + u_el.size()); + auto shapes_it = + shapes_.begin_reinterpret(nb_dof, nb_dof * nb_nodes_per_element, + nb_quad_points_per_element, nb_element); + auto u_it = u_el.begin_reinterpret(nb_dof * nb_nodes_per_element, 1, + nb_quad_points_per_element, u_el.size()); + + for_each_elements(nb_element, filter_elements, [&](auto && el) { + auto & uq = *out_it; + const auto & u = *u_it; + auto N = Tensor3<Real>(shapes_it[el]); + + for (auto && q : arange(uq.size(2))) { + auto uq_q = Matrix<Real>(uq(q)); + auto u_q = Matrix<Real>(u(q)); + auto N_q = Matrix<Real>(N(q)); + + uq_q.mul<false, false>(N, u); + } + + ++out_it; + ++u_it; + }); + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +template <ElementKind kind> +template <ElementType type> +void ShapeStructural<kind>::gradientOnIntegrationPoints( + const Array<Real> & in_u, Array<Real> & out_nablauq, + UInt nb_dof, const GhostType & ghost_type, + const Array<UInt> & filter_elements) const { + AKANTU_DEBUG_IN(); + + auto itp_type = FEEngine::getInterpolationType(type); + const auto & shapesd = shapes_derivatives(itp_type, ghost_type); + + auto nb_element = mesh.getNbElement(type, ghost_type); + auto element_dimension = ElementClass<type>::getSpatialDimension(); + auto nb_quad_points_per_element = integration_points(type, ghost_type).cols(); + auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement(); + + Array<Real> u_el(0, nb_nodes_per_element * nb_dof); + FEEngine::extractNodalToElementField<type>(mesh, in_u, u_el, + ghost_type, filter_elements); + + auto nb_quad_points = nb_quad_points_per_element * u_el.size(); + out_nablauq.resize(nb_quad_points); + + auto out_it = out_nablauq.begin_reinterpret(element_dimension, 1, nb_quad_points_per_element, + u_el.size()); + auto shapesd_it = + shapesd.begin_reinterpret(element_dimension, nb_dof * nb_nodes_per_element, + nb_quad_points_per_element, nb_element); + auto u_it = u_el.begin_reinterpret(nb_dof * nb_nodes_per_element, 1, + nb_quad_points_per_element, u_el.size()); + + for_each_elements(nb_element, filter_elements, [&](auto && el) { + auto & nablau = *out_it; + const auto & u = *u_it; + auto B = Tensor3<Real>(shapesd_it[el]); + + for (auto && q : arange(nablau.size(2))) { + auto nablau_q = Matrix<Real>(uq(q)); + auto u_q = Matrix<Real>(u(q)); + auto B_q = Matrix<Real>(N(q)); + + nablau_q.mul<false, false>(B, u); + } + + ++out_it; + ++u_it; + }); + + + AKANTU_DEBUG_OUT(); +} + +} // namespace akantu + +#endif /* __AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_CC__ */ diff --git a/src/io/model_io.hh b/src/io/model_io.hh deleted file mode 100644 index f008df2c5..000000000 --- a/src/io/model_io.hh +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file model_io.hh - * - * @author Nicolas Richart <nicolas.richart@epfl.ch> - * - * @date creation: Fri Jun 18 2010 - * @date last modification: Sun Oct 19 2014 - * - * @brief Reader for models (this is deprecated) - * - * @section LICENSE - * - * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de - * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des - * Solides) - * - * Akantu is free software: you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Akantu. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifndef __AKANTU_MODEL_IO_HH__ -#define __AKANTU_MODEL_IO_HH__ - -/* -------------------------------------------------------------------------- */ -#include "aka_common.hh" -#include "mesh.hh" -#include "model.hh" -/* -------------------------------------------------------------------------- */ - -namespace akantu { - - - - - -class ModelIO { - /* ------------------------------------------------------------------------ */ - /* Constructors/Destructors */ - /* ------------------------------------------------------------------------ */ -public: - - ModelIO(); - virtual ~ModelIO(); - - /* ------------------------------------------------------------------------ */ - /* Methods */ - /* ------------------------------------------------------------------------ */ -public: - - /// read a model from file - virtual void read(const std::string & filename, Model & model) = 0; - - /// write a mesh to a file - virtual void write(const std::string & filename, const Model & model) = 0; - - - /* ------------------------------------------------------------------------ */ - /* Accessors */ - /* ------------------------------------------------------------------------ */ -public: - - /* ------------------------------------------------------------------------ */ - /* Class Members */ - /* ------------------------------------------------------------------------ */ -private: - -}; - -} // akantu - -#endif /* __AKANTU_MODEL_IO_HH__ */ diff --git a/src/io/model_io/model_io_ibarras.cc b/src/io/model_io/model_io_ibarras.cc deleted file mode 100644 index e30831808..000000000 --- a/src/io/model_io/model_io_ibarras.cc +++ /dev/null @@ -1,313 +0,0 @@ -/** - * @file model_io_ibarras.cc - * - * @author Fabian Barras <fabian.barras@epfl.ch> - * - * @date creation: Thu Feb 21 2013 - * @date last modification: Fri Jan 22 2016 - * - * @brief Mesh Reader specially created for Wood's Tower analysis performed by - * the Institute I-Barras - * - * @section LICENSE - * - * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) - * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) - * - * Akantu is free software: you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Akantu. If not, see <http://www.gnu.org/licenses/>. - * - */ - -/* -------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------- */ - -/* -------------------------------------------------------------------------- */ -#include <fstream> -#include <iostream> - -/* -------------------------------------------------------------------------- */ -#include "model_io_ibarras.hh" -#include "static_communicator.hh" -#include "aka_math.hh" -#include "static_communicator.hh" -#include "sparse_matrix.hh" -#include "solver.hh" -#include "integration_scheme_2nd_order.hh" -/* -------------------------------------------------------------------------- */ -#include <string.h> -/* -------------------------------------------------------------------------- */ -#include <stdio.h> - -namespace akantu { - -/* -------------------------------------------------------------------------- */ -/* Methods Implentations */ -/* -------------------------------------------------------------------------- */ - -void ModelIOIBarras::read(const std::string & filename, Model & mod) { - - if (!dynamic_cast<StructuralMechanicsModel *>(&mod)) { - AKANTU_DEBUG_ERROR(""); - } - - StructuralMechanicsModel & model = - static_cast<StructuralMechanicsModel &>(mod); - Mesh * mesh = new Mesh(3); - - std::ifstream infile; - infile.open(filename.c_str()); - - std::string line; - UInt current_line = 0; - - if (!infile.good()) { - AKANTU_DEBUG_ERROR("Cannot open file " << filename); - } - - // Get Nodes Position - std::getline(infile, line); - current_line++; - std::stringstream sstr(line); - UInt nb_nodes; - sstr >> nb_nodes; - - const UInt spatial_dimension = 3; - Real coord[spatial_dimension]; - Real * temp_nodes = new Real[nb_nodes * spatial_dimension]; - UInt * connect_to_akantu = new UInt[nb_nodes]; - std::fill_n(connect_to_akantu, 0, nb_nodes); - std::fill_n(temp_nodes, 0., nb_nodes * spatial_dimension); - for (UInt i = 0; i < nb_nodes; ++i) { - UInt offset = i * spatial_dimension; - - std::getline(infile, line); - std::stringstream sstr_node(line); - sstr_node >> coord[0] >> coord[1] >> coord[2]; - current_line++; - - /// read the coordinates of structural nodes and help nodes - for (UInt j = 0; j < spatial_dimension; ++j) - temp_nodes[offset + j] = coord[j]; - } - - // Get Connectivities - std::getline(infile, line); - current_line++; - std::stringstream sstr_elem(line); - UInt nb_elements; - sstr_elem >> nb_elements; - - mesh->addConnectivityType(_bernoulli_beam_3); - Array<UInt> & connectivity = - const_cast<Array<UInt> &>(mesh->getConnectivity(_bernoulli_beam_3)); - - connectivity.resize(nb_elements); - - UInt nonodes[2]; - UInt nb_struct_nodes = 1; - for (UInt i = 0; i < nb_elements; ++i) { - - std::getline(infile, line); - std::stringstream sstr_element(line); - sstr_element >> nonodes[0] >> nonodes[1]; - current_line++; - - /// read the connectivities - for (UInt j = 0; j < 2; ++j) { - - if (connect_to_akantu[nonodes[j] - 1] == 0) { - connect_to_akantu[nonodes[j] - 1] = nb_struct_nodes; - ++nb_struct_nodes; - } - connectivity(i, j) = connect_to_akantu[nonodes[j] - 1] - 1; - } - } - nb_struct_nodes -= 1; - - /// read the coordinates of structural nodes - Array<Real> & nodes = const_cast<Array<Real> &>(mesh->getNodes()); - nodes.resize(nb_struct_nodes); - - for (UInt k = 0; k < nb_nodes; ++k) { - if (connect_to_akantu[k] != 0) { - for (UInt j = 0; j < spatial_dimension; ++j) - nodes(connect_to_akantu[k] - 1, j) = - temp_nodes[k * spatial_dimension + j]; - } - } - - // MeshPartitionScotch partition(*mesh, spatial_dimension); - // partition.reorder(); - - /// Apply Boundaries - model.registerFEEngineObject<StructuralMechanicsModel::MyFEEngineType>( - "StructuralMechanicsModel", *mesh, spatial_dimension); - - model.initModel(); - - model.initArrays(); - - Array<bool> & blocked_dofs = model.getBlockedDOFs(); - - std::getline(infile, line); - std::stringstream sstr_nb_boundaries(line); - UInt nb_boundaries; - sstr_nb_boundaries >> nb_boundaries; - current_line++; - - for (UInt i = 0; i < nb_boundaries; ++i) { - std::getline(infile, line); - std::stringstream sstr_boundary(line); - UInt boundnary_node; - sstr_boundary >> boundnary_node; - current_line++; - - for (UInt j = 0; j < spatial_dimension; ++j) - blocked_dofs(connect_to_akantu[boundnary_node - 1] - 1, j) = true; - } - - /// Define Materials - - std::getline(infile, line); - std::stringstream sstr_nb_materials(line); - UInt nb_materials; - sstr_nb_materials >> nb_materials; - current_line++; - - for (UInt i = 0; i < nb_materials; ++i) { - - std::getline(infile, line); - std::stringstream sstr_material(line); - Real material[6]; - sstr_material >> material[0] >> material[1] >> material[2] >> material[3] >> - material[4] >> material[5]; - current_line++; - - StructuralMaterial mat; - mat.E = material[0]; - mat.GJ = material[1] * material[2]; - mat.Iy = material[3]; - mat.Iz = material[4]; - mat.A = material[5]; - - model.addMaterial(mat); - } - - /// Apply normals and Material TO IMPLEMENT - - UInt property[2]; - - Array<UInt> & element_material = model.getElementMaterial(_bernoulli_beam_3); - - mesh->initNormals(); - Array<Real> & normals = - const_cast<Array<Real> &>(mesh->getNormals(_bernoulli_beam_3)); - normals.resize(nb_elements); - - for (UInt i = 0; i < nb_elements; ++i) { - - std::getline(infile, line); - std::stringstream sstr_properties(line); - sstr_properties >> property[0] >> property[1]; - current_line++; - - /// Assign material - element_material(i) = property[0] - 1; - - /// Compute normals - - Real x[3]; - Real v[3]; - Real w[3]; - Real n[3]; - - if (property[1] == 0) { - for (UInt j = 0; j < spatial_dimension; ++j) { - x[j] = nodes(connectivity(i, 1), j) - nodes(connectivity(i, 0), j); - } - n[0] = x[1]; - n[1] = -x[0]; - n[2] = 0.; - - } - - else { - for (UInt j = 0; j < spatial_dimension; ++j) { - x[j] = nodes(connectivity(i, 1), j) - nodes(connectivity(i, 0), j); - v[j] = nodes(connectivity(i, 1), j) - - temp_nodes[(property[1] - 1) * spatial_dimension + j]; - Math::vectorProduct3(x, v, w); - Math::vectorProduct3(x, w, n); - } - } - - Math::normalize3(n); - for (UInt j = 0; j < spatial_dimension; ++j) { - normals(i, j) = n[j]; - } - } - - model.computeRotationMatrix(_bernoulli_beam_3); - infile.close(); -} -/* -------------------------------------------------------------------------- */ -void ModelIOIBarras::assign_sets(const std::string & filename, - StructuralMechanicsModel & model) { - - std::ifstream infile; - infile.open(filename.c_str()); - - std::string line; - UInt current_line = 0; - - if (!infile.good()) { - AKANTU_DEBUG_ERROR("Cannot open file " << filename); - } - - // Define Sets of Beams - - Array<UInt> & set_ID = model.getSet_ID(_bernoulli_beam_3); - set_ID.clear(); - - std::getline(infile, line); - std::stringstream sstr_nb_sets(line); - UInt nb_sets; - sstr_nb_sets >> nb_sets; - current_line++; - - UInt no_element[2]; - - for (UInt i = 0; i < nb_sets; ++i) { - std::getline(infile, line); - std::stringstream sstr_set(line); - sstr_set >> no_element[0]; - no_element[1] = no_element[0]; - sstr_set >> no_element[1]; - - while (no_element[0] != 0) { - - for (UInt j = no_element[0] - 1; j < no_element[1]; ++j) { - set_ID(j) = i + 1; - } - std::getline(infile, line); - std::stringstream sstr_sets(line); - sstr_sets >> no_element[0]; - no_element[1] = no_element[0]; - sstr_sets >> no_element[1]; - } - } -} - -} // akantu diff --git a/src/io/model_io/model_io_ibarras.hh b/src/io/model_io/model_io_ibarras.hh deleted file mode 100644 index b86399428..000000000 --- a/src/io/model_io/model_io_ibarras.hh +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file model_io_ibarras.hh - * - * @author Fabian Barras <fabian.barras@epfl.ch> - * - * @date creation: Fri Jun 18 2010 - * @date last modification: Sun Oct 19 2014 - * - * @brief ModelIO implementation for IBarras input files - * - * @section LICENSE - * - * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de - * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des - * Solides) - * - * Akantu is free software: you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Akantu. If not, see <http://www.gnu.org/licenses/>. - * - */ - -/* -------------------------------------------------------------------------- */ -#ifndef __AKANTU_MODEL_IO_IBARRAS_HH__ -#define __AKANTU_MODEL_IO_IBARRAS_HH__ - -/* -------------------------------------------------------------------------- */ -#include "model_io.hh" -#include "structural_mechanics_model.hh" -/* -------------------------------------------------------------------------- */ - -namespace akantu { - -class ModelIOIBarras : public ModelIO { - /* ------------------------------------------------------------------------ */ - /* Constructors/Destructors */ - /* ------------------------------------------------------------------------ */ -public: - ModelIOIBarras(){}; - virtual ~ModelIOIBarras(){}; - - /* ------------------------------------------------------------------------ */ - /* Methods */ - /* ------------------------------------------------------------------------ */ -public: - /// read a model from the file - virtual void read(const std::string & filename, Model & model); - - /// assign sets of member to an already constructed model - virtual void assign_sets(const std::string & filename, - StructuralMechanicsModel & model); -}; - -} // akantu - -#endif /* __AKANTU_MODEL_IO_IBARRAS_HH__ */ diff --git a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh new file mode 100644 index 000000000..e70bd0a69 --- /dev/null +++ b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_2.hh @@ -0,0 +1,206 @@ +/** + * @file structural_element_bernoulli_beam_2.hh + * + * @author Fabian Barras <fabian.barras@epfl.ch> + * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch> + * @author Nicolas Richart <nicolas.richart@epfl.ch> + * @author Damien Spielmann <damien.spielmann@epfl.ch> + * + * @date creation Tue Sep 19 2017 + * + * @brief Specific functions for bernoulli beam 2d + * + * @section LICENSE + * + * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) + * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * + * Akantu is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Akantu. If not, see <http://www.gnu.org/licenses/>. + * + */ +/* -------------------------------------------------------------------------- */ +#ifndef __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_2_HH__ +#define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_2_HH__ + +namespace akantu { + +inline UInt +StructuralMechanicsModel::getTangentStiffnessVoigtSize<_bernoulli_beam_2>() { + return 2; +} + +/* -------------------------------------------------------------------------- */ +template <> +inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_2>() { + AKANTU_DEBUG_IN(); + + GhostType ghost_type = _not_ghost; + ElementType type = _bernoulli_beam_2; + MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); + UInt nb_element = getFEEngine().getMesh().getNbElement(type); + UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); + UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type); + UInt nb_fields_to_interpolate = + getTangentStiffnessVoigtSize<_bernoulli_beam_2>(); + + UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element; + + Array<Real> * n = + new Array<Real>(nb_element * nb_quadrature_points, + nb_fields_to_interpolate * nt_n_field_size, "N"); + n->clear(); + Array<Real> * rho_field = + new Array<Real>(nb_element * nb_quadrature_points, "Rho"); + rho_field->clear(); + computeRho(*rho_field, type, _not_ghost); + + bool sign = true; + + /* ------------------------------------------------------------------------ */ + fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, + 0, 0, 0, sign, ghost_type); // Ni ui -> u + fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, + 1, 1, 1, sign, ghost_type); // Mi vi -> v + fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, + 2, 2, 1, sign, ghost_type); // Li Theta_i -> v + /* ------------------------------------------------------------------------ */ + fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n, + rotation_matrix, type, ghost_type); + + delete n; + delete rho_field; + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +template <> +void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_2>( + Array<Real> & rotations) { + + ElementType type = _bernoulli_beam_2; + Mesh & mesh = getFEEngine().getMesh(); + UInt nb_element = mesh.getNbElement(type); + + Array<UInt>::iterator<Vector<UInt> > connec_it = + mesh.getConnectivity(type).begin(2); + Array<Real>::vector_iterator nodes_it = + mesh.getNodes().begin(spatial_dimension); + Array<Real>::matrix_iterator R_it = + rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom); + + for (UInt e = 0; e < nb_element; ++e, ++R_it, ++connec_it) { + Matrix<Real> & R = *R_it; + Vector<UInt> & connec = *connec_it; + + Vector<Real> x2; + x2 = nodes_it[connec(1)]; // X2 + Vector<Real> x1; + x1 = nodes_it[connec(0)]; // X1 + + Real le = x1.distance(x2); + Real c = (x2(0) - x1(0)) / le; + Real s = (x2(1) - x1(1)) / le; + + /// Definition of the rotation matrix + R(0, 0) = c; + R(0, 1) = s; + R(0, 2) = 0.; + R(1, 0) = -s; + R(1, 1) = c; + R(1, 2) = 0.; + R(2, 0) = 0.; + R(2, 1) = 0.; + R(2, 2) = 1.; + } +} + +/* -------------------------------------------------------------------------- */ +template <> +void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_2>( + Array<Real> & tangent_moduli) { + UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2); + UInt nb_quadrature_points = + getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2); + UInt tangent_size = 2; + + Array<Real>::matrix_iterator D_it = + tangent_moduli.begin(tangent_size, tangent_size); + Array<UInt> & el_mat = element_material(_bernoulli_beam_2, _not_ghost); + + for (UInt e = 0; e < nb_element; ++e) { + UInt mat = el_mat(e); + Real E = materials[mat].E; + Real A = materials[mat].A; + Real I = materials[mat].I; + for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) { + Matrix<Real> & D = *D_it; + D(0, 0) = E * A; + D(1, 1) = E * I; + } + } +} + +/* -------------------------------------------------------------------------- */ +template <> +void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix< + _bernoulli_beam_2>(Array<Real> & b, bool) { + UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2); + UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_bernoulli_beam_2); + UInt nb_quadrature_points = + getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2); + + MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); + Array<Real>::const_vector_iterator shape_Np = + fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 0) + .begin(nb_nodes_per_element); + Array<Real>::const_vector_iterator shape_Mpp = + fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 1) + .begin(nb_nodes_per_element); + Array<Real>::const_vector_iterator shape_Lpp = + fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 2) + .begin(nb_nodes_per_element); + + UInt tangent_size = getTangentStiffnessVoigtSize<_bernoulli_beam_2>(); + UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom; + b.clear(); + Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size); + + for (UInt e = 0; e < nb_element; ++e) { + for (UInt q = 0; q < nb_quadrature_points; ++q) { + Matrix<Real> & B = *B_it; + const Vector<Real> & Np = *shape_Np; + const Vector<Real> & Lpp = *shape_Lpp; + const Vector<Real> & Mpp = *shape_Mpp; + + B(0, 0) = Np(0); + B(0, 3) = Np(1); + + B(1, 1) = Mpp(0); + B(1, 2) = Lpp(0); + B(1, 4) = Mpp(1); + B(1, 5) = Lpp(1); + + ++B_it; + ++shape_Np; + ++shape_Mpp; + ++shape_Lpp; + } + + // ++R_it; + } +} + +} // akantu + +#endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_2_HH__ */ diff --git a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh new file mode 100644 index 000000000..65a0f7246 --- /dev/null +++ b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh @@ -0,0 +1,250 @@ +/** + * @file structural_element_bernoulli_beam_3.hh + * + * @author Fabian Barras <fabian.barras@epfl.ch> + * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch> + * @author Nicolas Richart <nicolas.richart@epfl.ch> + * @author Damien Spielmann <damien.spielmann@epfl.ch> + * + * @date creation Tue Sep 19 2017 + * + * @brief Specific functions for bernoulli beam 3d + * + * @section LICENSE + * + * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) + * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * + * Akantu is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Akantu. If not, see <http://www.gnu.org/licenses/>. + * + */ +/* -------------------------------------------------------------------------- */ +#ifndef __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__ +#define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__ + +namespace akantu { + +inline UInt +StructuralMechanicsModel::getTangentStiffnessVoigtSize<_bernoulli_beam_3>() { + return 4; +} + +/* -------------------------------------------------------------------------- */ +template <> +inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_3>() { + AKANTU_DEBUG_IN(); + + GhostType ghost_type = _not_ghost; + ElementType type = _bernoulli_beam_3; + MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); + UInt nb_element = getFEEngine().getMesh().getNbElement(type); + UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); + UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type); + UInt nb_fields_to_interpolate = + getTangentStiffnessVoigtSize<_bernoulli_beam_3>(); + + UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element; + + Array<Real> * n = + new Array<Real>(nb_element * nb_quadrature_points, + nb_fields_to_interpolate * nt_n_field_size, "N"); + n->clear(); + Array<Real> * rho_field = + new Array<Real>(nb_element * nb_quadrature_points, "Rho"); + rho_field->clear(); + computeRho(*rho_field, type, _not_ghost); + + /* -------------------------------------------------------------------------- + */ + fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, + 0, 0, 0, true, ghost_type); // Ni ui -> u + + fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, + 1, 1, 1, true, ghost_type); // Mi vi -> v + fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, + 2, 5, 1, true, ghost_type); // Li Theta_z_i -> v + + fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, + 1, 2, 2, true, ghost_type); // Mi wi -> w + fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, + 2, 4, 2, false, ghost_type); // -Li Theta_y_i -> w + + fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, + 0, 3, 3, true, ghost_type); // Ni Theta_x_i->Theta_x + /* -------------------------------------------------------------------------- + */ + + fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n, + rotation_matrix, type, ghost_type); + + delete n; + delete rho_field; + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +template <> +void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_3>( + Array<Real> & rotations) { + ElementType type = _bernoulli_beam_3; + Mesh & mesh = getFEEngine().getMesh(); + UInt nb_element = mesh.getNbElement(type); + + Array<Real>::vector_iterator n_it = + mesh.getNormals(type).begin(spatial_dimension); + Array<UInt>::iterator<Vector<UInt> > connec_it = + mesh.getConnectivity(type).begin(2); + Array<Real>::vector_iterator nodes_it = + mesh.getNodes().begin(spatial_dimension); + + Matrix<Real> Pe(spatial_dimension, spatial_dimension); + Matrix<Real> Pg(spatial_dimension, spatial_dimension); + Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension); + Vector<Real> x_n(spatial_dimension); // x vect n + + Array<Real>::matrix_iterator R_it = + rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom); + + for (UInt e = 0; e < nb_element; ++e, ++n_it, ++connec_it, ++R_it) { + Vector<Real> & n = *n_it; + Matrix<Real> & R = *R_it; + Vector<UInt> & connec = *connec_it; + + Vector<Real> x; + x = nodes_it[connec(1)]; // X2 + Vector<Real> y; + y = nodes_it[connec(0)]; // X1 + + Real l = x.distance(y); + x -= y; // X2 - X1 + x_n.crossProduct(x, n); + + Pe.eye(); + Pe(0, 0) *= l; + Pe(1, 1) *= -l; + + Pg(0, 0) = x(0); + Pg(0, 1) = x_n(0); + Pg(0, 2) = n(0); + Pg(1, 0) = x(1); + Pg(1, 1) = x_n(1); + Pg(1, 2) = n(1); + Pg(2, 0) = x(2); + Pg(2, 1) = x_n(2); + Pg(2, 2) = n(2); + + inv_Pg.inverse(Pg); + + Pe *= inv_Pg; + for (UInt i = 0; i < spatial_dimension; ++i) { + for (UInt j = 0; j < spatial_dimension; ++j) { + R(i, j) = Pe(i, j); + R(i + spatial_dimension, j + spatial_dimension) = Pe(i, j); + } + } + } +} + +/* -------------------------------------------------------------------------- */ +template <> +void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_3>( + Array<Real> & tangent_moduli) { + UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3); + UInt nb_quadrature_points = + getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3); + UInt tangent_size = 4; + + Array<Real>::matrix_iterator D_it = + tangent_moduli.begin(tangent_size, tangent_size); + + for (UInt e = 0; e < nb_element; ++e) { + UInt mat = element_material(_bernoulli_beam_3, _not_ghost)(e); + Real E = materials[mat].E; + Real A = materials[mat].A; + Real Iz = materials[mat].Iz; + Real Iy = materials[mat].Iy; + Real GJ = materials[mat].GJ; + for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) { + Matrix<Real> & D = *D_it; + D(0, 0) = E * A; + D(1, 1) = E * Iz; + D(2, 2) = E * Iy; + D(3, 3) = GJ; + } + } +} + +/* -------------------------------------------------------------------------- */ +template <> +void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix< + _bernoulli_beam_3>(Array<Real> & b, bool) { + MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); + + UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3); + UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_bernoulli_beam_3); + UInt nb_quadrature_points = + getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3); + + Array<Real>::const_vector_iterator shape_Np = + fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 0) + .begin(nb_nodes_per_element); + Array<Real>::const_vector_iterator shape_Mpp = + fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 1) + .begin(nb_nodes_per_element); + Array<Real>::const_vector_iterator shape_Lpp = + fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 2) + .begin(nb_nodes_per_element); + + UInt tangent_size = getTangentStiffnessVoigtSize<_bernoulli_beam_3>(); + UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom; + + b.clear(); + + Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size); + + for (UInt e = 0; e < nb_element; ++e) { + for (UInt q = 0; q < nb_quadrature_points; ++q) { + Matrix<Real> & B = *B_it; + + const Vector<Real> & Np = *shape_Np; + const Vector<Real> & Lpp = *shape_Lpp; + const Vector<Real> & Mpp = *shape_Mpp; + + B(0, 0) = Np(0); + B(0, 6) = Np(1); + + B(1, 1) = Mpp(0); + B(1, 5) = Lpp(0); + B(1, 7) = Mpp(1); + B(1, 11) = Lpp(1); + + B(2, 2) = Mpp(0); + B(2, 4) = -Lpp(0); + B(2, 8) = Mpp(1); + B(2, 10) = -Lpp(1); + + B(3, 3) = Np(0); + B(3, 9) = Np(1); + + ++B_it; + ++shape_Np; + ++shape_Mpp; + ++shape_Lpp; + } + } +} + +} // akantu + +#endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__ */ diff --git a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_kirchhoff_shell.hh b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_kirchhoff_shell.hh new file mode 100644 index 000000000..68a9900dd --- /dev/null +++ b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_kirchhoff_shell.hh @@ -0,0 +1,250 @@ +/** + * @file structural_element_bernoulli_kirchhoff_shell.hh + * + * @author Fabian Barras <fabian.barras@epfl.ch> + * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch> + * @author Nicolas Richart <nicolas.richart@epfl.ch> + * @author Damien Spielmann <damien.spielmann@epfl.ch> + * + * @date creation Tue Sep 19 2017 + * + * @brief Specific functions for bernoulli kirchhoff shell + * + * @section LICENSE + * + * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) + * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * + * Akantu is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Akantu. If not, see <http://www.gnu.org/licenses/>. + * + */ +/* -------------------------------------------------------------------------- */ +#ifndef __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_KIRCHHOFF_SHELL_HH__ +#define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_KIRCHHOFF_SHELL_HH__ + +namespace akantu { + +inline UInt +StructuralMechanicsModel::getTangentStiffnessVoigtSize<_bernoulli_kirchhoff_shell>() { + return 6; +} + +/* -------------------------------------------------------------------------- */ +template <> +inline void StructuralMechanicsModel::assembleMass<_kirchhoff_shell>() { + + AKANTU_DEBUG_TO_IMPLEMENT(); +} + +/* -------------------------------------------------------------------------- */ +template <> +void StructuralMechanicsModel::computeRotationMatrix<_kirchhoff_shell>( + Array<Real> & rotations) { + ElementType type = _kirchhoff_shell; + Mesh & mesh = getFEEngine().getMesh(); + UInt nb_element = mesh.getNbElement(type); + + Array<UInt>::iterator<Vector<UInt> > connec_it = + mesh.getConnectivity(type).begin(3); + Array<Real>::vector_iterator nodes_it = + mesh.getNodes().begin(spatial_dimension); + + Matrix<Real> Pe(spatial_dimension, spatial_dimension); + Matrix<Real> Pg(spatial_dimension, spatial_dimension); + Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension); + + Array<Real>::matrix_iterator R_it = + rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom); + + for (UInt e = 0; e < nb_element; ++e, ++connec_it, ++R_it) { + + Pe.eye(); + + Matrix<Real> & R = *R_it; + Vector<UInt> & connec = *connec_it; + + Vector<Real> x2; + x2 = nodes_it[connec(1)]; // X2 + Vector<Real> x1; + x1 = nodes_it[connec(0)]; // X1 + Vector<Real> x3; + x3 = nodes_it[connec(2)]; // X3 + + Vector<Real> Pg_col_1 = x2 - x1; + + Vector<Real> Pg_col_2 = x3 - x1; + + Vector<Real> Pg_col_3(spatial_dimension); + Pg_col_3.crossProduct(Pg_col_1, Pg_col_2); + + for (UInt i = 0; i < spatial_dimension; ++i) { + Pg(i, 0) = Pg_col_1(i); + Pg(i, 1) = Pg_col_2(i); + Pg(i, 2) = Pg_col_3(i); + } + + inv_Pg.inverse(Pg); + // Pe *= inv_Pg; + Pe.eye(); + + for (UInt i = 0; i < spatial_dimension; ++i) { + for (UInt j = 0; j < spatial_dimension; ++j) { + R(i, j) = Pe(i, j); + R(i + spatial_dimension, j + spatial_dimension) = Pe(i, j); + } + } + } +} + +/* -------------------------------------------------------------------------- */ +template <> +void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_3>( + Array<Real> & tangent_moduli) { + UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3); + UInt nb_quadrature_points = + getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3); + UInt tangent_size = 4; + + Array<Real>::matrix_iterator D_it = + tangent_moduli.begin(tangent_size, tangent_size); + + for (UInt e = 0; e < nb_element; ++e) { + UInt mat = element_material(_bernoulli_beam_3, _not_ghost)(e); + Real E = materials[mat].E; + Real A = materials[mat].A; + Real Iz = materials[mat].Iz; + Real Iy = materials[mat].Iy; + Real GJ = materials[mat].GJ; + for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) { + Matrix<Real> & D = *D_it; + D(0, 0) = E * A; + D(1, 1) = E * Iz; + D(2, 2) = E * Iy; + D(3, 3) = GJ; + } + } +} + +/* -------------------------------------------------------------------------- */ +template <> +void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix< + _kirchhoff_shell>(Array<Real> & b, __attribute__((unused)) bool local) { + MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); + + UInt nb_element = getFEEngine().getMesh().getNbElement(_kirchhoff_shell); + UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_kirchhoff_shell); + UInt nb_quadrature_points = + getFEEngine().getNbIntegrationPoints(_kirchhoff_shell); + + Array<Real>::const_matrix_iterator shape_Np = + fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 0) + .begin(2, nb_nodes_per_element); + Array<Real>::const_matrix_iterator shape_Nx1p = + fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 1) + .begin(2, nb_nodes_per_element); + Array<Real>::const_matrix_iterator shape_Nx2p = + fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 2) + .begin(2, nb_nodes_per_element); + Array<Real>::const_matrix_iterator shape_Nx3p = + fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 3) + .begin(2, nb_nodes_per_element); + Array<Real>::const_matrix_iterator shape_Ny1p = + fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 4) + .begin(2, nb_nodes_per_element); + Array<Real>::const_matrix_iterator shape_Ny2p = + fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 5) + .begin(2, nb_nodes_per_element); + Array<Real>::const_matrix_iterator shape_Ny3p = + fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 6) + .begin(2, nb_nodes_per_element); + + UInt tangent_size = getTangentStiffnessVoigtSize<_kirchhoff_shell>(); + UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom; + + b.clear(); + + Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size); + + for (UInt e = 0; e < nb_element; ++e) { + for (UInt q = 0; q < nb_quadrature_points; ++q) { + Matrix<Real> & B = *B_it; + + const Matrix<Real> & Np = *shape_Np; + const Matrix<Real> & Nx1p = *shape_Nx1p; + const Matrix<Real> & Nx2p = *shape_Nx2p; + const Matrix<Real> & Nx3p = *shape_Nx3p; + const Matrix<Real> & Ny1p = *shape_Ny1p; + const Matrix<Real> & Ny2p = *shape_Ny2p; + const Matrix<Real> & Ny3p = *shape_Ny3p; + + B(0, 0) = Np(0, 0); + B(0, 6) = Np(0, 1); + B(0, 12) = Np(0, 2); + + B(1, 1) = Np(1, 0); + B(1, 7) = Np(1, 1); + B(1, 13) = Np(1, 2); + + B(2, 0) = Np(1, 0); + B(2, 1) = Np(0, 0); + B(2, 6) = Np(1, 1); + B(2, 7) = Np(0, 1); + B(2, 12) = Np(1, 2); + B(2, 13) = Np(0, 2); + + B(3, 2) = Nx1p(0, 0); + B(3, 3) = Nx2p(0, 0); + B(3, 4) = Nx3p(0, 0); + B(3, 8) = Nx1p(0, 1); + B(3, 9) = Nx2p(0, 1); + B(3, 10) = Nx3p(0, 1); + B(3, 14) = Nx1p(0, 2); + B(3, 15) = Nx2p(0, 2); + B(3, 16) = Nx3p(0, 2); + + B(4, 2) = Ny1p(1, 0); + B(4, 3) = Ny2p(1, 0); + B(4, 4) = Ny3p(1, 0); + B(4, 8) = Ny1p(1, 1); + B(4, 9) = Ny2p(1, 1); + B(4, 10) = Ny3p(1, 1); + B(4, 14) = Ny1p(1, 2); + B(4, 15) = Ny2p(1, 2); + B(4, 16) = Ny3p(1, 2); + + B(5, 2) = Nx1p(1, 0) + Ny1p(0, 0); + B(5, 3) = Nx2p(1, 0) + Ny2p(0, 0); + B(5, 4) = Nx3p(1, 0) + Ny3p(0, 0); + B(5, 8) = Nx1p(1, 1) + Ny1p(0, 1); + B(5, 9) = Nx2p(1, 1) + Ny2p(0, 1); + B(5, 10) = Nx3p(1, 1) + Ny3p(0, 1); + B(5, 14) = Nx1p(1, 2) + Ny1p(0, 2); + B(5, 15) = Nx2p(1, 2) + Ny2p(0, 2); + B(5, 16) = Nx3p(1, 2) + Ny3p(0, 2); + + ++B_it; + ++shape_Np; + ++shape_Nx1p; + ++shape_Nx2p; + ++shape_Nx3p; + ++shape_Ny1p; + ++shape_Ny2p; + ++shape_Ny3p; + } + } +} + +} // akantu + +#endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_KIRCHHOFF_SHELL_HH__ */ diff --git a/src/model/structural_mechanics/structural_mechanics_model.cc b/src/model/structural_mechanics/structural_mechanics_model.cc index d9666b590..e54ec05f2 100644 --- a/src/model/structural_mechanics/structural_mechanics_model.cc +++ b/src/model/structural_mechanics/structural_mechanics_model.cc @@ -1,1225 +1,326 @@ /** * @file structural_mechanics_model.cc * * @author Fabian Barras <fabian.barras@epfl.ch> * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * @author Damien Spielmann <damien.spielmann@epfl.ch> * * @date creation: Fri Jul 15 2011 * @date last modification: Thu Oct 15 2015 * * @brief Model implementation for StucturalMechanics elements * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include "structural_mechanics_model.hh" -#include "group_manager_inline_impl.cc" -#include "dumpable_inline_impl.hh" -#include "aka_math.hh" -#include "integration_scheme_2nd_order.hh" -#include "static_communicator.hh" +#include "dof_manager.hh" #include "sparse_matrix.hh" -#include "solver.hh" - -#ifdef AKANTU_USE_MUMPS -#include "solver_mumps.hh" -#endif +/* -------------------------------------------------------------------------- */ #ifdef AKANTU_USE_IOHELPER -#include "dumper_paraview.hh" #include "dumper_elemental_field.hh" +#include "dumper_paraview.hh" #endif /* -------------------------------------------------------------------------- */ namespace akantu { -const StructuralMechanicsModelOptions - default_structural_mechanics_model_options(_static); - /* -------------------------------------------------------------------------- */ StructuralMechanicsModel::StructuralMechanicsModel(Mesh & mesh, UInt dim, const ID & id, const MemoryID & memory_id) : Model(mesh, dim, id, memory_id), time_step(NAN), f_m2a(1.0), stress("stress", id, memory_id), element_material("element_material", id, memory_id), - set_ID("beam sets", id, memory_id), stiffness_matrix(NULL), - mass_matrix(NULL), velocity_damping_matrix(NULL), jacobian_matrix(NULL), - solver(NULL), rotation_matrix("rotation_matices", id, memory_id), - increment_flag(false), integrator(NULL) { + set_ID("beam sets", id, memory_id), + rotation_matrix("rotation_matices", id, memory_id) { AKANTU_DEBUG_IN(); registerFEEngineObject<MyFEEngineType>("StructuralMechanicsFEEngine", mesh, spatial_dimension); - this->displacement_rotation = NULL; - this->mass = NULL; - this->velocity = NULL; - this->acceleration = NULL; - this->force_momentum = NULL; - this->residual = NULL; - this->blocked_dofs = NULL; - this->increment = NULL; - - this->previous_displacement = NULL; - if (spatial_dimension == 2) nb_degree_of_freedom = 3; else if (spatial_dimension == 3) nb_degree_of_freedom = 6; else { AKANTU_DEBUG_TO_IMPLEMENT(); } +#ifdef AKANTU_USE_IOHELPER this->mesh.registerDumper<DumperParaview>("paraview_all", id, true); +#endif this->mesh.addDumpMesh(mesh, spatial_dimension, _not_ghost, _ek_structural); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -StructuralMechanicsModel::~StructuralMechanicsModel() { - AKANTU_DEBUG_IN(); - - delete integrator; - delete solver; - delete stiffness_matrix; - delete jacobian_matrix; - delete mass_matrix; - delete velocity_damping_matrix; - - AKANTU_DEBUG_OUT(); -} +StructuralMechanicsModel::~StructuralMechanicsModel() = default; +/* -------------------------------------------------------------------------- */ void StructuralMechanicsModel::setTimeStep(Real time_step) { this->time_step = time_step; #if defined(AKANTU_USE_IOHELPER) this->mesh.getDumper().setTimeStep(time_step); #endif } /* -------------------------------------------------------------------------- */ /* Initialisation */ /* -------------------------------------------------------------------------- */ +void StructuralMechanicsModel::initSolver( + TimeStepSolverType time_step_solver_type, NonLinearSolverType) { + AKANTU_DEBUG_IN(); -void StructuralMechanicsModel::initFull(const ModelOptions & options) { - - const StructuralMechanicsModelOptions & stmm_options = - dynamic_cast<const StructuralMechanicsModelOptions &>(options); - - method = stmm_options.analysis_method; - - initModel(); - initArrays(); - - displacement_rotation->clear(); - velocity->clear(); - acceleration->clear(); - force_momentum->clear(); - residual->clear(); - blocked_dofs->clear(); - increment->clear(); + this->allocNodalField(displacement_rotation, nb_degree_of_freedom, + "displacement"); + this->allocNodalField(external_force_momentum, nb_degree_of_freedom, + "external_force"); + this->allocNodalField(internal_force_momentum, nb_degree_of_freedom, + "internal_force"); + this->allocNodalField(blocked_dofs, spatial_dimension, "blocked_dofs"); - Mesh::type_iterator it = getFEEngine().getMesh().firstType( - spatial_dimension, _not_ghost, _ek_structural); - Mesh::type_iterator end = getFEEngine().getMesh().lastType( - spatial_dimension, _not_ghost, _ek_structural); - for (; it != end; ++it) { - computeRotationMatrix(*it); - } + auto & dof_manager = this->getDOFManager(); - switch (method) { - case _implicit_dynamic: - initImplicit(); - break; - case _static: - initSolver(); - break; - default: - AKANTU_EXCEPTION( - "analysis method not recognised by StructuralMechanicsModel"); - break; + if (!dof_manager.hasDOFs("displacement")) { + dof_manager.registerDOFs("displacement", *displacement_rotation, + _dst_nodal); + dof_manager.registerBlockedDOFs("displacement", *this->blocked_dofs); } -} -/* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::initArrays() { - AKANTU_DEBUG_IN(); + if (time_step_solver_type == _tsst_dynamic || + time_step_solver_type == _tsst_dynamic_lumped) { + this->allocNodalField(velocity, spatial_dimension, "velocity"); + this->allocNodalField(acceleration, spatial_dimension, "acceleration"); - UInt nb_nodes = getFEEngine().getMesh().getNbNodes(); - std::stringstream sstr_disp; - sstr_disp << id << ":displacement"; - std::stringstream sstr_velo; - sstr_velo << id << ":velocity"; - std::stringstream sstr_acce; - sstr_acce << id << ":acceleration"; - std::stringstream sstr_forc; - sstr_forc << id << ":force"; - std::stringstream sstr_resi; - sstr_resi << id << ":residual"; - std::stringstream sstr_boun; - sstr_boun << id << ":blocked_dofs"; - std::stringstream sstr_incr; - sstr_incr << id << ":increment"; - - displacement_rotation = &(alloc<Real>(sstr_disp.str(), nb_nodes, - nb_degree_of_freedom, REAL_INIT_VALUE)); - velocity = &(alloc<Real>(sstr_velo.str(), nb_nodes, nb_degree_of_freedom, - REAL_INIT_VALUE)); - acceleration = &(alloc<Real>(sstr_acce.str(), nb_nodes, nb_degree_of_freedom, - REAL_INIT_VALUE)); - force_momentum = &(alloc<Real>(sstr_forc.str(), nb_nodes, - nb_degree_of_freedom, REAL_INIT_VALUE)); - residual = &(alloc<Real>(sstr_resi.str(), nb_nodes, nb_degree_of_freedom, - REAL_INIT_VALUE)); - blocked_dofs = - &(alloc<bool>(sstr_boun.str(), nb_nodes, nb_degree_of_freedom, false)); - increment = &(alloc<Real>(sstr_incr.str(), nb_nodes, nb_degree_of_freedom, - REAL_INIT_VALUE)); - - Mesh::type_iterator it = getFEEngine().getMesh().firstType( - spatial_dimension, _not_ghost, _ek_structural); - Mesh::type_iterator end = getFEEngine().getMesh().lastType( - spatial_dimension, _not_ghost, _ek_structural); - for (; it != end; ++it) { - UInt nb_element = getFEEngine().getMesh().getNbElement(*it); - UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(*it); - - element_material.alloc(nb_element, 1, *it, _not_ghost); - set_ID.alloc(nb_element, 1, *it, _not_ghost); - - UInt size = getTangentStiffnessVoigtSize(*it); - stress.alloc(nb_element * nb_quadrature_points, size, *it, _not_ghost); + if (!dof_manager.hasDOFsDerivatives("displacement", 1)) { + dof_manager.registerDOFsDerivative("displacement", 1, *this->velocity); + dof_manager.registerDOFsDerivative("displacement", 2, + *this->acceleration); + } } - dof_synchronizer = - new DOFSynchronizer(getFEEngine().getMesh(), nb_degree_of_freedom); - dof_synchronizer->initLocalDOFEquationNumbers(); - dof_synchronizer->initGlobalDOFEquationNumbers(); - AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void StructuralMechanicsModel::initModel() { - getFEEngine().initShapeFunctions(_not_ghost); -} - -/* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::initSolver(__attribute__((unused)) - SolverOptions & options) { - AKANTU_DEBUG_IN(); - - const Mesh & mesh = getFEEngine().getMesh(); -#if !defined(AKANTU_USE_MUMPS) // or other solver in the future \todo add - // AKANTU_HAS_SOLVER in CMake - AKANTU_DEBUG_ERROR("You should at least activate one solver."); -#else - UInt nb_global_node = mesh.getNbGlobalNodes(); - - std::stringstream sstr; - sstr << id << ":jacobian_matrix"; - jacobian_matrix = new SparseMatrix(nb_global_node * nb_degree_of_freedom, - _symmetric, sstr.str(), memory_id); - - jacobian_matrix->buildProfile(mesh, *dof_synchronizer, nb_degree_of_freedom); - - std::stringstream sstr_sti; - sstr_sti << id << ":stiffness_matrix"; - stiffness_matrix = - new SparseMatrix(*jacobian_matrix, sstr_sti.str(), memory_id); - -#ifdef AKANTU_USE_MUMPS - std::stringstream sstr_solv; - sstr_solv << id << ":solver"; - solver = new SolverMumps(*jacobian_matrix, sstr_solv.str()); - - dof_synchronizer->initScatterGatherCommunicationScheme(); -#else - AKANTU_DEBUG_ERROR("You should at least activate one solver."); -#endif // AKANTU_USE_MUMPS - - solver->initialize(options); -#endif // AKANTU_HAS_SOLVER - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::initImplicit( - __attribute__((unused)) bool dynamic, SolverOptions & solver_options) { - AKANTU_DEBUG_IN(); - - if (!increment) - setIncrementFlagOn(); - - initSolver(solver_options); - - if (integrator) - delete integrator; - integrator = new TrapezoidalRule2(); + for (auto && type : + mesh.elementTypes(spatial_dimension, _not_ghost, _ek_structural)) { + computeRotationMatrix(type); + } - AKANTU_DEBUG_OUT(); + getFEEngine().initShapeFunctions(_not_ghost); + getFEEngine().initShapeFunctions(_ghost); } /* -------------------------------------------------------------------------- */ UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize( const ElementType & type) { UInt size; #define GET_TANGENT_STIFFNESS_VOIGT_SIZE(type) \ size = getTangentStiffnessVoigtSize<type>(); AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(GET_TANGENT_STIFFNESS_VOIGT_SIZE); #undef GET_TANGENT_STIFFNESS_VOIGT_SIZE return size; } /* -------------------------------------------------------------------------- */ void StructuralMechanicsModel::assembleStiffnessMatrix() { AKANTU_DEBUG_IN(); - stiffness_matrix->clear(); - - Mesh::type_iterator it = getFEEngine().getMesh().firstType( - spatial_dimension, _not_ghost, _ek_structural); - Mesh::type_iterator end = getFEEngine().getMesh().lastType( - spatial_dimension, _not_ghost, _ek_structural); - for (; it != end; ++it) { - ElementType type = *it; + getDOFManager().getMatrix("K").clear(); + for (auto & type : mesh.elementTypes(_spatial_dimension = spatial_dimension, + _element_kind = _ek_structural)) { #define ASSEMBLE_STIFFNESS_MATRIX(type) assembleStiffnessMatrix<type>(); AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(ASSEMBLE_STIFFNESS_MATRIX); #undef ASSEMBLE_STIFFNESS_MATRIX } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template <> -void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_2>( - Array<Real> & rotations) { - - ElementType type = _bernoulli_beam_2; - Mesh & mesh = getFEEngine().getMesh(); - UInt nb_element = mesh.getNbElement(type); +void StructuralMechanicsModel::computeStresses() { + AKANTU_DEBUG_IN(); - Array<UInt>::iterator<Vector<UInt> > connec_it = - mesh.getConnectivity(type).begin(2); - Array<Real>::vector_iterator nodes_it = - mesh.getNodes().begin(spatial_dimension); - Array<Real>::matrix_iterator R_it = - rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom); - - for (UInt e = 0; e < nb_element; ++e, ++R_it, ++connec_it) { - Matrix<Real> & R = *R_it; - Vector<UInt> & connec = *connec_it; - - Vector<Real> x2; - x2 = nodes_it[connec(1)]; // X2 - Vector<Real> x1; - x1 = nodes_it[connec(0)]; // X1 - - Real le = x1.distance(x2); - Real c = (x2(0) - x1(0)) / le; - Real s = (x2(1) - x1(1)) / le; - - /// Definition of the rotation matrix - R(0, 0) = c; - R(0, 1) = s; - R(0, 2) = 0.; - R(1, 0) = -s; - R(1, 1) = c; - R(1, 2) = 0.; - R(2, 0) = 0.; - R(2, 1) = 0.; - R(2, 2) = 1.; - } -} + for (auto & type : mesh.elementTypes(_spatial_dimension = spatial_dimension, + _element_kind = _ek_structural)) { -/* -------------------------------------------------------------------------- */ -template <> -void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_3>( - Array<Real> & rotations) { - ElementType type = _bernoulli_beam_3; - Mesh & mesh = getFEEngine().getMesh(); - UInt nb_element = mesh.getNbElement(type); +#define COMPUTE_STRESS_ON_QUAD(type) computeStressOnQuad<type>(); - Array<Real>::vector_iterator n_it = - mesh.getNormals(type).begin(spatial_dimension); - Array<UInt>::iterator<Vector<UInt> > connec_it = - mesh.getConnectivity(type).begin(2); - Array<Real>::vector_iterator nodes_it = - mesh.getNodes().begin(spatial_dimension); - - Matrix<Real> Pe(spatial_dimension, spatial_dimension); - Matrix<Real> Pg(spatial_dimension, spatial_dimension); - Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension); - Vector<Real> x_n(spatial_dimension); // x vect n - - Array<Real>::matrix_iterator R_it = - rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom); - - for (UInt e = 0; e < nb_element; ++e, ++n_it, ++connec_it, ++R_it) { - Vector<Real> & n = *n_it; - Matrix<Real> & R = *R_it; - Vector<UInt> & connec = *connec_it; - - Vector<Real> x; - x = nodes_it[connec(1)]; // X2 - Vector<Real> y; - y = nodes_it[connec(0)]; // X1 - - Real l = x.distance(y); - x -= y; // X2 - X1 - x_n.crossProduct(x, n); - - Pe.eye(); - Pe(0, 0) *= l; - Pe(1, 1) *= -l; - - Pg(0, 0) = x(0); - Pg(0, 1) = x_n(0); - Pg(0, 2) = n(0); - Pg(1, 0) = x(1); - Pg(1, 1) = x_n(1); - Pg(1, 2) = n(1); - Pg(2, 0) = x(2); - Pg(2, 1) = x_n(2); - Pg(2, 2) = n(2); - - inv_Pg.inverse(Pg); - - Pe *= inv_Pg; - for (UInt i = 0; i < spatial_dimension; ++i) { - for (UInt j = 0; j < spatial_dimension; ++j) { - R(i, j) = Pe(i, j); - R(i + spatial_dimension, j + spatial_dimension) = Pe(i, j); - } - } + AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_STRESS_ON_QUAD); +#undef COMPUTE_STRESS_ON_QUAD } + + AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template <> -void StructuralMechanicsModel::computeRotationMatrix<_kirchhoff_shell>( - Array<Real> & rotations) { - ElementType type = _kirchhoff_shell; - Mesh & mesh = getFEEngine().getMesh(); - UInt nb_element = mesh.getNbElement(type); - - Array<UInt>::iterator<Vector<UInt> > connec_it = - mesh.getConnectivity(type).begin(3); - Array<Real>::vector_iterator nodes_it = - mesh.getNodes().begin(spatial_dimension); - - Matrix<Real> Pe(spatial_dimension, spatial_dimension); - Matrix<Real> Pg(spatial_dimension, spatial_dimension); - Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension); - - Array<Real>::matrix_iterator R_it = - rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom); - - for (UInt e = 0; e < nb_element; ++e, ++connec_it, ++R_it) { - - Pe.eye(); - - Matrix<Real> & R = *R_it; - Vector<UInt> & connec = *connec_it; - - Vector<Real> x2; - x2 = nodes_it[connec(1)]; // X2 - Vector<Real> x1; - x1 = nodes_it[connec(0)]; // X1 - Vector<Real> x3; - x3 = nodes_it[connec(2)]; // X3 - - Vector<Real> Pg_col_1 = x2 - x1; +void StructuralMechanicsModel::updateResidual() { + AKANTU_DEBUG_IN(); - Vector<Real> Pg_col_2 = x3 - x1; + auto & K = getDOFManager().getMatrix("K"); - Vector<Real> Pg_col_3(spatial_dimension); - Pg_col_3.crossProduct(Pg_col_1, Pg_col_2); + internal_force_momentum->clear(); + K.matVecMul(*displacement_rotation, *internal_force_momentum); + *internal_force_momentum *= -1.; - for (UInt i = 0; i < spatial_dimension; ++i) { - Pg(i, 0) = Pg_col_1(i); - Pg(i, 1) = Pg_col_2(i); - Pg(i, 2) = Pg_col_3(i); - } + getDOFManager().assembleToResidual("displacement", *external_force_momentum, + 1.); - inv_Pg.inverse(Pg); - // Pe *= inv_Pg; - Pe.eye(); + getDOFManager().assembleToResidual("displacement", *internal_force_momentum, + 1.); - for (UInt i = 0; i < spatial_dimension; ++i) { - for (UInt j = 0; j < spatial_dimension; ++j) { - R(i, j) = Pe(i, j); - R(i + spatial_dimension, j + spatial_dimension) = Pe(i, j); - } - } - } + AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void StructuralMechanicsModel::computeRotationMatrix(const ElementType & type) { Mesh & mesh = getFEEngine().getMesh(); UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); UInt nb_element = mesh.getNbElement(type); if (!rotation_matrix.exists(type)) { rotation_matrix.alloc(nb_element, nb_degree_of_freedom * nb_nodes_per_element * nb_degree_of_freedom * nb_nodes_per_element, type); } else { rotation_matrix(type).resize(nb_element); } rotation_matrix(type).clear(); Array<Real> rotations(nb_element, nb_degree_of_freedom * nb_degree_of_freedom); rotations.clear(); #define COMPUTE_ROTATION_MATRIX(type) computeRotationMatrix<type>(rotations); AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_ROTATION_MATRIX); #undef COMPUTE_ROTATION_MATRIX - Array<Real>::matrix_iterator R_it = - rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom); - Array<Real>::matrix_iterator T_it = + auto R_it = rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom); + auto T_it = rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element, nb_degree_of_freedom * nb_nodes_per_element); for (UInt el = 0; el < nb_element; ++el, ++R_it, ++T_it) { - Matrix<Real> & T = *T_it; - Matrix<Real> & R = *R_it; + auto & T = *T_it; + auto & R = *R_it; T.clear(); for (UInt k = 0; k < nb_nodes_per_element; ++k) { for (UInt i = 0; i < nb_degree_of_freedom; ++i) for (UInt j = 0; j < nb_degree_of_freedom; ++j) T(k * nb_degree_of_freedom + i, k * nb_degree_of_freedom + j) = R(i, j); } } } /* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::computeStresses() { - AKANTU_DEBUG_IN(); - - Mesh::type_iterator it = getFEEngine().getMesh().firstType( - spatial_dimension, _not_ghost, _ek_structural); - Mesh::type_iterator end = getFEEngine().getMesh().lastType( - spatial_dimension, _not_ghost, _ek_structural); - for (; it != end; ++it) { - ElementType type = *it; - -#define COMPUTE_STRESS_ON_QUAD(type) computeStressOnQuad<type>(); - - AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(COMPUTE_STRESS_ON_QUAD); -#undef COMPUTE_STRESS_ON_QUAD - } - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::updateResidual() { - AKANTU_DEBUG_IN(); - residual->copy(*force_momentum); - - Array<Real> ku(*displacement_rotation, true); - ku *= *stiffness_matrix; - *residual -= ku; - - this->updateResidualInternal(); - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::implicitPred() { - AKANTU_DEBUG_IN(); - - if (previous_displacement) - previous_displacement->copy(*displacement_rotation); - - if (method == _implicit_dynamic) - integrator->integrationSchemePred(time_step, *displacement_rotation, - *velocity, *acceleration, *blocked_dofs); - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::implicitCorr() { - AKANTU_DEBUG_IN(); - - Real * incr_val = increment->storage(); - bool * boun_val = blocked_dofs->storage(); - - UInt nb_nodes = displacement_rotation->size(); - - for (UInt j = 0; j < nb_nodes * nb_degree_of_freedom; - ++j, ++incr_val, ++boun_val) { - *incr_val *= (1. - *boun_val); - } - - if (method == _implicit_dynamic) { - integrator->integrationSchemeCorrDispl(time_step, *displacement_rotation, - *velocity, *acceleration, - *blocked_dofs, *increment); - } else { - - Real * disp_val = displacement_rotation->storage(); - incr_val = increment->storage(); - - for (UInt j = 0; j < nb_nodes * nb_degree_of_freedom; - ++j, ++disp_val, ++incr_val) { - *disp_val += *incr_val; - } - } - - AKANTU_DEBUG_OUT(); -} -/* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::updateResidualInternal() { - AKANTU_DEBUG_IN(); - - AKANTU_DEBUG_INFO("Update the residual"); - // f = f_ext - f_int - Ma - Cv = r - Ma - Cv; - - if (method != _static) { - // f -= Ma - if (mass_matrix) { - // if full mass_matrix - Array<Real> * Ma = new Array<Real>(*acceleration, true, "Ma"); - *Ma *= *mass_matrix; - /// \todo check unit conversion for implicit dynamics - // *Ma /= f_m2a - *residual -= *Ma; - delete Ma; - } else if (mass) { - - // else lumped mass - UInt nb_nodes = acceleration->size(); - UInt nb_degree_of_freedom = acceleration->getNbComponent(); - - Real * mass_val = mass->storage(); - Real * accel_val = acceleration->storage(); - Real * res_val = residual->storage(); - bool * blocked_dofs_val = blocked_dofs->storage(); - - for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) { - if (!(*blocked_dofs_val)) { - *res_val -= *accel_val ** mass_val / f_m2a; - } - blocked_dofs_val++; - res_val++; - mass_val++; - accel_val++; - } - } else { - AKANTU_DEBUG_ERROR("No function called to assemble the mass matrix."); - } - - // f -= Cv - if (velocity_damping_matrix) { - Array<Real> * Cv = new Array<Real>(*velocity); - *Cv *= *velocity_damping_matrix; - *residual -= *Cv; - delete Cv; - } - } - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::setIncrementFlagOn() { - AKANTU_DEBUG_IN(); - - if (!increment) { - UInt nb_nodes = mesh.getNbNodes(); - std::stringstream sstr_inc; - sstr_inc << id << ":increment"; - increment = &(alloc<Real>(sstr_inc.str(), nb_nodes, spatial_dimension, 0.)); - } - - increment_flag = true; - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::solve() { - AKANTU_DEBUG_IN(); - - AKANTU_DEBUG_INFO("Solving an implicit step."); - - UInt nb_nodes = displacement_rotation->size(); - - /// todo residual = force - Kxr * d_bloq - jacobian_matrix->copyContent(*stiffness_matrix); - jacobian_matrix->applyBoundary(*blocked_dofs); - - jacobian_matrix->saveMatrix("Kbound.mtx"); - - increment->clear(); - - solver->setRHS(*residual); - - solver->factorize(); - solver->solve(*increment); - - Real * increment_val = increment->storage(); - Real * displacement_val = displacement_rotation->storage(); - bool * blocked_dofs_val = blocked_dofs->storage(); - - for (UInt n = 0; n < nb_nodes * nb_degree_of_freedom; ++n) { - if (!(*blocked_dofs_val)) { - *displacement_val += *increment_val; - } else { - *increment_val = 0.0; - } - - displacement_val++; - blocked_dofs_val++; - increment_val++; - } - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template <> -bool StructuralMechanicsModel::testConvergence<_scc_increment>(Real tolerance, - Real & error) { - AKANTU_DEBUG_IN(); - - UInt nb_nodes = displacement_rotation->size(); - UInt nb_degree_of_freedom = displacement_rotation->getNbComponent(); - - error = 0; - Real norm[2] = {0., 0.}; - Real * increment_val = increment->storage(); - bool * blocked_dofs_val = blocked_dofs->storage(); - Real * displacement_val = displacement_rotation->storage(); - - for (UInt n = 0; n < nb_nodes; ++n) { - for (UInt d = 0; d < nb_degree_of_freedom; ++d) { - if (!(*blocked_dofs_val)) { - norm[0] += *increment_val * *increment_val; - norm[1] += *displacement_val * *displacement_val; - } - blocked_dofs_val++; - increment_val++; - displacement_val++; - } - } - - StaticCommunicator::getStaticCommunicator().allReduce(norm, 2, _so_sum); - - norm[0] = sqrt(norm[0]); - norm[1] = sqrt(norm[1]); - AKANTU_DEBUG_ASSERT(!Math::isnan(norm[0]), - "Something went wrong in the solve phase"); - - AKANTU_DEBUG_OUT(); - if (norm[1] > Math::getTolerance()) - error = norm[0] / norm[1]; - else - error = norm[0]; // In case the total displacement is zero! - return (error < tolerance); -} - -/* -------------------------------------------------------------------------- */ -template <> -bool StructuralMechanicsModel::testConvergence<_scc_residual>(Real tolerance, - Real & norm) { - AKANTU_DEBUG_IN(); - - UInt nb_nodes = residual->size(); - - norm = 0; - Real * residual_val = residual->storage(); - bool * blocked_dofs_val = blocked_dofs->storage(); - - for (UInt n = 0; n < nb_nodes; ++n) { - bool is_local_node = mesh.isLocalOrMasterNode(n); - if (is_local_node) { - for (UInt d = 0; d < nb_degree_of_freedom; ++d) { - if (!(*blocked_dofs_val)) { - norm += *residual_val * *residual_val; - } - blocked_dofs_val++; - residual_val++; - } - } else { - blocked_dofs_val += spatial_dimension; - residual_val += spatial_dimension; - } - } - - StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum); - - norm = sqrt(norm); - - AKANTU_DEBUG_ASSERT(!Math::isnan(norm), - "Something goes wrong in the solve phase"); - - AKANTU_DEBUG_OUT(); - return (norm < tolerance); -} - -/* -------------------------------------------------------------------------- */ -bool StructuralMechanicsModel::testConvergenceIncrement(Real tolerance) { - Real error; - bool tmp = testConvergenceIncrement(tolerance, error); - - AKANTU_DEBUG_INFO("Norm of increment : " << error); - - return tmp; -} - -/* -------------------------------------------------------------------------- */ -bool StructuralMechanicsModel::testConvergenceIncrement(Real tolerance, - Real & error) { - AKANTU_DEBUG_IN(); - Mesh & mesh = getFEEngine().getMesh(); - UInt nb_nodes = displacement_rotation->size(); - UInt nb_degree_of_freedom = displacement_rotation->getNbComponent(); - - Real norm = 0; - Real * increment_val = increment->storage(); - bool * blocked_dofs_val = blocked_dofs->storage(); - - for (UInt n = 0; n < nb_nodes; ++n) { - bool is_local_node = mesh.isLocalOrMasterNode(n); - for (UInt d = 0; d < nb_degree_of_freedom; ++d) { - if (!(*blocked_dofs_val) && is_local_node) { - norm += *increment_val * *increment_val; - } - blocked_dofs_val++; - increment_val++; - } - } - - StaticCommunicator::getStaticCommunicator().allReduce(&norm, 1, _so_sum); - - error = sqrt(norm); - AKANTU_DEBUG_ASSERT(!Math::isnan(norm), - "Something goes wrong in the solve phase"); - - AKANTU_DEBUG_OUT(); - return (error < tolerance); -} - -/* -------------------------------------------------------------------------- */ -template <> -void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_2>( - Array<Real> & tangent_moduli) { - UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2); - UInt nb_quadrature_points = - getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2); - UInt tangent_size = 2; - - Array<Real>::matrix_iterator D_it = - tangent_moduli.begin(tangent_size, tangent_size); - Array<UInt> & el_mat = element_material(_bernoulli_beam_2, _not_ghost); - - for (UInt e = 0; e < nb_element; ++e) { - UInt mat = el_mat(e); - Real E = materials[mat].E; - Real A = materials[mat].A; - Real I = materials[mat].I; - for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) { - Matrix<Real> & D = *D_it; - D(0, 0) = E * A; - D(1, 1) = E * I; - } - } -} -/* -------------------------------------------------------------------------- */ -template <> -void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_3>( - Array<Real> & tangent_moduli) { - UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3); - UInt nb_quadrature_points = - getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3); - UInt tangent_size = 4; - - Array<Real>::matrix_iterator D_it = - tangent_moduli.begin(tangent_size, tangent_size); - - for (UInt e = 0; e < nb_element; ++e) { - UInt mat = element_material(_bernoulli_beam_3, _not_ghost)(e); - Real E = materials[mat].E; - Real A = materials[mat].A; - Real Iz = materials[mat].Iz; - Real Iy = materials[mat].Iy; - Real GJ = materials[mat].GJ; - for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) { - Matrix<Real> & D = *D_it; - D(0, 0) = E * A; - D(1, 1) = E * Iz; - D(2, 2) = E * Iy; - D(3, 3) = GJ; - } - } -} - -/* -------------------------------------------------------------------------- */ -template <> -void StructuralMechanicsModel::computeTangentModuli<_kirchhoff_shell>( - Array<Real> & tangent_moduli) { - UInt nb_element = getFEEngine().getMesh().getNbElement(_kirchhoff_shell); - UInt nb_quadrature_points = - getFEEngine().getNbIntegrationPoints(_kirchhoff_shell); - UInt tangent_size = 6; - - Array<Real>::matrix_iterator D_it = - tangent_moduli.begin(tangent_size, tangent_size); - - for (UInt e = 0; e < nb_element; ++e) { - UInt mat = element_material(_kirchhoff_shell, _not_ghost)(e); - Real E = materials[mat].E; - Real nu = materials[mat].nu; - Real t = materials[mat].t; - - Real HH = E * t / (1 - nu * nu); - Real DD = E * t * t * t / (12 * (1 - nu * nu)); - - for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) { - Matrix<Real> & D = *D_it; - D(0, 0) = HH; - D(0, 1) = HH * nu; - D(1, 0) = HH * nu; - D(1, 1) = HH; - D(2, 2) = HH * (1 - nu) / 2; - D(3, 3) = DD; - D(3, 4) = DD * nu; - D(4, 3) = DD * nu; - D(4, 4) = DD; - D(5, 5) = DD * (1 - nu) / 2; - } - } -} - -/* -------------------------------------------------------------------------- */ -template <> -void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix< - _bernoulli_beam_2>(Array<Real> & b, __attribute__((unused)) bool local) { - UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_2); - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_bernoulli_beam_2); - UInt nb_quadrature_points = - getFEEngine().getNbIntegrationPoints(_bernoulli_beam_2); - - MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); - Array<Real>::const_vector_iterator shape_Np = - fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 0) - .begin(nb_nodes_per_element); - Array<Real>::const_vector_iterator shape_Mpp = - fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 1) - .begin(nb_nodes_per_element); - Array<Real>::const_vector_iterator shape_Lpp = - fem.getShapesDerivatives(_bernoulli_beam_2, _not_ghost, 2) - .begin(nb_nodes_per_element); - - UInt tangent_size = getTangentStiffnessVoigtSize<_bernoulli_beam_2>(); - UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom; - b.clear(); - Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size); - - for (UInt e = 0; e < nb_element; ++e) { - for (UInt q = 0; q < nb_quadrature_points; ++q) { - Matrix<Real> & B = *B_it; - const Vector<Real> & Np = *shape_Np; - const Vector<Real> & Lpp = *shape_Lpp; - const Vector<Real> & Mpp = *shape_Mpp; - - B(0, 0) = Np(0); - B(0, 3) = Np(1); - - B(1, 1) = Mpp(0); - B(1, 2) = Lpp(0); - B(1, 4) = Mpp(1); - B(1, 5) = Lpp(1); - - ++B_it; - ++shape_Np; - ++shape_Mpp; - ++shape_Lpp; - } - - // ++R_it; - } -} - -/* -------------------------------------------------------------------------- */ -template <> -void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix< - _bernoulli_beam_3>(Array<Real> & b, __attribute__((unused)) bool local) { - MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); - - UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3); - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_bernoulli_beam_3); - UInt nb_quadrature_points = - getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3); - - Array<Real>::const_vector_iterator shape_Np = - fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 0) - .begin(nb_nodes_per_element); - Array<Real>::const_vector_iterator shape_Mpp = - fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 1) - .begin(nb_nodes_per_element); - Array<Real>::const_vector_iterator shape_Lpp = - fem.getShapesDerivatives(_bernoulli_beam_3, _not_ghost, 2) - .begin(nb_nodes_per_element); - - UInt tangent_size = getTangentStiffnessVoigtSize<_bernoulli_beam_3>(); - UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom; - - b.clear(); - - Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size); - - for (UInt e = 0; e < nb_element; ++e) { - for (UInt q = 0; q < nb_quadrature_points; ++q) { - Matrix<Real> & B = *B_it; - - const Vector<Real> & Np = *shape_Np; - const Vector<Real> & Lpp = *shape_Lpp; - const Vector<Real> & Mpp = *shape_Mpp; - - B(0, 0) = Np(0); - B(0, 6) = Np(1); - - B(1, 1) = Mpp(0); - B(1, 5) = Lpp(0); - B(1, 7) = Mpp(1); - B(1, 11) = Lpp(1); - - B(2, 2) = Mpp(0); - B(2, 4) = -Lpp(0); - B(2, 8) = Mpp(1); - B(2, 10) = -Lpp(1); - - B(3, 3) = Np(0); - B(3, 9) = Np(1); - - ++B_it; - ++shape_Np; - ++shape_Mpp; - ++shape_Lpp; - } - } -} -/* -------------------------------------------------------------------------- */ -template <> -void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix< - _kirchhoff_shell>(Array<Real> & b, __attribute__((unused)) bool local) { - MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); - - UInt nb_element = getFEEngine().getMesh().getNbElement(_kirchhoff_shell); - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(_kirchhoff_shell); - UInt nb_quadrature_points = - getFEEngine().getNbIntegrationPoints(_kirchhoff_shell); - - Array<Real>::const_matrix_iterator shape_Np = - fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 0) - .begin(2, nb_nodes_per_element); - Array<Real>::const_matrix_iterator shape_Nx1p = - fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 1) - .begin(2, nb_nodes_per_element); - Array<Real>::const_matrix_iterator shape_Nx2p = - fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 2) - .begin(2, nb_nodes_per_element); - Array<Real>::const_matrix_iterator shape_Nx3p = - fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 3) - .begin(2, nb_nodes_per_element); - Array<Real>::const_matrix_iterator shape_Ny1p = - fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 4) - .begin(2, nb_nodes_per_element); - Array<Real>::const_matrix_iterator shape_Ny2p = - fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 5) - .begin(2, nb_nodes_per_element); - Array<Real>::const_matrix_iterator shape_Ny3p = - fem.getShapesDerivatives(_kirchhoff_shell, _not_ghost, 6) - .begin(2, nb_nodes_per_element); - - UInt tangent_size = getTangentStiffnessVoigtSize<_kirchhoff_shell>(); - UInt bt_d_b_size = nb_nodes_per_element * nb_degree_of_freedom; - - b.clear(); - - Array<Real>::matrix_iterator B_it = b.begin(tangent_size, bt_d_b_size); - - for (UInt e = 0; e < nb_element; ++e) { - for (UInt q = 0; q < nb_quadrature_points; ++q) { - Matrix<Real> & B = *B_it; - - const Matrix<Real> & Np = *shape_Np; - const Matrix<Real> & Nx1p = *shape_Nx1p; - const Matrix<Real> & Nx2p = *shape_Nx2p; - const Matrix<Real> & Nx3p = *shape_Nx3p; - const Matrix<Real> & Ny1p = *shape_Ny1p; - const Matrix<Real> & Ny2p = *shape_Ny2p; - const Matrix<Real> & Ny3p = *shape_Ny3p; - - B(0, 0) = Np(0, 0); - B(0, 6) = Np(0, 1); - B(0, 12) = Np(0, 2); - - B(1, 1) = Np(1, 0); - B(1, 7) = Np(1, 1); - B(1, 13) = Np(1, 2); - - B(2, 0) = Np(1, 0); - B(2, 1) = Np(0, 0); - B(2, 6) = Np(1, 1); - B(2, 7) = Np(0, 1); - B(2, 12) = Np(1, 2); - B(2, 13) = Np(0, 2); - - B(3, 2) = Nx1p(0, 0); - B(3, 3) = Nx2p(0, 0); - B(3, 4) = Nx3p(0, 0); - B(3, 8) = Nx1p(0, 1); - B(3, 9) = Nx2p(0, 1); - B(3, 10) = Nx3p(0, 1); - B(3, 14) = Nx1p(0, 2); - B(3, 15) = Nx2p(0, 2); - B(3, 16) = Nx3p(0, 2); - - B(4, 2) = Ny1p(1, 0); - B(4, 3) = Ny2p(1, 0); - B(4, 4) = Ny3p(1, 0); - B(4, 8) = Ny1p(1, 1); - B(4, 9) = Ny2p(1, 1); - B(4, 10) = Ny3p(1, 1); - B(4, 14) = Ny1p(1, 2); - B(4, 15) = Ny2p(1, 2); - B(4, 16) = Ny3p(1, 2); - - B(5, 2) = Nx1p(1, 0) + Ny1p(0, 0); - B(5, 3) = Nx2p(1, 0) + Ny2p(0, 0); - B(5, 4) = Nx3p(1, 0) + Ny3p(0, 0); - B(5, 8) = Nx1p(1, 1) + Ny1p(0, 1); - B(5, 9) = Nx2p(1, 1) + Ny2p(0, 1); - B(5, 10) = Nx3p(1, 1) + Ny3p(0, 1); - B(5, 14) = Nx1p(1, 2) + Ny1p(0, 2); - B(5, 15) = Nx2p(1, 2) + Ny2p(0, 2); - B(5, 16) = Nx3p(1, 2) + Ny3p(0, 2); - - ++B_it; - ++shape_Np; - ++shape_Nx1p; - ++shape_Nx2p; - ++shape_Nx3p; - ++shape_Ny1p; - ++shape_Ny2p; - ++shape_Ny3p; - } - } -} - -/* -------------------------------------------------------------------------- */ - -dumper::Field * -StructuralMechanicsModel::createNodalFieldBool(const std::string & field_name, - const std::string & group_name, - __attribute__((unused)) bool padding_flag) { +dumper::Field * StructuralMechanicsModel::createNodalFieldBool( + const std::string & field_name, const std::string & group_name, + __attribute__((unused)) bool padding_flag) { std::map<std::string, Array<bool> *> uint_nodal_fields; uint_nodal_fields["blocked_dofs"] = blocked_dofs; dumper::Field * field = NULL; field = mesh.createNodalField(uint_nodal_fields[field_name], group_name); return field; } /* -------------------------------------------------------------------------- */ - dumper::Field * StructuralMechanicsModel::createNodalFieldReal(const std::string & field_name, const std::string & group_name, bool padding_flag) { UInt n; if (spatial_dimension == 2) { n = 2; } else n = 3; - dumper::Field * field = NULL; - if (field_name == "displacement") { - field = mesh.createStridedNodalField(displacement_rotation, group_name, n, - 0, padding_flag); + return mesh.createStridedNodalField(displacement_rotation, group_name, n, 0, + padding_flag); } + if (field_name == "rotation") { - field = - mesh.createStridedNodalField(displacement_rotation, group_name, - nb_degree_of_freedom - n, n, padding_flag); + return mesh.createStridedNodalField(displacement_rotation, group_name, + nb_degree_of_freedom - n, n, + padding_flag); } + if (field_name == "force") { - field = mesh.createStridedNodalField(force_momentum, group_name, n, 0, - padding_flag); + return mesh.createStridedNodalField(external_force_momentum, group_name, n, + 0, padding_flag); } + if (field_name == "momentum") { - field = mesh.createStridedNodalField( - force_momentum, group_name, nb_degree_of_freedom - n, n, padding_flag); + return mesh.createStridedNodalField(external_force_momentum, group_name, + nb_degree_of_freedom - n, n, + padding_flag); } - if (field_name == "residual") { - field = mesh.createNodalField(residual, group_name, padding_flag); + + if (field_name == "internal_force") { + return mesh.createStridedNodalField(internal_force_momentum, group_name, n, + 0, padding_flag); } - return field; + if (field_name == "internal_momentum") { + return mesh.createStridedNodalField(internal_force_momentum, group_name, + nb_degree_of_freedom - n, n, + padding_flag); + } + + return nullptr; } /* -------------------------------------------------------------------------- */ - dumper::Field * StructuralMechanicsModel::createElementalField( - const std::string & field_name, const std::string & group_name, - __attribute__((unused)) bool padding_flag, const ElementKind & kind, - __attribute__((unused)) const std::string & fe_engine_id) { + const std::string & field_name, const std::string & group_name, bool, + const ElementKind & kind, const std::string &) { dumper::Field * field = NULL; if (field_name == "element_index_by_material") field = mesh.createElementalField<UInt, Vector, dumper::ElementalField>( field_name, group_name, this->spatial_dimension, kind); return field; } /* -------------------------------------------------------------------------- */ -} // akantu +} // namespace akantu diff --git a/src/model/structural_mechanics/structural_mechanics_model.hh b/src/model/structural_mechanics/structural_mechanics_model.hh index f884e79dd..8f96b2d9d 100644 --- a/src/model/structural_mechanics/structural_mechanics_model.hh +++ b/src/model/structural_mechanics/structural_mechanics_model.hh @@ -1,392 +1,292 @@ /** * @file structural_mechanics_model.hh * * @author Fabian Barras <fabian.barras@epfl.ch> * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * @author Damien Spielmann <damien.spielmann@epfl.ch> * * @date creation: Fri Jul 15 2011 * @date last modification: Thu Jan 21 2016 * * @brief Particular implementation of the structural elements in the * StructuralMechanicsModel * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ - +/* -------------------------------------------------------------------------- */ +#include "aka_named_argument.hh" +#include "model.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__ #define __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__ -/* -------------------------------------------------------------------------- */ -#include "aka_common.hh" -#include "model.hh" -#include "integrator_gauss.hh" -#include "shape_linked.hh" -#include "aka_types.hh" -#include "dumpable.hh" -#include "solver.hh" -#include "integration_scheme_2nd_order.hh" - /* -------------------------------------------------------------------------- */ namespace akantu { -class SparseMatrix; -} +class Material; +class MaterialSelector; +class DumperIOHelper; +class NonLocalManager; +template <ElementKind kind, class IntegrationOrderFunctor> +class IntegratorGauss; +template <ElementKind kind> class ShapeStructural; +} // namespace akantu namespace akantu { struct StructuralMaterial { - Real E; - Real A; - Real I; - Real Iz; - Real Iy; - Real GJ; - Real rho; - Real t; - Real nu; + Real E{0}; + Real A{1}; + Real I{0}; + Real Iz{0}; + Real Iy{0}; + Real GJ{0}; + Real rho{0}; + Real t{0}; + Real nu{0}; }; -struct StructuralMechanicsModelOptions : public ModelOptions { - StructuralMechanicsModelOptions(AnalysisMethod analysis_method = _static) - : analysis_method(analysis_method) {} - AnalysisMethod analysis_method; -}; - -extern const StructuralMechanicsModelOptions - default_structural_mechanics_model_options; - class StructuralMechanicsModel : public Model { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: - typedef FEEngineTemplate<IntegratorGauss, ShapeLinked, _ek_structural> - MyFEEngineType; + using MyFEEngineType = + FEEngineTemplate<IntegratorGauss, ShapeStructural, _ek_structural>; StructuralMechanicsModel(Mesh & mesh, UInt spatial_dimension = _all_dimensions, const ID & id = "structural_mechanics_model", const MemoryID & memory_id = 0); virtual ~StructuralMechanicsModel(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: - /// initialize fully the model - void initFull(const ModelOptions & options = - default_structural_mechanics_model_options); - - /// initialize the internal vectors - void initArrays(); + void initSolver(TimeStepSolverType, NonLinearSolverType); /// initialize the model void initModel(); - /// initialize the solver - void initSolver(SolverOptions & options = _solver_no_options); - - /// initialize the stuff for the implicit solver - void initImplicit(bool dynamic = false, - SolverOptions & solver_options = _solver_no_options); - /// compute the stresses per elements void computeStresses(); /// assemble the stiffness matrix void assembleStiffnessMatrix(); /// assemble the mass matrix for consistent mass resolutions void assembleMass(); - /// implicit time integration predictor - void implicitPred(); - - /// implicit time integration corrector - void implicitCorr(); - /// update the residual vector void updateResidual(); /// solve the system void solve(); - bool testConvergenceIncrement(Real tolerance); - bool testConvergenceIncrement(Real tolerance, Real & error); - void computeRotationMatrix(const ElementType & type); protected: UInt getTangentStiffnessVoigtSize(const ElementType & type); /// compute Rotation Matrices template <const ElementType type> void computeRotationMatrix(__attribute__((unused)) Array<Real> & rotations) {} - /// compute A and solve @f[ A\delta u = f_ext - f_int @f] - template <NewmarkBeta::IntegrationSchemeCorrectorType type> - void solve(Array<Real> & increment, - __attribute__((unused)) Real block_val = 1.); - /* ------------------------------------------------------------------------ */ /* Mass (structural_mechanics_model_mass.cc) */ /* ------------------------------------------------------------------------ */ /// assemble the mass matrix for either _ghost or _not_ghost elements void assembleMass(GhostType ghost_type); /// computes rho void computeRho(Array<Real> & rho, ElementType type, GhostType ghost_type); /// finish the computation of residual to solve in increment void updateResidualInternal(); /* ------------------------------------------------------------------------ */ private: template <ElementType type> inline UInt getTangentStiffnessVoigtSize(); template <ElementType type> void assembleStiffnessMatrix(); template <ElementType type> void assembleMass(); template <ElementType type> void computeStressOnQuad(); template <ElementType type> void computeTangentModuli(Array<Real> & tangent_moduli); template <ElementType type> void transferBMatrixToSymVoigtBMatrix(Array<Real> & B, bool local = false); template <ElementType type> void transferNMatrixToSymVoigtNMatrix(Array<Real> & N_matrix); /* ------------------------------------------------------------------------ */ /* Dumpable interface */ /* ------------------------------------------------------------------------ */ public: virtual dumper::Field * createNodalFieldReal(const std::string & field_name, const std::string & group_name, bool padding_flag); virtual dumper::Field * createNodalFieldBool(const std::string & field_name, const std::string & group_name, bool padding_flag); virtual dumper::Field * createElementalField(const std::string & field_name, const std::string & group_name, bool padding_flag, const ElementKind & kind, const std::string & fe_engine_id = ""); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /// set the value of the time step void setTimeStep(Real time_step); /// return the dimension of the system space AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt); /// get the StructuralMechanicsModel::displacement vector AKANTU_GET_MACRO(Displacement, *displacement_rotation, Array<Real> &); /// get the StructuralMechanicsModel::velocity vector AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &); /// get the StructuralMechanicsModel::acceleration vector, updated /// by /// StructuralMechanicsModel::updateAcceleration AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &); - /// get the StructuralMechanicsModel::force vector (boundary forces) - AKANTU_GET_MACRO(Force, *force_momentum, Array<Real> &); + /// get the StructuralMechanicsModel::external_force vector + AKANTU_GET_MACRO(ExternalForce, *external_force_momentum, Array<Real> &); + + /// get the StructuralMechanicsModel::internal_force vector (boundary forces) + AKANTU_GET_MACRO(InternalForce, *internal_force_momentum, Array<Real> &); - /// get the StructuralMechanicsModel::residual vector, computed by - /// StructuralMechanicsModel::updateResidual - AKANTU_GET_MACRO(Residual, *residual, const Array<Real> &); /// get the StructuralMechanicsModel::boundary vector AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(RotationMatrix, rotation_matrix, Real); - AKANTU_GET_MACRO(StiffnessMatrix, *stiffness_matrix, const SparseMatrix &); - - AKANTU_GET_MACRO(MassMatrix, *mass_matrix, const SparseMatrix &); - AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real); AKANTU_GET_MACRO_BY_ELEMENT_TYPE(ElementMaterial, element_material, UInt); AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Set_ID, set_ID, UInt); void addMaterial(StructuralMaterial & material) { materials.push_back(material); } /** * @brief set the StructuralMechanicsModel::increment_flag to on, the * activate the * update of the StructuralMechanicsModel::increment vector */ void setIncrementFlagOn(); /* ------------------------------------------------------------------------ */ /* Boundaries (structural_mechanics_model_boundary.cc) */ /* ------------------------------------------------------------------------ */ public: /// Compute Linear load function set in global axis template <ElementType type> void computeForcesByGlobalTractionArray(const Array<Real> & tractions); /// Compute Linear load function set in local axis template <ElementType type> void computeForcesByLocalTractionArray(const Array<Real> & tractions); /// compute force vector from a function(x,y,momentum) that describe stresses - template <ElementType type> - void computeForcesFromFunction(BoundaryFunction in_function, - BoundaryFunctionType function_type); - - /** - * solve a step (predictor + convergence loop + corrector) using the - * the given convergence method (see akantu::SolveConvergenceMethod) - * and the given convergence criteria (see - * akantu::SolveConvergenceCriteria) - **/ - template <SolveConvergenceMethod method, SolveConvergenceCriteria criteria> - bool solveStep(Real tolerance, UInt max_iteration = 100); - - template <SolveConvergenceMethod method, SolveConvergenceCriteria criteria> - bool solveStep(Real tolerance, Real & error, UInt max_iteration = 100); - - /// test if the system is converged - template <SolveConvergenceCriteria criteria> - bool testConvergence(Real tolerance, Real & error); + // template <ElementType type> + // void computeForcesFromFunction(BoundaryFunction in_function, + // BoundaryFunctionType function_type); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// time step Real time_step; /// conversion coefficient form force/mass to acceleration Real f_m2a; /// displacements array - Array<Real> * displacement_rotation; - - /// displacements array at the previous time step (used in finite deformation) - Array<Real> * previous_displacement; + Array<Real> * displacement_rotation{nullptr}; /// velocities array - Array<Real> * velocity; + Array<Real> * velocity{nullptr}; /// accelerations array - Array<Real> * acceleration; + Array<Real> * acceleration{nullptr}; /// forces array - Array<Real> * force_momentum; - - /// lumped mass array - Array<Real> * mass; - - /// stress arraz + Array<Real> * internal_force_momentum{nullptr}; - ElementTypeMapArray<Real> stress; + /// forces array + Array<Real> * external_force_momentum{nullptr}; - /// residuals array - Array<Real> * residual; + /// lumped mass array + Array<Real> * mass{nullptr}; /// boundaries array - Array<bool> * blocked_dofs; + Array<bool> * blocked_dofs{nullptr}; - /// position of a dof in the K matrix - Array<Int> * equation_number; + /// stress array + ElementTypeMapArray<Real> stress; ElementTypeMapArray<UInt> element_material; // Define sets of beams ElementTypeMapArray<UInt> set_ID; - /// local equation_number to global - unordered_map<UInt, UInt>::type local_eq_num_to_global; - - /// stiffness matrix - SparseMatrix * stiffness_matrix; - - /// mass matrix - SparseMatrix * mass_matrix; - - /// velocity damping matrix - SparseMatrix * velocity_damping_matrix; - - /// jacobian matrix - SparseMatrix * jacobian_matrix; - - /// increment of displacement - Array<Real> * increment; - - /// solver for implicit - Solver * solver; - /// number of degre of freedom UInt nb_degree_of_freedom; // Rotation matrix ElementTypeMapArray<Real> rotation_matrix; /// analysis method check the list in akantu::AnalysisMethod AnalysisMethod method; /// flag defining if the increment must be computed or not bool increment_flag; - /// integration scheme of second order used - IntegrationScheme2ndOrder * integrator; - - /* -------------------------------------------------------------------------- - */ + /* ------------------------------------------------------------------------ */ std::vector<StructuralMaterial> materials; }; -/* -------------------------------------------------------------------------- */ -/* inline functions */ -/* -------------------------------------------------------------------------- */ +} // namespace akantu #include "structural_mechanics_model_inline_impl.cc" -/// standard output stream operator -inline std::ostream & operator<<(std::ostream & stream, - const StructuralMechanicsModel & _this) { - _this.printself(stream); - return stream; -} - -} // akantu - #endif /* __AKANTU_STRUCTURAL_MECHANICS_MODEL_HH__ */ diff --git a/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc b/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc index f75781a8e..0de86744a 100644 --- a/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc +++ b/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc @@ -1,615 +1,379 @@ /** * @file structural_mechanics_model_inline_impl.cc * * @author Fabian Barras <fabian.barras@epfl.ch> * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * @author Damien Spielmann <damien.spielmann@epfl.ch> * * @date creation: Fri Jul 15 2011 * @date last modification: Thu Oct 15 2015 * * @brief Implementation of inline functions of StructuralMechanicsModel * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ - /* -------------------------------------------------------------------------- */ -template<ElementType type> -inline UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize() { - AKANTU_DEBUG_TO_IMPLEMENT(); - return 0; -} +#include "structural_mechanics_model.hh" +/* -------------------------------------------------------------------------- */ -template<> -inline UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize<_bernoulli_beam_2>() { - return 2; -} +#ifndef __AKANTU_STRUCTURAL_MECHANICS_MODEL_INLINE_IMPL_CC__ +#define __AKANTU_STRUCTURAL_MECHANICS_MODEL_INLINE_IMPL_CC__ -template<> -inline UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize<_bernoulli_beam_3>() { - return 4; -} +namespace akantu { /* -------------------------------------------------------------------------- */ - -template<> -inline UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize<_kirchhoff_shell>() { - return 6; +template <ElementType type> +inline UInt StructuralMechanicsModel::getTangentStiffnessVoigtSize() { + AKANTU_DEBUG_TO_IMPLEMENT(); + return 0; } - /* -------------------------------------------------------------------------- */ template <ElementType type> void StructuralMechanicsModel::assembleStiffnessMatrix() { AKANTU_DEBUG_IN(); - SparseMatrix & K = *stiffness_matrix; - - UInt nb_element = getFEEngine().getMesh().getNbElement(type); - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); - UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type); + UInt nb_element = getFEEngine().getMesh().getNbElement(type); + UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); + UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type); UInt tangent_size = getTangentStiffnessVoigtSize<type>(); - Array<Real> * tangent_moduli = - new Array<Real>(nb_element * nb_quadrature_points, tangent_size * tangent_size, - "tangent_stiffness_matrix"); + Array<Real> tangent_moduli(nb_element * nb_quadrature_points, + tangent_size * tangent_size, 0., + "tangent_stiffness_matrix"); - tangent_moduli->clear(); - - computeTangentModuli<type>(*tangent_moduli); + computeTangentModuli<type>(tangent_moduli); /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ UInt bt_d_b_size = nb_degree_of_freedom * nb_nodes_per_element; - Array<Real> * bt_d_b = new Array<Real>(nb_element*nb_quadrature_points, - bt_d_b_size * bt_d_b_size, - "B^t*D*B"); + Array<Real> bt_d_b(nb_element * nb_quadrature_points, + bt_d_b_size * bt_d_b_size, "B^t*D*B"); - Array<Real> * b = new Array<Real>(nb_element*nb_quadrature_points, - tangent_size*bt_d_b_size, - "B"); + Array<Real> b(nb_element * nb_quadrature_points, tangent_size * bt_d_b_size, + "B"); - transferBMatrixToSymVoigtBMatrix<type>(*b); + transferBMatrixToSymVoigtBMatrix<type>(b); Matrix<Real> Bt_D(bt_d_b_size, tangent_size); Matrix<Real> BT(tangent_size, bt_d_b_size); - Array<Real>::matrix_iterator B = b->begin(tangent_size, bt_d_b_size); - Array<Real>::matrix_iterator D = tangent_moduli->begin(tangent_size, tangent_size); - Array<Real>::matrix_iterator Bt_D_B = bt_d_b->begin(bt_d_b_size, bt_d_b_size); - Array<Real>::matrix_iterator T = rotation_matrix(type).begin(bt_d_b_size, bt_d_b_size); + auto B = b.begin(tangent_size, bt_d_b_size); + auto D = tangent_moduli.begin(tangent_size, tangent_size); + auto Bt_D_B = bt_d_b.begin(bt_d_b_size, bt_d_b_size); + auto T = rotation_matrix(type).begin(bt_d_b_size, bt_d_b_size); for (UInt e = 0; e < nb_element; ++e, ++T) { for (UInt q = 0; q < nb_quadrature_points; ++q, ++B, ++D, ++Bt_D_B) { BT.mul<false, false>(*B, *T); Bt_D.mul<true, false>(BT, *D); Bt_D_B->mul<false, false>(Bt_D, BT); } } - delete b; - delete tangent_moduli; - /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ - Array<Real> * int_bt_d_b = new Array<Real>(nb_element, - bt_d_b_size * bt_d_b_size, - "int_B^t*D*B"); - - getFEEngine().integrate(*bt_d_b, *int_bt_d_b, - bt_d_b_size * bt_d_b_size, - type); + Array<Real> int_bt_d_b(nb_element, bt_d_b_size * bt_d_b_size, "int_B^t*D*B"); - delete bt_d_b; + getFEEngine().integrate(bt_d_b, int_bt_d_b, bt_d_b_size * bt_d_b_size, type); - getFEEngine().assembleMatrix(*int_bt_d_b, K, nb_degree_of_freedom, type); - - delete int_bt_d_b; + getDOFManager().assembleElementalMatricesToMatrix("K", "displacement", + int_bt_d_b, type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template<ElementType type> -void StructuralMechanicsModel::computeTangentModuli(Array<Real> & tangent_moduli) { +template <ElementType type> +void StructuralMechanicsModel::computeTangentModuli(Array<Real> &) { AKANTU_DEBUG_TO_IMPLEMENT(); } - /* -------------------------------------------------------------------------- */ -template<ElementType type> -void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix(Array<Real> & b, bool local) { +template <ElementType type> +void StructuralMechanicsModel::transferBMatrixToSymVoigtBMatrix(Array<Real> &, + bool) { AKANTU_DEBUG_TO_IMPLEMENT(); } /* -------------------------------------------------------------------------- */ -template<ElementType type> +template <ElementType type> void StructuralMechanicsModel::computeStressOnQuad() { AKANTU_DEBUG_IN(); - Array<Real> & sigma = stress(type, _not_ghost); + Array<Real> & sigma = stress(type, _not_ghost); sigma.clear(); const Mesh & mesh = getFEEngine().getMesh(); - UInt nb_element = mesh.getNbElement(type); - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); - UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type); + UInt nb_element = mesh.getNbElement(type); + UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); + UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type); UInt tangent_size = getTangentStiffnessVoigtSize<type>(); Array<Real> * tangent_moduli = - new Array<Real>(nb_element*nb_quadrature_points, tangent_size * tangent_size, - "tangent_stiffness_matrix"); + new Array<Real>(nb_element * nb_quadrature_points, + tangent_size * tangent_size, "tangent_stiffness_matrix"); tangent_moduli->clear(); computeTangentModuli<type>(*tangent_moduli); /// compute DB UInt d_b_size = nb_degree_of_freedom * nb_nodes_per_element; - Array<Real> * d_b = new Array<Real>(nb_element*nb_quadrature_points, - d_b_size * tangent_size, - "D*B"); + Array<Real> * d_b = new Array<Real>(nb_element * nb_quadrature_points, + d_b_size * tangent_size, "D*B"); - Array<Real> * b = new Array<Real>(nb_element*nb_quadrature_points, - tangent_size*d_b_size, - "B"); + Array<Real> * b = new Array<Real>(nb_element * nb_quadrature_points, + tangent_size * d_b_size, "B"); transferBMatrixToSymVoigtBMatrix<type>(*b); Array<Real>::matrix_iterator B = b->begin(tangent_size, d_b_size); - Array<Real>::matrix_iterator D = tangent_moduli->begin(tangent_size, tangent_size); + Array<Real>::matrix_iterator D = + tangent_moduli->begin(tangent_size, tangent_size); Array<Real>::matrix_iterator D_B = d_b->begin(tangent_size, d_b_size); for (UInt e = 0; e < nb_element; ++e) { for (UInt q = 0; q < nb_quadrature_points; ++q, ++B, ++D, ++D_B) { D_B->mul<false, false>(*D, *B); } } delete b; delete tangent_moduli; /// compute DBu D_B = d_b->begin(tangent_size, d_b_size); - Array<Real>::iterator< Vector<Real> > DBu = sigma.begin(tangent_size); - Vector<Real> ul (d_b_size); + Array<Real>::iterator<Vector<Real>> DBu = sigma.begin(tangent_size); + Vector<Real> ul(d_b_size); Array<Real> u_el(0, d_b_size); - FEEngine::extractNodalToElementField(mesh, *displacement_rotation, u_el, type); + FEEngine::extractNodalToElementField(mesh, *displacement_rotation, u_el, + type); Array<Real>::vector_iterator ug = u_el.begin(d_b_size); - Array<Real>::matrix_iterator T = rotation_matrix(type).begin(d_b_size, d_b_size); + Array<Real>::matrix_iterator T = + rotation_matrix(type).begin(d_b_size, d_b_size); for (UInt e = 0; e < nb_element; ++e, ++T, ++ug) { ul.mul<false>(*T, *ug); for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_B, ++DBu) { DBu->mul<false>(*D_B, ul); } } delete d_b; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -template<ElementType type> -void StructuralMechanicsModel::computeForcesByLocalTractionArray(const Array<Real> & tractions) { +template <ElementType type> +void StructuralMechanicsModel::computeForcesByLocalTractionArray( + const Array<Real> & tractions) { AKANTU_DEBUG_IN(); UInt nb_element = getFEEngine().getMesh().getNbElement(type); - UInt nb_nodes_per_element = getFEEngine().getMesh().getNbNodesPerElement(type); + UInt nb_nodes_per_element = + getFEEngine().getMesh().getNbNodesPerElement(type); UInt nb_quad = getFEEngine().getNbIntegrationPoints(type); // check dimension match - AKANTU_DEBUG_ASSERT(Mesh::getSpatialDimension(type) == getFEEngine().getElementDimension(), - "element type dimension does not match the dimension of boundaries : " << - getFEEngine().getElementDimension() << " != " << - Mesh::getSpatialDimension(type)); + AKANTU_DEBUG_ASSERT( + Mesh::getSpatialDimension(type) == getFEEngine().getElementDimension(), + "element type dimension does not match the dimension of boundaries : " + << getFEEngine().getElementDimension() + << " != " << Mesh::getSpatialDimension(type)); // check size of the vector - AKANTU_DEBUG_ASSERT(tractions.size() == nb_quad*nb_element, - "the size of the vector should be the total number of quadrature points"); + AKANTU_DEBUG_ASSERT( + tractions.size() == nb_quad * nb_element, + "the size of the vector should be the total number of quadrature points"); // check number of components AKANTU_DEBUG_ASSERT(tractions.getNbComponent() == nb_degree_of_freedom, - "the number of components should be the spatial dimension of the problem"); - + "the number of components should be the spatial " + "dimension of the problem"); - Array<Real> Nvoigt(nb_element * nb_quad, nb_degree_of_freedom * nb_degree_of_freedom * nb_nodes_per_element); + Array<Real> Nvoigt(nb_element * nb_quad, nb_degree_of_freedom * + nb_degree_of_freedom * + nb_nodes_per_element); transferNMatrixToSymVoigtNMatrix<type>(Nvoigt); - Array<Real>::const_matrix_iterator N_it = Nvoigt.begin(nb_degree_of_freedom, - nb_degree_of_freedom * nb_nodes_per_element); - Array<Real>::const_matrix_iterator T_it = rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element, - nb_degree_of_freedom * nb_nodes_per_element); - Array<Real>::const_vector_iterator te_it = tractions.begin(nb_degree_of_freedom); + auto N_it = Nvoigt.begin(nb_degree_of_freedom, + nb_degree_of_freedom * nb_nodes_per_element); + auto T_it = + rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element, + nb_degree_of_freedom * nb_nodes_per_element); + auto te_it = tractions.begin(nb_degree_of_freedom); - Array<Real> funct(nb_element * nb_quad, nb_degree_of_freedom * nb_nodes_per_element, 0.); - Array<Real>::iterator< Vector<Real> > Fe_it = funct.begin(nb_degree_of_freedom * nb_nodes_per_element); + Array<Real> funct(nb_element * nb_quad, + nb_degree_of_freedom * nb_nodes_per_element, 0.); + auto Fe_it = funct.begin(nb_degree_of_freedom * nb_nodes_per_element); Vector<Real> fe(nb_degree_of_freedom * nb_nodes_per_element); for (UInt e = 0; e < nb_element; ++e, ++T_it) { const Matrix<Real> & T = *T_it; for (UInt q = 0; q < nb_quad; ++q, ++N_it, ++te_it, ++Fe_it) { const Matrix<Real> & N = *N_it; const Vector<Real> & te = *te_it; Vector<Real> & Fe = *Fe_it; // compute N^t tl fe.mul<true>(N, te); // turn N^t tl back in the global referential Fe.mul<true>(T, fe); } } // allocate the vector that will contain the integrated values - std::stringstream name; - name << id << type << ":integral_boundary"; - Array<Real> int_funct(nb_element, nb_degree_of_freedom * nb_nodes_per_element, name.str()); + Array<Real> int_funct(nb_element, nb_degree_of_freedom * nb_nodes_per_element, + std::string(id + ":integral_boundary")); - //do the integration - getFEEngine().integrate(funct, int_funct, nb_degree_of_freedom*nb_nodes_per_element, type); + // do the integration + getFEEngine().integrate(funct, int_funct, + nb_degree_of_freedom * nb_nodes_per_element, type); // assemble the result into force vector - getFEEngine().assembleArray(int_funct,*force_momentum, - dof_synchronizer->getLocalDOFEquationNumbers(), - nb_degree_of_freedom, type); + getDOFManager().assembleElementalArrayLocalArray( + int_funct, *internal_force_momentum, type, _not_ghost); + AKANTU_DEBUG_OUT(); } - /* -------------------------------------------------------------------------- */ -template<ElementType type> -void StructuralMechanicsModel::computeForcesByGlobalTractionArray(const Array<Real> & traction_global){ - AKANTU_DEBUG_IN(); +template <ElementType type> +void StructuralMechanicsModel::computeForcesByGlobalTractionArray( + const Array<Real> & traction_global) { + AKANTU_DEBUG_IN(); UInt nb_element = getFEEngine().getMesh().getNbElement(type); UInt nb_quad = getFEEngine().getNbIntegrationPoints(type); - UInt nb_nodes_per_element = getFEEngine().getMesh().getNbNodesPerElement(type); + UInt nb_nodes_per_element = + getFEEngine().getMesh().getNbNodesPerElement(type); std::stringstream name; name << id << ":structuralmechanics:imposed_linear_load"; - Array<Real> traction_local(nb_element*nb_quad, nb_degree_of_freedom, name.str()); + Array<Real> traction_local(nb_element * nb_quad, nb_degree_of_freedom, + name.str()); - Array<Real>::const_matrix_iterator T_it = rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element, - nb_degree_of_freedom * nb_nodes_per_element); + auto T_it = + rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element, + nb_degree_of_freedom * nb_nodes_per_element); - Array<Real>::const_iterator< Vector<Real> > Te_it = traction_global.begin(nb_degree_of_freedom); - Array<Real>::iterator< Vector<Real> > te_it = traction_local.begin(nb_degree_of_freedom); + auto Te_it = traction_global.begin(nb_degree_of_freedom); + auto te_it = traction_local.begin(nb_degree_of_freedom); Matrix<Real> R(nb_degree_of_freedom, nb_degree_of_freedom); for (UInt e = 0; e < nb_element; ++e, ++T_it) { const Matrix<Real> & T = *T_it; for (UInt i = 0; i < nb_degree_of_freedom; ++i) for (UInt j = 0; j < nb_degree_of_freedom; ++j) - R(i, j) = T(i, j); + R(i, j) = T(i, j); for (UInt q = 0; q < nb_quad; ++q, ++Te_it, ++te_it) { const Vector<Real> & Te = *Te_it; Vector<Real> & te = *te_it; // turn the traction in the local referential te.mul<false>(R, Te); } } computeForcesByLocalTractionArray<type>(traction_local); AKANTU_DEBUG_OUT(); - } /* -------------------------------------------------------------------------- */ /** * @param myf pointer to a function that fills a vector/tensor with respect to * passed coordinates */ -template<ElementType type> -inline void StructuralMechanicsModel::computeForcesFromFunction(BoundaryFunction myf, - BoundaryFunctionType function_type){ - /** function type is - ** _bft_forces : linear load is given - ** _bft_stress : stress function is given -> Not already done for this kind of model - */ - - std::stringstream name; - name << id << ":structuralmechanics:imposed_linear_load"; - Array<Real> lin_load(0, nb_degree_of_freedom,name.str()); - name.clear(); - - UInt offset = nb_degree_of_freedom; - - //prepare the loop over element types - UInt nb_quad = getFEEngine().getNbIntegrationPoints(type); - UInt nb_element = getFEEngine().getMesh().getNbElement(type); - - name.clear(); - name << id << ":structuralmechanics:quad_coords"; - Array<Real> quad_coords(nb_element * nb_quad, spatial_dimension, "quad_coords"); - - - getFEEngineClass<MyFEEngineType>().getShapeFunctions().interpolateOnIntegrationPoints<type>(getFEEngine().getMesh().getNodes(), - quad_coords, - spatial_dimension); - getFEEngineClass<MyFEEngineType>().getShapeFunctions().interpolateOnIntegrationPoints<type>(getFEEngine().getMesh().getNodes(), - quad_coords, - spatial_dimension, - _not_ghost, - empty_filter, - true, - 0, - 1, - 1); - if(spatial_dimension == 3) - getFEEngineClass<MyFEEngineType>().getShapeFunctions().interpolateOnIntegrationPoints<type>(getFEEngine().getMesh().getNodes(), - quad_coords, - spatial_dimension, - _not_ghost, - empty_filter, - true, - 0, - 2, - 2); - lin_load.resize(nb_element*nb_quad); - Real * imposed_val = lin_load.storage(); - - /// sigma/load on each quadrature points - Real * qcoord = quad_coords.storage(); - for (UInt el = 0; el < nb_element; ++el) { - for (UInt q = 0; q < nb_quad; ++q) { - myf(qcoord, imposed_val, NULL, 0); - imposed_val += offset; - qcoord += spatial_dimension; - } - } - - switch(function_type) { - case _bft_traction_local: - computeForcesByLocalTractionArray<type>(lin_load); break; - case _bft_traction: - computeForcesByGlobalTractionArray<type>(lin_load); break; - default: break; - } -} - -/* -------------------------------------------------------------------------- */ -template<> -inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_2>() { - AKANTU_DEBUG_IN(); - - GhostType ghost_type = _not_ghost; - ElementType type = _bernoulli_beam_2; - MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); - UInt nb_element = getFEEngine().getMesh().getNbElement(type); - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); - UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type); - UInt nb_fields_to_interpolate = getTangentStiffnessVoigtSize<_bernoulli_beam_2>(); - - UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element; - - Array<Real> * n = new Array<Real>(nb_element*nb_quadrature_points, - nb_fields_to_interpolate * nt_n_field_size, - "N"); - n->clear(); - Array<Real> * rho_field = new Array<Real>(nb_element*nb_quadrature_points, - "Rho"); - rho_field->clear(); - computeRho(*rho_field, type, _not_ghost); - - bool sign = true; - -/* -------------------------------------------------------------------------- */ - fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 0, 0, 0, sign, ghost_type); // Ni ui -> u - - fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 1, 1, 1, sign, ghost_type); // Mi vi -> v - fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 2, 2, 1, sign, ghost_type); // Li Theta_i -> v -/* -------------------------------------------------------------------------- */ - - fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n, rotation_matrix, type, ghost_type); - - delete n; - delete rho_field; - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template<> -inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_3>() { - AKANTU_DEBUG_IN(); - - GhostType ghost_type = _not_ghost; - ElementType type = _bernoulli_beam_3; - MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>(); - UInt nb_element = getFEEngine().getMesh().getNbElement(type); - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); - UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type); - UInt nb_fields_to_interpolate = getTangentStiffnessVoigtSize<_bernoulli_beam_3>(); - - UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element; - - Array<Real> * n = new Array<Real>(nb_element*nb_quadrature_points, - nb_fields_to_interpolate * nt_n_field_size, - "N"); - n->clear(); - Array<Real> * rho_field = new Array<Real>(nb_element * nb_quadrature_points, - "Rho"); - rho_field->clear(); - computeRho(*rho_field, type, _not_ghost); - -/* -------------------------------------------------------------------------- */ - fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 0, 0, 0, true, ghost_type); // Ni ui -> u - - fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 1, 1, 1, true, ghost_type); // Mi vi -> v - fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 2, 5, 1, true, ghost_type); // Li Theta_z_i -> v - - fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 1, 2, 2, true, ghost_type); // Mi wi -> w - fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 2, 4, 2, false,ghost_type);// -Li Theta_y_i -> w - - fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n, 0, 3, 3, true, ghost_type); // Ni Theta_x_i->Theta_x -/* -------------------------------------------------------------------------- */ - - fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n, rotation_matrix, type, ghost_type); - - delete n; - delete rho_field; - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -template<> -inline void StructuralMechanicsModel::assembleMass<_kirchhoff_shell>() { - - AKANTU_DEBUG_TO_IMPLEMENT(); - -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria> -bool StructuralMechanicsModel::solveStep(Real tolerance, - UInt max_iteration) { - Real error = 0.; - return this->template solveStep<cmethod,criteria>(tolerance, - error, - max_iteration); -} - -/* -------------------------------------------------------------------------- */ -template<SolveConvergenceMethod cmethod, SolveConvergenceCriteria criteria> -bool StructuralMechanicsModel::solveStep(Real tolerance, Real & error, UInt max_iteration) { - - this->implicitPred(); - this->updateResidual(); - - AKANTU_DEBUG_ASSERT(stiffness_matrix != NULL, - "You should first initialize the implicit solver and assemble the stiffness matrix"); - - if (method==_implicit_dynamic) { - AKANTU_DEBUG_ASSERT(mass_matrix != NULL, - "You should first initialize the implicit solver and assemble the mass matrix"); - } - - switch (cmethod) { - case _scm_newton_raphson_tangent: - case _scm_newton_raphson_tangent_not_computed: - break; - case _scm_newton_raphson_tangent_modified: - this->assembleStiffnessMatrix(); - break; - default: - AKANTU_DEBUG_ERROR("The resolution method " << cmethod << " has not been implemented!"); - } - - UInt iter = 0; - bool converged = false; - error = 0.; - if(criteria == _scc_residual) { - converged = this->testConvergence<criteria> (tolerance, error); - if(converged) return converged; - } - - do { - if (cmethod == _scm_newton_raphson_tangent) - this->assembleStiffnessMatrix(); - - solve<NewmarkBeta::_displacement_corrector> (*increment); - - this->implicitCorr(); - - if(criteria == _scc_residual) this->updateResidual(); - - converged = this->testConvergence<criteria> (tolerance, error); - - if(criteria == _scc_increment && !converged) this->updateResidual(); - //this->dump(); - - iter++; - AKANTU_DEBUG_INFO("[" << criteria << "] Convergence iteration " - << std::setw(std::log10(max_iteration)) << iter - << ": error " << error << (converged ? " < " : " > ") << tolerance); - - } while (!converged && iter < max_iteration); - - - if (converged) { - - } else if(iter == max_iteration) { - AKANTU_DEBUG_WARNING("[" << criteria << "] Convergence not reached after " - << std::setw(std::log10(max_iteration)) << iter << - " iteration" << (iter == 1 ? "" : "s") << "!" << std::endl); - } - - return converged; -} -/* -------------------------------------------------------------------------- */ -template<NewmarkBeta::IntegrationSchemeCorrectorType type> -void StructuralMechanicsModel::solve(Array<Real> & increment, - Real block_val) { - jacobian_matrix->clear(); - - //updateResidualInternal(); //doesn't do anything for static - - Real c = 0.,d = 0.,e = 0.; - - if(method == _static) { - AKANTU_DEBUG_INFO("Solving K inc = r"); - e = 1.; - } else { - AKANTU_DEBUG_INFO("Solving (c M + d C + e K) inc = r"); - - NewmarkBeta * nmb_int = dynamic_cast<NewmarkBeta *>(integrator); - c = nmb_int->getAccelerationCoefficient<type>(time_step); - d = nmb_int->getVelocityCoefficient<type>(time_step); - e = nmb_int->getDisplacementCoefficient<type>(time_step); - } - - // J = c M + d C + e K - if(stiffness_matrix) - jacobian_matrix->add(*stiffness_matrix, e); - -// if(type != NewmarkBeta::_acceleration_corrector) -// jacobian_matrix->add(*stiffness_matrix, e); - - if(mass_matrix) - jacobian_matrix->add(*mass_matrix, c); - -#if !defined(AKANTU_NDEBUG) - if(mass_matrix && AKANTU_DEBUG_TEST(dblDump)) - mass_matrix->saveMatrix("M.mtx"); -#endif - - if(velocity_damping_matrix) - jacobian_matrix->add(*velocity_damping_matrix, d); - - jacobian_matrix->applyBoundary(*blocked_dofs); - -#if !defined(AKANTU_NDEBUG) - if(AKANTU_DEBUG_TEST(dblDump)) - jacobian_matrix->saveMatrix("J.mtx"); -#endif - - solver->setRHS(*residual); - // solve @f[ J \delta w = r @f] - solver->factorize(); - solver->solve(increment); -} +// template <ElementType type> +// inline void StructuralMechanicsModel::computeForcesFromFunction( +// BoundaryFunction myf, BoundaryFunctionType function_type) { +// /** function type is +// ** _bft_forces : linear load is given +// ** _bft_stress : stress function is given -> Not already done for this kind +// *of model +// */ + +// std::stringstream name; +// name << id << ":structuralmechanics:imposed_linear_load"; +// Array<Real> lin_load(0, nb_degree_of_freedom, name.str()); +// name.clear(); + +// UInt offset = nb_degree_of_freedom; + +// // prepare the loop over element types +// UInt nb_quad = getFEEngine().getNbIntegrationPoints(type); +// UInt nb_element = getFEEngine().getMesh().getNbElement(type); + +// name.clear(); +// name << id << ":structuralmechanics:quad_coords"; +// Array<Real> quad_coords(nb_element * nb_quad, spatial_dimension, +// "quad_coords"); + +// getFEEngineClass<MyFEEngineType>() +// .getShapeFunctions() +// .interpolateOnIntegrationPoints<type>(mesh.getNodes(), quad_coords, +// spatial_dimension); +// getFEEngineClass<MyFEEngineType>() +// .getShapeFunctions() +// .interpolateOnIntegrationPoints<type>(mesh.getNodes(), quad_coords, +// spatial_dimension, _not_ghost, +// empty_filter, true, 0, 1, 1); +// if (spatial_dimension == 3) +// getFEEngineClass<MyFEEngineType>() +// .getShapeFunctions() +// .interpolateOnIntegrationPoints<type>( +// getFEEngine().getMesh().getNodes(), quad_coords, spatial_dimension, +// _not_ghost, empty_filter, true, 0, 2, 2); +// lin_load.resize(nb_element * nb_quad); +// Real * imposed_val = lin_load.storage(); + +// /// sigma/load on each quadrature points +// Real * qcoord = quad_coords.storage(); +// for (UInt el = 0; el < nb_element; ++el) { +// for (UInt q = 0; q < nb_quad; ++q) { +// myf(qcoord, imposed_val, NULL, 0); +// imposed_val += offset; +// qcoord += spatial_dimension; +// } +// } + +// switch (function_type) { +// case _bft_traction_local: +// computeForcesByLocalTractionArray<type>(lin_load); +// break; +// case _bft_traction: +// computeForcesByGlobalTractionArray<type>(lin_load); +// break; +// default: +// break; +// } +// } + +} // namespace akantu + +#endif /* __AKANTU_STRUCTURAL_MECHANICS_MODEL_INLINE_IMPL_CC__ */ diff --git a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc index a9a18f2ef..30cd35597 100644 --- a/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc +++ b/test/test_model/test_structural_mechanics_model/test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc @@ -1,252 +1,249 @@ /** * @file test_structural_mechanics_model_kirchhoff_shell_patch_test_4_5_5.cc * * @author Damien Spielmann <damien.spielmann@epfl.ch> * * @date creation: Thu Feb 21 2013 * @date last modification: Sun Oct 19 2014 * - * @brief patch test exemple 4.5.5 c.f. modelisation des structures par éléments finis J.-L. Batoz/G Dhatt + * @brief patch test exemple 4.5.5 c.f. modelisation des structures par + * éléments finis J.-L. Batoz/G Dhatt * * @section LICENSE * * Copyright (©) 2014, 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -#include <limits> #include <fstream> +#include <limits> /* -------------------------------------------------------------------------- */ #include "aka_common.hh" +#include "material.hh" #include "mesh.hh" #include "mesh_io.hh" #include "mesh_io_msh.hh" #include "structural_mechanics_model.hh" -#include "material.hh" /* -------------------------------------------------------------------------- */ #define TYPE _kirchhoff_shell using namespace akantu; - -int main(int argc, char *argv[]){ +int main(int argc, char * argv[]) { initialize(argc, argv); Mesh shell(3); debug::setDebugLevel(dblWarning); - std::cout<<"Initialisation"<<std::endl; - /* -------------------------------------------------------------------------- */ + std::cout << "Initialisation" << std::endl; + /* -------------------------------------------------------------------------- + */ // Defining the mesh - - UInt nb_nodes=5; - UInt nb_element=4; + + UInt nb_nodes = 5; + UInt nb_element = 4; Array<Real> & nodes = const_cast<Array<Real> &>(shell.getNodes()); nodes.resize(nb_nodes); - Real a=20.; - Real b=10.; + Real a = 20.; + Real b = 10.; - nodes(0,0)=0.; - nodes(0,1)=0.; - nodes(0,2)=0.; + nodes(0, 0) = 0.; + nodes(0, 1) = 0.; + nodes(0, 2) = 0.; - nodes(1,0)=2*a; - nodes(1,1)=0.; - nodes(1,2)=0.; + nodes(1, 0) = 2 * a; + nodes(1, 1) = 0.; + nodes(1, 2) = 0.; - nodes(2,0)=0.; - nodes(2,1)=2*b; - nodes(2,2)=0.; + nodes(2, 0) = 0.; + nodes(2, 1) = 2 * b; + nodes(2, 2) = 0.; - nodes(3,0)=2*a; - nodes(3,1)=2*b; - nodes(3,2)=0.; + nodes(3, 0) = 2 * a; + nodes(3, 1) = 2 * b; + nodes(3, 2) = 0.; - nodes(4,0)=15.; - nodes(4,1)=15.; - nodes(4,2)=0.; + nodes(4, 0) = 15.; + nodes(4, 1) = 15.; + nodes(4, 2) = 0.; shell.addConnectivityType(TYPE); - Array<UInt> & connectivity = const_cast<Array<UInt> &>(shell.getConnectivity(TYPE)); + Array<UInt> & connectivity = + const_cast<Array<UInt> &>(shell.getConnectivity(TYPE)); connectivity.resize(nb_element); - - - - connectivity(0,0)=1; - connectivity(0,1)=3; - connectivity(0,2)=4; - - connectivity(1,0)=3; - connectivity(1,1)=2; - connectivity(1,2)=4; + connectivity(0, 0) = 1; + connectivity(0, 1) = 3; + connectivity(0, 2) = 4; - connectivity(2,0)=2; - connectivity(2,1)=4; - connectivity(2,2)=0; + connectivity(1, 0) = 3; + connectivity(1, 1) = 2; + connectivity(1, 2) = 4; - connectivity(3,0)=0; - connectivity(3,1)=1; - connectivity(3,2)=4; + connectivity(2, 0) = 2; + connectivity(2, 1) = 4; + connectivity(2, 2) = 0; - + connectivity(3, 0) = 0; + connectivity(3, 1) = 1; + connectivity(3, 2) = 4; akantu::MeshIOMSH mesh_io; mesh_io.write("b_beam_3_12_10_13.msh", shell); - std::cout<<"Mesh definition"<<std::endl; - /* -------------------------------------------------------------------------- */ + std::cout << "Mesh definition" << std::endl; + /* -------------------------------------------------------------------------- + */ // Defining the materials - akantu::StructuralMechanicsModel model(shell); // ä döfinir StructuralMaterial mat1; - mat1.E=1000; - mat1.nu=0.3; - mat1.t=1; + mat1.E = 1000; + mat1.nu = 0.3; + mat1.t = 1; model.addMaterial(mat1); - std::cout<<"Material Definition"<<std::endl; - /* -------------------------------------------------------------------------- */ + std::cout << "Material Definition" << std::endl; + /* -------------------------------------------------------------------------- + */ // Defining the deplacement model.initFull(); // Array<Real> & forces = model.getForce(); Array<Real> & displacement = model.getDisplacement(); Array<bool> & boundary = model.getBlockedDOFs(); - - displacement(0,0)=0; - displacement(0,1)=0; - displacement(0,2)=0; - displacement(0,3)=0; - displacement(0,4)=0; - - displacement(1,0)=0; - displacement(1,1)=0; - displacement(1,2)=-800; - displacement(1,3)=-40; - displacement(1,4)=-20; - - displacement(2,0)=0; - displacement(2,1)=0; - displacement(2,2)=-200; - displacement(2,3)=-10; - displacement(2,4)=-20; - - displacement(3,0)=0; - displacement(3,1)=0; - displacement(3,2)=-1400; - displacement(3,3)=-50; - displacement(3,4)=-40; + displacement(0, 0) = 0; + displacement(0, 1) = 0; + displacement(0, 2) = 0; + displacement(0, 3) = 0; + displacement(0, 4) = 0; + + displacement(1, 0) = 0; + displacement(1, 1) = 0; + displacement(1, 2) = -800; + displacement(1, 3) = -40; + displacement(1, 4) = -20; + + displacement(2, 0) = 0; + displacement(2, 1) = 0; + displacement(2, 2) = -200; + displacement(2, 3) = -10; + displacement(2, 4) = -20; + + displacement(3, 0) = 0; + displacement(3, 1) = 0; + displacement(3, 2) = -1400; + displacement(3, 3) = -50; + displacement(3, 4) = -40; /*displacement(4,0)=0; displacement(4,1)=0;*/ /* displacement(4,2)=; displacement(4,3)=; displacement(4,4)=;*/ - - /* -------------------------------------------------------------------------- */ + + /* -------------------------------------------------------------------------- + */ // Defining the boundary conditions - boundary(0,0) = true; - boundary(0,1) = true; - boundary(0,2) = true; - boundary(0,3) = true; - boundary(0,4) = true; - boundary(0,5) = true; - - boundary(1,0) = true; - boundary(1,1) = true; - boundary(1,2) = true; - boundary(1,3) = true; - boundary(1,4) = true; - boundary(1,5) = true; - - boundary(2,0) = true; - boundary(2,1) = true; - boundary(2,2) = true; - boundary(2,3) = true; - boundary(2,4) = true; - boundary(2,5) = true; - - boundary(3,0) = true; - boundary(3,1) = true; - boundary(3,2) = true; - boundary(3,3) = true; - boundary(3,4) = true; - boundary(3,5) = true; + boundary(0, 0) = true; + boundary(0, 1) = true; + boundary(0, 2) = true; + boundary(0, 3) = true; + boundary(0, 4) = true; + boundary(0, 5) = true; + + boundary(1, 0) = true; + boundary(1, 1) = true; + boundary(1, 2) = true; + boundary(1, 3) = true; + boundary(1, 4) = true; + boundary(1, 5) = true; + + boundary(2, 0) = true; + boundary(2, 1) = true; + boundary(2, 2) = true; + boundary(2, 3) = true; + boundary(2, 4) = true; + boundary(2, 5) = true; + + boundary(3, 0) = true; + boundary(3, 1) = true; + boundary(3, 2) = true; + boundary(3, 3) = true; + boundary(3, 4) = true; + boundary(3, 5) = true; // boundary(4,0) = true; // boundary(4,1) = true; // boundary(4,2) = true; // boundary(4,3) = true; // boundary(4,4) = true; - boundary(4,5) = true; + boundary(4, 5) = true; - std::cout<<"BC Definition"<<std::endl; - /* -------------------------------------------------------------------------- */ + std::cout << "BC Definition" << std::endl; + /* -------------------------------------------------------------------------- + */ // Solve - + Real error; model.assembleStiffnessMatrix(); - std::cout<<"Assemble Done"<<std::endl; + std::cout << "Assemble Done" << std::endl; model.getStiffnessMatrix().saveMatrix("K_4_5_5.mtx"); - - + UInt count = 0; - std::cout<<"Matrix saved"<<std::endl; + std::cout << "Matrix saved" << std::endl; model.addDumpField("displacement"); model.addDumpField("rotation"); model.addDumpField("force"); model.addDumpField("momentum"); do { model.updateResidual(); model.solve(); count++; } while (!model.testConvergenceIncrement(1e-10, error) && count < 10); - - /* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- + */ // Post-Processing model.computeStresses(); - - //const SparseMatrix = model.getStiffnessMatrix(); - std::cout<< "u = " << displacement(4,0) << std::endl; - std::cout<< "v = " << displacement(4,1) << std::endl; - std::cout<< "w5 = " << displacement(4,2) << std::endl; - std::cout<< "betax = " << displacement(4,3) << std::endl; - std::cout<< "betay = " << displacement(4,4) << std::endl; - std::cout<< "betaz = " << displacement(4,5) << std::endl; - - - //model.dump(); + + // const SparseMatrix = model.getStiffnessMatrix(); + std::cout << "u = " << displacement(4, 0) << std::endl; + std::cout << "v = " << displacement(4, 1) << std::endl; + std::cout << "w5 = " << displacement(4, 2) << std::endl; + std::cout << "betax = " << displacement(4, 3) << std::endl; + std::cout << "betay = " << displacement(4, 4) << std::endl; + std::cout << "betaz = " << displacement(4, 5) << std::endl; + + // model.dump(); }