diff --git a/CMakeLists.txt b/CMakeLists.txt index afbecb4c4..ad8d332bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,214 +1,216 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Mon Jun 14 2010 # @date last modification: Sat Mar 13 2021 # # @brief main configuration file # # # @section LICENSE # # Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne) # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License along # with Akantu. If not, see . # # @section DESCRIPTION #------------------------------------------------------------------------------- # _ _ # | | | | # __ _| | ____ _ _ __ | |_ _ _ # / _` | |/ / _` | '_ \| __| | | | # | (_| | < (_| | | | | |_| |_| | # \__,_|_|\_\__,_|_| |_|\__|\__,_| # #=============================================================================== #=============================================================================== # CMake Project #=============================================================================== cmake_minimum_required(VERSION 3.5.1) # add this options before PROJECT keyword set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) if(CMAKE_VERSION VERSION_GREATER 3.12) cmake_policy(SET CMP0074 NEW) endif() set(AKANTU_COPYRIGHT "2010-2021, EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)") set(AKANTU_MAINTAINER "Nicolas Richart") set(AKANTU_HOMEPAGE_URL "https://akantu.ch") if(CMAKE_VERSION VERSION_GREATER 3.12) project(Akantu HOMEPAGE_URL "https://akantu.ch") else() project(Akantu) endif() enable_language(CXX) #=============================================================================== # Misc. config for cmake #=============================================================================== set(AKANTU_CMAKE_DIR "${PROJECT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules") set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "Enable/Disable output of compile commands during generation" FORCE) mark_as_advanced(BUILD_SHARED_LIBS) if(NOT AKANTU_TARGETS_EXPORT) set(AKANTU_TARGETS_EXPORT AkantuTargets) endif() include(CMakeVersionGenerator) include(CMakePackagesSystem) include(CMakeFlagsHandling) include(AkantuPackagesSystem) include(AkantuMacros) include(AkantuCleaning) #cmake_activate_debug_message() include(GNUInstallDirs) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") # add the automatically determined parts of the RPATH # which point to directories outside the build tree to the install RPATH set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) #=============================================================================== # Version Number #=============================================================================== # AKANTU version number. define_project_version() #=============================================================================== # Options #=============================================================================== option(AKANTU_EXAMPLES "Activate examples" OFF) option(AKANTU_TESTS "Activate tests" OFF) option(AKANTU_SHARED "Build Akantu as a shared library" ON) option(AKANTU_POSITION_INDEPENDENT "Build with -fPIC when static" ON) -option(AKANTU_RUN_IN_DOCKER "Set the approriate flage tu run in docker" OFF) +option(AKANTU_RUN_IN_DOCKER "Set the appropriate flags to run in docker" OFF) + +set(AKANTU_CXX_STANDARD 17 CACHE STRING "CXX standard needed by Akantu") set(AKANTU_PREFERRED_PYTHON_VERSION 3 CACHE STRING "Preferred version for python related things") mark_as_advanced( AKANTU_PREFERRED_PYTHON_VERSION AKANTU_RUN_IN_DOCKER AKANTU_POSITION_INDEPENDENT AKANTU_SHARED ) if (AKANTU_SHARED) set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries.") else() set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries.") set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() include(AkantuExtraCompilationProfiles) #=============================================================================== # Dependencies #=============================================================================== declare_akantu_types() package_list_packages(${PROJECT_SOURCE_DIR}/packages EXTRA_PACKAGES_FOLDER ${PROJECT_SOURCE_DIR}/extra_packages NO_AUTO_COMPILE_FLAGS) #=============================================================================== # Akantu library #=============================================================================== if (NOT AKANTU_BYPASS_AKANTU_TARGET) add_subdirectory(src) else() find_package(Akantu REQUIRED) if (Akantu_FOUND) get_target_property(_lib akantu INTERFACE_LINK_LIBRARIES) message(STATUS "Found Akantu: ${_lib} (found version ${AKANTU_VERSION})") endif() endif() #=============================================================================== # Documentation #=============================================================================== if(AKANTU_DOCUMENTATION OR AKANTU_DOCUMENTATION_MANUAL) add_subdirectory(doc) else() set(AKANTU_DOC_EXCLUDE_FILES "${PROJECT_SOURCE_DIR}/doc/manual" CACHE INTERNAL "") endif() #=============================================================================== # Python interface #=============================================================================== package_is_activated(python_interface _python_act) if(_python_act) include(AkantuNeedPybind11) if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}") set(AKANTU_PYTHON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) else() set(AKANTU_PYTHON_INSTALL_PREFIX "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_PREFIX}") endif() add_subdirectory(python) endif() #=============================================================================== # Examples and tests #=============================================================================== include(AkantuTestsMacros) include(AkantuExampleMacros) if(AKANTU_TESTS) include(AkantuNeedPybind11) option(AKANTU_BUILD_ALL_TESTS "Build all tests" ON) find_package(GMSH REQUIRED) endif() # tests add_test_tree(test) if(AKANTU_EXAMPLES) if(AKANTU_TESTS) option(AKANTU_TEST_EXAMPLES "Run the examples" ON) endif() find_package(GMSH REQUIRED) add_subdirectory(examples) endif() #=============================================================================== # Install and Packaging #=============================================================================== if (NOT AKANTU_BYPASS_AKANTU_TARGET) include(AkantuInstall) option(AKANTU_DISABLE_CPACK "This option commands the generation of extra info for the \"make package\" target" ON) mark_as_advanced(AKANTU_DISABLE_CPACK) if(NOT AKANTU_DISABLE_CPACK) include(AkantuCPack) endif() endif() diff --git a/cmake/AkantuMacros.cmake b/cmake/AkantuMacros.cmake index 0615d7b41..919087fb3 100644 --- a/cmake/AkantuMacros.cmake +++ b/cmake/AkantuMacros.cmake @@ -1,274 +1,274 @@ #=============================================================================== # @file AkantuMacros.cmake # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Fri Oct 22 2010 # @date last modification: Tue Mar 24 2020 # # @brief Set of macros used by akantu cmake files # # # @section LICENSE # # Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne) # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License along # with Akantu. If not, see . # #=============================================================================== #=============================================================================== function(set_third_party_shared_libirary_name _var _lib) set(${_var} ${PROJECT_BINARY_DIR}/third-party/lib/${CMAKE_SHARED_LIBRARY_PREFIX}${_lib}${CMAKE_SHARED_LIBRARY_SUFFIX} CACHE FILEPATH "" FORCE) endfunction() # ============================================================================== function(_add_file_to_copy target file) get_filename_component(_file_name_we ${file} NAME_WE) get_filename_component(_file_name_ext ${file} EXT) get_filename_component(_file_name ${file} NAME) get_filename_component(_file_path ${file} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) configure_file( ${_file_path} ${CMAKE_CURRENT_BINARY_DIR}/${_file_name} COPYONLY) # set(copy_target copy_${_file_name_we}_${_file_name_ext}_${target}) # add_custom_target(${copy_target} # DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_file_name}) # add_custom_command( # OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file_name} # COMMAND ${CMAKE_COMMAND} -E copy_if_different # ${file} # ${CMAKE_CURRENT_BINARY_DIR} # WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} # DEPENDS ${_file_path} # COMMENT "Copying file ${_file_name} for the target ${target}" # ) # add_dependencies(${target} ${copy_target}) endfunction() # ============================================================================== function(get_target_list_of_associated_files tgt files) if(TARGET ${tgt}) get_target_property(_type ${tgt} TYPE) else() set(_type ${tgt}-NOTFOUND) endif() if(_type STREQUAL "SHARED_LIBRARY" OR _type STREQUAL "STATIC_LIBRARY" OR _type STREQUAL "MODULE_LIBRARY" OR _type STREQUAL "EXECUTABLE") get_target_property(_srcs ${tgt} SOURCES) set(_dep_ressources) foreach(_file ${_srcs}) list(APPEND _dep_ressources ${CMAKE_CURRENT_SOURCE_DIR}/${_file}) endforeach() elseif(_type) get_target_property(_dep_ressources ${tgt} RESSOURCES) endif() set(${files} ${_dep_ressources} PARENT_SCOPE) endfunction() #=============================================================================== # Generate the list of currently loaded materials function(generate_material_list) message(STATUS "Determining the list of recognized materials...") package_get_all_include_directories( AKANTU_LIBRARY_INCLUDE_DIRS ) package_get_all_external_informations( PRIVATE_INCLUDE AKANTU_PRIVATE_EXTERNAL_INCLUDE_DIR INTERFACE_INCLUDE AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR LIBRARIES AKANTU_EXTERNAL_LIBRARIES ) set(_include_dirs ${AKANTU_INCLUDE_DIRS} ${AKANTU_PRIVATE_EXTERNAL_INCLUDE_DIR} ${AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR} ) try_run(_material_list_run _material_list_compile ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/material_lister.cc - CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${_include_dirs}" "-DCMAKE_CXX_STANDARD=14" + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${_include_dirs}" "-DCMAKE_CXX_STANDARD=${AKANTU_CXX_STANDARD}" COMPILE_DEFINITIONS "-DAKANTU_CMAKE_LIST_MATERIALS" COMPILE_OUTPUT_VARIABLE _compile_results RUN_OUTPUT_VARIABLE _result_material_list) if(_material_list_compile AND "${_material_list_run}" EQUAL 0) message(STATUS "Materials included in Akantu:") string(REPLACE "\n" ";" _material_list "${_result_material_list}") foreach(_mat ${_material_list}) string(REPLACE ":" ";" _mat_key "${_mat}") list(GET _mat_key 0 _key) list(GET _mat_key 1 _class) list(LENGTH _mat_key _l) if("${_l}" GREATER 2) list(REMOVE_AT _mat_key 0 1) set(_opt " -- options: [") foreach(_o ${_mat_key}) set(_opt "${_opt} ${_o}") endforeach() set(_opt "${_opt} ]") else() set(_opt "") endif() message(STATUS " ${_class} -- key: ${_key}${_opt}") endforeach() else() message(STATUS "Could not determine the list of materials.") message("${_compile_results}") endif() endfunction() #=============================================================================== # Declare the options for the types and defines the approriate typedefs function(declare_akantu_types) set(AKANTU_TYPE_FLOAT "double (64bit)" CACHE STRING "Precision force floating point types") mark_as_advanced(AKANTU_TYPE_FLOAT) set_property(CACHE AKANTU_TYPE_FLOAT PROPERTY STRINGS "quadruple (128bit)" "double (64bit)" "float (32bit)" ) set(AKANTU_TYPE_INTEGER "int (32bit)" CACHE STRING "Size of the integer types") mark_as_advanced(AKANTU_TYPE_INTEGER) set_property(CACHE AKANTU_TYPE_INTEGER PROPERTY STRINGS "int (32bit)" "long int (64bit)" ) include(CheckTypeSize) # ---------------------------------------------------------------------------- # Floating point types # ---------------------------------------------------------------------------- if(AKANTU_TYPE_FLOAT STREQUAL "float (32bit)") set(AKANTU_FLOAT_TYPE "float" CACHE INTERNAL "") set(AKANTU_FLOAT_SIZE 4 CACHE INTERNAL "") elseif(AKANTU_TYPE_FLOAT STREQUAL "double (64bit)") set(AKANTU_FLOAT_TYPE "double" CACHE INTERNAL "") set(AKANTU_FLOAT_SIZE 8 CACHE INTERNAL "") elseif(AKANTU_TYPE_FLOAT STREQUAL "quadruple (128bit)") check_type_size("long double" LONG_DOUBLE) if(HAVE_LONG_DOUBLE) set(AKANTU_FLOAT_TYPE "long double" CACHE INTERNAL "") set(AKANTU_FLOAT_SIZE 16 CACHE INTERNAL "") message("This feature is not tested and will most probably not compile") else() message(FATAL_ERROR "The type long double is not defined on your system") endif() else() message(FATAL_ERROR "The float type is not defined") endif() include(CheckIncludeFileCXX) include(CheckCXXSourceCompiles) # ---------------------------------------------------------------------------- # Integer types # ---------------------------------------------------------------------------- check_include_file_cxx(cstdint HAVE_CSTDINT) if(NOT HAVE_CSTDINT) check_include_file_cxx(stdint.h HAVE_STDINT_H) if(HAVE_STDINT_H) list(APPEND _int_include stdint.h) endif() else() list(APPEND _int_include cstdint) endif() check_include_file_cxx(cstddef HAVE_CSTDDEF) if(NOT HAVE_CSTDINT) check_include_file_cxx(stddef.h HAVE_STDDEF_H) if(HAVE_STDINT_H) list(APPEND _int_include stddef.h) endif() else() list(APPEND _int_include cstddef) endif() if(AKANTU_TYPE_INTEGER STREQUAL "int (32bit)") set(AKANTU_INTEGER_SIZE 4 CACHE INTERNAL "") check_type_size("int" INT) if(INT EQUAL 4) set(AKANTU_SIGNED_INTEGER_TYPE "int" CACHE INTERNAL "") set(AKANTU_UNSIGNED_INTEGER_TYPE "unsigned int" CACHE INTERNAL "") else() check_type_size("int32_t" INT32_T LANGUAGE CXX) if(HAVE_INT32_T) set(AKANTU_SIGNED_INTEGER_TYPE "int32_t" CACHE INTERNAL "") set(AKANTU_UNSIGNED_INTEGER_TYPE "uint32_t" CACHE INTERNAL "") list(APPEND _extra_includes ${_int_include}) endif() endif() elseif(AKANTU_TYPE_INTEGER STREQUAL "long int (64bit)") set(AKANTU_INTEGER_SIZE 8 CACHE INTERNAL "") check_type_size("long int" LONG_INT) if(LONG_INT EQUAL 8) set(AKANTU_SIGNED_INTEGER_TYPE "long int" CACHE INTERNAL "") set(AKANTU_UNSIGNED_INTEGER_TYPE "unsigned long int" CACHE INTERNAL "") else() check_type_size("long long int" LONG_LONG_INT) if(HAVE_LONG_LONG_INT AND LONG_LONG_INT EQUAL 8) set(AKANTU_SIGNED_INTEGER_TYPE "long long int" CACHE INTERNAL "") set(AKANTU_UNSIGNED_INTEGER_TYPE "unsigned long long int" CACHE INTERNAL "") else() check_type_size("int64_t" INT64_T) if(HAVE_INT64_T) set(AKANTU_SIGNED_INTEGER_TYPE "int64_t" CACHE INTERNAL "") set(AKANTU_UNSIGNED_INTEGER_TYPE "uint64_t" CACHE INTERNAL "") list(APPEND _extra_includes ${_int_include}) endif() endif() endif() else() message(FATAL_ERROR "The integer type is not defined") endif() # ---------------------------------------------------------------------------- # includes # ---------------------------------------------------------------------------- foreach(_inc ${_extra_includes}) set(_incs "#include <${_inc}>\n${_incs}") endforeach() set(AKANTU_TYPES_EXTRA_INCLUDES ${_incs} CACHE INTERNAL "") endfunction() function(mask_package_options prefix) get_property(_list DIRECTORY PROPERTY VARIABLES) foreach(_var ${_list}) if("${_var}" MATCHES "^${prefix}.*") mark_as_advanced(${_var}) endif() endforeach() endfunction() diff --git a/packages/core.cmake b/packages/core.cmake index b9e5f1d2a..6f1273886 100644 --- a/packages/core.cmake +++ b/packages/core.cmake @@ -1,429 +1,424 @@ #=============================================================================== # @file core.cmake # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Mon Nov 21 2011 # @date last modification: Fri Apr 09 2021 # # @brief package description for core # # # @section LICENSE # # Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne) # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License along # with Akantu. If not, see . # #=============================================================================== package_declare(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_range_for - cxx_delegating_constructors - DEPENDS INTERFACE akantu_iterators Boost ) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") package_set_compile_flags(core "-Wall -Wextra -pedantic") else() package_set_compile_flags(core "-Wall") endif() package_declare_sources(core common/aka_array.cc common/aka_array.hh common/aka_array_filter.hh common/aka_array_tmpl.hh common/aka_array_printer.hh common/aka_bbox.hh common/aka_blas_lapack.hh common/aka_circular_array.hh common/aka_circular_array_inline_impl.hh common/aka_common.cc common/aka_common.hh common/aka_common_inline_impl.hh common/aka_csr.hh common/aka_element_classes_info_inline_impl.hh common/aka_enum_macros.hh 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_named_argument.hh common/aka_random_generator.hh common/aka_safe_enum.hh common/aka_types.hh common/aka_voigthelper.hh common/aka_voigthelper_tmpl.hh common/aka_voigthelper.cc common/aka_warning.hh common/aka_warning_restore.hh fe_engine/element_class.hh fe_engine/element_class_helper.hh fe_engine/element_class_tmpl.hh fe_engine/element_classes/element_class_hexahedron_8_inline_impl.hh fe_engine/element_classes/element_class_hexahedron_20_inline_impl.hh fe_engine/element_classes/element_class_pentahedron_6_inline_impl.hh fe_engine/element_classes/element_class_pentahedron_15_inline_impl.hh fe_engine/element_classes/element_class_point_1_inline_impl.hh fe_engine/element_classes/element_class_quadrangle_4_inline_impl.hh fe_engine/element_classes/element_class_quadrangle_8_inline_impl.hh fe_engine/element_classes/element_class_segment_2_inline_impl.hh fe_engine/element_classes/element_class_segment_3_inline_impl.hh fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.hh fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.hh fe_engine/element_classes/element_class_triangle_3_inline_impl.hh fe_engine/element_classes/element_class_triangle_6_inline_impl.hh fe_engine/element_type_conversion.hh fe_engine/fe_engine.cc fe_engine/fe_engine.hh fe_engine/fe_engine_inline_impl.hh 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_property.hh fe_engine/geometrical_element_property.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.hh 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.hh fe_engine/shape_lagrange_base.cc fe_engine/shape_lagrange_base.hh fe_engine/shape_lagrange_base_inline_impl.hh fe_engine/shape_lagrange.hh fe_engine/shape_lagrange_inline_impl.hh fe_engine/element.hh io/new_dumpers/dumper.hh io/new_dumpers/dumper.cc io/new_dumpers/dumper_field.hh io/new_dumpers/dumper_variable.hh io/new_dumpers/support.hh io/new_dumpers/support_tmpl.hh io/mesh_io.cc io/mesh_io.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/parser/algebraic_parser.hh io/parser/input_file_parser.hh io/parser/parsable.cc io/parser/parsable.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.hh 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.hh mesh/mesh.cc mesh/mesh.hh mesh/mesh_periodic.cc mesh/mesh_accessor.hh mesh/mesh_events.hh mesh/mesh_filter.hh mesh/mesh_global_data_updater.hh mesh/mesh_data.cc mesh/mesh_data.hh mesh/mesh_data_tmpl.hh mesh/mesh_inline_impl.hh mesh/node_group.cc mesh/node_group.hh mesh/node_group_inline_impl.hh 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.hh mesh_utils/global_ids_updater.hh mesh_utils/global_ids_updater.cc mesh_utils/global_ids_updater_inline_impl.hh model/common/boundary_condition/boundary_condition.hh model/common/boundary_condition/boundary_condition_functor.hh model/common/boundary_condition/boundary_condition_functor_inline_impl.hh model/common/boundary_condition/boundary_condition_tmpl.hh model/common/non_local_toolbox/neighborhood_base.hh model/common/non_local_toolbox/neighborhood_base.cc model/common/non_local_toolbox/neighborhood_base_inline_impl.hh model/common/non_local_toolbox/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh model/common/non_local_toolbox/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc model/common/non_local_toolbox/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.hh 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.hh 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.hh model/common/non_local_toolbox/base_weight_function.hh model/common/non_local_toolbox/base_weight_function_inline_impl.hh model/common/model_solver.cc model/common/model_solver.hh model/common/solver_callback.hh model/common/solver_callback.cc model/common/dof_manager/dof_manager.cc model/common/dof_manager/dof_manager.hh model/common/dof_manager/dof_manager_default.cc model/common/dof_manager/dof_manager_default.hh model/common/dof_manager/dof_manager_default_inline_impl.hh model/common/dof_manager/dof_manager_inline_impl.hh model/common/non_linear_solver/non_linear_solver.cc model/common/non_linear_solver/non_linear_solver.hh model/common/non_linear_solver/non_linear_solver_default.hh model/common/non_linear_solver/non_linear_solver_lumped.cc model/common/non_linear_solver/non_linear_solver_lumped.hh model/common/time_step_solvers/time_step_solver.hh model/common/time_step_solvers/time_step_solver.cc model/common/time_step_solvers/time_step_solver_default.cc model/common/time_step_solvers/time_step_solver_default.hh model/common/time_step_solvers/time_step_solver_default_explicit.hh model/common/integration_scheme/generalized_trapezoidal.cc model/common/integration_scheme/generalized_trapezoidal.hh model/common/integration_scheme/integration_scheme.cc model/common/integration_scheme/integration_scheme.hh model/common/integration_scheme/integration_scheme_1st_order.cc model/common/integration_scheme/integration_scheme_1st_order.hh model/common/integration_scheme/integration_scheme_2nd_order.cc model/common/integration_scheme/integration_scheme_2nd_order.hh model/common/integration_scheme/newmark-beta.cc model/common/integration_scheme/newmark-beta.hh model/common/integration_scheme/pseudo_time.cc model/common/integration_scheme/pseudo_time.hh model/model.cc model/model.hh model/model_inline_impl.hh model/model_options.hh solver/solver_vector.hh solver/solver_vector_default.hh solver/solver_vector_default_tmpl.hh solver/solver_vector_distributed.cc solver/solver_vector_distributed.hh solver/sparse_matrix.cc solver/sparse_matrix.hh solver/sparse_matrix_aij.cc solver/sparse_matrix_aij.hh solver/sparse_matrix_aij_inline_impl.hh solver/sparse_matrix_inline_impl.hh solver/sparse_solver.cc solver/sparse_solver.hh solver/sparse_solver_inline_impl.hh solver/terms_to_assemble.hh synchronizer/communication_buffer_inline_impl.hh synchronizer/communication_descriptor.hh synchronizer/communication_descriptor_tmpl.hh synchronizer/communication_request.hh synchronizer/communication_tag.hh synchronizer/communications.hh synchronizer/communications_tmpl.hh synchronizer/communicator.cc synchronizer/communicator.hh synchronizer/communicator_dummy_inline_impl.hh synchronizer/communicator_event_handler.hh synchronizer/communicator_inline_impl.hh synchronizer/data_accessor.cc synchronizer/data_accessor.hh synchronizer/dof_synchronizer.cc synchronizer/dof_synchronizer.hh synchronizer/dof_synchronizer_inline_impl.hh synchronizer/element_info_per_processor.cc synchronizer/element_info_per_processor.hh synchronizer/element_info_per_processor_tmpl.hh synchronizer/element_synchronizer.cc synchronizer/element_synchronizer.hh synchronizer/facet_synchronizer.cc synchronizer/facet_synchronizer.hh synchronizer/facet_synchronizer_inline_impl.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/node_synchronizer.cc synchronizer/node_synchronizer.hh synchronizer/node_synchronizer_inline_impl.hh synchronizer/periodic_node_synchronizer.cc synchronizer/periodic_node_synchronizer.hh synchronizer/slave_element_info_per_processor.cc 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 synchronizer/communication_buffer.hh ) set(AKANTU_SPIRIT_SOURCES io/mesh_io/mesh_io_abaqus.cc io/parser/parser_real.cc io/parser/parser_random.cc io/parser/parser_types.cc io/parser/parser_input_files.cc PARENT_SCOPE ) 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_N compute_dnds compute_d2nds2 compute_jmat get_shapes_derivatives lagrange_base assemble_fields ) 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 ) 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() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0e64c1fbc..510469972 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,275 +1,262 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux # @author Nicolas Richart # # @date creation: Mon Jun 14 2010 # @date last modification: Tue Feb 13 2018 # # @brief CMake file for the library # # @section LICENSE # # Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== #=============================================================================== # Package Management #=============================================================================== package_get_all_source_files( AKANTU_LIBRARY_SRCS AKANTU_LIBRARY_PUBLIC_HDRS AKANTU_LIBRARY_PRIVATE_HDRS ) package_get_all_include_directories( AKANTU_LIBRARY_INCLUDE_DIRS ) package_get_all_external_informations( PRIVATE_INCLUDE AKANTU_PRIVATE_EXTERNAL_INCLUDE_DIR INTERFACE_INCLUDE AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR LIBRARIES AKANTU_EXTERNAL_LIBRARIES ) package_get_all_compilation_flags(CXX _cxx_flags) set(AKANTU_EXTRA_CXX_FLAGS "${_cxx_flags}" CACHE STRING "Extra flags defined by loaded packages" FORCE) mark_as_advanced(AKANTU_EXTRA_CXX_FLAGS) foreach(src_ ${AKANTU_SPIRIT_SOURCES}) set_property(SOURCE ${src_} PROPERTY COMPILE_FLAGS "-g0 -Werror") endforeach() #=========================================================================== # header for blas/lapack (any other fortran libraries) #=========================================================================== package_is_activated(BLAS _blas_activated) package_is_activated(LAPACK _lapack_activated) if(_blas_activated OR _lapack_activated) if(CMAKE_Fortran_COMPILER) # ugly hack set(CMAKE_Fortran_COMPILER_LOADED TRUE) endif() include(FortranCInterface) FortranCInterface_HEADER( "${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh" MACRO_NAMESPACE "AKA_FC_") mark_as_advanced(CDEFS) list(APPEND AKANTU_LIBRARY_PUBLIC_HDRS "${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh" ) endif() list(APPEND AKANTU_LIBRARY_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}") set(AKANTU_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ${AKANTU_LIBRARY_INCLUDE_DIRS} CACHE INTERNAL "Internal include directories to link with Akantu as a subproject") #=========================================================================== # configurations #=========================================================================== package_get_all_material_includes(AKANTU_MATERIAL_INCLUDES) package_get_all_material_lists(AKANTU_MATERIAL_LISTS) configure_file(model/solid_mechanics/material_list.hh.in "${CMAKE_CURRENT_BINARY_DIR}/material_list.hh" @ONLY) package_get_element_lists() configure_file(common/aka_element_classes_info.hh.in "${CMAKE_CURRENT_BINARY_DIR}/aka_element_classes_info.hh" @ONLY) configure_file(common/aka_config.hh.in "${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh" @ONLY) list(APPEND AKANTU_LIBRARY_PUBLIC_HDRS "${CMAKE_CURRENT_BINARY_DIR}/material_list.hh" "${CMAKE_CURRENT_BINARY_DIR}/aka_element_classes_info.hh" "${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh") configure_file(common/aka_config.cc.in "${CMAKE_CURRENT_BINARY_DIR}/aka_config.cc" @ONLY) list(APPEND AKANTU_LIBRARY_SRCS "${CMAKE_CURRENT_BINARY_DIR}/aka_config.cc") #=============================================================================== # Debug infos #=============================================================================== set(AKANTU_GDB_DIR ${PROJECT_SOURCE_DIR}/cmake) if(UNIX AND NOT APPLE) string(TOUPPER "${CMAKE_BUILD_TYPE}" _u_build_type) if(_u_build_type STREQUAL "DEBUG" OR _u_build_type STREQUAL "RELWITHDEBINFO") configure_file(${PROJECT_SOURCE_DIR}/cmake/libakantu-gdb.py.in "${PROJECT_BINARY_DIR}/libakantu-gdb.py" @ONLY) configure_file(${PROJECT_SOURCE_DIR}/cmake/akantu-debug.cc.in "${PROJECT_BINARY_DIR}/akantu-debug.cc" @ONLY) list(APPEND AKANTU_LIBRARY_SRCS ${PROJECT_BINARY_DIR}/akantu-debug.cc) endif() else() find_program(GDB_EXECUTABLE gdb) if(GDB_EXECUTABLE) execute_process(COMMAND ${GDB_EXECUTABLE} --batch -x "${PROJECT_SOURCE_DIR}/cmake/gdb_python_path" OUTPUT_VARIABLE AKANTU_PYTHON_GDB_DIR ERROR_QUIET RESULT_VARIABLE _res) if(_res EQUAL 0 AND UNIX) set(GDB_USER_CONFIG $ENV{HOME}/.gdb/auto-load) file(MAKE_DIRECTORY ${GDB_USER_CONFIG}) configure_file(${PROJECT_SOURCE_DIR}/cmake/libakantu-gdb.py.in "${GDB_USER_CONFIG}/${CMAKE_SHARED_LIBRARY_PREFIX}akantu${CMAKE_SHARED_LIBRARY_SUFFIX}.${AKANTU_VERSION}-gdb.py" @ONLY) endif() endif() endif() #=============================================================================== # GIT info #=============================================================================== #include(AkantuBuildOptions) #git_version_info(akantu_git_info ALL # OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/akantu_git_info.hh # ) #list(APPEND AKANTU_LIBRARY_SRCS ${CMAKE_CURRENT_BINARY_DIR}/akantu_git_info.hh) #=============================================================================== # Library generation #=============================================================================== add_library(akantu ${AKANTU_LIBRARY_SRCS}) target_include_directories(akantu PRIVATE $ INTERFACE $ ) # small trick for build includes in public set_property(TARGET akantu APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $) target_include_directories(akantu SYSTEM PUBLIC ${AKANTU_INTERFACE_EXTERNAL_INCLUDE_DIR} ) target_include_directories(akantu SYSTEM PRIVATE ${AKANTU_PRIVATE_EXTERNAL_INCLUDE_DIR} ) target_link_libraries(akantu PUBLIC ${AKANTU_EXTERNAL_LIBRARIES}) set_target_properties(akantu PROPERTIES ${AKANTU_LIBRARY_PROPERTIES} # this contains the version COMPILE_FLAGS "${_cxx_flags}" #PRIVATE_HEADER ${AKANTU_LIBRARY_PRIVATE_HDRS} ) if(NOT AKANTU_SHARED) set_property(TARGET akantu PROPERTY POSITION_INDEPENDENT_CODE ${AKANTU_POSITION_INDEPENDENT}) endif() if(AKANTU_LIBRARY_PUBLIC_HDRS) set_property(TARGET akantu PROPERTY PUBLIC_HEADER ${AKANTU_LIBRARY_PUBLIC_HDRS}) endif() if(AKANTU_LIBRARY_PRIVATE_HDRS) set_property(TARGET akantu PROPERTY PRIVATE_HEADER ${AKANTU_LIBRARY_PRIVATE_HDRS}) endif() -if(NOT CMAKE_VERSION VERSION_LESS 3.1) - package_get_all_features_public(_PUBLIC_features) - package_get_all_features_private(_PRIVATE_features) - foreach(_type PRIVATE PUBLIC) - if(_${_type}_features) - target_compile_features(akantu ${_type} ${_${_type}_features}) - endif() - endforeach() -else() - set_target_properties(akantu - PROPERTIES - CXX_STANDARD 14 - ) -endif() +target_compile_features(akantu PUBLIC cxx_std_${AKANTU_CXX_STANDARD}) package_get_all_extra_dependencies(_extra_target_dependencies) if(_extra_target_dependencies) # This only adding todo: find a solution for when a dependency was add the is removed... add_dependencies(akantu ${_extra_target_dependencies}) endif() package_get_all_export_list(AKANTU_EXPORT_LIST) list(APPEND AKANTU_EXPORT_LIST akantu) # TODO separate public from private headers install(TARGETS akantu EXPORT ${AKANTU_TARGETS_EXPORT} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Akantu_runtime # NAMELINK_ONLY # LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # COMPONENT Akantu_development # NAMELINK_SKIP Akantu_development ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Akantu_runtime RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Akantu_runtime PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/akantu/ COMPONENT Akantu_development ) if("${AKANTU_TARGETS_EXPORT}" STREQUAL "AkantuTargets") install(EXPORT AkantuTargets DESTINATION lib/cmake/${PROJECT_NAME} COMPONENT dev) #Export for build tree export(EXPORT AkantuTargets FILE "${CMAKE_BINARY_DIR}/AkantuTargets.cmake") export(PACKAGE Akantu) endif() #=============================================================================== # Adding module names for debug package_get_all_packages(_pkg_list) foreach(_pkg ${_pkg_list}) _package_get_real_name(${_pkg} _pkg_name) _package_get_source_files(${_pkg} _srcs _public_hdrs _private_hdrs) string(TOLOWER "${_pkg_name}" _l_package_name) set_property(SOURCE ${_srcs} ${_public_hdrs} ${_private_hdrs} APPEND PROPERTY COMPILE_DEFINITIONS AKANTU_MODULE=${_l_package_name}) endforeach() # print out the list of materials generate_material_list() register_target_to_tidy(akantu) register_tidy_all(${AKANTU_LIBRARY_SRCS}) register_code_to_format( ${AKANTU_LIBRARY_SRCS} ${AKANTU_LIBRARY_PUBLIC_HDRS} ${AKANTU_LIBRARY_PRIVATE_HDRS} ) diff --git a/src/io/new_dumpers/dumper_field.hh b/src/io/new_dumpers/dumper_field.hh index 338c32519..2bd3a6ddd 100644 --- a/src/io/new_dumpers/dumper_field.hh +++ b/src/io/new_dumpers/dumper_field.hh @@ -1,203 +1,400 @@ /** * @file dumper_field.hh * * @author Nicolas Richart * * @date creation: Tue Sep 02 2014 * @date last modification: Tue Jan 19 2016 * * @brief Common interface for fields * * @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 . * */ /* -------------------------------------------------------------------------- */ #include "element_type_map.hh" #include "support.hh" /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_DUMPER_FIELD_HH__ #define __AKANTU_DUMPER_FIELD_HH__ namespace akantu { namespace dumper { enum class FieldType { _not_defined, - _array, + _node_array, + _node_array_function, _element_map_array, - _connectivity + _element_map_array_function }; /// Field interface class FieldBase : public PropertiesManager { public: virtual ~FieldBase() = default; FieldBase(const FieldBase &) = default; - FieldBase(FieldBase &&) = delete; - FieldBase & operator=(const FieldBase &) = delete; - FieldBase & operator=(FieldBase &&) = delete; - explicit FieldBase(const SupportBase & support, FieldType type) - : support(support), field_type(type) {} - + FieldBase(FieldBase &&) noexcept = default; + FieldBase & operator=(const FieldBase &) = default; + FieldBase & operator=(FieldBase &&) noexcept = default; + FieldBase(const SupportBase & support, std::type_index type, + FieldType field_type) + : support(support), type_(type), field_type(field_type) {} + [[nodiscard]] std::type_index type() const { return type_; } AKANTU_GET_MACRO(FieldType, field_type, FieldType); AKANTU_GET_MACRO(Support, support, const SupportBase &); protected: + void setFieldType(FieldType type) { field_type = type; } + + private: const SupportBase & support; + std::type_index type_; FieldType field_type{FieldType::_not_defined}; }; /* ------------------------------------------------------------------------ */ - class FieldArrayBase : public FieldBase { + class FieldNodeArrayBase : public FieldBase { public: - FieldArrayBase(const FieldArrayBase &) = default; - FieldArrayBase(FieldArrayBase &&) = delete; - FieldArrayBase & operator=(const FieldArrayBase &) = delete; - FieldArrayBase & operator=(FieldArrayBase &&) = delete; - explicit FieldArrayBase(const SupportBase & support) - : FieldBase(support, FieldType::_array) {} - virtual ~FieldArrayBase() = default; - [[nodiscard]] virtual std::type_index type() const = 0; + FieldNodeArrayBase(const FieldNodeArrayBase &) = default; + FieldNodeArrayBase(FieldNodeArrayBase &&) noexcept = default; + FieldNodeArrayBase & operator=(const FieldNodeArrayBase &) = default; + FieldNodeArrayBase & operator=(FieldNodeArrayBase &&) noexcept = default; + ~FieldNodeArrayBase() override = default; + + FieldNodeArrayBase(const SupportBase & support, std::type_index type, + FieldType field_type = FieldType::_node_array) + : FieldBase(support, type, field_type) {} + [[nodiscard]] virtual const void * data() const = 0; [[nodiscard]] virtual void * data() = 0; + [[nodiscard]] virtual std::size_t size() const = 0; [[nodiscard]] virtual std::size_t getNbComponent() const = 0; }; /* ------------------------------------------------------------------------ */ - class FieldElementMapArrayBase : public FieldBase { + template class FieldNodeArray : public FieldNodeArrayBase { public: - using ElementTypesIteratorHelper = - ElementTypeMapArray::ElementTypesIteratorHelper; + FieldNodeArray(const FieldNodeArray &) = default; + FieldNodeArray(FieldNodeArray &&) noexcept = default; + FieldNodeArray & operator=(const FieldNodeArray &) = default; + FieldNodeArray & operator=(FieldNodeArray &&) noexcept = default; + ~FieldNodeArray() override = default; - explicit FieldElementMapArrayBase(const SupportBase & support) - : FieldBase(support, FieldType::_element_map_array) {} - [[nodiscard]] virtual ElementTypesIteratorHelper elementTypes() const = 0; - [[nodiscard]] virtual FieldArrayBase & - array(const Qualified & type) const = 0; - }; + FieldNodeArray(const Array & array, const SupportBase & support) + : FieldNodeArrayBase(support, typeid(T)), array(array) {} - /* ------------------------------------------------------------------------ */ - template class FieldArray : public FieldArrayBase { - public: - FieldArray(const Array & array, const SupportBase & support) - : FieldArrayBase(support), array(array) {} - [[nodiscard]] std::type_index type() const override { return {typeid(T)}; } [[nodiscard]] const void * data() const override { return array.storage(); } [[nodiscard]] void * data() override { return array.storage(); } + [[nodiscard]] std::size_t size() const override { return array.size(); } [[nodiscard]] std::size_t getNbComponent() const override { return array.getNbComponent(); } + [[nodiscard]] const Array & getArray() const { return array; } private: const Array & array; }; /* ------------------------------------------------------------------------ */ - template - class FieldElementMapArray : public FieldElementMapArrayBase { + template + class FieldFunctionNodeArray : public FieldNodeArrayBase { public: - FieldElementMapArray(const ElementTypeMapArray & map_array, - const SupportBase & support) - : FieldElementMapArrayBase(support), - support_element(dynamic_cast(support)), - map_array(map_array) { - for (auto && type : support_element.elementTypes()) { - std::string name = std::to_string(type.type); - if (type.ghost_type != _not_ghost) - name + ":" + std::to_string(type.ghost_type); + FieldFunctionNodeArray(const FieldFunctionNodeArray &) noexcept = default; + FieldFunctionNodeArray(FieldFunctionNodeArray &&) noexcept = default; + FieldFunctionNodeArray & + operator=(const FieldFunctionNodeArray &) noexcept = default; + FieldFunctionNodeArray & + operator=(FieldFunctionNodeArray &&) noexcept = default; + ~FieldFunctionNodeArray() override = default; - auto field = std::make_unique>(map_array(type), support); - field->addProperty("name", name); + FieldFunctionNodeArray(const Array & array_in, + const SupportBase & support, Function && function) + : FieldNodeArrayBase(support, typeid(T), + FieldType::_node_array_function), + function(std::forward(function)), array_in(array_in) { + update(); + } + + [[nodiscard]] const void * data() const override { + return array_out->storage(); + } + [[nodiscard]] void * data() override { + update(); + return array_out->storage(); + } - fields.emplace(type, std::move(field)); + [[nodiscard]] std::size_t size() const override { return array_in.size(); } + [[nodiscard]] std::size_t getNbComponent() const override { + if constexpr (std::is_class_v) { + return function.getNbComponent(array_in.getNbComponent()); + } else { + return array_in.getNbComponent(); } } - [[nodiscard]] FieldArrayBase & - array(const Qualified & type) const override { - return *fields.at(type); + [[nodiscard]] const Array & getArray() const { return *array_out; } + [[nodiscard]] const Array & getArray() { + update(); + return *array_out; } - [[nodiscard]] decltype(auto) - arrayTyped(const Qualified & type) const { - return (aka::as_type>(*fields.at(type))); + private: + void update() { + if (not array_out) { + array_out = + std::make_unique>(array_in.size(), this->getNbComponent()); + } else { + array_out->resize(array_in.size()); + } + + for (auto && [out, in] : + zip(make_view(*array_out, array_out->getNbComponent()), + make_view(array_in, array_in.getNbComponent()))) { + out = function(in); + } } - [[nodiscard]] ElementTypesIteratorHelper elementTypes() const override { - return support_element.elementTypes(); + private: + Function function; + const Array & array_in; + std::unique_ptr> array_out; + }; + + /* ------------------------------------------------------------------------ */ + class FieldElementMapArrayBase : public FieldBase { + public: + using ElementTypesIteratorHelper = + ElementTypeMapArray::ElementTypesIteratorHelper; + + FieldElementMapArrayBase(const FieldElementMapArrayBase &) = default; + FieldElementMapArrayBase(FieldElementMapArrayBase &&) noexcept = default; + FieldElementMapArrayBase & + operator=(const FieldElementMapArrayBase &) = default; + FieldElementMapArrayBase & + operator=(FieldElementMapArrayBase &&) noexcept = default; + ~FieldElementMapArrayBase() override = default; + + explicit FieldElementMapArrayBase( + const SupportBase & support, std::type_index type, + FieldType field_type = FieldType::_element_map_array) + : FieldBase(support, type, field_type), + support_element(dynamic_cast(support)) {} + + [[nodiscard]] virtual FieldNodeArrayBase & + array(const Qualified & type) const { + return *fields.at(type); + } + + [[nodiscard]] virtual ElementTypesIteratorHelper elementTypes() const { + return this->support_element.elementTypes(); }; - std::pair getTotalNbElements() { + [[nodiscard]] std::size_t getNbComponent(const ElementType & type) const { + return this->array(type).getNbComponent(); + } + + auto size() const { UInt total_element{0}; UInt total_size{0}; for (auto && type : this->elementTypes()) { auto && array = this->array(type); total_element += array.size(); total_size += array.size() * array.getNbComponent(); } return std::make_pair(total_element, total_size); } - private: + protected: const SupportElements & support_element; + std::map, std::unique_ptr> + fields; + }; + + /* ------------------------------------------------------------------------ */ + template + class FieldElementMapArray : public FieldElementMapArrayBase { + public: + FieldElementMapArray(const FieldElementMapArray &) = default; + FieldElementMapArray(FieldElementMapArray &&) noexcept = default; + FieldElementMapArray & operator=(const FieldElementMapArray &) = default; + FieldElementMapArray & + operator=(FieldElementMapArray &&) noexcept = default; + ~FieldElementMapArray() override = default; + + FieldElementMapArray(const ElementTypeMapArray & map_array, + const SupportBase & support) + : FieldElementMapArrayBase(support, typeid(T)), map_array(map_array) { + for (auto && type : this->support_element.elementTypes()) { + auto name = std::to_string(type.type); + if (type.ghost_type != _not_ghost) { + name + ":" + std::to_string(type.ghost_type); + } + + auto field = + std::make_unique>(map_array(type), support); + field->addProperty("name", name); + + this->fields.emplace(type, std::move(field)); + } + } + + [[nodiscard]] decltype(auto) + arrayTyped(const Qualified & type) const { + return (aka::as_type>(*this->fields.at(type))); + } + + private: const ElementTypeMapArray & map_array; - std::map, std::unique_ptr>> fields; }; /* ------------------------------------------------------------------------ */ - class FieldConnectivity : public FieldElementMapArray { + template + class FieldFunctionElementMapArray : public FieldElementMapArrayBase { + template struct ElementTypeMapArrayFunctor { + ElementTypeMapArrayFunctor(ElementType type, + const ElementFunction & function) + : type(type), function(function) {} + + UInt getNbComponent(UInt nb_component) const { + return function.getNbComponent(nb_component, type); + } + + decltype(auto) operator()(const Vector & in) const { + return function(in, type); + } + + ElementType type; + const ElementFunction & function; + }; + public: - FieldConnectivity(const ElementTypeMapArray & map_array, - const SupportBase & support) - : FieldElementMapArray(map_array, support) { - field_type = FieldType::_connectivity; + FieldFunctionElementMapArray( + const FieldFunctionElementMapArray &) noexcept = default; + FieldFunctionElementMapArray(FieldFunctionElementMapArray &&) noexcept = + default; + FieldFunctionElementMapArray & + operator=(const FieldFunctionElementMapArray &) noexcept = default; + FieldFunctionElementMapArray & + operator=(FieldFunctionElementMapArray &&) noexcept = default; + ~FieldFunctionElementMapArray() override = default; + + FieldFunctionElementMapArray(const ElementTypeMapArray & map_array_in, + const SupportBase & support, + Function && function) + : FieldElementMapArrayBase(support, typeid(T), + FieldType::_element_map_array_function), + function(std::forward(function)), + map_array_in(map_array_in) { + for (auto && type : dynamic_cast(support_element) + .elementTypes()) { + auto name = std::to_string(type.type); + if (type.ghost_type != _not_ghost) { + name + ":" + std::to_string(type.ghost_type); + } + + // if constexpr (std::is_class_v) { + this->fields.emplace( + type, make_field(map_array_in(type), support, + ElementTypeMapArrayFunctor>( + type, this->function))); + // } else { + // auto field = make_field(map_array_in(type), support, [&](auto && in) + // { + // return this->function(in, type); + // }); + // field->addProperty("name", name); + // this->fields.emplace(type, std::move(field)); + //} + } } + + [[nodiscard]] decltype(auto) + arrayTyped(const Qualified & type) const { + return (aka::as_type>( + *this->fields.at(type))); + } + + private: + Function function; + const ElementTypeMapArray & map_array_in; }; + struct ConnectivityFunctor { + UInt getNbComponent(UInt nb_component, ElementType /*type*/) const { + return nb_component + 1; + } + Vector operator()(const Vector & connectivity, + ElementType type) const { + Vector result(connectivity.size() + 1); + for (auto && [i, c] : enumerate(connectivity)) { + result(i + 1) = c; + } + result[0] = aka_type_to_dumper_type.at(type); + return result; + } + + private: + const std::unordered_map aka_type_to_dumper_type{ + {_triangle_3, 4}, {_quadrangle_4, 5}}; + }; + + using FieldConnectivity = + FieldFunctionElementMapArray; + /* ------------------------------------------------------------------------ */ template auto make_field(const Array & array, const SupportBase & support) { - return std::make_unique>(array, support); + return std::make_unique>(array, support); + } + + /* ------------------------------------------------------------------------ */ + template + auto make_field(const Array & array, const SupportBase & support, + Function && function) { + return std::make_unique>( + array, support, std::forward(function)); } /* ------------------------------------------------------------------------ */ template auto make_field(const ElementTypeMapArray & array, const SupportBase & support) { return std::make_unique>(array, support); } /* ------------------------------------------------------------------------ */ - template - auto make_connectivity_field(const ElementTypeMapArray & array, - const SupportBase & support) { - return std::make_unique(array, support); + template + auto make_field(const ElementTypeMapArray & array, + const SupportBase & support, Function && function) { + return std::make_unique>( + array, support, std::forward(function)); } } // namespace dumper } // namespace akantu #endif /* __AKANTU_DUMPER_FIELD_HH__ */ diff --git a/src/io/new_dumpers/dumper_file_base.hh b/src/io/new_dumpers/dumper_file_base.hh index 9f9ef4d76..3ab1eb40f 100644 --- a/src/io/new_dumpers/dumper_file_base.hh +++ b/src/io/new_dumpers/dumper_file_base.hh @@ -1,93 +1,98 @@ /** * @file dumper_file_base.hh * * @author Nicolas Richart * * @date creation Thu Oct 12 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 . * */ /* -------------------------------------------------------------------------- */ #include "dumper_field.hh" #include "dumper_variable.hh" #include "support.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_DUMPER_FILE_BASE_HH__ #define __AKANTU_DUMPER_FILE_BASE_HH__ namespace akantu { namespace dumper { class FileBase { public: /* ---------------------------------------------------------------------- */ FileBase(SupportBase & support) : support(support) {} + FileBase(const FileBase & other) = default; + FileBase & operator=(const FileBase & other) = delete; virtual ~FileBase() = default; protected: /* ---------------------------------------------------------------------- */ - virtual void dump(FieldArrayBase & field) = 0; + virtual void dump(FieldNodeArrayBase & field) = 0; virtual void dump(FieldElementMapArrayBase & field) = 0; /* ---------------------------------------------------------------------- */ virtual void dump(Support & support) = 0; virtual void dump(Support & /*support*/) { AKANTU_TO_IMPLEMENT(); } /* ---------------------------------------------------------------------- */ virtual void dump(FieldBase & field) { using dumper::FieldType; switch (field.getFieldType()) { - case FieldType::_array: - dump(aka::as_type(field)); + case FieldType::_node_array: + dump(aka::as_type(field)); break; case FieldType::_element_map_array: dump(aka::as_type(field)); break; + case FieldType::_not_defined: + AKANTU_EXCEPTION("The field type is not properly defined"); + break; } } public: virtual void dump() { dump(support); } /* ---------------------------------------------------------------------- */ virtual void dump(SupportBase & support) { using dumper::SupportType; switch (support.getType()) { case SupportType::_mesh: dump(aka::as_type>(support)); break; case SupportType::_element_group: dump(aka::as_type>(support)); break; } } protected: SupportBase & support; }; } // namespace dumper } // namespace akantu #endif /* __AKANTU_DUMPER_FILE_BASE_HH__ */ diff --git a/src/io/new_dumpers/hdf5_file.hh b/src/io/new_dumpers/hdf5_file.hh index 23325f775..69472809e 100644 --- a/src/io/new_dumpers/hdf5_file.hh +++ b/src/io/new_dumpers/hdf5_file.hh @@ -1,352 +1,380 @@ /** * @file dumper_hdf5.cc * * @author Nicolas Richart * * @date creation Tue Oct 03 2017 * * @brief Dump data in xdmf format * * @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 . * */ /* -------------------------------------------------------------------------- */ #include "aka_iterators.hh" #include "dumper_field.hh" #include "dumper_file_base.hh" #include "support.hh" /* -------------------------------------------------------------------------- */ #include #include #include #include #include /* -------------------------------------------------------------------------- */ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define ENDIANNESS(x) (x##LE) #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define ENDIANNESS(x) (x##BE) #else #error "Does not know from which end to open the eggs" #endif namespace akantu { namespace dumper { namespace { #define TIDX(x) std::type_index(typeid(x)) hid_t datatype_id_out(const std::type_index & type_idx) { const static std::unordered_map type_ids{ {TIDX(int), sizeof(int) == 4 ? ENDIANNESS(H5T_STD_I32) : ENDIANNESS(H5T_STD_I64)}, {TIDX(unsigned int), sizeof(int) == 4 ? ENDIANNESS(H5T_STD_U32) : ENDIANNESS(H5T_STD_U64)}, {TIDX(int32_t), ENDIANNESS(H5T_STD_I32)}, {TIDX(int64_t), ENDIANNESS(H5T_STD_I64)}, {TIDX(uint32_t), ENDIANNESS(H5T_STD_U32)}, {TIDX(uint64_t), ENDIANNESS(H5T_STD_U64)}, {TIDX(bool), ENDIANNESS(H5T_STD_U8)}, {TIDX(float), ENDIANNESS(H5T_IEEE_F32)}, {TIDX(double), ENDIANNESS(H5T_IEEE_F64)}, }; return type_ids.at(type_idx); } hid_t datatype_id_in(const std::type_index & type_idx) { const static std::unordered_map type_ids{ {TIDX(int), H5T_NATIVE_INT}, {TIDX(unsigned int), H5T_NATIVE_UINT}, {TIDX(int32_t), H5T_NATIVE_INT32}, {TIDX(int64_t), H5T_NATIVE_INT64}, {TIDX(uint32_t), H5T_NATIVE_UINT32}, {TIDX(uint64_t), H5T_NATIVE_UINT64}, {TIDX(bool), H5T_NATIVE_CHAR}, {TIDX(float), H5T_NATIVE_FLOAT}, {TIDX(double), H5T_NATIVE_DOUBLE}, }; return type_ids.at(type_idx); } #undef TIDX } // namespace namespace HDF5 { namespace fs = boost::filesystem; enum class EntityType { _group, _dataset, _file, _dataspace, _link }; struct Entity { hid_t id; fs::path path; EntityType type; Entity(const fs::path & path, EntityType type) : path(path), type(std::move(type)) {} ~Entity() { switch (type) { case EntityType::_group: H5Gclose(id); break; case EntityType::_file: H5Fclose(id); break; case EntityType::_dataset: H5Dclose(id); break; case EntityType::_dataspace: H5Sclose(id); break; case EntityType::_link: break; } } }; class File : public FileBase { public: File(SupportBase & support, const fs::path & path) : FileBase(support) { auto path_wof = path; path_wof.remove_filename(); if (not fs::exists(path_wof)) { fs::create_directories(path_wof); } auto file = std::make_unique("/", EntityType::_file); file->id = H5Fcreate(path.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); support.addProperty("hdf5_file", path.string()); entities.push_back(std::move(file)); /* Turn off error handling */ H5Eset_auto(H5E_DEFAULT, NULL, NULL); } ~File() override = default; protected: auto & openGroup(const std::string & path) { auto & group = *entities.back(); auto && new_group = std::make_unique(group.path, EntityType::_group); new_group->path /= path; auto status = H5Oexists_by_name(group.id, new_group->path.c_str(), H5P_DEFAULT); if (status <= 0) { AKANTU_DEBUG_INFO("DumperHDF5: creating group " << path); new_group->id = H5Gcreate(group.id, new_group->path.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); } else { AKANTU_DEBUG_INFO("DumperHDF5: opening group " << path << " in " << group.path); new_group->id = H5Gopen(group.id, new_group->path.c_str(), H5P_DEFAULT); } entities.push_back(std::move(new_group)); return *entities.back(); } auto & createSymlink(const std::string & path, const std::string & link) { auto & group = *entities.back(); auto && new_link = std::make_unique(group.path, EntityType::_link); new_link->path /= path; auto status = H5Lcreate_soft(link.c_str(), group.id, new_link->path.c_str(), H5P_DEFAULT, H5P_DEFAULT); AKANTU_DEBUG_ASSERT(status >= 0, "Could not create HDF5 link " << new_link->path.c_str() << " -> " << link.c_str() << ", status=" << status); entities.push_back(std::move(new_link)); return *entities.back(); } - protected: - void dump(FieldArrayBase & field) override { + private: + auto createDataSet(FieldBase & field) { auto & group = *entities.back(); - auto data_set = std::make_unique(group.path, EntityType::_dataset); data_set->path /= field.getName(); auto status = H5Oexists_by_name(group.id, data_set->path.c_str(), H5P_DEFAULT); decltype(data_set) data_space; if (status <= 0) { hsize_t dims[2]; - dims[0] = field.size(); - dims[1] = field.getNbComponent(); + dims[0] = field.getProperty("size"); + dims[1] = field.getProperty("nb_components"); data_space = std::make_unique("", EntityType::_dataspace); data_space->id = H5Screate_simple(2, dims, NULL); - AKANTU_DEBUG_INFO("DumperHDF5: creating dataset " + AKANTU_DEBUG_INFO("DumperHDF5: creating data-set " << field.getName() << " in " << group.path.generic_string()); data_set->id = H5Dcreate( group.id, data_set->path.c_str(), datatype_id_out(field.type()), data_space->id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - - field.addProperty("hdf5_path", data_set->path.generic_string()); } else { - AKANTU_DEBUG_INFO("HDF5: opening existing dataset " + AKANTU_DEBUG_INFO("HDF5: opening existing data-set " << data_set->path); data_set->id = H5Dopen(group.id, data_set->path.c_str(), H5P_DEFAULT); } + field.addProperty("hdf5_path", data_set->path.generic_string()); + return data_set; + } + + protected: + void dump(FieldNodeArrayBase & field) override { + field.addProperty("size", field.size()); + field.addProperty("nb_components", field.getNbComponent()); + + auto data_set = createDataSet(field); + AKANTU_DEBUG_INFO("HDF5: writing dataset " << data_set->path); H5Dwrite(data_set->id, datatype_id_in(field.type()), H5S_ALL, H5S_ALL, H5P_DEFAULT, field.data()); } void dump(FieldElementMapArrayBase & field) override { - auto & group = openGroup(field.getName()); - field.addProperty("hdf5_path", group.path.generic_string()); - + Int nb_components = -1; + auto sizes = field.size(); + auto size = sizes.first; for (auto && type : field.elementTypes()) { - dump(field.array(type)); + auto nb_new_components = field.getNbComponent(type); + if (nb_new_components != nb_components and nb_components != -1) { + nb_components = 1; + size = sizes.second; + break; + } + nb_components = nb_new_components; } - entities.pop_back(); - } + field.addProperty("size", size); + field.addProperty("nb_components", nb_components); - void dump(FieldConnectivity & field) { - auto && [total_element, total_size] = field.getTotalNbElements(); - total_size += total_element; + auto data_set = createDataSet(field); - field.addProperty("nb_total_element", total_element); + for (auto && type : field.elementTypes()) { + auto & array = field.array(type); - Array total_array(total_size); + // TODO: create correspoondig dataspaces - UInt i{0}; - for (auto && type : field.elementTypes()) { - auto && array = field.arrayTyped(type).getArray(); - for (auto && connectivity : - make_view(array, array.getNbComponent())) { - total_array[i++] = aka_type_to_dumper_type.at(type); - for (auto && c : connectivity) { - total_array[i++] = c; - } - } + AKANTU_DEBUG_INFO("HDF5: writing dataset " << data_set->path); + H5Dwrite(data_set->id, datatype_id_in(field.type()), H5S_ALL, H5S_ALL, + H5P_DEFAULT, array.data()); } + } - auto && connectivity_field = - make_field(total_array, field.getSupport()); - connectivity_field->addProperty("name", - field.getProperty("name")); - dump(*connectivity_field); + // void dump(FieldConnectivity & field) { + // auto && [total_element, total_size] = field.size(); + // total_size += total_element; - field.addProperty( - "hdf5_path", - connectivity_field->getProperty("hdf5_path")); + // field.addProperty("nb_total_element", total_element); - // entities.pop_back(); - } + // Array total_array(total_size); + + // UInt i{0}; + // for (auto && type : field.elementTypes()) { + // auto && array = field.arrayTyped(type).getArray(); + // for (auto && connectivity : + // make_view(array, array.getNbComponent())) { + // total_array[i++] = aka_type_to_dumper_type.at(type); + // for (auto && c : connectivity) { + // total_array[i++] = c; + // } + // } + // } + + // auto && connectivity_field = make_field(total_array, + // field.getSupport()); connectivity_field->addProperty("name", + // field.getProperty("name")); + // dump(*connectivity_field); + + // field.addProperty("size", total_size); + // field.addProperty("nb_components", 1); + + // field.addProperty( + // "hdf5_path", + // connectivity_field->getProperty("hdf5_path")); + + // // entities.pop_back(); + // } void dump(Support & support) override { if (support.hasProperty("hdf5_release") and support.getRelease() == support.getProperty("hdf5_release")) { auto & link = createSymlink( support.getName(), support.getProperty("hdf5_path")); entities.pop_back(); } auto & group = openGroup(support.getName()); support.addProperty("hdf5_path", group.path.generic_string()); openGroup("nodes"); auto && nodes = support.getNodes(); dump(nodes); entities.pop_back(); + openGroup("elements"); auto && connectivities = support.getConnectivities(); dump(connectivities); + entities.pop_back(); support.addProperty("hdf5_release", support.getRelease()); // auto && data_grp = Group(loc_id, path_ + "/data"); openGroup("groups"); for (auto && support : support.getSubSupports()) { dump(*support.second); } // close groups entities.pop_back(); for (auto && field : support.getFields()) FileBase::dump(*field.second); // close mesh entities.pop_back(); } void dump(Support & support) override { const auto & parent_support = support.getParentSupport(); auto & group = openGroup(support.getName()); support.addProperty("hdf5_path", group.path.generic_string()); support.addProperty( "hdf5_file", parent_support.getProperty("hdf5_file")); dump(support.getElements()); for (auto && field : support.getFields()) { FileBase::dump(*field.second); } entities.pop_back(); } void dump(SupportBase & support) override { FileBase::dump(support); } void dump() override { auto & group = openGroup("steps"); if (support.hasProperty("time")) { auto & group = openGroup(std::to_string(support.getProperty("time"))); } FileBase::dump(support); if (support.hasProperty("time")) { entities.pop_back(); } entities.pop_back(); } private: std::vector> entities; - - const std::unordered_map aka_type_to_dumper_type{ - {_triangle_3, 4}, {_quadrangle_4, 5}}; }; } // namespace HDF5 } // namespace dumper } // namespace akantu diff --git a/src/io/new_dumpers/support.hh b/src/io/new_dumpers/support.hh index 533c2de41..8e7a18cb3 100644 --- a/src/io/new_dumpers/support.hh +++ b/src/io/new_dumpers/support.hh @@ -1,179 +1,191 @@ /** * @file support.hh * * @author Nicolas Richart * * @date creation Tue Oct 03 2017 * * @brief Describe a support for data * * @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 . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "mesh.hh" /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_SUPPORT_HH__ #define __AKANTU_SUPPORT_HH__ // namespace akantu { // template class Property { // struct Value { // std::type_index type() { return type_id_; }; // protected: // template // Value(const T & data) : type_id_(std::type_index(typeid(data))) {} // std::type_index type_id_; // }; // template class ValueImpl : public Value { // public: // ValueImpl(T data) : data_(std::move(data)) {} // const T & data() const { return data_; } // private: // T data_; // }; // public: // static_assert() // template // const T & get() { // } // private: // bool not_set{true}; // std::unique_ptr value; // }; // } // namespace akantu namespace akantu { namespace dumper { class FieldBase; class VariableBase; enum class SupportType { _mesh, _element_group, }; /* ------------------------------------------------------------------------ */ class PropertiesManager { public: using Property = std::variant; template ::value> * = nullptr> void addProperty(const std::string & property, const T & value) { properties[property] = Int(value); } template ::value> * = nullptr> void addProperty(const std::string & property, const T & value) { properties[property] = Real(value); } void addProperty(const std::string & property, const std::string & value) { properties[property] = value; } - template + template ::value> * = nullptr> + const T & getProperty(const std::string & property) const { + return std::get(properties.at(property)); + } + + template ::value> * = nullptr> + const T & getProperty(const std::string & property) const { + return std::get(properties.at(property)); + } + + template ::value> * = nullptr> const T & getProperty(const std::string & property) const { return std::get(properties.at(property)); } bool hasProperty(const std::string & property) const { return (properties.find(property) != properties.end()); } virtual ID getName() const { return getProperty("name"); } private: std::map properties; }; /* ------------------------------------------------------------------------ */ class SupportBase : public PropertiesManager { public: using Fields = std::map>; using Variables = std::map>; using SubSupports = std::map>; explicit SupportBase(SupportType type) : type(std::move(type)) {} virtual ~SupportBase() = default; AKANTU_GET_MACRO(Type, type, SupportType); template inline auto & addSubSupport(const T & type); inline const auto & getSubSupports() const; inline const auto & getParentSupport() const; inline void addField(const ID & id, std::unique_ptr && field); decltype(auto) getFields() const { return (fields_); } protected: Fields fields_; SubSupports sub_supports_; Variables variables_; SupportType type; private: SupportBase * parent{nullptr}; }; /* ------------------------------------------------------------------------ */ template class Support : public SupportBase { ID getName() const override { return "not implemented"; }; }; /* ------------------------------------------------------------------------ */ class SupportElements { public: using ElementTypesIteratorHelper = ElementTypeMapArray::ElementTypesIteratorHelper; virtual ElementTypesIteratorHelper elementTypes() const = 0; virtual ~SupportElements() = default; }; } // namespace dumper } // namespace akantu #include "support_tmpl.hh" namespace akantu { template auto make_support(const T & t) { return std::make_unique>(t); } } // namespace akantu #endif /* __AKANTU_SUPPORT_HH__ */ diff --git a/src/io/new_dumpers/support_tmpl.hh b/src/io/new_dumpers/support_tmpl.hh index 7f0f1d4b1..35701a410 100644 --- a/src/io/new_dumpers/support_tmpl.hh +++ b/src/io/new_dumpers/support_tmpl.hh @@ -1,129 +1,129 @@ /** * @file support_tmpl.hh * * @author Nicolas Richart * * @date creation Fri Oct 06 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 . * */ /* -------------------------------------------------------------------------- */ #include "dumper_field.hh" #include "element_group.hh" #include "node_group.hh" #include "support.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_SUPPORT_TMPL_HH__ #define __AKANTU_SUPPORT_TMPL_HH__ namespace akantu { namespace dumper { template auto & SupportBase::addSubSupport(const T & type) { auto && ptr = make_support(type); auto & support = *ptr; ptr->parent = this; sub_supports_[support.getName()] = std::move(ptr); return support; } const auto & SupportBase::getSubSupports() const { return sub_supports_; } const auto & SupportBase::getParentSupport() const { return *parent; } void SupportBase::addField(const ID & id, std::unique_ptr && field) { field->addProperty("name", id); fields_.emplace(id, std::move(field)); } /* ------------------------------------------------------------------------ */ template <> class Support : public SupportBase, public SupportElements { public: using ElementTypesIteratorHelper = ElementTypeMapArray::ElementTypesIteratorHelper; explicit Support(const Mesh & inner) : SupportBase(SupportType::_mesh), inner(inner), nodes(make_field(inner.getNodes(), *this)), - connectivities( - make_connectivity_field(inner.getConnectivities(), *this)) { + connectivities(make_field(inner.getConnectivities(), *this, + ConnectivityFunctor())) { nodes->addProperty("name", "position"); connectivities->addProperty("name", "connectivities"); this->addProperty("name", inner.getID()); this->addProperty("release", this->getRelease()); } - FieldArray & getNodes() const { return *nodes; } + FieldNodeArray & getNodes() const { return *nodes; } FieldConnectivity & getConnectivities() const { return *connectivities; }; ElementTypesIteratorHelper elementTypes() const override { return inner.elementTypes(inner.getSpatialDimension(), _not_ghost, _ek_not_defined); } Int getRelease() { return inner.getRelease(); } protected: const Mesh & inner; - std::unique_ptr> nodes; + std::unique_ptr> nodes; std::unique_ptr connectivities; }; /* ------------------------------------------------------------------------ */ template <> class Support : public SupportBase, public SupportElements { public: explicit Support(const ElementGroup & inner) : SupportBase(SupportType::_element_group), inner(inner), nodes(make_field(inner.getNodeGroup().getNodes(), *this)), elements(make_field(inner.getElements(), *this)) { nodes->addProperty("name", "nodes"); elements->addProperty("name", "elements"); this->addProperty("name", inner.getName()); this->addProperty("release", this->getRelease()); } auto & getNodes() const { return *nodes; } auto & getElements() const { return *elements; }; ElementTypesIteratorHelper elementTypes() const override { return inner.elementTypes(inner.getMesh().getSpatialDimension(), _not_ghost, _ek_not_defined); } Int getRelease() { return inner.getMesh().getRelease(); } protected: const ElementGroup & inner; - std::unique_ptr> nodes; + std::unique_ptr> nodes; std::unique_ptr> elements; }; } // namespace dumper } // namespace akantu #endif /* __AKANTU_SUPPORT_TMPL_HH__ */ diff --git a/src/io/new_dumpers/xdmf_file.hh b/src/io/new_dumpers/xdmf_file.hh index e17b51592..950d16244 100644 --- a/src/io/new_dumpers/xdmf_file.hh +++ b/src/io/new_dumpers/xdmf_file.hh @@ -1,471 +1,476 @@ /** * @file xdmf_file.hh * * @author Nicolas Richart * * @date creation Thu Oct 12 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 . * */ /* -------------------------------------------------------------------------- */ #include "dumper_file_base.hh" #include "xml_helper.hh" /* -------------------------------------------------------------------------- */ #include #include #include #include #include /* -------------------------------------------------------------------------- */ namespace { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ static const auto ENDIAN{"Little"}; #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ static const auto ENDIAN{"Big"}; #else #error "Does not know from which end to open the eggs" #endif } // namespace #ifndef __AKANTU_XDMF_FILE_HH__ #define __AKANTU_XDMF_FILE_HH__ namespace akantu { namespace dumper { namespace { std::string xdmf_type(const ElementType & type) { static std::map element_map{ {_triangle_3, "Triangle"}, {_quadrangle_4, "Quadrilateral"}, {_tetrahedron_4, "Tetrahedron"}, {_pentahedron_6, "Wedge"}, {_hexahedron_8, "Hexahedron"}, {_triangle_6, "Tri_6"}, {_quadrangle_8, "Quad_8"}, {_tetrahedron_10, "Tet_10"}, {_pentahedron_15, "Wedge_15"}, {_hexahedron_20, "Hex_20"}}; return element_map[type]; } #define TIDX(x) std::type_index(typeid(x)) auto xdmf_datatype(const std::type_index & type_idx) { const static std::unordered_map> type_ids{ {TIDX(int), {"Int", 4}}, {TIDX(unsigned int), {"UInt", 4}}, {TIDX(int32_t), {"Int", 4}}, {TIDX(int64_t), {"Int", 8}}, {TIDX(uint32_t), {"UInt", 4}}, {TIDX(uint64_t), {"Int", 8}}, {TIDX(bool), {"UChar", 1}}, {TIDX(float), {"Float", 4}}, {TIDX(double), {"Float", 8}}, }; return type_ids.at(type_idx); } std::string xdmf_geometry(char dim) { switch (dim) { case 1: //[[gnu::fallthrougth]]; case 2: return "XY"; case 3: return "XYZ"; default: AKANTU_EXCEPTION("Dim " << dim << " is not a recognized geometry"); } } } // namespace namespace XDMF { namespace fs = boost::filesystem; class File : public XML::File, public dumper::FileBase { using Tag = XML::Tag; using CloseTag = XML::CloseTag; public: /* ---------------------------------------------------------------------- */ File(SupportBase & support, const boost::filesystem::path & path) : XML::File(path), FileBase(support), path(path) { *this << "\n"; *this << "\n"; current_xdmf_element.push_back(1); *this << Tag("Xdmf")("Version", "3.0")( "xmlns:xi", "http://www.w3.org/2001/XInclude"); *this << Tag("Domain"); support.addProperty("xdmf_file", path.string()); if (not support.hasProperty("dump_count")) { return; } auto mesh_name = support.getName(); *this << Tag("Grid")("Name", mesh_name + ":all")( "GridType", "Collection")("CollectionType", "Temporal"); } /* -------------------------------------------------------------------- */ File(SupportBase & support, const boost::filesystem::path & path, const std::vector & current_xdmf_path, const std::vector & current_xdmf_element) : XML::File(path), FileBase(support), include(true), current_xdmf_path(current_xdmf_path), current_xdmf_element(current_xdmf_element), path(path) {} /* -------------------------------------------------------------------- */ ~File() override = default; /* -------------------------------------------------------------------- */ XML::File & operator<<(const std::string & str) override { return XML::File::operator<<(str); } /* -------------------------------------------------------------------- */ XML::File & operator<<(const Tag & tag) override { XML::File::operator<<(tag); if (tag.autoclosing()) { if (not current_xdmf_element.empty()) { ++(current_xdmf_element.back()); } return *this; } auto tag_ = tag.tag(); if (tag.hasProperty("Name")) { tag_ += "[@Name=\"" + tag.getProperty("Name") + "\"]"; } current_xdmf_path.push_back(tag_); current_xdmf_element.push_back(1); //*this << "\n"; return *this; } /* -------------------------------------------------------------------- */ XML::File & operator<<(const CloseTag & tag) override { XML::File::operator<<(tag); current_xdmf_path.pop_back(); current_xdmf_element.pop_back(); if (not current_xdmf_element.empty()) { ++(current_xdmf_element.back()); } return *this; } /* -------------------------------------------------------------------- */ void dump() override { // if (include) { auto count = support.getProperty("dump_count"); *this << Tag("Grid")("CollectionType", "Spatial")( "GridType", "Collection")("Name", "model_" + std::to_string(count)); if (support.hasProperty("time")) { *this << Tag("Information", true)("Name", "Time")( "Value", support.getProperty("time")); } FileBase::dump(); *this << CloseTag{}; // return; // } // auto count = support.getProperty("dump_count"); // auto include_path = getIncludeFilename(count); // File xdmf_include(support, include_path, current_xdmf_path); // xdmf_include.dump(); // auto sub_path = // fs::relative(include_path, fs::path(path).remove_filename()); // *this << Tag("xi:include", true)("href", sub_path.string()); } private: fs::path getIncludeFilename(std::size_t num) { std::stringstream sstr; sstr << std::setw(5) << std::setfill('0') << num; auto include_path = path; include_path.remove_filename(); include_path /= "xmfs"; include_path /= path.stem().string() + '_' + sstr.str() + path.extension().string(); return include_path; } std::string currentXMFPath() const { auto tmp = fs::path("/"); for (auto && tag : current_xdmf_path) { tmp /= tag; } return tmp.generic_string(); } std::string currentXMFElement() const { auto tmp = fs::path("/"); auto copy = current_xdmf_element; copy.pop_back(); for (auto && tag : copy) { tmp /= std::to_string(tag); } return tmp.generic_string(); } std::string getName(const ID & name, const Qualified & type) const { std::stringstream sstr; sstr << name << ":" << type.type; if (type.ghost_type != _not_ghost) { sstr << ":" << type.ghost_type; } return sstr.str(); } protected: template void xi_include(const T & t, bool parent = false) { auto element = t.template getProperty("xdmf_element"); if (parent) { element = fs::path(element).parent_path().string(); } *this << Tag("xi:include", true)("xpointer", "element(" + element + ")"); } /* -------------------------------------------------------------------- */ - void dump(FieldArrayBase & field) override { + + /* -------------------------------------------------------------------- */ + void dump(FieldBase & field) override { auto && support = field.getSupport(); auto && tag = Tag("DataItem"); if (field.hasProperty("attribute_type")) { auto && attribute_tag = Tag("Attribute"); attribute_tag("Name", field.getName()); attribute_tag("Attribute_Type", field.getProperty("attribute_type")); attribute_tag("Center", field.getProperty("data_location")); if (field.hasProperty("finite_element_function")) { } *this << attribute_tag; } bool unchanged = true; if (field.hasProperty("hdf5_path") and field.hasProperty("xdmf_previous_hdf5_path")) { unchanged = (field.getProperty("hdf5_path") == field.getProperty("xdmf_previous_hdf5_path")); } if (field.hasProperty("xdmf_element") and unchanged) { xi_include(field); } else if (field.hasProperty("hdf5_path")) { - auto && dims = std::make_tuple(field.size(), field.getNbComponent()); + auto && dims = + std::to_string(field.getProperty("size")) + " " + + std::to_string(field.getProperty("nb_components")); auto && hdf5_path = fs::relative( fs::path(support.getProperty("hdf5_file")), fs::path(support.getProperty("xdmf_file")) .remove_filename()) .string() + ":" + field.getProperty("hdf5_path"); auto && xdmf_datatype_ = xdmf_datatype(field.type()); /* clang-format off */ *this << tag("Name", field.getName()) ("Dimensions", dims) ("Format", "HDF") ("NumberType", xdmf_datatype_.first) ("Precision", xdmf_datatype_.second) ("Endian", ENDIAN); /* clang-format on */ *this << hdf5_path << "\n"; field.addProperty("xdmf_path", currentXMFPath()); field.addProperty("xdmf_element", currentXMFElement()); field.addProperty("xdmf_previous_hdf5_path", field.getProperty("hdf5_path")); *this << CloseTag{}; } else { AKANTU_EXCEPTION("The XML and Binary format are not implemented yet"); } if (field.hasProperty("attribute_type")) { *this << CloseTag{}; } } + void dump(FieldNodeArrayBase & field) override {} void dump(FieldElementMapArrayBase & field) override {} /* -------------------------------------------------------------------- */ void dump(Support & support) override { auto && mesh_name = support.getName(); auto && nodes = support.getNodes(); if (support.hasProperty("xdmf_element") and support.getFields().empty()) { xi_include(support); } else { *this << Tag("Grid")("CollectionType", "Spatial")( "GridType", "Collection")("Name", mesh_name); support.addProperty("xdmf_path", currentXMFPath()); support.addProperty("xdmf_element", currentXMFElement()); *this << Tag("Grid")("Name", mesh_name)("GridType", "Uniform"); // Topology auto & connectivities = support.getConnectivities(); if (connectivities.hasProperty("xdmf_element")) { xi_include(connectivities, true); } else { UInt nb_elements{0}; if (connectivities.hasProperty("nb_elements")) { nb_elements = connectivities.getProperty("nb_total_element"); } else { - nb_elements = connectivities.getTotalNbElements().first; + nb_elements = connectivities.size().first; } *this << Tag("Topology")("TopologyType", "Mixed")("NumberOfElements", nb_elements); - dump(connectivities); + dump(aka::as_type(connectivities)); *this << CloseTag{}; } // Geometry if (nodes.hasProperty("xdmf_element")) { xi_include(nodes, true); } else { *this << Tag("Geometry")("GeometryType", xdmf_geometry(nodes.getNbComponent())); - dump(nodes); + dump(aka::as_type(nodes)); *this << CloseTag{}; } for (auto && data : support.getFields()) { auto && field = *data.second; switch (field.getFieldType()) { - case FieldType::_array: { + case FieldType::_node_array: { field.addProperty("attribute_type", "Vector"); field.addProperty("data_location", "Node"); - this->dump(aka::as_type(field)); + this->dump(aka::as_type(field)); break; } case FieldType::_element_map_array: { field.addProperty("attribute_type", "Tensor"); field.addProperty("data_location", "Cell"); field.addProperty("name", field.getName()); - this->dump(aka::as_type(field)); + this->dump(aka::as_type(field)); break; } } } *this << CloseTag{}; *this << CloseTag{}; } for (auto && support : support.getSubSupports()) { this->dump(*support.second); } } /* -------------------------------------------------------------------- */ void dump(Support & support) override { const auto & parent_support = support.getParentSupport(); fs::path xdmf_parent = parent_support.getProperty("xdmf_path"); auto parent_name = parent_support.getName(); auto name = parent_name + ":" + support.getName(); if (support.hasProperty("xdmf_element") and support.getFields().empty()) { xi_include(support); return; } *this << Tag("Grid")("Name", name)("GridType", "Collection")( "CollectionType", "Spatial"); support.addProperty("xdmf_path", currentXMFPath()); support.addProperty("xdmf_element", currentXMFElement()); support.addProperty( "xdmf_file", parent_support.getProperty("xdmf_file")); auto & elements = support.getElements(); for (auto && type : support.elementTypes()) { auto xdmf_path = xdmf_parent; auto && name = getName(support.getName(), type); *this << Tag("Grid")("Name", name)("GridType", "Subset")("Section", "DataItem"); dump(elements.array(type)); *this << Tag("Grid")("Name", "Target")("Reference", "XML"); xdmf_path /= "Grid[@Name=\"" + getName(parent_name, type) + "\"]"; *this << xdmf_path.generic_string() << "\n"; *this << CloseTag{}; for (auto && data : support.getFields()) { auto && field = *data.second; switch (field.getFieldType()) { - case FieldType::_array: { + case FieldType::_node_array: { field.addProperty("attribute_type", "Vector"); field.addProperty("data_location", "Node"); FileBase::dump(field); break; } case FieldType::_element_map_array: { auto && array = aka::as_type(field).array(type); array.addProperty("attribute_type", "Tensor"); array.addProperty("data_location", "Cell"); array.addProperty("name", field.getName()); dump(array); break; } } } *this << CloseTag{}; } *this << CloseTag{}; } void dump(SupportBase & support) override { FileBase::dump(support); } public: bool include{false}; std::vector current_xdmf_path; std::vector current_xdmf_element; boost::filesystem::path path; }; } // namespace XDMF } // namespace dumper } // namespace akantu #endif /* __AKANTU_XDMF_FILE_HH__ */ diff --git a/test/test_io/test_xdmf/test_xdmf.cc b/test/test_io/test_xdmf/test_xdmf.cc index 6c9b23989..f8a94c916 100644 --- a/test/test_io/test_xdmf/test_xdmf.cc +++ b/test/test_io/test_xdmf/test_xdmf.cc @@ -1,103 +1,103 @@ /* -------------------------------------------------------------------------- */ /* #include #include #include #include */ #include #include #include /* -------------------------------------------------------------------------- */ using namespace akantu; -int main(int argc, char *argv[]) { +int main(int argc, char * argv[]) { initialize("material.dat", argc, argv); Mesh mesh(2); mesh.read("mesh.msh"); SolidMechanicsModel model(mesh); auto material_selector = std::make_shared>("physical_names", model); model.setMaterialSelector(material_selector); model.initFull(); - auto &&support = make_support(mesh); - auto &&steel = support->addSubSupport(mesh.getElementGroup("steel")); - auto &&copper = support->addSubSupport(mesh.getElementGroup("copper")); + auto && support = make_support(mesh); + auto && steel = support->addSubSupport(mesh.getElementGroup("steel")); + auto && copper = support->addSubSupport(mesh.getElementGroup("copper")); steel.addField("stress", dumper::make_field( model.getMaterial("steel").getStress(), steel)); copper.addField( "stress", dumper::make_field(model.getMaterial("copper").getStress(), copper)); support->addField("u", dumper::make_field(model.getDisplacement(), *support)); DumperXdmf dumper(*support); dumper.dump(); dumper.dump(); // auto &&domain = XdmfDomain::New(); // auto &&geometry = XdmfGeometry::New(); // geometry->setType(XdmfGeometryType::XY()); // geometry->insert(0, mesh.getNodes().storage(), 2 * mesh.getNbNodes()); // auto &&topology_triangle = XdmfTopology::New(); // topology_triangle->setType(XdmfTopologyType::Triangle()); // const auto &triangles = mesh.getConnectivity(_triangle_3); // topology_triangle->insert(0, triangles.storage(), triangles.size() * 3); // auto &&topology_quad = XdmfTopology::New(); // topology_quad->setType(XdmfTopologyType::Quadrilateral()); // const auto &quadrangles = mesh.getConnectivity(_quadrangle_4); // topology_quad->insert(0, quadrangles.storage(), quadrangles.size() * 4); // auto &&grid_triangle = XdmfUnstructuredGrid::New(); // grid_triangle->setName("mesh::_triangle_3"); // grid_triangle->setGeometry(geometry); // grid_triangle->setTopology(topology_triangle); // auto &&grid_quadrangle = XdmfUnstructuredGrid::New(); // grid_quadrangle->setName("mesh::_quadrangle_4"); // grid_quadrangle->setGeometry(geometry); // grid_quadrangle->setTopology(topology_quad); // auto &&grid_mesh = XdmfGridCollection::New(); // grid_mesh->setName("mesh"); // grid_mesh->setType(XdmfGridCollectionType::Spatial()); // grid_mesh->insert(grid_triangle); // grid_mesh->insert(grid_quadrangle); // auto &&grid_mesh_0 = XdmfGridCollection::New(); // grid_mesh_0->setName("mesh:0"); // grid_mesh_0->setType(XdmfGridCollectionType::Spatial()); // grid_mesh_0->insert(grid_mesh); // shared_ptr i0 = XdmfInformation::New("Time", "0.0"); // grid_mesh_0->insert(i0); // auto &&grid_mesh_1 = XdmfGridCollection::New(); // grid_mesh_1->setName("mesh:1"); // grid_mesh_1->setType(XdmfGridCollectionType::Spatial()); // grid_mesh_1->insert(grid_mesh); // shared_ptr i1 = XdmfInformation::New("Time", "1.0"); // grid_mesh_1->insert(i1); // auto &&grid_all = XdmfGridCollection::New(); // grid_all->setName("all"); // grid_all->setType(XdmfGridCollectionType::Temporal()); // grid_all->insert(grid_mesh_0); // grid_all->insert(grid_mesh_1); // domain->insert(grid_all); // auto &&writer = XdmfWriter::New("output.xmf"); // domain->accept(writer); finalize(); return 0; }